我是靠谱客的博主 含糊路灯,最近开发中收集的这篇文章主要介绍全志 添加Gsensor da380 module Patch,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

add Gsensor da380 module & set Rotation Lock For Accessibility

diff --git a/android/device/softwinner/common/hardware/libhardware/libsensors/aw_sensors/sensorDetect.cpp b/android/device/softwinner/common/hardware/libhardware/libsensors/aw_sensors/sensorDetect.cpp
index 6291d54..43cb020 100755
--- a/android/device/softwinner/common/hardware/libhardware/libsensors/aw_sensors/sensorDetect.cpp
+++ b/android/device/softwinner/common/hardware/libhardware/libsensors/aw_sensors/sensorDetect.cpp
@@ -262,7 +262,22 @@ struct sensor_extend_t magSensorList[] = {
 };
 
 struct sensor_extend_t gsensorList[] = {
-        {
+		///$shh$20180925$add%
+         {
+                {
+                        "da380", LSG_DA380,
+                }, {
+                        "Bosch 3-axis Accelerometer",
+                        "da380",
+						1, 0,
+                        SENSOR_TYPE_ACCELEROMETER,
+                        6.0f*9.81f,
+                        (9.81f)/21.33f,
+                        0.2f, 0,0,0, { } ,
+                },
+        }, 
+		///$shh$20180925$add%
+		{
                 {
                         "bma250", LSG_BMA250,
                 }, {
@@ -530,6 +545,7 @@ int getDevice(struct sensor_extend_t list[], struct sensor_info *info,
 
 int otherDeviceDetect(char buf[])
 {
+		ALOGD("shh->otherDeviceDetectn");
         int number0 = 0, number1 = 0;
         int re_value = 0;
         number0 = ARRAY_SIZE(otherDevice);
diff --git a/android/device/softwinner/common/hardware/libhardware/libsensors/aw_sensors/sensors.h b/android/device/softwinner/common/hardware/libhardware/libsensors/aw_sensors/sensors.h
index 2e22a63..4275ee2 100755
--- a/android/device/softwinner/common/hardware/libhardware/libsensors/aw_sensors/sensors.h
+++ b/android/device/softwinner/common/hardware/libhardware/libsensors/aw_sensors/sensors.h
@@ -44,8 +44,8 @@ __BEGIN_DECLS
 #define ID_O                            (5)
 #define ID_T                            (6)
 #define ID_P                            (7)
-
-//#define DEBUG_SENSOR
+///$shh$20180925$
+///#define DEBUG_SENSOR
 
 #define HWROTATION_0                    (0)
 #define HWROTATION_90                   (1)
@@ -121,6 +121,7 @@ __BEGIN_DECLS
 #define LSG_MXC622X                     (64.0f)
 #define LSG_LIS3DE_ACC                  (65.0f)
 #define LSG_BMA250                      (256.0f)
+#define LSG_DA380                       (256.0f)
 #define LSG_DMARD06                     (256.0f)
 #define LSG_STK8313                     (256.0f)
 #define LSG_DMARD10                     (1024.0f)
diff --git a/android/device/softwinner/t3-p1/configs/gsensor.cfg b/android/device/softwinner/t3-p1/configs/gsensor.cfg
new file mode 100755
index 0000000..a0c6b9f
--- /dev/null
+++ b/android/device/softwinner/t3-p1/configs/gsensor.cfg
@@ -0,0 +1,117 @@
+;Direction parameter adjustment, including the x, y, z axis, and xy interchange four variables,
+;the name of the module used for identification, and drive registered name consistent
+;--------------------------
+;name:da380
+;--------------------------
+gsensor_name = da380
+gsensor_direct_x = true
+gsensor_direct_y = true
+gsensor_direct_z = true
+gsensor_xy_revert = false
+;--------------------------
+;name:bma250
+;--------------------------
+gsensor_name = bma250
+gsensor_direct_x = true
+gsensor_direct_y = true
+gsensor_direct_z = false
+gsensor_xy_revert = true
+;--------------------------
+;name:dmard06
+;--------------------------
+gsensor_name = dmard06
+gsensor_direct_x = true
+gsensor_direct_y = true
+gsensor_direct_z = true
+gsensor_xy_revert = false
+;--------------------------
+;name:mma7660
+;--------------------------
+gsensor_name = mma7660
+gsensor_direct_x = true
+gsensor_direct_y = true
+gsensor_direct_z = false
+gsensor_xy_revert = true
+;--------------------------
+;name:mma8452
+;--------------------------
+gsensor_name = mma8452
+gsensor_direct_x = true
+gsensor_direct_y = false
+gsensor_direct_z = false
+gsensor_xy_revert = false
+
+;--------------------------
+;name:kxtik
+;--------------------------
+gsensor_name = kxtik
+gsensor_direct_x = true
+gsensor_direct_y = true
+gsensor_direct_z = true
+gsensor_xy_revert = false
+;--------------------------
+;name:afa750
+;--------------------------
+gsensor_name = afa750
+gsensor_direct_x = false
+gsensor_direct_y = false
+gsensor_direct_z = false
+gsensor_xy_revert = true
+;--------------------------
+;name:mxc622x
+;--------------------------
+gsensor_name = mxc622x
+gsensor_direct_x = true
+gsensor_direct_y = false
+gsensor_direct_z = false
+gsensor_xy_revert = false
+;--------------------------
+;name:mma865x
+;--------------------------
+gsensor_name = mma865x
+gsensor_direct_x = true
+gsensor_direct_y = true
+gsensor_direct_z = false
+gsensor_xy_revert = true
+;--------------------------
+;name:lis3de_acc
+;--------------------------
+gsensor_name = lis3de_acc
+gsensor_direct_x = true
+gsensor_direct_y = true
+gsensor_direct_z = false
+gsensor_xy_revert = false
+;--------------------------
+;name:lis3dh_acc
+;--------------------------
+gsensor_name = lis3dh_acc
+gsensor_direct_x = true
+gsensor_direct_y = true
+gsensor_direct_z = false
+gsensor_xy_revert = false
+;--------------------------
+;name:stk831x
+;--------------------------
+gsensor_name = stk831x
+gsensor_direct_x = true
+gsensor_direct_y = true
+gsensor_direct_z = false
+gsensor_xy_revert = true
+;--------------------------
+;name:FreescaleAccelerometer
+;--------------------------
+gsensor_name = FreescaleAccelerometer
+gsensor_direct_x = true
+gsensor_direct_y = true
+gsensor_direct_z = true
+gsensor_xy_revert = false
+
+;--------------------------
+;name:sc7a30
+;--------------------------
+gsensor_name = sc7a30
+gsensor_direct_x = true
+gsensor_direct_y = true
+gsensor_direct_z = true
+gsensor_xy_revert = true
+
diff --git a/android/device/softwinner/t3-p1/t3_p1.mk b/android/device/softwinner/t3-p1/t3_p1.mk
index 0478010..bcb2035 100755
--- a/android/device/softwinner/t3-p1/t3_p1.mk
+++ b/android/device/softwinner/t3-p1/t3_p1.mk
@@ -50,7 +50,8 @@ PRODUCT_COPY_FILES += 
     device/softwinner/t3-p1/configs/tp.idc:system/usr/idc/tp.idc 
     device/softwinner/t3-p1/configs/sunxi-keyboard.kl:system/usr/keylayout/sunxi-keyboard.kl 
     device/softwinner/t3-p1/configs/sunxi-ir.kl:system/usr/keylayout/sunxi-ir.kl 
-    device/softwinner/t3-p1/configs/media_profiles.xml:system/etc/media_profiles.xml
+    device/softwinner/t3-p1/configs/media_profiles.xml:system/etc/media_profiles.xml 
+    device/softwinner/t3-p1/configs/gsensor.cfg:system/usr/gsensor.cfg
 
 PRODUCT_COPY_FILES += 
     frameworks/native/data/etc/android.hardware.usb.accessory.xml:system/etc/permissions/android.hardware.usb.accessory.xml
diff --git a/android/vendor/tvd/packages/TvdSettings/src/com/android/settings/DisplaySettings.java b/android/vendor/tvd/packages/TvdSettings/src/com/android/settings/DisplaySettings.java
index d3c31fd..4f61434 100755
--- a/android/vendor/tvd/packages/TvdSettings/src/com/android/settings/DisplaySettings.java
+++ b/android/vendor/tvd/packages/TvdSettings/src/com/android/settings/DisplaySettings.java
@@ -205,14 +205,15 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
 
         mAccelerometer = (CheckBoxPreference) findPreference(KEY_ACCELEROMETER);
         mAccelerometer.setPersistent(false);
-        if (!RotationPolicy.isRotationSupported(getActivity())
+		///$shh$20180924$remove$
+        /*if (!RotationPolicy.isRotationSupported(getActivity())
                 || RotationPolicy.isRotationLockToggleSupported(getActivity())) {
             // If rotation lock is supported, then we do not provide this option in
             // Display settings.  However, is still available in Accessibility settings,
             // if the device supports rotation.
             getPreferenceScreen().removePreference(mAccelerometer);
-        }
-
+        }*/
+		///$shh$20180924$remove$
 		///$shh$20180906$add$
 		mNavBarHide = (CheckBoxPreference) findPreference(KEY_NAVBAR_HIDE);
 		mStatusBarHide = (CheckBoxPreference) findPreference(KEY_STATUSBAR_HIDE);
@@ -677,8 +678,8 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
 
     private void updateAccelerometerRotationCheckbox() {
         if (getActivity() == null) return;
-
-        //mAccelerometer.setChecked(!RotationPolicy.isRotationLocked(getActivity()));
+		///$shh$20180924$add$
+        mAccelerometer.setChecked(!RotationPolicy.isRotationLocked(getActivity()));
     }
 
     public void writeFontSizePreference(Object objValue) {
@@ -695,10 +696,12 @@ public class DisplaySettings extends SettingsPreferenceFragment implements
         boolean value;
         int value2;
         try {
-            /*if (preference == mAccelerometer) {
+			///$shh$20180924$add$
+            if (preference == mAccelerometer) {
                 RotationPolicy.setRotationLockForAccessibility(
                         getActivity(), !mAccelerometer.isChecked());
-            } else */
+            }  
+			///$shh$20180924$add$
 			///$shh$20180906$add$
 			if(preference == mNavBarHide)
 			{
diff --git a/lichee/linux-3.10/arch/arm/configs/sun8iw11p1smp_android_defconfig b/lichee/linux-3.10/arch/arm/configs/sun8iw11p1smp_android_defconfig
index 0f1907a..2991861 100755
--- a/lichee/linux-3.10/arch/arm/configs/sun8iw11p1smp_android_defconfig
+++ b/lichee/linux-3.10/arch/arm/configs/sun8iw11p1smp_android_defconfig
@@ -1569,7 +1569,12 @@ CONFIG_INPUT_GPIO=y
 # CONFIG_INPUT_ADXL34X is not set
 # CONFIG_INPUT_IMS_PCU is not set
 # CONFIG_INPUT_CMA3000 is not set
-# CONFIG_INPUT_SENSOR is not set
+CONFIG_INPUT_SENSOR=y
+
+# CONFIG_SENSORS_BMA250 is not set
+# CONFIG_SENSORS_SC7A30 is not set
+# CONFIG_SENSORS_MMA7660 is not set
+CONFIG_SENSORS_DA380=m
 
 #
 # Hardware I/O ports
diff --git a/lichee/linux-3.10/drivers/input/sensor/Kconfig b/lichee/linux-3.10/drivers/input/sensor/Kconfig
index 6144521..ffde88c 100755
--- a/lichee/linux-3.10/drivers/input/sensor/Kconfig
+++ b/lichee/linux-3.10/drivers/input/sensor/Kconfig
@@ -50,4 +50,13 @@ config SENSORS_GPADC_TEST
         default n
         help
           If you say yes here you get support for the gpadc test sample
+
+config SENSORS_DA380
+	tristate "DA380 acceleration sensor support"
+	depends on INPUT_SENSOR && I2C
+	default m
+	help
+	  If you say yes here you get support for Bosch Sensortec's 
+	  acceleration sensors DA380.
+
 endif
diff --git a/lichee/linux-3.10/drivers/input/sensor/Makefile b/lichee/linux-3.10/drivers/input/sensor/Makefile
index 23ae018..8409c4f 100755
--- a/lichee/linux-3.10/drivers/input/sensor/Makefile
+++ b/lichee/linux-3.10/drivers/input/sensor/Makefile
@@ -9,4 +9,7 @@ obj-$(CONFIG_SENSORS_SC7A30)   += sc7a30.o
 obj-$(CONFIG_SENSORS_MMA7660)   += mma7660.o
 obj-$(CONFIG_SENSORS_GPADC)   += sunxi_gpadc.o
 obj-$(CONFIG_SENSORS_GPADC_TEST)   += sunxi_gpadc_test.o
+obj-$(CONFIG_SENSORS_DA380)	        += da380.o
+da380-objs:= mir3da_core.o mir3da_cust.o
+
 
diff --git a/lichee/linux-3.10/drivers/input/sensor/da380/Kconfig b/lichee/linux-3.10/drivers/input/sensor/da380/Kconfig
deleted file mode 100755
index beeee20..0000000
--- a/lichee/linux-3.10/drivers/input/sensor/da380/Kconfig
+++ /dev/null
@@ -1,11 +0,0 @@
-#
-# I2C gsensor chip drivers configuration
-#
-
-config SENSORS_DA380
-	tristate "DA380 acceleration sensor support"
-	depends on INPUT_SENSOR && I2C
-	default m
-	help
-	  If you say yes here you get support for Bosch Sensortec's 
-	  acceleration sensors DA380.
diff --git a/lichee/linux-3.10/drivers/input/sensor/da380/Makefile b/lichee/linux-3.10/drivers/input/sensor/da380/Makefile
deleted file mode 100755
index b24ad59..0000000
--- a/lichee/linux-3.10/drivers/input/sensor/da380/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Makefile for I2C gsensor chip drivers.
-#
-
-obj-$(CONFIG_SENSORS_DA380)	        += da380.o
-da380-objs:= mir3da_core.o mir3da_cust.o
-
diff --git a/lichee/linux-3.10/drivers/input/sensor/da380/mir3da_core.c b/lichee/linux-3.10/drivers/input/sensor/da380/mir3da_core.c
deleted file mode 100755
index f09cec0..0000000
--- a/lichee/linux-3.10/drivers/input/sensor/da380/mir3da_core.c
+++ /dev/null
@@ -1,2156 +0,0 @@
-/* Core file for MiraMEMS 3-Axis Accelerometer's driver. 
- *
- * mir3da_core.c - Linux kernel modules for 3-Axis Accelerometer
- *
- * Copyright (C) 2011-2013 MiraMEMS Sensing Technology Co., Ltd.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-#include "mir3da_core.h"
-#include "mir3da_cust.h"
-#include <linux/fs.h>
-#include <linux/stat.h>
-#include <linux/syscalls.h>
-
-#define MIR3DA_REG_PAGE(REG)                (((REG)>>8)&0xFF)
-#define MIR3DA_REG_ADDR(REG)                ((REG)&0xFF)
-
-#define MIR3DA_OFFSET_THRESHOLD             10
-#define PEAK_LVL                            800
-#define STICK_LSB                           2000
-#define AIX_HISTORY_SIZE                    3
-
-typedef struct reg_obj_s {
-
-	short addr;
-	unsigned char mask;
-	unsigned char value;
-
-} reg_obj_t;
-
-struct gsensor_data_fmt_s {
-
-	unsigned char msbw;
-	unsigned char lsbw;
-	unsigned char endian;	/* 0: little endian; 1: big endian */
-};
-
-struct gsensor_data_obj_s {
-
-#define MIR3DA_DATA_LEN         6
-	reg_obj_t data_sect[MIR3DA_DATA_LEN];
-	struct gsensor_data_fmt_s data_fmt;
-};
-
-struct gsensor_obj_s {
-
-	char asic[10];
-
-	reg_obj_t chip_id;
-	reg_obj_t mod_id;
-	reg_obj_t soft_reset;
-	reg_obj_t power;
-
-#define MIR3DA_INIT_SECT_LEN    11
-#define MIR3DA_OFF_SECT_LEN     MIR3DA_OFFSET_LEN
-#define MIR3DA_ODR_SECT_LEN   	3
-
-	reg_obj_t init_sect[MIR3DA_INIT_SECT_LEN];
-	reg_obj_t offset_sect[MIR3DA_OFF_SECT_LEN];
-	reg_obj_t odr_sect[MIR3DA_ODR_SECT_LEN];
-
-	struct gsensor_data_obj_s data;
-
-	int (*calibrate) (MIR_HANDLE handle, int z_dir);
-	int (*auto_calibrate) (MIR_HANDLE handle, int xyz[3]);
-	int (*int_ops) (MIR_HANDLE handle, mir_int_ops_t *ops);
-	int (*get_reg_data) (MIR_HANDLE handle, char *buf);
-};
-
-struct gsensor_drv_s {
-
-	struct general_op_s *method;
-
-	struct gsensor_obj_s *obj;
-};
-
-#define MIR3DA_SOCLE_INIT_SECTION                       { SOCLE_REG_TEMP_CFG_REG,       0xFF,   0x08    },                                  
-                                                        { SOCLE_REG_CTRL_REG5,          0xFF,   0x80    },                                  
-                                                        { SOCLE_REG_CTRL_REG4,          0x30,   0x00    },                                  
-                                                        { SOCLE_REG_CTRL_REG1,          0xFF,   0x6F    },                                  
-                                                        { SOCLE_REG_TEMP_CFG_REG,       0xFF,   0x88    },                                  
-                                                        { SOCLE_REG_LDO_REG,            0xFF,   0x02    },                                  
-                                                        { SOCLE_REG_OTP_TRIM_OSC,       0xFF,   0x27    },                                  
-                                                        { SOCLE_REG_LPF_ABSOLUTE,       0xFF,   0x30    },                                  
-                                                        { SOCLE_REG_TEMP_OFF1,          0xFF,   0x3f    },                                  
-                                                        { SOCLE_REG_TEMP_OFF2,          0xFF,   0xff    },                                  
-                                                        { SOCLE_REG_TEMP_OFF3,          0xFF,   0x0f    },                                  
-
-
-#define MIR3DA_SOCLE_OFFSET_SECTION                     { SOCLE_REG_OTP_XOFF_L,         0xFF,   0x00    },                                  
-                                                        { SOCLE_REG_OTP_XOFF_H,         0xFF,   0x00    },                                  
-                                                        { SOCLE_REG_OTP_YOFF_L,         0xFF,   0x00    },                                  
-                                                        { SOCLE_REG_OTP_YOFF_H,         0xFF,   0x00    },                                  
-                                                        { SOCLE_REG_OTP_ZOFF_L,         0xFF,   0x00    },                                  
-                                                        { SOCLE_REG_OTP_ZOFF_H,         0xFF,   0x00    },                                  
-                                                        { -1,                           0x00,   0x00    },                                  
-                                                        { -1,                           0x00,   0x00    },                                  
-                                                        { -1,                           0x00,   0x00    },                                  
-
-#define MIR3DA_SOCLE_ODR_SECTION                        { SOCLE_REG_CTRL_REG1,          0xF0,   0x40    },                                  
-                                                        { SOCLE_REG_CTRL_REG1,          0xF0,   0x50    },                                  
-                                                        { SOCLE_REG_CTRL_REG1,          0xF0,   0x60    },                                  
-
-
-#define MIR3DA_SOCLE_DATA_SECTION                     { { (SOCLE_REG_OUT_X_L|0x80),     0xFF,   0x00    },                                  
-                                                        { (SOCLE_REG_OUT_X_H|0x80),     0xFF,   0x00    },                                  
-                                                        { (SOCLE_REG_OUT_Y_L|0x80),     0xFF,   0x00    },                                  
-                                                        { (SOCLE_REG_OUT_Y_H|0x80),     0xFF,   0x00    },                                  
-                                                        { (SOCLE_REG_OUT_Z_L|0x80),     0xFF,   0x00    },                                  
-                                                        { (SOCLE_REG_OUT_Z_H|0x80),     0xFF,   0x00    } },                                
-                                                        { 8,                            4,      0       }
-
-#define MIR3DA_NSA_INIT_SECTION                         { NSA_REG_G_RANGE,              0x03,   0x02    },                                  
-                                                        { NSA_REG_POWERMODE_BW,         0xFF,   0x1e    },                                  
-                                                        { NSA_REG_ODR_AXIS_DISABLE,     0xFF,   0x07    },                                  
-                                                        { NSA_REG_INTERRUPT_SETTINGS2,  0xFF,   0x00    },                                  
-                                                        { NSA_REG_INTERRUPT_MAPPING2,   0xFF,   0x00    },                                  
-                                                        { NSA_REG_ENGINEERING_MODE,     0xFF,   0x83    },                                  
-                                                        { NSA_REG_ENGINEERING_MODE,     0xFF,   0x69    },                                  
-                                                        { NSA_REG_ENGINEERING_MODE,     0xFF,   0xBD    },                                  
-                                                        { NSA_REG_INT_PIN_CONFIG,       0x0F,   NRIPCV  },                                  
-                                                        { -1,                           0x00,   0x00    },                                  
-                                                        { -1,                           0x00,   0x00    },                                  
-
-
-#define MIR3DA_NSA_OFFSET_SECTION                       { NSA_REG_COARSE_OFFSET_TRIM_X, 0xFF,   0x00    },                                  
-                                                        { NSA_REG_COARSE_OFFSET_TRIM_Y, 0xFF,   0x00    },                                  
-                                                        { NSA_REG_COARSE_OFFSET_TRIM_Z, 0xFF,   0x00    },                                  
-                                                        { NSA_REG_FINE_OFFSET_TRIM_X,   0xFF,   0x00    },                                  
-                                                        { NSA_REG_FINE_OFFSET_TRIM_Y,   0xFF,   0x00    },                                  
-                                                        { NSA_REG_FINE_OFFSET_TRIM_Z,   0xFF,   0x00    },                                  
-                                                        { NSA_REG_CUSTOM_OFFSET_X,      0xFF,   0x00    },                                  
-                                                        { NSA_REG_CUSTOM_OFFSET_Y,      0xFF,   0x00    },                                  
-                                                        { NSA_REG_CUSTOM_OFFSET_Z,      0xFF,   0x00    },                                  
-
-#define MIR3DA_NSA_ODR_SECTION                          { NSA_REG_ODR_AXIS_DISABLE,     0x0F,   0x06    },                                  
-                                                        { NSA_REG_ODR_AXIS_DISABLE,     0x0F,   0x07    },                                  
-                                                        { NSA_REG_ODR_AXIS_DISABLE,     0x0F,   0x08    },                                  
-
-
-#define MIR3DA_NSA_DATA_SECTION                       { { NSA_REG_ACC_X_LSB,            0xFF,   0x00    },                                  
-                                                        { NSA_REG_ACC_X_MSB,            0xFF,   0x00    },                                  
-                                                        { NSA_REG_ACC_Y_LSB,            0xFF,   0x00    },                                  
-                                                        { NSA_REG_ACC_Y_MSB,            0xFF,   0x00    },                                  
-                                                        { NSA_REG_ACC_Z_LSB,            0xFF,   0x00    },                                  
-                                                        { NSA_REG_ACC_Z_MSB,            0xFF,   0x00    } },                                
-                                                        { 8,                            4,      0       }
-
-static int SOCLE_calibrate(MIR_HANDLE handle, int z_dir);
-static int SOCLE_auto_calibrate(MIR_HANDLE handle, int xyz[3]);
-static int NSA_MLM_calibrate(MIR_HANDLE handle, int z_dir);
-static int NSA_NTO_calibrate(MIR_HANDLE handle, int z_dir);
-static int NSA_MLM_auto_calibrate(MIR_HANDLE handle, int xyz[3]);
-static int NSA_NTO_auto_calibrate(MIR_HANDLE handle, int xyz[3]);
-#ifdef MIR3DA_AUTO_CALIBRATE
-static int mir3da_auto_calibrate(MIR_HANDLE handle, int x, int y, int z);
-#endif /* !MIR3DA_AUTO_CALIBRATE */
-static int SOCLE_interrupt_ops(MIR_HANDLE handle, mir_int_ops_t *ops);
-static int NSA_interrupt_ops(MIR_HANDLE handle, mir_int_ops_t *ops);
-static int SOCLE_get_reg_data(MIR_HANDLE handle, char *buf);
-static int NSA_get_reg_data(MIR_HANDLE handle, char *buf);
-
-#define MIR_SOCLE                       { "SOCLE",      { SOCLE_REG_WHO_AM_I,           0xFF,   0x13    },                                  
-                                                        { SOCLE_REG_WHO_AM_I,           0xFF,   0x13    },                                  
-                                                        { SOCLE_REG_SOFT_RESET,         0xFF,   0xAA    },                                  
-                                                        { SOCLE_REG_TEMP_CFG_REG,       0x20,   0x20    },                                  
-                                                        { MIR3DA_SOCLE_INIT_SECTION                     },                                  
-                                                        { MIR3DA_SOCLE_OFFSET_SECTION                   },                                  
-                                                        { MIR3DA_SOCLE_ODR_SECTION                      },                                  
-                                                        { MIR3DA_SOCLE_DATA_SECTION                     },                                  
-                                                          SOCLE_calibrate                                ,                                  
-                                                          SOCLE_auto_calibrate                           ,                                  
-                                                          SOCLE_interrupt_ops                            ,                                  
-                                                          SOCLE_get_reg_data                             ,                                  
-                                        }
-
-#define MIR_NSA_NTO                     { "NSA_NTO",    { NSA_REG_WHO_AM_I,             0xFF,   0x13    },                                  
-                                                        { NSA_REG_FIFO_CTRL,            0xFF,   0x00    },                                  
-                                                        { NSA_REG_SPI_I2C,              0x24,   0x24    },                                  
-                                                        { NSA_REG_POWERMODE_BW,         0xC0,   0xC0    },                                  
-                                                        { MIR3DA_NSA_INIT_SECTION                       },                                  
-                                                        { MIR3DA_NSA_OFFSET_SECTION                     },                                  
-                                                        { MIR3DA_NSA_ODR_SECTION                   	    },                                  
-                                                        { MIR3DA_NSA_DATA_SECTION                       },                                  
-                                                          NSA_NTO_calibrate                              ,                                  
-                                                          NSA_NTO_auto_calibrate                         ,                                  
-                                                          NSA_interrupt_ops                              ,                                  
-                                                          NSA_get_reg_data                               ,                                  
-                                        }
-
-#define MIR_NSA_MLM                     { "NSA_MLM",    { NSA_REG_WHO_AM_I,             0xFF,   0x13    },                                  
-                                                        { NSA_REG_FIFO_CTRL,            0xFF,   0x10    },                                  
-                                                        { NSA_REG_SPI_I2C,              0x24,   0x24    },                                  
-                                                        { NSA_REG_POWERMODE_BW,         0xC0,   0xC0    },                                  
-                                                        { MIR3DA_NSA_INIT_SECTION                       },                                  
-                                                        { MIR3DA_NSA_OFFSET_SECTION                     },                                  
-                                                        { MIR3DA_NSA_ODR_SECTION                        },                                  
-                                                        { MIR3DA_NSA_DATA_SECTION                       },                                  
-                                                          NSA_MLM_calibrate                              ,                                  
-                                                          NSA_MLM_auto_calibrate                         ,                                  
-                                                          NSA_interrupt_ops                              ,                                  
-                                                          NSA_get_reg_data                               ,                                  
-                                        }
-
-/**************************************************************** COMMON ***************************************************************************/
-#define MIR3DA_GSENSOR_SCHEME           MIR3DA_SUPPORT_CHIP_LIST
-
-/* this level can be modified while runtime through system attribute */
-int Log_level = DEBUG_ERR; /* | DEBUG_ASSERT | DEBUG_MSG | DEBUG_FUNC | DEBUG_DATA;*/
-int gsensor_mod = -1;		/* Initial value */
-static struct gsensor_obj_s mir3da_gsensor[] = { MIR3DA_GSENSOR_SCHEME };
-
-struct gsensor_drv_s mir3da_gsensor_drv;
-
-#define MI_DATA(format, ...)            if(DEBUG_DATA&Log_level){mir3da_gsensor_drv.method->myprintf(MI_TAG format "n", ## __VA_ARGS__);}
-#define MI_MSG(format, ...)             if(DEBUG_MSG&Log_level){mir3da_gsensor_drv.method->myprintf(MI_TAG format "n", ## __VA_ARGS__);}
-#define MI_ERR(format, ...)             if(DEBUG_ERR&Log_level){mir3da_gsensor_drv.method->myprintf(MI_TAG format "n", ## __VA_ARGS__);}
-#define MI_FUN                          if(DEBUG_FUNC&Log_level){mir3da_gsensor_drv.method->myprintf(MI_TAG "%s is called, line: %dn", __FUNCTION__,__LINE__);}
-#define MI_ASSERT(expr)                 
-	if (!(expr)) {
-		mir3da_gsensor_drv.method->myprintf("Assertion failed! %s,%d,%s,%sn",
-			__FILE__, __LINE__, __func__, #expr);
-	}
-
-//#define abs(x) ({ long __x = (x); (__x < 0) ? -__x : __x; })
-
-#ifdef FILTER_AVERAGE_ENHANCE
-typedef struct FilterAverageContextTag {
-	int sample_l;
-	int sample_h;
-	int filter_param_l;
-	int filter_param_h;
-	int filter_threhold;
-
-	int refN_l;
-	int refN_h;
-
-} FilterAverageContext;
-
-typedef struct mir3da_core_ctx_s {
-	struct mir3da_filter_param_s filter_param;
-	FilterAverageContext tFac[3];
-} mir3da_core_ctx;
-
-static mir3da_core_ctx core_ctx;
-#endif
-
-#ifdef MIR3DA_SENS_TEMP_SOLUTION
-static int bSensZoom = 0;
-#endif
-
-#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
-static int is_cali = 0;
-char bLoad = 0;
-static char readOffsetCnt = -1;
-static unsigned char original_offset[9];
-static int mir3da_write_offset_to_file(unsigned char *offset);
-static int mir3da_read_offset_from_file(unsigned char *offset);
-void manual_load_cali_file(MIR_HANDLE handle);
-#endif /* !MIR3DA_OFFSET_TEMP_SOLUTION */
-
-#if MIR3DA_STK_TEMP_SOLUTION
-static short aixHistort[AIX_HISTORY_SIZE * 3] = { 0 };
-
-static short aixHistoryIndex = 0;
-char bxstk = 0;
-char bystk = 0;
-char bzstk = 0;
-
-static void addAixHistory(short x, short y, short z)
-{
-	aixHistort[aixHistoryIndex++] = x;
-	aixHistort[aixHistoryIndex++] = y;
-	aixHistort[aixHistoryIndex++] = z;
-	aixHistoryIndex = (aixHistoryIndex) % (AIX_HISTORY_SIZE * 3);
-}
-
-static char isXStick(void)
-{
-	int i;
-	for (i = 0; i < AIX_HISTORY_SIZE; i++) {
-		if ((abs(aixHistort[i * 3]) < STICK_LSB) && (aixHistort[i * 3] != 0)) {
-			break;
-		}
-	}
-
-	if ((aixHistort[0] + aixHistort[3] + aixHistort[6]) == 0)
-		return 1;
-
-	return i == AIX_HISTORY_SIZE;
-}
-
-static char isYStick(void)
-{
-	int i;
-	for (i = 0; i < AIX_HISTORY_SIZE; i++) {
-		if ((abs(aixHistort[i * 3 + 1]) < STICK_LSB) && (aixHistort[i * 3 + 1] != 0)) {
-			break;
-		}
-	}
-
-	if ((aixHistort[1] + aixHistort[4] + aixHistort[7]) == 0)
-		return 1;
-
-	return i == AIX_HISTORY_SIZE;
-}
-
-static char isZStick(void)
-{
-	int i;
-	for (i = 0; i < AIX_HISTORY_SIZE; i++) {
-		if ((abs(aixHistort[i * 3 + 2]) < STICK_LSB) && (aixHistort[i * 3 + 2] != 0)) {
-			break;
-		}
-	}
-
-	if ((aixHistort[2] + aixHistort[5] + aixHistort[8]) == 0)
-		return 1;
-
-	return i == AIX_HISTORY_SIZE;
-}
-
-int squareRoot(int val)
-{
-	int r = 0;
-	int shift;
-
-	if (val < 0) {
-		return 0;
-	}
-
-	for (shift = 0; shift < 32; shift += 2) {
-		int x = 0x40000000l >> shift;
-		if (x + r <= val) {
-			val -= x + r;
-			r = (r >> 1) | x;
-		} else {
-			r = r >> 1;
-		}
-	}
-
-	return r;
-}
-#endif /* ! MIR3DA_STK_TEMP_SOLUTION */
-
-#if FILTER_AVERAGE_ENHANCE
-static short filter_average(short preAve, short sample, int paramN, int *refNum)
-{
-#if FILTER_AVERAGE_EX
-	if (abs(sample - preAve) > PEAK_LVL && *refNum < 3) {
-		MI_DATA("Hit, sample = %d, preAve = %d, refN =%dn", sample, preAve, *refNum);
-		sample = preAve;
-		(*refNum)++;
-	} else {
-		if (*refNum == 3) {
-			preAve = sample;
-		}
-
-		*refNum = 0;
-	}
-#endif
-
-	return preAve + (sample - preAve) / paramN;
-}
-
-static int filter_average_enhance(FilterAverageContext * fac, short sample)
-{
-	if (fac == 0) {
-		MI_ERR("0 parameter fac");
-		return 0;
-	}
-
-	if (fac->filter_param_l == fac->filter_param_h) {
-		fac->sample_l = fac->sample_h = filter_average(fac->sample_l, sample, fac->filter_param_l, &fac->refN_l);
-	} else {
-		fac->sample_l = filter_average(fac->sample_l, sample, fac->filter_param_l, &fac->refN_l);
-		fac->sample_h = filter_average(fac->sample_h, sample, fac->filter_param_h, &fac->refN_h);
-		if (abs(fac->sample_l - fac->sample_h) > fac->filter_threhold) {
-			MI_DATA("adjust, fac->sample_l = %d, fac->sample_h = %dn", fac->sample_l, fac->sample_h);
-			fac->sample_h = fac->sample_l;
-		}
-	}
-
-	return fac->sample_h;
-}
-#endif /* ! FILTER_AVERAGE_ENHANCE */
-
-int mir3da_register_read(MIR_HANDLE handle, short addr, unsigned char *data)
-{
-	unsigned char cur_page;
-	int res = 0;
-
-	/* check page */
-	if (MIR3DA_REG_PAGE(addr) > 0) {
-		res = mir3da_gsensor_drv.method->smi.read(handle, 0x0, &cur_page);
-		if (res != 0) {
-			return res;
-		}
-
-		if (cur_page != MIR3DA_REG_PAGE(addr)) {
-			res |= mir3da_gsensor_drv.method->smi.write(handle, 0x0, MIR3DA_REG_PAGE(addr));
-			if (res != 0) {
-				return res;
-			}
-		}
-	}
-
-	res = mir3da_gsensor_drv.method->smi.read(handle, MIR3DA_REG_ADDR(addr), data);
-
-	if (MIR3DA_REG_PAGE(addr) > 0) {
-		/* restore page NO. */
-		res |= mir3da_gsensor_drv.method->smi.write(handle, 0x0, cur_page);
-	}
-
-	return res;
-}
-
-int mir3da_register_read_continuously(MIR_HANDLE handle, short addr, unsigned char count, unsigned char *data)
-{
-	unsigned char cur_page;
-	int res = 0;
-
-	/* check page */
-	if (MIR3DA_REG_PAGE(addr) > 0) {
-		res = mir3da_gsensor_drv.method->smi.read(handle, 0x0, &cur_page);
-		if (res != 0) {
-			return res;
-		}
-
-		if (cur_page != MIR3DA_REG_PAGE(addr)) {
-			res |= mir3da_gsensor_drv.method->smi.write(handle, 0x0, MIR3DA_REG_PAGE(addr));
-			if (res != 0) {
-				return res;
-			}
-		}
-	}
-
-	res = (count == mir3da_gsensor_drv.method->smi.read_block(handle, MIR3DA_REG_ADDR(addr), count, data)) ? 0 : 1;
-
-	if (MIR3DA_REG_PAGE(addr) > 0) {
-		/* restore page NO. */
-		res |= mir3da_gsensor_drv.method->smi.write(handle, 0x0, cur_page);
-	}
-
-	return res;
-}
-
-int mir3da_register_write(MIR_HANDLE handle, short addr, unsigned char data)
-{
-	unsigned char cur_page;
-	int res = 0;
-
-	/* check page */
-	if (MIR3DA_REG_PAGE(addr) > 0) {
-		res = mir3da_gsensor_drv.method->smi.read(handle, 0x0, &cur_page);
-		if (res != 0) {
-			return res;
-		}
-
-		if (cur_page != MIR3DA_REG_PAGE(addr)) {
-			res |= mir3da_gsensor_drv.method->smi.write(handle, 0x0, MIR3DA_REG_PAGE(addr));
-			if (res != 0) {
-				return res;
-			}
-		}
-	}
-
-	res = mir3da_gsensor_drv.method->smi.write(handle, MIR3DA_REG_ADDR(addr), data);
-
-	if (MIR3DA_REG_PAGE(addr) > 0) {
-		/* restore page NO. */
-		res |= mir3da_gsensor_drv.method->smi.write(handle, 0x0, cur_page);
-	}
-
-	return res;
-}
-
-int mir3da_register_mask_write(MIR_HANDLE handle, short addr, unsigned char mask, unsigned char data)
-{
-	int res = 0;
-	unsigned char tmp_data;
-
-	res = mir3da_register_read(handle, addr, &tmp_data);
-	if (res) {
-		return res;
-	}
-
-	tmp_data &= ~mask;
-	tmp_data |= data & mask;
-	res = mir3da_register_write(handle, addr, tmp_data);
-
-	return res;
-}
-
-static int mir3da_read_raw_data(MIR_HANDLE handle, short *x, short *y, short *z)
-{
-	unsigned char tmp_data[6] = { 0 };
-
-	if (mir3da_register_read_continuously(handle, mir3da_gsensor_drv.obj[gsensor_mod].data.data_sect[0].addr, 6, tmp_data) != 0) {
-		MI_ERR("i2c block read failedn");
-		return -1;
-	}
-
-	*x = ((short)(tmp_data[1] << mir3da_gsensor_drv.obj[gsensor_mod].data.data_fmt.msbw | tmp_data[0])) >> (8 - mir3da_gsensor_drv.obj[gsensor_mod].data.data_fmt.lsbw);
-	*y = ((short)(tmp_data[3] << mir3da_gsensor_drv.obj[gsensor_mod].data.data_fmt.msbw | tmp_data[2])) >> (8 - mir3da_gsensor_drv.obj[gsensor_mod].data.data_fmt.lsbw);
-	*z = ((short)(tmp_data[5] << mir3da_gsensor_drv.obj[gsensor_mod].data.data_fmt.msbw | tmp_data[4])) >> (8 - mir3da_gsensor_drv.obj[gsensor_mod].data.data_fmt.lsbw);
-	//printk("%d,%dn",mir3da_gsensor_drv.obj[gsensor_mod].data.data_fmt.msbw,mir3da_gsensor_drv.obj[gsensor_mod].data.data_fmt.lsbw);
-	MI_DATA("mir3da_raw: x=%d, y=%d, z=%d", *x, *y, *z);
-
-#if MIR3DA_SENS_TEMP_SOLUTION
-	if (bSensZoom == 1) {
-		*z = (*z) * 5 / 4;
-		MI_DATA("SensZoom take effect, Zoomed Z = %d", *z);
-	}
-#endif
-	return 0;
-}
-
-static int remap[8][4] = { {0, 0, 0, 0},
-{0, 1, 0, 1},
-{1, 1, 0, 0},
-{1, 0, 0, 1},
-{1, 0, 1, 0},
-{0, 0, 1, 1},
-{0, 1, 1, 0},
-{1, 1, 1, 1}
-};
-
-int mir3da_direction_remap(short *x, short *y, short *z, int direction)
-{
-	short temp = 0;
-
-	*x = *x - ((*x) * remap[direction][0] * 2);
-	*y = *y - ((*y) * remap[direction][1] * 2);
-	*z = *z - ((*z) * remap[direction][2] * 2);
-
-	if (remap[direction][3]) {
-		temp = *x;
-		*x = *y;
-		*y = temp;
-	}
-
-	if (remap[direction][2])
-		return -1;
-
-	return 1;
-}
-
-int mir3da_read_data(MIR_HANDLE handle, short *x, short *y, short *z)
-{
-	int rst = 0;
-#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
-	static int load_cnt = 0;
-
-	if (is_cali) {
-		*x = *y = *z = 0;
-		return 0;
-	}
-
-	if (load_cnt > 200) {
-		manual_load_cali_file(handle);
-	} else {
-		load_cnt++;
-	}
-#endif
-
-	rst = mir3da_read_raw_data(handle, x, y, z);
-	if (rst != 0) {
-		MI_ERR("mir3da_read_raw_data failed, rst = %d", rst);
-		return rst;
-	}
-#ifdef MIR3DA_AUTO_CALIBRATE
-	if ((!bLoad) && (load_cnt > 200)) {
-		if (GSENSOR_MOD_SOCLE != gsensor_mod) {
-			mir3da_auto_calibrate(handle, *x, *y, *z);
-		}
-	}
-#endif
-
-#if MIR3DA_STK_TEMP_SOLUTION
-	addAixHistory(*x, *y, *z);
-
-	bxstk = isXStick();
-	bystk = isYStick();
-	bzstk = isZStick();
-
-	if ((bxstk + bystk + bzstk) < 2) {
-		if (bxstk)
-			/* *x = squareRoot(256*256 - (*y)*(*y) - (*z)*(*z)); */
-			if (bystk)
-				/* *y = squareRoot(256*256 - (*x)*(*x) - (*z)*(*z));*/
-				if (bzstk)
-					*z = squareRoot(256 * 256 - (*x) * (*x) - (*y) * (*y));
-	} else {
-		/* MI_ERR( "CHIP ERR !MORE STK!n"); */
-		return 0;
-	}
-#endif
-
-#if FILTER_AVERAGE_ENHANCE
-	if (GSENSOR_MOD_SOCLE == gsensor_mod) {
-		*x = filter_average_enhance(&core_ctx.tFac[0], *x);
-		*y = filter_average_enhance(&core_ctx.tFac[1], *y);
-		*z = filter_average_enhance(&core_ctx.tFac[2], *z);
-
-		MI_DATA("mir3da_filt: x=%d, y=%d, z=%d", *x, *y, *z);
-	}
-#endif
-	/* printk("mir3da_filt: x=%d, y=%d, z=%d",  *x, *y, *z);*/
-	return 0;
-}
-
-int cycle_read_xyz(MIR_HANDLE handle, int *x, int *y, int *z, int ncycle)
-{
-	unsigned int j = 0;
-	short raw_x, raw_y, raw_z;
-
-	*x = *y = *z = 0;
-
-	for (j = 0; j < ncycle; j++) {
-		raw_x = raw_y = raw_z = 0;
-		mir3da_read_raw_data(handle, &raw_x, &raw_y, &raw_z);
-
-		(*x) += raw_x;
-		(*y) += raw_y;
-		(*z) += raw_z;
-
-		mir3da_gsensor_drv.method->msdelay(5);
-	}
-
-	(*x) /= ncycle;
-	(*y) /= ncycle;
-	(*z) /= ncycle;
-
-	return 0;
-}
-
-#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
-int mir3da_read_offset(MIR_HANDLE handle, unsigned char *offset)
-{
-	int i, res = 0;
-
-	for (i = 0; i < MIR3DA_OFF_SECT_LEN; i++) {
-		if (mir3da_gsensor_drv.obj[gsensor_mod].offset_sect[i].addr < 0) {
-			break;
-		}
-
-		res = mir3da_register_read(handle, mir3da_gsensor_drv.obj[gsensor_mod].offset_sect[i].addr, &offset[i]);
-		if (res != 0) {
-			return res;
-		}
-	}
-
-	return res;
-}
-
-int mir3da_write_offset(MIR_HANDLE handle, unsigned char *offset)
-{
-	int i, res = 0;
-
-	for (i = 0; i < MIR3DA_OFF_SECT_LEN; i++) {
-		if (mir3da_gsensor_drv.obj[gsensor_mod].offset_sect[i].addr < 0) {
-			break;
-		}
-
-		res = mir3da_register_write(handle, mir3da_gsensor_drv.obj[gsensor_mod].offset_sect[i].addr, offset[i]);
-		if (res != 0) {
-			return res;
-		}
-	}
-
-	return res;
-}
-
-static int mir3da_write_offset_to_file(unsigned char *offset)
-{
-	int ret = 0;
-
-	ret = mir3da_gsensor_drv.method->data_save(offset);
-
-	MI_MSG("====sensor_sync_write, offset = 0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x", offset[0], offset[1], offset[2], offset[3], offset[4], offset[5], offset[6], offset[7], offset[8]);
-
-	return ret;
-}
-
-static int mir3da_read_offset_from_file(unsigned char *offset)
-{
-	int ret = 0;
-
-	ret = mir3da_gsensor_drv.method->data_get(offset);
-
-	MI_MSG("====sensor_sync_read, offset = 0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x", offset[0], offset[1], offset[2], offset[3], offset[4], offset[5], offset[6], offset[7], offset[8]);
-
-	return ret;
-}
-
-void manual_load_cali_file(MIR_HANDLE handle)
-{
-	unsigned char offset[MIR3DA_OFFSET_LEN] = { 0 };
-
-	if (!bLoad) {
-		readOffsetCnt++;
-		if (readOffsetCnt % 100 == 0) {
-			if (readOffsetCnt > 0)
-				readOffsetCnt = 0;
-
-			MI_DATA("====444 manual_load_cali_file(), bLoad = %d, readOffsetCnt=%d.n", bLoad, readOffsetCnt);
-			if (!mir3da_read_offset_from_file(offset)) {
-				MI_MSG("========= WRITE OFFSET");
-				mir3da_write_offset(handle, offset);
-				bLoad = 1;
-			}
-		}
-	}
-}
-
-typedef struct linearitydata {
-	unsigned short off;
-	int val;
-
-} LinearityData;
-
-int check_linearity_offset(MIR_HANDLE handle, int *step)
-{
-
-	int i, result = 0;
-	int x, y, z;
-
-#if 1
-	unsigned char xdata_count = 0;
-	unsigned char ydata_count = 0;
-	unsigned char zdata_count = 0;
-	LinearityData xdata[2] = { {0} };
-	LinearityData ydata[2] = { {0} };
-	LinearityData zdata[2] = { {0} };
-
-	for (i = 10; i <= 0x3ff; i += 50) {
-		result |= mir3da_register_write(handle, SOCLE_REG_OTP_XOFF_L, i & 0xFF);
-		result |= mir3da_register_write(handle, SOCLE_REG_OTP_XOFF_H, (i & 0xFF00) >> 8);
-		result |= mir3da_register_write(handle, SOCLE_REG_OTP_YOFF_L, i & 0xFF);
-		result |= mir3da_register_write(handle, SOCLE_REG_OTP_YOFF_H, (i & 0xFF00) >> 8);
-		result |= mir3da_register_write(handle, SOCLE_REG_OTP_ZOFF_L, i & 0xFF);
-		result |= mir3da_register_write(handle, SOCLE_REG_OTP_ZOFF_H, (i & 0xFF00) >> 8);
-		result |= cycle_read_xyz(handle, &x, &y, &z, 20);
-
-		MI_MSG("detect_linearity_ratio: i = %d, x = %d, y = %d, z= %d n", i, x, y, z);
-
-		if (result) {
-			MI_MSG("detect_linearity_ratio: chip op failed, result = %d n", result);
-			return result;
-		}
-
-		if (abs(x) < 1800 && xdata_count < 2) {
-			MI_MSG("detect linearity ratio: xdata_count = %d, x = %d i = %dn", xdata_count, x, i);
-
-			xdata[xdata_count].val = x;
-			xdata[xdata_count].off = i;
-			xdata_count++;
-		}
-
-		if (abs(y) < 1800 && ydata_count < 2) {
-			MI_MSG("detect linearity ratio: ydata_count = %d, y = %d i = %dn", ydata_count, y, i);
-			ydata[ydata_count].val = y;
-			ydata[ydata_count].off = i;
-			ydata_count++;
-		}
-
-		if (abs(z) < 1800 && zdata_count < 2) {
-			MI_MSG("detect linearity ratio: zdata_count = %d, z = %d i = %dn", zdata_count, z, i);
-			zdata[zdata_count].val = z;
-			zdata[zdata_count].off = i;
-			zdata_count++;
-		}
-
-		if (xdata_count == 2 && ydata_count == 2 && zdata_count == 2) {
-			MI_MSG("all linearity_ratio found!");
-			step[0] = (xdata[1].val - xdata[0].val) / (xdata[1].off - xdata[0].off);
-			step[1] = (ydata[1].val - ydata[0].val) / (ydata[1].off - ydata[0].off);
-			step[2] = (zdata[1].val - zdata[0].val) / (zdata[1].off - zdata[0].off);
-
-			MI_MSG("CUSTOM offset step: x = %d, y = %d, z= %d", step[0], step[1], step[2]);
-
-			break;
-		}
-	}
-
-	if (abs(step[0]) < 10 || abs(step[1]) < 10 || abs(step[2]) < 10) {
-		MI_MSG("detect linearity ratio failed!");
-		return -1;
-	}
-#endif
-	return result;
-}
-
-static void mir3da_cali_off_to_lsb(int off, int *coarse, int coarse_step, int *fine, int fine_step)
-{
-	*coarse = off / coarse_step;
-	*fine = 100 * (off - (*coarse) * coarse_step) / fine_step;
-
-	MI_MSG("off = %d; delta_coarse = %d; delta_fine = %d", off, *coarse, *fine);
-}
-
-#ifdef MIR3DA_AUTO_CALIBRATE
-static int NSA_once_calibrate(MIR_HANDLE handle, int coarse_step[3], int fine_step[3], int xyz[3])
-{
-	int coarse[3] = { 0 };
-	int coarse_delta[3] = { 0 };
-	int fine[3] = { 0 };
-	int fine_delta[3] = { 0 };
-	int target[3] = { 0 };
-	int i;
-	unsigned char offset_data[9] = { 0 };
-
-	if (mir3da_read_offset(handle, offset_data)) {
-		MI_ERR("Get old offset failed !");
-		return -1;
-	}
-	coarse[0] = offset_data[0] & 0x3f;
-	coarse[1] = offset_data[1] & 0x3f;
-	coarse[2] = offset_data[2] & 0x3f;
-	fine[0] = (((int)offset_data[0] << 2) & 0x300) | offset_data[3];
-	fine[1] = (((int)offset_data[1] << 2) & 0x300) | offset_data[4];
-	fine[2] = (((int)offset_data[2] << 2) & 0x300) | offset_data[5];
-
-	MI_MSG("Old coarse_x = %d; coarse_y = %d; coarse_z = %d; fine_x = %d; fine_y = %d; fine_z = %d;", coarse[0], coarse[1], coarse[2], fine[0], fine[1], fine[2]);
-
-	/* 0 means auto detect z direction assume z axis is verticle */
-	if ((abs(target[0]) + abs(target[1]) + abs(target[2])) == 0) {
-		target[2] = (xyz[2] > 0) ? 1024 : (-1024);
-	}
-
-	for (i = 0; i < 3; i++) {
-		coarse_step[i] *= coarse[i] >= 32 ? (-1) : 1;
-		mir3da_cali_off_to_lsb((xyz[i] - target[i]), &coarse_delta[i], coarse_step[i], &fine_delta[i], fine_step[i]);
-
-		coarse[i] += coarse_delta[i];
-		fine[i] += fine_delta[i];
-		offset_data[i] = coarse[i] | ((fine[i] >> 2) & 0xc0);
-		offset_data[i + 3] = fine[i] & 0xFF;
-	}
-
-	if (mir3da_write_offset(handle, offset_data)) {
-		MI_ERR("Update offset failed !");
-		return -1;
-	}
-	/* Discard unstable data after offset register changed */
-	cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], 5);
-	if (cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], 10)) {
-		return -1;
-	}
-	MI_MSG("---calibrate_Done, x = %d, y = %d, z = %d, coarse_x = %d, coarse_y = %d, coarse_z = %d, fine_x = %d, fine_y = %d, fine_z = %d", xyz[0], xyz[1], xyz[2], coarse[0], coarse[1], coarse[2],
-	       fine[0], fine[1], fine[2]);
-
-	return mir3da_write_offset_to_file(offset_data);
-}
-#endif /* !MIR3DA_AUTO_CALIBRATE */
-
-static int NSA_calibrate(MIR_HANDLE handle, int coarse_step[3], int fine_step[3], int fine_max, int target[3])
-{
-	int i = 0, j = 0;
-	unsigned char ncycle = 20;
-	unsigned char nLoop = 20;
-	unsigned char offset_data[9] = { 0 };
-	unsigned char fine_ok_map = 0;
-
-	int xyz[3] = { 0 };
-	int coarse[3] = { 0 };
-	int coarse_delta[3] = { 0 };
-	int fine[3] = { 0 };
-	int fine_delta[3] = { 0 };
-
-	if ((abs(target[0]) + abs(target[1]) + abs(target[2])) != 0 && (abs(target[0]) + abs(target[1]) + abs(target[2])) != 1024) {
-		MI_ERR("Invalid argument !");
-		return -1;
-	}
-
-	/* 0 means auto detect z direction assume z axis is verticle */
-	if ((abs(target[0]) + abs(target[1]) + abs(target[2])) == 0) {
-		if (cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], 5)) {
-			MI_ERR("check z direction failedn");
-			return -1;
-		}
-		target[2] = (xyz[2] > 0) ? 1024 : (-1024);
-	}
-
-	MI_MSG("---Start Calibrate, trim target %d, %d, %d---n", target[0], target[1], target[2]);
-
-	// Stage1: Coarse tune once
-	MI_MSG("---Stage1, coarse tune---");
-	// change to 16G mode
-	if (mir3da_register_mask_write(handle, NSA_REG_G_RANGE, 0x03, 3)) {
-		MI_ERR("i2c mask write failed !n");
-		return -1;
-	}
-
-	/* reset coarse offset register */
-	mir3da_write_offset(handle, offset_data);
-	/* Discard unstable data after offset register changed */
-	cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], 5);
-
-	if (cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], ncycle)) {
-		goto EXIT_16G_MOD;
-	}
-
-	for (i = 0; i < 3; i++) {
-		/* check rule */
-		xyz[i] *= 8;
-
-		coarse[i] = ((xyz[i] - target[i]) > 0) ? 0 : 32;
-
-		MI_MSG("xyz[%d] = %d, coarse[%d] = 0x%x", i, xyz[i], i, coarse[i]);
-
-		coarse_step[i] *= coarse[i] >= 32 ? (-1) : 1;
-		mir3da_cali_off_to_lsb((xyz[i] - target[i]), &coarse_delta[i], coarse_step[i], &fine_delta[i], fine_step[i]);
-
-		coarse[i] += coarse_delta[i];
-		fine[i] += fine_delta[i];
-		mir3da_register_mask_write(handle, NSA_REG_COARSE_OFFSET_TRIM_X + i, 0x3f, (unsigned char)coarse[i]);
-	}
-
-	/* Discard unstable data after offset register changed */
-	cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], 5);
-	if (cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], 5)) {
-		return -1;
-	}
-	for (i = 0; i < 3; i++) {
-		fine[i] += (xyz[i] > 0) ? 0 : fine_max;
-		mir3da_register_write(handle, NSA_REG_FINE_OFFSET_TRIM_X + i, (unsigned char)(fine[i] & 0xff));
-		mir3da_register_mask_write(handle, NSA_REG_COARSE_OFFSET_TRIM_X + i, 0xc0, (unsigned char)(0xc0 & (fine[i] >> 2)));
-	}
-
-EXIT_16G_MOD:
-	// change back to 2G mode
-	if (mir3da_register_mask_write(handle, NSA_REG_G_RANGE, 0x03, 0)) {
-		MI_ERR("i2c mask write failed !n");
-		return -1;
-	}
-	/* Discard unstable data after offset register changed */
-	cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], 5);
-	if (cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], ncycle)) {
-		return -1;
-	}
-	MI_MSG("---Stage1, coarse tune done: x = %d, y = %d, z = %d, coarse_x = %d, coarse_y = %d, coarse_z = %d, fine_x = %d, fine_y = %d, fine_z = %d", xyz[0], xyz[1], xyz[2], coarse[0], coarse[1],
-	       coarse[2], fine[0], fine[1], fine[2]);
-
-	// Stage2: Fine tune
-	MI_MSG("---Stage2, Fine tune---");
-	for (i = 0; i < nLoop; i++) {
-
-		if (0x07 == (fine_ok_map & 0x07)) {
-			break;
-		}
-		/* Discard unstable data after offset register changed */
-		cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], 5);
-		MI_MSG("---Stage2, Fine loop %d", i);
-		if (cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], ncycle)) {
-			return -1;
-		}
-
-		for (j = 0; j < 3; j++) {
-			MI_MSG("xyz[%d] = %d, caorse[%d] = 0x%x, fine[%d] = 0x%x", j, xyz[j], j, coarse[j], j, fine[j]);
-			if (abs(xyz[j] - target[j]) < MIR3DA_OFFSET_THRESHOLD) {
-				fine_ok_map |= (1 << j);
-				offset_data[j] = coarse[j] | ((fine[j] >> 2) & 0xc0);
-				offset_data[j + 3] = fine[j];
-				continue;
-			}
-			mir3da_cali_off_to_lsb((xyz[j] - target[j]), &coarse_delta[j], coarse_step[j], &fine_delta[j], fine_step[j]);
-
-			coarse[j] += coarse_delta[j];
-			fine[j] += fine_delta[j];
-			mir3da_register_write(handle, NSA_REG_FINE_OFFSET_TRIM_X + j, (unsigned char)(fine[j] & 0xff));
-			mir3da_register_mask_write(handle, NSA_REG_COARSE_OFFSET_TRIM_X + j, 0xFF, (unsigned char)(0xc0 & (fine[j] >> 2)) | coarse[j]);
-		}
-	}
-	MI_MSG("---Stage2, Fine tune done: x = %d, y = %d, z = %d, coarse_x = %d, coarse_y = %d, coarse_z = %d, fine_x = %d, fine_y = %d, fine_z = %d", xyz[0], xyz[1], xyz[2], coarse[0], coarse[1],
-	       coarse[2], fine[0], fine[1], fine[2]);
-
-	if (0x07 == (fine_ok_map & 0x07)) {
-		goto SUCCESS_EXIT;
-	}
-#if MIR3DA_STK_TEMP_SOLUTION
-	if (0x03 == (fine_ok_map & 0x07)) {
-		goto SUCCESS_EXIT;
-	}
-#endif
-
-	MI_MSG("---calibrate Failed !---");
-	return -1;
-
-SUCCESS_EXIT:
-	MI_MSG("---calibrate OK !---");
-	return mir3da_write_offset_to_file(offset_data);
-}
-
-static int NSA_NTO_cali_step_calc(MIR_HANDLE handle, int coarse[3], int x100_fine[3], int x100_cust[3])
-{
-	int i;
-	unsigned int total_gain[3] = { 0 };
-	unsigned char coarse_gain = 0;
-	unsigned char fine_gain[3] = { 0 };
-	unsigned int const coarse_gain_map[] = { 1000, 1125, 1250, 1375, 500, 625, 750, 875 };	/* *1000  */
-	unsigned char const fine_dig_gain_map[] = { 1, 2, 4, 8 };
-
-	if (mir3da_register_read_continuously(handle, NSA_REG_SENSITIVITY_TRIM_X, 3, fine_gain) != 0) {
-		MI_ERR("i2c block read failedn");
-		return -1;
-	}
-
-	if (mir3da_register_read(handle, NSA_REG_SENS_COARSE_TRIM, &coarse_gain) != 0) {
-		MI_ERR("i2c block read failedn");
-		return -1;
-	}
-
-	for (i = 0; i < 3; i++) {
-		// *100*1000
-		total_gain[i] = ((1000 + (fine_gain[i] & 0x1F) * 1000 / 32) / 15) * fine_dig_gain_map[((fine_gain[i] >> 5) & 0x03)] * coarse_gain_map[coarse_gain & 0x07];
-		coarse[i] = (int)(total_gain[i] * 500 / 100000);
-		x100_fine[i] = (int)(total_gain[i] * 293 / 100000);
-		x100_cust[i] = (int)(total_gain[i] * 390 / 100000);
-	}
-	MI_MSG("coarse_step_x = %d, coarse_step_y = %d, coarse_step_z = %dn", coarse[0], coarse[1], coarse[2]);
-	MI_MSG("fine_step_x = %d, fine_step_y = %d, fine_step_z = %dn", x100_fine[0], x100_fine[1], x100_fine[2]);
-	MI_MSG("custom_step_x = %d, custom_step_y = %d, custom_step_z = %dn", x100_cust[0], x100_cust[1], x100_cust[2]);
-
-	return 0;
-}
-
-static int NSA_MLM_cali_step_calc(MIR_HANDLE handle, int coarse[3], int x100_fine[3], int x100_cust[3])
-{
-	int i;
-	unsigned int total_gain[3] = { 0 };
-	unsigned char gain[3] = { 0 };
-	unsigned int const coarse_gain_map[] = { 1000, 1125, 1250, 1375, 500, 625, 750, 875 };	/* *1000  */
-
-	if (mir3da_register_read_continuously(handle, NSA_REG_SENSITIVITY_TRIM_X, 3, gain) != 0) {
-		MI_ERR("i2c block read failedn");
-		return -1;
-	}
-
-	for (i = 0; i < 3; i++) {
-		// *100*1000
-		total_gain[i] = ((1000 + (gain[i] & 0x1F) * 1000 / 32) / 15) * coarse_gain_map[((gain[i] >> 5) & 0x07)];
-		MI_MSG("total gain = %d", total_gain[i]);
-		coarse[i] = (int)(total_gain[i] * 500 / 100000);
-		x100_fine[i] = (int)(total_gain[i] * 589 / 100000);
-		x100_cust[i] = (int)(total_gain[i] * 390 / 100000);
-	}
-
-	MI_MSG("coarse_step_x = %d, coarse_step_y = %d, coarse_step_z = %dn", coarse[0], coarse[1], coarse[2]);
-	MI_MSG("fine_step_x = %d, fine_step_y = %d, fine_step_z = %dn", x100_fine[0], x100_fine[1], x100_fine[2]);
-	MI_MSG("custom_step_x = %d, custom_step_y = %d, custom_step_z = %dn", x100_cust[0], x100_cust[1], x100_cust[2]);
-
-	return 0;
-}
-
-#endif /* !MIR3DA_OFFSET_TEMP_SOLUTION */
-int mir3da_write_offset(MIR_HANDLE handle, unsigned char *offset)
-{
-	return 0;
-}
-
-int mir3da_read_offset(MIR_HANDLE handle, unsigned char *offset)
-{
-	return 0;
-}
-
-static int NSA_NTO_calibrate(MIR_HANDLE handle, int z_dir)
-{
-	int result = 0;
-
-#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
-	int coarse_step[3] = { 0 };
-	int fine_step[3] = { 0 };
-	int custom_step[3] = { 0 };
-	int target[3] = { 0 };
-
-	unsigned char swap_plarity_old = 0;
-
-	/* compute step */
-	if (NSA_NTO_cali_step_calc(handle, coarse_step, fine_step, custom_step)) {
-		MI_ERR("Compute step failed !");
-		return -1;
-	}
-	target[2] = z_dir * 1024;
-
-	// save swap/plarity old setting
-	if (mir3da_register_read(handle, NSA_REG_SWAP_POLARITY, &swap_plarity_old)) {
-		MI_ERR("Get SWAP/PLARITY setting failed !");
-		return -1;
-	}
-	if (mir3da_register_mask_write(handle, NSA_REG_SWAP_POLARITY, 0x0F, 0x00)) {
-		MI_ERR("Set Plarity failed !");
-		return -1;
-	}
-
-	result = NSA_calibrate(handle, coarse_step, fine_step, 0x3ff, target);
-
-	// Restore swap/plarity setting
-	if (mir3da_register_mask_write(handle, NSA_REG_SWAP_POLARITY, 0x0F, swap_plarity_old & 0x0F)) {
-		MI_ERR("Restore SWAP/PLARITY setting failed !");
-		return -1;
-	}
-#endif /* !MIR3DA_OFFSET_TEMP_SOLUTION */
-	return result;
-}
-
-static int NSA_NTO_auto_calibrate(MIR_HANDLE handle, int xyz[3])
-{
-	int result = 0;
-
-#ifdef MIR3DA_AUTO_CALIBRATE
-	int coarse_step[3];
-	int fine_step[3];
-	int custom_step[3] = { 0 };
-	unsigned char swap_plarity_old = 0;
-	int temp = 0;
-
-	/* compute step */
-	if (NSA_NTO_cali_step_calc(handle, coarse_step, fine_step, custom_step)) {
-		MI_ERR("Compute step failed !");
-		return -1;
-	}
-	// save swap/plarity old setting
-	if (mir3da_register_read(handle, NSA_REG_SWAP_POLARITY, &swap_plarity_old)) {
-		MI_ERR("Get SWAP/PLARITY setting failed !");
-		return -1;
-	}
-	if ((swap_plarity_old & (1 << 0))) {
-		MI_ERR("==xy swap==n");
-		temp = xyz[0];
-		xyz[0] = ((swap_plarity_old & (1 << 2)) != 0) ? (-xyz[1]) : xyz[1];
-		xyz[1] = ((swap_plarity_old & (1 << 3)) != 0) ? (-temp) : temp;
-	} else {
-		MI_ERR("==xy no swap==n");
-		xyz[0] = ((swap_plarity_old & (1 << 3)) != 0) ? (-xyz[0]) : xyz[0];
-		xyz[1] = ((swap_plarity_old & (1 << 2)) != 0) ? (-xyz[1]) : xyz[1];
-	}
-
-	xyz[2] = ((swap_plarity_old & (1 << 1)) != 0) ? (-xyz[2]) : xyz[2];
-
-	result = NSA_once_calibrate(handle, coarse_step, fine_step, xyz);
-
-#endif /* !MIR3DA_AUTO_CALIBRATE */
-	return result;
-}
-
-static int NSA_MLM_calibrate(MIR_HANDLE handle, int z_dir)
-{
-	int result = 0;
-#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
-	int coarse_step[3] = { 0 };
-	int fine_step[3] = { 0 };
-	int custom_step[3] = { 0 };
-	int target[3] = { 0 };
-	unsigned char swap_plarity_old = 0;
-
-	/* compute step */
-	if (NSA_MLM_cali_step_calc(handle, coarse_step, fine_step, custom_step)) {
-		MI_ERR("Compute step failed !");
-		return -1;
-	}
-	target[2] = z_dir * 1024;
-
-	// save swap/plarity old setting
-	if (mir3da_register_read(handle, NSA_REG_SWAP_POLARITY, &swap_plarity_old)) {
-		MI_ERR("Get SWAP/PLARITY setting failed !");
-		return -1;
-	}
-	if (mir3da_register_mask_write(handle, NSA_REG_SWAP_POLARITY, 0x0F, 0x0E)) {
-		MI_ERR("Set Plarity failed !");
-		return -1;
-	}
-
-	result = NSA_calibrate(handle, coarse_step, fine_step, 0xff, target);
-	// Restore swap/plarity setting
-	if (mir3da_register_mask_write(handle, NSA_REG_SWAP_POLARITY, 0x0F, swap_plarity_old & 0x0F)) {
-		MI_ERR("Restore SWAP/PLARITY setting failed !");
-		return -1;
-	}
-#endif /* !MIR3DA_OFFSET_TEMP_SOLUTION */
-	return result;
-}
-
-static int NSA_MLM_auto_calibrate(MIR_HANDLE handle, int xyz[3])
-{
-	int result = 0;
-#ifdef MIR3DA_AUTO_CALIBRATE
-	int coarse_step[3] = { 0 };
-	int fine_step[3] = { 0 };
-	int custom_step[3] = { 0 };
-	unsigned char swap_plarity_old = 0;
-
-	/* compute step */
-	if (NSA_MLM_cali_step_calc(handle, coarse_step, fine_step, custom_step)) {
-		MI_ERR("Compute step failed !");
-		return -1;
-	}
-	// save swap/plarity old setting
-	if (mir3da_register_read(handle, NSA_REG_SWAP_POLARITY, &swap_plarity_old)) {
-		MI_ERR("Get SWAP/PLARITY setting failed !");
-		return -1;
-	}
-
-	xyz[0] = ((swap_plarity_old & (1 << 3)) != 0) ? xyz[0] : (-xyz[0]);
-	xyz[1] = ((swap_plarity_old & (1 << 2)) != 0) ? xyz[1] : (-xyz[1]);
-	xyz[2] = ((swap_plarity_old & (1 << 1)) != 0) ? xyz[2] : (-xyz[2]);
-
-	result = NSA_once_calibrate(handle, coarse_step, fine_step, xyz);
-
-#endif /* !MIR3DA_AUTO_CALIBRATE */
-	return result;
-}
-
-static int SOCLE_auto_calibrate(MIR_HANDLE handle, int xyz[3])
-{
-#ifdef MIR3DA_AUTO_CALIBRATE
-	int coarse_step[3] = { -20, -20, -20 };
-	int coarse_delta[3] = { 0 };
-	int coarse[3] = { 0 };
-	int fine_step[3] = { 0 };
-	int fine_delta[3] = { 0 };
-	int target[3] = { 0 };
-	int i;
-	unsigned char offset_data[9] = { 0 };
-
-	if (mir3da_read_offset(handle, offset_data)) {
-		MI_ERR("Get old offset failed !");
-		return -1;
-	}
-
-	/* 0 means auto detect z direction assume z axis is verticle */
-	if ((abs(target[0]) + abs(target[1]) + abs(target[2])) == 0) {
-		target[2] = (xyz[2] > 0) ? 1024 : (-1024);
-	}
-
-	for (i = 0; i < 3; i++) {
-		coarse[i] = offset_data[i * 2 + 1] & 0xff;	/* high byte */
-		coarse[i] = (coarse[i] << 8) | offset_data[i * 2];	/* low gyte */
-
-		mir3da_cali_off_to_lsb((xyz[i] - target[i]), &coarse_delta[i], coarse_step[i], &fine_delta[i], fine_step[i]);
-		coarse[i] += coarse_delta[i];
-
-		offset_data[i * 2] = coarse[i] & 0xff;
-		offset_data[i * 2 + 1] = (coarse[i] >> 8) & 0xff;
-	}
-
-	if (mir3da_write_offset(handle, offset_data)) {
-		MI_ERR("Update offset failed !");
-		return -1;
-	}
-
-	if (cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], 10)) {
-		return -1;
-	}
-	MI_MSG("---calibrate_Done, x = %d, y = %d, z = %d, off_x = %d, off_y = %d, off_z = %d", xyz[0], xyz[1], xyz[2], coarse[0], coarse[1], coarse[2]);
-
-	return mir3da_write_offset_to_file(offset_data);
-
-#endif /* !MIR3DA_AUTO_CALIBRATE */
-	return 0;
-}
-
-static int SOCLE_calibrate(MIR_HANDLE handle, int z_dir)
-{
-	int result = 0;
-#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
-	short i;
-	unsigned char tmp_data[6];
-	int x = 0, y = 0, z = 0;
-	short tmp_off = 0, tmp_off2 = 0;
-	unsigned char ncycle = 50;
-	unsigned char offset_data[9] = { 0 };
-	int fine_step[3] = { 0 };
-
-	unsigned char x_ok = 0;
-	unsigned char y_ok = 0;
-	unsigned char z_ok = 0;
-	unsigned short x_off = 0;
-	unsigned short y_off = 0;
-	unsigned short z_off = 0;
-	unsigned short x_off_original = 0;
-	unsigned short y_off_original = 0;
-	unsigned short z_off_original = 0;
-
-	/* decide the z direction, if 0 which means auto */
-	if (z_dir == 0) {
-		result = cycle_read_xyz(handle, &x, &y, &z, 5);
-		if (result != 0) {
-			MI_ERR("check z direction failedn");
-			goto fail_exit;
-		}
-		z_dir = z > 0 ? 1 : (-1);
-	}
-
-	if (mir3da_register_read_continuously(handle, (SOCLE_REG_OTP_XOFF_L | 0x80), 6, tmp_data)) {
-		MI_ERR("i2c block read failedn");
-		goto fail_exit;
-	}
-
-	x_off = (tmp_data[1] << 8) | tmp_data[0];
-	y_off = (tmp_data[3] << 8) | tmp_data[2];
-	z_off = (tmp_data[5] << 8) | tmp_data[4];
-
-#if MIR3DA_STK_TEMP_SOLUTION
-	x_off_original = x_off;
-	y_off_original = y_off;
-	z_off_original = z_off;
-#endif
-
-	if (0 != check_linearity_offset(handle, fine_step)) {
-		fine_step[0] = fine_step[1] = fine_step[2] = -20;
-	}
-
-	result = mir3da_register_write(handle, SOCLE_REG_OTP_XOFF_L, x_off & 0xFF);
-	MI_ASSERT(result == 0);
-	result = mir3da_register_write(handle, SOCLE_REG_OTP_XOFF_H, (x_off & 0xFF00) >> 8);
-	MI_ASSERT(result == 0);
-	result = mir3da_register_write(handle, SOCLE_REG_OTP_YOFF_L, y_off & 0xFF);
-	MI_ASSERT(result == 0);
-	result = mir3da_register_write(handle, SOCLE_REG_OTP_YOFF_H, (y_off & 0xFF00) >> 8);
-	MI_ASSERT(result == 0);
-	result = mir3da_register_write(handle, SOCLE_REG_OTP_ZOFF_L, z_off & 0xFF);
-	MI_ASSERT(result == 0);
-	result = mir3da_register_write(handle, SOCLE_REG_OTP_ZOFF_H, (z_off & 0xFF00) >> 8);
-	MI_ASSERT(result == 0);
-
-	MI_MSG("---Start Calibrate, z direction = %d---n", z_dir);
-
-	for (i = 0; i < 20; i++) {
-		x = y = z = 0;
-
-		result = cycle_read_xyz(handle, &x, &y, &z, ncycle);
-		if (result != 0) {
-			MI_ERR("i2c block read failedn");
-			goto fail_exit;
-		}
-
-		MI_MSG("----loop %d: x = %d, y = %d, z = %d; x_off = 0x%x, y_off = 0x%x, z_off = 0x%xn", i, x, y, z, x_off, y_off, z_off);
-
-		if (!x_ok) {
-			if (abs(x) <= MIR3DA_OFFSET_THRESHOLD) {
-				x_ok = 1;
-				MI_MSG("------X is OK, 0x%X-------n", x_off);
-			} else {
-				tmp_off = x / fine_step[0];
-
-				tmp_off2 = (short)x_off - tmp_off;
-				if (tmp_off2 > 0x3ff) {
-					tmp_off2 = 0x3ff;
-				} else if (tmp_off2 < 0) {
-					tmp_off2 = 0x01;
-				}
-
-				x_off = (unsigned short)tmp_off2;
-				MI_MSG("tmp_off = %d, tmp_off2 = %d,  x_off = %dn", tmp_off, tmp_off2, x_off);
-
-				result = mir3da_register_write(handle, SOCLE_REG_OTP_XOFF_L, x_off & 0xFF);
-				MI_ASSERT(result == 0);
-				result = mir3da_register_write(handle, SOCLE_REG_OTP_XOFF_H, (x_off & 0xFF00) >> 8);
-				MI_ASSERT(result == 0);
-			}
-
-		}
-
-		if (!y_ok) {
-			if (abs(y) <= MIR3DA_OFFSET_THRESHOLD) {
-				y_ok = 1;
-				MI_MSG("------Y is OK, 0x%X-------n", y_off);
-			} else {
-				tmp_off = y / fine_step[1];
-
-				tmp_off2 = (short)y_off - tmp_off;
-				if (tmp_off2 > 0x3ff) {
-					tmp_off2 = 0x3ff;
-				} else if (tmp_off2 < 0) {
-					tmp_off2 = 0x01;
-				}
-
-				y_off = (unsigned short)tmp_off2;
-				MI_MSG("tmp_off = %d, tmp_off2 = %d,  y_off = %dn", tmp_off, tmp_off2, y_off);
-
-				result = mir3da_register_write(handle, SOCLE_REG_OTP_YOFF_L, y_off & 0xFF);
-				MI_ASSERT(result == 0);
-				result = mir3da_register_write(handle, SOCLE_REG_OTP_YOFF_H, (y_off & 0xFF00) >> 8);
-				MI_ASSERT(result == 0);
-			}
-
-		}
-
-		if (!z_ok) {
-			if (abs(z - (z_dir > 0 ? 1024 : -1024)) <= MIR3DA_OFFSET_THRESHOLD) {
-				z_ok = 1;
-				MI_MSG("------Z is OK, 0x%X-------n", z_off);
-			} else {
-				tmp_off = (z - (z_dir > 0 ? 1024 : -1024)) / fine_step[2];
-
-				tmp_off2 = (short)z_off - tmp_off;
-				if (tmp_off2 > 0x3ff) {
-					tmp_off2 = 0x3ff;
-				} else if (tmp_off2 < 0) {
-					tmp_off2 = 0x01;
-				}
-
-				z_off = (unsigned short)tmp_off2;
-				MI_MSG("tmp_off = %d, tmp_off2 = %d,  z_off = %dn", tmp_off, tmp_off2, z_off);
-
-				result = mir3da_register_write(handle, SOCLE_REG_OTP_ZOFF_L, z_off & 0xFF);
-				MI_ASSERT(result == 0);
-				result = mir3da_register_write(handle, SOCLE_REG_OTP_ZOFF_H, (z_off & 0xFF00) >> 8);
-				MI_ASSERT(result == 0);
-			}
-
-		}
-
-		if (x_ok && y_ok && z_ok) {
-			MI_MSG("--- Calibrate done ---n");
-			goto success_exit;
-		}
-	}
-
-#if MIR3DA_STK_TEMP_SOLUTION
-	if (x_ok + y_ok + z_ok == 2) {
-
-		if (x_ok == 0) {
-			x_off = x_off_original;
-			result = mir3da_register_write(handle, SOCLE_REG_OTP_XOFF_L, x_off & 0xFF);
-			MI_ASSERT(result == 0);
-			result = mir3da_register_write(handle, SOCLE_REG_OTP_XOFF_H, (x_off & 0xFF00) >> 8);
-			MI_ASSERT(result == 0);
-
-			MI_MSG("--- Calibrate done but x skipped---n");
-
-		} else if (y_ok == 0) {
-
-			y_off = y_off_original;
-			result = mir3da_register_write(handle, SOCLE_REG_OTP_YOFF_L, y_off & 0xFF);
-			MI_ASSERT(result == 0);
-			result = mir3da_register_write(handle, SOCLE_REG_OTP_YOFF_H, (y_off & 0xFF00) >> 8);
-			MI_ASSERT(result == 0);
-
-			MI_MSG("--- Calibrate done but y skipped---n");
-
-		} else if (z_ok == 0) {
-
-			z_off = z_off_original;
-			result = mir3da_register_write(handle, SOCLE_REG_OTP_ZOFF_L, z_off & 0xFF);
-			MI_ASSERT(result == 0);
-			result = mir3da_register_write(handle, SOCLE_REG_OTP_ZOFF_H, (z_off & 0xFF00) >> 8);
-			MI_ASSERT(result == 0);
-
-			MI_MSG("--- Calibrate done but z skipped---n");
-		}
-
-		goto success_exit;
-	}
-#endif
-
-fail_exit:
-	return -1;
-
-success_exit:
-	offset_data[0] = x_off & 0xFF;
-	offset_data[1] = (x_off & 0xFF00) >> 8;
-	offset_data[2] = y_off & 0xFF;
-	offset_data[3] = (y_off & 0xFF00) >> 8;
-	offset_data[4] = z_off & 0xFF;
-	offset_data[5] = (z_off & 0xFF00) >> 8;
-	result = mir3da_write_offset_to_file(offset_data);
-
-#endif /* !MIR3DA_OFFSET_TEMP_SOLUTION */
-	return result;
-}
-
-int mir3da_calibrate(MIR_HANDLE handle, int z_dir)
-{
-	int res = 0;
-#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
-	if (is_cali)
-		return -1;
-	is_cali = 1;
-
-	/* restore original direction if last calibration was done in a wrong direction */
-	mir3da_write_offset(handle, original_offset);
-
-	res = mir3da_gsensor_drv.obj[gsensor_mod].calibrate(handle, z_dir);
-	if (res != 0) {
-		MI_ERR("Calibrate failed !");
-		mir3da_write_offset(handle, original_offset);
-	}
-	bLoad = 1;
-	is_cali = 0;
-#endif /* !MIR3DA_OFFSET_TEMP_SOLUTION */
-	return res;
-}
-
-#ifdef MIR3DA_AUTO_CALIBRATE
-#define STABLE_CHECK_SAMPLE_NUM     10
-#define STABLE_CHECK_THRESHOLD      50000
-#define AUTO_CALI_THRESHOLD_XY      300
-#define AUTO_CALI_THRESHOLD_Z       500
-static unsigned char stable_sample_cnt = 0;
-static int stable_sample_pow_sum[STABLE_CHECK_SAMPLE_NUM] = { 0 };
-static int stable_sample_sum[3] = { 0 };
-
-static int mir3da_auto_cali_condition_confirm(int x, int y, int z, int ave_xyz[3])
-{
-	int max = 0, min = 0;
-	int i;
-	int x_ok = 0, y_ok = 0, z_ok = 0;
-
-	stable_sample_pow_sum[stable_sample_cnt] = x * x + y * y + z * z;
-	stable_sample_sum[0] += x;
-	stable_sample_sum[1] += y;
-	stable_sample_sum[2] += z;
-	stable_sample_cnt++;
-
-	MI_MSG("---stable_sample_cnt = %d", stable_sample_cnt);
-
-	if (stable_sample_cnt < STABLE_CHECK_SAMPLE_NUM)
-		return -1;
-	stable_sample_cnt = 0;
-
-	max = stable_sample_pow_sum[0];
-	min = stable_sample_pow_sum[0];
-	stable_sample_pow_sum[0] = 0;
-	for (i = 1; i < STABLE_CHECK_SAMPLE_NUM; i++) {
-		if (stable_sample_pow_sum[i] > max)
-			max = stable_sample_pow_sum[i];
-		if (stable_sample_pow_sum[i] < min)
-			min = stable_sample_pow_sum[i];
-		stable_sample_pow_sum[i] = 0;
-	}
-	MI_MSG("---max = %d; min = %d", max, min);
-
-	ave_xyz[0] = stable_sample_sum[0] / STABLE_CHECK_SAMPLE_NUM;
-	stable_sample_sum[0] = 0;
-	ave_xyz[1] = stable_sample_sum[1] / STABLE_CHECK_SAMPLE_NUM;
-	stable_sample_sum[1] = 0;
-	ave_xyz[2] = stable_sample_sum[2] / STABLE_CHECK_SAMPLE_NUM;
-	stable_sample_sum[2] = 0;
-
-	MI_MSG("ave_x = %d, ave_y = %d, ave_z = %d", ave_xyz[0], ave_xyz[1], ave_xyz[2]);
-	x_ok = (abs(ave_xyz[0]) < AUTO_CALI_THRESHOLD_XY) ? 1 : 0;
-	y_ok = (abs(ave_xyz[1]) < AUTO_CALI_THRESHOLD_XY) ? 1 : 0;
-	z_ok = (abs(abs(ave_xyz[2]) - 1024) < AUTO_CALI_THRESHOLD_Z) ? 1 : 0;
-
-	if ((abs(max - min) > STABLE_CHECK_THRESHOLD) || ((x_ok + y_ok + z_ok) < 2)) {
-		return -1;
-	}
-	return 0;
-}
-
-static int mir3da_auto_calibrate(MIR_HANDLE handle, int x, int y, int z)
-{
-	int res = 0;
-	int xyz[3] = { 0 };
-
-	if (is_cali)
-		return -1;
-	is_cali = 1;
-
-	if (mir3da_auto_cali_condition_confirm(x, y, z, xyz)) {
-		res = -1;
-		goto EXIT;
-	}
-
-	/* restore original direction if last calibration was done in a wrong direction */
-	mir3da_write_offset(handle, original_offset);
-
-	res = mir3da_gsensor_drv.obj[gsensor_mod].auto_calibrate(handle, xyz);
-	if (res != 0) {
-		MI_ERR("Calibrate failed !");
-		mir3da_write_offset(handle, original_offset);
-	}
-
-EXIT:
-	is_cali = 0;
-
-	return res;
-}
-#endif /* !MIR3DA_AUTO_CALIBRATE */
-
-static int SOCLE_interrupt_ops(MIR_HANDLE handle, mir_int_ops_t * ops)
-{
-	int res = 0;
-
-	switch (ops->type) {
-	case INTERRUPT_OP_INIT:
-
-		/* active level */
-		mir3da_register_mask_write(handle, SOCLE_REG_CTRL_REG6, (1 << 1), (ops->data.init.level << 1));
-		/* latch */
-		mir3da_register_mask_write(handle, SOCLE_REG_CTRL_REG5, (1 << 3), (ops->data.init.latch << 3));
-		mir3da_register_mask_write(handle, SOCLE_REG_CLICK_CFG, (1 << 6), (ops->data.init.latch << 6));
-
-		break;
-
-	case INTERRUPT_OP_ENABLE:
-
-		switch (ops->data.int_src) {
-		case INTERRUPT_ACTIVITY:
-
-			mir3da_register_write(handle, SOCLE_REG_INT1_CFG, 0x7f);
-			mir3da_register_write(handle, SOCLE_REG_INT2_CFG, 0x7f);
-			break;
-
-		case INTERRUPT_CLICK:
-			/* Enable all directions click and double click detect */
-			mir3da_register_mask_write(handle, SOCLE_REG_CLICK_CFG, 0x3f, 0x3f);
-			break;
-		}
-		break;
-
-	case INTERRUPT_OP_CONFIG:
-
-		switch (ops->data.cfg.int_src) {
-		case INTERRUPT_ACTIVITY:
-
-			if (ops->data.cfg.pin == INTERRUPT_PIN1) {
-				/* enable this int on INT1 */
-				mir3da_register_mask_write(handle, SOCLE_REG_CTRL_REG3, (1 << 6), (1 << 6));
-
-				mir3da_register_mask_write(handle, SOCLE_REG_INT1_THS, 0x7f, ops->data.cfg.int_cfg.act.threshold);
-				mir3da_register_mask_write(handle, SOCLE_REG_INT1_DURATION, 0x7f, ops->data.cfg.int_cfg.act.duration);
-			} else if (ops->data.cfg.pin == INTERRUPT_PIN2) {
-				/* enable this int on INT2 */
-				mir3da_register_mask_write(handle, SOCLE_REG_CTRL_REG6, (1 << 5), (1 << 5));
-
-				mir3da_register_mask_write(handle, SOCLE_REG_INT2_THS, 0x7f, ops->data.cfg.int_cfg.act.threshold);
-				mir3da_register_mask_write(handle, SOCLE_REG_INT2_DURATION, 0x7f, ops->data.cfg.int_cfg.act.duration);
-			}
-			break;
-
-		case INTERRUPT_CLICK:
-
-			mir3da_register_mask_write(handle, SOCLE_REG_CLICK_THS, 0x7f, ops->data.cfg.int_cfg.clk.threshold);
-			mir3da_register_mask_write(handle, SOCLE_REG_TIME_LIMIT, 0x7f, ops->data.cfg.int_cfg.clk.click_time);
-			mir3da_register_write(handle, SOCLE_REG_TIME_LATENCY, ops->data.cfg.int_cfg.clk.quiet_time);
-			mir3da_register_write(handle, SOCLE_REG_TIME_WINDOW, ops->data.cfg.int_cfg.clk.window);
-
-			if (ops->data.cfg.pin == INTERRUPT_PIN1) {
-				mir3da_register_mask_write(handle, SOCLE_REG_CTRL_REG3, (1 << 7), (1 << 7));
-			} else if (ops->data.cfg.pin == INTERRUPT_PIN2) {
-				mir3da_register_mask_write(handle, SOCLE_REG_CTRL_REG6, (1 << 7), (1 << 7));
-			}
-			break;
-		}
-		break;
-
-	case INTERRUPT_OP_DISABLE:
-		switch (ops->data.int_src) {
-		case INTERRUPT_ACTIVITY:
-
-			mir3da_register_write(handle, SOCLE_REG_INT1_CFG, 0);
-			mir3da_register_write(handle, SOCLE_REG_INT2_CFG, 0);
-			break;
-
-		case INTERRUPT_CLICK:
-			/* Enable all directions click and double click detect */
-			mir3da_register_mask_write(handle, SOCLE_REG_CLICK_CFG, 0x3f, 0);
-			break;
-		}
-		break;
-
-	default:
-		MI_ERR("Unsupport operation !");
-	}
-
-	return res;
-}
-
-static int NSA_interrupt_ops(MIR_HANDLE handle, mir_int_ops_t * ops)
-{
-	switch (ops->type) {
-	case INTERRUPT_OP_INIT:
-
-		/* latch */
-		mir3da_register_mask_write(handle, NSA_REG_INT_LATCH, 0x0f, ops->data.init.latch);
-		/* active level & output mode */
-		mir3da_register_mask_write(handle, NSA_REG_INT_PIN_CONFIG, 0x0f, ops->data.init.level | (ops->data.init.pin_mod << 1) | (ops->data.init.level << 2) | (ops->data.init.pin_mod << 3));
-
-		break;
-
-	case INTERRUPT_OP_ENABLE:
-		switch (ops->data.int_src) {
-		case INTERRUPT_ACTIVITY:
-			/* Enable active interrupt */
-			mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_SETTINGS1, 0x07, 0x07);
-			break;
-		case INTERRUPT_CLICK:
-			/* Enable single and double tap detect */
-			mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_SETTINGS1, 0x30, 0x30);
-			break;
-		}
-		break;
-
-	case INTERRUPT_OP_CONFIG:
-
-		switch (ops->data.cfg.int_src) {
-		case INTERRUPT_ACTIVITY:
-
-			mir3da_register_write(handle, NSA_REG_ACTIVE_THRESHOLD, ops->data.cfg.int_cfg.act.threshold);
-			mir3da_register_mask_write(handle, NSA_REG_ACTIVE_DURATION, 0x03, ops->data.cfg.int_cfg.act.duration);
-
-			/* Int mapping */
-			if (ops->data.cfg.pin == INTERRUPT_PIN1) {
-				mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING1, (1 << 2), (1 << 2));
-			} else if (ops->data.cfg.pin == INTERRUPT_PIN2) {
-				printk(" gensor int2  open n");
-				mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING3, (1 << 2), (1 << 2));
-			}
-			break;
-
-		case INTERRUPT_CLICK:
-
-			mir3da_register_mask_write(handle, NSA_REG_TAP_THRESHOLD, 0x1f, ops->data.cfg.int_cfg.clk.threshold);
-			mir3da_register_mask_write(handle, NSA_REG_TAP_DURATION, (0x03 << 5) | (0x07),
-						   (ops->data.cfg.int_cfg.clk.quiet_time << 7) | (ops->data.cfg.int_cfg.clk.click_time << 6) | (ops->data.cfg.int_cfg.clk.window));
-
-			if (ops->data.cfg.pin == INTERRUPT_PIN1) {
-				mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING1, 0x30, 0x30);
-			} else if (ops->data.cfg.pin == INTERRUPT_PIN2) {
-				printk(" gensor int2  close n");
-				mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING3, 0x30, 0x30);
-			}
-			break;
-		}
-		break;
-
-	case INTERRUPT_OP_DISABLE:
-		switch (ops->data.int_src) {
-		case INTERRUPT_ACTIVITY:
-			/* Enable active interrupt */
-			mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_SETTINGS1, 0x07, 0x00);
-			break;
-
-		case INTERRUPT_CLICK:
-			/* Enable single and double tap detect */
-			mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_SETTINGS1, 0x30, 0x00);
-			break;
-		}
-		break;
-
-	default:
-		MI_ERR("Unsupport operation !");
-	}
-	return 0;
-}
-
-int mir3da_interrupt_ops(MIR_HANDLE handle, mir_int_ops_t *ops)
-{
-	int res = 0;
-
-	res = mir3da_gsensor_drv.obj[gsensor_mod].int_ops(handle, ops);
-	return res;
-}
-
-#if FILTER_AVERAGE_ENHANCE
-int mir3da_get_filter_param(struct mir3da_filter_param_s *param)
-{
-	if (param == 0) {
-		MI_ERR("Invalid param!");
-		return -1;
-	}
-
-	param->filter_param_h = core_ctx.tFac[0].filter_param_h;
-	param->filter_param_l = core_ctx.tFac[0].filter_param_l;
-	param->filter_threhold = core_ctx.tFac[0].filter_threhold;
-
-	MI_MSG("FILTER param is get: filter_param_h = %d, filter_param_l = %d, filter_threhold = %d", param->filter_param_h, param->filter_param_l, param->filter_threhold);
-
-	return 0;
-}
-
-int mir3da_set_filter_param(struct mir3da_filter_param_s *param)
-{
-
-	if (param == 0) {
-		MI_ERR("Invalid param!");
-		return -1;
-	}
-
-	MI_MSG("FILTER param is set: filter_param_h = %d, filter_param_l = %d, filter_threhold = %d", param->filter_param_h, param->filter_param_l, param->filter_threhold);
-
-	core_ctx.tFac[1].filter_param_l = core_ctx.tFac[2].filter_param_l = core_ctx.tFac[0].filter_param_l = param->filter_param_l;
-	core_ctx.tFac[1].filter_param_h = core_ctx.tFac[2].filter_param_h = core_ctx.tFac[0].filter_param_h = param->filter_param_h;
-	core_ctx.tFac[1].filter_threhold = core_ctx.tFac[2].filter_threhold = core_ctx.tFac[0].filter_threhold = param->filter_threhold;
-
-	return 0;
-}
-#endif //#if FILTER_AVERAGE_ENHANCE
-
-int mir3da_get_enable(MIR_HANDLE handle, char *enable)
-{
-	unsigned char reg_data;
-	int res = 0;
-
-	res = mir3da_register_read(handle, mir3da_gsensor_drv.obj[gsensor_mod].power.addr, &reg_data);
-	if (res != 0) {
-		return res;
-	}
-
-	*enable = (reg_data & mir3da_gsensor_drv.obj[gsensor_mod].power.mask) ? 0 : 1;
-
-	return res;
-}
-
-int mir3da_set_enable(MIR_HANDLE handle, char enable)
-{
-	int res = 0;
-	unsigned char reg_data = 0;
-
-	if (!enable) {
-		reg_data = mir3da_gsensor_drv.obj[gsensor_mod].power.value;
-	}
-
-	res = mir3da_register_mask_write(handle, mir3da_gsensor_drv.obj[gsensor_mod].power.addr, mir3da_gsensor_drv.obj[gsensor_mod].power.mask, reg_data);
-
-	return res;
-}
-
-static int SOCLE_get_reg_data(MIR_HANDLE handle, char *buf)
-{
-	int i, count = 0;
-	unsigned char val;
-
-	count += mir3da_gsensor_drv.method->mysprintf(buf + count, "---------page 0---------");
-	for (i = 0; i <= 0x003d; i++) {
-		if (i % 16 == 0)
-			count += mir3da_gsensor_drv.method->mysprintf(buf + count, "n%02xt", i);
-		mir3da_register_read(handle, i, &val);
-		count += mir3da_gsensor_drv.method->mysprintf(buf + count, "%02X ", val);
-	}
-
-	count += mir3da_gsensor_drv.method->mysprintf(buf + count, "n---------page 1---------");
-	for (i = 0x0100; i <= 0x012a; i++) {
-		if ((i & 0xff) % 16 == 0)
-			count += mir3da_gsensor_drv.method->mysprintf(buf + count, "n%02xt", (i & 0xff));
-		mir3da_register_read(handle, i, &val);
-		count += mir3da_gsensor_drv.method->mysprintf(buf + count, "%02X ", val);
-
-	}
-	count += mir3da_gsensor_drv.method->mysprintf(buf + count, "n---------end---------n");
-
-	return count;
-}
-
-static int NSA_get_reg_data(MIR_HANDLE handle, char *buf)
-{
-	int count = 0;
-	int i;
-	unsigned char val;
-
-	count += mir3da_gsensor_drv.method->mysprintf(buf + count, "---------start---------");
-	for (i = 0; i <= 0xd2; i++) {
-		if (i % 16 == 0)
-			count += mir3da_gsensor_drv.method->mysprintf(buf + count, "n%02xt", i);
-		mir3da_register_read(handle, i, &val);
-		count += mir3da_gsensor_drv.method->mysprintf(buf + count, "%02X ", val);
-	}
-
-	count += mir3da_gsensor_drv.method->mysprintf(buf + count, "n--------end---------n");
-	return count;
-}
-
-int mir3da_get_reg_data(MIR_HANDLE handle, char *buf)
-{
-	return mir3da_gsensor_drv.obj[gsensor_mod].get_reg_data(handle, buf);
-}
-
-int mir3da_set_odr(MIR_HANDLE handle, int delay)
-{
-	int res = 0;
-	int odr = 0;
-
-	if (delay <= 5) {
-		odr = MIR3DA_ODR_200HZ;
-	} else if (delay <= 10) {
-		odr = MIR3DA_ODR_100HZ;
-	} else {
-		odr = MIR3DA_ODR_50HZ;
-	}
-
-	res = mir3da_register_mask_write(handle, mir3da_gsensor_drv.obj[gsensor_mod].odr_sect[odr].addr,
-					 mir3da_gsensor_drv.obj[gsensor_mod].odr_sect[odr].mask, mir3da_gsensor_drv.obj[gsensor_mod].odr_sect[odr].value);
-	if (res != 0) {
-		return res;
-	}
-
-	return res;
-}
-
-static int mir3da_soft_reset(MIR_HANDLE handle)
-{
-	int res = 0;
-	unsigned char reg_data;
-
-	reg_data = mir3da_gsensor_drv.obj[gsensor_mod].soft_reset.value;
-	res = mir3da_register_mask_write(handle, mir3da_gsensor_drv.obj[gsensor_mod].soft_reset.addr, mir3da_gsensor_drv.obj[gsensor_mod].soft_reset.mask, reg_data);
-	mir3da_gsensor_drv.method->msdelay(5);
-
-	return res;
-}
-
-int mir3da_module_detect(PLAT_HANDLE handle)
-{
-	int i, res = 0;
-	unsigned char cid, mid;
-	int is_find = -1;
-
-	/* Probe gsensor module */
-	for (i = 0; i < sizeof(mir3da_gsensor) / sizeof(mir3da_gsensor[0]); i++) {
-
-		//       res = mir3da_register_mask_write(handle, mir3da_gsensor_drv.obj[i].soft_reset.addr, mir3da_gsensor_drv.obj[i].soft_reset.mask,  mir3da_gsensor_drv.obj[i].soft_reset.value);
-		mir3da_gsensor_drv.method->msdelay(5);
-
-		res = mir3da_register_read(handle, mir3da_gsensor[i].chip_id.addr, &cid);
-		if (res != 0) {
-			return res;
-		}
-
-		cid &= mir3da_gsensor[i].chip_id.mask;
-		if (mir3da_gsensor[i].chip_id.value == cid) {
-			res = mir3da_register_read(handle, mir3da_gsensor[i].mod_id.addr, &mid);
-			if (res != 0) {
-				return res;
-			}
-
-			mid &= mir3da_gsensor[i].mod_id.mask;
-			if (mir3da_gsensor[i].mod_id.value == mid) {
-				MI_MSG("Found Gsensor MIR3DA ! mid =0x%x", mid)
-				    gsensor_mod = i;
-				is_find = 0;
-				break;
-			}
-		}
-	}
-
-	return is_find;
-}
-
-int mir3da_install_general_ops(struct general_op_s *ops)
-{
-	if (0 == ops) {
-		return -1;
-	}
-
-	mir3da_gsensor_drv.method = ops;
-	return 0;
-}
-
-MIR_HANDLE mir3da_core_init(PLAT_HANDLE handle)
-{
-	int res = 0;
-	unsigned char data;
-#if FILTER_AVERAGE_ENHANCE
-	int i = 0;
-#endif
-	int j = 0;
-
-	mir3da_gsensor_drv.obj = mir3da_gsensor;
-
-	for (j = 0; j < 5; j++) {
-		if (gsensor_mod < 0) {
-			res = mir3da_module_detect(handle);
-			if (!res) {
-				MI_ERR("find Mir3da gsensor!!");
-				break;
-			}
-		}
-	}
-
-/*	if(j==5){
-	   MI_ERR("Can't find Mir3da gsensor!!");
-	   return 0;
-	}
-*/
-	MI_MSG("Probe gsensor module: %s", mir3da_gsensor[gsensor_mod].asic);
-
-#if MIR3DA_SENS_TEMP_SOLUTION
-	if (GSENSOR_MOD_SOCLE == gsensor_mod) {
-		mir3da_register_read(handle, SOCLE_REG_OTP_TRIM_THERM_H, &data);
-		if (data == 2) {
-			MI_ERR("Enable sens temp solution !");
-			bSensZoom = 1;
-		}
-	}
-#endif
-
-#if FILTER_AVERAGE_ENHANCE
-	/* configure default filter param */
-	for (i = 0; i < 3; i++) {
-		core_ctx.tFac[i].filter_param_l = 2;
-		core_ctx.tFac[i].filter_param_h = 8;
-		core_ctx.tFac[i].filter_threhold = 60;
-
-		core_ctx.tFac[i].refN_l = 0;
-		core_ctx.tFac[i].refN_h = 0;
-	}
-#endif
-
-	res = mir3da_chip_resume(handle);
-	if (res) {
-		MI_ERR("chip resume fail!!n");
-		return 0;
-	}
-
-	return handle;
-}
-
-int mir3da_chip_resume(MIR_HANDLE handle)
-{
-	int res = 0;
-	unsigned char reg_data;
-	unsigned char i = 0;
-
-	res = mir3da_soft_reset(handle);
-	if (res) {
-		MI_ERR("Do softreset failed !");
-		return res;
-	}
-
-	for (i = 0; i < MIR3DA_INIT_SECT_LEN; i++) {
-		if (mir3da_gsensor_drv.obj[gsensor_mod].init_sect[i].addr < 0) {
-			break;
-		}
-
-		reg_data = mir3da_gsensor_drv.obj[gsensor_mod].init_sect[i].value;
-		res = mir3da_register_mask_write(handle, mir3da_gsensor_drv.obj[gsensor_mod].init_sect[i].addr, mir3da_gsensor_drv.obj[gsensor_mod].init_sect[i].mask, reg_data);
-		if (res != 0) {
-			return res;
-		}
-	}
-
-#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
-	res = mir3da_read_offset(handle, original_offset);
-	if (res != 0) {
-		MI_ERR("Read offset failed !");
-		return res;
-	}
-
-	bLoad = 0;
-	readOffsetCnt = -1;
-	manual_load_cali_file(handle);
-#endif
-
-	return res;
-}
-
-int mir3da_get_primary_offset(MIR_HANDLE handle, int *x, int *y, int *z)
-{
-	int res = 0;
-	unsigned char reg_data;
-	unsigned char i = 0;
-	unsigned char offset[9] = { 0 };
-
-	res = mir3da_read_offset(handle, offset);
-	if (res != 0) {
-		MI_ERR("Read offset failed !");
-		return -1;
-	}
-
-	res = mir3da_soft_reset(handle);
-	if (res) {
-		MI_ERR("Do softreset failed !");
-		return -1;
-	}
-
-	for (i = 0; i < MIR3DA_INIT_SECT_LEN; i++) {
-		if (mir3da_gsensor_drv.obj[gsensor_mod].init_sect[i].addr < 0) {
-			break;
-		}
-
-		reg_data = mir3da_gsensor_drv.obj[gsensor_mod].init_sect[i].value;
-		res = mir3da_register_mask_write(handle, mir3da_gsensor_drv.obj[gsensor_mod].init_sect[i].addr, mir3da_gsensor_drv.obj[gsensor_mod].init_sect[i].mask, reg_data);
-		if (res != 0) {
-			MI_ERR("Write register[0x%x] error!", mir3da_gsensor_drv.obj[gsensor_mod].init_sect[i].addr);
-			goto EXIT;
-		}
-	}
-
-	mir3da_gsensor_drv.method->msdelay(100);
-
-	res = cycle_read_xyz(handle, x, y, z, 20);
-	if (res) {
-		MI_ERR("i2c block read failedn");
-		goto EXIT;
-	}
-
-	mir3da_write_offset(handle, offset);
-
-	return 0;
-
-EXIT:
-	mir3da_write_offset(handle, offset);
-	return -1;
-}
-
-int mir3da_read_int_status(MIR_HANDLE handle)
-{
-	char data = 0;
-
-	mir3da_register_read(handle, NSA_REG_MOTION_FLAG, &data);
-	if (data & 0x04)
-		return 1;
-
-	return 0;
-}
-
-int mir3da_clear_intterrupt(MIR_HANDLE handle)
-{
-	int res = 0;
-
-	res |= mir3da_register_mask_write(handle, NSA_REG_INT_LATCH, 0x80, 0x86);
-
-	return res;
-}
-
-int mir3da_open_interrupt(MIR_HANDLE handle, int num, int on)
-{
-	int res = 0;
-
-	//res |=  mir3da_register_mask_write(handle,NSA_REG_INT_LATCH,0x8F,0x8F);
-	res |= mir3da_register_mask_write(handle, NSA_REG_INT_LATCH, 0x8F, 0x86);
-	// 83 1s 84 2s 85 4s  86 8s  8f yiz 
-	res |= mir3da_register_mask_write(handle, NSA_REG_ACTIVE_DURATION, 0xff, 0x03);
-	res |= mir3da_register_mask_write(handle, NSA_REG_ACTIVE_THRESHOLD, 0xff, 0x10);
-	if (on) {
-		res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_SETTINGS1, 0xff, 0x03);
-		switch (num) {
-
-		case 0:
-			res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING1, 0xff, 0x04);
-			break;
-
-		case 1:
-			res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING3, 0xff, 0x04);
-			break;
-		}
-	} else {
-		res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_SETTINGS1, 0xff, 0x00);
-		res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING1, 0xff, 0x00);
-		res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING3, 0xff, 0x00);
-	}
-
-	return res;
-}
diff --git a/lichee/linux-3.10/drivers/input/sensor/da380/mir3da_core.h b/lichee/linux-3.10/drivers/input/sensor/da380/mir3da_core.h
deleted file mode 100755
index 210390c..0000000
--- a/lichee/linux-3.10/drivers/input/sensor/da380/mir3da_core.h
+++ /dev/null
@@ -1,328 +0,0 @@
-/* Core header for MiraMEMS 3-Axis Accelerometer's driver. 
- * 
- * mir3da_core.h - Linux kernel modules for MiraMEMS 3-Axis Accelerometer
- *
- * Copyright (C) 2011-2013 MiraMEMS Sensing Technology Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#ifndef __MIR3DA_CORE_H__
-#define __MIR3DA_CORE_H__
-
-#define CUST_VER                            ""	/* for Custom debug version */
-#define CORE_VER                            "1.4.2_2014-08-05-17:30:00_"CUST_VER
-
-#define MIR3DA_SUPPORT_CHIP_LIST            MIR_SOCLE, MIR_NSA_NTO, MIR_NSA_MLM
-
-#define MIR3DA_BUFSIZE                      256
-
-#ifdef CONFIG_DA280
-#define NRIPCV				0x08
-#define MIR3DA_TYPE			1	/*da280 */
-#else
-#define MIR3DA_TYPE			0	/*da380 */
-#define NRIPCV				0x05
-#endif
-
-#define MIR3DA_STK_TEMP_SOLUTION            0
-//#define MIR3DA_OFFSET_TEMP_SOLUTION         0
-#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
-#define MIR3DA_AUTO_CALIBRATE               0
-#else
-//#define MIR3DA_AUTO_CALIBRATE               0
-#endif /* !MIR3DA_OFFSET_TEMP_SOLUTION */
-#define MIR3DA_SENS_TEMP_SOLUTION           1
-#define FILTER_AVERAGE_ENHANCE              1
-#define FILTER_AVERAGE_EX                   1
-
-#define MIR3DA_OFFSET_LEN                   9
-
-typedef void *MIR_HANDLE;
-typedef void *PLAT_HANDLE;
-
-struct serial_manage_if_s {
-
-	int (*read) (PLAT_HANDLE handle, unsigned char addr, unsigned char *data);
-	int (*write) (PLAT_HANDLE handle, unsigned char addr, unsigned char data);
-	int (*read_block) (PLAT_HANDLE handle, unsigned char base_addr, unsigned char count, unsigned char *data);
-};
-
-struct general_op_s {
-
-	struct serial_manage_if_s smi;
-
-	int (*data_save) (unsigned char *data);
-	int (*data_get) (unsigned char *data);
-
-	int (*myprintf) (const char *fmt, ...);
-	int (*mysprintf) (char *buf, const char *fmt, ...);
-	void (*msdelay) (int ms);
-};
-
-#define MIR_GENERAL_OPS_DECLARE(OPS_HDL, SMI_RD, SMI_RDBL, SMI_WR, DAT_SAVE, DAT_GET, MDELAY, MYPRINTF, MYSPRINTF)                                      
-                                                                                                                                                        
-                                struct general_op_s     OPS_HDL = { { SMI_RD, SMI_WR, SMI_RDBL }, DAT_SAVE, DAT_GET, MYPRINTF, MYSPRINTF, MDELAY }
-
-enum interrupt_src {
-
-	INTERRUPT_ACTIVITY = 1,
-	INTERRUPT_CLICK,
-
-};
-
-typedef enum _int_op_type {
-
-	INTERRUPT_OP_INIT,
-	INTERRUPT_OP_ENABLE,
-	INTERRUPT_OP_CONFIG,
-	INTERRUPT_OP_DISABLE,
-
-} mir_int_op_type;
-
-enum interrupt_pin {
-
-	INTERRUPT_PIN1,
-	INTERRUPT_PIN2,
-};
-
-enum pin_output_mode {
-
-	OUTPUT_MOD_PULL_PUSH,
-	OUTPUT_MOD_OD,
-};
-
-struct int_act_cfg_s {
-
-	unsigned char threshold;
-	unsigned char duration;
-};
-
-struct int_clk_cfg_s {
-
-	unsigned char threshold;
-	unsigned char click_time;	/* click time */
-	unsigned char quiet_time;	/* quiet time after click */
-	unsigned char window;	/* for second click time window */
-};
-
-typedef union _int_src_configuration {
-
-	struct int_act_cfg_s act;
-	struct int_clk_cfg_s clk;
-
-} mir_int_src_cfg_t;
-
-typedef struct _int_configuration {
-
-	enum interrupt_pin pin;
-	enum interrupt_src int_src;
-
-	mir_int_src_cfg_t int_cfg;
-
-} mir_int_cfg_t;
-
-typedef struct _int_init_data {
-
-	enum pin_output_mode pin_mod;
-
-	unsigned char level;	/* 1: high active, 0: low active */
-	unsigned char latch;	/* >0: latch time, 0: no latch */
-
-} mir_int_init_t;
-
-typedef union _int_op_data {
-
-	enum interrupt_src int_src;
-
-	mir_int_init_t init;
-	mir_int_cfg_t cfg;
-
-} mir_int_op_data;
-
-typedef struct _int_operations {
-
-	mir_int_op_type type;
-	mir_int_op_data data;
-
-} mir_int_ops_t;
-
-/* Register Define for SOCLE asic */
-#define SOCLE_REG_SOFT_RESET            0x0105
-#define SOCLE_REG_LDO_REG               0x0006
-#define SOCLE_REG_WHO_AM_I              0x000f
-#define SOCLE_REG_TEMP_CFG_REG          0x001f
-#define SOCLE_REG_CTRL_REG1             0x0020
-#define SOCLE_REG_CTRL_REG3             0X0022
-#define SOCLE_REG_CTRL_REG4             0x0023
-#define SOCLE_REG_CTRL_REG5             0x0024
-#define SOCLE_REG_CTRL_REG6             0x0025
-#define SOCLE_REG_STATUS_REG            0x0027
-#define SOCLE_REG_OUT_X_L               0x0028
-#define SOCLE_REG_OUT_X_H               0x0029
-#define SOCLE_REG_OUT_Y_L               0x002A
-#define SOCLE_REG_OUT_Y_H               0x002B
-#define SOCLE_REG_OUT_Z_L               0x002C
-#define SOCLE_REG_OUT_Z_H               0x002D
-#define SOCLE_REG_INT1_CFG              0x0030
-#define SOCLE_REG_INT1_SRC              0x0031
-#define SOCLE_REG_INT1_THS              0x0032
-#define SOCLE_REG_INT1_DURATION         0x0033
-#define SOCLE_REG_INT2_CFG              0x0034
-#define SOCLE_REG_INT2_SRC              0x0035
-#define SOCLE_REG_INT2_THS              0x0036
-#define SOCLE_REG_INT2_DURATION         0x0037
-#define SOCLE_REG_CLICK_CFG             0x0038
-#define SOCLE_REG_CLICK_SRC             0x0039
-#define SOCLE_REG_CLICK_THS             0x003A
-#define SOCLE_REG_TIME_LIMIT            0x003B
-#define SOCLE_REG_TIME_LATENCY          0x003C
-#define SOCLE_REG_TIME_WINDOW           0x003D
-#define SOCLE_REG_OTP_XOFF_L            0x0110
-#define SOCLE_REG_OTP_XOFF_H            0x0111
-#define SOCLE_REG_OTP_YOFF_L            0x0112
-#define SOCLE_REG_OTP_YOFF_H            0x0113
-#define SOCLE_REG_OTP_ZOFF_L            0x0114
-#define SOCLE_REG_OTP_ZOFF_H            0x0115
-#define SOCLE_REG_OTP_XSO               0x0116
-#define SOCLE_REG_OTP_YSO               0x0117
-#define SOCLE_REG_OTP_ZSO               0x0118
-#define SOCLE_REG_OTP_TRIM_OSC          0x011b
-#define SOCLE_REG_LPF_ABSOLUTE          0x011c
-#define SOCLE_REG_TEMP_OFF1             0x0127
-#define SOCLE_REG_TEMP_OFF2             0x0128
-#define SOCLE_REG_TEMP_OFF3             0x0129
-#define SOCLE_REG_OTP_TRIM_THERM_H      0x011a
-
-/* Register define for NSA asic */
-#define NSA_REG_SPI_I2C                 0x00
-#define NSA_REG_WHO_AM_I                0x01
-#define NSA_REG_ACC_X_LSB               0x02
-#define NSA_REG_ACC_X_MSB               0x03
-#define NSA_REG_ACC_Y_LSB               0x04
-#define NSA_REG_ACC_Y_MSB               0x05
-#define NSA_REG_ACC_Z_LSB               0x06
-#define NSA_REG_ACC_Z_MSB               0x07
-#define NSA_REG_G_RANGE                 0x0f
-#define NSA_REG_MOTION_FLAG          0x09
-#define NSA_REG_ODR_AXIS_DISABLE        0x10
-#define NSA_REG_POWERMODE_BW            0x11
-#define NSA_REG_SWAP_POLARITY           0x12
-#define NSA_REG_FIFO_CTRL               0x14
-#define NSA_REG_INTERRUPT_SETTINGS1     0x16
-#define NSA_REG_INTERRUPT_SETTINGS2     0x17
-#define NSA_REG_INTERRUPT_MAPPING1      0x19
-#define NSA_REG_INTERRUPT_MAPPING2      0x1a
-#define NSA_REG_INTERRUPT_MAPPING3      0x1b
-#define NSA_REG_INT_PIN_CONFIG          0x20
-#define NSA_REG_INT_LATCH               0x21
-#define NSA_REG_ACTIVE_DURATION         0x27
-#define NSA_REG_ACTIVE_THRESHOLD        0x28
-#define NSA_REG_TAP_DURATION            0x2A
-#define NSA_REG_TAP_THRESHOLD           0x2B
-#define NSA_REG_CUSTOM_OFFSET_X         0x38
-#define NSA_REG_CUSTOM_OFFSET_Y         0x39
-#define NSA_REG_CUSTOM_OFFSET_Z         0x3a
-#define NSA_REG_ENGINEERING_MODE        0x7f
-#define NSA_REG_SENSITIVITY_TRIM_X      0x80
-#define NSA_REG_SENSITIVITY_TRIM_Y      0x81
-#define NSA_REG_SENSITIVITY_TRIM_Z      0x82
-#define NSA_REG_COARSE_OFFSET_TRIM_X    0x83
-#define NSA_REG_COARSE_OFFSET_TRIM_Y    0x84
-#define NSA_REG_COARSE_OFFSET_TRIM_Z    0x85
-#define NSA_REG_FINE_OFFSET_TRIM_X      0x86
-#define NSA_REG_FINE_OFFSET_TRIM_Y      0x87
-#define NSA_REG_FINE_OFFSET_TRIM_Z      0x88
-#define NSA_REG_SENS_COMP               0x8c
-#define NSA_REG_SENS_COARSE_TRIM        0xd1
-
-#define MIR3DA_ODR_50HZ                  0
-#define MIR3DA_ODR_100HZ                 1
-#define MIR3DA_ODR_200HZ                 2
-
-#define MI_TAG                          "[MIR3DA] "
-enum {
-	DEBUG_ERR = 1,
-	DEBUG_ASSERT = 1 << 1,
-	DEBUG_MSG = 1 << 2,
-	DEBUG_FUNC = 1 << 3,
-	DEBUG_DATA = 1 << 4,
-};
-
-/* register operation */
-int mir3da_register_read(MIR_HANDLE handle, short reg, unsigned char *data);
-int mir3da_register_write(MIR_HANDLE handle, short reg, unsigned char data);
-int mir3da_register_read_continuously(MIR_HANDLE handle, short base_reg, unsigned char count, unsigned char *data);
-int mir3da_register_mask_write(MIR_HANDLE handle, short addr, unsigned char mask, unsigned char data);
-
-int mir3da_install_general_ops(struct general_op_s *ops);
-/* chip init */
-int mir3da_module_detect(PLAT_HANDLE handle);
-MIR_HANDLE mir3da_core_init(PLAT_HANDLE handle);
-
-/* data polling */
-int mir3da_read_data(MIR_HANDLE handle, short *x, short *y, short *z);
-
-/* filter configure */
-#ifdef FILTER_AVERAGE_ENHANCE
-struct mir3da_filter_param_s {
-	int filter_param_l;
-	int filter_param_h;
-	int filter_threhold;
-};
-
-int mir3da_get_filter_param(struct mir3da_filter_param_s *param);
-int mir3da_set_filter_param(struct mir3da_filter_param_s *param);
-#endif
-
-#ifdef MIR3DA_STK_TEMP_SOLUTION
-extern char bxstk;
-extern char bystk;
-extern char bzstk;
-extern int squareRoot(int val);
-#endif
-
-enum {
-	GSENSOR_MOD_SOCLE = 0,
-	GSENSOR_MOD_NSA_NTO,
-	GSENSOR_MOD_NSA_MLM,
-};
-
-extern int gsensor_mod;		/* Initial value */
-
-/* CALI */
-int mir3da_calibrate(MIR_HANDLE handle, int z_dir);
-
-/* calibration */
-#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
-extern char bLoad;
-void manual_load_cali_file(MIR_HANDLE handle);
-#endif
-
-/* Interrupt operations */
-int mir3da_interrupt_ops(MIR_HANDLE handle, mir_int_ops_t * ops);
-
-int cycle_read_xyz(MIR_HANDLE handle, int *x, int *y, int *z, int ncycle);
-
-int mir3da_read_offset(MIR_HANDLE handle, unsigned char *offst);
-int mir3da_write_offset(MIR_HANDLE handle, unsigned char *offset);
-int mir3da_open_interrupt(MIR_HANDLE handle, int num, int on);
-int mir3da_clear_intterrupt(MIR_HANDLE handle);
-int mir3da_set_enable(MIR_HANDLE handle, char bEnable);
-int mir3da_get_enable(MIR_HANDLE handle, char *bEnable);
-int mir3da_get_reg_data(MIR_HANDLE handle, char *buf);
-int mir3da_set_odr(MIR_HANDLE handle, int delay);
-int mir3da_direction_remap(short *x, short *y, short *z, int direction);
-
-int mir3da_chip_resume(MIR_HANDLE handle);
-int mir3da_read_int_status(MIR_HANDLE handle);
-int mir3da_get_primary_offset(MIR_HANDLE handle, int *x, int *y, int *z);
-#endif /* __MIR3DA_CORE_H__ */
diff --git a/lichee/linux-3.10/drivers/input/sensor/da380/mir3da_cust.c b/lichee/linux-3.10/drivers/input/sensor/da380/mir3da_cust.c
deleted file mode 100755
index c10bc1e..0000000
--- a/lichee/linux-3.10/drivers/input/sensor/da380/mir3da_cust.c
+++ /dev/null
@@ -1,1207 +0,0 @@
-/* For AllWinner android platform.
- *
- * mir3da.c - Linux kernel modules for 3-Axis Accelerometer
- *
- * Copyright (C) 2011-2013 MiraMEMS Sensing Technology Co., Ltd.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/i2c.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/hwmon-sysfs.h>
-#include <linux/err.h>
-#include <linux/input-polldev.h>
-#include <linux/miscdevice.h>
-#include <linux/fs.h>
-#include <linux/stat.h>
-#include <linux/syscalls.h>
-#include <asm/uaccess.h>
-#include <linux/kernel.h>
-#include <linux/gpio.h>
-#include <linux/init-input.h>
-#include <linux/of_gpio.h>
-#include <linux/hwmon.h>
-#include <linux/hwmon-sysfs.h>
-#include <linux/hwmon-vid.h>
-#include "mir3da_core.h"
-#include "mir3da_cust.h"
-#ifdef CONFIG_HAS_EARLYSUSPEND
-#include <linux/earlysuspend.h>
-#endif
-#if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_PM)
-#include <linux/pm.h>
-#endif
-
-#define MIR3DA_DRV_NAME                 	"da380"
-#define MIR3DA_INPUT_DEV_NAME     			MIR3DA_DRV_NAME
-#define MIR3DA_MISC_NAME                	MIR3DA_DRV_NAME
-
-#define POLL_INTERVAL_MAX               	500
-#define POLL_INTERVAL                   	50
-#define INPUT_FUZZ                      	0
-#define INPUT_FLAT                      	0
-
-static int wake_threshold = 10;
-/*static u32 int_handle = 0;*/
-static struct input_polled_dev *mir3da_idev;
-static struct device *hwmon_dev;
-static MIR_HANDLE mir_handle;
-static unsigned int slope_th;
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static struct early_suspend early_suspend;
-#endif
-
-static unsigned int delayMs = 50;
-static unsigned char twi_id = 0;
-
-extern int Log_level;
-static int int2_enable = 0;
-static int int2_statu = 0;
-
-static const unsigned short normal_i2c[] = { 0x27, 0x26, I2C_CLIENT_END };
-
-static struct sensor_config_info gsensor_info = {
-	.input_type = GSENSOR_TYPE,
-};
-
-#define MI_DATA(format, ...)         	if(DEBUG_DATA&Log_level){printk(KERN_ERR MI_TAG format "n", ## __VA_ARGS__);}
-#define MI_MSG(format, ...)             if(DEBUG_MSG&Log_level){printk(KERN_ERR MI_TAG format "n", ## __VA_ARGS__);}
-#define MI_ERR(format, ...)             	if(DEBUG_ERR&Log_level){printk(KERN_ERR MI_TAG format "n", ## __VA_ARGS__);}
-#define MI_FUN                          	if(DEBUG_FUNC&Log_level){printk(KERN_ERR MI_TAG "%s is called, line: %dn", __FUNCTION__,__LINE__);}
-#define MI_ASSERT(expr)                 
-	if (!(expr)) {
-		printk(KERN_ERR "Assertion failed! %s,%d,%s,%sn",
-			__FILE__, __LINE__, __func__, #expr);
-	}
-
-/*----------------------------------------------------------------------------*/
-#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
-static char OffsetFileName[] = "/data/misc/miraGSensorOffset.txt";
-#define OFFSET_STRING_LEN               26
-struct work_info {
-	char tst1[20];
-	char tst2[20];
-	char buffer[OFFSET_STRING_LEN];
-	struct workqueue_struct *wq;
-	struct delayed_work read_work;
-	struct delayed_work write_work;
-	struct completion completion;
-	int len;
-	int rst;
-};
-
-static struct work_info m_work_info = { {0} };
-
-/*----------------------------------------------------------------------------*/
-static void sensor_write_work(struct work_struct *work)
-{
-	struct work_info *pWorkInfo;
-	struct file *filep;
-	u32 orgfs;
-	int ret;
-
-	orgfs = get_fs();
-	set_fs(KERNEL_DS);
-
-	pWorkInfo = container_of((struct delayed_work *)work, struct work_info, write_work);
-	if (pWorkInfo == NULL) {
-		MI_ERR("get pWorkInfo failed!");
-		return;
-	}
-
-	filep = filp_open(OffsetFileName, O_RDWR | O_CREAT, 0600);
-	if (IS_ERR(filep)) {
-		MI_ERR("write, sys_open %s error!!.n", OffsetFileName);
-		ret = -1;
-	} else {
-		filep->f_op->write(filep, pWorkInfo->buffer, pWorkInfo->len, &filep->f_pos);
-		filp_close(filep, NULL);
-		ret = 0;
-	}
-
-	set_fs(orgfs);
-	pWorkInfo->rst = ret;
-	complete(&pWorkInfo->completion);
-}
-
-/*----------------------------------------------------------------------------*/
-static void sensor_read_work(struct work_struct *work)
-{
-	u32 orgfs;
-	struct file *filep;
-	int ret;
-	struct work_info *pWorkInfo;
-
-	orgfs = get_fs();
-	set_fs(KERNEL_DS);
-
-	pWorkInfo = container_of((struct delayed_work *)work, struct work_info, read_work);
-	if (pWorkInfo == NULL) {
-		MI_ERR("get pWorkInfo failed!");
-		return;
-	}
-
-	filep = filp_open(OffsetFileName, O_RDONLY, 0600);
-	if (IS_ERR(filep)) {
-		MI_ERR("read, sys_open %s error!!.n", OffsetFileName);
-		set_fs(orgfs);
-		ret = -1;
-	} else {
-		filep->f_op->read(filep, pWorkInfo->buffer, sizeof(pWorkInfo->buffer), &filep->f_pos);
-		filp_close(filep, NULL);
-		set_fs(orgfs);
-		ret = 0;
-	}
-
-	pWorkInfo->rst = ret;
-	complete(&(pWorkInfo->completion));
-}
-
-/*----------------------------------------------------------------------------*/
-static int sensor_sync_read(u8 *offset)
-{
-	int err;
-	int off[MIR3DA_OFFSET_LEN] = { 0 };
-	struct work_info *pWorkInfo = &m_work_info;
-
-	init_completion(&pWorkInfo->completion);
-	queue_delayed_work(pWorkInfo->wq, &pWorkInfo->read_work, msecs_to_jiffies(0));
-	err = wait_for_completion_timeout(&pWorkInfo->completion, msecs_to_jiffies(2000));
-	if (err == 0) {
-		MI_ERR("wait_for_completion_timeout TIMEOUT");
-		return -1;
-	}
-
-	if (pWorkInfo->rst != 0) {
-		MI_ERR("work_info.rst  not equal 0");
-		return pWorkInfo->rst;
-	}
-
-	sscanf(m_work_info.buffer, "%x,%x,%x,%x,%x,%x,%x,%x,%x", &off[0], &off[1], &off[2], &off[3], &off[4], &off[5], &off[6], &off[7], &off[8]);
-
-	offset[0] = (u8) off[0];
-	offset[1] = (u8) off[1];
-	offset[2] = (u8) off[2];
-	offset[3] = (u8) off[3];
-	offset[4] = (u8) off[4];
-	offset[5] = (u8) off[5];
-	offset[6] = (u8) off[6];
-	offset[7] = (u8) off[7];
-	offset[8] = (u8) off[8];
-
-	return 0;
-}
-
-/*----------------------------------------------------------------------------*/
-static int sensor_sync_write(u8 *off)
-{
-	int err = 0;
-	struct work_info *pWorkInfo = &m_work_info;
-
-	init_completion(&pWorkInfo->completion);
-
-	sprintf(m_work_info.buffer, "%x,%x,%x,%x,%x,%x,%x,%x,%xn", off[0], off[1], off[2], off[3], off[4], off[5], off[6], off[7], off[8]);
-
-	pWorkInfo->len = sizeof(m_work_info.buffer);
-
-	queue_delayed_work(pWorkInfo->wq, &pWorkInfo->write_work, msecs_to_jiffies(0));
-	err = wait_for_completion_timeout(&pWorkInfo->completion, msecs_to_jiffies(2000));
-	if (err == 0) {
-		MI_ERR("wait_for_completion_timeout TIMEOUT");
-		return -1;
-	}
-
-	if (pWorkInfo->rst != 0) {
-		MI_ERR("work_info.rst  not equal 0");
-		return pWorkInfo->rst;
-	}
-
-	return 0;
-}
-#endif
-/*----------------------------------------------------------------------------*/
-#ifdef MIR3DA_AUTO_CALIBRAE
-static bool check_califile_exist(void)
-{
-	u32 orgfs = 0;
-	struct file *filep;
-
-	orgfs = get_fs();
-	set_fs(KERNEL_DS);
-
-	filep = filp_open(OffsetFileName, O_RDONLY, 0600);
-	if (IS_ERR(filep)) {
-		MI_MSG("%s read, sys_open %s error!!.n", __func__, OffsetFileName);
-		set_fs(orgfs);
-		return false;
-	}
-
-	filp_close(filep, NULL);
-	set_fs(orgfs);
-
-	return true;
-}
-#endif
-/*----------------------------------------------------------------------------*/
-static void report_abs(void)
-{
-	short x = 0, y = 0, z = 0;
-	MIR_HANDLE handle = mir_handle;
-
-	if (mir3da_read_data(handle, &x, &y, &z) != 0) {
-		MI_ERR("MIR3DA data read failed!n");
-		return;
-	}
-
-	input_report_abs(mir3da_idev->input, ABS_X, x);
-	input_report_abs(mir3da_idev->input, ABS_Y, y);
-	input_report_abs(mir3da_idev->input, ABS_Z, z);
-	input_sync(mir3da_idev->input);
-}
-
-/*----------------------------------------------------------------------------*/
-static void mir3da_dev_poll(struct input_polled_dev *dev)
-{
-	dev->poll_interval = delayMs;
-	report_abs();
-}
-
-/*----------------------------------------------------------------------------*/
-static long mir3da_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-	void __user *argp = (void __user *)arg;
-	int err = 0;
-	int interval = 0;
-	char bEnable = 0;
-
-	short xyz[3] = { 0 };
-	MIR_HANDLE handle = mir_handle;
-
-	if (_IOC_DIR(cmd) & _IOC_READ) {
-		err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
-	} else if (_IOC_DIR(cmd) & _IOC_WRITE) {
-		err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
-	}
-
-	if (err) {
-		return -EFAULT;
-	}
-
-	switch (cmd) {
-	case MIR3DA_ACC_IOCTL_GET_DELAY:
-		interval = POLL_INTERVAL;
-		if (copy_to_user(argp, &interval, sizeof(interval)))
-			return -EFAULT;
-		break;
-
-	case MIR3DA_ACC_IOCTL_SET_DELAY:
-		if (copy_from_user(&interval, argp, sizeof(interval)))
-			return -EFAULT;
-		if (interval < 0 || interval > 1000)
-			return -EINVAL;
-		if ((interval <= 30) && (interval > 10)) {
-			interval = 10;
-		}
-		delayMs = interval;
-		break;
-
-	case MIR3DA_ACC_IOCTL_SET_ENABLE:
-		if (copy_from_user(&bEnable, argp, sizeof(bEnable)))
-			return -EFAULT;
-
-		err = mir3da_set_enable(handle, bEnable);
-		if (err < 0)
-			return EINVAL;
-		break;
-
-	case MIR3DA_ACC_IOCTL_GET_ENABLE:
-		err = mir3da_get_enable(handle, &bEnable);
-		if (err < 0) {
-			return -EINVAL;
-		}
-
-		if (copy_to_user(argp, &bEnable, sizeof(bEnable)))
-			return -EINVAL;
-		break;
-
-#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
-	case MIR3DA_ACC_IOCTL_CALIBRATION:
-		if (copy_from_user(&z_dir, argp, sizeof(z_dir)))
-			return -EFAULT;
-
-		if (mir3da_calibrate(handle, z_dir)) {
-			return -EFAULT;
-		}
-
-		if (copy_to_user(argp, &z_dir, sizeof(z_dir)))
-			return -EFAULT;
-		break;
-
-	case MIR3DA_ACC_IOCTL_UPDATE_OFFSET:
-		manual_load_cali_file(handle);
-		break;
-#endif
-
-	case MIR3DA_ACC_IOCTL_GET_COOR_XYZ:
-
-		if (mir3da_read_data(handle, &xyz[0], &xyz[1], &xyz[2]))
-			return -EFAULT;
-
-		if (copy_to_user((void __user *)arg, xyz, sizeof(xyz)))
-			return -EFAULT;
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
-/*----------------------------------------------------------------------------*/
-static const struct file_operations mir3da_misc_fops = {
-	.owner = THIS_MODULE,
-	.unlocked_ioctl = mir3da_misc_ioctl,
-};
-
-static struct miscdevice misc_mir3da = {
-	.minor = MISC_DYNAMIC_MINOR,
-	.name = MIR3DA_MISC_NAME,
-	.fops = &mir3da_misc_fops,
-};
-
-/*----------------------------------------------------------------------------*/
-static ssize_t mir3da_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	int ret;
-	char bEnable;
-	MIR_HANDLE handle = mir_handle;
-
-	ret = mir3da_get_enable(handle, &bEnable);
-	if (ret < 0) {
-		ret = -EINVAL;
-	} else {
-		ret = sprintf(buf, "%dn", bEnable);
-	}
-
-	return ret;
-}
-
-static int flags = 0;
-/*----------------------------------------------------------------------------*/
-static ssize_t mir3da_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	int ret;
-	char bEnable;
-	unsigned long enable;
-	MIR_HANDLE handle = mir_handle;
-
-	if (buf == NULL) {
-		return -1;
-	}
-
-	if (flags == 1)
-		return 0;
-
-	enable = simple_strtoul(buf, NULL, 10);
-	bEnable = (enable > 0) ? 1 : 0;
-
-	ret = mir3da_set_enable(handle, bEnable);
-	if (ret < 0) {
-		ret = -EINVAL;
-	} else {
-		ret = count;
-	}
-
-	return ret;
-}
-
-/*----------------------------------------------------------------------------*/
-static ssize_t mir3da_delay_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "%dn", delayMs);
-}
-
-/*----------------------------------------------------------------------------*/
-static ssize_t mir3da_delay_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	int interval = 0;
-
-	interval = simple_strtoul(buf, NULL, 10);
-
-	if (interval < 0 || interval > 1000)
-		return -EINVAL;
-
-	if ((interval <= 30) && (interval > 10)) {
-		interval = 10;
-	}
-
-	delayMs = interval;
-
-	return count;
-}
-
-/*----------------------------------------------------------------------------*/
-static ssize_t mir3da_axis_data_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	int result;
-	short x, y, z;
-	int count = 0;
-	MIR_HANDLE handle = mir_handle;
-
-	result = mir3da_read_data(handle, &x, &y, &z);
-	if (result == 0)
-		count += sprintf(buf + count, "x= %d;y=%d;z=%dn", x, y, z);
-	else
-		count += sprintf(buf + count, "reading failed!");
-
-	return count;
-}
-
-/*----------------------------------------------------------------------------*/
-static ssize_t mir3da_reg_data_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	int addr, data;
-	int result;
-	MIR_HANDLE handle = mir_handle;
-
-	sscanf(buf, "0x%x, 0x%xn", &addr, &data);
-
-	result = mir3da_register_write(handle, addr, data);
-
-	MI_ASSERT(result == 0);
-
-	return count;
-}
-
-/*----------------------------------------------------------------------------*/
-static ssize_t mir3da_reg_data_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	MIR_HANDLE handle = mir_handle;
-
-	return mir3da_get_reg_data(handle, buf);
-}
-
-/*----------------------------------------------------------------------------*/
-#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
-static ssize_t mir3da_offset_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	ssize_t count = 0;
-	int rst = 0;
-	u8 off[9] = { 0 };
-	MIR_HANDLE handle = mir_handle;
-
-	rst = mir3da_read_offset(handle, off);
-	if (!rst) {
-		count = sprintf(buf, "%d,%d,%d,%d,%d,%d,%d,%d,%dn", off[0], off[1], off[2], off[3], off[4], off[5], off[6], off[7], off[8]);
-	}
-	return count;
-}
-
-/*----------------------------------------------------------------------------*/
-static ssize_t mir3da_offset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	int off[9] = { 0 };
-	u8 offset[9] = { 0 };
-	int rst = 0;
-	MIR_HANDLE handle = mir_handle;
-
-	sscanf(buf, "%d,%d,%d,%d,%d,%d,%d,%d,%dn", &off[0], &off[1], &off[2], &off[3], &off[4], &off[5], &off[6], &off[7], &off[8]);
-
-	offset[0] = (u8) off[0];
-	offset[1] = (u8) off[1];
-	offset[2] = (u8) off[2];
-	offset[3] = (u8) off[3];
-	offset[4] = (u8) off[4];
-	offset[5] = (u8) off[5];
-	offset[6] = (u8) off[6];
-	offset[7] = (u8) off[7];
-	offset[8] = (u8) off[8];
-
-	rst = mir3da_write_offset(handle, offset);
-	return count;
-}
-#endif
-
-static int int_status = 0;
-static ssize_t mir3da_status_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	int ret = 0;
-
-	ret = sprintf(buf, "%dn", int_status);
-	int_status = 0;
-	return ret;
-}
-
-static ssize_t mir3da_status_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	//int_status = simple_strtol(buf,NULL,10);
-	return count;
-}
-
-/*----------------------------------------------------------------------------*/
-#if FILTER_AVERAGE_ENHANCE
-static ssize_t mir3da_average_enhance_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	int ret = 0;
-	struct mir3da_filter_param_s param = { 0 };
-
-	ret = mir3da_get_filter_param(&param);
-	ret |= sprintf(buf, "%d %d %dn", param.filter_param_l, param.filter_param_h, param.filter_threhold);
-
-	return ret;
-}
-
-/*----------------------------------------------------------------------------*/
-static ssize_t mir3da_average_enhance_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	int ret = 0;
-	struct mir3da_filter_param_s param = { 0 };
-
-	sscanf(buf, "%d %d %dn", &param.filter_param_l, &param.filter_param_h, &param.filter_threhold);
-
-	ret = mir3da_set_filter_param(&param);
-
-	return count;
-}
-#endif
-/*----------------------------------------------------------------------------*/
-#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
-int bCaliResult = -1;
-static ssize_t mir3da_calibrate_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	int ret;
-
-	ret = sprintf(buf, "%dn", bCaliResult);
-	return ret;
-}
-
-/*----------------------------------------------------------------------------*/
-static ssize_t mir3da_calibrate_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	s8 z_dir = 0;
-	MIR_HANDLE handle = mir_handle;
-
-	z_dir = simple_strtol(buf, NULL, 10);
-	bCaliResult = mir3da_calibrate(handle, z_dir);
-
-	return count;
-}
-#endif
-/*----------------------------------------------------------------------------*/
-static ssize_t mir3da_log_level_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	int ret;
-
-	ret = sprintf(buf, "%dn", Log_level);
-
-	return ret;
-}
-
-/*----------------------------------------------------------------------------*/
-static ssize_t mir3da_log_level_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	Log_level = simple_strtoul(buf, NULL, 10);
-
-	return count;
-}
-
-static int mir3da_int2_set_onoff(struct device *dev, int onoff)
-{
-	int res = 0;
-	MIR_HANDLE handle = mir_handle;
-	int2_enable = onoff;
-	MI_ERR("mir3da_int2_enable_store num:%d onoff:%d slope 0x%xn", MIR3DA_TYPE, onoff, slope_th);
-	res |= mir3da_register_mask_write(handle, NSA_REG_INT_LATCH, 0x8F, slope_th);
-	// 83 1s 84 2s 85 4s  86 8s  8f 
-	res |= mir3da_register_mask_write(handle, NSA_REG_ACTIVE_DURATION, 0xff, 0x03);
-	res |= mir3da_register_mask_write(handle, NSA_REG_ACTIVE_THRESHOLD, 0xff, wake_threshold);
-	if (onoff) {
-		res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_SETTINGS1, 0xff, 0x03);
-		switch (MIR3DA_TYPE) {
-
-		case 0:
-			res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING1, 0xff, 0x04);
-			break;
-
-		case 1:
-			res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING3, 0xff, 0x04);
-			break;
-		}
-	} else {
-		res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_SETTINGS1, 0xff, 0x00);
-		res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING1, 0xff, 0x00);
-		res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING3, 0xff, 0x00);
-	}
-	return 0;
-}
-
-static ssize_t mir3da_int2_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	int2_enable = simple_strtoul(buf, NULL, 10);
-
-	mir3da_int2_set_onoff(dev, int2_enable);
-
-	return count;
-}
-
-static ssize_t mir3da_int2_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	int ret;
-
-	ret = sprintf(buf, "%dn", int2_enable);
-	printk(" mir3da_int2_enable_show ret [ %d ]n", ret);
-	return ret;
-}
-
-static ssize_t mir3da_int2_clear_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-
-	MIR_HANDLE handle = mir_handle;
-
-	printk(" mir3da_int2_clear_enable_store int2_clean n");
-	mir3da_clear_intterrupt(handle);
-
-	return count;
-}
-
-static ssize_t mir3da_wake_threshold_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	int ret;
-
-	ret = sprintf(buf, "%dn", wake_threshold);
-	printk(" wake_threshold [ %d ]n", wake_threshold);
-	return ret;
-}
-
-static ssize_t mir3da_wake_threshold_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	wake_threshold = simple_strtoul(buf, NULL, 10);
-
-	if (wake_threshold < 0)
-		wake_threshold = 0;
-	if (wake_threshold > 250)
-		wake_threshold = 250;
-
-	printk(" wake_threshold [ %d ]n", wake_threshold);
-	return count;
-}
-
-static ssize_t mir3da_int2_clear_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	int ret = 0;
-
-	//ret = sprintf(buf, "%dn", int2_enable);
-	//printk(" mir3da_int2_clear_enable_show ret [ %d ]n",ret);
-	return ret;
-}
-
-static ssize_t mir3da_int2_start_statu_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-
-	//MIR_HANDLE      handle = mir_handle;
-
-	int2_statu = simple_strtoul(buf, NULL, 10);
-
-	return count;
-}
-
-static ssize_t mir3da_int2_start_statu_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	int ret;
-	//MIR_HANDLE      handle = mir_handle;
-
-	//int2_statu =  mir3da_read_int_status( handle);
-
-	ret = sprintf(buf, "%dn", int2_statu);
-	printk(" mir3da_int2_enable_show ret [ %d ]n", ret);
-	return ret;
-}
-
-/*----------------------------------------------------------------------------*/
-static ssize_t mir3da_primary_offset_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	MIR_HANDLE handle = mir_handle;
-	int x = 0, y = 0, z = 0;
-
-	mir3da_get_primary_offset(handle, &x, &y, &z);
-
-	return sprintf(buf, "x=%d ,y=%d ,z=%dn", x, y, z);
-
-}
-
-/*----------------------------------------------------------------------------*/
-static ssize_t mir3da_version_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-
-	return sprintf(buf, "%s_%sn", DRI_VER, CORE_VER);
-}
-
-/*----------------------------------------------------------------------------*/
-static ssize_t mir3da_vendor_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "%sn", "MiraMEMS");
-}
-
-static ssize_t mir3da_slope_th_show(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "0x%xn", slope_th);
-}
-
-static ssize_t mir3da_slope_th_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
-	unsigned long data;
-	int error = 0;
-	error = strict_strtoul(buf, 16, &data);
-	if (error)
-		return error;
-	if (data == 0x3) {	//high
-		data = 0x84;
-	} else if (data == 0xf) {	//low
-		data = 0x86;
-	} else if (data == 0x5) {	//mid
-		data = 0x85;
-	}
-	printk("set slope 0x%lxn", data);
-	slope_th = data;
-	return count;
-}
-
-/*----------------------------------------------------------------------------*/
-static DEVICE_ATTR(enable, S_IRUGO | S_IWUGO, mir3da_enable_show, mir3da_enable_store);
-static DEVICE_ATTR(delay, S_IRUGO | S_IWUGO, mir3da_delay_show, mir3da_delay_store);
-static DEVICE_ATTR(axis_data, S_IRUGO | S_IWUGO, mir3da_axis_data_show, NULL);
-static DEVICE_ATTR(reg_data, S_IWUGO | S_IRUGO, mir3da_reg_data_show, mir3da_reg_data_store);
-static DEVICE_ATTR(log_level, S_IWUGO | S_IRUGO, mir3da_log_level_show, mir3da_log_level_store);
-#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
-static DEVICE_ATTR(offset, S_IWUGO | S_IRUGO, mir3da_offset_show, mir3da_offset_store);
-static DEVICE_ATTR(calibrate_miraGSensor, S_IWUGO | S_IRUGO, mir3da_calibrate_show, mir3da_calibrate_store);
-#endif
-#ifdef FILTER_AVERAGE_ENHANCE
-static DEVICE_ATTR(average_enhance, S_IWUGO | S_IRUGO, mir3da_average_enhance_show, mir3da_average_enhance_store);
-#endif
-// aad cz
-static DEVICE_ATTR(int2_enable, S_IRUGO | S_IWUGO, mir3da_int2_enable_show, mir3da_int2_enable_store);
-static DEVICE_ATTR(int2_clear, S_IRUGO | S_IWUGO, mir3da_int2_clear_enable_show, mir3da_int2_clear_enable_store);
-static DEVICE_ATTR(int2_start_status, S_IRUGO | S_IWUGO, mir3da_int2_start_statu_show, mir3da_int2_start_statu_store);
-
-static DEVICE_ATTR(threshold, S_IRUGO | S_IWUGO, mir3da_wake_threshold_show, mir3da_wake_threshold_store);
-static DEVICE_ATTR(status, S_IRUGO | S_IWUGO, mir3da_status_show, mir3da_status_store);
-static DEVICE_ATTR(primary_offset, S_IWUGO, mir3da_primary_offset_show, NULL);
-static DEVICE_ATTR(version, S_IRUGO, mir3da_version_show, NULL);
-static DEVICE_ATTR(vendor, S_IRUGO, mir3da_vendor_show, NULL);
-static DEVICE_ATTR(slope_th, S_IRUGO | S_IWUGO, mir3da_slope_th_show, mir3da_slope_th_store);
-
-/*----------------------------------------------------------------------------*/
-static struct attribute *mir3da_attributes[] = {
-	&dev_attr_enable.attr,
-	&dev_attr_delay.attr,
-	&dev_attr_axis_data.attr,
-	&dev_attr_reg_data.attr,
-	&dev_attr_log_level.attr,
-#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
-	&dev_attr_offset.attr,
-	&dev_attr_calibrate_miraGSensor.attr,
-//  &dev_attr_primary_offset.attr,
-#endif
-#ifdef FILTER_AVERAGE_ENHANCE
-	&dev_attr_average_enhance.attr,
-#endif /* ! FILTER_AVERAGE_ENHANCE */
-	&dev_attr_int2_enable.attr,
-	&dev_attr_int2_clear.attr,
-	&dev_attr_int2_start_status.attr,
-	&dev_attr_threshold.attr,
-	&dev_attr_status.attr,
-	&dev_attr_primary_offset.attr,
-	&dev_attr_version.attr,
-	&dev_attr_vendor.attr,
-	&dev_attr_slope_th.attr,
-	NULL
-};
-
-static const struct attribute_group mir3da_attr_group = {
-	.attrs = mir3da_attributes,
-};
-
-/*----------------------------------------------------------------------------*/
-int i2c_smbus_read(PLAT_HANDLE handle, u8 addr, u8 * data)
-{
-	int res = 0;
-	struct i2c_client *client = (struct i2c_client *)handle;
-
-	*data = i2c_smbus_read_byte_data(client, addr);
-
-	return res;
-}
-
-/*----------------------------------------------------------------------------*/
-int i2c_smbus_read_block(PLAT_HANDLE handle, u8 addr, u8 count, u8 * data)
-{
-	int res = 0;
-	struct i2c_client *client = (struct i2c_client *)handle;
-
-	res = i2c_smbus_read_i2c_block_data(client, addr, count, data);
-
-	return res;
-}
-
-/*----------------------------------------------------------------------------*/
-int i2c_smbus_write(PLAT_HANDLE handle, u8 addr, u8 data)
-{
-	int res = 0;
-	struct i2c_client *client = (struct i2c_client *)handle;
-
-	res = i2c_smbus_write_byte_data(client, addr, data);
-
-	return res;
-}
-
-/*----------------------------------------------------------------------------*/
-void msdelay(int ms)
-{
-	mdelay(ms);
-}
-
-#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
-MIR_GENERAL_OPS_DECLARE(ops_handle, i2c_smbus_read, i2c_smbus_read_block, i2c_smbus_write, sensor_sync_write, sensor_sync_read, msdelay, printk, sprintf);
-#else
-MIR_GENERAL_OPS_DECLARE(ops_handle, i2c_smbus_read, i2c_smbus_read_block, i2c_smbus_write, NULL, NULL, msdelay, printk, sprintf);
-#endif
-/*----------------------------------------------------------------------------*/
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static void mir3da_early_suspend(struct early_suspend *h)
-{
-	MIR_HANDLE handle = mir_handle;
-	MI_FUN;
-	flags = 1;
-#if 1
-	mir3da_register_write(handle, NSA_REG_POWERMODE_BW, 0x0E);
-	mir3da_register_write(handle, NSA_REG_INT_PIN_CONFIG, 0x05);
-	mir3da_register_write(handle, NSA_REG_INT_LATCH, slope_th);
-	mir3da_register_write(handle, NSA_REG_INTERRUPT_SETTINGS1, 0x03);
-	mir3da_register_write(handle, NSA_REG_ACTIVE_DURATION, 0x03);
-	mir3da_register_write(handle, NSA_REG_ACTIVE_THRESHOLD, wake_threshold);
-	mir3da_register_write(handle, NSA_REG_INTERRUPT_MAPPING1, 0x04);
-#endif
-	printk("=============== mir3da early suspend======================000===n");
-	//mir3da_set_enable(handle, 0);
-	mir3da_idev->input->close(mir3da_idev->input);
-}
-
-static void mir3da_late_resume(struct early_suspend *h)
-{
-	//MIR_HANDLE handle = mir_handle;
-	MI_FUN;
-	printk("=============== mir3da early resume=========================n");
-	//mir3da_chip_resume(handle);
-	//mir3da_set_enable(handle, 1);
-	mir3da_int2_set_onoff(NULL, 0);
-	mir3da_idev->input->open(mir3da_idev->input);
-	flags = 0;
-}
-#else
-/*----------------------------------------------------------------------------*/
-static int mir3da_suspend(struct i2c_client *client, pm_message_t mesg)
-{
-	int result = 0;
-	MIR_HANDLE handle = mir_handle;
-
-	MI_FUN;
-
-	printk(KERN_ERR "=============== mir3da  suspend=========================n");
-	result = mir3da_set_enable(handle, 0);
-	if (result) {
-		MI_ERR("%s:set disable fail!!n", __func__);
-		return result;
-	}
-	mir3da_idev->input->close(mir3da_idev->input);
-
-	return result;
-}
-
-/*----------------------------------------------------------------------------*/
-static int mir3da_resume(struct i2c_client *client)
-{
-	int result = 0;
-	MIR_HANDLE handle = mir_handle;
-
-	MI_FUN;
-	printk(KERN_ERR "=============== mir3da  resume=========================n");
-
-	result = mir3da_chip_resume(handle);
-	if (result) {
-		MI_ERR("%s:chip resume fail!!n", __func__);
-		return result;
-	}
-
-	result = mir3da_set_enable(handle, 1);
-	if (result) {
-		MI_ERR("%s:set enable fail!!n", __func__);
-		return result;
-	}
-
-	mir3da_idev->input->open(mir3da_idev->input);
-
-	return result;
-}
-
-/*----------------------------------------------------------------------------*/
-
-#endif
-
-/*static u32 gsensor_irq_func(int irq, void *para)
-{
-	printk("[haibo] mir gsensor into irq funcn");
-	int_status = 1;
-	return 0;
-}*/
-
-static int mir3da_probe(struct i2c_client *client, const struct i2c_device_id *id)
-{
-	int result = 0;
-	/*int ret;*/
-	struct input_dev *idev;
-	if (mir3da_install_general_ops(&ops_handle)) {
-		MI_ERR("Install ops failed !n");
-		goto err_detach_client;
-	}
-#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
-	m_work_info.wq = create_singlethread_workqueue("oo");
-	if (NULL == m_work_info.wq) {
-		MI_ERR("Failed to create workqueue !");
-		goto err_detach_client;
-	}
-
-	INIT_DELAYED_WORK(&m_work_info.read_work, sensor_read_work);
-	INIT_DELAYED_WORK(&m_work_info.write_work, sensor_write_work);
-#endif
-
-	int2_statu = mir3da_read_int_status((PLAT_HANDLE) client);
-	printk("ParkMonitor powerOn status is %dn", int2_statu);
-
-	/* Initialize the MIR3DA chip */
-	mir_handle = mir3da_core_init((PLAT_HANDLE) client);
-	if (NULL == mir_handle) {
-		MI_ERR("chip init failed !n");
-		goto err_detach_client;
-	}
-
-	hwmon_dev = hwmon_device_register(&client->dev);
-	MI_ASSERT(!(IS_ERR(hwmon_dev)));
-
-	/* input poll device register */
-	mir3da_idev = input_allocate_polled_device();
-	if (!mir3da_idev) {
-		MI_ERR("alloc poll device failed!n");
-		result = -ENOMEM;
-		goto err_hwmon_device_unregister;
-	}
-	mir3da_idev->poll = mir3da_dev_poll;
-	mir3da_idev->poll_interval = POLL_INTERVAL;
-	delayMs = POLL_INTERVAL;
-	mir3da_idev->poll_interval_max = POLL_INTERVAL_MAX;
-	idev = mir3da_idev->input;
-
-	idev->name = MIR3DA_INPUT_DEV_NAME;
-	idev->id.bustype = BUS_I2C;
-	idev->evbit[0] = BIT_MASK(EV_ABS);
-
-	input_set_abs_params(idev, ABS_X, -16384, 16383, INPUT_FUZZ, INPUT_FLAT);
-	input_set_abs_params(idev, ABS_Y, -16384, 16383, INPUT_FUZZ, INPUT_FLAT);
-	input_set_abs_params(idev, ABS_Z, -16384, 16383, INPUT_FUZZ, INPUT_FLAT);
-
-	result = input_register_polled_device(mir3da_idev);
-	if (result) {
-		MI_ERR("register poll device failed!n");
-		goto err_free_polled_device;
-	}
-
-	/*int_handle = gpio_to_irq(gsensor_info.irq_gpio.gpio);
-	ret = request_irq(int_handle, gsensor_irq_func, IRQF_NO_SUSPEND | IRQF_TRIGGER_RISING, "sensor da380", NULL);
-	if (IS_ERR_VALUE(ret)) {
-		printk("[haibo] mir gsensor request irq failed!n");
-		goto err_unregister_polled_device;
-	}*/
-
-	/* Sys Attribute Register */
-	result = sysfs_create_group(&idev->dev.kobj, &mir3da_attr_group);
-	if (result) {
-		MI_ERR("create device file failed!n");
-		result = -EINVAL;
-		goto err_unregister_polled_device;
-	}
-
-	/* Misc device interface Register */
-	result = misc_register(&misc_mir3da);
-	if (result) {
-		MI_ERR("%s: mir3da_dev register failed", __func__);
-		goto err_remove_sysfs_group;
-	}
-	slope_th = 0x83;
-#ifdef CONFIG_HAS_EARLYSUSPEND
-	early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
-	early_suspend.suspend = mir3da_early_suspend;
-	early_suspend.resume = mir3da_late_resume;
-	register_early_suspend(&early_suspend);
-#endif
-	return result;
-
-err_remove_sysfs_group:
-	sysfs_remove_group(&idev->dev.kobj, &mir3da_attr_group);
-err_unregister_polled_device:
-	/*free_irq(gsensor_info.irq_gpio.gpio, NULL);*/
-	input_unregister_polled_device(mir3da_idev);
-err_free_polled_device:
-	input_free_polled_device(mir3da_idev);
-err_hwmon_device_unregister:
-	hwmon_device_unregister(&client->dev);
-err_detach_client:
-	return result;
-}
-
-/*----------------------------------------------------------------------------*/
-static int mir3da_remove(struct i2c_client *client)
-{
-	MIR_HANDLE handle = mir_handle;
-
-	mir3da_set_enable(handle, 0);
-
-	misc_deregister(&misc_mir3da);
-
-	sysfs_remove_group(&mir3da_idev->input->dev.kobj, &mir3da_attr_group);
-
-	input_unregister_polled_device(mir3da_idev);
-
-	input_free_polled_device(mir3da_idev);
-
-#ifdef  MIR3DA_OFFSET_TEMP_SOLUTION
-	flush_workqueue(m_work_info.wq);
-	destroy_workqueue(m_work_info.wq);
-#endif
-
-	hwmon_device_unregister(hwmon_dev);
-
-	return 0;
-}
-
-static int mir3da_detect(struct i2c_client *new_client, struct i2c_board_info *info)
-{
-	struct i2c_adapter *adapter = new_client->adapter;
-
-	MI_MSG("%s:bus[%d] addr[0x%x]n", __func__, adapter->nr, new_client->addr);
-
-	printk(" richard mir3da_detect: %s:bus[%d] addr[0x%x]n", __func__, adapter->nr, new_client->addr);
-
-	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
-		return -ENODEV;
-
-	if (twi_id == adapter->nr) {
-		if (mir3da_install_general_ops(&ops_handle)) {
-			MI_ERR("Install ops failed !n");
-			return -ENODEV;
-		}
-		if (mir3da_module_detect((PLAT_HANDLE) new_client)) {
-			MI_ERR("Can't find Mir3da gsensor!!");
-		} else {
-			MI_ERR("'Find Mir3da gsensor!!");
-			strlcpy(info->type, MIR3DA_DRV_NAME, I2C_NAME_SIZE);
-			return 0;
-		}
-	}
-
-	return -ENODEV;
-}
-
-static int gsensor_fetch_sysconfig_para(void)
-{
-	if (input_fetch_sysconfig_para(&(gsensor_info.input_type))) {
-		printk("%s: err.n", __func__);
-		return -1;
-	} else
-		twi_id = gsensor_info.twi_id;
-
-	return 0;
-}
-
-static const struct i2c_device_id mir3da_id[] = {
-	{MIR3DA_DRV_NAME, 0},
-	{}
-};
-
-MODULE_DEVICE_TABLE(i2c, mir3da_id);
-static struct i2c_driver mir3da_driver = {
-	.class = I2C_CLASS_HWMON,
-	.driver = {
-		   .name = MIR3DA_DRV_NAME,
-		   .owner = THIS_MODULE,
-		   },
-
-	.probe = mir3da_probe,
-#ifndef CONFIG_HAS_EARLYSUSPEND
-	.suspend = mir3da_suspend,
-	.resume = mir3da_resume,
-#endif
-	.detect = mir3da_detect,
-	.remove = mir3da_remove,
-	.id_table = mir3da_id,
-	.address_list = normal_i2c,
-};
-
-/*----------------------------------------------------------------------------*/
-static int __init mir3da_init(void)
-{
-	int ret;
-
-	MI_FUN;
-
-	if (gsensor_fetch_sysconfig_para()) {
-		MI_ERR("fetch_sysconfig_para failed!n");
-		return -1;
-	}
-	printk("step4 : mir3da_initn");
-
-	if (gsensor_info.sensor_used == 0) {
-		MI_ERR("*** gsensor_used set to 0 !n");
-		return -1;
-	}
-
-	ret = i2c_add_driver(&mir3da_driver);
-	if (ret < 0) {
-		MI_ERR("add mir3da i2c driver failedn");
-		return -ENODEV;
-	}
-
-	return (ret);
-}
-
-/*----------------------------------------------------------------------------*/
-static void __exit mir3da_exit(void)
-{
-	MI_FUN;
-
-	i2c_del_driver(&mir3da_driver);
-}
-
-/*----------------------------------------------------------------------------*/
-MODULE_AUTHOR("MiraMEMS <lschen@miramems.com>");
-MODULE_DESCRIPTION("MIR3DA 3-Axis Accelerometer driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("1.0");
-
-module_init(mir3da_init);
-module_exit(mir3da_exit);
diff --git a/lichee/linux-3.10/drivers/input/sensor/da380/mir3da_cust.h b/lichee/linux-3.10/drivers/input/sensor/da380/mir3da_cust.h
deleted file mode 100755
index 5231a52..0000000
--- a/lichee/linux-3.10/drivers/input/sensor/da380/mir3da_cust.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* For AllWinner android platform.
- *
- * mir3da.h - Linux kernel modules for 3-Axis Accelerometer
- *
- * Copyright (C) 2011-2013 MiraMEMS Sensing Technology Co., Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- * 0x26<-> SD0=GND;0x27<-> SD0=High
- */
-
-#ifndef __MIR3DA_STANDARD_H__
-#define __MIR3DA_STANDARD_H__
-
-#include <linux/ioctl.h>
-
-#define DRI_VER                  		        "1.0"
-
-#define MIR3DA_I2C_ADDR		                    0x27
-
-#define MIR3DA_ACC_IOCTL_BASE                   88
-#define IOCTL_INDEX_BASE                        0x00
-
-#define MIR3DA_ACC_IOCTL_SET_DELAY              _IOW(MIR3DA_ACC_IOCTL_BASE, IOCTL_INDEX_BASE, int)
-#define MIR3DA_ACC_IOCTL_GET_DELAY              _IOR(MIR3DA_ACC_IOCTL_BASE, IOCTL_INDEX_BASE+1, int)
-#define MIR3DA_ACC_IOCTL_SET_ENABLE             _IOW(MIR3DA_ACC_IOCTL_BASE, IOCTL_INDEX_BASE+2, int)
-#define MIR3DA_ACC_IOCTL_GET_ENABLE             _IOR(MIR3DA_ACC_IOCTL_BASE, IOCTL_INDEX_BASE+3, int)
-#define MIR3DA_ACC_IOCTL_SET_G_RANGE            _IOW(MIR3DA_ACC_IOCTL_BASE, IOCTL_INDEX_BASE+4, int)
-#define MIR3DA_ACC_IOCTL_GET_G_RANGE            _IOR(MIR3DA_ACC_IOCTL_BASE, IOCTL_INDEX_BASE+5, int)
-
-#define MIR3DA_ACC_IOCTL_GET_COOR_XYZ           _IOW(MIR3DA_ACC_IOCTL_BASE, IOCTL_INDEX_BASE+22, int)
-#define MIR3DA_ACC_IOCTL_CALIBRATION            _IOW(MIR3DA_ACC_IOCTL_BASE, IOCTL_INDEX_BASE+23, int)
-#define MIR3DA_ACC_IOCTL_UPDATE_OFFSET     	    _IOW(MIR3DA_ACC_IOCTL_BASE, IOCTL_INDEX_BASE+24, int)
-
-#endif /* !__MIR3DA_STANDARD_H__ */
diff --git a/lichee/linux-3.10/drivers/input/sensor/mir3da_core.c b/lichee/linux-3.10/drivers/input/sensor/mir3da_core.c
new file mode 100755
index 0000000..c2c2f84
--- /dev/null
+++ b/lichee/linux-3.10/drivers/input/sensor/mir3da_core.c
@@ -0,0 +1,2156 @@
+/* Core file for MiraMEMS 3-Axis Accelerometer's driver. 
+ *
+ * mir3da_core.c - Linux kernel modules for 3-Axis Accelerometer
+ *
+ * Copyright (C) 2011-2013 MiraMEMS Sensing Technology Co., Ltd.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#include "mir3da_core.h"
+#include "mir3da_cust.h"
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/syscalls.h>
+
+#define MIR3DA_REG_PAGE(REG)                (((REG)>>8)&0xFF)
+#define MIR3DA_REG_ADDR(REG)                ((REG)&0xFF)
+
+#define MIR3DA_OFFSET_THRESHOLD             10
+#define PEAK_LVL                            800
+#define STICK_LSB                           2000
+#define AIX_HISTORY_SIZE                    3
+
+typedef struct reg_obj_s {
+
+	short addr;
+	unsigned char mask;
+	unsigned char value;
+
+} reg_obj_t;
+
+struct gsensor_data_fmt_s {
+
+	unsigned char msbw;
+	unsigned char lsbw;
+	unsigned char endian;	/* 0: little endian; 1: big endian */
+};
+
+struct gsensor_data_obj_s {
+
+#define MIR3DA_DATA_LEN         6
+	reg_obj_t data_sect[MIR3DA_DATA_LEN];
+	struct gsensor_data_fmt_s data_fmt;
+};
+
+struct gsensor_obj_s {
+
+	char asic[10];
+
+	reg_obj_t chip_id;
+	reg_obj_t mod_id;
+	reg_obj_t soft_reset;
+	reg_obj_t power;
+
+#define MIR3DA_INIT_SECT_LEN    11
+#define MIR3DA_OFF_SECT_LEN     MIR3DA_OFFSET_LEN
+#define MIR3DA_ODR_SECT_LEN   	3
+
+	reg_obj_t init_sect[MIR3DA_INIT_SECT_LEN];
+	reg_obj_t offset_sect[MIR3DA_OFF_SECT_LEN];
+	reg_obj_t odr_sect[MIR3DA_ODR_SECT_LEN];
+
+	struct gsensor_data_obj_s data;
+
+	int (*calibrate) (MIR_HANDLE handle, int z_dir);
+	int (*auto_calibrate) (MIR_HANDLE handle, int xyz[3]);
+	int (*int_ops) (MIR_HANDLE handle, mir_int_ops_t *ops);
+	int (*get_reg_data) (MIR_HANDLE handle, char *buf);
+};
+
+struct gsensor_drv_s {
+
+	struct general_op_s *method;
+
+	struct gsensor_obj_s *obj;
+};
+
+#define MIR3DA_SOCLE_INIT_SECTION                       { SOCLE_REG_TEMP_CFG_REG,       0xFF,   0x08    },                                  
+                                                        { SOCLE_REG_CTRL_REG5,          0xFF,   0x80    },                                  
+                                                        { SOCLE_REG_CTRL_REG4,          0x30,   0x00    },                                  
+                                                        { SOCLE_REG_CTRL_REG1,          0xFF,   0x6F    },                                  
+                                                        { SOCLE_REG_TEMP_CFG_REG,       0xFF,   0x88    },                                  
+                                                        { SOCLE_REG_LDO_REG,            0xFF,   0x02    },                                  
+                                                        { SOCLE_REG_OTP_TRIM_OSC,       0xFF,   0x27    },                                  
+                                                        { SOCLE_REG_LPF_ABSOLUTE,       0xFF,   0x30    },                                  
+                                                        { SOCLE_REG_TEMP_OFF1,          0xFF,   0x3f    },                                  
+                                                        { SOCLE_REG_TEMP_OFF2,          0xFF,   0xff    },                                  
+                                                        { SOCLE_REG_TEMP_OFF3,          0xFF,   0x0f    },                                  
+
+
+#define MIR3DA_SOCLE_OFFSET_SECTION                     { SOCLE_REG_OTP_XOFF_L,         0xFF,   0x00    },                                  
+                                                        { SOCLE_REG_OTP_XOFF_H,         0xFF,   0x00    },                                  
+                                                        { SOCLE_REG_OTP_YOFF_L,         0xFF,   0x00    },                                  
+                                                        { SOCLE_REG_OTP_YOFF_H,         0xFF,   0x00    },                                  
+                                                        { SOCLE_REG_OTP_ZOFF_L,         0xFF,   0x00    },                                  
+                                                        { SOCLE_REG_OTP_ZOFF_H,         0xFF,   0x00    },                                  
+                                                        { -1,                           0x00,   0x00    },                                  
+                                                        { -1,                           0x00,   0x00    },                                  
+                                                        { -1,                           0x00,   0x00    },                                  
+
+#define MIR3DA_SOCLE_ODR_SECTION                        { SOCLE_REG_CTRL_REG1,          0xF0,   0x40    },                                  
+                                                        { SOCLE_REG_CTRL_REG1,          0xF0,   0x50    },                                  
+                                                        { SOCLE_REG_CTRL_REG1,          0xF0,   0x60    },                                  
+
+
+#define MIR3DA_SOCLE_DATA_SECTION                     { { (SOCLE_REG_OUT_X_L|0x80),     0xFF,   0x00    },                                  
+                                                        { (SOCLE_REG_OUT_X_H|0x80),     0xFF,   0x00    },                                  
+                                                        { (SOCLE_REG_OUT_Y_L|0x80),     0xFF,   0x00    },                                  
+                                                        { (SOCLE_REG_OUT_Y_H|0x80),     0xFF,   0x00    },                                  
+                                                        { (SOCLE_REG_OUT_Z_L|0x80),     0xFF,   0x00    },                                  
+                                                        { (SOCLE_REG_OUT_Z_H|0x80),     0xFF,   0x00    } },                                
+                                                        { 8,                            4,      0       }
+
+#define MIR3DA_NSA_INIT_SECTION                         { NSA_REG_G_RANGE,              0x03,   0x02    },                                  
+                                                        { NSA_REG_POWERMODE_BW,         0xFF,   0x1e    },                                  
+                                                        { NSA_REG_ODR_AXIS_DISABLE,     0xFF,   0x07    },                                  
+                                                        { NSA_REG_INTERRUPT_SETTINGS2,  0xFF,   0x00    },                                  
+                                                        { NSA_REG_INTERRUPT_MAPPING2,   0xFF,   0x00    },                                  
+                                                        { NSA_REG_ENGINEERING_MODE,     0xFF,   0x83    },                                  
+                                                        { NSA_REG_ENGINEERING_MODE,     0xFF,   0x69    },                                  
+                                                        { NSA_REG_ENGINEERING_MODE,     0xFF,   0xBD    },                                  
+                                                        { NSA_REG_INT_PIN_CONFIG,       0x0F,   NRIPCV  },                                  
+                                                        { -1,                           0x00,   0x00    },                                  
+                                                        { -1,                           0x00,   0x00    },                                  
+
+
+#define MIR3DA_NSA_OFFSET_SECTION                       { NSA_REG_COARSE_OFFSET_TRIM_X, 0xFF,   0x00    },                                  
+                                                        { NSA_REG_COARSE_OFFSET_TRIM_Y, 0xFF,   0x00    },                                  
+                                                        { NSA_REG_COARSE_OFFSET_TRIM_Z, 0xFF,   0x00    },                                  
+                                                        { NSA_REG_FINE_OFFSET_TRIM_X,   0xFF,   0x00    },                                  
+                                                        { NSA_REG_FINE_OFFSET_TRIM_Y,   0xFF,   0x00    },                                  
+                                                        { NSA_REG_FINE_OFFSET_TRIM_Z,   0xFF,   0x00    },                                  
+                                                        { NSA_REG_CUSTOM_OFFSET_X,      0xFF,   0x00    },                                  
+                                                        { NSA_REG_CUSTOM_OFFSET_Y,      0xFF,   0x00    },                                  
+                                                        { NSA_REG_CUSTOM_OFFSET_Z,      0xFF,   0x00    },                                  
+
+#define MIR3DA_NSA_ODR_SECTION                          { NSA_REG_ODR_AXIS_DISABLE,     0x0F,   0x06    },                                  
+                                                        { NSA_REG_ODR_AXIS_DISABLE,     0x0F,   0x07    },                                  
+                                                        { NSA_REG_ODR_AXIS_DISABLE,     0x0F,   0x08    },                                  
+
+
+#define MIR3DA_NSA_DATA_SECTION                       { { NSA_REG_ACC_X_LSB,            0xFF,   0x00    },                                  
+                                                        { NSA_REG_ACC_X_MSB,            0xFF,   0x00    },                                  
+                                                        { NSA_REG_ACC_Y_LSB,            0xFF,   0x00    },                                  
+                                                        { NSA_REG_ACC_Y_MSB,            0xFF,   0x00    },                                  
+                                                        { NSA_REG_ACC_Z_LSB,            0xFF,   0x00    },                                  
+                                                        { NSA_REG_ACC_Z_MSB,            0xFF,   0x00    } },                                
+                                                        { 8,                            4,      0       }
+
+static int SOCLE_calibrate(MIR_HANDLE handle, int z_dir);
+static int SOCLE_auto_calibrate(MIR_HANDLE handle, int xyz[3]);
+static int NSA_MLM_calibrate(MIR_HANDLE handle, int z_dir);
+static int NSA_NTO_calibrate(MIR_HANDLE handle, int z_dir);
+static int NSA_MLM_auto_calibrate(MIR_HANDLE handle, int xyz[3]);
+static int NSA_NTO_auto_calibrate(MIR_HANDLE handle, int xyz[3]);
+#ifdef MIR3DA_AUTO_CALIBRATE
+static int mir3da_auto_calibrate(MIR_HANDLE handle, int x, int y, int z);
+#endif /* !MIR3DA_AUTO_CALIBRATE */
+static int SOCLE_interrupt_ops(MIR_HANDLE handle, mir_int_ops_t *ops);
+static int NSA_interrupt_ops(MIR_HANDLE handle, mir_int_ops_t *ops);
+static int SOCLE_get_reg_data(MIR_HANDLE handle, char *buf);
+static int NSA_get_reg_data(MIR_HANDLE handle, char *buf);
+
+#define MIR_SOCLE                       { "SOCLE",      { SOCLE_REG_WHO_AM_I,           0xFF,   0x13    },                                  
+                                                        { SOCLE_REG_WHO_AM_I,           0xFF,   0x13    },                                  
+                                                        { SOCLE_REG_SOFT_RESET,         0xFF,   0xAA    },                                  
+                                                        { SOCLE_REG_TEMP_CFG_REG,       0x20,   0x20    },                                  
+                                                        { MIR3DA_SOCLE_INIT_SECTION                     },                                  
+                                                        { MIR3DA_SOCLE_OFFSET_SECTION                   },                                  
+                                                        { MIR3DA_SOCLE_ODR_SECTION                      },                                  
+                                                        { MIR3DA_SOCLE_DATA_SECTION                     },                                  
+                                                          SOCLE_calibrate                                ,                                  
+                                                          SOCLE_auto_calibrate                           ,                                  
+                                                          SOCLE_interrupt_ops                            ,                                  
+                                                          SOCLE_get_reg_data                             ,                                  
+                                        }
+
+#define MIR_NSA_NTO                     { "NSA_NTO",    { NSA_REG_WHO_AM_I,             0xFF,   0x13    },                                  
+                                                        { NSA_REG_FIFO_CTRL,            0xFF,   0x00    },                                  
+                                                        { NSA_REG_SPI_I2C,              0x24,   0x24    },                                  
+                                                        { NSA_REG_POWERMODE_BW,         0xC0,   0xC0    },                                  
+                                                        { MIR3DA_NSA_INIT_SECTION                       },                                  
+                                                        { MIR3DA_NSA_OFFSET_SECTION                     },                                  
+                                                        { MIR3DA_NSA_ODR_SECTION                   	    },                                  
+                                                        { MIR3DA_NSA_DATA_SECTION                       },                                  
+                                                          NSA_NTO_calibrate                              ,                                  
+                                                          NSA_NTO_auto_calibrate                         ,                                  
+                                                          NSA_interrupt_ops                              ,                                  
+                                                          NSA_get_reg_data                               ,                                  
+                                        }
+
+#define MIR_NSA_MLM                     { "NSA_MLM",    { NSA_REG_WHO_AM_I,             0xFF,   0x13    },                                  
+                                                        { NSA_REG_FIFO_CTRL,            0xFF,   0x10    },                                  
+                                                        { NSA_REG_SPI_I2C,              0x24,   0x24    },                                  
+                                                        { NSA_REG_POWERMODE_BW,         0xC0,   0xC0    },                                  
+                                                        { MIR3DA_NSA_INIT_SECTION                       },                                  
+                                                        { MIR3DA_NSA_OFFSET_SECTION                     },                                  
+                                                        { MIR3DA_NSA_ODR_SECTION                        },                                  
+                                                        { MIR3DA_NSA_DATA_SECTION                       },                                  
+                                                          NSA_MLM_calibrate                              ,                                  
+                                                          NSA_MLM_auto_calibrate                         ,                                  
+                                                          NSA_interrupt_ops                              ,                                  
+                                                          NSA_get_reg_data                               ,                                  
+                                        }
+
+/**************************************************************** COMMON ***************************************************************************/
+#define MIR3DA_GSENSOR_SCHEME           MIR3DA_SUPPORT_CHIP_LIST
+
+/* this level can be modified while runtime through system attribute */
+int Log_level = DEBUG_ERR; /* | DEBUG_ASSERT | DEBUG_MSG | DEBUG_FUNC | DEBUG_DATA;*/
+int gsensor_mod = -1;		/* Initial value */
+static struct gsensor_obj_s mir3da_gsensor[] = { MIR3DA_GSENSOR_SCHEME };
+
+struct gsensor_drv_s mir3da_gsensor_drv;
+///$shh$20180925$
+#define MI_DATA(format, ...)            if(DEBUG_DATA&Log_level){mir3da_gsensor_drv.method->myprintf(MI_TAG format "n", ## __VA_ARGS__);}
+#define MI_MSG(format, ...)             if(DEBUG_MSG&Log_level){mir3da_gsensor_drv.method->myprintf(MI_TAG format "n", ## __VA_ARGS__);}
+#define MI_ERR(format, ...)             if(DEBUG_ERR&Log_level){mir3da_gsensor_drv.method->myprintf(MI_TAG format "n", ## __VA_ARGS__);}
+#define MI_FUN                          if(DEBUG_FUNC&Log_level){mir3da_gsensor_drv.method->myprintf(MI_TAG "%s is called, line: %dn", __FUNCTION__,__LINE__);}
+#define MI_ASSERT(expr)                 
+	if (!(expr)) {
+		mir3da_gsensor_drv.method->myprintf("Assertion failed! %s,%d,%s,%sn",
+			__FILE__, __LINE__, __func__, #expr);
+	}
+
+//#define abs(x) ({ long __x = (x); (__x < 0) ? -__x : __x; })
+
+#ifdef FILTER_AVERAGE_ENHANCE
+typedef struct FilterAverageContextTag {
+	int sample_l;
+	int sample_h;
+	int filter_param_l;
+	int filter_param_h;
+	int filter_threhold;
+
+	int refN_l;
+	int refN_h;
+
+} FilterAverageContext;
+
+typedef struct mir3da_core_ctx_s {
+	struct mir3da_filter_param_s filter_param;
+	FilterAverageContext tFac[3];
+} mir3da_core_ctx;
+
+static mir3da_core_ctx core_ctx;
+#endif
+
+#ifdef MIR3DA_SENS_TEMP_SOLUTION
+static int bSensZoom = 0;
+#endif
+
+#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
+static int is_cali = 0;
+char bLoad = 0;
+static char readOffsetCnt = -1;
+static unsigned char original_offset[9];
+static int mir3da_write_offset_to_file(unsigned char *offset);
+static int mir3da_read_offset_from_file(unsigned char *offset);
+void manual_load_cali_file(MIR_HANDLE handle);
+#endif /* !MIR3DA_OFFSET_TEMP_SOLUTION */
+
+#if MIR3DA_STK_TEMP_SOLUTION
+static short aixHistort[AIX_HISTORY_SIZE * 3] = { 0 };
+
+static short aixHistoryIndex = 0;
+char bxstk = 0;
+char bystk = 0;
+char bzstk = 0;
+
+static void addAixHistory(short x, short y, short z)
+{
+	aixHistort[aixHistoryIndex++] = x;
+	aixHistort[aixHistoryIndex++] = y;
+	aixHistort[aixHistoryIndex++] = z;
+	aixHistoryIndex = (aixHistoryIndex) % (AIX_HISTORY_SIZE * 3);
+}
+
+static char isXStick(void)
+{
+	int i;
+	for (i = 0; i < AIX_HISTORY_SIZE; i++) {
+		if ((abs(aixHistort[i * 3]) < STICK_LSB) && (aixHistort[i * 3] != 0)) {
+			break;
+		}
+	}
+
+	if ((aixHistort[0] + aixHistort[3] + aixHistort[6]) == 0)
+		return 1;
+
+	return i == AIX_HISTORY_SIZE;
+}
+
+static char isYStick(void)
+{
+	int i;
+	for (i = 0; i < AIX_HISTORY_SIZE; i++) {
+		if ((abs(aixHistort[i * 3 + 1]) < STICK_LSB) && (aixHistort[i * 3 + 1] != 0)) {
+			break;
+		}
+	}
+
+	if ((aixHistort[1] + aixHistort[4] + aixHistort[7]) == 0)
+		return 1;
+
+	return i == AIX_HISTORY_SIZE;
+}
+
+static char isZStick(void)
+{
+	int i;
+	for (i = 0; i < AIX_HISTORY_SIZE; i++) {
+		if ((abs(aixHistort[i * 3 + 2]) < STICK_LSB) && (aixHistort[i * 3 + 2] != 0)) {
+			break;
+		}
+	}
+
+	if ((aixHistort[2] + aixHistort[5] + aixHistort[8]) == 0)
+		return 1;
+
+	return i == AIX_HISTORY_SIZE;
+}
+
+int squareRoot(int val)
+{
+	int r = 0;
+	int shift;
+
+	if (val < 0) {
+		return 0;
+	}
+
+	for (shift = 0; shift < 32; shift += 2) {
+		int x = 0x40000000l >> shift;
+		if (x + r <= val) {
+			val -= x + r;
+			r = (r >> 1) | x;
+		} else {
+			r = r >> 1;
+		}
+	}
+
+	return r;
+}
+#endif /* ! MIR3DA_STK_TEMP_SOLUTION */
+
+#if FILTER_AVERAGE_ENHANCE
+static short filter_average(short preAve, short sample, int paramN, int *refNum)
+{
+#if FILTER_AVERAGE_EX
+	if (abs(sample - preAve) > PEAK_LVL && *refNum < 3) {
+		MI_DATA("Hit, sample = %d, preAve = %d, refN =%dn", sample, preAve, *refNum);
+		sample = preAve;
+		(*refNum)++;
+	} else {
+		if (*refNum == 3) {
+			preAve = sample;
+		}
+
+		*refNum = 0;
+	}
+#endif
+
+	return preAve + (sample - preAve) / paramN;
+}
+
+static int filter_average_enhance(FilterAverageContext * fac, short sample)
+{
+	if (fac == 0) {
+		MI_ERR("0 parameter fac");
+		return 0;
+	}
+
+	if (fac->filter_param_l == fac->filter_param_h) {
+		fac->sample_l = fac->sample_h = filter_average(fac->sample_l, sample, fac->filter_param_l, &fac->refN_l);
+	} else {
+		fac->sample_l = filter_average(fac->sample_l, sample, fac->filter_param_l, &fac->refN_l);
+		fac->sample_h = filter_average(fac->sample_h, sample, fac->filter_param_h, &fac->refN_h);
+		if (abs(fac->sample_l - fac->sample_h) > fac->filter_threhold) {
+			MI_DATA("adjust, fac->sample_l = %d, fac->sample_h = %dn", fac->sample_l, fac->sample_h);
+			fac->sample_h = fac->sample_l;
+		}
+	}
+
+	return fac->sample_h;
+}
+#endif /* ! FILTER_AVERAGE_ENHANCE */
+
+int mir3da_register_read(MIR_HANDLE handle, short addr, unsigned char *data)
+{
+	unsigned char cur_page;
+	int res = 0;
+
+	/* check page */
+	if (MIR3DA_REG_PAGE(addr) > 0) {
+		res = mir3da_gsensor_drv.method->smi.read(handle, 0x0, &cur_page);
+		if (res != 0) {
+			return res;
+		}
+
+		if (cur_page != MIR3DA_REG_PAGE(addr)) {
+			res |= mir3da_gsensor_drv.method->smi.write(handle, 0x0, MIR3DA_REG_PAGE(addr));
+			if (res != 0) {
+				return res;
+			}
+		}
+	}
+
+	res = mir3da_gsensor_drv.method->smi.read(handle, MIR3DA_REG_ADDR(addr), data);
+
+	if (MIR3DA_REG_PAGE(addr) > 0) {
+		/* restore page NO. */
+		res |= mir3da_gsensor_drv.method->smi.write(handle, 0x0, cur_page);
+	}
+
+	return res;
+}
+
+int mir3da_register_read_continuously(MIR_HANDLE handle, short addr, unsigned char count, unsigned char *data)
+{
+	unsigned char cur_page;
+	int res = 0;
+
+	/* check page */
+	if (MIR3DA_REG_PAGE(addr) > 0) {
+		res = mir3da_gsensor_drv.method->smi.read(handle, 0x0, &cur_page);
+		if (res != 0) {
+			return res;
+		}
+
+		if (cur_page != MIR3DA_REG_PAGE(addr)) {
+			res |= mir3da_gsensor_drv.method->smi.write(handle, 0x0, MIR3DA_REG_PAGE(addr));
+			if (res != 0) {
+				return res;
+			}
+		}
+	}
+
+	res = (count == mir3da_gsensor_drv.method->smi.read_block(handle, MIR3DA_REG_ADDR(addr), count, data)) ? 0 : 1;
+
+	if (MIR3DA_REG_PAGE(addr) > 0) {
+		/* restore page NO. */
+		res |= mir3da_gsensor_drv.method->smi.write(handle, 0x0, cur_page);
+	}
+
+	return res;
+}
+
+int mir3da_register_write(MIR_HANDLE handle, short addr, unsigned char data)
+{
+	unsigned char cur_page;
+	int res = 0;
+
+	/* check page */
+	if (MIR3DA_REG_PAGE(addr) > 0) {
+		res = mir3da_gsensor_drv.method->smi.read(handle, 0x0, &cur_page);
+		if (res != 0) {
+			return res;
+		}
+
+		if (cur_page != MIR3DA_REG_PAGE(addr)) {
+			res |= mir3da_gsensor_drv.method->smi.write(handle, 0x0, MIR3DA_REG_PAGE(addr));
+			if (res != 0) {
+				return res;
+			}
+		}
+	}
+
+	res = mir3da_gsensor_drv.method->smi.write(handle, MIR3DA_REG_ADDR(addr), data);
+
+	if (MIR3DA_REG_PAGE(addr) > 0) {
+		/* restore page NO. */
+		res |= mir3da_gsensor_drv.method->smi.write(handle, 0x0, cur_page);
+	}
+
+	return res;
+}
+
+int mir3da_register_mask_write(MIR_HANDLE handle, short addr, unsigned char mask, unsigned char data)
+{
+	int res = 0;
+	unsigned char tmp_data;
+
+	res = mir3da_register_read(handle, addr, &tmp_data);
+	if (res) {
+		return res;
+	}
+
+	tmp_data &= ~mask;
+	tmp_data |= data & mask;
+	res = mir3da_register_write(handle, addr, tmp_data);
+
+	return res;
+}
+
+static int mir3da_read_raw_data(MIR_HANDLE handle, short *x, short *y, short *z)
+{
+	unsigned char tmp_data[6] = { 0 };
+
+	if (mir3da_register_read_continuously(handle, mir3da_gsensor_drv.obj[gsensor_mod].data.data_sect[0].addr, 6, tmp_data) != 0) {
+		MI_ERR("i2c block read failedn");
+		return -1;
+	}
+
+	*x = ((short)(tmp_data[1] << mir3da_gsensor_drv.obj[gsensor_mod].data.data_fmt.msbw | tmp_data[0])) >> (8 - mir3da_gsensor_drv.obj[gsensor_mod].data.data_fmt.lsbw);
+	*y = ((short)(tmp_data[3] << mir3da_gsensor_drv.obj[gsensor_mod].data.data_fmt.msbw | tmp_data[2])) >> (8 - mir3da_gsensor_drv.obj[gsensor_mod].data.data_fmt.lsbw);
+	*z = ((short)(tmp_data[5] << mir3da_gsensor_drv.obj[gsensor_mod].data.data_fmt.msbw | tmp_data[4])) >> (8 - mir3da_gsensor_drv.obj[gsensor_mod].data.data_fmt.lsbw);
+	//printk("%d,%dn",mir3da_gsensor_drv.obj[gsensor_mod].data.data_fmt.msbw,mir3da_gsensor_drv.obj[gsensor_mod].data.data_fmt.lsbw);
+	MI_DATA("mir3da_raw: x=%d, y=%d, z=%d", *x, *y, *z);
+
+#if MIR3DA_SENS_TEMP_SOLUTION
+	if (bSensZoom == 1) {
+		*z = (*z) * 5 / 4;
+		MI_DATA("SensZoom take effect, Zoomed Z = %d", *z);
+	}
+#endif
+	return 0;
+}
+
+static int remap[8][4] = { {0, 0, 0, 0},
+{0, 1, 0, 1},
+{1, 1, 0, 0},
+{1, 0, 0, 1},
+{1, 0, 1, 0},
+{0, 0, 1, 1},
+{0, 1, 1, 0},
+{1, 1, 1, 1}
+};
+
+int mir3da_direction_remap(short *x, short *y, short *z, int direction)
+{
+	short temp = 0;
+
+	*x = *x - ((*x) * remap[direction][0] * 2);
+	*y = *y - ((*y) * remap[direction][1] * 2);
+	*z = *z - ((*z) * remap[direction][2] * 2);
+
+	if (remap[direction][3]) {
+		temp = *x;
+		*x = *y;
+		*y = temp;
+	}
+
+	if (remap[direction][2])
+		return -1;
+
+	return 1;
+}
+
+int mir3da_read_data(MIR_HANDLE handle, short *x, short *y, short *z)
+{
+	int rst = 0;
+#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
+	static int load_cnt = 0;
+
+	if (is_cali) {
+		*x = *y = *z = 0;
+		return 0;
+	}
+
+	if (load_cnt > 200) {
+		manual_load_cali_file(handle);
+	} else {
+		load_cnt++;
+	}
+#endif
+
+	rst = mir3da_read_raw_data(handle, x, y, z);
+	if (rst != 0) {
+		MI_ERR("mir3da_read_raw_data failed, rst = %d", rst);
+		return rst;
+	}
+#ifdef MIR3DA_AUTO_CALIBRATE
+	if ((!bLoad) && (load_cnt > 200)) {
+		if (GSENSOR_MOD_SOCLE != gsensor_mod) {
+			mir3da_auto_calibrate(handle, *x, *y, *z);
+		}
+	}
+#endif
+
+#if MIR3DA_STK_TEMP_SOLUTION
+	addAixHistory(*x, *y, *z);
+
+	bxstk = isXStick();
+	bystk = isYStick();
+	bzstk = isZStick();
+
+	if ((bxstk + bystk + bzstk) < 2) {
+		if (bxstk)
+			/* *x = squareRoot(256*256 - (*y)*(*y) - (*z)*(*z)); */
+			if (bystk)
+				/* *y = squareRoot(256*256 - (*x)*(*x) - (*z)*(*z));*/
+				if (bzstk)
+					*z = squareRoot(256 * 256 - (*x) * (*x) - (*y) * (*y));
+	} else {
+		/* MI_ERR( "CHIP ERR !MORE STK!n"); */
+		return 0;
+	}
+#endif
+
+#if FILTER_AVERAGE_ENHANCE
+	if (GSENSOR_MOD_SOCLE == gsensor_mod) {
+		*x = filter_average_enhance(&core_ctx.tFac[0], *x);
+		*y = filter_average_enhance(&core_ctx.tFac[1], *y);
+		*z = filter_average_enhance(&core_ctx.tFac[2], *z);
+
+		MI_DATA("mir3da_filt: x=%d, y=%d, z=%d", *x, *y, *z);
+	}
+#endif
+	/* printk("mir3da_filt: x=%d, y=%d, z=%d",  *x, *y, *z);*/
+	return 0;
+}
+
+int cycle_read_xyz(MIR_HANDLE handle, int *x, int *y, int *z, int ncycle)
+{
+	unsigned int j = 0;
+	short raw_x, raw_y, raw_z;
+
+	*x = *y = *z = 0;
+
+	for (j = 0; j < ncycle; j++) {
+		raw_x = raw_y = raw_z = 0;
+		mir3da_read_raw_data(handle, &raw_x, &raw_y, &raw_z);
+
+		(*x) += raw_x;
+		(*y) += raw_y;
+		(*z) += raw_z;
+
+		mir3da_gsensor_drv.method->msdelay(5);
+	}
+
+	(*x) /= ncycle;
+	(*y) /= ncycle;
+	(*z) /= ncycle;
+
+	return 0;
+}
+
+#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
+int mir3da_read_offset(MIR_HANDLE handle, unsigned char *offset)
+{
+	int i, res = 0;
+
+	for (i = 0; i < MIR3DA_OFF_SECT_LEN; i++) {
+		if (mir3da_gsensor_drv.obj[gsensor_mod].offset_sect[i].addr < 0) {
+			break;
+		}
+
+		res = mir3da_register_read(handle, mir3da_gsensor_drv.obj[gsensor_mod].offset_sect[i].addr, &offset[i]);
+		if (res != 0) {
+			return res;
+		}
+	}
+
+	return res;
+}
+
+int mir3da_write_offset(MIR_HANDLE handle, unsigned char *offset)
+{
+	int i, res = 0;
+
+	for (i = 0; i < MIR3DA_OFF_SECT_LEN; i++) {
+		if (mir3da_gsensor_drv.obj[gsensor_mod].offset_sect[i].addr < 0) {
+			break;
+		}
+
+		res = mir3da_register_write(handle, mir3da_gsensor_drv.obj[gsensor_mod].offset_sect[i].addr, offset[i]);
+		if (res != 0) {
+			return res;
+		}
+	}
+
+	return res;
+}
+
+static int mir3da_write_offset_to_file(unsigned char *offset)
+{
+	int ret = 0;
+
+	ret = mir3da_gsensor_drv.method->data_save(offset);
+
+	MI_MSG("====sensor_sync_write, offset = 0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x", offset[0], offset[1], offset[2], offset[3], offset[4], offset[5], offset[6], offset[7], offset[8]);
+
+	return ret;
+}
+
+static int mir3da_read_offset_from_file(unsigned char *offset)
+{
+	int ret = 0;
+
+	ret = mir3da_gsensor_drv.method->data_get(offset);
+
+	MI_MSG("====sensor_sync_read, offset = 0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x,0x%x", offset[0], offset[1], offset[2], offset[3], offset[4], offset[5], offset[6], offset[7], offset[8]);
+
+	return ret;
+}
+
+void manual_load_cali_file(MIR_HANDLE handle)
+{
+	unsigned char offset[MIR3DA_OFFSET_LEN] = { 0 };
+
+	if (!bLoad) {
+		readOffsetCnt++;
+		if (readOffsetCnt % 100 == 0) {
+			if (readOffsetCnt > 0)
+				readOffsetCnt = 0;
+
+			MI_DATA("====444 manual_load_cali_file(), bLoad = %d, readOffsetCnt=%d.n", bLoad, readOffsetCnt);
+			if (!mir3da_read_offset_from_file(offset)) {
+				MI_MSG("========= WRITE OFFSET");
+				mir3da_write_offset(handle, offset);
+				bLoad = 1;
+			}
+		}
+	}
+}
+
+typedef struct linearitydata {
+	unsigned short off;
+	int val;
+
+} LinearityData;
+
+int check_linearity_offset(MIR_HANDLE handle, int *step)
+{
+
+	int i, result = 0;
+	int x, y, z;
+
+#if 1
+	unsigned char xdata_count = 0;
+	unsigned char ydata_count = 0;
+	unsigned char zdata_count = 0;
+	LinearityData xdata[2] = { {0} };
+	LinearityData ydata[2] = { {0} };
+	LinearityData zdata[2] = { {0} };
+
+	for (i = 10; i <= 0x3ff; i += 50) {
+		result |= mir3da_register_write(handle, SOCLE_REG_OTP_XOFF_L, i & 0xFF);
+		result |= mir3da_register_write(handle, SOCLE_REG_OTP_XOFF_H, (i & 0xFF00) >> 8);
+		result |= mir3da_register_write(handle, SOCLE_REG_OTP_YOFF_L, i & 0xFF);
+		result |= mir3da_register_write(handle, SOCLE_REG_OTP_YOFF_H, (i & 0xFF00) >> 8);
+		result |= mir3da_register_write(handle, SOCLE_REG_OTP_ZOFF_L, i & 0xFF);
+		result |= mir3da_register_write(handle, SOCLE_REG_OTP_ZOFF_H, (i & 0xFF00) >> 8);
+		result |= cycle_read_xyz(handle, &x, &y, &z, 20);
+
+		MI_MSG("detect_linearity_ratio: i = %d, x = %d, y = %d, z= %d n", i, x, y, z);
+
+		if (result) {
+			MI_MSG("detect_linearity_ratio: chip op failed, result = %d n", result);
+			return result;
+		}
+
+		if (abs(x) < 1800 && xdata_count < 2) {
+			MI_MSG("detect linearity ratio: xdata_count = %d, x = %d i = %dn", xdata_count, x, i);
+
+			xdata[xdata_count].val = x;
+			xdata[xdata_count].off = i;
+			xdata_count++;
+		}
+
+		if (abs(y) < 1800 && ydata_count < 2) {
+			MI_MSG("detect linearity ratio: ydata_count = %d, y = %d i = %dn", ydata_count, y, i);
+			ydata[ydata_count].val = y;
+			ydata[ydata_count].off = i;
+			ydata_count++;
+		}
+
+		if (abs(z) < 1800 && zdata_count < 2) {
+			MI_MSG("detect linearity ratio: zdata_count = %d, z = %d i = %dn", zdata_count, z, i);
+			zdata[zdata_count].val = z;
+			zdata[zdata_count].off = i;
+			zdata_count++;
+		}
+
+		if (xdata_count == 2 && ydata_count == 2 && zdata_count == 2) {
+			MI_MSG("all linearity_ratio found!");
+			step[0] = (xdata[1].val - xdata[0].val) / (xdata[1].off - xdata[0].off);
+			step[1] = (ydata[1].val - ydata[0].val) / (ydata[1].off - ydata[0].off);
+			step[2] = (zdata[1].val - zdata[0].val) / (zdata[1].off - zdata[0].off);
+
+			MI_MSG("CUSTOM offset step: x = %d, y = %d, z= %d", step[0], step[1], step[2]);
+
+			break;
+		}
+	}
+
+	if (abs(step[0]) < 10 || abs(step[1]) < 10 || abs(step[2]) < 10) {
+		MI_MSG("detect linearity ratio failed!");
+		return -1;
+	}
+#endif
+	return result;
+}
+
+static void mir3da_cali_off_to_lsb(int off, int *coarse, int coarse_step, int *fine, int fine_step)
+{
+	*coarse = off / coarse_step;
+	*fine = 100 * (off - (*coarse) * coarse_step) / fine_step;
+
+	MI_MSG("off = %d; delta_coarse = %d; delta_fine = %d", off, *coarse, *fine);
+}
+
+#ifdef MIR3DA_AUTO_CALIBRATE
+static int NSA_once_calibrate(MIR_HANDLE handle, int coarse_step[3], int fine_step[3], int xyz[3])
+{
+	int coarse[3] = { 0 };
+	int coarse_delta[3] = { 0 };
+	int fine[3] = { 0 };
+	int fine_delta[3] = { 0 };
+	int target[3] = { 0 };
+	int i;
+	unsigned char offset_data[9] = { 0 };
+
+	if (mir3da_read_offset(handle, offset_data)) {
+		MI_ERR("Get old offset failed !");
+		return -1;
+	}
+	coarse[0] = offset_data[0] & 0x3f;
+	coarse[1] = offset_data[1] & 0x3f;
+	coarse[2] = offset_data[2] & 0x3f;
+	fine[0] = (((int)offset_data[0] << 2) & 0x300) | offset_data[3];
+	fine[1] = (((int)offset_data[1] << 2) & 0x300) | offset_data[4];
+	fine[2] = (((int)offset_data[2] << 2) & 0x300) | offset_data[5];
+
+	MI_MSG("Old coarse_x = %d; coarse_y = %d; coarse_z = %d; fine_x = %d; fine_y = %d; fine_z = %d;", coarse[0], coarse[1], coarse[2], fine[0], fine[1], fine[2]);
+
+	/* 0 means auto detect z direction assume z axis is verticle */
+	if ((abs(target[0]) + abs(target[1]) + abs(target[2])) == 0) {
+		target[2] = (xyz[2] > 0) ? 1024 : (-1024);
+	}
+
+	for (i = 0; i < 3; i++) {
+		coarse_step[i] *= coarse[i] >= 32 ? (-1) : 1;
+		mir3da_cali_off_to_lsb((xyz[i] - target[i]), &coarse_delta[i], coarse_step[i], &fine_delta[i], fine_step[i]);
+
+		coarse[i] += coarse_delta[i];
+		fine[i] += fine_delta[i];
+		offset_data[i] = coarse[i] | ((fine[i] >> 2) & 0xc0);
+		offset_data[i + 3] = fine[i] & 0xFF;
+	}
+
+	if (mir3da_write_offset(handle, offset_data)) {
+		MI_ERR("Update offset failed !");
+		return -1;
+	}
+	/* Discard unstable data after offset register changed */
+	cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], 5);
+	if (cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], 10)) {
+		return -1;
+	}
+	MI_MSG("---calibrate_Done, x = %d, y = %d, z = %d, coarse_x = %d, coarse_y = %d, coarse_z = %d, fine_x = %d, fine_y = %d, fine_z = %d", xyz[0], xyz[1], xyz[2], coarse[0], coarse[1], coarse[2],
+	       fine[0], fine[1], fine[2]);
+
+	return mir3da_write_offset_to_file(offset_data);
+}
+#endif /* !MIR3DA_AUTO_CALIBRATE */
+
+static int NSA_calibrate(MIR_HANDLE handle, int coarse_step[3], int fine_step[3], int fine_max, int target[3])
+{
+	int i = 0, j = 0;
+	unsigned char ncycle = 20;
+	unsigned char nLoop = 20;
+	unsigned char offset_data[9] = { 0 };
+	unsigned char fine_ok_map = 0;
+
+	int xyz[3] = { 0 };
+	int coarse[3] = { 0 };
+	int coarse_delta[3] = { 0 };
+	int fine[3] = { 0 };
+	int fine_delta[3] = { 0 };
+
+	if ((abs(target[0]) + abs(target[1]) + abs(target[2])) != 0 && (abs(target[0]) + abs(target[1]) + abs(target[2])) != 1024) {
+		MI_ERR("Invalid argument !");
+		return -1;
+	}
+
+	/* 0 means auto detect z direction assume z axis is verticle */
+	if ((abs(target[0]) + abs(target[1]) + abs(target[2])) == 0) {
+		if (cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], 5)) {
+			MI_ERR("check z direction failedn");
+			return -1;
+		}
+		target[2] = (xyz[2] > 0) ? 1024 : (-1024);
+	}
+
+	MI_MSG("---Start Calibrate, trim target %d, %d, %d---n", target[0], target[1], target[2]);
+
+	// Stage1: Coarse tune once
+	MI_MSG("---Stage1, coarse tune---");
+	// change to 16G mode
+	if (mir3da_register_mask_write(handle, NSA_REG_G_RANGE, 0x03, 3)) {
+		MI_ERR("i2c mask write failed !n");
+		return -1;
+	}
+
+	/* reset coarse offset register */
+	mir3da_write_offset(handle, offset_data);
+	/* Discard unstable data after offset register changed */
+	cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], 5);
+
+	if (cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], ncycle)) {
+		goto EXIT_16G_MOD;
+	}
+
+	for (i = 0; i < 3; i++) {
+		/* check rule */
+		xyz[i] *= 8;
+
+		coarse[i] = ((xyz[i] - target[i]) > 0) ? 0 : 32;
+
+		MI_MSG("xyz[%d] = %d, coarse[%d] = 0x%x", i, xyz[i], i, coarse[i]);
+
+		coarse_step[i] *= coarse[i] >= 32 ? (-1) : 1;
+		mir3da_cali_off_to_lsb((xyz[i] - target[i]), &coarse_delta[i], coarse_step[i], &fine_delta[i], fine_step[i]);
+
+		coarse[i] += coarse_delta[i];
+		fine[i] += fine_delta[i];
+		mir3da_register_mask_write(handle, NSA_REG_COARSE_OFFSET_TRIM_X + i, 0x3f, (unsigned char)coarse[i]);
+	}
+
+	/* Discard unstable data after offset register changed */
+	cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], 5);
+	if (cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], 5)) {
+		return -1;
+	}
+	for (i = 0; i < 3; i++) {
+		fine[i] += (xyz[i] > 0) ? 0 : fine_max;
+		mir3da_register_write(handle, NSA_REG_FINE_OFFSET_TRIM_X + i, (unsigned char)(fine[i] & 0xff));
+		mir3da_register_mask_write(handle, NSA_REG_COARSE_OFFSET_TRIM_X + i, 0xc0, (unsigned char)(0xc0 & (fine[i] >> 2)));
+	}
+
+EXIT_16G_MOD:
+	// change back to 2G mode
+	if (mir3da_register_mask_write(handle, NSA_REG_G_RANGE, 0x03, 0)) {
+		MI_ERR("i2c mask write failed !n");
+		return -1;
+	}
+	/* Discard unstable data after offset register changed */
+	cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], 5);
+	if (cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], ncycle)) {
+		return -1;
+	}
+	MI_MSG("---Stage1, coarse tune done: x = %d, y = %d, z = %d, coarse_x = %d, coarse_y = %d, coarse_z = %d, fine_x = %d, fine_y = %d, fine_z = %d", xyz[0], xyz[1], xyz[2], coarse[0], coarse[1],
+	       coarse[2], fine[0], fine[1], fine[2]);
+
+	// Stage2: Fine tune
+	MI_MSG("---Stage2, Fine tune---");
+	for (i = 0; i < nLoop; i++) {
+
+		if (0x07 == (fine_ok_map & 0x07)) {
+			break;
+		}
+		/* Discard unstable data after offset register changed */
+		cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], 5);
+		MI_MSG("---Stage2, Fine loop %d", i);
+		if (cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], ncycle)) {
+			return -1;
+		}
+
+		for (j = 0; j < 3; j++) {
+			MI_MSG("xyz[%d] = %d, caorse[%d] = 0x%x, fine[%d] = 0x%x", j, xyz[j], j, coarse[j], j, fine[j]);
+			if (abs(xyz[j] - target[j]) < MIR3DA_OFFSET_THRESHOLD) {
+				fine_ok_map |= (1 << j);
+				offset_data[j] = coarse[j] | ((fine[j] >> 2) & 0xc0);
+				offset_data[j + 3] = fine[j];
+				continue;
+			}
+			mir3da_cali_off_to_lsb((xyz[j] - target[j]), &coarse_delta[j], coarse_step[j], &fine_delta[j], fine_step[j]);
+
+			coarse[j] += coarse_delta[j];
+			fine[j] += fine_delta[j];
+			mir3da_register_write(handle, NSA_REG_FINE_OFFSET_TRIM_X + j, (unsigned char)(fine[j] & 0xff));
+			mir3da_register_mask_write(handle, NSA_REG_COARSE_OFFSET_TRIM_X + j, 0xFF, (unsigned char)(0xc0 & (fine[j] >> 2)) | coarse[j]);
+		}
+	}
+	MI_MSG("---Stage2, Fine tune done: x = %d, y = %d, z = %d, coarse_x = %d, coarse_y = %d, coarse_z = %d, fine_x = %d, fine_y = %d, fine_z = %d", xyz[0], xyz[1], xyz[2], coarse[0], coarse[1],
+	       coarse[2], fine[0], fine[1], fine[2]);
+
+	if (0x07 == (fine_ok_map & 0x07)) {
+		goto SUCCESS_EXIT;
+	}
+#if MIR3DA_STK_TEMP_SOLUTION
+	if (0x03 == (fine_ok_map & 0x07)) {
+		goto SUCCESS_EXIT;
+	}
+#endif
+
+	MI_MSG("---calibrate Failed !---");
+	return -1;
+
+SUCCESS_EXIT:
+	MI_MSG("---calibrate OK !---");
+	return mir3da_write_offset_to_file(offset_data);
+}
+
+static int NSA_NTO_cali_step_calc(MIR_HANDLE handle, int coarse[3], int x100_fine[3], int x100_cust[3])
+{
+	int i;
+	unsigned int total_gain[3] = { 0 };
+	unsigned char coarse_gain = 0;
+	unsigned char fine_gain[3] = { 0 };
+	unsigned int const coarse_gain_map[] = { 1000, 1125, 1250, 1375, 500, 625, 750, 875 };	/* *1000  */
+	unsigned char const fine_dig_gain_map[] = { 1, 2, 4, 8 };
+
+	if (mir3da_register_read_continuously(handle, NSA_REG_SENSITIVITY_TRIM_X, 3, fine_gain) != 0) {
+		MI_ERR("i2c block read failedn");
+		return -1;
+	}
+
+	if (mir3da_register_read(handle, NSA_REG_SENS_COARSE_TRIM, &coarse_gain) != 0) {
+		MI_ERR("i2c block read failedn");
+		return -1;
+	}
+
+	for (i = 0; i < 3; i++) {
+		// *100*1000
+		total_gain[i] = ((1000 + (fine_gain[i] & 0x1F) * 1000 / 32) / 15) * fine_dig_gain_map[((fine_gain[i] >> 5) & 0x03)] * coarse_gain_map[coarse_gain & 0x07];
+		coarse[i] = (int)(total_gain[i] * 500 / 100000);
+		x100_fine[i] = (int)(total_gain[i] * 293 / 100000);
+		x100_cust[i] = (int)(total_gain[i] * 390 / 100000);
+	}
+	MI_MSG("coarse_step_x = %d, coarse_step_y = %d, coarse_step_z = %dn", coarse[0], coarse[1], coarse[2]);
+	MI_MSG("fine_step_x = %d, fine_step_y = %d, fine_step_z = %dn", x100_fine[0], x100_fine[1], x100_fine[2]);
+	MI_MSG("custom_step_x = %d, custom_step_y = %d, custom_step_z = %dn", x100_cust[0], x100_cust[1], x100_cust[2]);
+
+	return 0;
+}
+
+static int NSA_MLM_cali_step_calc(MIR_HANDLE handle, int coarse[3], int x100_fine[3], int x100_cust[3])
+{
+	int i;
+	unsigned int total_gain[3] = { 0 };
+	unsigned char gain[3] = { 0 };
+	unsigned int const coarse_gain_map[] = { 1000, 1125, 1250, 1375, 500, 625, 750, 875 };	/* *1000  */
+
+	if (mir3da_register_read_continuously(handle, NSA_REG_SENSITIVITY_TRIM_X, 3, gain) != 0) {
+		MI_ERR("i2c block read failedn");
+		return -1;
+	}
+
+	for (i = 0; i < 3; i++) {
+		// *100*1000
+		total_gain[i] = ((1000 + (gain[i] & 0x1F) * 1000 / 32) / 15) * coarse_gain_map[((gain[i] >> 5) & 0x07)];
+		MI_MSG("total gain = %d", total_gain[i]);
+		coarse[i] = (int)(total_gain[i] * 500 / 100000);
+		x100_fine[i] = (int)(total_gain[i] * 589 / 100000);
+		x100_cust[i] = (int)(total_gain[i] * 390 / 100000);
+	}
+
+	MI_MSG("coarse_step_x = %d, coarse_step_y = %d, coarse_step_z = %dn", coarse[0], coarse[1], coarse[2]);
+	MI_MSG("fine_step_x = %d, fine_step_y = %d, fine_step_z = %dn", x100_fine[0], x100_fine[1], x100_fine[2]);
+	MI_MSG("custom_step_x = %d, custom_step_y = %d, custom_step_z = %dn", x100_cust[0], x100_cust[1], x100_cust[2]);
+
+	return 0;
+}
+
+#endif /* !MIR3DA_OFFSET_TEMP_SOLUTION */
+int mir3da_write_offset(MIR_HANDLE handle, unsigned char *offset)
+{
+	return 0;
+}
+
+int mir3da_read_offset(MIR_HANDLE handle, unsigned char *offset)
+{
+	return 0;
+}
+
+static int NSA_NTO_calibrate(MIR_HANDLE handle, int z_dir)
+{
+	int result = 0;
+
+#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
+	int coarse_step[3] = { 0 };
+	int fine_step[3] = { 0 };
+	int custom_step[3] = { 0 };
+	int target[3] = { 0 };
+
+	unsigned char swap_plarity_old = 0;
+
+	/* compute step */
+	if (NSA_NTO_cali_step_calc(handle, coarse_step, fine_step, custom_step)) {
+		MI_ERR("Compute step failed !");
+		return -1;
+	}
+	target[2] = z_dir * 1024;
+
+	// save swap/plarity old setting
+	if (mir3da_register_read(handle, NSA_REG_SWAP_POLARITY, &swap_plarity_old)) {
+		MI_ERR("Get SWAP/PLARITY setting failed !");
+		return -1;
+	}
+	if (mir3da_register_mask_write(handle, NSA_REG_SWAP_POLARITY, 0x0F, 0x00)) {
+		MI_ERR("Set Plarity failed !");
+		return -1;
+	}
+
+	result = NSA_calibrate(handle, coarse_step, fine_step, 0x3ff, target);
+
+	// Restore swap/plarity setting
+	if (mir3da_register_mask_write(handle, NSA_REG_SWAP_POLARITY, 0x0F, swap_plarity_old & 0x0F)) {
+		MI_ERR("Restore SWAP/PLARITY setting failed !");
+		return -1;
+	}
+#endif /* !MIR3DA_OFFSET_TEMP_SOLUTION */
+	return result;
+}
+
+static int NSA_NTO_auto_calibrate(MIR_HANDLE handle, int xyz[3])
+{
+	int result = 0;
+
+#ifdef MIR3DA_AUTO_CALIBRATE
+	int coarse_step[3];
+	int fine_step[3];
+	int custom_step[3] = { 0 };
+	unsigned char swap_plarity_old = 0;
+	int temp = 0;
+
+	/* compute step */
+	if (NSA_NTO_cali_step_calc(handle, coarse_step, fine_step, custom_step)) {
+		MI_ERR("Compute step failed !");
+		return -1;
+	}
+	// save swap/plarity old setting
+	if (mir3da_register_read(handle, NSA_REG_SWAP_POLARITY, &swap_plarity_old)) {
+		MI_ERR("Get SWAP/PLARITY setting failed !");
+		return -1;
+	}
+	if ((swap_plarity_old & (1 << 0))) {
+		MI_ERR("==xy swap==n");
+		temp = xyz[0];
+		xyz[0] = ((swap_plarity_old & (1 << 2)) != 0) ? (-xyz[1]) : xyz[1];
+		xyz[1] = ((swap_plarity_old & (1 << 3)) != 0) ? (-temp) : temp;
+	} else {
+		MI_ERR("==xy no swap==n");
+		xyz[0] = ((swap_plarity_old & (1 << 3)) != 0) ? (-xyz[0]) : xyz[0];
+		xyz[1] = ((swap_plarity_old & (1 << 2)) != 0) ? (-xyz[1]) : xyz[1];
+	}
+
+	xyz[2] = ((swap_plarity_old & (1 << 1)) != 0) ? (-xyz[2]) : xyz[2];
+
+	result = NSA_once_calibrate(handle, coarse_step, fine_step, xyz);
+
+#endif /* !MIR3DA_AUTO_CALIBRATE */
+	return result;
+}
+
+static int NSA_MLM_calibrate(MIR_HANDLE handle, int z_dir)
+{
+	int result = 0;
+#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
+	int coarse_step[3] = { 0 };
+	int fine_step[3] = { 0 };
+	int custom_step[3] = { 0 };
+	int target[3] = { 0 };
+	unsigned char swap_plarity_old = 0;
+
+	/* compute step */
+	if (NSA_MLM_cali_step_calc(handle, coarse_step, fine_step, custom_step)) {
+		MI_ERR("Compute step failed !");
+		return -1;
+	}
+	target[2] = z_dir * 1024;
+
+	// save swap/plarity old setting
+	if (mir3da_register_read(handle, NSA_REG_SWAP_POLARITY, &swap_plarity_old)) {
+		MI_ERR("Get SWAP/PLARITY setting failed !");
+		return -1;
+	}
+	if (mir3da_register_mask_write(handle, NSA_REG_SWAP_POLARITY, 0x0F, 0x0E)) {
+		MI_ERR("Set Plarity failed !");
+		return -1;
+	}
+
+	result = NSA_calibrate(handle, coarse_step, fine_step, 0xff, target);
+	// Restore swap/plarity setting
+	if (mir3da_register_mask_write(handle, NSA_REG_SWAP_POLARITY, 0x0F, swap_plarity_old & 0x0F)) {
+		MI_ERR("Restore SWAP/PLARITY setting failed !");
+		return -1;
+	}
+#endif /* !MIR3DA_OFFSET_TEMP_SOLUTION */
+	return result;
+}
+
+static int NSA_MLM_auto_calibrate(MIR_HANDLE handle, int xyz[3])
+{
+	int result = 0;
+#ifdef MIR3DA_AUTO_CALIBRATE
+	int coarse_step[3] = { 0 };
+	int fine_step[3] = { 0 };
+	int custom_step[3] = { 0 };
+	unsigned char swap_plarity_old = 0;
+
+	/* compute step */
+	if (NSA_MLM_cali_step_calc(handle, coarse_step, fine_step, custom_step)) {
+		MI_ERR("Compute step failed !");
+		return -1;
+	}
+	// save swap/plarity old setting
+	if (mir3da_register_read(handle, NSA_REG_SWAP_POLARITY, &swap_plarity_old)) {
+		MI_ERR("Get SWAP/PLARITY setting failed !");
+		return -1;
+	}
+
+	xyz[0] = ((swap_plarity_old & (1 << 3)) != 0) ? xyz[0] : (-xyz[0]);
+	xyz[1] = ((swap_plarity_old & (1 << 2)) != 0) ? xyz[1] : (-xyz[1]);
+	xyz[2] = ((swap_plarity_old & (1 << 1)) != 0) ? xyz[2] : (-xyz[2]);
+
+	result = NSA_once_calibrate(handle, coarse_step, fine_step, xyz);
+
+#endif /* !MIR3DA_AUTO_CALIBRATE */
+	return result;
+}
+
+static int SOCLE_auto_calibrate(MIR_HANDLE handle, int xyz[3])
+{
+#ifdef MIR3DA_AUTO_CALIBRATE
+	int coarse_step[3] = { -20, -20, -20 };
+	int coarse_delta[3] = { 0 };
+	int coarse[3] = { 0 };
+	int fine_step[3] = { 0 };
+	int fine_delta[3] = { 0 };
+	int target[3] = { 0 };
+	int i;
+	unsigned char offset_data[9] = { 0 };
+
+	if (mir3da_read_offset(handle, offset_data)) {
+		MI_ERR("Get old offset failed !");
+		return -1;
+	}
+
+	/* 0 means auto detect z direction assume z axis is verticle */
+	if ((abs(target[0]) + abs(target[1]) + abs(target[2])) == 0) {
+		target[2] = (xyz[2] > 0) ? 1024 : (-1024);
+	}
+
+	for (i = 0; i < 3; i++) {
+		coarse[i] = offset_data[i * 2 + 1] & 0xff;	/* high byte */
+		coarse[i] = (coarse[i] << 8) | offset_data[i * 2];	/* low gyte */
+
+		mir3da_cali_off_to_lsb((xyz[i] - target[i]), &coarse_delta[i], coarse_step[i], &fine_delta[i], fine_step[i]);
+		coarse[i] += coarse_delta[i];
+
+		offset_data[i * 2] = coarse[i] & 0xff;
+		offset_data[i * 2 + 1] = (coarse[i] >> 8) & 0xff;
+	}
+
+	if (mir3da_write_offset(handle, offset_data)) {
+		MI_ERR("Update offset failed !");
+		return -1;
+	}
+
+	if (cycle_read_xyz(handle, &xyz[0], &xyz[1], &xyz[2], 10)) {
+		return -1;
+	}
+	MI_MSG("---calibrate_Done, x = %d, y = %d, z = %d, off_x = %d, off_y = %d, off_z = %d", xyz[0], xyz[1], xyz[2], coarse[0], coarse[1], coarse[2]);
+
+	return mir3da_write_offset_to_file(offset_data);
+
+#endif /* !MIR3DA_AUTO_CALIBRATE */
+	return 0;
+}
+
+static int SOCLE_calibrate(MIR_HANDLE handle, int z_dir)
+{
+	int result = 0;
+#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
+	short i;
+	unsigned char tmp_data[6];
+	int x = 0, y = 0, z = 0;
+	short tmp_off = 0, tmp_off2 = 0;
+	unsigned char ncycle = 50;
+	unsigned char offset_data[9] = { 0 };
+	int fine_step[3] = { 0 };
+
+	unsigned char x_ok = 0;
+	unsigned char y_ok = 0;
+	unsigned char z_ok = 0;
+	unsigned short x_off = 0;
+	unsigned short y_off = 0;
+	unsigned short z_off = 0;
+	unsigned short x_off_original = 0;
+	unsigned short y_off_original = 0;
+	unsigned short z_off_original = 0;
+
+	/* decide the z direction, if 0 which means auto */
+	if (z_dir == 0) {
+		result = cycle_read_xyz(handle, &x, &y, &z, 5);
+		if (result != 0) {
+			MI_ERR("check z direction failedn");
+			goto fail_exit;
+		}
+		z_dir = z > 0 ? 1 : (-1);
+	}
+
+	if (mir3da_register_read_continuously(handle, (SOCLE_REG_OTP_XOFF_L | 0x80), 6, tmp_data)) {
+		MI_ERR("i2c block read failedn");
+		goto fail_exit;
+	}
+
+	x_off = (tmp_data[1] << 8) | tmp_data[0];
+	y_off = (tmp_data[3] << 8) | tmp_data[2];
+	z_off = (tmp_data[5] << 8) | tmp_data[4];
+
+#if MIR3DA_STK_TEMP_SOLUTION
+	x_off_original = x_off;
+	y_off_original = y_off;
+	z_off_original = z_off;
+#endif
+
+	if (0 != check_linearity_offset(handle, fine_step)) {
+		fine_step[0] = fine_step[1] = fine_step[2] = -20;
+	}
+
+	result = mir3da_register_write(handle, SOCLE_REG_OTP_XOFF_L, x_off & 0xFF);
+	MI_ASSERT(result == 0);
+	result = mir3da_register_write(handle, SOCLE_REG_OTP_XOFF_H, (x_off & 0xFF00) >> 8);
+	MI_ASSERT(result == 0);
+	result = mir3da_register_write(handle, SOCLE_REG_OTP_YOFF_L, y_off & 0xFF);
+	MI_ASSERT(result == 0);
+	result = mir3da_register_write(handle, SOCLE_REG_OTP_YOFF_H, (y_off & 0xFF00) >> 8);
+	MI_ASSERT(result == 0);
+	result = mir3da_register_write(handle, SOCLE_REG_OTP_ZOFF_L, z_off & 0xFF);
+	MI_ASSERT(result == 0);
+	result = mir3da_register_write(handle, SOCLE_REG_OTP_ZOFF_H, (z_off & 0xFF00) >> 8);
+	MI_ASSERT(result == 0);
+
+	MI_MSG("---Start Calibrate, z direction = %d---n", z_dir);
+
+	for (i = 0; i < 20; i++) {
+		x = y = z = 0;
+
+		result = cycle_read_xyz(handle, &x, &y, &z, ncycle);
+		if (result != 0) {
+			MI_ERR("i2c block read failedn");
+			goto fail_exit;
+		}
+
+		MI_MSG("----loop %d: x = %d, y = %d, z = %d; x_off = 0x%x, y_off = 0x%x, z_off = 0x%xn", i, x, y, z, x_off, y_off, z_off);
+
+		if (!x_ok) {
+			if (abs(x) <= MIR3DA_OFFSET_THRESHOLD) {
+				x_ok = 1;
+				MI_MSG("------X is OK, 0x%X-------n", x_off);
+			} else {
+				tmp_off = x / fine_step[0];
+
+				tmp_off2 = (short)x_off - tmp_off;
+				if (tmp_off2 > 0x3ff) {
+					tmp_off2 = 0x3ff;
+				} else if (tmp_off2 < 0) {
+					tmp_off2 = 0x01;
+				}
+
+				x_off = (unsigned short)tmp_off2;
+				MI_MSG("tmp_off = %d, tmp_off2 = %d,  x_off = %dn", tmp_off, tmp_off2, x_off);
+
+				result = mir3da_register_write(handle, SOCLE_REG_OTP_XOFF_L, x_off & 0xFF);
+				MI_ASSERT(result == 0);
+				result = mir3da_register_write(handle, SOCLE_REG_OTP_XOFF_H, (x_off & 0xFF00) >> 8);
+				MI_ASSERT(result == 0);
+			}
+
+		}
+
+		if (!y_ok) {
+			if (abs(y) <= MIR3DA_OFFSET_THRESHOLD) {
+				y_ok = 1;
+				MI_MSG("------Y is OK, 0x%X-------n", y_off);
+			} else {
+				tmp_off = y / fine_step[1];
+
+				tmp_off2 = (short)y_off - tmp_off;
+				if (tmp_off2 > 0x3ff) {
+					tmp_off2 = 0x3ff;
+				} else if (tmp_off2 < 0) {
+					tmp_off2 = 0x01;
+				}
+
+				y_off = (unsigned short)tmp_off2;
+				MI_MSG("tmp_off = %d, tmp_off2 = %d,  y_off = %dn", tmp_off, tmp_off2, y_off);
+
+				result = mir3da_register_write(handle, SOCLE_REG_OTP_YOFF_L, y_off & 0xFF);
+				MI_ASSERT(result == 0);
+				result = mir3da_register_write(handle, SOCLE_REG_OTP_YOFF_H, (y_off & 0xFF00) >> 8);
+				MI_ASSERT(result == 0);
+			}
+
+		}
+
+		if (!z_ok) {
+			if (abs(z - (z_dir > 0 ? 1024 : -1024)) <= MIR3DA_OFFSET_THRESHOLD) {
+				z_ok = 1;
+				MI_MSG("------Z is OK, 0x%X-------n", z_off);
+			} else {
+				tmp_off = (z - (z_dir > 0 ? 1024 : -1024)) / fine_step[2];
+
+				tmp_off2 = (short)z_off - tmp_off;
+				if (tmp_off2 > 0x3ff) {
+					tmp_off2 = 0x3ff;
+				} else if (tmp_off2 < 0) {
+					tmp_off2 = 0x01;
+				}
+
+				z_off = (unsigned short)tmp_off2;
+				MI_MSG("tmp_off = %d, tmp_off2 = %d,  z_off = %dn", tmp_off, tmp_off2, z_off);
+
+				result = mir3da_register_write(handle, SOCLE_REG_OTP_ZOFF_L, z_off & 0xFF);
+				MI_ASSERT(result == 0);
+				result = mir3da_register_write(handle, SOCLE_REG_OTP_ZOFF_H, (z_off & 0xFF00) >> 8);
+				MI_ASSERT(result == 0);
+			}
+
+		}
+
+		if (x_ok && y_ok && z_ok) {
+			MI_MSG("--- Calibrate done ---n");
+			goto success_exit;
+		}
+	}
+
+#if MIR3DA_STK_TEMP_SOLUTION
+	if (x_ok + y_ok + z_ok == 2) {
+
+		if (x_ok == 0) {
+			x_off = x_off_original;
+			result = mir3da_register_write(handle, SOCLE_REG_OTP_XOFF_L, x_off & 0xFF);
+			MI_ASSERT(result == 0);
+			result = mir3da_register_write(handle, SOCLE_REG_OTP_XOFF_H, (x_off & 0xFF00) >> 8);
+			MI_ASSERT(result == 0);
+
+			MI_MSG("--- Calibrate done but x skipped---n");
+
+		} else if (y_ok == 0) {
+
+			y_off = y_off_original;
+			result = mir3da_register_write(handle, SOCLE_REG_OTP_YOFF_L, y_off & 0xFF);
+			MI_ASSERT(result == 0);
+			result = mir3da_register_write(handle, SOCLE_REG_OTP_YOFF_H, (y_off & 0xFF00) >> 8);
+			MI_ASSERT(result == 0);
+
+			MI_MSG("--- Calibrate done but y skipped---n");
+
+		} else if (z_ok == 0) {
+
+			z_off = z_off_original;
+			result = mir3da_register_write(handle, SOCLE_REG_OTP_ZOFF_L, z_off & 0xFF);
+			MI_ASSERT(result == 0);
+			result = mir3da_register_write(handle, SOCLE_REG_OTP_ZOFF_H, (z_off & 0xFF00) >> 8);
+			MI_ASSERT(result == 0);
+
+			MI_MSG("--- Calibrate done but z skipped---n");
+		}
+
+		goto success_exit;
+	}
+#endif
+
+fail_exit:
+	return -1;
+
+success_exit:
+	offset_data[0] = x_off & 0xFF;
+	offset_data[1] = (x_off & 0xFF00) >> 8;
+	offset_data[2] = y_off & 0xFF;
+	offset_data[3] = (y_off & 0xFF00) >> 8;
+	offset_data[4] = z_off & 0xFF;
+	offset_data[5] = (z_off & 0xFF00) >> 8;
+	result = mir3da_write_offset_to_file(offset_data);
+
+#endif /* !MIR3DA_OFFSET_TEMP_SOLUTION */
+	return result;
+}
+
+int mir3da_calibrate(MIR_HANDLE handle, int z_dir)
+{
+	int res = 0;
+#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
+	if (is_cali)
+		return -1;
+	is_cali = 1;
+
+	/* restore original direction if last calibration was done in a wrong direction */
+	mir3da_write_offset(handle, original_offset);
+
+	res = mir3da_gsensor_drv.obj[gsensor_mod].calibrate(handle, z_dir);
+	if (res != 0) {
+		MI_ERR("Calibrate failed !");
+		mir3da_write_offset(handle, original_offset);
+	}
+	bLoad = 1;
+	is_cali = 0;
+#endif /* !MIR3DA_OFFSET_TEMP_SOLUTION */
+	return res;
+}
+
+#ifdef MIR3DA_AUTO_CALIBRATE
+#define STABLE_CHECK_SAMPLE_NUM     10
+#define STABLE_CHECK_THRESHOLD      50000
+#define AUTO_CALI_THRESHOLD_XY      300
+#define AUTO_CALI_THRESHOLD_Z       500
+static unsigned char stable_sample_cnt = 0;
+static int stable_sample_pow_sum[STABLE_CHECK_SAMPLE_NUM] = { 0 };
+static int stable_sample_sum[3] = { 0 };
+
+static int mir3da_auto_cali_condition_confirm(int x, int y, int z, int ave_xyz[3])
+{
+	int max = 0, min = 0;
+	int i;
+	int x_ok = 0, y_ok = 0, z_ok = 0;
+
+	stable_sample_pow_sum[stable_sample_cnt] = x * x + y * y + z * z;
+	stable_sample_sum[0] += x;
+	stable_sample_sum[1] += y;
+	stable_sample_sum[2] += z;
+	stable_sample_cnt++;
+
+	MI_MSG("---stable_sample_cnt = %d", stable_sample_cnt);
+
+	if (stable_sample_cnt < STABLE_CHECK_SAMPLE_NUM)
+		return -1;
+	stable_sample_cnt = 0;
+
+	max = stable_sample_pow_sum[0];
+	min = stable_sample_pow_sum[0];
+	stable_sample_pow_sum[0] = 0;
+	for (i = 1; i < STABLE_CHECK_SAMPLE_NUM; i++) {
+		if (stable_sample_pow_sum[i] > max)
+			max = stable_sample_pow_sum[i];
+		if (stable_sample_pow_sum[i] < min)
+			min = stable_sample_pow_sum[i];
+		stable_sample_pow_sum[i] = 0;
+	}
+	MI_MSG("---max = %d; min = %d", max, min);
+
+	ave_xyz[0] = stable_sample_sum[0] / STABLE_CHECK_SAMPLE_NUM;
+	stable_sample_sum[0] = 0;
+	ave_xyz[1] = stable_sample_sum[1] / STABLE_CHECK_SAMPLE_NUM;
+	stable_sample_sum[1] = 0;
+	ave_xyz[2] = stable_sample_sum[2] / STABLE_CHECK_SAMPLE_NUM;
+	stable_sample_sum[2] = 0;
+
+	MI_MSG("ave_x = %d, ave_y = %d, ave_z = %d", ave_xyz[0], ave_xyz[1], ave_xyz[2]);
+	x_ok = (abs(ave_xyz[0]) < AUTO_CALI_THRESHOLD_XY) ? 1 : 0;
+	y_ok = (abs(ave_xyz[1]) < AUTO_CALI_THRESHOLD_XY) ? 1 : 0;
+	z_ok = (abs(abs(ave_xyz[2]) - 1024) < AUTO_CALI_THRESHOLD_Z) ? 1 : 0;
+
+	if ((abs(max - min) > STABLE_CHECK_THRESHOLD) || ((x_ok + y_ok + z_ok) < 2)) {
+		return -1;
+	}
+	return 0;
+}
+
+static int mir3da_auto_calibrate(MIR_HANDLE handle, int x, int y, int z)
+{
+	int res = 0;
+	int xyz[3] = { 0 };
+
+	if (is_cali)
+		return -1;
+	is_cali = 1;
+
+	if (mir3da_auto_cali_condition_confirm(x, y, z, xyz)) {
+		res = -1;
+		goto EXIT;
+	}
+
+	/* restore original direction if last calibration was done in a wrong direction */
+	mir3da_write_offset(handle, original_offset);
+
+	res = mir3da_gsensor_drv.obj[gsensor_mod].auto_calibrate(handle, xyz);
+	if (res != 0) {
+		MI_ERR("Calibrate failed !");
+		mir3da_write_offset(handle, original_offset);
+	}
+
+EXIT:
+	is_cali = 0;
+
+	return res;
+}
+#endif /* !MIR3DA_AUTO_CALIBRATE */
+
+static int SOCLE_interrupt_ops(MIR_HANDLE handle, mir_int_ops_t * ops)
+{
+	int res = 0;
+
+	switch (ops->type) {
+	case INTERRUPT_OP_INIT:
+
+		/* active level */
+		mir3da_register_mask_write(handle, SOCLE_REG_CTRL_REG6, (1 << 1), (ops->data.init.level << 1));
+		/* latch */
+		mir3da_register_mask_write(handle, SOCLE_REG_CTRL_REG5, (1 << 3), (ops->data.init.latch << 3));
+		mir3da_register_mask_write(handle, SOCLE_REG_CLICK_CFG, (1 << 6), (ops->data.init.latch << 6));
+
+		break;
+
+	case INTERRUPT_OP_ENABLE:
+
+		switch (ops->data.int_src) {
+		case INTERRUPT_ACTIVITY:
+
+			mir3da_register_write(handle, SOCLE_REG_INT1_CFG, 0x7f);
+			mir3da_register_write(handle, SOCLE_REG_INT2_CFG, 0x7f);
+			break;
+
+		case INTERRUPT_CLICK:
+			/* Enable all directions click and double click detect */
+			mir3da_register_mask_write(handle, SOCLE_REG_CLICK_CFG, 0x3f, 0x3f);
+			break;
+		}
+		break;
+
+	case INTERRUPT_OP_CONFIG:
+
+		switch (ops->data.cfg.int_src) {
+		case INTERRUPT_ACTIVITY:
+
+			if (ops->data.cfg.pin == INTERRUPT_PIN1) {
+				/* enable this int on INT1 */
+				mir3da_register_mask_write(handle, SOCLE_REG_CTRL_REG3, (1 << 6), (1 << 6));
+
+				mir3da_register_mask_write(handle, SOCLE_REG_INT1_THS, 0x7f, ops->data.cfg.int_cfg.act.threshold);
+				mir3da_register_mask_write(handle, SOCLE_REG_INT1_DURATION, 0x7f, ops->data.cfg.int_cfg.act.duration);
+			} else if (ops->data.cfg.pin == INTERRUPT_PIN2) {
+				/* enable this int on INT2 */
+				mir3da_register_mask_write(handle, SOCLE_REG_CTRL_REG6, (1 << 5), (1 << 5));
+
+				mir3da_register_mask_write(handle, SOCLE_REG_INT2_THS, 0x7f, ops->data.cfg.int_cfg.act.threshold);
+				mir3da_register_mask_write(handle, SOCLE_REG_INT2_DURATION, 0x7f, ops->data.cfg.int_cfg.act.duration);
+			}
+			break;
+
+		case INTERRUPT_CLICK:
+
+			mir3da_register_mask_write(handle, SOCLE_REG_CLICK_THS, 0x7f, ops->data.cfg.int_cfg.clk.threshold);
+			mir3da_register_mask_write(handle, SOCLE_REG_TIME_LIMIT, 0x7f, ops->data.cfg.int_cfg.clk.click_time);
+			mir3da_register_write(handle, SOCLE_REG_TIME_LATENCY, ops->data.cfg.int_cfg.clk.quiet_time);
+			mir3da_register_write(handle, SOCLE_REG_TIME_WINDOW, ops->data.cfg.int_cfg.clk.window);
+
+			if (ops->data.cfg.pin == INTERRUPT_PIN1) {
+				mir3da_register_mask_write(handle, SOCLE_REG_CTRL_REG3, (1 << 7), (1 << 7));
+			} else if (ops->data.cfg.pin == INTERRUPT_PIN2) {
+				mir3da_register_mask_write(handle, SOCLE_REG_CTRL_REG6, (1 << 7), (1 << 7));
+			}
+			break;
+		}
+		break;
+
+	case INTERRUPT_OP_DISABLE:
+		switch (ops->data.int_src) {
+		case INTERRUPT_ACTIVITY:
+
+			mir3da_register_write(handle, SOCLE_REG_INT1_CFG, 0);
+			mir3da_register_write(handle, SOCLE_REG_INT2_CFG, 0);
+			break;
+
+		case INTERRUPT_CLICK:
+			/* Enable all directions click and double click detect */
+			mir3da_register_mask_write(handle, SOCLE_REG_CLICK_CFG, 0x3f, 0);
+			break;
+		}
+		break;
+
+	default:
+		MI_ERR("Unsupport operation !");
+	}
+
+	return res;
+}
+
+static int NSA_interrupt_ops(MIR_HANDLE handle, mir_int_ops_t * ops)
+{
+	switch (ops->type) {
+	case INTERRUPT_OP_INIT:
+
+		/* latch */
+		mir3da_register_mask_write(handle, NSA_REG_INT_LATCH, 0x0f, ops->data.init.latch);
+		/* active level & output mode */
+		mir3da_register_mask_write(handle, NSA_REG_INT_PIN_CONFIG, 0x0f, ops->data.init.level | (ops->data.init.pin_mod << 1) | (ops->data.init.level << 2) | (ops->data.init.pin_mod << 3));
+
+		break;
+
+	case INTERRUPT_OP_ENABLE:
+		switch (ops->data.int_src) {
+		case INTERRUPT_ACTIVITY:
+			/* Enable active interrupt */
+			mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_SETTINGS1, 0x07, 0x07);
+			break;
+		case INTERRUPT_CLICK:
+			/* Enable single and double tap detect */
+			mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_SETTINGS1, 0x30, 0x30);
+			break;
+		}
+		break;
+
+	case INTERRUPT_OP_CONFIG:
+
+		switch (ops->data.cfg.int_src) {
+		case INTERRUPT_ACTIVITY:
+
+			mir3da_register_write(handle, NSA_REG_ACTIVE_THRESHOLD, ops->data.cfg.int_cfg.act.threshold);
+			mir3da_register_mask_write(handle, NSA_REG_ACTIVE_DURATION, 0x03, ops->data.cfg.int_cfg.act.duration);
+
+			/* Int mapping */
+			if (ops->data.cfg.pin == INTERRUPT_PIN1) {
+				mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING1, (1 << 2), (1 << 2));
+			} else if (ops->data.cfg.pin == INTERRUPT_PIN2) {
+				printk(" gensor int2  open n");
+				mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING3, (1 << 2), (1 << 2));
+			}
+			break;
+
+		case INTERRUPT_CLICK:
+
+			mir3da_register_mask_write(handle, NSA_REG_TAP_THRESHOLD, 0x1f, ops->data.cfg.int_cfg.clk.threshold);
+			mir3da_register_mask_write(handle, NSA_REG_TAP_DURATION, (0x03 << 5) | (0x07),
+						   (ops->data.cfg.int_cfg.clk.quiet_time << 7) | (ops->data.cfg.int_cfg.clk.click_time << 6) | (ops->data.cfg.int_cfg.clk.window));
+
+			if (ops->data.cfg.pin == INTERRUPT_PIN1) {
+				mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING1, 0x30, 0x30);
+			} else if (ops->data.cfg.pin == INTERRUPT_PIN2) {
+				printk(" gensor int2  close n");
+				mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING3, 0x30, 0x30);
+			}
+			break;
+		}
+		break;
+
+	case INTERRUPT_OP_DISABLE:
+		switch (ops->data.int_src) {
+		case INTERRUPT_ACTIVITY:
+			/* Enable active interrupt */
+			mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_SETTINGS1, 0x07, 0x00);
+			break;
+
+		case INTERRUPT_CLICK:
+			/* Enable single and double tap detect */
+			mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_SETTINGS1, 0x30, 0x00);
+			break;
+		}
+		break;
+
+	default:
+		MI_ERR("Unsupport operation !");
+	}
+	return 0;
+}
+
+int mir3da_interrupt_ops(MIR_HANDLE handle, mir_int_ops_t *ops)
+{
+	int res = 0;
+
+	res = mir3da_gsensor_drv.obj[gsensor_mod].int_ops(handle, ops);
+	return res;
+}
+
+#if FILTER_AVERAGE_ENHANCE
+int mir3da_get_filter_param(struct mir3da_filter_param_s *param)
+{
+	if (param == 0) {
+		MI_ERR("Invalid param!");
+		return -1;
+	}
+
+	param->filter_param_h = core_ctx.tFac[0].filter_param_h;
+	param->filter_param_l = core_ctx.tFac[0].filter_param_l;
+	param->filter_threhold = core_ctx.tFac[0].filter_threhold;
+
+	MI_MSG("FILTER param is get: filter_param_h = %d, filter_param_l = %d, filter_threhold = %d", param->filter_param_h, param->filter_param_l, param->filter_threhold);
+
+	return 0;
+}
+
+int mir3da_set_filter_param(struct mir3da_filter_param_s *param)
+{
+
+	if (param == 0) {
+		MI_ERR("Invalid param!");
+		return -1;
+	}
+
+	MI_MSG("FILTER param is set: filter_param_h = %d, filter_param_l = %d, filter_threhold = %d", param->filter_param_h, param->filter_param_l, param->filter_threhold);
+
+	core_ctx.tFac[1].filter_param_l = core_ctx.tFac[2].filter_param_l = core_ctx.tFac[0].filter_param_l = param->filter_param_l;
+	core_ctx.tFac[1].filter_param_h = core_ctx.tFac[2].filter_param_h = core_ctx.tFac[0].filter_param_h = param->filter_param_h;
+	core_ctx.tFac[1].filter_threhold = core_ctx.tFac[2].filter_threhold = core_ctx.tFac[0].filter_threhold = param->filter_threhold;
+
+	return 0;
+}
+#endif //#if FILTER_AVERAGE_ENHANCE
+
+int mir3da_get_enable(MIR_HANDLE handle, char *enable)
+{
+	unsigned char reg_data;
+	int res = 0;
+
+	res = mir3da_register_read(handle, mir3da_gsensor_drv.obj[gsensor_mod].power.addr, &reg_data);
+	if (res != 0) {
+		return res;
+	}
+
+	*enable = (reg_data & mir3da_gsensor_drv.obj[gsensor_mod].power.mask) ? 0 : 1;
+
+	return res;
+}
+
+int mir3da_set_enable(MIR_HANDLE handle, char enable)
+{
+	int res = 0;
+	unsigned char reg_data = 0;
+
+	if (!enable) {
+		reg_data = mir3da_gsensor_drv.obj[gsensor_mod].power.value;
+	}
+
+	res = mir3da_register_mask_write(handle, mir3da_gsensor_drv.obj[gsensor_mod].power.addr, mir3da_gsensor_drv.obj[gsensor_mod].power.mask, reg_data);
+
+	return res;
+}
+
+static int SOCLE_get_reg_data(MIR_HANDLE handle, char *buf)
+{
+	int i, count = 0;
+	unsigned char val;
+
+	count += mir3da_gsensor_drv.method->mysprintf(buf + count, "---------page 0---------");
+	for (i = 0; i <= 0x003d; i++) {
+		if (i % 16 == 0)
+			count += mir3da_gsensor_drv.method->mysprintf(buf + count, "n%02xt", i);
+		mir3da_register_read(handle, i, &val);
+		count += mir3da_gsensor_drv.method->mysprintf(buf + count, "%02X ", val);
+	}
+
+	count += mir3da_gsensor_drv.method->mysprintf(buf + count, "n---------page 1---------");
+	for (i = 0x0100; i <= 0x012a; i++) {
+		if ((i & 0xff) % 16 == 0)
+			count += mir3da_gsensor_drv.method->mysprintf(buf + count, "n%02xt", (i & 0xff));
+		mir3da_register_read(handle, i, &val);
+		count += mir3da_gsensor_drv.method->mysprintf(buf + count, "%02X ", val);
+
+	}
+	count += mir3da_gsensor_drv.method->mysprintf(buf + count, "n---------end---------n");
+
+	return count;
+}
+
+static int NSA_get_reg_data(MIR_HANDLE handle, char *buf)
+{
+	int count = 0;
+	int i;
+	unsigned char val;
+
+	count += mir3da_gsensor_drv.method->mysprintf(buf + count, "---------start---------");
+	for (i = 0; i <= 0xd2; i++) {
+		if (i % 16 == 0)
+			count += mir3da_gsensor_drv.method->mysprintf(buf + count, "n%02xt", i);
+		mir3da_register_read(handle, i, &val);
+		count += mir3da_gsensor_drv.method->mysprintf(buf + count, "%02X ", val);
+	}
+
+	count += mir3da_gsensor_drv.method->mysprintf(buf + count, "n--------end---------n");
+	return count;
+}
+
+int mir3da_get_reg_data(MIR_HANDLE handle, char *buf)
+{
+	return mir3da_gsensor_drv.obj[gsensor_mod].get_reg_data(handle, buf);
+}
+
+int mir3da_set_odr(MIR_HANDLE handle, int delay)
+{
+	int res = 0;
+	int odr = 0;
+
+	if (delay <= 5) {
+		odr = MIR3DA_ODR_200HZ;
+	} else if (delay <= 10) {
+		odr = MIR3DA_ODR_100HZ;
+	} else {
+		odr = MIR3DA_ODR_50HZ;
+	}
+
+	res = mir3da_register_mask_write(handle, mir3da_gsensor_drv.obj[gsensor_mod].odr_sect[odr].addr,
+					 mir3da_gsensor_drv.obj[gsensor_mod].odr_sect[odr].mask, mir3da_gsensor_drv.obj[gsensor_mod].odr_sect[odr].value);
+	if (res != 0) {
+		return res;
+	}
+
+	return res;
+}
+
+static int mir3da_soft_reset(MIR_HANDLE handle)
+{
+	int res = 0;
+	unsigned char reg_data;
+
+	reg_data = mir3da_gsensor_drv.obj[gsensor_mod].soft_reset.value;
+	res = mir3da_register_mask_write(handle, mir3da_gsensor_drv.obj[gsensor_mod].soft_reset.addr, mir3da_gsensor_drv.obj[gsensor_mod].soft_reset.mask, reg_data);
+	mir3da_gsensor_drv.method->msdelay(5);
+
+	return res;
+}
+
+int mir3da_module_detect(PLAT_HANDLE handle)
+{
+	int i, res = 0;
+	unsigned char cid, mid;
+	int is_find = -1;
+
+	/* Probe gsensor module */
+	for (i = 0; i < sizeof(mir3da_gsensor) / sizeof(mir3da_gsensor[0]); i++) {
+
+		//       res = mir3da_register_mask_write(handle, mir3da_gsensor_drv.obj[i].soft_reset.addr, mir3da_gsensor_drv.obj[i].soft_reset.mask,  mir3da_gsensor_drv.obj[i].soft_reset.value);
+		mir3da_gsensor_drv.method->msdelay(5);
+
+		res = mir3da_register_read(handle, mir3da_gsensor[i].chip_id.addr, &cid);
+		if (res != 0) {
+			return res;
+		}
+
+		cid &= mir3da_gsensor[i].chip_id.mask;
+		if (mir3da_gsensor[i].chip_id.value == cid) {
+			res = mir3da_register_read(handle, mir3da_gsensor[i].mod_id.addr, &mid);
+			if (res != 0) {
+				return res;
+			}
+
+			mid &= mir3da_gsensor[i].mod_id.mask;
+			if (mir3da_gsensor[i].mod_id.value == mid) {
+				MI_MSG("Found Gsensor MIR3DA ! mid =0x%x", mid)
+				    gsensor_mod = i;
+				is_find = 0;
+				break;
+			}
+		}
+	}
+
+	return is_find;
+}
+
+int mir3da_install_general_ops(struct general_op_s *ops)
+{
+	if (0 == ops) {
+		return -1;
+	}
+
+	mir3da_gsensor_drv.method = ops;
+	return 0;
+}
+
+MIR_HANDLE mir3da_core_init(PLAT_HANDLE handle)
+{
+	int res = 0;
+	unsigned char data;
+#if FILTER_AVERAGE_ENHANCE
+	int i = 0;
+#endif
+	int j = 0;
+
+	mir3da_gsensor_drv.obj = mir3da_gsensor;
+
+	for (j = 0; j < 5; j++) {
+		if (gsensor_mod < 0) {
+			res = mir3da_module_detect(handle);
+			if (!res) {
+				MI_ERR("find Mir3da gsensor!!");
+				break;
+			}
+		}
+	}
+
+/*	if(j==5){
+	   MI_ERR("Can't find Mir3da gsensor!!");
+	   return 0;
+	}
+*/
+	MI_MSG("Probe gsensor module: %s", mir3da_gsensor[gsensor_mod].asic);
+
+#if MIR3DA_SENS_TEMP_SOLUTION
+	if (GSENSOR_MOD_SOCLE == gsensor_mod) {
+		mir3da_register_read(handle, SOCLE_REG_OTP_TRIM_THERM_H, &data);
+		if (data == 2) {
+			MI_ERR("Enable sens temp solution !");
+			bSensZoom = 1;
+		}
+	}
+#endif
+
+#if FILTER_AVERAGE_ENHANCE
+	/* configure default filter param */
+	for (i = 0; i < 3; i++) {
+		core_ctx.tFac[i].filter_param_l = 2;
+		core_ctx.tFac[i].filter_param_h = 8;
+		core_ctx.tFac[i].filter_threhold = 60;
+
+		core_ctx.tFac[i].refN_l = 0;
+		core_ctx.tFac[i].refN_h = 0;
+	}
+#endif
+
+	res = mir3da_chip_resume(handle);
+	if (res) {
+		MI_ERR("chip resume fail!!n");
+		return 0;
+	}
+
+	return handle;
+}
+
+int mir3da_chip_resume(MIR_HANDLE handle)
+{
+	int res = 0;
+	unsigned char reg_data;
+	unsigned char i = 0;
+
+	res = mir3da_soft_reset(handle);
+	if (res) {
+		MI_ERR("Do softreset failed !");
+		return res;
+	}
+
+	for (i = 0; i < MIR3DA_INIT_SECT_LEN; i++) {
+		if (mir3da_gsensor_drv.obj[gsensor_mod].init_sect[i].addr < 0) {
+			break;
+		}
+
+		reg_data = mir3da_gsensor_drv.obj[gsensor_mod].init_sect[i].value;
+		res = mir3da_register_mask_write(handle, mir3da_gsensor_drv.obj[gsensor_mod].init_sect[i].addr, mir3da_gsensor_drv.obj[gsensor_mod].init_sect[i].mask, reg_data);
+		if (res != 0) {
+			return res;
+		}
+	}
+
+#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
+	res = mir3da_read_offset(handle, original_offset);
+	if (res != 0) {
+		MI_ERR("Read offset failed !");
+		return res;
+	}
+
+	bLoad = 0;
+	readOffsetCnt = -1;
+	manual_load_cali_file(handle);
+#endif
+
+	return res;
+}
+
+int mir3da_get_primary_offset(MIR_HANDLE handle, int *x, int *y, int *z)
+{
+	int res = 0;
+	unsigned char reg_data;
+	unsigned char i = 0;
+	unsigned char offset[9] = { 0 };
+
+	res = mir3da_read_offset(handle, offset);
+	if (res != 0) {
+		MI_ERR("Read offset failed !");
+		return -1;
+	}
+
+	res = mir3da_soft_reset(handle);
+	if (res) {
+		MI_ERR("Do softreset failed !");
+		return -1;
+	}
+
+	for (i = 0; i < MIR3DA_INIT_SECT_LEN; i++) {
+		if (mir3da_gsensor_drv.obj[gsensor_mod].init_sect[i].addr < 0) {
+			break;
+		}
+
+		reg_data = mir3da_gsensor_drv.obj[gsensor_mod].init_sect[i].value;
+		res = mir3da_register_mask_write(handle, mir3da_gsensor_drv.obj[gsensor_mod].init_sect[i].addr, mir3da_gsensor_drv.obj[gsensor_mod].init_sect[i].mask, reg_data);
+		if (res != 0) {
+			MI_ERR("Write register[0x%x] error!", mir3da_gsensor_drv.obj[gsensor_mod].init_sect[i].addr);
+			goto EXIT;
+		}
+	}
+
+	mir3da_gsensor_drv.method->msdelay(100);
+
+	res = cycle_read_xyz(handle, x, y, z, 20);
+	if (res) {
+		MI_ERR("i2c block read failedn");
+		goto EXIT;
+	}
+
+	mir3da_write_offset(handle, offset);
+
+	return 0;
+
+EXIT:
+	mir3da_write_offset(handle, offset);
+	return -1;
+}
+
+int mir3da_read_int_status(MIR_HANDLE handle)
+{
+	char data = 0;
+
+	mir3da_register_read(handle, NSA_REG_MOTION_FLAG, &data);
+	if (data & 0x04)
+		return 1;
+
+	return 0;
+}
+
+int mir3da_clear_intterrupt(MIR_HANDLE handle)
+{
+	int res = 0;
+
+	res |= mir3da_register_mask_write(handle, NSA_REG_INT_LATCH, 0x80, 0x86);
+
+	return res;
+}
+
+int mir3da_open_interrupt(MIR_HANDLE handle, int num, int on)
+{
+	int res = 0;
+
+	//res |=  mir3da_register_mask_write(handle,NSA_REG_INT_LATCH,0x8F,0x8F);
+	res |= mir3da_register_mask_write(handle, NSA_REG_INT_LATCH, 0x8F, 0x86);
+	// 83 1s 84 2s 85 4s  86 8s  8f yiz 
+	res |= mir3da_register_mask_write(handle, NSA_REG_ACTIVE_DURATION, 0xff, 0x03);
+	res |= mir3da_register_mask_write(handle, NSA_REG_ACTIVE_THRESHOLD, 0xff, 0x10);
+	if (on) {
+		res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_SETTINGS1, 0xff, 0x03);
+		switch (num) {
+
+		case 0:
+			res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING1, 0xff, 0x04);
+			break;
+
+		case 1:
+			res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING3, 0xff, 0x04);
+			break;
+		}
+	} else {
+		res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_SETTINGS1, 0xff, 0x00);
+		res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING1, 0xff, 0x00);
+		res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING3, 0xff, 0x00);
+	}
+
+	return res;
+}
diff --git a/lichee/linux-3.10/drivers/input/sensor/mir3da_core.h b/lichee/linux-3.10/drivers/input/sensor/mir3da_core.h
new file mode 100755
index 0000000..210390c
--- /dev/null
+++ b/lichee/linux-3.10/drivers/input/sensor/mir3da_core.h
@@ -0,0 +1,328 @@
+/* Core header for MiraMEMS 3-Axis Accelerometer's driver. 
+ * 
+ * mir3da_core.h - Linux kernel modules for MiraMEMS 3-Axis Accelerometer
+ *
+ * Copyright (C) 2011-2013 MiraMEMS Sensing Technology Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MIR3DA_CORE_H__
+#define __MIR3DA_CORE_H__
+
+#define CUST_VER                            ""	/* for Custom debug version */
+#define CORE_VER                            "1.4.2_2014-08-05-17:30:00_"CUST_VER
+
+#define MIR3DA_SUPPORT_CHIP_LIST            MIR_SOCLE, MIR_NSA_NTO, MIR_NSA_MLM
+
+#define MIR3DA_BUFSIZE                      256
+
+#ifdef CONFIG_DA280
+#define NRIPCV				0x08
+#define MIR3DA_TYPE			1	/*da280 */
+#else
+#define MIR3DA_TYPE			0	/*da380 */
+#define NRIPCV				0x05
+#endif
+
+#define MIR3DA_STK_TEMP_SOLUTION            0
+//#define MIR3DA_OFFSET_TEMP_SOLUTION         0
+#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
+#define MIR3DA_AUTO_CALIBRATE               0
+#else
+//#define MIR3DA_AUTO_CALIBRATE               0
+#endif /* !MIR3DA_OFFSET_TEMP_SOLUTION */
+#define MIR3DA_SENS_TEMP_SOLUTION           1
+#define FILTER_AVERAGE_ENHANCE              1
+#define FILTER_AVERAGE_EX                   1
+
+#define MIR3DA_OFFSET_LEN                   9
+
+typedef void *MIR_HANDLE;
+typedef void *PLAT_HANDLE;
+
+struct serial_manage_if_s {
+
+	int (*read) (PLAT_HANDLE handle, unsigned char addr, unsigned char *data);
+	int (*write) (PLAT_HANDLE handle, unsigned char addr, unsigned char data);
+	int (*read_block) (PLAT_HANDLE handle, unsigned char base_addr, unsigned char count, unsigned char *data);
+};
+
+struct general_op_s {
+
+	struct serial_manage_if_s smi;
+
+	int (*data_save) (unsigned char *data);
+	int (*data_get) (unsigned char *data);
+
+	int (*myprintf) (const char *fmt, ...);
+	int (*mysprintf) (char *buf, const char *fmt, ...);
+	void (*msdelay) (int ms);
+};
+
+#define MIR_GENERAL_OPS_DECLARE(OPS_HDL, SMI_RD, SMI_RDBL, SMI_WR, DAT_SAVE, DAT_GET, MDELAY, MYPRINTF, MYSPRINTF)                                      
+                                                                                                                                                        
+                                struct general_op_s     OPS_HDL = { { SMI_RD, SMI_WR, SMI_RDBL }, DAT_SAVE, DAT_GET, MYPRINTF, MYSPRINTF, MDELAY }
+
+enum interrupt_src {
+
+	INTERRUPT_ACTIVITY = 1,
+	INTERRUPT_CLICK,
+
+};
+
+typedef enum _int_op_type {
+
+	INTERRUPT_OP_INIT,
+	INTERRUPT_OP_ENABLE,
+	INTERRUPT_OP_CONFIG,
+	INTERRUPT_OP_DISABLE,
+
+} mir_int_op_type;
+
+enum interrupt_pin {
+
+	INTERRUPT_PIN1,
+	INTERRUPT_PIN2,
+};
+
+enum pin_output_mode {
+
+	OUTPUT_MOD_PULL_PUSH,
+	OUTPUT_MOD_OD,
+};
+
+struct int_act_cfg_s {
+
+	unsigned char threshold;
+	unsigned char duration;
+};
+
+struct int_clk_cfg_s {
+
+	unsigned char threshold;
+	unsigned char click_time;	/* click time */
+	unsigned char quiet_time;	/* quiet time after click */
+	unsigned char window;	/* for second click time window */
+};
+
+typedef union _int_src_configuration {
+
+	struct int_act_cfg_s act;
+	struct int_clk_cfg_s clk;
+
+} mir_int_src_cfg_t;
+
+typedef struct _int_configuration {
+
+	enum interrupt_pin pin;
+	enum interrupt_src int_src;
+
+	mir_int_src_cfg_t int_cfg;
+
+} mir_int_cfg_t;
+
+typedef struct _int_init_data {
+
+	enum pin_output_mode pin_mod;
+
+	unsigned char level;	/* 1: high active, 0: low active */
+	unsigned char latch;	/* >0: latch time, 0: no latch */
+
+} mir_int_init_t;
+
+typedef union _int_op_data {
+
+	enum interrupt_src int_src;
+
+	mir_int_init_t init;
+	mir_int_cfg_t cfg;
+
+} mir_int_op_data;
+
+typedef struct _int_operations {
+
+	mir_int_op_type type;
+	mir_int_op_data data;
+
+} mir_int_ops_t;
+
+/* Register Define for SOCLE asic */
+#define SOCLE_REG_SOFT_RESET            0x0105
+#define SOCLE_REG_LDO_REG               0x0006
+#define SOCLE_REG_WHO_AM_I              0x000f
+#define SOCLE_REG_TEMP_CFG_REG          0x001f
+#define SOCLE_REG_CTRL_REG1             0x0020
+#define SOCLE_REG_CTRL_REG3             0X0022
+#define SOCLE_REG_CTRL_REG4             0x0023
+#define SOCLE_REG_CTRL_REG5             0x0024
+#define SOCLE_REG_CTRL_REG6             0x0025
+#define SOCLE_REG_STATUS_REG            0x0027
+#define SOCLE_REG_OUT_X_L               0x0028
+#define SOCLE_REG_OUT_X_H               0x0029
+#define SOCLE_REG_OUT_Y_L               0x002A
+#define SOCLE_REG_OUT_Y_H               0x002B
+#define SOCLE_REG_OUT_Z_L               0x002C
+#define SOCLE_REG_OUT_Z_H               0x002D
+#define SOCLE_REG_INT1_CFG              0x0030
+#define SOCLE_REG_INT1_SRC              0x0031
+#define SOCLE_REG_INT1_THS              0x0032
+#define SOCLE_REG_INT1_DURATION         0x0033
+#define SOCLE_REG_INT2_CFG              0x0034
+#define SOCLE_REG_INT2_SRC              0x0035
+#define SOCLE_REG_INT2_THS              0x0036
+#define SOCLE_REG_INT2_DURATION         0x0037
+#define SOCLE_REG_CLICK_CFG             0x0038
+#define SOCLE_REG_CLICK_SRC             0x0039
+#define SOCLE_REG_CLICK_THS             0x003A
+#define SOCLE_REG_TIME_LIMIT            0x003B
+#define SOCLE_REG_TIME_LATENCY          0x003C
+#define SOCLE_REG_TIME_WINDOW           0x003D
+#define SOCLE_REG_OTP_XOFF_L            0x0110
+#define SOCLE_REG_OTP_XOFF_H            0x0111
+#define SOCLE_REG_OTP_YOFF_L            0x0112
+#define SOCLE_REG_OTP_YOFF_H            0x0113
+#define SOCLE_REG_OTP_ZOFF_L            0x0114
+#define SOCLE_REG_OTP_ZOFF_H            0x0115
+#define SOCLE_REG_OTP_XSO               0x0116
+#define SOCLE_REG_OTP_YSO               0x0117
+#define SOCLE_REG_OTP_ZSO               0x0118
+#define SOCLE_REG_OTP_TRIM_OSC          0x011b
+#define SOCLE_REG_LPF_ABSOLUTE          0x011c
+#define SOCLE_REG_TEMP_OFF1             0x0127
+#define SOCLE_REG_TEMP_OFF2             0x0128
+#define SOCLE_REG_TEMP_OFF3             0x0129
+#define SOCLE_REG_OTP_TRIM_THERM_H      0x011a
+
+/* Register define for NSA asic */
+#define NSA_REG_SPI_I2C                 0x00
+#define NSA_REG_WHO_AM_I                0x01
+#define NSA_REG_ACC_X_LSB               0x02
+#define NSA_REG_ACC_X_MSB               0x03
+#define NSA_REG_ACC_Y_LSB               0x04
+#define NSA_REG_ACC_Y_MSB               0x05
+#define NSA_REG_ACC_Z_LSB               0x06
+#define NSA_REG_ACC_Z_MSB               0x07
+#define NSA_REG_G_RANGE                 0x0f
+#define NSA_REG_MOTION_FLAG          0x09
+#define NSA_REG_ODR_AXIS_DISABLE        0x10
+#define NSA_REG_POWERMODE_BW            0x11
+#define NSA_REG_SWAP_POLARITY           0x12
+#define NSA_REG_FIFO_CTRL               0x14
+#define NSA_REG_INTERRUPT_SETTINGS1     0x16
+#define NSA_REG_INTERRUPT_SETTINGS2     0x17
+#define NSA_REG_INTERRUPT_MAPPING1      0x19
+#define NSA_REG_INTERRUPT_MAPPING2      0x1a
+#define NSA_REG_INTERRUPT_MAPPING3      0x1b
+#define NSA_REG_INT_PIN_CONFIG          0x20
+#define NSA_REG_INT_LATCH               0x21
+#define NSA_REG_ACTIVE_DURATION         0x27
+#define NSA_REG_ACTIVE_THRESHOLD        0x28
+#define NSA_REG_TAP_DURATION            0x2A
+#define NSA_REG_TAP_THRESHOLD           0x2B
+#define NSA_REG_CUSTOM_OFFSET_X         0x38
+#define NSA_REG_CUSTOM_OFFSET_Y         0x39
+#define NSA_REG_CUSTOM_OFFSET_Z         0x3a
+#define NSA_REG_ENGINEERING_MODE        0x7f
+#define NSA_REG_SENSITIVITY_TRIM_X      0x80
+#define NSA_REG_SENSITIVITY_TRIM_Y      0x81
+#define NSA_REG_SENSITIVITY_TRIM_Z      0x82
+#define NSA_REG_COARSE_OFFSET_TRIM_X    0x83
+#define NSA_REG_COARSE_OFFSET_TRIM_Y    0x84
+#define NSA_REG_COARSE_OFFSET_TRIM_Z    0x85
+#define NSA_REG_FINE_OFFSET_TRIM_X      0x86
+#define NSA_REG_FINE_OFFSET_TRIM_Y      0x87
+#define NSA_REG_FINE_OFFSET_TRIM_Z      0x88
+#define NSA_REG_SENS_COMP               0x8c
+#define NSA_REG_SENS_COARSE_TRIM        0xd1
+
+#define MIR3DA_ODR_50HZ                  0
+#define MIR3DA_ODR_100HZ                 1
+#define MIR3DA_ODR_200HZ                 2
+
+#define MI_TAG                          "[MIR3DA] "
+enum {
+	DEBUG_ERR = 1,
+	DEBUG_ASSERT = 1 << 1,
+	DEBUG_MSG = 1 << 2,
+	DEBUG_FUNC = 1 << 3,
+	DEBUG_DATA = 1 << 4,
+};
+
+/* register operation */
+int mir3da_register_read(MIR_HANDLE handle, short reg, unsigned char *data);
+int mir3da_register_write(MIR_HANDLE handle, short reg, unsigned char data);
+int mir3da_register_read_continuously(MIR_HANDLE handle, short base_reg, unsigned char count, unsigned char *data);
+int mir3da_register_mask_write(MIR_HANDLE handle, short addr, unsigned char mask, unsigned char data);
+
+int mir3da_install_general_ops(struct general_op_s *ops);
+/* chip init */
+int mir3da_module_detect(PLAT_HANDLE handle);
+MIR_HANDLE mir3da_core_init(PLAT_HANDLE handle);
+
+/* data polling */
+int mir3da_read_data(MIR_HANDLE handle, short *x, short *y, short *z);
+
+/* filter configure */
+#ifdef FILTER_AVERAGE_ENHANCE
+struct mir3da_filter_param_s {
+	int filter_param_l;
+	int filter_param_h;
+	int filter_threhold;
+};
+
+int mir3da_get_filter_param(struct mir3da_filter_param_s *param);
+int mir3da_set_filter_param(struct mir3da_filter_param_s *param);
+#endif
+
+#ifdef MIR3DA_STK_TEMP_SOLUTION
+extern char bxstk;
+extern char bystk;
+extern char bzstk;
+extern int squareRoot(int val);
+#endif
+
+enum {
+	GSENSOR_MOD_SOCLE = 0,
+	GSENSOR_MOD_NSA_NTO,
+	GSENSOR_MOD_NSA_MLM,
+};
+
+extern int gsensor_mod;		/* Initial value */
+
+/* CALI */
+int mir3da_calibrate(MIR_HANDLE handle, int z_dir);
+
+/* calibration */
+#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
+extern char bLoad;
+void manual_load_cali_file(MIR_HANDLE handle);
+#endif
+
+/* Interrupt operations */
+int mir3da_interrupt_ops(MIR_HANDLE handle, mir_int_ops_t * ops);
+
+int cycle_read_xyz(MIR_HANDLE handle, int *x, int *y, int *z, int ncycle);
+
+int mir3da_read_offset(MIR_HANDLE handle, unsigned char *offst);
+int mir3da_write_offset(MIR_HANDLE handle, unsigned char *offset);
+int mir3da_open_interrupt(MIR_HANDLE handle, int num, int on);
+int mir3da_clear_intterrupt(MIR_HANDLE handle);
+int mir3da_set_enable(MIR_HANDLE handle, char bEnable);
+int mir3da_get_enable(MIR_HANDLE handle, char *bEnable);
+int mir3da_get_reg_data(MIR_HANDLE handle, char *buf);
+int mir3da_set_odr(MIR_HANDLE handle, int delay);
+int mir3da_direction_remap(short *x, short *y, short *z, int direction);
+
+int mir3da_chip_resume(MIR_HANDLE handle);
+int mir3da_read_int_status(MIR_HANDLE handle);
+int mir3da_get_primary_offset(MIR_HANDLE handle, int *x, int *y, int *z);
+#endif /* __MIR3DA_CORE_H__ */
diff --git a/lichee/linux-3.10/drivers/input/sensor/mir3da_cust.c b/lichee/linux-3.10/drivers/input/sensor/mir3da_cust.c
new file mode 100755
index 0000000..c10bc1e
--- /dev/null
+++ b/lichee/linux-3.10/drivers/input/sensor/mir3da_cust.c
@@ -0,0 +1,1207 @@
+/* For AllWinner android platform.
+ *
+ * mir3da.c - Linux kernel modules for 3-Axis Accelerometer
+ *
+ * Copyright (C) 2011-2013 MiraMEMS Sensing Technology Co., Ltd.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/input-polldev.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/syscalls.h>
+#include <asm/uaccess.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+#include <linux/init-input.h>
+#include <linux/of_gpio.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/hwmon-vid.h>
+#include "mir3da_core.h"
+#include "mir3da_cust.h"
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_PM)
+#include <linux/pm.h>
+#endif
+
+#define MIR3DA_DRV_NAME                 	"da380"
+#define MIR3DA_INPUT_DEV_NAME     			MIR3DA_DRV_NAME
+#define MIR3DA_MISC_NAME                	MIR3DA_DRV_NAME
+
+#define POLL_INTERVAL_MAX               	500
+#define POLL_INTERVAL                   	50
+#define INPUT_FUZZ                      	0
+#define INPUT_FLAT                      	0
+
+static int wake_threshold = 10;
+/*static u32 int_handle = 0;*/
+static struct input_polled_dev *mir3da_idev;
+static struct device *hwmon_dev;
+static MIR_HANDLE mir_handle;
+static unsigned int slope_th;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static struct early_suspend early_suspend;
+#endif
+
+static unsigned int delayMs = 50;
+static unsigned char twi_id = 0;
+
+extern int Log_level;
+static int int2_enable = 0;
+static int int2_statu = 0;
+
+static const unsigned short normal_i2c[] = { 0x27, 0x26, I2C_CLIENT_END };
+
+static struct sensor_config_info gsensor_info = {
+	.input_type = GSENSOR_TYPE,
+};
+
+#define MI_DATA(format, ...)         	if(DEBUG_DATA&Log_level){printk(KERN_ERR MI_TAG format "n", ## __VA_ARGS__);}
+#define MI_MSG(format, ...)             if(DEBUG_MSG&Log_level){printk(KERN_ERR MI_TAG format "n", ## __VA_ARGS__);}
+#define MI_ERR(format, ...)             	if(DEBUG_ERR&Log_level){printk(KERN_ERR MI_TAG format "n", ## __VA_ARGS__);}
+#define MI_FUN                          	if(DEBUG_FUNC&Log_level){printk(KERN_ERR MI_TAG "%s is called, line: %dn", __FUNCTION__,__LINE__);}
+#define MI_ASSERT(expr)                 
+	if (!(expr)) {
+		printk(KERN_ERR "Assertion failed! %s,%d,%s,%sn",
+			__FILE__, __LINE__, __func__, #expr);
+	}
+
+/*----------------------------------------------------------------------------*/
+#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
+static char OffsetFileName[] = "/data/misc/miraGSensorOffset.txt";
+#define OFFSET_STRING_LEN               26
+struct work_info {
+	char tst1[20];
+	char tst2[20];
+	char buffer[OFFSET_STRING_LEN];
+	struct workqueue_struct *wq;
+	struct delayed_work read_work;
+	struct delayed_work write_work;
+	struct completion completion;
+	int len;
+	int rst;
+};
+
+static struct work_info m_work_info = { {0} };
+
+/*----------------------------------------------------------------------------*/
+static void sensor_write_work(struct work_struct *work)
+{
+	struct work_info *pWorkInfo;
+	struct file *filep;
+	u32 orgfs;
+	int ret;
+
+	orgfs = get_fs();
+	set_fs(KERNEL_DS);
+
+	pWorkInfo = container_of((struct delayed_work *)work, struct work_info, write_work);
+	if (pWorkInfo == NULL) {
+		MI_ERR("get pWorkInfo failed!");
+		return;
+	}
+
+	filep = filp_open(OffsetFileName, O_RDWR | O_CREAT, 0600);
+	if (IS_ERR(filep)) {
+		MI_ERR("write, sys_open %s error!!.n", OffsetFileName);
+		ret = -1;
+	} else {
+		filep->f_op->write(filep, pWorkInfo->buffer, pWorkInfo->len, &filep->f_pos);
+		filp_close(filep, NULL);
+		ret = 0;
+	}
+
+	set_fs(orgfs);
+	pWorkInfo->rst = ret;
+	complete(&pWorkInfo->completion);
+}
+
+/*----------------------------------------------------------------------------*/
+static void sensor_read_work(struct work_struct *work)
+{
+	u32 orgfs;
+	struct file *filep;
+	int ret;
+	struct work_info *pWorkInfo;
+
+	orgfs = get_fs();
+	set_fs(KERNEL_DS);
+
+	pWorkInfo = container_of((struct delayed_work *)work, struct work_info, read_work);
+	if (pWorkInfo == NULL) {
+		MI_ERR("get pWorkInfo failed!");
+		return;
+	}
+
+	filep = filp_open(OffsetFileName, O_RDONLY, 0600);
+	if (IS_ERR(filep)) {
+		MI_ERR("read, sys_open %s error!!.n", OffsetFileName);
+		set_fs(orgfs);
+		ret = -1;
+	} else {
+		filep->f_op->read(filep, pWorkInfo->buffer, sizeof(pWorkInfo->buffer), &filep->f_pos);
+		filp_close(filep, NULL);
+		set_fs(orgfs);
+		ret = 0;
+	}
+
+	pWorkInfo->rst = ret;
+	complete(&(pWorkInfo->completion));
+}
+
+/*----------------------------------------------------------------------------*/
+static int sensor_sync_read(u8 *offset)
+{
+	int err;
+	int off[MIR3DA_OFFSET_LEN] = { 0 };
+	struct work_info *pWorkInfo = &m_work_info;
+
+	init_completion(&pWorkInfo->completion);
+	queue_delayed_work(pWorkInfo->wq, &pWorkInfo->read_work, msecs_to_jiffies(0));
+	err = wait_for_completion_timeout(&pWorkInfo->completion, msecs_to_jiffies(2000));
+	if (err == 0) {
+		MI_ERR("wait_for_completion_timeout TIMEOUT");
+		return -1;
+	}
+
+	if (pWorkInfo->rst != 0) {
+		MI_ERR("work_info.rst  not equal 0");
+		return pWorkInfo->rst;
+	}
+
+	sscanf(m_work_info.buffer, "%x,%x,%x,%x,%x,%x,%x,%x,%x", &off[0], &off[1], &off[2], &off[3], &off[4], &off[5], &off[6], &off[7], &off[8]);
+
+	offset[0] = (u8) off[0];
+	offset[1] = (u8) off[1];
+	offset[2] = (u8) off[2];
+	offset[3] = (u8) off[3];
+	offset[4] = (u8) off[4];
+	offset[5] = (u8) off[5];
+	offset[6] = (u8) off[6];
+	offset[7] = (u8) off[7];
+	offset[8] = (u8) off[8];
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+static int sensor_sync_write(u8 *off)
+{
+	int err = 0;
+	struct work_info *pWorkInfo = &m_work_info;
+
+	init_completion(&pWorkInfo->completion);
+
+	sprintf(m_work_info.buffer, "%x,%x,%x,%x,%x,%x,%x,%x,%xn", off[0], off[1], off[2], off[3], off[4], off[5], off[6], off[7], off[8]);
+
+	pWorkInfo->len = sizeof(m_work_info.buffer);
+
+	queue_delayed_work(pWorkInfo->wq, &pWorkInfo->write_work, msecs_to_jiffies(0));
+	err = wait_for_completion_timeout(&pWorkInfo->completion, msecs_to_jiffies(2000));
+	if (err == 0) {
+		MI_ERR("wait_for_completion_timeout TIMEOUT");
+		return -1;
+	}
+
+	if (pWorkInfo->rst != 0) {
+		MI_ERR("work_info.rst  not equal 0");
+		return pWorkInfo->rst;
+	}
+
+	return 0;
+}
+#endif
+/*----------------------------------------------------------------------------*/
+#ifdef MIR3DA_AUTO_CALIBRAE
+static bool check_califile_exist(void)
+{
+	u32 orgfs = 0;
+	struct file *filep;
+
+	orgfs = get_fs();
+	set_fs(KERNEL_DS);
+
+	filep = filp_open(OffsetFileName, O_RDONLY, 0600);
+	if (IS_ERR(filep)) {
+		MI_MSG("%s read, sys_open %s error!!.n", __func__, OffsetFileName);
+		set_fs(orgfs);
+		return false;
+	}
+
+	filp_close(filep, NULL);
+	set_fs(orgfs);
+
+	return true;
+}
+#endif
+/*----------------------------------------------------------------------------*/
+static void report_abs(void)
+{
+	short x = 0, y = 0, z = 0;
+	MIR_HANDLE handle = mir_handle;
+
+	if (mir3da_read_data(handle, &x, &y, &z) != 0) {
+		MI_ERR("MIR3DA data read failed!n");
+		return;
+	}
+
+	input_report_abs(mir3da_idev->input, ABS_X, x);
+	input_report_abs(mir3da_idev->input, ABS_Y, y);
+	input_report_abs(mir3da_idev->input, ABS_Z, z);
+	input_sync(mir3da_idev->input);
+}
+
+/*----------------------------------------------------------------------------*/
+static void mir3da_dev_poll(struct input_polled_dev *dev)
+{
+	dev->poll_interval = delayMs;
+	report_abs();
+}
+
+/*----------------------------------------------------------------------------*/
+static long mir3da_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+	void __user *argp = (void __user *)arg;
+	int err = 0;
+	int interval = 0;
+	char bEnable = 0;
+
+	short xyz[3] = { 0 };
+	MIR_HANDLE handle = mir_handle;
+
+	if (_IOC_DIR(cmd) & _IOC_READ) {
+		err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
+	} else if (_IOC_DIR(cmd) & _IOC_WRITE) {
+		err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
+	}
+
+	if (err) {
+		return -EFAULT;
+	}
+
+	switch (cmd) {
+	case MIR3DA_ACC_IOCTL_GET_DELAY:
+		interval = POLL_INTERVAL;
+		if (copy_to_user(argp, &interval, sizeof(interval)))
+			return -EFAULT;
+		break;
+
+	case MIR3DA_ACC_IOCTL_SET_DELAY:
+		if (copy_from_user(&interval, argp, sizeof(interval)))
+			return -EFAULT;
+		if (interval < 0 || interval > 1000)
+			return -EINVAL;
+		if ((interval <= 30) && (interval > 10)) {
+			interval = 10;
+		}
+		delayMs = interval;
+		break;
+
+	case MIR3DA_ACC_IOCTL_SET_ENABLE:
+		if (copy_from_user(&bEnable, argp, sizeof(bEnable)))
+			return -EFAULT;
+
+		err = mir3da_set_enable(handle, bEnable);
+		if (err < 0)
+			return EINVAL;
+		break;
+
+	case MIR3DA_ACC_IOCTL_GET_ENABLE:
+		err = mir3da_get_enable(handle, &bEnable);
+		if (err < 0) {
+			return -EINVAL;
+		}
+
+		if (copy_to_user(argp, &bEnable, sizeof(bEnable)))
+			return -EINVAL;
+		break;
+
+#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
+	case MIR3DA_ACC_IOCTL_CALIBRATION:
+		if (copy_from_user(&z_dir, argp, sizeof(z_dir)))
+			return -EFAULT;
+
+		if (mir3da_calibrate(handle, z_dir)) {
+			return -EFAULT;
+		}
+
+		if (copy_to_user(argp, &z_dir, sizeof(z_dir)))
+			return -EFAULT;
+		break;
+
+	case MIR3DA_ACC_IOCTL_UPDATE_OFFSET:
+		manual_load_cali_file(handle);
+		break;
+#endif
+
+	case MIR3DA_ACC_IOCTL_GET_COOR_XYZ:
+
+		if (mir3da_read_data(handle, &xyz[0], &xyz[1], &xyz[2]))
+			return -EFAULT;
+
+		if (copy_to_user((void __user *)arg, xyz, sizeof(xyz)))
+			return -EFAULT;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+static const struct file_operations mir3da_misc_fops = {
+	.owner = THIS_MODULE,
+	.unlocked_ioctl = mir3da_misc_ioctl,
+};
+
+static struct miscdevice misc_mir3da = {
+	.minor = MISC_DYNAMIC_MINOR,
+	.name = MIR3DA_MISC_NAME,
+	.fops = &mir3da_misc_fops,
+};
+
+/*----------------------------------------------------------------------------*/
+static ssize_t mir3da_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	int ret;
+	char bEnable;
+	MIR_HANDLE handle = mir_handle;
+
+	ret = mir3da_get_enable(handle, &bEnable);
+	if (ret < 0) {
+		ret = -EINVAL;
+	} else {
+		ret = sprintf(buf, "%dn", bEnable);
+	}
+
+	return ret;
+}
+
+static int flags = 0;
+/*----------------------------------------------------------------------------*/
+static ssize_t mir3da_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	int ret;
+	char bEnable;
+	unsigned long enable;
+	MIR_HANDLE handle = mir_handle;
+
+	if (buf == NULL) {
+		return -1;
+	}
+
+	if (flags == 1)
+		return 0;
+
+	enable = simple_strtoul(buf, NULL, 10);
+	bEnable = (enable > 0) ? 1 : 0;
+
+	ret = mir3da_set_enable(handle, bEnable);
+	if (ret < 0) {
+		ret = -EINVAL;
+	} else {
+		ret = count;
+	}
+
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+static ssize_t mir3da_delay_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%dn", delayMs);
+}
+
+/*----------------------------------------------------------------------------*/
+static ssize_t mir3da_delay_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	int interval = 0;
+
+	interval = simple_strtoul(buf, NULL, 10);
+
+	if (interval < 0 || interval > 1000)
+		return -EINVAL;
+
+	if ((interval <= 30) && (interval > 10)) {
+		interval = 10;
+	}
+
+	delayMs = interval;
+
+	return count;
+}
+
+/*----------------------------------------------------------------------------*/
+static ssize_t mir3da_axis_data_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	int result;
+	short x, y, z;
+	int count = 0;
+	MIR_HANDLE handle = mir_handle;
+
+	result = mir3da_read_data(handle, &x, &y, &z);
+	if (result == 0)
+		count += sprintf(buf + count, "x= %d;y=%d;z=%dn", x, y, z);
+	else
+		count += sprintf(buf + count, "reading failed!");
+
+	return count;
+}
+
+/*----------------------------------------------------------------------------*/
+static ssize_t mir3da_reg_data_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	int addr, data;
+	int result;
+	MIR_HANDLE handle = mir_handle;
+
+	sscanf(buf, "0x%x, 0x%xn", &addr, &data);
+
+	result = mir3da_register_write(handle, addr, data);
+
+	MI_ASSERT(result == 0);
+
+	return count;
+}
+
+/*----------------------------------------------------------------------------*/
+static ssize_t mir3da_reg_data_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	MIR_HANDLE handle = mir_handle;
+
+	return mir3da_get_reg_data(handle, buf);
+}
+
+/*----------------------------------------------------------------------------*/
+#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
+static ssize_t mir3da_offset_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	ssize_t count = 0;
+	int rst = 0;
+	u8 off[9] = { 0 };
+	MIR_HANDLE handle = mir_handle;
+
+	rst = mir3da_read_offset(handle, off);
+	if (!rst) {
+		count = sprintf(buf, "%d,%d,%d,%d,%d,%d,%d,%d,%dn", off[0], off[1], off[2], off[3], off[4], off[5], off[6], off[7], off[8]);
+	}
+	return count;
+}
+
+/*----------------------------------------------------------------------------*/
+static ssize_t mir3da_offset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	int off[9] = { 0 };
+	u8 offset[9] = { 0 };
+	int rst = 0;
+	MIR_HANDLE handle = mir_handle;
+
+	sscanf(buf, "%d,%d,%d,%d,%d,%d,%d,%d,%dn", &off[0], &off[1], &off[2], &off[3], &off[4], &off[5], &off[6], &off[7], &off[8]);
+
+	offset[0] = (u8) off[0];
+	offset[1] = (u8) off[1];
+	offset[2] = (u8) off[2];
+	offset[3] = (u8) off[3];
+	offset[4] = (u8) off[4];
+	offset[5] = (u8) off[5];
+	offset[6] = (u8) off[6];
+	offset[7] = (u8) off[7];
+	offset[8] = (u8) off[8];
+
+	rst = mir3da_write_offset(handle, offset);
+	return count;
+}
+#endif
+
+static int int_status = 0;
+static ssize_t mir3da_status_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	int ret = 0;
+
+	ret = sprintf(buf, "%dn", int_status);
+	int_status = 0;
+	return ret;
+}
+
+static ssize_t mir3da_status_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	//int_status = simple_strtol(buf,NULL,10);
+	return count;
+}
+
+/*----------------------------------------------------------------------------*/
+#if FILTER_AVERAGE_ENHANCE
+static ssize_t mir3da_average_enhance_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	int ret = 0;
+	struct mir3da_filter_param_s param = { 0 };
+
+	ret = mir3da_get_filter_param(&param);
+	ret |= sprintf(buf, "%d %d %dn", param.filter_param_l, param.filter_param_h, param.filter_threhold);
+
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+static ssize_t mir3da_average_enhance_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	int ret = 0;
+	struct mir3da_filter_param_s param = { 0 };
+
+	sscanf(buf, "%d %d %dn", &param.filter_param_l, &param.filter_param_h, &param.filter_threhold);
+
+	ret = mir3da_set_filter_param(&param);
+
+	return count;
+}
+#endif
+/*----------------------------------------------------------------------------*/
+#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
+int bCaliResult = -1;
+static ssize_t mir3da_calibrate_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	int ret;
+
+	ret = sprintf(buf, "%dn", bCaliResult);
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+static ssize_t mir3da_calibrate_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	s8 z_dir = 0;
+	MIR_HANDLE handle = mir_handle;
+
+	z_dir = simple_strtol(buf, NULL, 10);
+	bCaliResult = mir3da_calibrate(handle, z_dir);
+
+	return count;
+}
+#endif
+/*----------------------------------------------------------------------------*/
+static ssize_t mir3da_log_level_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	int ret;
+
+	ret = sprintf(buf, "%dn", Log_level);
+
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+static ssize_t mir3da_log_level_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	Log_level = simple_strtoul(buf, NULL, 10);
+
+	return count;
+}
+
+static int mir3da_int2_set_onoff(struct device *dev, int onoff)
+{
+	int res = 0;
+	MIR_HANDLE handle = mir_handle;
+	int2_enable = onoff;
+	MI_ERR("mir3da_int2_enable_store num:%d onoff:%d slope 0x%xn", MIR3DA_TYPE, onoff, slope_th);
+	res |= mir3da_register_mask_write(handle, NSA_REG_INT_LATCH, 0x8F, slope_th);
+	// 83 1s 84 2s 85 4s  86 8s  8f 
+	res |= mir3da_register_mask_write(handle, NSA_REG_ACTIVE_DURATION, 0xff, 0x03);
+	res |= mir3da_register_mask_write(handle, NSA_REG_ACTIVE_THRESHOLD, 0xff, wake_threshold);
+	if (onoff) {
+		res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_SETTINGS1, 0xff, 0x03);
+		switch (MIR3DA_TYPE) {
+
+		case 0:
+			res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING1, 0xff, 0x04);
+			break;
+
+		case 1:
+			res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING3, 0xff, 0x04);
+			break;
+		}
+	} else {
+		res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_SETTINGS1, 0xff, 0x00);
+		res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING1, 0xff, 0x00);
+		res |= mir3da_register_mask_write(handle, NSA_REG_INTERRUPT_MAPPING3, 0xff, 0x00);
+	}
+	return 0;
+}
+
+static ssize_t mir3da_int2_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	int2_enable = simple_strtoul(buf, NULL, 10);
+
+	mir3da_int2_set_onoff(dev, int2_enable);
+
+	return count;
+}
+
+static ssize_t mir3da_int2_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	int ret;
+
+	ret = sprintf(buf, "%dn", int2_enable);
+	printk(" mir3da_int2_enable_show ret [ %d ]n", ret);
+	return ret;
+}
+
+static ssize_t mir3da_int2_clear_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+
+	MIR_HANDLE handle = mir_handle;
+
+	printk(" mir3da_int2_clear_enable_store int2_clean n");
+	mir3da_clear_intterrupt(handle);
+
+	return count;
+}
+
+static ssize_t mir3da_wake_threshold_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	int ret;
+
+	ret = sprintf(buf, "%dn", wake_threshold);
+	printk(" wake_threshold [ %d ]n", wake_threshold);
+	return ret;
+}
+
+static ssize_t mir3da_wake_threshold_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	wake_threshold = simple_strtoul(buf, NULL, 10);
+
+	if (wake_threshold < 0)
+		wake_threshold = 0;
+	if (wake_threshold > 250)
+		wake_threshold = 250;
+
+	printk(" wake_threshold [ %d ]n", wake_threshold);
+	return count;
+}
+
+static ssize_t mir3da_int2_clear_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	int ret = 0;
+
+	//ret = sprintf(buf, "%dn", int2_enable);
+	//printk(" mir3da_int2_clear_enable_show ret [ %d ]n",ret);
+	return ret;
+}
+
+static ssize_t mir3da_int2_start_statu_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+
+	//MIR_HANDLE      handle = mir_handle;
+
+	int2_statu = simple_strtoul(buf, NULL, 10);
+
+	return count;
+}
+
+static ssize_t mir3da_int2_start_statu_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	int ret;
+	//MIR_HANDLE      handle = mir_handle;
+
+	//int2_statu =  mir3da_read_int_status( handle);
+
+	ret = sprintf(buf, "%dn", int2_statu);
+	printk(" mir3da_int2_enable_show ret [ %d ]n", ret);
+	return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+static ssize_t mir3da_primary_offset_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	MIR_HANDLE handle = mir_handle;
+	int x = 0, y = 0, z = 0;
+
+	mir3da_get_primary_offset(handle, &x, &y, &z);
+
+	return sprintf(buf, "x=%d ,y=%d ,z=%dn", x, y, z);
+
+}
+
+/*----------------------------------------------------------------------------*/
+static ssize_t mir3da_version_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+
+	return sprintf(buf, "%s_%sn", DRI_VER, CORE_VER);
+}
+
+/*----------------------------------------------------------------------------*/
+static ssize_t mir3da_vendor_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "%sn", "MiraMEMS");
+}
+
+static ssize_t mir3da_slope_th_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "0x%xn", slope_th);
+}
+
+static ssize_t mir3da_slope_th_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	unsigned long data;
+	int error = 0;
+	error = strict_strtoul(buf, 16, &data);
+	if (error)
+		return error;
+	if (data == 0x3) {	//high
+		data = 0x84;
+	} else if (data == 0xf) {	//low
+		data = 0x86;
+	} else if (data == 0x5) {	//mid
+		data = 0x85;
+	}
+	printk("set slope 0x%lxn", data);
+	slope_th = data;
+	return count;
+}
+
+/*----------------------------------------------------------------------------*/
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUGO, mir3da_enable_show, mir3da_enable_store);
+static DEVICE_ATTR(delay, S_IRUGO | S_IWUGO, mir3da_delay_show, mir3da_delay_store);
+static DEVICE_ATTR(axis_data, S_IRUGO | S_IWUGO, mir3da_axis_data_show, NULL);
+static DEVICE_ATTR(reg_data, S_IWUGO | S_IRUGO, mir3da_reg_data_show, mir3da_reg_data_store);
+static DEVICE_ATTR(log_level, S_IWUGO | S_IRUGO, mir3da_log_level_show, mir3da_log_level_store);
+#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
+static DEVICE_ATTR(offset, S_IWUGO | S_IRUGO, mir3da_offset_show, mir3da_offset_store);
+static DEVICE_ATTR(calibrate_miraGSensor, S_IWUGO | S_IRUGO, mir3da_calibrate_show, mir3da_calibrate_store);
+#endif
+#ifdef FILTER_AVERAGE_ENHANCE
+static DEVICE_ATTR(average_enhance, S_IWUGO | S_IRUGO, mir3da_average_enhance_show, mir3da_average_enhance_store);
+#endif
+// aad cz
+static DEVICE_ATTR(int2_enable, S_IRUGO | S_IWUGO, mir3da_int2_enable_show, mir3da_int2_enable_store);
+static DEVICE_ATTR(int2_clear, S_IRUGO | S_IWUGO, mir3da_int2_clear_enable_show, mir3da_int2_clear_enable_store);
+static DEVICE_ATTR(int2_start_status, S_IRUGO | S_IWUGO, mir3da_int2_start_statu_show, mir3da_int2_start_statu_store);
+
+static DEVICE_ATTR(threshold, S_IRUGO | S_IWUGO, mir3da_wake_threshold_show, mir3da_wake_threshold_store);
+static DEVICE_ATTR(status, S_IRUGO | S_IWUGO, mir3da_status_show, mir3da_status_store);
+static DEVICE_ATTR(primary_offset, S_IWUGO, mir3da_primary_offset_show, NULL);
+static DEVICE_ATTR(version, S_IRUGO, mir3da_version_show, NULL);
+static DEVICE_ATTR(vendor, S_IRUGO, mir3da_vendor_show, NULL);
+static DEVICE_ATTR(slope_th, S_IRUGO | S_IWUGO, mir3da_slope_th_show, mir3da_slope_th_store);
+
+/*----------------------------------------------------------------------------*/
+static struct attribute *mir3da_attributes[] = {
+	&dev_attr_enable.attr,
+	&dev_attr_delay.attr,
+	&dev_attr_axis_data.attr,
+	&dev_attr_reg_data.attr,
+	&dev_attr_log_level.attr,
+#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
+	&dev_attr_offset.attr,
+	&dev_attr_calibrate_miraGSensor.attr,
+//  &dev_attr_primary_offset.attr,
+#endif
+#ifdef FILTER_AVERAGE_ENHANCE
+	&dev_attr_average_enhance.attr,
+#endif /* ! FILTER_AVERAGE_ENHANCE */
+	&dev_attr_int2_enable.attr,
+	&dev_attr_int2_clear.attr,
+	&dev_attr_int2_start_status.attr,
+	&dev_attr_threshold.attr,
+	&dev_attr_status.attr,
+	&dev_attr_primary_offset.attr,
+	&dev_attr_version.attr,
+	&dev_attr_vendor.attr,
+	&dev_attr_slope_th.attr,
+	NULL
+};
+
+static const struct attribute_group mir3da_attr_group = {
+	.attrs = mir3da_attributes,
+};
+
+/*----------------------------------------------------------------------------*/
+int i2c_smbus_read(PLAT_HANDLE handle, u8 addr, u8 * data)
+{
+	int res = 0;
+	struct i2c_client *client = (struct i2c_client *)handle;
+
+	*data = i2c_smbus_read_byte_data(client, addr);
+
+	return res;
+}
+
+/*----------------------------------------------------------------------------*/
+int i2c_smbus_read_block(PLAT_HANDLE handle, u8 addr, u8 count, u8 * data)
+{
+	int res = 0;
+	struct i2c_client *client = (struct i2c_client *)handle;
+
+	res = i2c_smbus_read_i2c_block_data(client, addr, count, data);
+
+	return res;
+}
+
+/*----------------------------------------------------------------------------*/
+int i2c_smbus_write(PLAT_HANDLE handle, u8 addr, u8 data)
+{
+	int res = 0;
+	struct i2c_client *client = (struct i2c_client *)handle;
+
+	res = i2c_smbus_write_byte_data(client, addr, data);
+
+	return res;
+}
+
+/*----------------------------------------------------------------------------*/
+void msdelay(int ms)
+{
+	mdelay(ms);
+}
+
+#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
+MIR_GENERAL_OPS_DECLARE(ops_handle, i2c_smbus_read, i2c_smbus_read_block, i2c_smbus_write, sensor_sync_write, sensor_sync_read, msdelay, printk, sprintf);
+#else
+MIR_GENERAL_OPS_DECLARE(ops_handle, i2c_smbus_read, i2c_smbus_read_block, i2c_smbus_write, NULL, NULL, msdelay, printk, sprintf);
+#endif
+/*----------------------------------------------------------------------------*/
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void mir3da_early_suspend(struct early_suspend *h)
+{
+	MIR_HANDLE handle = mir_handle;
+	MI_FUN;
+	flags = 1;
+#if 1
+	mir3da_register_write(handle, NSA_REG_POWERMODE_BW, 0x0E);
+	mir3da_register_write(handle, NSA_REG_INT_PIN_CONFIG, 0x05);
+	mir3da_register_write(handle, NSA_REG_INT_LATCH, slope_th);
+	mir3da_register_write(handle, NSA_REG_INTERRUPT_SETTINGS1, 0x03);
+	mir3da_register_write(handle, NSA_REG_ACTIVE_DURATION, 0x03);
+	mir3da_register_write(handle, NSA_REG_ACTIVE_THRESHOLD, wake_threshold);
+	mir3da_register_write(handle, NSA_REG_INTERRUPT_MAPPING1, 0x04);
+#endif
+	printk("=============== mir3da early suspend======================000===n");
+	//mir3da_set_enable(handle, 0);
+	mir3da_idev->input->close(mir3da_idev->input);
+}
+
+static void mir3da_late_resume(struct early_suspend *h)
+{
+	//MIR_HANDLE handle = mir_handle;
+	MI_FUN;
+	printk("=============== mir3da early resume=========================n");
+	//mir3da_chip_resume(handle);
+	//mir3da_set_enable(handle, 1);
+	mir3da_int2_set_onoff(NULL, 0);
+	mir3da_idev->input->open(mir3da_idev->input);
+	flags = 0;
+}
+#else
+/*----------------------------------------------------------------------------*/
+static int mir3da_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+	int result = 0;
+	MIR_HANDLE handle = mir_handle;
+
+	MI_FUN;
+
+	printk(KERN_ERR "=============== mir3da  suspend=========================n");
+	result = mir3da_set_enable(handle, 0);
+	if (result) {
+		MI_ERR("%s:set disable fail!!n", __func__);
+		return result;
+	}
+	mir3da_idev->input->close(mir3da_idev->input);
+
+	return result;
+}
+
+/*----------------------------------------------------------------------------*/
+static int mir3da_resume(struct i2c_client *client)
+{
+	int result = 0;
+	MIR_HANDLE handle = mir_handle;
+
+	MI_FUN;
+	printk(KERN_ERR "=============== mir3da  resume=========================n");
+
+	result = mir3da_chip_resume(handle);
+	if (result) {
+		MI_ERR("%s:chip resume fail!!n", __func__);
+		return result;
+	}
+
+	result = mir3da_set_enable(handle, 1);
+	if (result) {
+		MI_ERR("%s:set enable fail!!n", __func__);
+		return result;
+	}
+
+	mir3da_idev->input->open(mir3da_idev->input);
+
+	return result;
+}
+
+/*----------------------------------------------------------------------------*/
+
+#endif
+
+/*static u32 gsensor_irq_func(int irq, void *para)
+{
+	printk("[haibo] mir gsensor into irq funcn");
+	int_status = 1;
+	return 0;
+}*/
+
+static int mir3da_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+	int result = 0;
+	/*int ret;*/
+	struct input_dev *idev;
+	if (mir3da_install_general_ops(&ops_handle)) {
+		MI_ERR("Install ops failed !n");
+		goto err_detach_client;
+	}
+#ifdef MIR3DA_OFFSET_TEMP_SOLUTION
+	m_work_info.wq = create_singlethread_workqueue("oo");
+	if (NULL == m_work_info.wq) {
+		MI_ERR("Failed to create workqueue !");
+		goto err_detach_client;
+	}
+
+	INIT_DELAYED_WORK(&m_work_info.read_work, sensor_read_work);
+	INIT_DELAYED_WORK(&m_work_info.write_work, sensor_write_work);
+#endif
+
+	int2_statu = mir3da_read_int_status((PLAT_HANDLE) client);
+	printk("ParkMonitor powerOn status is %dn", int2_statu);
+
+	/* Initialize the MIR3DA chip */
+	mir_handle = mir3da_core_init((PLAT_HANDLE) client);
+	if (NULL == mir_handle) {
+		MI_ERR("chip init failed !n");
+		goto err_detach_client;
+	}
+
+	hwmon_dev = hwmon_device_register(&client->dev);
+	MI_ASSERT(!(IS_ERR(hwmon_dev)));
+
+	/* input poll device register */
+	mir3da_idev = input_allocate_polled_device();
+	if (!mir3da_idev) {
+		MI_ERR("alloc poll device failed!n");
+		result = -ENOMEM;
+		goto err_hwmon_device_unregister;
+	}
+	mir3da_idev->poll = mir3da_dev_poll;
+	mir3da_idev->poll_interval = POLL_INTERVAL;
+	delayMs = POLL_INTERVAL;
+	mir3da_idev->poll_interval_max = POLL_INTERVAL_MAX;
+	idev = mir3da_idev->input;
+
+	idev->name = MIR3DA_INPUT_DEV_NAME;
+	idev->id.bustype = BUS_I2C;
+	idev->evbit[0] = BIT_MASK(EV_ABS);
+
+	input_set_abs_params(idev, ABS_X, -16384, 16383, INPUT_FUZZ, INPUT_FLAT);
+	input_set_abs_params(idev, ABS_Y, -16384, 16383, INPUT_FUZZ, INPUT_FLAT);
+	input_set_abs_params(idev, ABS_Z, -16384, 16383, INPUT_FUZZ, INPUT_FLAT);
+
+	result = input_register_polled_device(mir3da_idev);
+	if (result) {
+		MI_ERR("register poll device failed!n");
+		goto err_free_polled_device;
+	}
+
+	/*int_handle = gpio_to_irq(gsensor_info.irq_gpio.gpio);
+	ret = request_irq(int_handle, gsensor_irq_func, IRQF_NO_SUSPEND | IRQF_TRIGGER_RISING, "sensor da380", NULL);
+	if (IS_ERR_VALUE(ret)) {
+		printk("[haibo] mir gsensor request irq failed!n");
+		goto err_unregister_polled_device;
+	}*/
+
+	/* Sys Attribute Register */
+	result = sysfs_create_group(&idev->dev.kobj, &mir3da_attr_group);
+	if (result) {
+		MI_ERR("create device file failed!n");
+		result = -EINVAL;
+		goto err_unregister_polled_device;
+	}
+
+	/* Misc device interface Register */
+	result = misc_register(&misc_mir3da);
+	if (result) {
+		MI_ERR("%s: mir3da_dev register failed", __func__);
+		goto err_remove_sysfs_group;
+	}
+	slope_th = 0x83;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+	early_suspend.suspend = mir3da_early_suspend;
+	early_suspend.resume = mir3da_late_resume;
+	register_early_suspend(&early_suspend);
+#endif
+	return result;
+
+err_remove_sysfs_group:
+	sysfs_remove_group(&idev->dev.kobj, &mir3da_attr_group);
+err_unregister_polled_device:
+	/*free_irq(gsensor_info.irq_gpio.gpio, NULL);*/
+	input_unregister_polled_device(mir3da_idev);
+err_free_polled_device:
+	input_free_polled_device(mir3da_idev);
+err_hwmon_device_unregister:
+	hwmon_device_unregister(&client->dev);
+err_detach_client:
+	return result;
+}
+
+/*----------------------------------------------------------------------------*/
+static int mir3da_remove(struct i2c_client *client)
+{
+	MIR_HANDLE handle = mir_handle;
+
+	mir3da_set_enable(handle, 0);
+
+	misc_deregister(&misc_mir3da);
+
+	sysfs_remove_group(&mir3da_idev->input->dev.kobj, &mir3da_attr_group);
+
+	input_unregister_polled_device(mir3da_idev);
+
+	input_free_polled_device(mir3da_idev);
+
+#ifdef  MIR3DA_OFFSET_TEMP_SOLUTION
+	flush_workqueue(m_work_info.wq);
+	destroy_workqueue(m_work_info.wq);
+#endif
+
+	hwmon_device_unregister(hwmon_dev);
+
+	return 0;
+}
+
+static int mir3da_detect(struct i2c_client *new_client, struct i2c_board_info *info)
+{
+	struct i2c_adapter *adapter = new_client->adapter;
+
+	MI_MSG("%s:bus[%d] addr[0x%x]n", __func__, adapter->nr, new_client->addr);
+
+	printk(" richard mir3da_detect: %s:bus[%d] addr[0x%x]n", __func__, adapter->nr, new_client->addr);
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	if (twi_id == adapter->nr) {
+		if (mir3da_install_general_ops(&ops_handle)) {
+			MI_ERR("Install ops failed !n");
+			return -ENODEV;
+		}
+		if (mir3da_module_detect((PLAT_HANDLE) new_client)) {
+			MI_ERR("Can't find Mir3da gsensor!!");
+		} else {
+			MI_ERR("'Find Mir3da gsensor!!");
+			strlcpy(info->type, MIR3DA_DRV_NAME, I2C_NAME_SIZE);
+			return 0;
+		}
+	}
+
+	return -ENODEV;
+}
+
+static int gsensor_fetch_sysconfig_para(void)
+{
+	if (input_fetch_sysconfig_para(&(gsensor_info.input_type))) {
+		printk("%s: err.n", __func__);
+		return -1;
+	} else
+		twi_id = gsensor_info.twi_id;
+
+	return 0;
+}
+
+static const struct i2c_device_id mir3da_id[] = {
+	{MIR3DA_DRV_NAME, 0},
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, mir3da_id);
+static struct i2c_driver mir3da_driver = {
+	.class = I2C_CLASS_HWMON,
+	.driver = {
+		   .name = MIR3DA_DRV_NAME,
+		   .owner = THIS_MODULE,
+		   },
+
+	.probe = mir3da_probe,
+#ifndef CONFIG_HAS_EARLYSUSPEND
+	.suspend = mir3da_suspend,
+	.resume = mir3da_resume,
+#endif
+	.detect = mir3da_detect,
+	.remove = mir3da_remove,
+	.id_table = mir3da_id,
+	.address_list = normal_i2c,
+};
+
+/*----------------------------------------------------------------------------*/
+static int __init mir3da_init(void)
+{
+	int ret;
+
+	MI_FUN;
+
+	if (gsensor_fetch_sysconfig_para()) {
+		MI_ERR("fetch_sysconfig_para failed!n");
+		return -1;
+	}
+	printk("step4 : mir3da_initn");
+
+	if (gsensor_info.sensor_used == 0) {
+		MI_ERR("*** gsensor_used set to 0 !n");
+		return -1;
+	}
+
+	ret = i2c_add_driver(&mir3da_driver);
+	if (ret < 0) {
+		MI_ERR("add mir3da i2c driver failedn");
+		return -ENODEV;
+	}
+
+	return (ret);
+}
+
+/*----------------------------------------------------------------------------*/
+static void __exit mir3da_exit(void)
+{
+	MI_FUN;
+
+	i2c_del_driver(&mir3da_driver);
+}
+
+/*----------------------------------------------------------------------------*/
+MODULE_AUTHOR("MiraMEMS <lschen@miramems.com>");
+MODULE_DESCRIPTION("MIR3DA 3-Axis Accelerometer driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+
+module_init(mir3da_init);
+module_exit(mir3da_exit);
diff --git a/lichee/linux-3.10/drivers/input/sensor/mir3da_cust.h b/lichee/linux-3.10/drivers/input/sensor/mir3da_cust.h
new file mode 100755
index 0000000..5231a52
--- /dev/null
+++ b/lichee/linux-3.10/drivers/input/sensor/mir3da_cust.h
@@ -0,0 +1,42 @@
+/* For AllWinner android platform.
+ *
+ * mir3da.h - Linux kernel modules for 3-Axis Accelerometer
+ *
+ * Copyright (C) 2011-2013 MiraMEMS Sensing Technology Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 0x26<-> SD0=GND;0x27<-> SD0=High
+ */
+
+#ifndef __MIR3DA_STANDARD_H__
+#define __MIR3DA_STANDARD_H__
+
+#include <linux/ioctl.h>
+
+#define DRI_VER                  		        "1.0"
+
+#define MIR3DA_I2C_ADDR		                    0x27
+
+#define MIR3DA_ACC_IOCTL_BASE                   88
+#define IOCTL_INDEX_BASE                        0x00
+
+#define MIR3DA_ACC_IOCTL_SET_DELAY              _IOW(MIR3DA_ACC_IOCTL_BASE, IOCTL_INDEX_BASE, int)
+#define MIR3DA_ACC_IOCTL_GET_DELAY              _IOR(MIR3DA_ACC_IOCTL_BASE, IOCTL_INDEX_BASE+1, int)
+#define MIR3DA_ACC_IOCTL_SET_ENABLE             _IOW(MIR3DA_ACC_IOCTL_BASE, IOCTL_INDEX_BASE+2, int)
+#define MIR3DA_ACC_IOCTL_GET_ENABLE             _IOR(MIR3DA_ACC_IOCTL_BASE, IOCTL_INDEX_BASE+3, int)
+#define MIR3DA_ACC_IOCTL_SET_G_RANGE            _IOW(MIR3DA_ACC_IOCTL_BASE, IOCTL_INDEX_BASE+4, int)
+#define MIR3DA_ACC_IOCTL_GET_G_RANGE            _IOR(MIR3DA_ACC_IOCTL_BASE, IOCTL_INDEX_BASE+5, int)
+
+#define MIR3DA_ACC_IOCTL_GET_COOR_XYZ           _IOW(MIR3DA_ACC_IOCTL_BASE, IOCTL_INDEX_BASE+22, int)
+#define MIR3DA_ACC_IOCTL_CALIBRATION            _IOW(MIR3DA_ACC_IOCTL_BASE, IOCTL_INDEX_BASE+23, int)
+#define MIR3DA_ACC_IOCTL_UPDATE_OFFSET     	    _IOW(MIR3DA_ACC_IOCTL_BASE, IOCTL_INDEX_BASE+24, int)
+
+#endif /* !__MIR3DA_STANDARD_H__ */
diff --git a/lichee/tools/pack/chips/sun8iw11p1/configs/t3-p1/sys_config.fex b/lichee/tools/pack/chips/sun8iw11p1/configs/t3-p1/sys_config.fex
index 04e8d89..18c23d9 100755
--- a/lichee/tools/pack/chips/sun8iw11p1/configs/t3-p1/sys_config.fex
+++ b/lichee/tools/pack/chips/sun8iw11p1/configs/t3-p1/sys_config.fex
@@ -300,7 +300,7 @@ twi1_scl         = port:PB18<2><default><default><default>
 twi1_sda         = port:PB19<2><default><default><default>
 
 [twi2]
-twi2_used        = 0
+twi2_used        = 1
 twi2_scl         = port:PB20<2><default><default><default>
 twi2_sda         = port:PB21<2><default><default><default>
 
@@ -1228,12 +1228,19 @@ usb_wakeup_suspend  = 0
 ; G sensor configuration
 ; gs_twi_id	---  TWI ID for controlling Gsensor (0: TWI0, 1: TWI1, 2: TWI2)
 ;--------------------------------------------------------------------------------
-[gsensor_para]
-gsensor_used        = 0
-gsensor_twi_id      = 2
-gsensor_twi_addr    = 0x18
-gsensor_int1        = port:PA09<6><1><default><default>
-gsensor_int2        =
+[gsensor]
+compatible = "allwinner,sun50i-gsensor-para"
+gsensor_used = 1
+gsensor_twi_id = 2
+gsensor_twi_addr = 0x27
+gsensor_int1  = port:PH26<0><1><default><1>
+;gsensor_int1 = port:power1<6><default><default><default>
+gsensor_int2 =
+
+[gsensor_list]
+compatible = "allwinner,sun50i-gsensor-list-para"
+gsensor_list__used = 1
+da380 = 1
 
 ;--------------------------------------------------------------------------------
 ; gps gpio configuration

最后

以上就是含糊路灯为你收集整理的全志 添加Gsensor da380 module Patch的全部内容,希望文章能够帮你解决全志 添加Gsensor da380 module Patch所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部