/*! * @section LICENSE * (C) Copyright 2011~2014 Bosch Sensortec GmbH All Rights Reserved * * This software program is licensed subject to the GNU General * Public License (GPL).Version 2,June 1991, * available at http://www.fsf.org/copyleft/gpl.html * * @filename bma2x2.c * @date 2014/06/24 09:40 * @id "999d791" * @version 2.0.3 * * @brief * This file contains all function implementations for the BMA2X2 in linux */ #ifdef CONFIG_SIG_MOTION #undef CONFIG_HAS_EARLYSUSPEND #endif #include #include #include #include #include #include #include #include #include #include #include #include #ifdef CONFIG_HAS_EARLYSUSPEND #include #endif #ifdef __KERNEL__ #include #include #include #include #include #else #include #include #include #endif #include "../../init-input.h" #include "bstclass.h" #define ACC_NAME "ACC" /*#define CONFIG_BMA_ENABLE_NEWDATA_INT 1*/ #define SENSOR_NAME "bma250" #define ABSMIN -512 #define ABSMAX 512 #define SLOPE_THRESHOLD_VALUE 32 #define SLOPE_DURATION_VALUE 1 #define INTERRUPT_LATCH_MODE 13 #define INTERRUPT_ENABLE 1 #define INTERRUPT_DISABLE 0 #define MAP_SLOPE_INTERRUPT 2 #define SLOPE_X_INDEX 5 #define SLOPE_Y_INDEX 6 #define SLOPE_Z_INDEX 7 #define BMA2X2_MAX_DELAY 1000 #define BMA2X2_RANGE_SET 3 /* +/- 2G */ #define BMA2X2_BW_SET 12 /* 125HZ */ #define LOW_G_INTERRUPT REL_Z #define HIGH_G_INTERRUPT REL_HWHEEL #define SLOP_INTERRUPT REL_DIAL #define DOUBLE_TAP_INTERRUPT REL_WHEEL #define SINGLE_TAP_INTERRUPT REL_MISC #define ORIENT_INTERRUPT ABS_PRESSURE #define FLAT_INTERRUPT ABS_DISTANCE #define SLOW_NO_MOTION_INTERRUPT REL_Y #define HIGH_G_INTERRUPT_X_HAPPENED 1 #define HIGH_G_INTERRUPT_Y_HAPPENED 2 #define HIGH_G_INTERRUPT_Z_HAPPENED 3 #define HIGH_G_INTERRUPT_X_NEGATIVE_HAPPENED 4 #define HIGH_G_INTERRUPT_Y_NEGATIVE_HAPPENED 5 #define HIGH_G_INTERRUPT_Z_NEGATIVE_HAPPENED 6 #define SLOPE_INTERRUPT_X_HAPPENED 7 #define SLOPE_INTERRUPT_Y_HAPPENED 8 #define SLOPE_INTERRUPT_Z_HAPPENED 9 #define SLOPE_INTERRUPT_X_NEGATIVE_HAPPENED 10 #define SLOPE_INTERRUPT_Y_NEGATIVE_HAPPENED 11 #define SLOPE_INTERRUPT_Z_NEGATIVE_HAPPENED 12 #define DOUBLE_TAP_INTERRUPT_HAPPENED 13 #define SINGLE_TAP_INTERRUPT_HAPPENED 14 #define UPWARD_PORTRAIT_UP_INTERRUPT_HAPPENED 15 #define UPWARD_PORTRAIT_DOWN_INTERRUPT_HAPPENED 16 #define UPWARD_LANDSCAPE_LEFT_INTERRUPT_HAPPENED 17 #define UPWARD_LANDSCAPE_RIGHT_INTERRUPT_HAPPENED 18 #define DOWNWARD_PORTRAIT_UP_INTERRUPT_HAPPENED 19 #define DOWNWARD_PORTRAIT_DOWN_INTERRUPT_HAPPENED 20 #define DOWNWARD_LANDSCAPE_LEFT_INTERRUPT_HAPPENED 21 #define DOWNWARD_LANDSCAPE_RIGHT_INTERRUPT_HAPPENED 22 #define FLAT_INTERRUPT_TURE_HAPPENED 23 #define FLAT_INTERRUPT_FALSE_HAPPENED 24 #define LOW_G_INTERRUPT_HAPPENED 25 #define SLOW_NO_MOTION_INTERRUPT_HAPPENED 26 #define PAD_LOWG 0 #define PAD_HIGHG 1 #define PAD_SLOP 2 #define PAD_DOUBLE_TAP 3 #define PAD_SINGLE_TAP 4 #define PAD_ORIENT 5 #define PAD_FLAT 6 #define PAD_SLOW_NO_MOTION 7 #define BMA2X2_EEP_OFFSET 0x16 #define BMA2X2_IMAGE_BASE 0x38 #define BMA2X2_IMAGE_LEN 22 #define BMA2X2_CHIP_ID_REG 0x00 #define BMA2X2_VERSION_REG 0x01 #define BMA2X2_X_AXIS_LSB_REG 0x02 #define BMA2X2_X_AXIS_MSB_REG 0x03 #define BMA2X2_Y_AXIS_LSB_REG 0x04 #define BMA2X2_Y_AXIS_MSB_REG 0x05 #define BMA2X2_Z_AXIS_LSB_REG 0x06 #define BMA2X2_Z_AXIS_MSB_REG 0x07 #define BMA2X2_TEMPERATURE_REG 0x08 #define BMA2X2_STATUS1_REG 0x09 #define BMA2X2_STATUS2_REG 0x0A #define BMA2X2_STATUS_TAP_SLOPE_REG 0x0B #define BMA2X2_STATUS_ORIENT_HIGH_REG 0x0C #define BMA2X2_STATUS_FIFO_REG 0x0E #define BMA2X2_RANGE_SEL_REG 0x0F #define BMA2X2_BW_SEL_REG 0x10 #define BMA2X2_MODE_CTRL_REG 0x11 #define BMA2X2_LOW_NOISE_CTRL_REG 0x12 #define BMA2X2_DATA_CTRL_REG 0x13 #define BMA2X2_RESET_REG 0x14 #define BMA2X2_INT_ENABLE1_REG 0x16 #define BMA2X2_INT_ENABLE2_REG 0x17 #define BMA2X2_INT_SLO_NO_MOT_REG 0x18 #define BMA2X2_INT1_PAD_SEL_REG 0x19 #define BMA2X2_INT_DATA_SEL_REG 0x1A #define BMA2X2_INT2_PAD_SEL_REG 0x1B #define BMA2X2_INT_SRC_REG 0x1E #define BMA2X2_INT_SET_REG 0x20 #define BMA2X2_INT_CTRL_REG 0x21 #define BMA2X2_LOW_DURN_REG 0x22 #define BMA2X2_LOW_THRES_REG 0x23 #define BMA2X2_LOW_HIGH_HYST_REG 0x24 #define BMA2X2_HIGH_DURN_REG 0x25 #define BMA2X2_HIGH_THRES_REG 0x26 #define BMA2X2_SLOPE_DURN_REG 0x27 #define BMA2X2_SLOPE_THRES_REG 0x28 #define BMA2X2_SLO_NO_MOT_THRES_REG 0x29 #define BMA2X2_TAP_PARAM_REG 0x2A #define BMA2X2_TAP_THRES_REG 0x2B #define BMA2X2_ORIENT_PARAM_REG 0x2C #define BMA2X2_THETA_BLOCK_REG 0x2D #define BMA2X2_THETA_FLAT_REG 0x2E #define BMA2X2_FLAT_HOLD_TIME_REG 0x2F #define BMA2X2_FIFO_WML_TRIG 0x30 #define BMA2X2_SELF_TEST_REG 0x32 #define BMA2X2_EEPROM_CTRL_REG 0x33 #define BMA2X2_SERIAL_CTRL_REG 0x34 #define BMA2X2_EXTMODE_CTRL_REG 0x35 #define BMA2X2_OFFSET_CTRL_REG 0x36 #define BMA2X2_OFFSET_PARAMS_REG 0x37 #define BMA2X2_OFFSET_X_AXIS_REG 0x38 #define BMA2X2_OFFSET_Y_AXIS_REG 0x39 #define BMA2X2_OFFSET_Z_AXIS_REG 0x3A #define BMA2X2_GP0_REG 0x3B #define BMA2X2_GP1_REG 0x3C #define BMA2X2_FIFO_MODE_REG 0x3E #define BMA2X2_FIFO_DATA_OUTPUT_REG 0x3F #define BMA2X2_CHIP_ID__POS 0 #define BMA2X2_CHIP_ID__MSK 0xFF #define BMA2X2_CHIP_ID__LEN 8 #define BMA2X2_CHIP_ID__REG BMA2X2_CHIP_ID_REG #define BMA2X2_VERSION__POS 0 #define BMA2X2_VERSION__LEN 8 #define BMA2X2_VERSION__MSK 0xFF #define BMA2X2_VERSION__REG BMA2X2_VERSION_REG #define BMA2x2_SLO_NO_MOT_DUR__POS 2 #define BMA2x2_SLO_NO_MOT_DUR__LEN 6 #define BMA2x2_SLO_NO_MOT_DUR__MSK 0xFC #define BMA2x2_SLO_NO_MOT_DUR__REG BMA2X2_SLOPE_DURN_REG #define BMA2X2_NEW_DATA_X__POS 0 #define BMA2X2_NEW_DATA_X__LEN 1 #define BMA2X2_NEW_DATA_X__MSK 0x01 #define BMA2X2_NEW_DATA_X__REG BMA2X2_X_AXIS_LSB_REG #define BMA2X2_ACC_X14_LSB__POS 2 #define BMA2X2_ACC_X14_LSB__LEN 6 #define BMA2X2_ACC_X14_LSB__MSK 0xFC #define BMA2X2_ACC_X14_LSB__REG BMA2X2_X_AXIS_LSB_REG #define BMA2X2_ACC_X12_LSB__POS 4 #define BMA2X2_ACC_X12_LSB__LEN 4 #define BMA2X2_ACC_X12_LSB__MSK 0xF0 #define BMA2X2_ACC_X12_LSB__REG BMA2X2_X_AXIS_LSB_REG #define BMA2X2_ACC_X10_LSB__POS 6 #define BMA2X2_ACC_X10_LSB__LEN 2 #define BMA2X2_ACC_X10_LSB__MSK 0xC0 #define BMA2X2_ACC_X10_LSB__REG BMA2X2_X_AXIS_LSB_REG #define BMA2X2_ACC_X8_LSB__POS 0 #define BMA2X2_ACC_X8_LSB__LEN 0 #define BMA2X2_ACC_X8_LSB__MSK 0x00 #define BMA2X2_ACC_X8_LSB__REG BMA2X2_X_AXIS_LSB_REG #define BMA2X2_ACC_X_MSB__POS 0 #define BMA2X2_ACC_X_MSB__LEN 8 #define BMA2X2_ACC_X_MSB__MSK 0xFF #define BMA2X2_ACC_X_MSB__REG BMA2X2_X_AXIS_MSB_REG #define BMA2X2_NEW_DATA_Y__POS 0 #define BMA2X2_NEW_DATA_Y__LEN 1 #define BMA2X2_NEW_DATA_Y__MSK 0x01 #define BMA2X2_NEW_DATA_Y__REG BMA2X2_Y_AXIS_LSB_REG #define BMA2X2_ACC_Y14_LSB__POS 2 #define BMA2X2_ACC_Y14_LSB__LEN 6 #define BMA2X2_ACC_Y14_LSB__MSK 0xFC #define BMA2X2_ACC_Y14_LSB__REG BMA2X2_Y_AXIS_LSB_REG #define BMA2X2_ACC_Y12_LSB__POS 4 #define BMA2X2_ACC_Y12_LSB__LEN 4 #define BMA2X2_ACC_Y12_LSB__MSK 0xF0 #define BMA2X2_ACC_Y12_LSB__REG BMA2X2_Y_AXIS_LSB_REG #define BMA2X2_ACC_Y10_LSB__POS 6 #define BMA2X2_ACC_Y10_LSB__LEN 2 #define BMA2X2_ACC_Y10_LSB__MSK 0xC0 #define BMA2X2_ACC_Y10_LSB__REG BMA2X2_Y_AXIS_LSB_REG #define BMA2X2_ACC_Y8_LSB__POS 0 #define BMA2X2_ACC_Y8_LSB__LEN 0 #define BMA2X2_ACC_Y8_LSB__MSK 0x00 #define BMA2X2_ACC_Y8_LSB__REG BMA2X2_Y_AXIS_LSB_REG #define BMA2X2_ACC_Y_MSB__POS 0 #define BMA2X2_ACC_Y_MSB__LEN 8 #define BMA2X2_ACC_Y_MSB__MSK 0xFF #define BMA2X2_ACC_Y_MSB__REG BMA2X2_Y_AXIS_MSB_REG #define BMA2X2_NEW_DATA_Z__POS 0 #define BMA2X2_NEW_DATA_Z__LEN 1 #define BMA2X2_NEW_DATA_Z__MSK 0x01 #define BMA2X2_NEW_DATA_Z__REG BMA2X2_Z_AXIS_LSB_REG #define BMA2X2_ACC_Z14_LSB__POS 2 #define BMA2X2_ACC_Z14_LSB__LEN 6 #define BMA2X2_ACC_Z14_LSB__MSK 0xFC #define BMA2X2_ACC_Z14_LSB__REG BMA2X2_Z_AXIS_LSB_REG #define BMA2X2_ACC_Z12_LSB__POS 4 #define BMA2X2_ACC_Z12_LSB__LEN 4 #define BMA2X2_ACC_Z12_LSB__MSK 0xF0 #define BMA2X2_ACC_Z12_LSB__REG BMA2X2_Z_AXIS_LSB_REG #define BMA2X2_ACC_Z10_LSB__POS 6 #define BMA2X2_ACC_Z10_LSB__LEN 2 #define BMA2X2_ACC_Z10_LSB__MSK 0xC0 #define BMA2X2_ACC_Z10_LSB__REG BMA2X2_Z_AXIS_LSB_REG #define BMA2X2_ACC_Z8_LSB__POS 0 #define BMA2X2_ACC_Z8_LSB__LEN 0 #define BMA2X2_ACC_Z8_LSB__MSK 0x00 #define BMA2X2_ACC_Z8_LSB__REG BMA2X2_Z_AXIS_LSB_REG #define BMA2X2_ACC_Z_MSB__POS 0 #define BMA2X2_ACC_Z_MSB__LEN 8 #define BMA2X2_ACC_Z_MSB__MSK 0xFF #define BMA2X2_ACC_Z_MSB__REG BMA2X2_Z_AXIS_MSB_REG #define BMA2X2_TEMPERATURE__POS 0 #define BMA2X2_TEMPERATURE__LEN 8 #define BMA2X2_TEMPERATURE__MSK 0xFF #define BMA2X2_TEMPERATURE__REG BMA2X2_TEMP_RD_REG #define BMA2X2_LOWG_INT_S__POS 0 #define BMA2X2_LOWG_INT_S__LEN 1 #define BMA2X2_LOWG_INT_S__MSK 0x01 #define BMA2X2_LOWG_INT_S__REG BMA2X2_STATUS1_REG #define BMA2X2_HIGHG_INT_S__POS 1 #define BMA2X2_HIGHG_INT_S__LEN 1 #define BMA2X2_HIGHG_INT_S__MSK 0x02 #define BMA2X2_HIGHG_INT_S__REG BMA2X2_STATUS1_REG #define BMA2X2_SLOPE_INT_S__POS 2 #define BMA2X2_SLOPE_INT_S__LEN 1 #define BMA2X2_SLOPE_INT_S__MSK 0x04 #define BMA2X2_SLOPE_INT_S__REG BMA2X2_STATUS1_REG #define BMA2X2_SLO_NO_MOT_INT_S__POS 3 #define BMA2X2_SLO_NO_MOT_INT_S__LEN 1 #define BMA2X2_SLO_NO_MOT_INT_S__MSK 0x08 #define BMA2X2_SLO_NO_MOT_INT_S__REG BMA2X2_STATUS1_REG #define BMA2X2_DOUBLE_TAP_INT_S__POS 4 #define BMA2X2_DOUBLE_TAP_INT_S__LEN 1 #define BMA2X2_DOUBLE_TAP_INT_S__MSK 0x10 #define BMA2X2_DOUBLE_TAP_INT_S__REG BMA2X2_STATUS1_REG #define BMA2X2_SINGLE_TAP_INT_S__POS 5 #define BMA2X2_SINGLE_TAP_INT_S__LEN 1 #define BMA2X2_SINGLE_TAP_INT_S__MSK 0x20 #define BMA2X2_SINGLE_TAP_INT_S__REG BMA2X2_STATUS1_REG #define BMA2X2_ORIENT_INT_S__POS 6 #define BMA2X2_ORIENT_INT_S__LEN 1 #define BMA2X2_ORIENT_INT_S__MSK 0x40 #define BMA2X2_ORIENT_INT_S__REG BMA2X2_STATUS1_REG #define BMA2X2_FLAT_INT_S__POS 7 #define BMA2X2_FLAT_INT_S__LEN 1 #define BMA2X2_FLAT_INT_S__MSK 0x80 #define BMA2X2_FLAT_INT_S__REG BMA2X2_STATUS1_REG #define BMA2X2_FIFO_FULL_INT_S__POS 5 #define BMA2X2_FIFO_FULL_INT_S__LEN 1 #define BMA2X2_FIFO_FULL_INT_S__MSK 0x20 #define BMA2X2_FIFO_FULL_INT_S__REG BMA2X2_STATUS2_REG #define BMA2X2_FIFO_WM_INT_S__POS 6 #define BMA2X2_FIFO_WM_INT_S__LEN 1 #define BMA2X2_FIFO_WM_INT_S__MSK 0x40 #define BMA2X2_FIFO_WM_INT_S__REG BMA2X2_STATUS2_REG #define BMA2X2_DATA_INT_S__POS 7 #define BMA2X2_DATA_INT_S__LEN 1 #define BMA2X2_DATA_INT_S__MSK 0x80 #define BMA2X2_DATA_INT_S__REG BMA2X2_STATUS2_REG #define BMA2X2_SLOPE_FIRST_X__POS 0 #define BMA2X2_SLOPE_FIRST_X__LEN 1 #define BMA2X2_SLOPE_FIRST_X__MSK 0x01 #define BMA2X2_SLOPE_FIRST_X__REG BMA2X2_STATUS_TAP_SLOPE_REG #define BMA2X2_SLOPE_FIRST_Y__POS 1 #define BMA2X2_SLOPE_FIRST_Y__LEN 1 #define BMA2X2_SLOPE_FIRST_Y__MSK 0x02 #define BMA2X2_SLOPE_FIRST_Y__REG BMA2X2_STATUS_TAP_SLOPE_REG #define BMA2X2_SLOPE_FIRST_Z__POS 2 #define BMA2X2_SLOPE_FIRST_Z__LEN 1 #define BMA2X2_SLOPE_FIRST_Z__MSK 0x04 #define BMA2X2_SLOPE_FIRST_Z__REG BMA2X2_STATUS_TAP_SLOPE_REG #define BMA2X2_SLOPE_SIGN_S__POS 3 #define BMA2X2_SLOPE_SIGN_S__LEN 1 #define BMA2X2_SLOPE_SIGN_S__MSK 0x08 #define BMA2X2_SLOPE_SIGN_S__REG BMA2X2_STATUS_TAP_SLOPE_REG #define BMA2X2_TAP_FIRST_X__POS 4 #define BMA2X2_TAP_FIRST_X__LEN 1 #define BMA2X2_TAP_FIRST_X__MSK 0x10 #define BMA2X2_TAP_FIRST_X__REG BMA2X2_STATUS_TAP_SLOPE_REG #define BMA2X2_TAP_FIRST_Y__POS 5 #define BMA2X2_TAP_FIRST_Y__LEN 1 #define BMA2X2_TAP_FIRST_Y__MSK 0x20 #define BMA2X2_TAP_FIRST_Y__REG BMA2X2_STATUS_TAP_SLOPE_REG #define BMA2X2_TAP_FIRST_Z__POS 6 #define BMA2X2_TAP_FIRST_Z__LEN 1 #define BMA2X2_TAP_FIRST_Z__MSK 0x40 #define BMA2X2_TAP_FIRST_Z__REG BMA2X2_STATUS_TAP_SLOPE_REG #define BMA2X2_TAP_SIGN_S__POS 7 #define BMA2X2_TAP_SIGN_S__LEN 1 #define BMA2X2_TAP_SIGN_S__MSK 0x80 #define BMA2X2_TAP_SIGN_S__REG BMA2X2_STATUS_TAP_SLOPE_REG #define BMA2X2_HIGHG_FIRST_X__POS 0 #define BMA2X2_HIGHG_FIRST_X__LEN 1 #define BMA2X2_HIGHG_FIRST_X__MSK 0x01 #define BMA2X2_HIGHG_FIRST_X__REG BMA2X2_STATUS_ORIENT_HIGH_REG #define BMA2X2_HIGHG_FIRST_Y__POS 1 #define BMA2X2_HIGHG_FIRST_Y__LEN 1 #define BMA2X2_HIGHG_FIRST_Y__MSK 0x02 #define BMA2X2_HIGHG_FIRST_Y__REG BMA2X2_STATUS_ORIENT_HIGH_REG #define BMA2X2_HIGHG_FIRST_Z__POS 2 #define BMA2X2_HIGHG_FIRST_Z__LEN 1 #define BMA2X2_HIGHG_FIRST_Z__MSK 0x04 #define BMA2X2_HIGHG_FIRST_Z__REG BMA2X2_STATUS_ORIENT_HIGH_REG #define BMA2X2_HIGHG_SIGN_S__POS 3 #define BMA2X2_HIGHG_SIGN_S__LEN 1 #define BMA2X2_HIGHG_SIGN_S__MSK 0x08 #define BMA2X2_HIGHG_SIGN_S__REG BMA2X2_STATUS_ORIENT_HIGH_REG #define BMA2X2_ORIENT_S__POS 4 #define BMA2X2_ORIENT_S__LEN 3 #define BMA2X2_ORIENT_S__MSK 0x70 #define BMA2X2_ORIENT_S__REG BMA2X2_STATUS_ORIENT_HIGH_REG #define BMA2X2_FLAT_S__POS 7 #define BMA2X2_FLAT_S__LEN 1 #define BMA2X2_FLAT_S__MSK 0x80 #define BMA2X2_FLAT_S__REG BMA2X2_STATUS_ORIENT_HIGH_REG #define BMA2X2_FIFO_FRAME_COUNTER_S__POS 0 #define BMA2X2_FIFO_FRAME_COUNTER_S__LEN 7 #define BMA2X2_FIFO_FRAME_COUNTER_S__MSK 0x7F #define BMA2X2_FIFO_FRAME_COUNTER_S__REG BMA2X2_STATUS_FIFO_REG #define BMA2X2_FIFO_OVERRUN_S__POS 7 #define BMA2X2_FIFO_OVERRUN_S__LEN 1 #define BMA2X2_FIFO_OVERRUN_S__MSK 0x80 #define BMA2X2_FIFO_OVERRUN_S__REG BMA2X2_STATUS_FIFO_REG #define BMA2X2_RANGE_SEL__POS 0 #define BMA2X2_RANGE_SEL__LEN 4 #define BMA2X2_RANGE_SEL__MSK 0x0F #define BMA2X2_RANGE_SEL__REG BMA2X2_RANGE_SEL_REG #define BMA2X2_BANDWIDTH__POS 0 #define BMA2X2_BANDWIDTH__LEN 5 #define BMA2X2_BANDWIDTH__MSK 0x1F #define BMA2X2_BANDWIDTH__REG BMA2X2_BW_SEL_REG #define BMA2X2_SLEEP_DUR__POS 1 #define BMA2X2_SLEEP_DUR__LEN 4 #define BMA2X2_SLEEP_DUR__MSK 0x1E #define BMA2X2_SLEEP_DUR__REG BMA2X2_MODE_CTRL_REG #define BMA2X2_MODE_CTRL__POS 5 #define BMA2X2_MODE_CTRL__LEN 3 #define BMA2X2_MODE_CTRL__MSK 0xE0 #define BMA2X2_MODE_CTRL__REG BMA2X2_MODE_CTRL_REG #define BMA2X2_DEEP_SUSPEND__POS 5 #define BMA2X2_DEEP_SUSPEND__LEN 1 #define BMA2X2_DEEP_SUSPEND__MSK 0x20 #define BMA2X2_DEEP_SUSPEND__REG BMA2X2_MODE_CTRL_REG #define BMA2X2_EN_LOW_POWER__POS 6 #define BMA2X2_EN_LOW_POWER__LEN 1 #define BMA2X2_EN_LOW_POWER__MSK 0x40 #define BMA2X2_EN_LOW_POWER__REG BMA2X2_MODE_CTRL_REG #define BMA2X2_EN_SUSPEND__POS 7 #define BMA2X2_EN_SUSPEND__LEN 1 #define BMA2X2_EN_SUSPEND__MSK 0x80 #define BMA2X2_EN_SUSPEND__REG BMA2X2_MODE_CTRL_REG #define BMA2X2_SLEEP_TIMER__POS 5 #define BMA2X2_SLEEP_TIMER__LEN 1 #define BMA2X2_SLEEP_TIMER__MSK 0x20 #define BMA2X2_SLEEP_TIMER__REG BMA2X2_LOW_NOISE_CTRL_REG #define BMA2X2_LOW_POWER_MODE__POS 6 #define BMA2X2_LOW_POWER_MODE__LEN 1 #define BMA2X2_LOW_POWER_MODE__MSK 0x40 #define BMA2X2_LOW_POWER_MODE__REG BMA2X2_LOW_NOISE_CTRL_REG #define BMA2X2_EN_LOW_NOISE__POS 7 #define BMA2X2_EN_LOW_NOISE__LEN 1 #define BMA2X2_EN_LOW_NOISE__MSK 0x80 #define BMA2X2_EN_LOW_NOISE__REG BMA2X2_LOW_NOISE_CTRL_REG #define BMA2X2_DIS_SHADOW_PROC__POS 6 #define BMA2X2_DIS_SHADOW_PROC__LEN 1 #define BMA2X2_DIS_SHADOW_PROC__MSK 0x40 #define BMA2X2_DIS_SHADOW_PROC__REG BMA2X2_DATA_CTRL_REG #define BMA2X2_EN_DATA_HIGH_BW__POS 7 #define BMA2X2_EN_DATA_HIGH_BW__LEN 1 #define BMA2X2_EN_DATA_HIGH_BW__MSK 0x80 #define BMA2X2_EN_DATA_HIGH_BW__REG BMA2X2_DATA_CTRL_REG #define BMA2X2_EN_SOFT_RESET__POS 0 #define BMA2X2_EN_SOFT_RESET__LEN 8 #define BMA2X2_EN_SOFT_RESET__MSK 0xFF #define BMA2X2_EN_SOFT_RESET__REG BMA2X2_RESET_REG #define BMA2X2_EN_SOFT_RESET_VALUE 0xB6 #define BMA2X2_EN_SLOPE_X_INT__POS 0 #define BMA2X2_EN_SLOPE_X_INT__LEN 1 #define BMA2X2_EN_SLOPE_X_INT__MSK 0x01 #define BMA2X2_EN_SLOPE_X_INT__REG BMA2X2_INT_ENABLE1_REG #define BMA2X2_EN_SLOPE_Y_INT__POS 1 #define BMA2X2_EN_SLOPE_Y_INT__LEN 1 #define BMA2X2_EN_SLOPE_Y_INT__MSK 0x02 #define BMA2X2_EN_SLOPE_Y_INT__REG BMA2X2_INT_ENABLE1_REG #define BMA2X2_EN_SLOPE_Z_INT__POS 2 #define BMA2X2_EN_SLOPE_Z_INT__LEN 1 #define BMA2X2_EN_SLOPE_Z_INT__MSK 0x04 #define BMA2X2_EN_SLOPE_Z_INT__REG BMA2X2_INT_ENABLE1_REG #define BMA2X2_EN_DOUBLE_TAP_INT__POS 4 #define BMA2X2_EN_DOUBLE_TAP_INT__LEN 1 #define BMA2X2_EN_DOUBLE_TAP_INT__MSK 0x10 #define BMA2X2_EN_DOUBLE_TAP_INT__REG BMA2X2_INT_ENABLE1_REG #define BMA2X2_EN_SINGLE_TAP_INT__POS 5 #define BMA2X2_EN_SINGLE_TAP_INT__LEN 1 #define BMA2X2_EN_SINGLE_TAP_INT__MSK 0x20 #define BMA2X2_EN_SINGLE_TAP_INT__REG BMA2X2_INT_ENABLE1_REG #define BMA2X2_EN_ORIENT_INT__POS 6 #define BMA2X2_EN_ORIENT_INT__LEN 1 #define BMA2X2_EN_ORIENT_INT__MSK 0x40 #define BMA2X2_EN_ORIENT_INT__REG BMA2X2_INT_ENABLE1_REG #define BMA2X2_EN_FLAT_INT__POS 7 #define BMA2X2_EN_FLAT_INT__LEN 1 #define BMA2X2_EN_FLAT_INT__MSK 0x80 #define BMA2X2_EN_FLAT_INT__REG BMA2X2_INT_ENABLE1_REG #define BMA2X2_EN_HIGHG_X_INT__POS 0 #define BMA2X2_EN_HIGHG_X_INT__LEN 1 #define BMA2X2_EN_HIGHG_X_INT__MSK 0x01 #define BMA2X2_EN_HIGHG_X_INT__REG BMA2X2_INT_ENABLE2_REG #define BMA2X2_EN_HIGHG_Y_INT__POS 1 #define BMA2X2_EN_HIGHG_Y_INT__LEN 1 #define BMA2X2_EN_HIGHG_Y_INT__MSK 0x02 #define BMA2X2_EN_HIGHG_Y_INT__REG BMA2X2_INT_ENABLE2_REG #define BMA2X2_EN_HIGHG_Z_INT__POS 2 #define BMA2X2_EN_HIGHG_Z_INT__LEN 1 #define BMA2X2_EN_HIGHG_Z_INT__MSK 0x04 #define BMA2X2_EN_HIGHG_Z_INT__REG BMA2X2_INT_ENABLE2_REG #define BMA2X2_EN_LOWG_INT__POS 3 #define BMA2X2_EN_LOWG_INT__LEN 1 #define BMA2X2_EN_LOWG_INT__MSK 0x08 #define BMA2X2_EN_LOWG_INT__REG BMA2X2_INT_ENABLE2_REG #define BMA2X2_EN_NEW_DATA_INT__POS 4 #define BMA2X2_EN_NEW_DATA_INT__LEN 1 #define BMA2X2_EN_NEW_DATA_INT__MSK 0x10 #define BMA2X2_EN_NEW_DATA_INT__REG BMA2X2_INT_ENABLE2_REG #define BMA2X2_INT_FFULL_EN_INT__POS 5 #define BMA2X2_INT_FFULL_EN_INT__LEN 1 #define BMA2X2_INT_FFULL_EN_INT__MSK 0x20 #define BMA2X2_INT_FFULL_EN_INT__REG BMA2X2_INT_ENABLE2_REG #define BMA2X2_INT_FWM_EN_INT__POS 6 #define BMA2X2_INT_FWM_EN_INT__LEN 1 #define BMA2X2_INT_FWM_EN_INT__MSK 0x40 #define BMA2X2_INT_FWM_EN_INT__REG BMA2X2_INT_ENABLE2_REG #define BMA2X2_INT_SLO_NO_MOT_EN_X_INT__POS 0 #define BMA2X2_INT_SLO_NO_MOT_EN_X_INT__LEN 1 #define BMA2X2_INT_SLO_NO_MOT_EN_X_INT__MSK 0x01 #define BMA2X2_INT_SLO_NO_MOT_EN_X_INT__REG BMA2X2_INT_SLO_NO_MOT_REG #define BMA2X2_INT_SLO_NO_MOT_EN_Y_INT__POS 1 #define BMA2X2_INT_SLO_NO_MOT_EN_Y_INT__LEN 1 #define BMA2X2_INT_SLO_NO_MOT_EN_Y_INT__MSK 0x02 #define BMA2X2_INT_SLO_NO_MOT_EN_Y_INT__REG BMA2X2_INT_SLO_NO_MOT_REG #define BMA2X2_INT_SLO_NO_MOT_EN_Z_INT__POS 2 #define BMA2X2_INT_SLO_NO_MOT_EN_Z_INT__LEN 1 #define BMA2X2_INT_SLO_NO_MOT_EN_Z_INT__MSK 0x04 #define BMA2X2_INT_SLO_NO_MOT_EN_Z_INT__REG BMA2X2_INT_SLO_NO_MOT_REG #define BMA2X2_INT_SLO_NO_MOT_EN_SEL_INT__POS 3 #define BMA2X2_INT_SLO_NO_MOT_EN_SEL_INT__LEN 1 #define BMA2X2_INT_SLO_NO_MOT_EN_SEL_INT__MSK 0x08 #define BMA2X2_INT_SLO_NO_MOT_EN_SEL_INT__REG BMA2X2_INT_SLO_NO_MOT_REG #define BMA2X2_EN_INT1_PAD_LOWG__POS 0 #define BMA2X2_EN_INT1_PAD_LOWG__LEN 1 #define BMA2X2_EN_INT1_PAD_LOWG__MSK 0x01 #define BMA2X2_EN_INT1_PAD_LOWG__REG BMA2X2_INT1_PAD_SEL_REG #define BMA2X2_EN_INT1_PAD_HIGHG__POS 1 #define BMA2X2_EN_INT1_PAD_HIGHG__LEN 1 #define BMA2X2_EN_INT1_PAD_HIGHG__MSK 0x02 #define BMA2X2_EN_INT1_PAD_HIGHG__REG BMA2X2_INT1_PAD_SEL_REG #define BMA2X2_EN_INT1_PAD_SLOPE__POS 2 #define BMA2X2_EN_INT1_PAD_SLOPE__LEN 1 #define BMA2X2_EN_INT1_PAD_SLOPE__MSK 0x04 #define BMA2X2_EN_INT1_PAD_SLOPE__REG BMA2X2_INT1_PAD_SEL_REG #define BMA2X2_EN_INT1_PAD_SLO_NO_MOT__POS 3 #define BMA2X2_EN_INT1_PAD_SLO_NO_MOT__LEN 1 #define BMA2X2_EN_INT1_PAD_SLO_NO_MOT__MSK 0x08 #define BMA2X2_EN_INT1_PAD_SLO_NO_MOT__REG BMA2X2_INT1_PAD_SEL_REG #define BMA2X2_EN_INT1_PAD_DB_TAP__POS 4 #define BMA2X2_EN_INT1_PAD_DB_TAP__LEN 1 #define BMA2X2_EN_INT1_PAD_DB_TAP__MSK 0x10 #define BMA2X2_EN_INT1_PAD_DB_TAP__REG BMA2X2_INT1_PAD_SEL_REG #define BMA2X2_EN_INT1_PAD_SNG_TAP__POS 5 #define BMA2X2_EN_INT1_PAD_SNG_TAP__LEN 1 #define BMA2X2_EN_INT1_PAD_SNG_TAP__MSK 0x20 #define BMA2X2_EN_INT1_PAD_SNG_TAP__REG BMA2X2_INT1_PAD_SEL_REG #define BMA2X2_EN_INT1_PAD_ORIENT__POS 6 #define BMA2X2_EN_INT1_PAD_ORIENT__LEN 1 #define BMA2X2_EN_INT1_PAD_ORIENT__MSK 0x40 #define BMA2X2_EN_INT1_PAD_ORIENT__REG BMA2X2_INT1_PAD_SEL_REG #define BMA2X2_EN_INT1_PAD_FLAT__POS 7 #define BMA2X2_EN_INT1_PAD_FLAT__LEN 1 #define BMA2X2_EN_INT1_PAD_FLAT__MSK 0x80 #define BMA2X2_EN_INT1_PAD_FLAT__REG BMA2X2_INT1_PAD_SEL_REG #define BMA2X2_EN_INT2_PAD_LOWG__POS 0 #define BMA2X2_EN_INT2_PAD_LOWG__LEN 1 #define BMA2X2_EN_INT2_PAD_LOWG__MSK 0x01 #define BMA2X2_EN_INT2_PAD_LOWG__REG BMA2X2_INT2_PAD_SEL_REG #define BMA2X2_EN_INT2_PAD_HIGHG__POS 1 #define BMA2X2_EN_INT2_PAD_HIGHG__LEN 1 #define BMA2X2_EN_INT2_PAD_HIGHG__MSK 0x02 #define BMA2X2_EN_INT2_PAD_HIGHG__REG BMA2X2_INT2_PAD_SEL_REG #define BMA2X2_EN_INT2_PAD_SLOPE__POS 2 #define BMA2X2_EN_INT2_PAD_SLOPE__LEN 1 #define BMA2X2_EN_INT2_PAD_SLOPE__MSK 0x04 #define BMA2X2_EN_INT2_PAD_SLOPE__REG BMA2X2_INT2_PAD_SEL_REG #define BMA2X2_EN_INT2_PAD_SLO_NO_MOT__POS 3 #define BMA2X2_EN_INT2_PAD_SLO_NO_MOT__LEN 1 #define BMA2X2_EN_INT2_PAD_SLO_NO_MOT__MSK 0x08 #define BMA2X2_EN_INT2_PAD_SLO_NO_MOT__REG BMA2X2_INT2_PAD_SEL_REG #define BMA2X2_EN_INT2_PAD_DB_TAP__POS 4 #define BMA2X2_EN_INT2_PAD_DB_TAP__LEN 1 #define BMA2X2_EN_INT2_PAD_DB_TAP__MSK 0x10 #define BMA2X2_EN_INT2_PAD_DB_TAP__REG BMA2X2_INT2_PAD_SEL_REG #define BMA2X2_EN_INT2_PAD_SNG_TAP__POS 5 #define BMA2X2_EN_INT2_PAD_SNG_TAP__LEN 1 #define BMA2X2_EN_INT2_PAD_SNG_TAP__MSK 0x20 #define BMA2X2_EN_INT2_PAD_SNG_TAP__REG BMA2X2_INT2_PAD_SEL_REG #define BMA2X2_EN_INT2_PAD_ORIENT__POS 6 #define BMA2X2_EN_INT2_PAD_ORIENT__LEN 1 #define BMA2X2_EN_INT2_PAD_ORIENT__MSK 0x40 #define BMA2X2_EN_INT2_PAD_ORIENT__REG BMA2X2_INT2_PAD_SEL_REG #define BMA2X2_EN_INT2_PAD_FLAT__POS 7 #define BMA2X2_EN_INT2_PAD_FLAT__LEN 1 #define BMA2X2_EN_INT2_PAD_FLAT__MSK 0x80 #define BMA2X2_EN_INT2_PAD_FLAT__REG BMA2X2_INT2_PAD_SEL_REG #define BMA2X2_EN_INT1_PAD_NEWDATA__POS 0 #define BMA2X2_EN_INT1_PAD_NEWDATA__LEN 1 #define BMA2X2_EN_INT1_PAD_NEWDATA__MSK 0x01 #define BMA2X2_EN_INT1_PAD_NEWDATA__REG BMA2X2_INT_DATA_SEL_REG #define BMA2X2_EN_INT1_PAD_FWM__POS 1 #define BMA2X2_EN_INT1_PAD_FWM__LEN 1 #define BMA2X2_EN_INT1_PAD_FWM__MSK 0x02 #define BMA2X2_EN_INT1_PAD_FWM__REG BMA2X2_INT_DATA_SEL_REG #define BMA2X2_EN_INT1_PAD_FFULL__POS 2 #define BMA2X2_EN_INT1_PAD_FFULL__LEN 1 #define BMA2X2_EN_INT1_PAD_FFULL__MSK 0x04 #define BMA2X2_EN_INT1_PAD_FFULL__REG BMA2X2_INT_DATA_SEL_REG #define BMA2X2_EN_INT2_PAD_FFULL__POS 5 #define BMA2X2_EN_INT2_PAD_FFULL__LEN 1 #define BMA2X2_EN_INT2_PAD_FFULL__MSK 0x20 #define BMA2X2_EN_INT2_PAD_FFULL__REG BMA2X2_INT_DATA_SEL_REG #define BMA2X2_EN_INT2_PAD_FWM__POS 6 #define BMA2X2_EN_INT2_PAD_FWM__LEN 1 #define BMA2X2_EN_INT2_PAD_FWM__MSK 0x40 #define BMA2X2_EN_INT2_PAD_FWM__REG BMA2X2_INT_DATA_SEL_REG #define BMA2X2_EN_INT2_PAD_NEWDATA__POS 7 #define BMA2X2_EN_INT2_PAD_NEWDATA__LEN 1 #define BMA2X2_EN_INT2_PAD_NEWDATA__MSK 0x80 #define BMA2X2_EN_INT2_PAD_NEWDATA__REG BMA2X2_INT_DATA_SEL_REG #define BMA2X2_UNFILT_INT_SRC_LOWG__POS 0 #define BMA2X2_UNFILT_INT_SRC_LOWG__LEN 1 #define BMA2X2_UNFILT_INT_SRC_LOWG__MSK 0x01 #define BMA2X2_UNFILT_INT_SRC_LOWG__REG BMA2X2_INT_SRC_REG #define BMA2X2_UNFILT_INT_SRC_HIGHG__POS 1 #define BMA2X2_UNFILT_INT_SRC_HIGHG__LEN 1 #define BMA2X2_UNFILT_INT_SRC_HIGHG__MSK 0x02 #define BMA2X2_UNFILT_INT_SRC_HIGHG__REG BMA2X2_INT_SRC_REG #define BMA2X2_UNFILT_INT_SRC_SLOPE__POS 2 #define BMA2X2_UNFILT_INT_SRC_SLOPE__LEN 1 #define BMA2X2_UNFILT_INT_SRC_SLOPE__MSK 0x04 #define BMA2X2_UNFILT_INT_SRC_SLOPE__REG BMA2X2_INT_SRC_REG #define BMA2X2_UNFILT_INT_SRC_SLO_NO_MOT__POS 3 #define BMA2X2_UNFILT_INT_SRC_SLO_NO_MOT__LEN 1 #define BMA2X2_UNFILT_INT_SRC_SLO_NO_MOT__MSK 0x08 #define BMA2X2_UNFILT_INT_SRC_SLO_NO_MOT__REG BMA2X2_INT_SRC_REG #define BMA2X2_UNFILT_INT_SRC_TAP__POS 4 #define BMA2X2_UNFILT_INT_SRC_TAP__LEN 1 #define BMA2X2_UNFILT_INT_SRC_TAP__MSK 0x10 #define BMA2X2_UNFILT_INT_SRC_TAP__REG BMA2X2_INT_SRC_REG #define BMA2X2_UNFILT_INT_SRC_DATA__POS 5 #define BMA2X2_UNFILT_INT_SRC_DATA__LEN 1 #define BMA2X2_UNFILT_INT_SRC_DATA__MSK 0x20 #define BMA2X2_UNFILT_INT_SRC_DATA__REG BMA2X2_INT_SRC_REG #define BMA2X2_INT1_PAD_ACTIVE_LEVEL__POS 0 #define BMA2X2_INT1_PAD_ACTIVE_LEVEL__LEN 1 #define BMA2X2_INT1_PAD_ACTIVE_LEVEL__MSK 0x01 #define BMA2X2_INT1_PAD_ACTIVE_LEVEL__REG BMA2X2_INT_SET_REG #define BMA2X2_INT2_PAD_ACTIVE_LEVEL__POS 2 #define BMA2X2_INT2_PAD_ACTIVE_LEVEL__LEN 1 #define BMA2X2_INT2_PAD_ACTIVE_LEVEL__MSK 0x04 #define BMA2X2_INT2_PAD_ACTIVE_LEVEL__REG BMA2X2_INT_SET_REG #define BMA2X2_INT1_PAD_OUTPUT_TYPE__POS 1 #define BMA2X2_INT1_PAD_OUTPUT_TYPE__LEN 1 #define BMA2X2_INT1_PAD_OUTPUT_TYPE__MSK 0x02 #define BMA2X2_INT1_PAD_OUTPUT_TYPE__REG BMA2X2_INT_SET_REG #define BMA2X2_INT2_PAD_OUTPUT_TYPE__POS 3 #define BMA2X2_INT2_PAD_OUTPUT_TYPE__LEN 1 #define BMA2X2_INT2_PAD_OUTPUT_TYPE__MSK 0x08 #define BMA2X2_INT2_PAD_OUTPUT_TYPE__REG BMA2X2_INT_SET_REG #define BMA2X2_INT_MODE_SEL__POS 0 #define BMA2X2_INT_MODE_SEL__LEN 4 #define BMA2X2_INT_MODE_SEL__MSK 0x0F #define BMA2X2_INT_MODE_SEL__REG BMA2X2_INT_CTRL_REG #define BMA2X2_RESET_INT__POS 7 #define BMA2X2_RESET_INT__LEN 1 #define BMA2X2_RESET_INT__MSK 0x80 #define BMA2X2_RESET_INT__REG BMA2X2_INT_CTRL_REG #define BMA2X2_LOWG_DUR__POS 0 #define BMA2X2_LOWG_DUR__LEN 8 #define BMA2X2_LOWG_DUR__MSK 0xFF #define BMA2X2_LOWG_DUR__REG BMA2X2_LOW_DURN_REG #define BMA2X2_LOWG_THRES__POS 0 #define BMA2X2_LOWG_THRES__LEN 8 #define BMA2X2_LOWG_THRES__MSK 0xFF #define BMA2X2_LOWG_THRES__REG BMA2X2_LOW_THRES_REG #define BMA2X2_LOWG_HYST__POS 0 #define BMA2X2_LOWG_HYST__LEN 2 #define BMA2X2_LOWG_HYST__MSK 0x03 #define BMA2X2_LOWG_HYST__REG BMA2X2_LOW_HIGH_HYST_REG #define BMA2X2_LOWG_INT_MODE__POS 2 #define BMA2X2_LOWG_INT_MODE__LEN 1 #define BMA2X2_LOWG_INT_MODE__MSK 0x04 #define BMA2X2_LOWG_INT_MODE__REG BMA2X2_LOW_HIGH_HYST_REG #define BMA2X2_HIGHG_DUR__POS 0 #define BMA2X2_HIGHG_DUR__LEN 8 #define BMA2X2_HIGHG_DUR__MSK 0xFF #define BMA2X2_HIGHG_DUR__REG BMA2X2_HIGH_DURN_REG #define BMA2X2_HIGHG_THRES__POS 0 #define BMA2X2_HIGHG_THRES__LEN 8 #define BMA2X2_HIGHG_THRES__MSK 0xFF #define BMA2X2_HIGHG_THRES__REG BMA2X2_HIGH_THRES_REG #define BMA2X2_HIGHG_HYST__POS 6 #define BMA2X2_HIGHG_HYST__LEN 2 #define BMA2X2_HIGHG_HYST__MSK 0xC0 #define BMA2X2_HIGHG_HYST__REG BMA2X2_LOW_HIGH_HYST_REG #define BMA2X2_SLOPE_DUR__POS 0 #define BMA2X2_SLOPE_DUR__LEN 2 #define BMA2X2_SLOPE_DUR__MSK 0x03 #define BMA2X2_SLOPE_DUR__REG BMA2X2_SLOPE_DURN_REG #define BMA2X2_SLO_NO_MOT_DUR__POS 2 #define BMA2X2_SLO_NO_MOT_DUR__LEN 6 #define BMA2X2_SLO_NO_MOT_DUR__MSK 0xFC #define BMA2X2_SLO_NO_MOT_DUR__REG BMA2X2_SLOPE_DURN_REG #define BMA2X2_SLOPE_THRES__POS 0 #define BMA2X2_SLOPE_THRES__LEN 8 #define BMA2X2_SLOPE_THRES__MSK 0xFF #define BMA2X2_SLOPE_THRES__REG BMA2X2_SLOPE_THRES_REG #define BMA2X2_SLO_NO_MOT_THRES__POS 0 #define BMA2X2_SLO_NO_MOT_THRES__LEN 8 #define BMA2X2_SLO_NO_MOT_THRES__MSK 0xFF #define BMA2X2_SLO_NO_MOT_THRES__REG BMA2X2_SLO_NO_MOT_THRES_REG #define BMA2X2_TAP_DUR__POS 0 #define BMA2X2_TAP_DUR__LEN 3 #define BMA2X2_TAP_DUR__MSK 0x07 #define BMA2X2_TAP_DUR__REG BMA2X2_TAP_PARAM_REG #define BMA2X2_TAP_SHOCK_DURN__POS 6 #define BMA2X2_TAP_SHOCK_DURN__LEN 1 #define BMA2X2_TAP_SHOCK_DURN__MSK 0x40 #define BMA2X2_TAP_SHOCK_DURN__REG BMA2X2_TAP_PARAM_REG #define BMA2X2_ADV_TAP_INT__POS 5 #define BMA2X2_ADV_TAP_INT__LEN 1 #define BMA2X2_ADV_TAP_INT__MSK 0x20 #define BMA2X2_ADV_TAP_INT__REG BMA2X2_TAP_PARAM_REG #define BMA2X2_TAP_QUIET_DURN__POS 7 #define BMA2X2_TAP_QUIET_DURN__LEN 1 #define BMA2X2_TAP_QUIET_DURN__MSK 0x80 #define BMA2X2_TAP_QUIET_DURN__REG BMA2X2_TAP_PARAM_REG #define BMA2X2_TAP_THRES__POS 0 #define BMA2X2_TAP_THRES__LEN 5 #define BMA2X2_TAP_THRES__MSK 0x1F #define BMA2X2_TAP_THRES__REG BMA2X2_TAP_THRES_REG #define BMA2X2_TAP_SAMPLES__POS 6 #define BMA2X2_TAP_SAMPLES__LEN 2 #define BMA2X2_TAP_SAMPLES__MSK 0xC0 #define BMA2X2_TAP_SAMPLES__REG BMA2X2_TAP_THRES_REG #define BMA2X2_ORIENT_MODE__POS 0 #define BMA2X2_ORIENT_MODE__LEN 2 #define BMA2X2_ORIENT_MODE__MSK 0x03 #define BMA2X2_ORIENT_MODE__REG BMA2X2_ORIENT_PARAM_REG #define BMA2X2_ORIENT_BLOCK__POS 2 #define BMA2X2_ORIENT_BLOCK__LEN 2 #define BMA2X2_ORIENT_BLOCK__MSK 0x0C #define BMA2X2_ORIENT_BLOCK__REG BMA2X2_ORIENT_PARAM_REG #define BMA2X2_ORIENT_HYST__POS 4 #define BMA2X2_ORIENT_HYST__LEN 3 #define BMA2X2_ORIENT_HYST__MSK 0x70 #define BMA2X2_ORIENT_HYST__REG BMA2X2_ORIENT_PARAM_REG #define BMA2X2_ORIENT_AXIS__POS 7 #define BMA2X2_ORIENT_AXIS__LEN 1 #define BMA2X2_ORIENT_AXIS__MSK 0x80 #define BMA2X2_ORIENT_AXIS__REG BMA2X2_THETA_BLOCK_REG #define BMA2X2_ORIENT_UD_EN__POS 6 #define BMA2X2_ORIENT_UD_EN__LEN 1 #define BMA2X2_ORIENT_UD_EN__MSK 0x40 #define BMA2X2_ORIENT_UD_EN__REG BMA2X2_THETA_BLOCK_REG #define BMA2X2_THETA_BLOCK__POS 0 #define BMA2X2_THETA_BLOCK__LEN 6 #define BMA2X2_THETA_BLOCK__MSK 0x3F #define BMA2X2_THETA_BLOCK__REG BMA2X2_THETA_BLOCK_REG #define BMA2X2_THETA_FLAT__POS 0 #define BMA2X2_THETA_FLAT__LEN 6 #define BMA2X2_THETA_FLAT__MSK 0x3F #define BMA2X2_THETA_FLAT__REG BMA2X2_THETA_FLAT_REG #define BMA2X2_FLAT_HOLD_TIME__POS 4 #define BMA2X2_FLAT_HOLD_TIME__LEN 2 #define BMA2X2_FLAT_HOLD_TIME__MSK 0x30 #define BMA2X2_FLAT_HOLD_TIME__REG BMA2X2_FLAT_HOLD_TIME_REG #define BMA2X2_FLAT_HYS__POS 0 #define BMA2X2_FLAT_HYS__LEN 3 #define BMA2X2_FLAT_HYS__MSK 0x07 #define BMA2X2_FLAT_HYS__REG BMA2X2_FLAT_HOLD_TIME_REG #define BMA2X2_FIFO_WML_TRIG_RETAIN__POS 0 #define BMA2X2_FIFO_WML_TRIG_RETAIN__LEN 6 #define BMA2X2_FIFO_WML_TRIG_RETAIN__MSK 0x3F #define BMA2X2_FIFO_WML_TRIG_RETAIN__REG BMA2X2_FIFO_WML_TRIG #define BMA2X2_EN_SELF_TEST__POS 0 #define BMA2X2_EN_SELF_TEST__LEN 2 #define BMA2X2_EN_SELF_TEST__MSK 0x03 #define BMA2X2_EN_SELF_TEST__REG BMA2X2_SELF_TEST_REG #define BMA2X2_NEG_SELF_TEST__POS 2 #define BMA2X2_NEG_SELF_TEST__LEN 1 #define BMA2X2_NEG_SELF_TEST__MSK 0x04 #define BMA2X2_NEG_SELF_TEST__REG BMA2X2_SELF_TEST_REG #define BMA2X2_SELF_TEST_AMP__POS 4 #define BMA2X2_SELF_TEST_AMP__LEN 1 #define BMA2X2_SELF_TEST_AMP__MSK 0x10 #define BMA2X2_SELF_TEST_AMP__REG BMA2X2_SELF_TEST_REG #define BMA2X2_UNLOCK_EE_PROG_MODE__POS 0 #define BMA2X2_UNLOCK_EE_PROG_MODE__LEN 1 #define BMA2X2_UNLOCK_EE_PROG_MODE__MSK 0x01 #define BMA2X2_UNLOCK_EE_PROG_MODE__REG BMA2X2_EEPROM_CTRL_REG #define BMA2X2_START_EE_PROG_TRIG__POS 1 #define BMA2X2_START_EE_PROG_TRIG__LEN 1 #define BMA2X2_START_EE_PROG_TRIG__MSK 0x02 #define BMA2X2_START_EE_PROG_TRIG__REG BMA2X2_EEPROM_CTRL_REG #define BMA2X2_EE_PROG_READY__POS 2 #define BMA2X2_EE_PROG_READY__LEN 1 #define BMA2X2_EE_PROG_READY__MSK 0x04 #define BMA2X2_EE_PROG_READY__REG BMA2X2_EEPROM_CTRL_REG #define BMA2X2_UPDATE_IMAGE__POS 3 #define BMA2X2_UPDATE_IMAGE__LEN 1 #define BMA2X2_UPDATE_IMAGE__MSK 0x08 #define BMA2X2_UPDATE_IMAGE__REG BMA2X2_EEPROM_CTRL_REG #define BMA2X2_EE_REMAIN__POS 4 #define BMA2X2_EE_REMAIN__LEN 4 #define BMA2X2_EE_REMAIN__MSK 0xF0 #define BMA2X2_EE_REMAIN__REG BMA2X2_EEPROM_CTRL_REG #define BMA2X2_EN_SPI_MODE_3__POS 0 #define BMA2X2_EN_SPI_MODE_3__LEN 1 #define BMA2X2_EN_SPI_MODE_3__MSK 0x01 #define BMA2X2_EN_SPI_MODE_3__REG BMA2X2_SERIAL_CTRL_REG #define BMA2X2_I2C_WATCHDOG_PERIOD__POS 1 #define BMA2X2_I2C_WATCHDOG_PERIOD__LEN 1 #define BMA2X2_I2C_WATCHDOG_PERIOD__MSK 0x02 #define BMA2X2_I2C_WATCHDOG_PERIOD__REG BMA2X2_SERIAL_CTRL_REG #define BMA2X2_EN_I2C_WATCHDOG__POS 2 #define BMA2X2_EN_I2C_WATCHDOG__LEN 1 #define BMA2X2_EN_I2C_WATCHDOG__MSK 0x04 #define BMA2X2_EN_I2C_WATCHDOG__REG BMA2X2_SERIAL_CTRL_REG #define BMA2X2_EXT_MODE__POS 7 #define BMA2X2_EXT_MODE__LEN 1 #define BMA2X2_EXT_MODE__MSK 0x80 #define BMA2X2_EXT_MODE__REG BMA2X2_EXTMODE_CTRL_REG #define BMA2X2_ALLOW_UPPER__POS 6 #define BMA2X2_ALLOW_UPPER__LEN 1 #define BMA2X2_ALLOW_UPPER__MSK 0x40 #define BMA2X2_ALLOW_UPPER__REG BMA2X2_EXTMODE_CTRL_REG #define BMA2X2_MAP_2_LOWER__POS 5 #define BMA2X2_MAP_2_LOWER__LEN 1 #define BMA2X2_MAP_2_LOWER__MSK 0x20 #define BMA2X2_MAP_2_LOWER__REG BMA2X2_EXTMODE_CTRL_REG #define BMA2X2_MAGIC_NUMBER__POS 0 #define BMA2X2_MAGIC_NUMBER__LEN 5 #define BMA2X2_MAGIC_NUMBER__MSK 0x1F #define BMA2X2_MAGIC_NUMBER__REG BMA2X2_EXTMODE_CTRL_REG #define BMA2X2_UNLOCK_EE_WRITE_TRIM__POS 4 #define BMA2X2_UNLOCK_EE_WRITE_TRIM__LEN 4 #define BMA2X2_UNLOCK_EE_WRITE_TRIM__MSK 0xF0 #define BMA2X2_UNLOCK_EE_WRITE_TRIM__REG BMA2X2_CTRL_UNLOCK_REG #define BMA2X2_EN_SLOW_COMP_X__POS 0 #define BMA2X2_EN_SLOW_COMP_X__LEN 1 #define BMA2X2_EN_SLOW_COMP_X__MSK 0x01 #define BMA2X2_EN_SLOW_COMP_X__REG BMA2X2_OFFSET_CTRL_REG #define BMA2X2_EN_SLOW_COMP_Y__POS 1 #define BMA2X2_EN_SLOW_COMP_Y__LEN 1 #define BMA2X2_EN_SLOW_COMP_Y__MSK 0x02 #define BMA2X2_EN_SLOW_COMP_Y__REG BMA2X2_OFFSET_CTRL_REG #define BMA2X2_EN_SLOW_COMP_Z__POS 2 #define BMA2X2_EN_SLOW_COMP_Z__LEN 1 #define BMA2X2_EN_SLOW_COMP_Z__MSK 0x04 #define BMA2X2_EN_SLOW_COMP_Z__REG BMA2X2_OFFSET_CTRL_REG #define BMA2X2_FAST_CAL_RDY_S__POS 4 #define BMA2X2_FAST_CAL_RDY_S__LEN 1 #define BMA2X2_FAST_CAL_RDY_S__MSK 0x10 #define BMA2X2_FAST_CAL_RDY_S__REG BMA2X2_OFFSET_CTRL_REG #define BMA2X2_CAL_TRIGGER__POS 5 #define BMA2X2_CAL_TRIGGER__LEN 2 #define BMA2X2_CAL_TRIGGER__MSK 0x60 #define BMA2X2_CAL_TRIGGER__REG BMA2X2_OFFSET_CTRL_REG #define BMA2X2_RESET_OFFSET_REGS__POS 7 #define BMA2X2_RESET_OFFSET_REGS__LEN 1 #define BMA2X2_RESET_OFFSET_REGS__MSK 0x80 #define BMA2X2_RESET_OFFSET_REGS__REG BMA2X2_OFFSET_CTRL_REG #define BMA2X2_COMP_CUTOFF__POS 0 #define BMA2X2_COMP_CUTOFF__LEN 1 #define BMA2X2_COMP_CUTOFF__MSK 0x01 #define BMA2X2_COMP_CUTOFF__REG BMA2X2_OFFSET_PARAMS_REG #define BMA2X2_COMP_TARGET_OFFSET_X__POS 1 #define BMA2X2_COMP_TARGET_OFFSET_X__LEN 2 #define BMA2X2_COMP_TARGET_OFFSET_X__MSK 0x06 #define BMA2X2_COMP_TARGET_OFFSET_X__REG BMA2X2_OFFSET_PARAMS_REG #define BMA2X2_COMP_TARGET_OFFSET_Y__POS 3 #define BMA2X2_COMP_TARGET_OFFSET_Y__LEN 2 #define BMA2X2_COMP_TARGET_OFFSET_Y__MSK 0x18 #define BMA2X2_COMP_TARGET_OFFSET_Y__REG BMA2X2_OFFSET_PARAMS_REG #define BMA2X2_COMP_TARGET_OFFSET_Z__POS 5 #define BMA2X2_COMP_TARGET_OFFSET_Z__LEN 2 #define BMA2X2_COMP_TARGET_OFFSET_Z__MSK 0x60 #define BMA2X2_COMP_TARGET_OFFSET_Z__REG BMA2X2_OFFSET_PARAMS_REG #define BMA2X2_FIFO_DATA_SELECT__POS 0 #define BMA2X2_FIFO_DATA_SELECT__LEN 2 #define BMA2X2_FIFO_DATA_SELECT__MSK 0x03 #define BMA2X2_FIFO_DATA_SELECT__REG BMA2X2_FIFO_MODE_REG #define BMA2X2_FIFO_TRIGGER_SOURCE__POS 2 #define BMA2X2_FIFO_TRIGGER_SOURCE__LEN 2 #define BMA2X2_FIFO_TRIGGER_SOURCE__MSK 0x0C #define BMA2X2_FIFO_TRIGGER_SOURCE__REG BMA2X2_FIFO_MODE_REG #define BMA2X2_FIFO_TRIGGER_ACTION__POS 4 #define BMA2X2_FIFO_TRIGGER_ACTION__LEN 2 #define BMA2X2_FIFO_TRIGGER_ACTION__MSK 0x30 #define BMA2X2_FIFO_TRIGGER_ACTION__REG BMA2X2_FIFO_MODE_REG #define BMA2X2_FIFO_MODE__POS 6 #define BMA2X2_FIFO_MODE__LEN 2 #define BMA2X2_FIFO_MODE__MSK 0xC0 #define BMA2X2_FIFO_MODE__REG BMA2X2_FIFO_MODE_REG #define BMA2X2_STATUS1 0 #define BMA2X2_STATUS2 1 #define BMA2X2_STATUS3 2 #define BMA2X2_STATUS4 3 #define BMA2X2_STATUS5 4 #define BMA2X2_RANGE_2G 3 #define BMA2X2_RANGE_4G 5 #define BMA2X2_RANGE_8G 8 #define BMA2X2_RANGE_16G 12 #define BMA2X2_BW_7_81HZ 0x08 #define BMA2X2_BW_15_63HZ 0x09 #define BMA2X2_BW_31_25HZ 0x0A #define BMA2X2_BW_62_50HZ 0x0B #define BMA2X2_BW_125HZ 0x0C #define BMA2X2_BW_250HZ 0x0D #define BMA2X2_BW_500HZ 0x0E #define BMA2X2_BW_1000HZ 0x0F #define BMA2X2_SLEEP_DUR_0_5MS 0x05 #define BMA2X2_SLEEP_DUR_1MS 0x06 #define BMA2X2_SLEEP_DUR_2MS 0x07 #define BMA2X2_SLEEP_DUR_4MS 0x08 #define BMA2X2_SLEEP_DUR_6MS 0x09 #define BMA2X2_SLEEP_DUR_10MS 0x0A #define BMA2X2_SLEEP_DUR_25MS 0x0B #define BMA2X2_SLEEP_DUR_50MS 0x0C #define BMA2X2_SLEEP_DUR_100MS 0x0D #define BMA2X2_SLEEP_DUR_500MS 0x0E #define BMA2X2_SLEEP_DUR_1S 0x0F #define BMA2X2_LATCH_DUR_NON_LATCH 0x00 #define BMA2X2_LATCH_DUR_250MS 0x01 #define BMA2X2_LATCH_DUR_500MS 0x02 #define BMA2X2_LATCH_DUR_1S 0x03 #define BMA2X2_LATCH_DUR_2S 0x04 #define BMA2X2_LATCH_DUR_4S 0x05 #define BMA2X2_LATCH_DUR_8S 0x06 #define BMA2X2_LATCH_DUR_LATCH 0x07 #define BMA2X2_LATCH_DUR_NON_LATCH1 0x08 #define BMA2X2_LATCH_DUR_250US 0x09 #define BMA2X2_LATCH_DUR_500US 0x0A #define BMA2X2_LATCH_DUR_1MS 0x0B #define BMA2X2_LATCH_DUR_12_5MS 0x0C #define BMA2X2_LATCH_DUR_25MS 0x0D #define BMA2X2_LATCH_DUR_50MS 0x0E #define BMA2X2_LATCH_DUR_LATCH1 0x0F #define BMA2X2_MODE_NORMAL 0 #define BMA2X2_MODE_LOWPOWER1 1 #define BMA2X2_MODE_SUSPEND 2 #define BMA2X2_MODE_DEEP_SUSPEND 3 #define BMA2X2_MODE_LOWPOWER2 4 #define BMA2X2_MODE_STANDBY 5 #define BMA2X2_X_AXIS 0 #define BMA2X2_Y_AXIS 1 #define BMA2X2_Z_AXIS 2 #define BMA2X2_Low_G_Interrupt 0 #define BMA2X2_High_G_X_Interrupt 1 #define BMA2X2_High_G_Y_Interrupt 2 #define BMA2X2_High_G_Z_Interrupt 3 #define BMA2X2_DATA_EN 4 #define BMA2X2_Slope_X_Interrupt 5 #define BMA2X2_Slope_Y_Interrupt 6 #define BMA2X2_Slope_Z_Interrupt 7 #define BMA2X2_Single_Tap_Interrupt 8 #define BMA2X2_Double_Tap_Interrupt 9 #define BMA2X2_Orient_Interrupt 10 #define BMA2X2_Flat_Interrupt 11 #define BMA2X2_FFULL_INTERRUPT 12 #define BMA2X2_FWM_INTERRUPT 13 #define BMA2X2_INT1_LOWG 0 #define BMA2X2_INT2_LOWG 1 #define BMA2X2_INT1_HIGHG 0 #define BMA2X2_INT2_HIGHG 1 #define BMA2X2_INT1_SLOPE 0 #define BMA2X2_INT2_SLOPE 1 #define BMA2X2_INT1_SLO_NO_MOT 0 #define BMA2X2_INT2_SLO_NO_MOT 1 #define BMA2X2_INT1_DTAP 0 #define BMA2X2_INT2_DTAP 1 #define BMA2X2_INT1_STAP 0 #define BMA2X2_INT2_STAP 1 #define BMA2X2_INT1_ORIENT 0 #define BMA2X2_INT2_ORIENT 1 #define BMA2X2_INT1_FLAT 0 #define BMA2X2_INT2_FLAT 1 #define BMA2X2_INT1_NDATA 0 #define BMA2X2_INT2_NDATA 1 #define BMA2X2_INT1_FWM 0 #define BMA2X2_INT2_FWM 1 #define BMA2X2_INT1_FFULL 0 #define BMA2X2_INT2_FFULL 1 #define BMA2X2_SRC_LOWG 0 #define BMA2X2_SRC_HIGHG 1 #define BMA2X2_SRC_SLOPE 2 #define BMA2X2_SRC_SLO_NO_MOT 3 #define BMA2X2_SRC_TAP 4 #define BMA2X2_SRC_DATA 5 #define BMA2X2_INT1_OUTPUT 0 #define BMA2X2_INT2_OUTPUT 1 #define BMA2X2_INT1_LEVEL 0 #define BMA2X2_INT2_LEVEL 1 #define BMA2X2_LOW_DURATION 0 #define BMA2X2_HIGH_DURATION 1 #define BMA2X2_SLOPE_DURATION 2 #define BMA2X2_SLO_NO_MOT_DURATION 3 #define BMA2X2_LOW_THRESHOLD 0 #define BMA2X2_HIGH_THRESHOLD 1 #define BMA2X2_SLOPE_THRESHOLD 2 #define BMA2X2_SLO_NO_MOT_THRESHOLD 3 #define BMA2X2_LOWG_HYST 0 #define BMA2X2_HIGHG_HYST 1 #define BMA2X2_ORIENT_THETA 0 #define BMA2X2_FLAT_THETA 1 #define BMA2X2_I2C_SELECT 0 #define BMA2X2_I2C_EN 1 #define BMA2X2_SLOW_COMP_X 0 #define BMA2X2_SLOW_COMP_Y 1 #define BMA2X2_SLOW_COMP_Z 2 #define BMA2X2_CUT_OFF 0 #define BMA2X2_OFFSET_TRIGGER_X 1 #define BMA2X2_OFFSET_TRIGGER_Y 2 #define BMA2X2_OFFSET_TRIGGER_Z 3 #define BMA2X2_GP0 0 #define BMA2X2_GP1 1 #define BMA2X2_SLO_NO_MOT_EN_X 0 #define BMA2X2_SLO_NO_MOT_EN_Y 1 #define BMA2X2_SLO_NO_MOT_EN_Z 2 #define BMA2X2_SLO_NO_MOT_EN_SEL 3 #define BMA2X2_WAKE_UP_DUR_20MS 0 #define BMA2X2_WAKE_UP_DUR_80MS 1 #define BMA2X2_WAKE_UP_DUR_320MS 2 #define BMA2X2_WAKE_UP_DUR_2560MS 3 #define BMA2X2_SELF_TEST0_ON 1 #define BMA2X2_SELF_TEST1_ON 2 #define BMA2X2_EE_W_OFF 0 #define BMA2X2_EE_W_ON 1 #define BMA2X2_LOW_TH_IN_G(gthres, range) ((256 * gthres) / range) #define BMA2X2_HIGH_TH_IN_G(gthres, range) ((256 * gthres) / range) #define BMA2X2_LOW_HY_IN_G(ghyst, range) ((32 * ghyst) / range) #define BMA2X2_HIGH_HY_IN_G(ghyst, range) ((32 * ghyst) / range) #define BMA2X2_SLOPE_TH_IN_G(gthres, range) ((128 * gthres) / range) #define BMA2X2_GET_BITSLICE(regvar, bitname)\ ((regvar & bitname##__MSK) >> bitname##__POS) #define BMA2X2_SET_BITSLICE(regvar, bitname, val)\ ((regvar & ~bitname##__MSK) | ((val< #include static struct sensor_config_info gsensor_info = { .input_type = GSENSOR_TYPE, }; static const struct bma2x2_type_map_t sensor_type_map[] = { {BMA255_CHIP_ID, BMA255_TYPE, "BMA255/254"}, {BMA355_CHIP_ID, BMA255_TYPE, "BMA355"}, {BMA250E_CHIP_ID, BMA250E_TYPE, "BMA250E"}, {BMA222E_CHIP_ID, BMA222E_TYPE, "BMA222E"}, {BMA280_CHIP_ID, BMA280_TYPE, "BMA280"}, }; /*! * Bst sensor common definition, * please give parameters in BSP file. */ struct bosch_sensor_specific { char *name; /* 0 to 7 */ int place; int irq; int (*irq_gpio_cfg)(void); }; /*! * we use a typedef to hide the detail, * because this type might be changed */ struct bosch_sensor_axis_remap { /* src means which source will be mapped to target x, y, z axis */ /* if an target OS axis is remapped from (-)x, * src is 0, sign_* is (-)1 */ /* if an target OS axis is remapped from (-)y, * src is 1, sign_* is (-)1 */ /* if an target OS axis is remapped from (-)z, * src is 2, sign_* is (-)1 */ int src_x:3; int src_y:3; int src_z:3; int sign_x:2; int sign_y:2; int sign_z:2; }; struct bosch_sensor_data { union { int16_t v[3]; struct { int16_t x; int16_t y; int16_t z; }; }; }; struct bma2x2acc { s16 x; s16 y; s16 z; }; struct bma2x2_data { struct i2c_client *bma2x2_client; atomic_t delay; atomic_t enable; atomic_t selftest_result; unsigned int chip_id; unsigned int fifo_count; unsigned char fifo_datasel; unsigned char mode; signed char sensor_type; struct input_dev *input; struct bst_dev *bst_acc; struct bma2x2acc value; struct mutex value_mutex; struct mutex enable_mutex; struct mutex mode_mutex; struct delayed_work work; struct workqueue_struct *workqueue; struct work_struct irq_work; #ifdef CONFIG_HAS_EARLYSUSPEND struct early_suspend early_suspend; #endif int IRQ; struct bosch_sensor_specific *bst_pd; int bma_mode_enabled; struct input_dev *dev_interrupt; #ifdef CONFIG_SIG_MOTION struct class *g_sensor_class; struct device *g_sensor_dev; /*struct bma250_platform_data *pdata;*/ atomic_t en_sig_motion; #endif #ifdef CONFIG_DOUBLE_TAP struct class *g_sensor_class_doubletap; struct device *g_sensor_dev_doubletap; atomic_t en_double_tap; unsigned char tap_times; struct mutex tap_mutex; struct timer_list tap_timer; int tap_time_period; #endif }; #ifdef CONFIG_HAS_EARLYSUSPEND static void bma2x2_early_suspend(struct early_suspend *h); static void bma2x2_late_resume(struct early_suspend *h); #endif static int bma2x2_set_mode(struct i2c_client *client, u8 mode, u8 enabled_mode); static int bma2x2_get_mode(struct i2c_client *client, u8 *mode); static int bma2x2_get_fifo_mode(struct i2c_client *client, u8 *fifo_mode); static int bma2x2_set_fifo_mode(struct i2c_client *client, u8 fifo_mode); static int bma2x2_normal_to_suspend(struct bma2x2_data *bma2x2, unsigned char data1, unsigned char data2); /*Remapping for BMA2X2*/ static const struct bosch_sensor_axis_remap bst_axis_remap_tab_dft[MAX_AXIS_REMAP_TAB_SZ] = { /* src_x src_y src_z sign_x sign_y sign_z */ { 0, 1, 2, 1, 1, 1 }, /* P0 */ { 1, 0, 2, 1, -1, 1 }, /* P1 */ { 0, 1, 2, -1, -1, 1 }, /* P2 */ { 1, 0, 2, -1, 1, 1 }, /* P3 */ { 0, 1, 2, -1, 1, -1 }, /* P4 */ { 1, 0, 2, -1, -1, -1 }, /* P5 */ { 0, 1, 2, 1, -1, -1 }, /* P6 */ { 1, 0, 2, 1, 1, -1 }, /* P7 */ }; static void bst_remap_sensor_data(struct bosch_sensor_data *data, const struct bosch_sensor_axis_remap *remap) { struct bosch_sensor_data tmp; tmp.x = data->v[remap->src_x] * remap->sign_x; tmp.y = data->v[remap->src_y] * remap->sign_y; tmp.z = data->v[remap->src_z] * remap->sign_z; memcpy(data, &tmp, sizeof(*data)); } static void bst_remap_sensor_data_dft_tab(struct bosch_sensor_data *data, int place) { /* sensor with place 0 needs not to be remapped */ if ((place <= 0) || (place >= MAX_AXIS_REMAP_TAB_SZ)) return; bst_remap_sensor_data(data, &bst_axis_remap_tab_dft[place]); } static void bma2x2_remap_sensor_data(struct bma2x2acc *val, struct bma2x2_data *client_data) { struct bosch_sensor_data bsd; int place; if ((NULL == client_data->bst_pd) || (BOSCH_SENSOR_PLACE_UNKNOWN == client_data->bst_pd->place)) place = BOSCH_SENSOR_PLACE_UNKNOWN; else place = client_data->bst_pd->place; #ifdef CONFIG_SENSORS_BMI058 /*x,y need to be invesed becase of HW Register for BMI058*/ bsd.y = val->x; bsd.x = val->y; bsd.z = val->z; #else bsd.x = val->x; bsd.y = val->y; bsd.z = val->z; #endif bst_remap_sensor_data_dft_tab(&bsd, place); val->x = bsd.x; val->y = bsd.y; val->z = bsd.z; } static int bma2x2_smbus_read_byte(struct i2c_client *client, unsigned char reg_addr, unsigned char *data) { s32 dummy; dummy = i2c_smbus_read_byte_data(client, reg_addr); if (dummy < 0) return -1; *data = dummy & 0x000000ff; return 0; } static int bma2x2_smbus_write_byte(struct i2c_client *client, unsigned char reg_addr, unsigned char *data) { s32 dummy; dummy = i2c_smbus_write_byte_data(client, reg_addr, *data); if (dummy < 0) return -1; udelay(2); return 0; } static int bma2x2_smbus_read_byte_block(struct i2c_client *client, unsigned char reg_addr, unsigned char *data, unsigned char len) { s32 dummy; dummy = i2c_smbus_read_i2c_block_data(client, reg_addr, len, data); if (dummy < 0) return -1; return 0; } static int bma_i2c_burst_read(struct i2c_client *client, u8 reg_addr, u8 *data, u16 len) { int retry; struct i2c_msg msg[] = { { .addr = client->addr, .flags = 0, .len = 1, .buf = ®_addr, }, { .addr = client->addr, .flags = I2C_M_RD, .len = len, .buf = data, }, }; for (retry = 0; retry < BMA_MAX_RETRY_I2C_XFER; retry++) { if (i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)) > 0) break; else mdelay(1); } if (BMA_MAX_RETRY_I2C_XFER <= retry) { printk(KERN_INFO "I2C xfer error"); return -EIO; } return 0; } static int bma2x2_check_chip_id(struct i2c_client *client, struct bma2x2_data *data) { int i = 0; int err = 0; unsigned char chip_id; unsigned char read_count = 0; unsigned char bma2x2_sensor_type_count = 0; bma2x2_sensor_type_count = sizeof(sensor_type_map) / sizeof(struct bma2x2_type_map_t); while (read_count++ < CHECK_CHIP_ID_TIME_MAX) { if (bma2x2_smbus_read_byte(client, BMA2X2_CHIP_ID_REG, &chip_id) < 0) { dev_err(&client->dev, "Bosch Sensortec Device not found" "i2c bus read error, read chip_id:%d\n", chip_id); continue; } else { for (i = 0; i < bma2x2_sensor_type_count; i++) { if (sensor_type_map[i].chip_id == chip_id) { data->sensor_type = sensor_type_map[i].sensor_type; data->chip_id = chip_id; dev_notice(&client->dev, "Bosch Sensortec Device detected," " HW IC name: %s\n", sensor_type_map[i].sensor_name); return err; } } if (i < bma2x2_sensor_type_count) return err; else { if (read_count == CHECK_CHIP_ID_TIME_MAX) { dev_err(&client->dev, "Failed!Bosch Sensortec Device" " not found, mismatch chip_id:%d\n", chip_id); err = -ENODEV; return err; } } mdelay(1); } } return err; } #ifdef CONFIG_BMA_ENABLE_NEWDATA_INT static int bma2x2_set_newdata(struct i2c_client *client, unsigned char channel, unsigned char int_newdata) { unsigned char data; int comres = 0; switch (channel) { case BMA2X2_INT1_NDATA: comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_INT1_PAD_NEWDATA__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT1_PAD_NEWDATA, int_newdata); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_INT1_PAD_NEWDATA__REG, &data); break; case BMA2X2_INT2_NDATA: comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_INT2_PAD_NEWDATA__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT2_PAD_NEWDATA, int_newdata); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_INT2_PAD_NEWDATA__REG, &data); break; default: comres = -1; break; } return comres; } #endif /* CONFIG_BMA_ENABLE_NEWDATA_INT */ #ifdef BMA2X2_ENABLE_INT1 static int bma2x2_set_int1_pad_sel(struct i2c_client *client, unsigned char int1sel) { int comres = 0; unsigned char data; unsigned char state; state = 0x01; switch (int1sel) { case 0: comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_INT1_PAD_LOWG__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT1_PAD_LOWG, state); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_INT1_PAD_LOWG__REG, &data); break; case 1: comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_INT1_PAD_HIGHG__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT1_PAD_HIGHG, state); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_INT1_PAD_HIGHG__REG, &data); break; case 2: comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_INT1_PAD_SLOPE__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT1_PAD_SLOPE, state); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_INT1_PAD_SLOPE__REG, &data); break; case 3: comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_INT1_PAD_DB_TAP__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT1_PAD_DB_TAP, state); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_INT1_PAD_DB_TAP__REG, &data); break; case 4: comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_INT1_PAD_SNG_TAP__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT1_PAD_SNG_TAP, state); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_INT1_PAD_SNG_TAP__REG, &data); break; case 5: comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_INT1_PAD_ORIENT__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT1_PAD_ORIENT, state); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_INT1_PAD_ORIENT__REG, &data); break; case 6: comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_INT1_PAD_FLAT__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT1_PAD_FLAT, state); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_INT1_PAD_FLAT__REG, &data); break; case 7: comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_INT1_PAD_SLO_NO_MOT__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT1_PAD_SLO_NO_MOT, state); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_INT1_PAD_SLO_NO_MOT__REG, &data); break; default: break; } return comres; } #endif /* BMA2X2_ENABLE_INT1 */ #ifdef BMA2X2_ENABLE_INT2 static int bma2x2_set_int2_pad_sel(struct i2c_client *client, unsigned char int2sel) { int comres = 0; unsigned char data; unsigned char state; state = 0x01; switch (int2sel) { case 0: comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_INT2_PAD_LOWG__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT2_PAD_LOWG, state); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_INT2_PAD_LOWG__REG, &data); break; case 1: comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_INT2_PAD_HIGHG__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT2_PAD_HIGHG, state); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_INT2_PAD_HIGHG__REG, &data); break; case 2: comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_INT2_PAD_SLOPE__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT2_PAD_SLOPE, state); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_INT2_PAD_SLOPE__REG, &data); break; case 3: comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_INT2_PAD_DB_TAP__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT2_PAD_DB_TAP, state); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_INT2_PAD_DB_TAP__REG, &data); break; case 4: comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_INT2_PAD_SNG_TAP__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT2_PAD_SNG_TAP, state); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_INT2_PAD_SNG_TAP__REG, &data); break; case 5: comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_INT2_PAD_ORIENT__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT2_PAD_ORIENT, state); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_INT2_PAD_ORIENT__REG, &data); break; case 6: comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_INT2_PAD_FLAT__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT2_PAD_FLAT, state); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_INT2_PAD_FLAT__REG, &data); break; case 7: comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_INT2_PAD_SLO_NO_MOT__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT2_PAD_SLO_NO_MOT, state); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_INT2_PAD_SLO_NO_MOT__REG, &data); break; default: break; } return comres; } #endif /* BMA2X2_ENABLE_INT2 */ static int bma2x2_set_Int_Enable(struct i2c_client *client, unsigned char InterruptType , unsigned char value) { int comres = 0; unsigned char data1, data2; if ((11 < InterruptType) && (InterruptType < 16)) { switch (InterruptType) { case 12: /* slow/no motion X Interrupt */ comres = bma2x2_smbus_read_byte(client, BMA2X2_INT_SLO_NO_MOT_EN_X_INT__REG, &data1); data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_INT_SLO_NO_MOT_EN_X_INT, value); comres = bma2x2_smbus_write_byte(client, BMA2X2_INT_SLO_NO_MOT_EN_X_INT__REG, &data1); break; case 13: /* slow/no motion Y Interrupt */ comres = bma2x2_smbus_read_byte(client, BMA2X2_INT_SLO_NO_MOT_EN_Y_INT__REG, &data1); data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_INT_SLO_NO_MOT_EN_Y_INT, value); comres = bma2x2_smbus_write_byte(client, BMA2X2_INT_SLO_NO_MOT_EN_Y_INT__REG, &data1); break; case 14: /* slow/no motion Z Interrupt */ comres = bma2x2_smbus_read_byte(client, BMA2X2_INT_SLO_NO_MOT_EN_Z_INT__REG, &data1); data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_INT_SLO_NO_MOT_EN_Z_INT, value); comres = bma2x2_smbus_write_byte(client, BMA2X2_INT_SLO_NO_MOT_EN_Z_INT__REG, &data1); break; case 15: /* slow / no motion Interrupt select */ comres = bma2x2_smbus_read_byte(client, BMA2X2_INT_SLO_NO_MOT_EN_SEL_INT__REG, &data1); data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_INT_SLO_NO_MOT_EN_SEL_INT, value); comres = bma2x2_smbus_write_byte(client, BMA2X2_INT_SLO_NO_MOT_EN_SEL_INT__REG, &data1); } return comres; } comres = bma2x2_smbus_read_byte(client, BMA2X2_INT_ENABLE1_REG, &data1); comres = bma2x2_smbus_read_byte(client, BMA2X2_INT_ENABLE2_REG, &data2); value = value & 1; switch (InterruptType) { case 0: /* Low G Interrupt */ data2 = BMA2X2_SET_BITSLICE(data2, BMA2X2_EN_LOWG_INT, value); break; case 1: /* High G X Interrupt */ data2 = BMA2X2_SET_BITSLICE(data2, BMA2X2_EN_HIGHG_X_INT, value); break; case 2: /* High G Y Interrupt */ data2 = BMA2X2_SET_BITSLICE(data2, BMA2X2_EN_HIGHG_Y_INT, value); break; case 3: /* High G Z Interrupt */ data2 = BMA2X2_SET_BITSLICE(data2, BMA2X2_EN_HIGHG_Z_INT, value); break; case 4: /* New Data Interrupt */ data2 = BMA2X2_SET_BITSLICE(data2, BMA2X2_EN_NEW_DATA_INT, value); break; case 5: /* Slope X Interrupt */ data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_EN_SLOPE_X_INT, value); break; case 6: /* Slope Y Interrupt */ data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_EN_SLOPE_Y_INT, value); break; case 7: /* Slope Z Interrupt */ data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_EN_SLOPE_Z_INT, value); break; case 8: /* Single Tap Interrupt */ data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_EN_SINGLE_TAP_INT, value); break; case 9: /* Double Tap Interrupt */ data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_EN_DOUBLE_TAP_INT, value); break; case 10: /* Orient Interrupt */ data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_EN_ORIENT_INT, value); break; case 11: /* Flat Interrupt */ data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_EN_FLAT_INT, value); break; default: break; } comres = bma2x2_smbus_write_byte(client, BMA2X2_INT_ENABLE1_REG, &data1); comres = bma2x2_smbus_write_byte(client, BMA2X2_INT_ENABLE2_REG, &data2); return comres; } #if defined(BMA2X2_ENABLE_INT1) || defined(BMA2X2_ENABLE_INT2) static int bma2x2_get_interruptstatus1(struct i2c_client *client, unsigned char *intstatus) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS1_REG, &data); *intstatus = data; return comres; } #ifdef CONFIG_BMA_ENABLE_NEWDATA_INT static int bma2x2_get_interruptstatus2(struct i2c_client *client, unsigned char *intstatus) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS2_REG, &data); *intstatus = data; return comres; } #endif static int bma2x2_get_HIGH_first(struct i2c_client *client, unsigned char param, unsigned char *intstatus) { int comres = 0; unsigned char data; switch (param) { case 0: comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS_ORIENT_HIGH_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_HIGHG_FIRST_X); *intstatus = data; break; case 1: comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS_ORIENT_HIGH_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_HIGHG_FIRST_Y); *intstatus = data; break; case 2: comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS_ORIENT_HIGH_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_HIGHG_FIRST_Z); *intstatus = data; break; default: break; } return comres; } static int bma2x2_get_HIGH_sign(struct i2c_client *client, unsigned char *intstatus) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS_ORIENT_HIGH_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_HIGHG_SIGN_S); *intstatus = data; return comres; } #ifndef CONFIG_SIG_MOTION static int bma2x2_get_slope_first(struct i2c_client *client, unsigned char param, unsigned char *intstatus) { int comres = 0; unsigned char data; switch (param) { case 0: comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS_TAP_SLOPE_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_SLOPE_FIRST_X); *intstatus = data; break; case 1: comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS_TAP_SLOPE_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_SLOPE_FIRST_Y); *intstatus = data; break; case 2: comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS_TAP_SLOPE_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_SLOPE_FIRST_Z); *intstatus = data; break; default: break; } return comres; } static int bma2x2_get_slope_sign(struct i2c_client *client, unsigned char *intstatus) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS_TAP_SLOPE_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_SLOPE_SIGN_S); *intstatus = data; return comres; } #endif static int bma2x2_get_orient_status(struct i2c_client *client, unsigned char *intstatus) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS_ORIENT_HIGH_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_ORIENT_S); *intstatus = data; return comres; } static int bma2x2_get_orient_flat_status(struct i2c_client *client, unsigned char *intstatus) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS_ORIENT_HIGH_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_FLAT_S); *intstatus = data; return comres; } #endif /* defined(BMA2X2_ENABLE_INT1)||defined(BMA2X2_ENABLE_INT2) */ static int bma2x2_set_Int_Mode(struct i2c_client *client, unsigned char Mode) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_INT_MODE_SEL__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_INT_MODE_SEL, Mode); comres = bma2x2_smbus_write_byte(client, BMA2X2_INT_MODE_SEL__REG, &data); return comres; } static int bma2x2_get_Int_Mode(struct i2c_client *client, unsigned char *Mode) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_INT_MODE_SEL__REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_INT_MODE_SEL); *Mode = data; return comres; } static int bma2x2_set_slope_duration(struct i2c_client *client, unsigned char duration) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_SLOPE_DUR__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_SLOPE_DUR, duration); comres = bma2x2_smbus_write_byte(client, BMA2X2_SLOPE_DUR__REG, &data); return comres; } static int bma2x2_get_slope_duration(struct i2c_client *client, unsigned char *status) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_SLOPE_DURN_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_SLOPE_DUR); *status = data; return comres; } static int bma2x2_set_slope_no_mot_duration(struct i2c_client *client, unsigned char duration) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2x2_SLO_NO_MOT_DUR__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2x2_SLO_NO_MOT_DUR, duration); comres = bma2x2_smbus_write_byte(client, BMA2x2_SLO_NO_MOT_DUR__REG, &data); return comres; } static int bma2x2_get_slope_no_mot_duration(struct i2c_client *client, unsigned char *status) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2x2_SLO_NO_MOT_DUR__REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2x2_SLO_NO_MOT_DUR); *status = data; return comres; } static int bma2x2_set_slope_threshold(struct i2c_client *client, unsigned char threshold) { int comres = 0; unsigned char data; data = threshold; comres = bma2x2_smbus_write_byte(client, BMA2X2_SLOPE_THRES__REG, &data); return comres; } static int bma2x2_get_slope_threshold(struct i2c_client *client, unsigned char *status) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_SLOPE_THRES_REG, &data); *status = data; return comres; } static int bma2x2_set_slope_no_mot_threshold(struct i2c_client *client, unsigned char threshold) { int comres = 0; unsigned char data; data = threshold; comres = bma2x2_smbus_write_byte(client, BMA2X2_SLO_NO_MOT_THRES_REG, &data); return comres; } static int bma2x2_get_slope_no_mot_threshold(struct i2c_client *client, unsigned char *status) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_SLO_NO_MOT_THRES_REG, &data); *status = data; return comres; } static int bma2x2_set_low_g_duration(struct i2c_client *client, unsigned char duration) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_LOWG_DUR__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_LOWG_DUR, duration); comres = bma2x2_smbus_write_byte(client, BMA2X2_LOWG_DUR__REG, &data); return comres; } static int bma2x2_get_low_g_duration(struct i2c_client *client, unsigned char *status) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_LOW_DURN_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_LOWG_DUR); *status = data; return comres; } static int bma2x2_set_low_g_threshold(struct i2c_client *client, unsigned char threshold) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_LOWG_THRES__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_LOWG_THRES, threshold); comres = bma2x2_smbus_write_byte(client, BMA2X2_LOWG_THRES__REG, &data); return comres; } static int bma2x2_get_low_g_threshold(struct i2c_client *client, unsigned char *status) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_LOW_THRES_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_LOWG_THRES); *status = data; return comres; } static int bma2x2_set_high_g_duration(struct i2c_client *client, unsigned char duration) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_HIGHG_DUR__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_HIGHG_DUR, duration); comres = bma2x2_smbus_write_byte(client, BMA2X2_HIGHG_DUR__REG, &data); return comres; } static int bma2x2_get_high_g_duration(struct i2c_client *client, unsigned char *status) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_HIGH_DURN_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_HIGHG_DUR); *status = data; return comres; } static int bma2x2_set_high_g_threshold(struct i2c_client *client, unsigned char threshold) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_HIGHG_THRES__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_HIGHG_THRES, threshold); comres = bma2x2_smbus_write_byte(client, BMA2X2_HIGHG_THRES__REG, &data); return comres; } static int bma2x2_get_high_g_threshold(struct i2c_client *client, unsigned char *status) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_HIGH_THRES_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_HIGHG_THRES); *status = data; return comres; } static int bma2x2_set_tap_duration(struct i2c_client *client, unsigned char duration) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_DUR__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_TAP_DUR, duration); comres = bma2x2_smbus_write_byte(client, BMA2X2_TAP_DUR__REG, &data); return comres; } static int bma2x2_get_tap_duration(struct i2c_client *client, unsigned char *status) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_PARAM_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_TAP_DUR); *status = data; return comres; } static int bma2x2_set_tap_shock(struct i2c_client *client, unsigned char setval) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_SHOCK_DURN__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_TAP_SHOCK_DURN, setval); comres = bma2x2_smbus_write_byte(client, BMA2X2_TAP_SHOCK_DURN__REG, &data); return comres; } static int bma2x2_get_tap_shock(struct i2c_client *client, unsigned char *status) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_PARAM_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_TAP_SHOCK_DURN); *status = data; return comres; } static int bma2x2_set_tap_quiet(struct i2c_client *client, unsigned char duration) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_QUIET_DURN__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_TAP_QUIET_DURN, duration); comres = bma2x2_smbus_write_byte(client, BMA2X2_TAP_QUIET_DURN__REG, &data); return comres; } static int bma2x2_get_tap_quiet(struct i2c_client *client, unsigned char *status) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_PARAM_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_TAP_QUIET_DURN); *status = data; return comres; } static int bma2x2_set_tap_threshold(struct i2c_client *client, unsigned char threshold) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_THRES__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_TAP_THRES, threshold); comres = bma2x2_smbus_write_byte(client, BMA2X2_TAP_THRES__REG, &data); return comres; } static int bma2x2_get_tap_threshold(struct i2c_client *client, unsigned char *status) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_THRES_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_TAP_THRES); *status = data; return comres; } static int bma2x2_set_tap_samp(struct i2c_client *client, unsigned char samp) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_SAMPLES__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_TAP_SAMPLES, samp); comres = bma2x2_smbus_write_byte(client, BMA2X2_TAP_SAMPLES__REG, &data); return comres; } static int bma2x2_get_tap_samp(struct i2c_client *client, unsigned char *status) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_THRES_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_TAP_SAMPLES); *status = data; return comres; } static int bma2x2_set_orient_mode(struct i2c_client *client, unsigned char mode) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_ORIENT_MODE__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_ORIENT_MODE, mode); comres = bma2x2_smbus_write_byte(client, BMA2X2_ORIENT_MODE__REG, &data); return comres; } static int bma2x2_get_orient_mode(struct i2c_client *client, unsigned char *status) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_ORIENT_PARAM_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_ORIENT_MODE); *status = data; return comres; } static int bma2x2_set_orient_blocking(struct i2c_client *client, unsigned char samp) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_ORIENT_BLOCK__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_ORIENT_BLOCK, samp); comres = bma2x2_smbus_write_byte(client, BMA2X2_ORIENT_BLOCK__REG, &data); return comres; } static int bma2x2_get_orient_blocking(struct i2c_client *client, unsigned char *status) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_ORIENT_PARAM_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_ORIENT_BLOCK); *status = data; return comres; } static int bma2x2_set_orient_hyst(struct i2c_client *client, unsigned char orienthyst) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_ORIENT_HYST__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_ORIENT_HYST, orienthyst); comres = bma2x2_smbus_write_byte(client, BMA2X2_ORIENT_HYST__REG, &data); return comres; } static int bma2x2_get_orient_hyst(struct i2c_client *client, unsigned char *status) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_ORIENT_PARAM_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_ORIENT_HYST); *status = data; return comres; } static int bma2x2_set_theta_blocking(struct i2c_client *client, unsigned char thetablk) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_THETA_BLOCK__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_THETA_BLOCK, thetablk); comres = bma2x2_smbus_write_byte(client, BMA2X2_THETA_BLOCK__REG, &data); return comres; } static int bma2x2_get_theta_blocking(struct i2c_client *client, unsigned char *status) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_THETA_BLOCK_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_THETA_BLOCK); *status = data; return comres; } static int bma2x2_set_theta_flat(struct i2c_client *client, unsigned char thetaflat) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_THETA_FLAT__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_THETA_FLAT, thetaflat); comres = bma2x2_smbus_write_byte(client, BMA2X2_THETA_FLAT__REG, &data); return comres; } static int bma2x2_get_theta_flat(struct i2c_client *client, unsigned char *status) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_THETA_FLAT_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_THETA_FLAT); *status = data; return comres; } static int bma2x2_set_flat_hold_time(struct i2c_client *client, unsigned char holdtime) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_FLAT_HOLD_TIME__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_FLAT_HOLD_TIME, holdtime); comres = bma2x2_smbus_write_byte(client, BMA2X2_FLAT_HOLD_TIME__REG, &data); return comres; } static int bma2x2_get_flat_hold_time(struct i2c_client *client, unsigned char *holdtime) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_FLAT_HOLD_TIME_REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_FLAT_HOLD_TIME); *holdtime = data; return comres; } /*! * brief: bma2x2 switch from normal to suspend mode * @param[i] bma2x2 * @param[i] data1, write to PMU_LPW * @param[i] data2, write to PMU_LOW_NOSIE * * @return zero success, none-zero failed */ static int bma2x2_normal_to_suspend(struct bma2x2_data *bma2x2, unsigned char data1, unsigned char data2) { unsigned char current_fifo_mode; unsigned char current_op_mode; if (bma2x2 == NULL) return -1; /* get current op mode from mode register */ if (bma2x2_get_mode(bma2x2->bma2x2_client, ¤t_op_mode) < 0) return -1; /* only aimed at operatiom mode chang from normal/lpw1 mode * to suspend state. */ if (current_op_mode == BMA2X2_MODE_NORMAL || current_op_mode == BMA2X2_MODE_LOWPOWER1) { /* get current fifo mode from fifo config register */ if (bma2x2_get_fifo_mode(bma2x2->bma2x2_client, ¤t_fifo_mode) < 0) return -1; else { bma2x2_smbus_write_byte(bma2x2->bma2x2_client, BMA2X2_LOW_NOISE_CTRL_REG, &data2); bma2x2_smbus_write_byte(bma2x2->bma2x2_client, BMA2X2_MODE_CTRL_REG, &data1); bma2x2_smbus_write_byte(bma2x2->bma2x2_client, BMA2X2_FIFO_MODE__REG, ¤t_fifo_mode); mdelay(3); return 0; } } else { bma2x2_smbus_write_byte(bma2x2->bma2x2_client, BMA2X2_LOW_NOISE_CTRL_REG, &data2); bma2x2_smbus_write_byte(bma2x2->bma2x2_client, BMA2X2_MODE_CTRL_REG, &data1); mdelay(3); return 0; } } static int bma2x2_set_mode(struct i2c_client *client, unsigned char mode, unsigned char enabled_mode) { int comres = 0; unsigned char data1, data2; int ret = 0; struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); mutex_lock(&bma2x2->mode_mutex); if (BMA2X2_MODE_SUSPEND == mode) { if (enabled_mode != BMA_ENABLED_ALL) { if ((bma2x2->bma_mode_enabled & (1<mode_mutex); return 0; } else { bma2x2->bma_mode_enabled &= ~(1<bma_mode_enabled = 0; } } else { if ((bma2x2->bma_mode_enabled & (1<mode_mutex); return 0; } else { bma2x2->bma_mode_enabled |= (1<mode_mutex); if (mode < 6) { comres = bma2x2_smbus_read_byte(client, BMA2X2_MODE_CTRL_REG, &data1); comres = bma2x2_smbus_read_byte(client, BMA2X2_LOW_NOISE_CTRL_REG, &data2); switch (mode) { case BMA2X2_MODE_NORMAL: data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_MODE_CTRL, 0); data2 = BMA2X2_SET_BITSLICE(data2, BMA2X2_LOW_POWER_MODE, 0); bma2x2_smbus_write_byte(client, BMA2X2_MODE_CTRL_REG, &data1); mdelay(3); bma2x2_smbus_write_byte(client, BMA2X2_LOW_NOISE_CTRL_REG, &data2); break; case BMA2X2_MODE_LOWPOWER1: data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_MODE_CTRL, 2); data2 = BMA2X2_SET_BITSLICE(data2, BMA2X2_LOW_POWER_MODE, 0); bma2x2_smbus_write_byte(client, BMA2X2_MODE_CTRL_REG, &data1); mdelay(3); bma2x2_smbus_write_byte(client, BMA2X2_LOW_NOISE_CTRL_REG, &data2); break; case BMA2X2_MODE_SUSPEND: data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_MODE_CTRL, 4); data2 = BMA2X2_SET_BITSLICE(data2, BMA2X2_LOW_POWER_MODE, 0); /*aimed at anomaly resolution when switch to suspend*/ ret = bma2x2_normal_to_suspend(bma2x2, data1, data2); if (ret < 0) printk(KERN_ERR "Error switching to suspend"); break; case BMA2X2_MODE_DEEP_SUSPEND: data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_MODE_CTRL, 1); data2 = BMA2X2_SET_BITSLICE(data2, BMA2X2_LOW_POWER_MODE, 1); bma2x2_smbus_write_byte(client, BMA2X2_MODE_CTRL_REG, &data1); mdelay(3); bma2x2_smbus_write_byte(client, BMA2X2_LOW_NOISE_CTRL_REG, &data2); break; case BMA2X2_MODE_LOWPOWER2: data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_MODE_CTRL, 2); data2 = BMA2X2_SET_BITSLICE(data2, BMA2X2_LOW_POWER_MODE, 1); bma2x2_smbus_write_byte(client, BMA2X2_MODE_CTRL_REG, &data1); mdelay(3); bma2x2_smbus_write_byte(client, BMA2X2_LOW_NOISE_CTRL_REG, &data2); break; case BMA2X2_MODE_STANDBY: data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_MODE_CTRL, 4); data2 = BMA2X2_SET_BITSLICE(data2, BMA2X2_LOW_POWER_MODE, 1); bma2x2_smbus_write_byte(client, BMA2X2_LOW_NOISE_CTRL_REG, &data2); mdelay(3); bma2x2_smbus_write_byte(client, BMA2X2_MODE_CTRL_REG, &data1); break; } } else { comres = -1; } return comres; } static int bma2x2_get_mode(struct i2c_client *client, unsigned char *mode) { int comres = 0; unsigned char data1, data2; comres = bma2x2_smbus_read_byte(client, BMA2X2_MODE_CTRL_REG, &data1); comres = bma2x2_smbus_read_byte(client, BMA2X2_LOW_NOISE_CTRL_REG, &data2); data1 = (data1 & 0xE0) >> 5; data2 = (data2 & 0x40) >> 6; if ((data1 == 0x00) && (data2 == 0x00)) { *mode = BMA2X2_MODE_NORMAL; } else { if ((data1 == 0x02) && (data2 == 0x00)) { *mode = BMA2X2_MODE_LOWPOWER1; } else { if ((data1 == 0x04 || data1 == 0x06) && (data2 == 0x00)) { *mode = BMA2X2_MODE_SUSPEND; } else { if (((data1 & 0x01) == 0x01)) { *mode = BMA2X2_MODE_DEEP_SUSPEND; } else { if ((data1 == 0x02) && (data2 == 0x01)) { *mode = BMA2X2_MODE_LOWPOWER2; } else { if ((data1 == 0x04) && (data2 == 0x01)) { *mode = BMA2X2_MODE_STANDBY; } else { *mode = BMA2X2_MODE_DEEP_SUSPEND; } } } } } } return comres; } static int bma2x2_set_range(struct i2c_client *client, unsigned char Range) { int comres = 0; unsigned char data1; if ((Range == 3) || (Range == 5) || (Range == 8) || (Range == 12)) { comres = bma2x2_smbus_read_byte(client, BMA2X2_RANGE_SEL_REG, &data1); switch (Range) { case BMA2X2_RANGE_2G: data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_RANGE_SEL, 3); break; case BMA2X2_RANGE_4G: data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_RANGE_SEL, 5); break; case BMA2X2_RANGE_8G: data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_RANGE_SEL, 8); break; case BMA2X2_RANGE_16G: data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_RANGE_SEL, 12); break; default: break; } comres += bma2x2_smbus_write_byte(client, BMA2X2_RANGE_SEL_REG, &data1); } else { comres = -1; } return comres; } static int bma2x2_get_range(struct i2c_client *client, unsigned char *Range) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_RANGE_SEL__REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_RANGE_SEL); *Range = data; return comres; } static int bma2x2_set_bandwidth(struct i2c_client *client, unsigned char BW) { int comres = 0; unsigned char data; int Bandwidth = 0; if (BW > 7 && BW < 16) { switch (BW) { case BMA2X2_BW_7_81HZ: Bandwidth = BMA2X2_BW_7_81HZ; /* 7.81 Hz 64000 uS */ break; case BMA2X2_BW_15_63HZ: Bandwidth = BMA2X2_BW_15_63HZ; /* 15.63 Hz 32000 uS */ break; case BMA2X2_BW_31_25HZ: Bandwidth = BMA2X2_BW_31_25HZ; /* 31.25 Hz 16000 uS */ break; case BMA2X2_BW_62_50HZ: Bandwidth = BMA2X2_BW_62_50HZ; /* 62.50 Hz 8000 uS */ break; case BMA2X2_BW_125HZ: Bandwidth = BMA2X2_BW_125HZ; /* 125 Hz 4000 uS */ break; case BMA2X2_BW_250HZ: Bandwidth = BMA2X2_BW_250HZ; /* 250 Hz 2000 uS */ break; case BMA2X2_BW_500HZ: Bandwidth = BMA2X2_BW_500HZ; /* 500 Hz 1000 uS */ break; case BMA2X2_BW_1000HZ: Bandwidth = BMA2X2_BW_1000HZ; /* 1000 Hz 500 uS */ break; default: break; } comres = bma2x2_smbus_read_byte(client, BMA2X2_BANDWIDTH__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_BANDWIDTH, Bandwidth); comres += bma2x2_smbus_write_byte(client, BMA2X2_BANDWIDTH__REG, &data); } else { comres = -1; } return comres; } static int bma2x2_get_bandwidth(struct i2c_client *client, unsigned char *BW) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_BANDWIDTH__REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_BANDWIDTH); *BW = data; return comres; } int bma2x2_get_sleep_duration(struct i2c_client *client, unsigned char *sleep_dur) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_SLEEP_DUR__REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_SLEEP_DUR); *sleep_dur = data; return comres; } int bma2x2_set_sleep_duration(struct i2c_client *client, unsigned char sleep_dur) { int comres = 0; unsigned char data; int sleep_duration = 0; if (sleep_dur > 4 && sleep_dur < 16) { switch (sleep_dur) { case BMA2X2_SLEEP_DUR_0_5MS: sleep_duration = BMA2X2_SLEEP_DUR_0_5MS; /* 0.5 MS */ break; case BMA2X2_SLEEP_DUR_1MS: sleep_duration = BMA2X2_SLEEP_DUR_1MS; /* 1 MS */ break; case BMA2X2_SLEEP_DUR_2MS: sleep_duration = BMA2X2_SLEEP_DUR_2MS; /* 2 MS */ break; case BMA2X2_SLEEP_DUR_4MS: sleep_duration = BMA2X2_SLEEP_DUR_4MS; /* 4 MS */ break; case BMA2X2_SLEEP_DUR_6MS: sleep_duration = BMA2X2_SLEEP_DUR_6MS; /* 6 MS */ break; case BMA2X2_SLEEP_DUR_10MS: sleep_duration = BMA2X2_SLEEP_DUR_10MS; /* 10 MS */ break; case BMA2X2_SLEEP_DUR_25MS: sleep_duration = BMA2X2_SLEEP_DUR_25MS; /* 25 MS */ break; case BMA2X2_SLEEP_DUR_50MS: sleep_duration = BMA2X2_SLEEP_DUR_50MS; /* 50 MS */ break; case BMA2X2_SLEEP_DUR_100MS: sleep_duration = BMA2X2_SLEEP_DUR_100MS; /* 100 MS */ break; case BMA2X2_SLEEP_DUR_500MS: sleep_duration = BMA2X2_SLEEP_DUR_500MS; /* 500 MS */ break; case BMA2X2_SLEEP_DUR_1S: sleep_duration = BMA2X2_SLEEP_DUR_1S; /* 1 SECS */ break; default: break; } comres = bma2x2_smbus_read_byte(client, BMA2X2_SLEEP_DUR__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_SLEEP_DUR, sleep_duration); comres = bma2x2_smbus_write_byte(client, BMA2X2_SLEEP_DUR__REG, &data); } else { comres = -1; } return comres; } static int bma2x2_get_fifo_mode(struct i2c_client *client, unsigned char *fifo_mode) { int comres; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_FIFO_MODE__REG, &data); *fifo_mode = BMA2X2_GET_BITSLICE(data, BMA2X2_FIFO_MODE); return comres; } static int bma2x2_set_fifo_mode(struct i2c_client *client, unsigned char fifo_mode) { unsigned char data; int comres = 0; if (fifo_mode < 4) { comres = bma2x2_smbus_read_byte(client, BMA2X2_FIFO_MODE__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_FIFO_MODE, fifo_mode); comres = bma2x2_smbus_write_byte(client, BMA2X2_FIFO_MODE__REG, &data); } else { comres = -1; } return comres; } static int bma2x2_get_fifo_trig(struct i2c_client *client, unsigned char *fifo_trig) { int comres; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_FIFO_TRIGGER_ACTION__REG, &data); *fifo_trig = BMA2X2_GET_BITSLICE(data, BMA2X2_FIFO_TRIGGER_ACTION); return comres; } static int bma2x2_set_fifo_trig(struct i2c_client *client, unsigned char fifo_trig) { unsigned char data; int comres = 0; if (fifo_trig < 4) { comres = bma2x2_smbus_read_byte(client, BMA2X2_FIFO_TRIGGER_ACTION__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_FIFO_TRIGGER_ACTION, fifo_trig); comres = bma2x2_smbus_write_byte(client, BMA2X2_FIFO_TRIGGER_ACTION__REG, &data); } else { comres = -1; } return comres; } static int bma2x2_get_fifo_trig_src(struct i2c_client *client, unsigned char *trig_src) { int comres; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_FIFO_TRIGGER_SOURCE__REG, &data); *trig_src = BMA2X2_GET_BITSLICE(data, BMA2X2_FIFO_TRIGGER_SOURCE); return comres; } static int bma2x2_set_fifo_trig_src(struct i2c_client *client, unsigned char trig_src) { unsigned char data; int comres = 0; if (trig_src < 4) { comres = bma2x2_smbus_read_byte(client, BMA2X2_FIFO_TRIGGER_SOURCE__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_FIFO_TRIGGER_SOURCE, trig_src); comres = bma2x2_smbus_write_byte(client, BMA2X2_FIFO_TRIGGER_SOURCE__REG, &data); } else { comres = -1; } return comres; } static int bma2x2_get_fifo_framecount(struct i2c_client *client, unsigned char *framecount) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_FIFO_FRAME_COUNTER_S__REG, &data); *framecount = BMA2X2_GET_BITSLICE(data, BMA2X2_FIFO_FRAME_COUNTER_S); return comres; } static int bma2x2_get_fifo_data_sel(struct i2c_client *client, unsigned char *data_sel) { int comres; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_FIFO_DATA_SELECT__REG, &data); *data_sel = BMA2X2_GET_BITSLICE(data, BMA2X2_FIFO_DATA_SELECT); return comres; } static int bma2x2_set_fifo_data_sel(struct i2c_client *client, unsigned char data_sel) { unsigned char data; int comres = 0; if (data_sel < 4) { comres = bma2x2_smbus_read_byte(client, BMA2X2_FIFO_DATA_SELECT__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_FIFO_DATA_SELECT, data_sel); comres = bma2x2_smbus_write_byte(client, BMA2X2_FIFO_DATA_SELECT__REG, &data); } else { comres = -1; } return comres; } static int bma2x2_get_offset_target(struct i2c_client *client, unsigned char channel, unsigned char *offset) { unsigned char data; int comres = 0; switch (channel) { case BMA2X2_CUT_OFF: comres = bma2x2_smbus_read_byte(client, BMA2X2_COMP_CUTOFF__REG, &data); *offset = BMA2X2_GET_BITSLICE(data, BMA2X2_COMP_CUTOFF); break; case BMA2X2_OFFSET_TRIGGER_X: comres = bma2x2_smbus_read_byte(client, BMA2X2_COMP_TARGET_OFFSET_X__REG, &data); *offset = BMA2X2_GET_BITSLICE(data, BMA2X2_COMP_TARGET_OFFSET_X); break; case BMA2X2_OFFSET_TRIGGER_Y: comres = bma2x2_smbus_read_byte(client, BMA2X2_COMP_TARGET_OFFSET_Y__REG, &data); *offset = BMA2X2_GET_BITSLICE(data, BMA2X2_COMP_TARGET_OFFSET_Y); break; case BMA2X2_OFFSET_TRIGGER_Z: comres = bma2x2_smbus_read_byte(client, BMA2X2_COMP_TARGET_OFFSET_Z__REG, &data); *offset = BMA2X2_GET_BITSLICE(data, BMA2X2_COMP_TARGET_OFFSET_Z); break; default: comres = -1; break; } return comres; } static int bma2x2_set_offset_target(struct i2c_client *client, unsigned char channel, unsigned char offset) { unsigned char data; int comres = 0; switch (channel) { case BMA2X2_CUT_OFF: comres = bma2x2_smbus_read_byte(client, BMA2X2_COMP_CUTOFF__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_COMP_CUTOFF, offset); comres = bma2x2_smbus_write_byte(client, BMA2X2_COMP_CUTOFF__REG, &data); break; case BMA2X2_OFFSET_TRIGGER_X: comres = bma2x2_smbus_read_byte(client, BMA2X2_COMP_TARGET_OFFSET_X__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_COMP_TARGET_OFFSET_X, offset); comres = bma2x2_smbus_write_byte(client, BMA2X2_COMP_TARGET_OFFSET_X__REG, &data); break; case BMA2X2_OFFSET_TRIGGER_Y: comres = bma2x2_smbus_read_byte(client, BMA2X2_COMP_TARGET_OFFSET_Y__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_COMP_TARGET_OFFSET_Y, offset); comres = bma2x2_smbus_write_byte(client, BMA2X2_COMP_TARGET_OFFSET_Y__REG, &data); break; case BMA2X2_OFFSET_TRIGGER_Z: comres = bma2x2_smbus_read_byte(client, BMA2X2_COMP_TARGET_OFFSET_Z__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_COMP_TARGET_OFFSET_Z, offset); comres = bma2x2_smbus_write_byte(client, BMA2X2_COMP_TARGET_OFFSET_Z__REG, &data); break; default: comres = -1; break; } return comres; } static int bma2x2_get_cal_ready(struct i2c_client *client, unsigned char *calrdy) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_FAST_CAL_RDY_S__REG, &data); data = BMA2X2_GET_BITSLICE(data, BMA2X2_FAST_CAL_RDY_S); *calrdy = data; return comres; } static int bma2x2_set_cal_trigger(struct i2c_client *client, unsigned char caltrigger) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_CAL_TRIGGER__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_CAL_TRIGGER, caltrigger); comres = bma2x2_smbus_write_byte(client, BMA2X2_CAL_TRIGGER__REG, &data); return comres; } static int bma2x2_write_reg(struct i2c_client *client, unsigned char addr, unsigned char *data) { int comres = 0; comres = bma2x2_smbus_write_byte(client, addr, data); return comres; } static int bma2x2_set_offset_x(struct i2c_client *client, unsigned char offsetfilt) { int comres = 0; unsigned char data; data = offsetfilt; #ifdef CONFIG_SENSORS_BMI058 comres = bma2x2_smbus_write_byte(client, BMI058_OFFSET_X_AXIS_REG, &data); #else comres = bma2x2_smbus_write_byte(client, BMA2X2_OFFSET_X_AXIS_REG, &data); #endif return comres; } static int bma2x2_get_offset_x(struct i2c_client *client, unsigned char *offsetfilt) { int comres = 0; unsigned char data; #ifdef CONFIG_SENSORS_BMI058 comres = bma2x2_smbus_read_byte(client, BMI058_OFFSET_X_AXIS_REG, &data); #else comres = bma2x2_smbus_read_byte(client, BMA2X2_OFFSET_X_AXIS_REG, &data); #endif *offsetfilt = data; return comres; } static int bma2x2_set_offset_y(struct i2c_client *client, unsigned char offsetfilt) { int comres = 0; unsigned char data; data = offsetfilt; #ifdef CONFIG_SENSORS_BMI058 comres = bma2x2_smbus_write_byte(client, BMI058_OFFSET_Y_AXIS_REG, &data); #else comres = bma2x2_smbus_write_byte(client, BMA2X2_OFFSET_Y_AXIS_REG, &data); #endif return comres; } static int bma2x2_get_offset_y(struct i2c_client *client, unsigned char *offsetfilt) { int comres = 0; unsigned char data; #ifdef CONFIG_SENSORS_BMI058 comres = bma2x2_smbus_read_byte(client, BMI058_OFFSET_Y_AXIS_REG, &data); #else comres = bma2x2_smbus_read_byte(client, BMA2X2_OFFSET_Y_AXIS_REG, &data); #endif *offsetfilt = data; return comres; } static int bma2x2_set_offset_z(struct i2c_client *client, unsigned char offsetfilt) { int comres = 0; unsigned char data; data = offsetfilt; comres = bma2x2_smbus_write_byte(client, BMA2X2_OFFSET_Z_AXIS_REG, &data); return comres; } static int bma2x2_get_offset_z(struct i2c_client *client, unsigned char *offsetfilt) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_OFFSET_Z_AXIS_REG, &data); *offsetfilt = data; return comres; } static int bma2x2_set_selftest_st(struct i2c_client *client, unsigned char selftest) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_EN_SELF_TEST__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_SELF_TEST, selftest); comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_SELF_TEST__REG, &data); return comres; } static int bma2x2_set_selftest_stn(struct i2c_client *client, unsigned char stn) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_NEG_SELF_TEST__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_NEG_SELF_TEST, stn); comres = bma2x2_smbus_write_byte(client, BMA2X2_NEG_SELF_TEST__REG, &data); return comres; } static int bma2x2_set_selftest_amp(struct i2c_client *client, unsigned char amp) { int comres = 0; unsigned char data; comres = bma2x2_smbus_read_byte(client, BMA2X2_SELF_TEST_AMP__REG, &data); data = BMA2X2_SET_BITSLICE(data, BMA2X2_SELF_TEST_AMP, amp); comres = bma2x2_smbus_write_byte(client, BMA2X2_SELF_TEST_AMP__REG, &data); return comres; } static int bma2x2_read_accel_x(struct i2c_client *client, signed char sensor_type, short *a_x) { int comres = 0; unsigned char data[2]; switch (sensor_type) { case 0: comres = bma2x2_smbus_read_byte_block(client, BMA2X2_ACC_X12_LSB__REG, data, 2); *a_x = BMA2X2_GET_BITSLICE(data[0], BMA2X2_ACC_X12_LSB)| (BMA2X2_GET_BITSLICE(data[1], BMA2X2_ACC_X_MSB)<<(BMA2X2_ACC_X12_LSB__LEN)); *a_x = *a_x << (sizeof(short)*8-(BMA2X2_ACC_X12_LSB__LEN + BMA2X2_ACC_X_MSB__LEN)); *a_x = *a_x >> (sizeof(short)*8-(BMA2X2_ACC_X12_LSB__LEN + BMA2X2_ACC_X_MSB__LEN)); break; case 1: comres = bma2x2_smbus_read_byte_block(client, BMA2X2_ACC_X10_LSB__REG, data, 2); *a_x = BMA2X2_GET_BITSLICE(data[0], BMA2X2_ACC_X10_LSB)| (BMA2X2_GET_BITSLICE(data[1], BMA2X2_ACC_X_MSB)<<(BMA2X2_ACC_X10_LSB__LEN)); *a_x = *a_x << (sizeof(short)*8-(BMA2X2_ACC_X10_LSB__LEN + BMA2X2_ACC_X_MSB__LEN)); *a_x = *a_x >> (sizeof(short)*8-(BMA2X2_ACC_X10_LSB__LEN + BMA2X2_ACC_X_MSB__LEN)); break; case 2: comres = bma2x2_smbus_read_byte_block(client, BMA2X2_ACC_X8_LSB__REG, data, 2); *a_x = BMA2X2_GET_BITSLICE(data[0], BMA2X2_ACC_X8_LSB)| (BMA2X2_GET_BITSLICE(data[1], BMA2X2_ACC_X_MSB)<<(BMA2X2_ACC_X8_LSB__LEN)); *a_x = *a_x << (sizeof(short)*8-(BMA2X2_ACC_X8_LSB__LEN + BMA2X2_ACC_X_MSB__LEN)); *a_x = *a_x >> (sizeof(short)*8-(BMA2X2_ACC_X8_LSB__LEN + BMA2X2_ACC_X_MSB__LEN)); break; case 3: comres = bma2x2_smbus_read_byte_block(client, BMA2X2_ACC_X14_LSB__REG, data, 2); *a_x = BMA2X2_GET_BITSLICE(data[0], BMA2X2_ACC_X14_LSB)| (BMA2X2_GET_BITSLICE(data[1], BMA2X2_ACC_X_MSB)<<(BMA2X2_ACC_X14_LSB__LEN)); *a_x = *a_x << (sizeof(short)*8-(BMA2X2_ACC_X14_LSB__LEN + BMA2X2_ACC_X_MSB__LEN)); *a_x = *a_x >> (sizeof(short)*8-(BMA2X2_ACC_X14_LSB__LEN + BMA2X2_ACC_X_MSB__LEN)); break; default: break; } return comres; } static int bma2x2_soft_reset(struct i2c_client *client) { int comres = 0; unsigned char data = BMA2X2_EN_SOFT_RESET_VALUE; comres = bma2x2_smbus_write_byte(client, BMA2X2_EN_SOFT_RESET__REG, &data); return comres; } static int bma2x2_read_accel_y(struct i2c_client *client, signed char sensor_type, short *a_y) { int comres = 0; unsigned char data[2]; switch (sensor_type) { case 0: comres = bma2x2_smbus_read_byte_block(client, BMA2X2_ACC_Y12_LSB__REG, data, 2); *a_y = BMA2X2_GET_BITSLICE(data[0], BMA2X2_ACC_Y12_LSB)| (BMA2X2_GET_BITSLICE(data[1], BMA2X2_ACC_Y_MSB)<<(BMA2X2_ACC_Y12_LSB__LEN)); *a_y = *a_y << (sizeof(short)*8-(BMA2X2_ACC_Y12_LSB__LEN + BMA2X2_ACC_Y_MSB__LEN)); *a_y = *a_y >> (sizeof(short)*8-(BMA2X2_ACC_Y12_LSB__LEN + BMA2X2_ACC_Y_MSB__LEN)); break; case 1: comres = bma2x2_smbus_read_byte_block(client, BMA2X2_ACC_Y10_LSB__REG, data, 2); *a_y = BMA2X2_GET_BITSLICE(data[0], BMA2X2_ACC_Y10_LSB)| (BMA2X2_GET_BITSLICE(data[1], BMA2X2_ACC_Y_MSB)<<(BMA2X2_ACC_Y10_LSB__LEN)); *a_y = *a_y << (sizeof(short)*8-(BMA2X2_ACC_Y10_LSB__LEN + BMA2X2_ACC_Y_MSB__LEN)); *a_y = *a_y >> (sizeof(short)*8-(BMA2X2_ACC_Y10_LSB__LEN + BMA2X2_ACC_Y_MSB__LEN)); break; case 2: comres = bma2x2_smbus_read_byte_block(client, BMA2X2_ACC_Y8_LSB__REG, data, 2); *a_y = BMA2X2_GET_BITSLICE(data[0], BMA2X2_ACC_Y8_LSB)| (BMA2X2_GET_BITSLICE(data[1], BMA2X2_ACC_Y_MSB)<<(BMA2X2_ACC_Y8_LSB__LEN)); *a_y = *a_y << (sizeof(short)*8-(BMA2X2_ACC_Y8_LSB__LEN + BMA2X2_ACC_Y_MSB__LEN)); *a_y = *a_y >> (sizeof(short)*8-(BMA2X2_ACC_Y8_LSB__LEN + BMA2X2_ACC_Y_MSB__LEN)); break; case 3: comres = bma2x2_smbus_read_byte_block(client, BMA2X2_ACC_Y14_LSB__REG, data, 2); *a_y = BMA2X2_GET_BITSLICE(data[0], BMA2X2_ACC_Y14_LSB)| (BMA2X2_GET_BITSLICE(data[1], BMA2X2_ACC_Y_MSB)<<(BMA2X2_ACC_Y14_LSB__LEN)); *a_y = *a_y << (sizeof(short)*8-(BMA2X2_ACC_Y14_LSB__LEN + BMA2X2_ACC_Y_MSB__LEN)); *a_y = *a_y >> (sizeof(short)*8-(BMA2X2_ACC_Y14_LSB__LEN + BMA2X2_ACC_Y_MSB__LEN)); break; default: break; } return comres; } static int bma2x2_read_accel_z(struct i2c_client *client, signed char sensor_type, short *a_z) { int comres = 0; unsigned char data[2]; switch (sensor_type) { case 0: comres = bma2x2_smbus_read_byte_block(client, BMA2X2_ACC_Z12_LSB__REG, data, 2); *a_z = BMA2X2_GET_BITSLICE(data[0], BMA2X2_ACC_Z12_LSB)| (BMA2X2_GET_BITSLICE(data[1], BMA2X2_ACC_Z_MSB)<<(BMA2X2_ACC_Z12_LSB__LEN)); *a_z = *a_z << (sizeof(short)*8-(BMA2X2_ACC_Z12_LSB__LEN + BMA2X2_ACC_Z_MSB__LEN)); *a_z = *a_z >> (sizeof(short)*8-(BMA2X2_ACC_Z12_LSB__LEN + BMA2X2_ACC_Z_MSB__LEN)); break; case 1: comres = bma2x2_smbus_read_byte_block(client, BMA2X2_ACC_Z10_LSB__REG, data, 2); *a_z = BMA2X2_GET_BITSLICE(data[0], BMA2X2_ACC_Z10_LSB)| (BMA2X2_GET_BITSLICE(data[1], BMA2X2_ACC_Z_MSB)<<(BMA2X2_ACC_Z10_LSB__LEN)); *a_z = *a_z << (sizeof(short)*8-(BMA2X2_ACC_Z10_LSB__LEN + BMA2X2_ACC_Z_MSB__LEN)); *a_z = *a_z >> (sizeof(short)*8-(BMA2X2_ACC_Z10_LSB__LEN + BMA2X2_ACC_Z_MSB__LEN)); break; case 2: comres = bma2x2_smbus_read_byte_block(client, BMA2X2_ACC_Z8_LSB__REG, data, 2); *a_z = BMA2X2_GET_BITSLICE(data[0], BMA2X2_ACC_Z8_LSB)| (BMA2X2_GET_BITSLICE(data[1], BMA2X2_ACC_Z_MSB)<<(BMA2X2_ACC_Z8_LSB__LEN)); *a_z = *a_z << (sizeof(short)*8-(BMA2X2_ACC_Z8_LSB__LEN + BMA2X2_ACC_Z_MSB__LEN)); *a_z = *a_z >> (sizeof(short)*8-(BMA2X2_ACC_Z8_LSB__LEN + BMA2X2_ACC_Z_MSB__LEN)); break; case 3: comres = bma2x2_smbus_read_byte_block(client, BMA2X2_ACC_Z14_LSB__REG, data, 2); *a_z = BMA2X2_GET_BITSLICE(data[0], BMA2X2_ACC_Z14_LSB)| (BMA2X2_GET_BITSLICE(data[1], BMA2X2_ACC_Z_MSB)<<(BMA2X2_ACC_Z14_LSB__LEN)); *a_z = *a_z << (sizeof(short)*8-(BMA2X2_ACC_Z14_LSB__LEN + BMA2X2_ACC_Z_MSB__LEN)); *a_z = *a_z >> (sizeof(short)*8-(BMA2X2_ACC_Z14_LSB__LEN + BMA2X2_ACC_Z_MSB__LEN)); break; default: break; } return comres; } static int bma2x2_read_temperature(struct i2c_client *client, signed char *temperature) { unsigned char data; int comres = 0; comres = bma2x2_smbus_read_byte(client, BMA2X2_TEMPERATURE_REG, &data); *temperature = (signed char)data; return comres; } static ssize_t bma2x2_enable_int_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int type, value; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); #ifdef CONFIG_SENSORS_BMI058 int i; #endif sscanf(buf, "%3d %3d", &type, &value); #ifdef CONFIG_SENSORS_BMI058 for (i = 0; i < sizeof(int_map) / sizeof(struct interrupt_map_t); i++) { if (int_map[i].x == type) { type = int_map[i].y; break; } if (int_map[i].y == type) { type = int_map[i].x; break; } } #endif if (bma2x2_set_Int_Enable(bma2x2->bma2x2_client, type, value) < 0) return -EINVAL; return count; } static ssize_t bma2x2_int_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_Int_Mode(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_int_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_Int_Mode(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_slope_duration_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_slope_duration(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_slope_duration_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_slope_duration(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_slope_no_mot_duration_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_slope_no_mot_duration(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_slope_no_mot_duration_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_slope_no_mot_duration(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_slope_threshold_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_slope_threshold(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_slope_threshold_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_slope_threshold(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_slope_no_mot_threshold_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_slope_no_mot_threshold(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_slope_no_mot_threshold_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_slope_no_mot_threshold(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_high_g_duration_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_high_g_duration(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_high_g_duration_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_high_g_duration(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_high_g_threshold_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_high_g_threshold(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_high_g_threshold_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_high_g_threshold(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_low_g_duration_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_low_g_duration(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_low_g_duration_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_low_g_duration(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_low_g_threshold_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_low_g_threshold(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_low_g_threshold_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_low_g_threshold(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_tap_threshold_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_tap_threshold(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_tap_threshold_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_tap_threshold(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_tap_duration_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_tap_duration(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_tap_duration_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_tap_duration(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_tap_quiet_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_tap_quiet(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_tap_quiet_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_tap_quiet(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_tap_shock_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_tap_shock(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_tap_shock_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_tap_shock(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_tap_samp_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_tap_samp(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_tap_samp_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_tap_samp(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_orient_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_orient_mode(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_orient_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_orient_mode(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_orient_blocking_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_orient_blocking(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_orient_blocking_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_orient_blocking(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_orient_hyst_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_orient_hyst(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_orient_hyst_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_orient_hyst(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_orient_theta_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_theta_blocking(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_orient_theta_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_theta_blocking(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_flat_theta_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_theta_flat(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_flat_theta_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_theta_flat(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_flat_hold_time_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_flat_hold_time(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_selftest_show(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); return sprintf(buf, "%d\n", atomic_read(&bma2x2->selftest_result)); } static ssize_t bma2x2_softreset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_soft_reset(bma2x2->bma2x2_client) < 0) return -EINVAL; return count; } static ssize_t bma2x2_selftest_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; unsigned char clear_value = 0; int error; short value1 = 0; short value2 = 0; short diff = 0; unsigned long result = 0; unsigned char test_result_branch = 0; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); bma2x2_soft_reset(bma2x2->bma2x2_client); mdelay(5); error = kstrtoul(buf, 10, &data); if (error) return error; if (data != 1) return -EINVAL; bma2x2_write_reg(bma2x2->bma2x2_client, 0x32, &clear_value); if ((bma2x2->sensor_type == BMA280_TYPE) || (bma2x2->sensor_type == BMA255_TYPE)) { #ifdef CONFIG_SENSORS_BMI058 /*set self test amp */ if (bma2x2_set_selftest_amp(bma2x2->bma2x2_client, 1) < 0) return -EINVAL; /* set to 8 G range */ if (bma2x2_set_range(bma2x2->bma2x2_client, BMA2X2_RANGE_8G) < 0) return -EINVAL; #else /* set to 4 G range */ if (bma2x2_set_range(bma2x2->bma2x2_client, BMA2X2_RANGE_4G) < 0) return -EINVAL; #endif } if ((bma2x2->sensor_type == BMA250E_TYPE) || (bma2x2->sensor_type == BMA222E_TYPE)) { /* set to 8 G range */ if (bma2x2_set_range(bma2x2->bma2x2_client, 8) < 0) return -EINVAL; if (bma2x2_set_selftest_amp(bma2x2->bma2x2_client, 1) < 0) return -EINVAL; } /* 1 for x-axis(but BMI058 is 1 for y-axis )*/ bma2x2_set_selftest_st(bma2x2->bma2x2_client, 1); bma2x2_set_selftest_stn(bma2x2->bma2x2_client, 0); mdelay(10); bma2x2_read_accel_x(bma2x2->bma2x2_client, bma2x2->sensor_type, &value1); bma2x2_set_selftest_stn(bma2x2->bma2x2_client, 1); mdelay(10); bma2x2_read_accel_x(bma2x2->bma2x2_client, bma2x2->sensor_type, &value2); diff = value1-value2; #ifdef CONFIG_SENSORS_BMI058 printk(KERN_INFO "diff y is %d,value1 is %d, value2 is %d\n", diff, value1, value2); test_result_branch = 2; #else printk(KERN_INFO "diff x is %d,value1 is %d, value2 is %d\n", diff, value1, value2); test_result_branch = 1; #endif if (bma2x2->sensor_type == BMA280_TYPE) { #ifdef CONFIG_SENSORS_BMI058 if (abs(diff) < 819) result |= test_result_branch; #else if (abs(diff) < 1638) result |= test_result_branch; #endif } if (bma2x2->sensor_type == BMA255_TYPE) { if (abs(diff) < 409) result |= 1; } if (bma2x2->sensor_type == BMA250E_TYPE) { if (abs(diff) < 51) result |= 1; } if (bma2x2->sensor_type == BMA222E_TYPE) { if (abs(diff) < 12) result |= 1; } /* 2 for y-axis but BMI058 is 1*/ bma2x2_set_selftest_st(bma2x2->bma2x2_client, 2); bma2x2_set_selftest_stn(bma2x2->bma2x2_client, 0); mdelay(10); bma2x2_read_accel_y(bma2x2->bma2x2_client, bma2x2->sensor_type, &value1); bma2x2_set_selftest_stn(bma2x2->bma2x2_client, 1); mdelay(10); bma2x2_read_accel_y(bma2x2->bma2x2_client, bma2x2->sensor_type, &value2); diff = value1-value2; #ifdef CONFIG_SENSORS_BMI058 printk(KERN_INFO "diff x is %d,value1 is %d, value2 is %d\n", diff, value1, value2); test_result_branch = 1; #else printk(KERN_INFO "diff y is %d,value1 is %d, value2 is %d\n", diff, value1, value2); test_result_branch = 2; #endif if (bma2x2->sensor_type == BMA280_TYPE) { #ifdef CONFIG_SENSORS_BMI058 if (abs(diff) < 819) result |= test_result_branch; #else if (abs(diff) < 1638) result |= test_result_branch; #endif } if (bma2x2->sensor_type == BMA255_TYPE) { if (abs(diff) < 409) result |= test_result_branch; } if (bma2x2->sensor_type == BMA250E_TYPE) { if (abs(diff) < 51) result |= test_result_branch; } if (bma2x2->sensor_type == BMA222E_TYPE) { if (abs(diff) < 12) result |= test_result_branch; } bma2x2_set_selftest_st(bma2x2->bma2x2_client, 3); /* 3 for z-axis*/ bma2x2_set_selftest_stn(bma2x2->bma2x2_client, 0); mdelay(10); bma2x2_read_accel_z(bma2x2->bma2x2_client, bma2x2->sensor_type, &value1); bma2x2_set_selftest_stn(bma2x2->bma2x2_client, 1); mdelay(10); bma2x2_read_accel_z(bma2x2->bma2x2_client, bma2x2->sensor_type, &value2); diff = value1-value2; printk(KERN_INFO "diff z is %d,value1 is %d, value2 is %d\n", diff, value1, value2); if (bma2x2->sensor_type == BMA280_TYPE) { #ifdef CONFIG_SENSORS_BMI058 if (abs(diff) < 409) result |= 4; #else if (abs(diff) < 819) result |= 4; #endif } if (bma2x2->sensor_type == BMA255_TYPE) { if (abs(diff) < 204) result |= 4; } if (bma2x2->sensor_type == BMA250E_TYPE) { if (abs(diff) < 25) result |= 4; } if (bma2x2->sensor_type == BMA222E_TYPE) { if (abs(diff) < 6) result |= 4; } /* self test for bma254 */ if ((bma2x2->sensor_type == BMA255_TYPE) && (result > 0)) { result = 0; bma2x2_soft_reset(bma2x2->bma2x2_client); mdelay(5); bma2x2_write_reg(bma2x2->bma2x2_client, 0x32, &clear_value); /* set to 8 G range */ if (bma2x2_set_range(bma2x2->bma2x2_client, 8) < 0) return -EINVAL; if (bma2x2_set_selftest_amp(bma2x2->bma2x2_client, 1) < 0) return -EINVAL; bma2x2_set_selftest_st(bma2x2->bma2x2_client, 1); /* 1 for x-axis*/ bma2x2_set_selftest_stn(bma2x2->bma2x2_client, 0); /* positive direction*/ mdelay(10); bma2x2_read_accel_x(bma2x2->bma2x2_client, bma2x2->sensor_type, &value1); bma2x2_set_selftest_stn(bma2x2->bma2x2_client, 1); /* negative direction*/ mdelay(10); bma2x2_read_accel_x(bma2x2->bma2x2_client, bma2x2->sensor_type, &value2); diff = value1-value2; printk(KERN_INFO "diff x is %d,value1 is %d, value2 is %d\n", diff, value1, value2); if (abs(diff) < 204) result |= 1; bma2x2_set_selftest_st(bma2x2->bma2x2_client, 2); /* 2 for y-axis*/ bma2x2_set_selftest_stn(bma2x2->bma2x2_client, 0); /* positive direction*/ mdelay(10); bma2x2_read_accel_y(bma2x2->bma2x2_client, bma2x2->sensor_type, &value1); bma2x2_set_selftest_stn(bma2x2->bma2x2_client, 1); /* negative direction*/ mdelay(10); bma2x2_read_accel_y(bma2x2->bma2x2_client, bma2x2->sensor_type, &value2); diff = value1-value2; printk(KERN_INFO "diff y is %d,value1 is %d, value2 is %d\n", diff, value1, value2); if (abs(diff) < 204) result |= 2; bma2x2_set_selftest_st(bma2x2->bma2x2_client, 3); /* 3 for z-axis*/ bma2x2_set_selftest_stn(bma2x2->bma2x2_client, 0); /* positive direction*/ mdelay(10); bma2x2_read_accel_z(bma2x2->bma2x2_client, bma2x2->sensor_type, &value1); bma2x2_set_selftest_stn(bma2x2->bma2x2_client, 1); /* negative direction*/ mdelay(10); bma2x2_read_accel_z(bma2x2->bma2x2_client, bma2x2->sensor_type, &value2); diff = value1-value2; printk(KERN_INFO "diff z is %d,value1 is %d, value2 is %d\n", diff, value1, value2); if (abs(diff) < 102) result |= 4; } atomic_set(&bma2x2->selftest_result, (unsigned int)result); bma2x2_soft_reset(bma2x2->bma2x2_client); mdelay(5); printk(KERN_INFO "self test finished\n"); return count; } static ssize_t bma2x2_flat_hold_time_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_flat_hold_time(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } const int bma2x2_sensor_bitwidth[] = { 12, 10, 12, 14 }; static int bma2x2_read_accel_xyz(struct i2c_client *client, signed char sensor_type, struct bma2x2acc *acc) { int comres = 0; unsigned char data[6]; struct bma2x2_data *client_data = i2c_get_clientdata(client); #ifndef BMA2X2_SENSOR_IDENTIFICATION_ENABLE int bitwidth; #endif comres = bma2x2_smbus_read_byte_block(client, BMA2X2_ACC_X12_LSB__REG, data, 6); if (sensor_type >= 4) return -EINVAL; acc->x = (data[1]<<8)|data[0]; acc->y = (data[3]<<8)|data[2]; acc->z = (data[5]<<8)|data[4]; #ifndef BMA2X2_SENSOR_IDENTIFICATION_ENABLE bitwidth = bma2x2_sensor_bitwidth[sensor_type]; acc->x = (acc->x >> (16 - bitwidth)); acc->y = (acc->y >> (16 - bitwidth)); acc->z = (acc->z >> (16 - bitwidth)); #endif bma2x2_remap_sensor_data(acc, client_data); return comres; } #ifndef CONFIG_BMA_ENABLE_NEWDATA_INT static void bma2x2_work_func(struct work_struct *work) { struct bma2x2_data *bma2x2 = container_of((struct delayed_work *)work, struct bma2x2_data, work); static uint64_t startTime; static struct bma2x2acc acc; unsigned long setDelay; unsigned long delay = msecs_to_jiffies(atomic_read(&bma2x2->delay)) - 1; bma2x2_read_accel_xyz(bma2x2->bma2x2_client, bma2x2->sensor_type, &acc); input_report_abs(bma2x2->input, ABS_X, acc.x); input_report_abs(bma2x2->input, ABS_Y, acc.y); input_report_abs(bma2x2->input, ABS_Z, acc.z); input_sync(bma2x2->input); mutex_lock(&bma2x2->value_mutex); bma2x2->value = acc; mutex_unlock(&bma2x2->value_mutex); uint64_t deltaTime = get_jiffies_64() - startTime; if (deltaTime > delay && deltaTime <= 2 * delay) setDelay = 2 * delay - deltaTime; else if (deltaTime > 2 * delay) setDelay = 0; else setDelay = delay; if (setDelay <= 1) setDelay = 1; queue_delayed_work(bma2x2->workqueue, &bma2x2->work, setDelay); startTime = get_jiffies_64(); } #endif static ssize_t bma2x2_register_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int address, value; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); sscanf(buf, "%3d %3d", &address, &value); if (bma2x2_write_reg(bma2x2->bma2x2_client, (unsigned char)address, (unsigned char *)&value) < 0) return -EINVAL; return count; } static ssize_t bma2x2_register_show(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); size_t count = 0; u8 reg[0x40]; int i; for (i = 0; i < 0x40; i++) { bma2x2_smbus_read_byte(bma2x2->bma2x2_client, i, reg+i); count += sprintf(&buf[count], "0x%x: %d\n", i, reg[i]); } return count; } static ssize_t bma2x2_range_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_range(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_range_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_range(bma2x2->bma2x2_client, (unsigned char) data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_bandwidth_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_bandwidth(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_bandwidth_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2->sensor_type == BMA280_TYPE) if ((unsigned char) data > 14) return -EINVAL; if (bma2x2_set_bandwidth(bma2x2->bma2x2_client, (unsigned char) data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_mode(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d %d\n", data, bma2x2->bma_mode_enabled); } static ssize_t bma2x2_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_mode(bma2x2->bma2x2_client, (unsigned char) data, BMA_ENABLED_BSX) < 0) return -EINVAL; return count; } static ssize_t bma2x2_value_cache_show(struct device *dev, struct device_attribute *attr, char *buf) { struct input_dev *input = to_input_dev(dev); struct bma2x2_data *bma2x2 = input_get_drvdata(input); struct bma2x2acc acc_value; mutex_lock(&bma2x2->value_mutex); acc_value = bma2x2->value; mutex_unlock(&bma2x2->value_mutex); return sprintf(buf, "%d %d %d\n", acc_value.x, acc_value.y, acc_value.z); } static ssize_t bma2x2_value_show(struct device *dev, struct device_attribute *attr, char *buf) { struct input_dev *input = to_input_dev(dev); struct bma2x2_data *bma2x2 = input_get_drvdata(input); struct bma2x2acc acc_value; bma2x2_read_accel_xyz(bma2x2->bma2x2_client, bma2x2->sensor_type, &acc_value); return sprintf(buf, "%d %d %d\n", acc_value.x, acc_value.y, acc_value.z); } static ssize_t bma2x2_delay_show(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); return sprintf(buf, "%d\n", atomic_read(&bma2x2->delay)); } static ssize_t bma2x2_chip_id_show(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); return sprintf(buf, "%u\n", bma2x2->chip_id); } static ssize_t bma2x2_place_show(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); int place = BOSCH_SENSOR_PLACE_UNKNOWN; if (NULL != bma2x2->bst_pd) place = bma2x2->bst_pd->place; return sprintf(buf, "%d\n", place); } static ssize_t bma2x2_delay_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (data > BMA2X2_MAX_DELAY) data = BMA2X2_MAX_DELAY; atomic_set(&bma2x2->delay, (unsigned int) data); return count; } static ssize_t bma2x2_enable_show(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); return sprintf(buf, "%d\n", atomic_read(&bma2x2->enable)); } static void bma2x2_set_enable(struct device *dev, int enable) { struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); int pre_enable = atomic_read(&bma2x2->enable); mutex_lock(&bma2x2->enable_mutex); if (enable) { if (pre_enable == 0) { bma2x2_set_mode(bma2x2->bma2x2_client, BMA2X2_MODE_NORMAL, BMA_ENABLED_INPUT); #ifndef CONFIG_BMA_ENABLE_NEWDATA_INT queue_delayed_work(bma2x2->workqueue, &bma2x2->work, msecs_to_jiffies(atomic_read(&bma2x2->delay))); #endif atomic_set(&bma2x2->enable, 1); } } else { if (pre_enable == 1) { bma2x2_set_mode(bma2x2->bma2x2_client, BMA2X2_MODE_SUSPEND, BMA_ENABLED_INPUT); #ifndef CONFIG_BMA_ENABLE_NEWDATA_INT cancel_delayed_work_sync(&bma2x2->work); flush_workqueue(bma2x2->workqueue); #endif atomic_set(&bma2x2->enable, 0); } } mutex_unlock(&bma2x2->enable_mutex); } static ssize_t bma2x2_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; error = kstrtoul(buf, 10, &data); if (error) return error; if ((data == 0) || (data == 1)) bma2x2_set_enable(dev, data); return count; } static ssize_t bma2x2_fast_calibration_x_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); #ifdef CONFIG_SENSORS_BMI058 if (bma2x2_get_offset_target(bma2x2->bma2x2_client, BMI058_OFFSET_TRIGGER_X, &data) < 0) return -EINVAL; #else if (bma2x2_get_offset_target(bma2x2->bma2x2_client, BMA2X2_OFFSET_TRIGGER_X, &data) < 0) return -EINVAL; #endif return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_fast_calibration_x_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; signed char tmp; unsigned char timeout = 0; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; #ifdef CONFIG_SENSORS_BMI058 if (bma2x2_set_offset_target(bma2x2->bma2x2_client, BMI058_OFFSET_TRIGGER_X, (unsigned char)data) < 0) return -EINVAL; #else if (bma2x2_set_offset_target(bma2x2->bma2x2_client, BMA2X2_OFFSET_TRIGGER_X, (unsigned char)data) < 0) return -EINVAL; #endif if (bma2x2_set_cal_trigger(bma2x2->bma2x2_client, 1) < 0) return -EINVAL; do { mdelay(2); bma2x2_get_cal_ready(bma2x2->bma2x2_client, &tmp); /*printk(KERN_INFO "wait 2ms cal ready flag is %d\n", tmp); */ timeout++; if (timeout == 50) { printk(KERN_INFO "get fast calibration ready error\n"); return -EINVAL; }; } while (tmp == 0); printk(KERN_INFO "x axis fast calibration finished\n"); return count; } static ssize_t bma2x2_fast_calibration_y_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); #ifdef CONFIG_SENSORS_BMI058 if (bma2x2_get_offset_target(bma2x2->bma2x2_client, BMI058_OFFSET_TRIGGER_Y, &data) < 0) return -EINVAL; #else if (bma2x2_get_offset_target(bma2x2->bma2x2_client, BMA2X2_OFFSET_TRIGGER_Y, &data) < 0) return -EINVAL; #endif return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_fast_calibration_y_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; signed char tmp; unsigned char timeout = 0; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; #ifdef CONFIG_SENSORS_BMI058 if (bma2x2_set_offset_target(bma2x2->bma2x2_client, BMI058_OFFSET_TRIGGER_Y, (unsigned char)data) < 0) return -EINVAL; #else if (bma2x2_set_offset_target(bma2x2->bma2x2_client, BMA2X2_OFFSET_TRIGGER_Y, (unsigned char)data) < 0) return -EINVAL; #endif if (bma2x2_set_cal_trigger(bma2x2->bma2x2_client, 2) < 0) return -EINVAL; do { mdelay(2); bma2x2_get_cal_ready(bma2x2->bma2x2_client, &tmp); /*printk(KERN_INFO "wait 2ms cal ready flag is %d\n", tmp); */ timeout++; if (timeout == 50) { printk(KERN_INFO "get fast calibration ready error\n"); return -EINVAL; }; } while (tmp == 0); printk(KERN_INFO "y axis fast calibration finished\n"); return count; } static ssize_t bma2x2_fast_calibration_z_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_offset_target(bma2x2->bma2x2_client, 3, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_fast_calibration_z_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; signed char tmp; unsigned char timeout = 0; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_offset_target(bma2x2->bma2x2_client, 3, (unsigned char)data) < 0) return -EINVAL; if (bma2x2_set_cal_trigger(bma2x2->bma2x2_client, 3) < 0) return -EINVAL; do { mdelay(2); bma2x2_get_cal_ready(bma2x2->bma2x2_client, &tmp); /*printk(KERN_INFO "wait 2ms cal ready flag is %d\n", tmp); */ timeout++; if (timeout == 50) { printk(KERN_INFO "get fast calibration ready error\n"); return -EINVAL; }; } while (tmp == 0); printk(KERN_INFO "z axis fast calibration finished\n"); return count; } static ssize_t bma2x2_SleepDur_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_sleep_duration(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_SleepDur_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_sleep_duration(bma2x2->bma2x2_client, (unsigned char) data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_fifo_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_fifo_mode(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_fifo_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_fifo_mode(bma2x2->bma2x2_client, (unsigned char) data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_fifo_trig_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_fifo_trig(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_fifo_trig_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_fifo_trig(bma2x2->bma2x2_client, (unsigned char) data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_fifo_trig_src_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_fifo_trig_src(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_fifo_trig_src_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_fifo_trig_src(bma2x2->bma2x2_client, (unsigned char) data) < 0) return -EINVAL; return count; } /*! * @brief show fifo_data_sel axis definition(Android definition, not sensor HW reg). * 0--> x, y, z axis fifo data for every frame * 1--> only x axis fifo data for every frame * 2--> only y axis fifo data for every frame * 3--> only z axis fifo data for every frame */ static ssize_t bma2x2_fifo_data_sel_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); signed char place = BOSCH_SENSOR_PLACE_UNKNOWN; if (bma2x2_get_fifo_data_sel(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; #ifdef CONFIG_SENSORS_BMI058 /*Update BMI058 fifo_data_sel to the BMA2x2 common definition*/ if (BMI058_FIFO_DAT_SEL_X == data) data = BMA2X2_FIFO_DAT_SEL_X; else if (BMI058_FIFO_DAT_SEL_Y == data) data = BMA2X2_FIFO_DAT_SEL_Y; #endif /*remaping fifo_dat_sel if define virtual place in BSP files*/ if ((NULL != bma2x2->bst_pd) && (BOSCH_SENSOR_PLACE_UNKNOWN != bma2x2->bst_pd->place)) { place = bma2x2->bst_pd->place; /* sensor with place 0 needs not to be remapped */ if ((place > 0) && (place < MAX_AXIS_REMAP_TAB_SZ)) { /* BMA2X2_FIFO_DAT_SEL_X: 1, Y:2, Z:3; * but bst_axis_remap_tab_dft[i].src_x:0, y:1, z:2 * so we need to +1*/ if (BMA2X2_FIFO_DAT_SEL_X == data) data = bst_axis_remap_tab_dft[place].src_x + 1; else if (BMA2X2_FIFO_DAT_SEL_Y == data) data = bst_axis_remap_tab_dft[place].src_y + 1; } } return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_fifo_framecount_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_fifo_framecount(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_fifo_framecount_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; bma2x2->fifo_count = (unsigned int) data; return count; } static ssize_t bma2x2_temperature_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_read_temperature(bma2x2->bma2x2_client, &data) < 0) return -EINVAL; return sprintf(buf, "%d\n", data); } /*! * @brief store fifo_data_sel axis definition(Android definition, not sensor HW reg). * 0--> x, y, z axis fifo data for every frame * 1--> only x axis fifo data for every frame * 2--> only y axis fifo data for every frame * 3--> only z axis fifo data for every frame */ static ssize_t bma2x2_fifo_data_sel_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); signed char place; error = kstrtoul(buf, 10, &data); if (error) return error; /*save fifo_data_sel(android definition)*/ bma2x2->fifo_datasel = (unsigned char) data; /*remaping fifo_dat_sel if define virtual place*/ if ((NULL != bma2x2->bst_pd) && (BOSCH_SENSOR_PLACE_UNKNOWN != bma2x2->bst_pd->place)) { place = bma2x2->bst_pd->place; /* sensor with place 0 needs not to be remapped */ if ((place > 0) && (place < MAX_AXIS_REMAP_TAB_SZ)) { /*Need X Y axis revesal sensor place: P1, P3, P5, P7 */ /* BMA2X2_FIFO_DAT_SEL_X: 1, Y:2, Z:3; * but bst_axis_remap_tab_dft[i].src_x:0, y:1, z:2 * so we need to +1*/ if (BMA2X2_FIFO_DAT_SEL_X == data) data = bst_axis_remap_tab_dft[place].src_x + 1; else if (BMA2X2_FIFO_DAT_SEL_Y == data) data = bst_axis_remap_tab_dft[place].src_y + 1; } } #ifdef CONFIG_SENSORS_BMI058 /*Update BMI058 fifo_data_sel to the BMA2x2 common definition*/ if (BMA2X2_FIFO_DAT_SEL_X == data) data = BMI058_FIFO_DAT_SEL_X; else if (BMA2X2_FIFO_DAT_SEL_Y == data) data = BMI058_FIFO_DAT_SEL_Y; #endif if (bma2x2_set_fifo_data_sel(bma2x2->bma2x2_client, (unsigned char) data) < 0) return -EINVAL; return count; } /*! * brief: bma2x2 single axis data remaping * @param[i] fifo_datasel fifo axis data select setting * @param[i/o] remap_dir remapping direction * @param[i] client_data to transfer sensor place * * @return none */ static void bma2x2_single_axis_remaping(unsigned char fifo_datasel, unsigned char *remap_dir, struct bma2x2_data *client_data) { if ((NULL == client_data->bst_pd) || (BOSCH_SENSOR_PLACE_UNKNOWN == client_data->bst_pd->place)) return; else { signed char place = client_data->bst_pd->place; /* sensor with place 0 needs not to be remapped */ if ((place <= 0) || (place >= MAX_AXIS_REMAP_TAB_SZ)) return; if (fifo_datasel < 1 || fifo_datasel > 3) return; else { switch (fifo_datasel) { /*P2, P3, P4, P5 X axis(andorid) need to reverse*/ case BMA2X2_FIFO_DAT_SEL_X: if (-1 == bst_axis_remap_tab_dft[place].sign_x) *remap_dir = 1; else *remap_dir = 0; break; /*P1, P2, P5, P6 Y axis(andorid) need to reverse*/ case BMA2X2_FIFO_DAT_SEL_Y: if (-1 == bst_axis_remap_tab_dft[place].sign_y) *remap_dir = 1; else *remap_dir = 0; break; case BMA2X2_FIFO_DAT_SEL_Z: /*P4, P5, P6, P7 Z axis(andorid) need to reverse*/ if (-1 == bst_axis_remap_tab_dft[place].sign_z) *remap_dir = 1; else *remap_dir = 0; break; default: break; } } } return; } static ssize_t bma2x2_fifo_data_out_frame_show(struct device *dev, struct device_attribute *attr, char *buf) { int err, i, len; signed char fifo_data_out[MAX_FIFO_F_LEVEL * MAX_FIFO_F_BYTES] = {0}; unsigned char f_len = 0; s16 value; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); struct bma2x2acc acc_lsb; unsigned char axis_dir_remap = 0; if (bma2x2->fifo_datasel) { /*Select one axis data output for every fifo frame*/ f_len = 2; } else { /*Select X Y Z axis data output for every fifo frame*/ f_len = 6; } if (bma2x2->fifo_count == 0) return -EINVAL; if (bma_i2c_burst_read(bma2x2->bma2x2_client, BMA2X2_FIFO_DATA_OUTPUT_REG, fifo_data_out, bma2x2->fifo_count * f_len) < 0) return -EINVAL; err = 0; /* please give attation for the fifo output data format*/ if (f_len == 6) { /* Select X Y Z axis data output for every frame */ for (i = 0; i < bma2x2->fifo_count; i++) { acc_lsb.x = ((unsigned char)fifo_data_out[i * f_len + 1] << 8 | (unsigned char)fifo_data_out[i * f_len + 0]); acc_lsb.y = ((unsigned char)fifo_data_out[i * f_len + 3] << 8 | (unsigned char)fifo_data_out[i * f_len + 2]); acc_lsb.z = ((unsigned char)fifo_data_out[i * f_len + 5] << 8 | (unsigned char)fifo_data_out[i * f_len + 4]); #ifndef BMA2X2_SENSOR_IDENTIFICATION_ENABLE acc_lsb.x >>= (16 - bma2x2_sensor_bitwidth[bma2x2->sensor_type]); acc_lsb.y >>= (16 - bma2x2_sensor_bitwidth[bma2x2->sensor_type]); acc_lsb.z >>= (16 - bma2x2_sensor_bitwidth[bma2x2->sensor_type]); #endif bma2x2_remap_sensor_data(&acc_lsb, bma2x2); len = sprintf(buf, "%d %d %d ", acc_lsb.x, acc_lsb.y, acc_lsb.z); buf += len; err += len; } } else { /* single axis data output for every frame */ bma2x2_single_axis_remaping(bma2x2->fifo_datasel, &axis_dir_remap, bma2x2); for (i = 0; i < bma2x2->fifo_count * f_len / 2; i++) { value = ((unsigned char)fifo_data_out[2 * i + 1] << 8 | (unsigned char)fifo_data_out[2 * i]); #ifndef BMA2X2_SENSOR_IDENTIFICATION_ENABLE value >>= (16 - bma2x2_sensor_bitwidth[bma2x2->sensor_type]); #endif if (axis_dir_remap) value = 0 - value; len = sprintf(buf, "%d ", value); buf += len; err += len; } } return err; } static ssize_t bma2x2_offset_x_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_offset_x(bma2x2->bma2x2_client, &data) < 0) return sprintf(buf, "Read error\n"); return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_offset_x_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_offset_x(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_offset_y_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_offset_y(bma2x2->bma2x2_client, &data) < 0) return sprintf(buf, "Read error\n"); return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_offset_y_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_offset_y(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } static ssize_t bma2x2_offset_z_show(struct device *dev, struct device_attribute *attr, char *buf) { unsigned char data; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); if (bma2x2_get_offset_z(bma2x2->bma2x2_client, &data) < 0) return sprintf(buf, "Read error\n"); return sprintf(buf, "%d\n", data); } static ssize_t bma2x2_offset_z_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if (bma2x2_set_offset_z(bma2x2->bma2x2_client, (unsigned char)data) < 0) return -EINVAL; return count; } #ifdef CONFIG_SIG_MOTION static int bma2x2_set_en_slope_int(struct bma2x2_data *bma2x2, int en) { int err; struct i2c_client *client = bma2x2->bma2x2_client; if (en) { /* Set the related parameters which needs to be fine tuned by * interfaces: slope_threshold and slope_duration */ /*dur: 192 samples ~= 3s*/ err = bma2x2_set_slope_duration(client, 0xc0); err += bma2x2_set_slope_threshold(client, 0x16); /*Enable the interrupts*/ err += bma2x2_set_Int_Enable(client, 5, 1);/*Slope X*/ err += bma2x2_set_Int_Enable(client, 6, 1);/*Slope Y*/ err += bma2x2_set_Int_Enable(client, 7, 1);/*Slope Z*/ #ifdef BMA2X2_ENABLE_INT1 /* TODO: SLOPE can now only be routed to INT1 pin*/ err += bma2x2_set_int1_pad_sel(client, PAD_SLOP); #else /* err += bma2x2_set_int2_pad_sel(client, PAD_SLOP); */ #endif } else { err = bma2x2_set_Int_Enable(client, 5, 0);/*Slope X*/ err += bma2x2_set_Int_Enable(client, 6, 0);/*Slope Y*/ err += bma2x2_set_Int_Enable(client, 7, 0);/*Slope Z*/ } return err; } static ssize_t bma2x2_en_sig_motion_show(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); return sprintf(buf, "%d\n", atomic_read(&bma2x2->en_sig_motion)); } static int bma2x2_set_en_sig_motion(struct bma2x2_data *bma2x2, int en) { int err = 0; en = (en >= 1) ? 1 : 0; /* set sig motion sensor status */ if (atomic_read(&bma2x2->en_sig_motion) != en) { if (en) { err = bma2x2_set_mode(bma2x2->bma2x2_client, BMA2X2_MODE_NORMAL, BMA_ENABLED_SGM); err = bma2x2_set_en_slope_int(bma2x2, en); enable_irq_wake(bma2x2->IRQ); } else { disable_irq_wake(bma2x2->IRQ); err = bma2x2_set_en_slope_int(bma2x2, en); err = bma2x2_set_mode(bma2x2->bma2x2_client, BMA2X2_MODE_SUSPEND, BMA_ENABLED_SGM); } atomic_set(&bma2x2->en_sig_motion, en); } return err; } static ssize_t bma2x2_en_sig_motion_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if ((data == 0) || (data == 1)) bma2x2_set_en_sig_motion(bma2x2, data); return count; } #endif #ifdef CONFIG_DOUBLE_TAP static int bma2x2_set_en_single_tap_int(struct bma2x2_data *bma2x2, int en) { int err; struct i2c_client *client = bma2x2->bma2x2_client; if (en) { /* set tap interruption parameter here if needed. bma2x2_set_tap_duration(client, 0xc0); bma2x2_set_tap_threshold(client, 0x16); */ /*Enable the single tap interrupts*/ err = bma2x2_set_Int_Enable(client, 8, 1); #ifdef BMA2X2_ENABLE_INT1 err += bma2x2_set_int1_pad_sel(client, PAD_SINGLE_TAP); #else err += bma2x2_set_int2_pad_sel(client, PAD_SINGLE_TAP); #endif } else { err = bma2x2_set_Int_Enable(client, 8, 0); } return err; } static ssize_t bma2x2_tap_time_period_show(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); return sprintf(buf, "%d\n", bma2x2->tap_time_period); } static ssize_t bma2x2_tap_time_period_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; bma2x2->tap_time_period = data; return count; } static ssize_t bma2x2_en_double_tap_show(struct device *dev, struct device_attribute *attr, char *buf) { struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); return sprintf(buf, "%d\n", atomic_read(&bma2x2->en_double_tap)); } static int bma2x2_set_en_double_tap(struct bma2x2_data *bma2x2, int en) { int err = 0; en = (en >= 1) ? 1 : 0; if (atomic_read(&bma2x2->en_double_tap) != en) { if (en) { err = bma2x2_set_mode(bma2x2->bma2x2_client, BMA2X2_MODE_NORMAL, BMA_ENABLED_DTAP); err = bma2x2_set_en_single_tap_int(bma2x2, en); } else { err = bma2x2_set_en_single_tap_int(bma2x2, en); err = bma2x2_set_mode(bma2x2->bma2x2_client, BMA2X2_MODE_SUSPEND, BMA_ENABLED_DTAP); } atomic_set(&bma2x2->en_double_tap, en); } return err; } static ssize_t bma2x2_en_double_tap_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { unsigned long data; int error; struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *bma2x2 = i2c_get_clientdata(client); error = kstrtoul(buf, 10, &data); if (error) return error; if ((data == 0) || (data == 1)) bma2x2_set_en_double_tap(bma2x2, data); return count; } static void bma2x2_tap_timeout_handle(unsigned long data) { struct bma2x2_data *bma2x2 = (struct bma2x2_data *)data; printk(KERN_INFO "tap interrupt handle, timeout\n"); mutex_lock(&bma2x2->tap_mutex); bma2x2->tap_times = 0; mutex_unlock(&bma2x2->tap_mutex); /* if a single tap need to report, open the define */ #ifdef REPORT_SINGLE_TAP_WHEN_DOUBLE_TAP_SENSOR_ENABLED input_report_rel(bma2x2->dev_interrupt, SINGLE_TAP_INTERRUPT, SINGLE_TAP_INTERRUPT_HAPPENED); input_sync(bma2x2->dev_interrupt); #endif } #endif static DEVICE_ATTR(range, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_range_show, bma2x2_range_store); static DEVICE_ATTR(bandwidth, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_bandwidth_show, bma2x2_bandwidth_store); static DEVICE_ATTR(op_mode, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_mode_show, bma2x2_mode_store); static DEVICE_ATTR(value, S_IRUGO, bma2x2_value_show, NULL); static DEVICE_ATTR(value_cache, S_IRUGO, bma2x2_value_cache_show, NULL); static DEVICE_ATTR(delay, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_delay_show, bma2x2_delay_store); static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_enable_show, bma2x2_enable_store); static DEVICE_ATTR(SleepDur, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_SleepDur_show, bma2x2_SleepDur_store); static DEVICE_ATTR(fast_calibration_x, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_fast_calibration_x_show, bma2x2_fast_calibration_x_store); static DEVICE_ATTR(fast_calibration_y, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_fast_calibration_y_show, bma2x2_fast_calibration_y_store); static DEVICE_ATTR(fast_calibration_z, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_fast_calibration_z_show, bma2x2_fast_calibration_z_store); static DEVICE_ATTR(fifo_mode, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_fifo_mode_show, bma2x2_fifo_mode_store); static DEVICE_ATTR(fifo_framecount, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_fifo_framecount_show, bma2x2_fifo_framecount_store); static DEVICE_ATTR(fifo_trig, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_fifo_trig_show, bma2x2_fifo_trig_store); static DEVICE_ATTR(fifo_trig_src, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_fifo_trig_src_show, bma2x2_fifo_trig_src_store); static DEVICE_ATTR(fifo_data_sel, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_fifo_data_sel_show, bma2x2_fifo_data_sel_store); static DEVICE_ATTR(fifo_data_frame, S_IRUGO, bma2x2_fifo_data_out_frame_show, NULL); static DEVICE_ATTR(reg, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_register_show, bma2x2_register_store); static DEVICE_ATTR(chip_id, S_IRUGO, bma2x2_chip_id_show, NULL); static DEVICE_ATTR(offset_x, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_offset_x_show, bma2x2_offset_x_store); static DEVICE_ATTR(offset_y, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_offset_y_show, bma2x2_offset_y_store); static DEVICE_ATTR(offset_z, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_offset_z_show, bma2x2_offset_z_store); static DEVICE_ATTR(enable_int, S_IWUSR|S_IWGRP, NULL, bma2x2_enable_int_store); static DEVICE_ATTR(int_mode, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_int_mode_show, bma2x2_int_mode_store); static DEVICE_ATTR(slope_duration, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_slope_duration_show, bma2x2_slope_duration_store); static DEVICE_ATTR(slope_threshold, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_slope_threshold_show, bma2x2_slope_threshold_store); static DEVICE_ATTR(slope_no_mot_duration, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_slope_no_mot_duration_show, bma2x2_slope_no_mot_duration_store); static DEVICE_ATTR(slope_no_mot_threshold, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_slope_no_mot_threshold_show, bma2x2_slope_no_mot_threshold_store); static DEVICE_ATTR(high_g_duration, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_high_g_duration_show, bma2x2_high_g_duration_store); static DEVICE_ATTR(high_g_threshold, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_high_g_threshold_show, bma2x2_high_g_threshold_store); static DEVICE_ATTR(low_g_duration, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_low_g_duration_show, bma2x2_low_g_duration_store); static DEVICE_ATTR(low_g_threshold, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_low_g_threshold_show, bma2x2_low_g_threshold_store); static DEVICE_ATTR(tap_duration, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_tap_duration_show, bma2x2_tap_duration_store); static DEVICE_ATTR(tap_threshold, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_tap_threshold_show, bma2x2_tap_threshold_store); static DEVICE_ATTR(tap_quiet, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_tap_quiet_show, bma2x2_tap_quiet_store); static DEVICE_ATTR(tap_shock, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_tap_shock_show, bma2x2_tap_shock_store); static DEVICE_ATTR(tap_samp, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_tap_samp_show, bma2x2_tap_samp_store); static DEVICE_ATTR(orient_mode, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_orient_mode_show, bma2x2_orient_mode_store); static DEVICE_ATTR(orient_blocking, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_orient_blocking_show, bma2x2_orient_blocking_store); static DEVICE_ATTR(orient_hyst, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_orient_hyst_show, bma2x2_orient_hyst_store); static DEVICE_ATTR(orient_theta, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_orient_theta_show, bma2x2_orient_theta_store); static DEVICE_ATTR(flat_theta, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_flat_theta_show, bma2x2_flat_theta_store); static DEVICE_ATTR(flat_hold_time, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_flat_hold_time_show, bma2x2_flat_hold_time_store); static DEVICE_ATTR(selftest, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_selftest_show, bma2x2_selftest_store); static DEVICE_ATTR(softreset, S_IWUSR|S_IWGRP, NULL, bma2x2_softreset_store); static DEVICE_ATTR(temperature, S_IRUGO, bma2x2_temperature_show, NULL); static DEVICE_ATTR(place, S_IRUGO, bma2x2_place_show, NULL); #ifdef CONFIG_SIG_MOTION static DEVICE_ATTR(en_sig_motion, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_en_sig_motion_show, bma2x2_en_sig_motion_store); #endif #ifdef CONFIG_DOUBLE_TAP static DEVICE_ATTR(tap_time_period, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_tap_time_period_show, bma2x2_tap_time_period_store); static DEVICE_ATTR(en_double_tap, S_IRUGO|S_IWUSR|S_IWGRP, bma2x2_en_double_tap_show, bma2x2_en_double_tap_store); #endif static struct attribute *bma2x2_attributes[] = { &dev_attr_range.attr, &dev_attr_bandwidth.attr, &dev_attr_op_mode.attr, &dev_attr_value.attr, &dev_attr_value_cache.attr, &dev_attr_delay.attr, &dev_attr_enable.attr, &dev_attr_SleepDur.attr, &dev_attr_reg.attr, &dev_attr_fast_calibration_x.attr, &dev_attr_fast_calibration_y.attr, &dev_attr_fast_calibration_z.attr, &dev_attr_fifo_mode.attr, &dev_attr_fifo_framecount.attr, &dev_attr_fifo_trig.attr, &dev_attr_fifo_trig_src.attr, &dev_attr_fifo_data_sel.attr, &dev_attr_fifo_data_frame.attr, &dev_attr_chip_id.attr, &dev_attr_offset_x.attr, &dev_attr_offset_y.attr, &dev_attr_offset_z.attr, &dev_attr_enable_int.attr, &dev_attr_int_mode.attr, &dev_attr_slope_duration.attr, &dev_attr_slope_threshold.attr, &dev_attr_slope_no_mot_duration.attr, &dev_attr_slope_no_mot_threshold.attr, &dev_attr_high_g_duration.attr, &dev_attr_high_g_threshold.attr, &dev_attr_low_g_duration.attr, &dev_attr_low_g_threshold.attr, &dev_attr_tap_threshold.attr, &dev_attr_tap_duration.attr, &dev_attr_tap_quiet.attr, &dev_attr_tap_shock.attr, &dev_attr_tap_samp.attr, &dev_attr_orient_mode.attr, &dev_attr_orient_blocking.attr, &dev_attr_orient_hyst.attr, &dev_attr_orient_theta.attr, &dev_attr_flat_theta.attr, &dev_attr_flat_hold_time.attr, &dev_attr_selftest.attr, &dev_attr_softreset.attr, &dev_attr_temperature.attr, &dev_attr_place.attr, #ifdef CONFIG_SIG_MOTION &dev_attr_en_sig_motion.attr, #endif #ifdef CONFIG_DOUBLE_TAP &dev_attr_en_double_tap.attr, #endif NULL }; static struct attribute_group bma2x2_attribute_group = { .attrs = bma2x2_attributes }; #ifdef CONFIG_SIG_MOTION static struct attribute *bma2x2_sig_motion_attributes[] = { &dev_attr_slope_duration.attr, &dev_attr_slope_threshold.attr, &dev_attr_en_sig_motion.attr, NULL }; static struct attribute_group bma2x2_sig_motion_attribute_group = { .attrs = bma2x2_sig_motion_attributes }; #endif #ifdef CONFIG_DOUBLE_TAP static struct attribute *bma2x2_double_tap_attributes[] = { &dev_attr_tap_threshold.attr, &dev_attr_tap_duration.attr, &dev_attr_tap_quiet.attr, &dev_attr_tap_shock.attr, &dev_attr_tap_samp.attr, &dev_attr_tap_time_period.attr, &dev_attr_en_double_tap.attr, NULL }; static struct attribute_group bma2x2_double_tap_attribute_group = { .attrs = bma2x2_double_tap_attributes }; #endif #if defined(BMA2X2_ENABLE_INT1) || defined(BMA2X2_ENABLE_INT2) unsigned char *orient[] = {"upward looking portrait upright", "upward looking portrait upside-down", "upward looking landscape left", "upward looking landscape right", "downward looking portrait upright", "downward looking portrait upside-down", "downward looking landscape left", "downward looking landscape right"}; static void bma2x2_high_g_interrupt_handle(struct bma2x2_data *bma2x2) { unsigned char first_value = 0; unsigned char sign_value = 0; int i; for (i = 0; i < 3; i++) { bma2x2_get_HIGH_first(bma2x2->bma2x2_client, i, &first_value); if (first_value == 1) { bma2x2_get_HIGH_sign(bma2x2->bma2x2_client, &sign_value); if (sign_value == 1) { if (i == 0) input_report_rel(bma2x2->dev_interrupt, HIGH_G_INTERRUPT, HIGH_G_INTERRUPT_X_N); if (i == 1) input_report_rel(bma2x2->dev_interrupt, HIGH_G_INTERRUPT, HIGH_G_INTERRUPT_Y_N); if (i == 2) input_report_rel(bma2x2->dev_interrupt, HIGH_G_INTERRUPT, HIGH_G_INTERRUPT_Z_N); } else { if (i == 0) input_report_rel(bma2x2->dev_interrupt, HIGH_G_INTERRUPT, HIGH_G_INTERRUPT_X); if (i == 1) input_report_rel(bma2x2->dev_interrupt, HIGH_G_INTERRUPT, HIGH_G_INTERRUPT_Y); if (i == 2) input_report_rel(bma2x2->dev_interrupt, HIGH_G_INTERRUPT, HIGH_G_INTERRUPT_Z); } } printk(KERN_INFO "High G interrupt happened,exis is %d," "first is %d,sign is %d\n", i, first_value, sign_value); } } #ifndef CONFIG_SIG_MOTION static void bma2x2_slope_interrupt_handle(struct bma2x2_data *bma2x2) { unsigned char first_value = 0; unsigned char sign_value = 0; int i; for (i = 0; i < 3; i++) { bma2x2_get_slope_first(bma2x2->bma2x2_client, i, &first_value); if (first_value == 1) { bma2x2_get_slope_sign(bma2x2->bma2x2_client, &sign_value); if (sign_value == 1) { if (i == 0) input_report_rel(bma2x2->dev_interrupt, SLOP_INTERRUPT, SLOPE_INTERRUPT_X_N); if (i == 1) input_report_rel(bma2x2->dev_interrupt, SLOP_INTERRUPT, SLOPE_INTERRUPT_Y_N); if (i == 2) input_report_rel(bma2x2->dev_interrupt, SLOP_INTERRUPT, SLOPE_INTERRUPT_Z_N); } else { if (i == 0) input_report_rel(bma2x2->dev_interrupt, SLOP_INTERRUPT, SLOPE_INTERRUPT_X); if (i == 1) input_report_rel(bma2x2->dev_interrupt, SLOP_INTERRUPT, SLOPE_INTERRUPT_Y); if (i == 2) input_report_rel(bma2x2->dev_interrupt, SLOP_INTERRUPT, SLOPE_INTERRUPT_Z); } } printk(KERN_INFO "Slop interrupt happened,exis is %d," "first is %d,sign is %d\n", i, first_value, sign_value); } } #endif static void bma2x2_irq_work_func(struct work_struct *work) { struct bma2x2_data *bma2x2 = container_of((struct work_struct *)work, struct bma2x2_data, irq_work); #ifdef CONFIG_DOUBLE_TAP struct i2c_client *client = bma2x2->bma2x2_client; #endif unsigned char status = 0; unsigned char first_value = 0; unsigned char sign_value = 0; #ifdef CONFIG_BMA_ENABLE_NEWDATA_INT static struct bma2x2acc acc; bma2x2_get_interruptstatus2(bma2x2->bma2x2_client, &status); if ((status&0x80) == 0x80) { /* printk(KERN_INFO "New data interrupt happened\n");*/ bma2x2_read_accel_xyz(bma2x2->bma2x2_client, bma2x2->sensor_type, &acc); input_report_abs(bma2x2->input, ABS_X, acc.x); input_report_abs(bma2x2->input, ABS_Y, acc.y); input_report_abs(bma2x2->input, ABS_Z, acc.z); input_sync(bma2x2->input); mutex_lock(&bma2x2->value_mutex); bma2x2->value = acc; mutex_unlock(&bma2x2->value_mutex); return; } #endif bma2x2_get_interruptstatus1(bma2x2->bma2x2_client, &status); printk(KERN_INFO "bma2x2_irq_work_func, status = 0x%x\n", status); #ifdef CONFIG_SIG_MOTION if (status & 0x04) { if (atomic_read(&bma2x2->en_sig_motion) == 1) { printk(KERN_INFO "Significant motion interrupt happened\n"); /* close sig sensor, it will be open again if APP wants */ bma2x2_set_en_sig_motion(bma2x2, 0); input_report_rel(bma2x2->dev_interrupt, SLOP_INTERRUPT, 1); input_sync(bma2x2->dev_interrupt); } } #endif #ifdef CONFIG_DOUBLE_TAP if (status & 0x20) { if (atomic_read(&bma2x2->en_double_tap) == 1) { printk(KERN_INFO "single tap interrupt happened\n"); bma2x2_set_Int_Enable(client, 8, 0); if (bma2x2->tap_times == 0) { mod_timer(&bma2x2->tap_timer, jiffies + msecs_to_jiffies(bma2x2->tap_time_period)); bma2x2->tap_times = 1; } else { /* only double tap is judged */ printk(KERN_INFO "double tap\n"); mutex_lock(&bma2x2->tap_mutex); bma2x2->tap_times = 0; del_timer(&bma2x2->tap_timer); mutex_unlock(&bma2x2->tap_mutex); input_report_rel(bma2x2->dev_interrupt, DOUBLE_TAP_INTERRUPT, DOUBLE_TAP_INTERRUPT_HAPPENED); input_sync(bma2x2->dev_interrupt); } bma2x2_set_Int_Enable(client, 8, 1); } } #endif switch (status) { case 0x01: printk(KERN_INFO "Low G interrupt happened\n"); input_report_rel(bma2x2->dev_interrupt, LOW_G_INTERRUPT, LOW_G_INTERRUPT_HAPPENED); break; case 0x02: bma2x2_high_g_interrupt_handle(bma2x2); break; #ifndef CONFIG_SIG_MOTION case 0x04: bma2x2_slope_interrupt_handle(bma2x2); break; #endif case 0x08: printk(KERN_INFO "slow/ no motion interrupt happened\n"); input_report_rel(bma2x2->dev_interrupt, SLOW_NO_MOTION_INTERRUPT, SLOW_NO_MOTION_INTERRUPT_HAPPENED); break; #ifndef CONFIG_DOUBLE_TAP case 0x10: printk(KERN_INFO "double tap interrupt happened\n"); input_report_rel(bma2x2->dev_interrupt, DOUBLE_TAP_INTERRUPT, DOUBLE_TAP_INTERRUPT_HAPPENED); break; case 0x20: printk(KERN_INFO "single tap interrupt happened\n"); input_report_rel(bma2x2->dev_interrupt, SINGLE_TAP_INTERRUPT, SINGLE_TAP_INTERRUPT_HAPPENED); break; #endif case 0x40: bma2x2_get_orient_status(bma2x2->bma2x2_client, &first_value); printk(KERN_INFO "orient interrupt happened,%s\n", orient[first_value]); if (first_value == 0) input_report_abs(bma2x2->dev_interrupt, ORIENT_INTERRUPT, UPWARD_PORTRAIT_UP_INTERRUPT_HAPPENED); else if (first_value == 1) input_report_abs(bma2x2->dev_interrupt, ORIENT_INTERRUPT, UPWARD_PORTRAIT_DOWN_INTERRUPT_HAPPENED); else if (first_value == 2) input_report_abs(bma2x2->dev_interrupt, ORIENT_INTERRUPT, UPWARD_LANDSCAPE_LEFT_INTERRUPT_HAPPENED); else if (first_value == 3) input_report_abs(bma2x2->dev_interrupt, ORIENT_INTERRUPT, UPWARD_LANDSCAPE_RIGHT_INTERRUPT_HAPPENED); else if (first_value == 4) input_report_abs(bma2x2->dev_interrupt, ORIENT_INTERRUPT, DOWNWARD_PORTRAIT_UP_INTERRUPT_HAPPENED); else if (first_value == 5) input_report_abs(bma2x2->dev_interrupt, ORIENT_INTERRUPT, DOWNWARD_PORTRAIT_DOWN_INTERRUPT_HAPPENED); else if (first_value == 6) input_report_abs(bma2x2->dev_interrupt, ORIENT_INTERRUPT, DOWNWARD_LANDSCAPE_LEFT_INTERRUPT_HAPPENED); else if (first_value == 7) input_report_abs(bma2x2->dev_interrupt, ORIENT_INTERRUPT, DOWNWARD_LANDSCAPE_RIGHT_INTERRUPT_HAPPENED); break; case 0x80: bma2x2_get_orient_flat_status(bma2x2->bma2x2_client, &sign_value); printk(KERN_INFO "flat interrupt happened,flat status is %d\n", sign_value); if (sign_value == 1) { input_report_abs(bma2x2->dev_interrupt, FLAT_INTERRUPT, FLAT_INTERRUPT_TURE_HAPPENED); } else { input_report_abs(bma2x2->dev_interrupt, FLAT_INTERRUPT, FLAT_INTERRUPT_FALSE_HAPPENED); } break; default: break; } } static irqreturn_t bma2x2_irq_handler(int irq, void *handle) { struct bma2x2_data *data = handle; if (data == NULL) return IRQ_HANDLED; if (data->bma2x2_client == NULL) return IRQ_HANDLED; schedule_work(&data->irq_work); return IRQ_HANDLED; } #endif /* defined(BMA2X2_ENABLE_INT1)||defined(BMA2X2_ENABLE_INT2) */ static int bma2x2_probe(struct i2c_client *client, const struct i2c_device_id *id) { int err = 0; struct bma2x2_data *data; struct input_dev *dev; struct bst_dev *dev_acc; struct device_node *np = NULL; int irq_number = 0; struct gpio_config config; #if defined(BMA2X2_ENABLE_INT1) || defined(BMA2X2_ENABLE_INT2) struct bosch_sensor_specific *pdata; #endif struct input_dev *dev_interrupt; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { printk(KERN_INFO "i2c_check_functionality error\n"); err = -EIO; goto exit; } data = kzalloc(sizeof(struct bma2x2_data), GFP_KERNEL); if (!data) { err = -ENOMEM; goto exit; } /* do soft reset */ mdelay(5); if (bma2x2_soft_reset(client) < 0) { dev_err(&client->dev, "i2c bus write error, pls check HW connection\n"); err = -EINVAL; goto kfree_exit; } mdelay(5); /* read and check chip id */ if (bma2x2_check_chip_id(client, data) < 0) { err = -EINVAL; goto kfree_exit; } i2c_set_clientdata(client, data); data->bma2x2_client = client; mutex_init(&data->value_mutex); mutex_init(&data->mode_mutex); mutex_init(&data->enable_mutex); bma2x2_set_bandwidth(client, BMA2X2_BW_SET); bma2x2_set_range(client, BMA2X2_RANGE_SET); #if defined(BMA2X2_ENABLE_INT1) || defined(BMA2X2_ENABLE_INT2) pdata = client->dev.platform_data; if (pdata) { if (pdata->irq_gpio_cfg && (pdata->irq_gpio_cfg() < 0)) { dev_err(&client->dev, "IRQ GPIO conf. error %d\n", client->irq); } } #ifdef BMA2X2_ENABLE_INT1 /* maps interrupt to INT1 pin */ bma2x2_set_int1_pad_sel(client, PAD_LOWG); bma2x2_set_int1_pad_sel(client, PAD_HIGHG); bma2x2_set_int1_pad_sel(client, PAD_SLOP); bma2x2_set_int1_pad_sel(client, PAD_DOUBLE_TAP); bma2x2_set_int1_pad_sel(client, PAD_SINGLE_TAP); bma2x2_set_int1_pad_sel(client, PAD_ORIENT); bma2x2_set_int1_pad_sel(client, PAD_FLAT); bma2x2_set_int1_pad_sel(client, PAD_SLOW_NO_MOTION); #ifdef CONFIG_BMA_ENABLE_NEWDATA_INT bma2x2_set_newdata(client, BMA2X2_INT1_NDATA, 1); bma2x2_set_newdata(client, BMA2X2_INT2_NDATA, 0); #endif #endif #ifdef BMA2X2_ENABLE_INT2 /* maps interrupt to INT2 pin */ bma2x2_set_int2_pad_sel(client, PAD_LOWG); bma2x2_set_int2_pad_sel(client, PAD_HIGHG); bma2x2_set_int2_pad_sel(client, PAD_SLOP); bma2x2_set_int2_pad_sel(client, PAD_DOUBLE_TAP); bma2x2_set_int2_pad_sel(client, PAD_SINGLE_TAP); bma2x2_set_int2_pad_sel(client, PAD_ORIENT); bma2x2_set_int2_pad_sel(client, PAD_FLAT); bma2x2_set_int2_pad_sel(client, PAD_SLOW_NO_MOTION); #ifdef CONFIG_BMA_ENABLE_NEWDATA_INT bma2x2_set_newdata(client, BMA2X2_INT1_NDATA, 0); bma2x2_set_newdata(client, BMA2X2_INT2_NDATA, 1); #endif #endif bma2x2_set_Int_Mode(client, 1);/*latch interrupt 250ms*/ /* do not open any interrupt here */ /*10,orient 11,flat*/ /* bma2x2_set_Int_Enable(client, 10, 1); */ /* bma2x2_set_Int_Enable(client, 11, 1); */ #ifdef CONFIG_BMA_ENABLE_NEWDATA_INT /* enable new data interrupt */ bma2x2_set_Int_Enable(client, 4, 1); #endif np = of_find_node_by_name(NULL, "gsensor"); if (!np) { pr_err("ERROR! get gsensor_para failed, func:%s, line:%d\n", __FUNCTION__, __LINE__); } irq_number = of_get_named_gpio_flags(np, "gsensor_int1", 0, (enum of_gpio_flags *)&config); if (!gpio_is_valid(irq_number)) { pr_err("aw==== gpio valid\n"); } gsensor_info.int_number = irq_number; /*register irq*/ irq_number = gpio_to_irq(gsensor_info.int_number); client->irq = irq_number; data->IRQ = client->irq; err = request_irq(data->IRQ, bma2x2_irq_handler, IRQF_TRIGGER_RISING, "bma2x2", data); #ifdef CONFIG_SIG_MOTION enable_irq_wake(data->IRQ); #endif if (err) dev_err(&client->dev, "could not request irq\n"); INIT_WORK(&data->irq_work, bma2x2_irq_work_func); #endif #ifndef CONFIG_BMA_ENABLE_NEWDATA_INT data->workqueue = create_singlethread_workqueue(dev_name(&client->dev)); if (!data->workqueue) { err = -ESRCH; printk("bma2x2 creat workqueue fail!\n"); goto kfree_exit; } INIT_DELAYED_WORK(&data->work, bma2x2_work_func); #endif atomic_set(&data->delay, BMA2X2_MAX_DELAY); atomic_set(&data->enable, 0); dev = input_allocate_device(); if (!dev) return -ENOMEM; dev_interrupt = input_allocate_device(); if (!dev_interrupt) { kfree(data); input_free_device(dev); /*free the successful dev and return*/ return -ENOMEM; } /* only value events reported */ dev->name = SENSOR_NAME; dev->id.bustype = BUS_I2C; input_set_capability(dev, EV_ABS, ABS_MISC); input_set_abs_params(dev, ABS_X, ABSMIN, ABSMAX, 0, 0); input_set_abs_params(dev, ABS_Y, ABSMIN, ABSMAX, 0, 0); input_set_abs_params(dev, ABS_Z, ABSMIN, ABSMAX, 0, 0); input_set_drvdata(dev, data); err = input_register_device(dev); if (err < 0) goto err_register_input_device; /* all interrupt generated events are moved to interrupt input devices*/ dev_interrupt->name = "bma_interrupt"; dev_interrupt->id.bustype = BUS_I2C; input_set_capability(dev_interrupt, EV_REL, SLOW_NO_MOTION_INTERRUPT); input_set_capability(dev_interrupt, EV_REL, LOW_G_INTERRUPT); input_set_capability(dev_interrupt, EV_REL, HIGH_G_INTERRUPT); input_set_capability(dev_interrupt, EV_REL, SLOP_INTERRUPT); input_set_capability(dev_interrupt, EV_REL, DOUBLE_TAP_INTERRUPT); input_set_capability(dev_interrupt, EV_REL, SINGLE_TAP_INTERRUPT); input_set_capability(dev_interrupt, EV_ABS, ORIENT_INTERRUPT); input_set_capability(dev_interrupt, EV_ABS, FLAT_INTERRUPT); input_set_drvdata(dev_interrupt, data); err = input_register_device(dev_interrupt); if (err < 0) goto err_register_input_device_interrupt; data->dev_interrupt = dev_interrupt; data->input = dev; #ifdef CONFIG_SIG_MOTION data->g_sensor_class = class_create(THIS_MODULE, "sig_sensor"); if (IS_ERR(data->g_sensor_class)) { err = PTR_ERR(data->g_sensor_class); data->g_sensor_class = NULL; printk(KERN_ERR "could not allocate g_sensor_class\n"); goto err_create_class; } data->g_sensor_dev = device_create(data->g_sensor_class, NULL, 0, "%s", "g_sensor"); if (unlikely(IS_ERR(data->g_sensor_dev))) { err = PTR_ERR(data->g_sensor_dev); data->g_sensor_dev = NULL; printk(KERN_ERR "could not allocate g_sensor_dev\n"); goto err_create_g_sensor_device; } dev_set_drvdata(data->g_sensor_dev, data); err = sysfs_create_group(&data->g_sensor_dev->kobj, &bma2x2_sig_motion_attribute_group); if (err < 0) goto error_sysfs; #endif #ifdef CONFIG_DOUBLE_TAP data->g_sensor_class_doubletap = class_create(THIS_MODULE, "dtap_sensor"); if (IS_ERR(data->g_sensor_class_doubletap)) { err = PTR_ERR(data->g_sensor_class_doubletap); data->g_sensor_class_doubletap = NULL; printk(KERN_ERR "could not allocate g_sensor_class_doubletap\n"); goto err_create_class; } data->g_sensor_dev_doubletap = device_create( data->g_sensor_class_doubletap, NULL, 0, "%s", "g_sensor"); if (unlikely(IS_ERR(data->g_sensor_dev_doubletap))) { err = PTR_ERR(data->g_sensor_dev_doubletap); data->g_sensor_dev_doubletap = NULL; printk(KERN_ERR "could not allocate g_sensor_dev_doubletap\n"); goto err_create_g_sensor_device_double_tap; } dev_set_drvdata(data->g_sensor_dev_doubletap, data); err = sysfs_create_group(&data->g_sensor_dev_doubletap->kobj, &bma2x2_double_tap_attribute_group); if (err < 0) goto error_sysfs; #endif err = sysfs_create_group(&data->input->dev.kobj, &bma2x2_attribute_group); if (err < 0) goto error_sysfs; dev_acc = bst_allocate_device(); if (!dev_acc) { err = -ENOMEM; goto error_sysfs; } dev_acc->name = ACC_NAME; bst_set_drvdata(dev_acc, data); err = bst_register_device(dev_acc); if (err < 0) goto bst_free_acc_exit; data->bst_acc = dev_acc; err = sysfs_create_group(&data->bst_acc->dev.kobj, &bma2x2_attribute_group); if (err < 0) goto bst_free_exit; if (NULL != client->dev.platform_data) { data->bst_pd = kzalloc(sizeof(*data->bst_pd), GFP_KERNEL); if (NULL != data->bst_pd) { memcpy(data->bst_pd, client->dev.platform_data, sizeof(*data->bst_pd)); dev_notice(&client->dev, "%s sensor driver set place: p%d", data->bst_pd->name, data->bst_pd->place); } } #ifdef CONFIG_HAS_EARLYSUSPEND data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; data->early_suspend.suspend = bma2x2_early_suspend; data->early_suspend.resume = bma2x2_late_resume; register_early_suspend(&data->early_suspend); #endif data->bma_mode_enabled = 0; data->fifo_datasel = 0; data->fifo_count = 0; #ifdef CONFIG_SIG_MOTION atomic_set(&data->en_sig_motion, 0); #endif #ifdef CONFIG_DOUBLE_TAP atomic_set(&data->en_double_tap, 0); data->tap_times = 0; data->tap_time_period = DEFAULT_TAP_JUDGE_PERIOD; mutex_init(&data->tap_mutex); setup_timer(&data->tap_timer, bma2x2_tap_timeout_handle, (unsigned long)data); #endif dev_notice(&client->dev, "BMA2x2 driver probe successfully"); return 0; bst_free_exit: bst_unregister_device(dev_acc); bst_free_acc_exit: bst_free_device(dev_acc); error_sysfs: input_unregister_device(data->input); #ifdef CONFIG_DOUBLE_TAP err_create_g_sensor_device_double_tap: class_destroy(data->g_sensor_class_doubletap); #endif #ifdef CONFIG_SIG_MOTION err_create_g_sensor_device: class_destroy(data->g_sensor_class); #endif #if defined(CONFIG_SIG_MOTION) || defined(CONFIG_DOUBLE_TAP) err_create_class: input_unregister_device(data->dev_interrupt); #endif err_register_input_device_interrupt: input_free_device(dev_interrupt); input_unregister_device(data->input); err_register_input_device: input_free_device(dev); destroy_workqueue(data->workqueue); kfree_exit: if ((NULL != data) && (NULL != data->bst_pd)) { kfree(data->bst_pd); data->bst_pd = NULL; } kfree(data); exit: return err; } #ifdef CONFIG_HAS_EARLYSUSPEND static void bma2x2_early_suspend(struct early_suspend *h) { struct bma2x2_data *data = container_of(h, struct bma2x2_data, early_suspend); mutex_lock(&data->enable_mutex); if (atomic_read(&data->enable) == 1) { bma2x2_set_mode(data->bma2x2_client, BMA2X2_MODE_SUSPEND, BMA_ENABLED_INPUT); #ifndef CONFIG_BMA_ENABLE_NEWDATA_INT cancel_delayed_work_sync(&data->work); flush_workqueue(data->workqueue); #endif } mutex_unlock(&data->enable_mutex); } static void bma2x2_late_resume(struct early_suspend *h) { struct bma2x2_data *data = container_of(h, struct bma2x2_data, early_suspend); mutex_lock(&data->enable_mutex); if (atomic_read(&data->enable) == 1) { bma2x2_set_mode(data->bma2x2_client, BMA2X2_MODE_NORMAL, BMA_ENABLED_INPUT); #ifndef CONFIG_BMA_ENABLE_NEWDATA_INT queue_delayed_work(data->workqueue, &data->work, msecs_to_jiffies(atomic_read(&data->delay))); #endif } mutex_unlock(&data->enable_mutex); } #endif static int bma2x2_remove(struct i2c_client *client) { struct bma2x2_data *data = i2c_get_clientdata(client); bma2x2_set_enable(&client->dev, 0); #ifdef CONFIG_HAS_EARLYSUSPEND unregister_early_suspend(&data->early_suspend); #endif sysfs_remove_group(&data->input->dev.kobj, &bma2x2_attribute_group); input_unregister_device(data->input); if (NULL != data->bst_pd) { kfree(data->bst_pd); data->bst_pd = NULL; } destroy_workqueue(data->workqueue); kfree(data); return 0; } void bma2x2_shutdown(struct i2c_client *client) { struct bma2x2_data *data = i2c_get_clientdata(client); mutex_lock(&data->enable_mutex); bma2x2_set_mode(data->bma2x2_client, BMA2X2_MODE_DEEP_SUSPEND, BMA_ENABLED_ALL); mutex_unlock(&data->enable_mutex); } #ifdef CONFIG_PM static int bma2x2_suspend(struct device *dev, pm_message_t mesg) { struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *data = i2c_get_clientdata(client); mutex_lock(&data->enable_mutex); if (atomic_read(&data->enable) == 1) { bma2x2_set_mode(data->bma2x2_client, BMA2X2_MODE_SUSPEND, BMA_ENABLED_INPUT); #ifndef CONFIG_BMA_ENABLE_NEWDATA_INT cancel_delayed_work_sync(&data->work); flush_workqueue(data->workqueue); #endif } mutex_unlock(&data->enable_mutex); if (gsensor_info.sensor_power_ldo != NULL) { regulator_disable(gsensor_info.sensor_power_ldo); /* msleep(500); */ } return 0; } static int bma2x2_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct bma2x2_data *data = i2c_get_clientdata(client); if (gsensor_info.sensor_power_ldo != NULL) { regulator_enable(gsensor_info.sensor_power_ldo); msleep(100); } mutex_lock(&data->enable_mutex); if (atomic_read(&data->enable) == 1) { bma2x2_set_mode(data->bma2x2_client, BMA2X2_MODE_NORMAL, BMA_ENABLED_INPUT); #ifndef CONFIG_BMA_ENABLE_NEWDATA_INT queue_delayed_work(data->workqueue, &data->work, msecs_to_jiffies(atomic_read(&data->delay))); #endif } mutex_unlock(&data->enable_mutex); return 0; } #else #define bma2x2_suspend NULL #define bma2x2_resume NULL #endif /* CONFIG_PM */ static const struct i2c_device_id bma2x2_id[] = { { SENSOR_NAME, 0 }, { } }; #define BMA223_CHIP_ID 0xF8 /** * gsensor_detect - Device detection callback for automatic device creation * return value: * = 0; success; * < 0; err */ static int gsensor_detect(struct i2c_client *client, struct i2c_board_info *info) { struct i2c_adapter *adapter = client->adapter; int ret; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) return -ENODEV; if (twi_id == adapter->nr) { for (i2c_num = 0; i2c_num < (sizeof(i2c_address)/sizeof(i2c_address[0])); i2c_num++) { client->addr = i2c_address[i2c_num]; pr_info("%s:addr= 0x%x,i2c_num:%d\n", __func__, client->addr, i2c_num); ret = i2c_smbus_read_byte_data(client, BMA2X2_CHIP_ID__REG); pr_info("Read ID value is :%d", ret); if ((ret & 0x00FF) == BMA255_CHIP_ID) { pr_info("Bosch Sensortec Device detected!\n"); strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE); return 0; } else if ((ret & 0x00FF) == BMA250E_CHIP_ID) { pr_info("Bosch Sensortec Device detected!\n" \ "BMA250E registered I2C driver!\n"); strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE); deep_suspend = 1; return 0; } else if ((ret & 0x00FF) == BMA223_CHIP_ID) { pr_info("Bosch Sensortec Device detected!\n" \ "BMA223 registered I2C driver!\n"); strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE); deep_suspend = 1; return 0; } } pr_info("%s:Bosch Sensortec Device not found, \ maybe the other gsensor equipment! \n", __func__); return -ENODEV; } else { return -ENODEV; } } MODULE_DEVICE_TABLE(i2c, bma2x2_id); static const struct of_device_id bma250_of_match[] = { {.compatible = "allwinner,sun8i-gsensor-para"}, {}, }; static struct i2c_driver bma2x2_driver = { .class = I2C_CLASS_HWMON, .driver = { .owner = THIS_MODULE, .name = SENSOR_NAME, .of_match_table = bma250_of_match, .suspend = bma2x2_suspend, .resume = bma2x2_resume, }, .id_table = bma2x2_id, .probe = bma2x2_probe, .remove = bma2x2_remove, .shutdown = bma2x2_shutdown, .detect = gsensor_detect, .address_list = i2c_address, }; extern struct class bst_class; static int __init BMA2X2_init(void) { int err; if (input_sensor_startup(&(gsensor_info.input_type))) { printk("%s: gsensor-bma2x2 fetch paras err.\n", __func__); return -1; } else{ err = input_sensor_init(&(gsensor_info.input_type)); if (0 != err) { printk("%s: gsensor-bma2x2 initialize platform err.\n", __func__); } } twi_id = gsensor_info.twi_id; if (gsensor_info.sensor_power_ldo != NULL) { regulator_enable(gsensor_info.sensor_power_ldo); msleep(500); } err = class_register(&bst_class); if (err) { pr_err("unable to register bst_dev class\n"); return err; } return i2c_add_driver(&bma2x2_driver); } static void __exit BMA2X2_exit(void) { /*bst class*/ class_unregister(&bst_class); i2c_del_driver(&bma2x2_driver); } MODULE_AUTHOR("contact@bosch-sensortec.com"); MODULE_DESCRIPTION("BMA2X2 ACCELEROMETER SENSOR DRIVER"); MODULE_LICENSE("GPL v2"); module_init(BMA2X2_init); module_exit(BMA2X2_exit);