概述
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, ®_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(¶m);
- 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", ¶m.filter_param_l, ¶m.filter_param_h, ¶m.filter_threhold);
-
- ret = mir3da_set_filter_param(¶m);
-
- 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, ®_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(¶m);
+ 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", ¶m.filter_param_l, ¶m.filter_param_h, ¶m.filter_threhold);
+
+ ret = mir3da_set_filter_param(¶m);
+
+ 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所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复