diff options
Diffstat (limited to 'drivers/input/sensor/mc3230_gsensor')
-rwxr-xr-x | drivers/input/sensor/mc3230_gsensor/Makefile | 34 | ||||
-rwxr-xr-x | drivers/input/sensor/mc3230_gsensor/mc32x0.c | 2580 | ||||
-rwxr-xr-x | drivers/input/sensor/mc3230_gsensor/mc32x0_driver.c | 505 | ||||
-rwxr-xr-x | drivers/input/sensor/mc3230_gsensor/mc32x0_driver.h | 219 |
4 files changed, 3338 insertions, 0 deletions
diff --git a/drivers/input/sensor/mc3230_gsensor/Makefile b/drivers/input/sensor/mc3230_gsensor/Makefile new file mode 100755 index 00000000..8a419fc7 --- /dev/null +++ b/drivers/input/sensor/mc3230_gsensor/Makefile @@ -0,0 +1,34 @@ +KERNELDIR=../../../../
+#KERNELDIR=/home/hangyan/android8850/kernel/ANDROID_3.0.8
+CROSS = arm_1103_le-
+CC= $(CROSS)gcc
+LD= $(CROSS)ld
+STRIP = $(CROSS)strip
+
+DEBUG = n
+
+# Add your debugging flag (or not) to EXTRA_CFLAGS
+ifeq ($(DEBUG),y)
+# DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines
+DEBFLAGS = -O0 -g -DSCULL_DEBUG # "-O" is needed to expand inlines
+
+else
+ DEBFLAGS = -O2 -Wall
+endif
+
+EXTRA_CFLAGS += $(DEBFLAGS)
+
+
+MY_MODULE_NAME=s_wmt_gsensor_mc3230
+
+obj-m := $(MY_MODULE_NAME).o
+$(MY_MODULE_NAME)-objs := mc32x0.o
+
+default:
+ $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules
+ $(STRIP) --strip-debug $(MY_MODULE_NAME).ko
+ rm -rf *.o *~ core .depend .*.cmd *.mod.c .tmp_versions
+
+clean:
+ rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.order *.symvers
+
diff --git a/drivers/input/sensor/mc3230_gsensor/mc32x0.c b/drivers/input/sensor/mc3230_gsensor/mc32x0.c new file mode 100755 index 00000000..4330dbb6 --- /dev/null +++ b/drivers/input/sensor/mc3230_gsensor/mc32x0.c @@ -0,0 +1,2580 @@ +/* Date: 2011/4/8 11:00:00
+ * Revision: 2.5
+ */
+
+/*
+ * This software program is licensed subject to the GNU General Public License
+ * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html
+
+ * (C) Copyright 2011 Bosch Sensortec GmbH
+ * All Rights Reserved
+ */
+
+
+/* file mc32x0.c
+ brief This file contains all function implementations for the mc32x0 in linux
+
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+//#include <linux/earlysuspend.h>
+#include <linux/delay.h>
+#include <asm/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+
+//#include <linux/init-input.h>
+#include <mach/hardware.h>
+#include <linux/fs.h>
+
+#include "../sensor.h"
+#include "mc32x0_driver.h"
+
+
+#if 0
+#define mcprintkreg(x...) printk(x)
+#else
+#define mcprintkreg(x...)
+#endif
+
+#if 0
+#define mcprintkfunc(x...) printk(x)
+#else
+#define mcprintkfunc(x...)
+#endif
+
+#if 0
+#define GSE_ERR(x...) printk(x)
+#define GSE_LOG(x...) printk(x)
+#else
+#define GSE_ERR(x...)
+#define GSE_LOG(x...)
+#endif
+
+static int g_virtual_z = 0;
+#define G_2_REVERSE_VIRTUAL_Z 0 //!!!!! 1
+#define SUPPORT_VIRTUAL_Z_SENSOR //add 2013-10-23
+#define LOW_RESOLUTION 1
+#define HIGH_RESOLUTION 2
+#define RBM_RESOLUTION 3
+#ifdef SUPPORT_VIRTUAL_Z_SENSOR
+#define Low_Pos_Max 127
+#define Low_Neg_Max -128
+#define High_Pos_Max 8191
+#define High_Neg_Max -8192
+#define VIRTUAL_Z 1
+static int Railed = 0;
+#else
+#define VIRTUAL_Z 0
+#endif
+
+
+static struct class* l_dev_class = NULL;
+
+
+
+
+#define GSENSOR_NAME "mc3230"
+#define SENSOR_DATA_SIZE 3
+#define AVG_NUM 16
+/* Addresses to scan */
+//static const unsigned short normal_i2c[2] = {0x00,I2C_CLIENT_END};
+
+
+//volatile unsigned char mc32x0_on_off=0;
+//static int mc32x0_pin_hd;
+static char mc32x0_on_off_str[32];
+#define G_0 ABS_X
+#define G_1 ABS_Y
+#define G_2 ABS_Z
+#define G_0_REVERSE 1
+#define G_1_REVERSE 1
+#define G_2_REVERSE -1
+
+#define GRAVITY_1G_VALUE 1000
+
+#define SENSOR_DMARD_IOCTL_BASE 234
+
+#define IOCTL_SENSOR_SET_DELAY_ACCEL _IO(SENSOR_DMARD_IOCTL_BASE, 100)
+#define IOCTL_SENSOR_GET_DELAY_ACCEL _IO(SENSOR_DMARD_IOCTL_BASE, 101)
+#define IOCTL_SENSOR_GET_STATE_ACCEL _IO(SENSOR_DMARD_IOCTL_BASE, 102)
+#define IOCTL_SENSOR_SET_STATE_ACCEL _IO(SENSOR_DMARD_IOCTL_BASE, 103)
+#define IOCTL_SENSOR_GET_DATA_ACCEL _IO(SENSOR_DMARD_IOCTL_BASE, 104)
+
+#define IOCTL_MSENSOR_SET_DELAY_MAGNE _IO(SENSOR_DMARD_IOCTL_BASE, 200)
+#define IOCTL_MSENSOR_GET_DATA_MAGNE _IO(SENSOR_DMARD_IOCTL_BASE, 201)
+#define IOCTL_MSENSOR_GET_STATE_MAGNE _IO(SENSOR_DMARD_IOCTL_BASE, 202)
+#define IOCTL_MSENSOR_SET_STATE_MAGNE _IO(SENSOR_DMARD_IOCTL_BASE, 203)
+
+#define IOCTL_SENSOR_GET_NAME _IO(SENSOR_DMARD_IOCTL_BASE, 301)
+#define IOCTL_SENSOR_GET_VENDOR _IO(SENSOR_DMARD_IOCTL_BASE, 302)
+
+#define IOCTL_SENSOR_GET_CONVERT_PARA _IO(SENSOR_DMARD_IOCTL_BASE, 401)
+
+#define SENSOR_CALIBRATION _IOWR(SENSOR_DMARD_IOCTL_BASE, 402, int[SENSOR_DATA_SIZE])
+
+
+#define mc32x0_CONVERT_PARAMETER (1.5f * (9.80665f) / 256.0f)
+//#define mc32x0_DISPLAY_NAME "mc32x0"
+//#define mc32x0_DIPLAY_VENDOR "domintech"
+
+#define X_OUT 0x41
+#define CONTROL_REGISTER 0x44
+#define SW_RESET 0x53
+#define WHO_AM_I 0x0f
+#define WHO_AM_I_VALUE 0x06
+
+#define MC32X0_AXIS_X 0
+#define MC32X0_AXIS_Y 1
+#define MC32X0_AXIS_Z 2
+#define MC32X0_AXES_NUM 3
+#define MC32X0_DATA_LEN 6
+
+#define MC32X0_XOUT_REG 0x00
+#define MC32X0_YOUT_REG 0x01
+#define MC32X0_ZOUT_REG 0x02
+#define MC32X0_Tilt_Status_REG 0x03
+#define MC32X0_Sampling_Rate_Status_REG 0x04
+#define MC32X0_Sleep_Count_REG 0x05
+#define MC32X0_Interrupt_Enable_REG 0x06
+#define MC32X0_Mode_Feature_REG 0x07
+#define MC32X0_Sample_Rate_REG 0x08
+#define MC32X0_Tap_Detection_Enable_REG 0x09
+#define MC32X0_TAP_Dwell_Reject_REG 0x0a
+#define MC32X0_DROP_Control_Register_REG 0x0b
+#define MC32X0_SHAKE_Debounce_REG 0x0c
+#define MC32X0_XOUT_EX_L_REG 0x0d
+#define MC32X0_XOUT_EX_H_REG 0x0e
+#define MC32X0_YOUT_EX_L_REG 0x0f
+#define MC32X0_YOUT_EX_H_REG 0x10
+#define MC32X0_ZOUT_EX_L_REG 0x11
+#define MC32X0_ZOUT_EX_H_REG 0x12
+#define MC32X0_CHIP_ID_REG 0x18
+#define MC32X0_RANGE_Control_REG 0x20
+#define MC32X0_SHAKE_Threshold_REG 0x2B
+#define MC32X0_UD_Z_TH_REG 0x2C
+#define MC32X0_UD_X_TH_REG 0x2D
+#define MC32X0_RL_Z_TH_REG 0x2E
+#define MC32X0_RL_Y_TH_REG 0x2F
+#define MC32X0_FB_Z_TH_REG 0x30
+#define MC32X0_DROP_Threshold_REG 0x31
+#define MC32X0_TAP_Threshold_REG 0x32
+#define MC32X0_HIGH_END 0x01
+/*******MC3210/20 define this**********/
+
+
+#define MCUBE_8G_14BIT 0x10
+
+#define DOT_CALI
+
+#define MC32X0_LOW_END 0x02
+/*******mc32x0 define this**********/
+
+#define MCUBE_1_5G_8BIT 0x20
+//#define MCUBE_1_5G_8BIT_TAP
+//#define MCUBE_1_5G_6BIT
+#define MC32X0_MODE_DEF 0x43
+
+#define MC32X0ADDRESS 0x4c
+
+#define mc32x0_I2C_NAME "mc32x0"
+#define GSENSOR_DEV_COUNT 1
+#define GSENSOR_DURATION_MAX 200
+#define GSENSOR_DURATION_MIN 10
+#define GSENSOR_DURATION_DEFAULT 20
+
+#define MAX_RETRY 20
+#define INPUT_FUZZ 0
+#define INPUT_FLAT 0
+
+#define AUTO_CALIBRATION 0
+
+static unsigned char is_new_mc34x0 = 0;
+static unsigned char is_mc3250 = 0;
+
+static unsigned char McubeID=0;
+#ifdef DOT_CALI
+#define CALIB_PATH "/data/data/com.mcube.acc/files/mcube-calib.txt"
+//MCUBE_BACKUP_FILE
+#define BACKUP_CALIB_PATH "/data/misc/sensors/mcube-calib.txt"
+//static char backup_buf[64];
+//MCUBE_BACKUP_FILE
+#define DATA_PATH "/sdcard/mcube-register-map.txt"
+
+typedef struct {
+ unsigned short x; /**< X axis */
+ unsigned short y; /**< Y axis */
+ unsigned short z; /**< Z axis */
+} GSENSOR_VECTOR3D;
+
+static GSENSOR_VECTOR3D gsensor_gain;
+static struct miscdevice mc32x0_device;
+
+//static struct file * fd_file = NULL;
+
+static mm_segment_t oldfs;
+//add by Liang for storage offset data
+static unsigned char offset_buf[9];
+static signed int offset_data[3];
+s16 G_RAW_DATA[3];
+static signed int gain_data[3];
+static signed int enable_RBM_calibration = 0;
+#endif
+
+#ifdef DOT_CALI
+
+#if 1
+#define GSENSOR 0xA1//0x95
+
+#define GSENSOR_IOCTL_INIT _IO(GSENSOR, 0x01)
+#define GSENSOR_IOCTL_READ_CHIPINFO _IOR(GSENSOR, 0x02, int)
+#define GSENSOR_IOCTL_READ_SENSORDATA _IOR(GSENSOR, 0x17, int)
+#define GSENSOR_IOCTL_READ_OFFSET _IOR(GSENSOR, 0x04, GSENSOR_VECTOR3D)
+#define GSENSOR_IOCTL_READ_GAIN _IOR(GSENSOR, 0x05, GSENSOR_VECTOR3D)
+#define GSENSOR_IOCTL_READ_RAW_DATA _IOR(GSENSOR, 0x30, int)
+//#define GSENSOR_IOCTL_SET_CALI _IOW(GSENSOR, 0x06, SENSOR_DATA)
+#define GSENSOR_IOCTL_GET_CALI _IOW(GSENSOR, 0x22, SENSOR_DATA)
+#define GSENSOR_IOCTL_CLR_CALI _IO(GSENSOR, 0x23)
+#define GSENSOR_MCUBE_IOCTL_READ_RBM_DATA _IOR(GSENSOR, 0x24, SENSOR_DATA)
+#define GSENSOR_MCUBE_IOCTL_SET_RBM_MODE _IO(GSENSOR, 0x25)
+#define GSENSOR_MCUBE_IOCTL_CLEAR_RBM_MODE _IO(GSENSOR, 0x26)
+#define GSENSOR_MCUBE_IOCTL_SET_CALI _IOW(GSENSOR, 0x27, SENSOR_DATA)
+#define GSENSOR_MCUBE_IOCTL_REGISTER_MAP _IO(GSENSOR, 0x28)
+#define GSENSOR_IOCTL_SET_CALI_MODE _IOW(GSENSOR, 0x29,int)
+#else
+
+#define GSENSOR_IOCTL_INIT 0xa1
+#define GSENSOR_IOCTL_READ_CHIPINFO 0xa2
+#define GSENSOR_IOCTL_READ_SENSORDATA 0xa3
+#define GSENSOR_IOCTL_READ_OFFSET 0xa4
+#define GSENSOR_IOCTL_READ_GAIN 0xa5
+#define GSENSOR_IOCTL_READ_RAW_DATA 0xa6
+#define GSENSOR_IOCTL_SET_CALI 0xa7
+#define GSENSOR_IOCTL_GET_CALI 0xa8
+#define GSENSOR_IOCTL_CLR_CALI 0xa9
+
+#define GSENSOR_MCUBE_IOCTL_READ_RBM_DATA 0xaa
+#define GSENSOR_MCUBE_IOCTL_SET_RBM_MODE 0xab
+#define GSENSOR_MCUBE_IOCTL_CLEAR_RBM_MODE 0xac
+#define GSENSOR_MCUBE_IOCTL_SET_CALI 0xad
+#define GSENSOR_MCUBE_IOCTL_REGISTER_MAP 0xae
+#define GSENSOR_IOCTL_SET_CALI_MODE 0xaf
+#endif
+
+typedef struct{
+ int x;
+ int y;
+ int z;
+}SENSOR_DATA;
+
+static int load_cali_flg = 0;
+//MCUBE_BACKUP_FILE
+//static bool READ_FROM_BACKUP = false;
+//MCUBE_BACKUP_FILE
+
+#endif
+
+#define MC32X0_WAKE 1
+#define MC32X0_SNIFF 2
+#define MC32X0_STANDBY 3
+
+struct dev_data {
+ struct i2c_client *client;
+};
+static struct dev_data dev;
+
+/* Addresses to scan */
+static const unsigned short normal_i2c[2] = {MC32X0ADDRESS, I2C_CLIENT_END};
+
+/*
+typedef union {
+ struct {
+ s16 x;
+ s16 y;
+ s16 z;
+ } u;
+ s16 v[SENSOR_DATA_SIZE];
+} raw_data;
+static raw_data offset;
+*/
+
+struct acceleration {
+ int x;
+ int y;
+ int z;
+};
+
+//void gsensor_write_offset_to_file(void);
+//void gsensor_read_offset_from_file(void);
+//char OffsetFileName[] = "/data/misc/dmt/offset.txt";
+/*static struct sensor_config_info gsensor_info = {
+ .input_type = GSENSOR_TYPE,
+};*/
+
+static u32 debug_mask = 0;
+#define dprintk(level_mask, fmt, arg...) if (unlikely(debug_mask & level_mask)) \
+ printk(KERN_DEBUG fmt , ## arg)
+
+module_param_named(debug_mask, debug_mask, int, 0644);
+
+
+enum {
+ DEBUG_INIT = 1U << 0,
+ DEBUG_CONTROL_INFO = 1U << 1,
+ DEBUG_DATA_INFO = 1U << 2,
+ DEBUG_SUSPEND = 1U << 3,
+};
+
+struct mc32x0_data {
+ struct mutex lock;
+ struct i2c_client *client;
+ struct delayed_work work;
+ struct workqueue_struct *mc32x0_wq;
+ struct hrtimer timer;
+ struct device *device;
+ struct input_dev *input_dev;
+ int use_count;
+ int enabled;
+ volatile unsigned int duration;
+ int use_irq;
+ int irq;
+ unsigned long irqflags;
+ int gpio;
+ unsigned int map[3];
+ int inv[3];
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend early_suspend;
+#endif
+ // for control
+ int int_gpio; //0-3 + int op; + int samp; + //int xyz_axis[3][3]; // (axis,direction)
+ struct proc_dir_entry* sensor_proc;
+ int isdbg;
+ int sensor_samp; // + int sensor_enable; // 0 --> disable sensor, 1 --> enable sensor + int test_pass;
+ int offset[MC32X0_AXES_NUM+1]; /*+1: for 4-byte alignment*/
+ s16 data[MC32X0_AXES_NUM+1];
+};
+
+static struct mc32x0_data l_sensorconfig = {
+ .op = 0,
+ .int_gpio = 3,
+ .samp = 16,
+ /*.xyz_axis = {
+ {ABS_X, -1},
+ {ABS_Y, 1},
+ {ABS_Z, -1},
+ },*/
+ .sensor_proc = NULL,
+ .isdbg = 1,
+ .sensor_samp = 1, // 1 sample/second
+ .sensor_enable = 1, // enable sensor
+ .test_pass = 0, // for test program
+ //.offset={0,0,0},
+};
+
+
+//=============================================================================
+enum mc3xx0_orientation
+{
+ MC3XX0_TOP_LEFT_DOWN = 0,
+ MC3XX0_TOP_RIGHT_DOWN,
+ MC3XX0_TOP_RIGHT_UP,
+ MC3XX0_TOP_LEFT_UP,
+ MC3XX0_BOTTOM_LEFT_DOWN,
+ MC3XX0_BOTTOM_RIGHT_DOWN,
+ MC3XX0_BOTTOM_RIGHT_UP,
+ MC3XX0_BOTTOM_LEFT_UP
+};
+
+enum mc3xx0_axis
+{
+ MC3XX0_AXIS_X = 0,
+ MC3XX0_AXIS_Y,
+ MC3XX0_AXIS_Z,
+ MC3XX0_AXIS_NUM
+};
+
+struct mc3xx0_hwmsen_convert
+{
+ signed int sign[3];
+ unsigned int map[3];
+};
+
+// Transformation matrix for chip mounting position
+static const struct mc3xx0_hwmsen_convert mc3xx0_cvt[] =
+{
+ {{ 1, 1, 1}, {MC3XX0_AXIS_X, MC3XX0_AXIS_Y, MC3XX0_AXIS_Z}}, // 0: top , left-down
+ {{-1, 1, 1}, {MC3XX0_AXIS_Y, MC3XX0_AXIS_X, MC3XX0_AXIS_Z}}, // 1: top , right-down
+ {{-1, -1, 1}, {MC3XX0_AXIS_X, MC3XX0_AXIS_Y, MC3XX0_AXIS_Z}}, // 2: top , right-up
+ {{ 1, -1, 1}, {MC3XX0_AXIS_Y, MC3XX0_AXIS_X, MC3XX0_AXIS_Z}}, // 3: top , left-up
+ {{-1, 1, -1}, {MC3XX0_AXIS_X, MC3XX0_AXIS_Y, MC3XX0_AXIS_Z}}, // 4: bottom, left-down
+ {{ 1, 1, -1}, {MC3XX0_AXIS_Y, MC3XX0_AXIS_X, MC3XX0_AXIS_Z}}, // 5: bottom, right-down
+ {{ 1, -1, -1}, {MC3XX0_AXIS_X, MC3XX0_AXIS_Y, MC3XX0_AXIS_Z}}, // 6: bottom, right-up
+ {{-1, -1, -1}, {MC3XX0_AXIS_Y, MC3XX0_AXIS_X, MC3XX0_AXIS_Z}}, // 7: bottom, left-up
+};
+
+//static unsigned char mc3xx0_current_placement = MC3XX0_BOTTOM_LEFT_DOWN; // current soldered placement
+static struct mc3xx0_hwmsen_convert *pCvt;
+
+//volatile static short sensor_duration = SENSOR_DURATION_DEFAULT;//delay
+//volatile static short sensor_state_flag = 1;
+
+#ifdef SUPPORT_VIRTUAL_Z_SENSOR //add 2013-10-23
+int Verify_Z_Railed(int AccData, int resolution)
+{
+ int status = 0;
+ GSE_LOG("%s: AccData = %d",__func__, AccData);
+ if(resolution == 1) // Low resolution
+ {
+ if((AccData >= Low_Pos_Max && AccData >=0)|| (AccData <= Low_Neg_Max && AccData < 0))
+ {
+ status = 1;
+ GSE_LOG("%s: Railed at Low Resolution",__func__);
+ }
+ }
+ else if (resolution == 2) //High resolution
+ {
+ if((AccData >= High_Pos_Max && AccData >=0) || (AccData <= High_Neg_Max && AccData < 0))
+ {
+ status = 1;
+ GSE_LOG("%s: Railed at High Resolution",__func__);
+ }
+ }
+ else if (resolution == 3) //High resolution
+ {
+ if((AccData >= Low_Pos_Max*3 && AccData >=0) || (AccData <= Low_Neg_Max*3 && AccData < 0))
+ {
+ status = 1;
+ GSE_LOG("%s: Railed at High Resolution",__func__);
+ }
+ }
+ else
+ GSE_LOG("%s, Wrong resolution",__func__);
+
+ return status;
+}
+
+int SquareRoot(int x)
+{
+ int lowerbound;
+ int upperbound;
+ int root;
+
+ if(x < 0) return -1;
+ if(x == 0 || x == 1) return x;
+ lowerbound = 1;
+ upperbound = x;
+ root = lowerbound + (upperbound - lowerbound)/2;
+
+ while(root > x/root || root+1 <= x/(root+1))
+ {
+ if(root > x/root)
+ {
+ upperbound = root;
+ }
+ else
+ {
+ lowerbound = root;
+ }
+ root = lowerbound + (upperbound - lowerbound)/2;
+ }
+ GSE_LOG("%s: Sqrt root is %d",__func__, root);
+ return root;
+}
+#endif
+
+
+unsigned int sample_rate_2_memsec(unsigned int rate)
+{
+ return (1000/rate);
+}
+
+static ssize_t mc32x0_map_show(struct device *dev, struct device_attribute *attr,char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct mc32x0_data *data;
+ int i;
+ data = i2c_get_clientdata(client);
+ for (i = 0; i< 3; i++)
+ {
+ if(data->inv[i] == 1)
+ {
+ switch(data->map[i])
+ {
+ case ABS_X:
+ buf[i] = 'x';
+ break;
+ case ABS_Y:
+ buf[i] = 'y';
+ break;
+ case ABS_Z:
+ buf[i] = 'z';
+ break;
+ default:
+ buf[i] = '_';
+ break;
+ }
+ }
+ else
+ {
+ switch(data->map[i])
+ {
+ case ABS_X:
+ buf[i] = 'X';
+ break;
+ case ABS_Y:
+ buf[i] = 'Y';
+ break;
+ case ABS_Z:
+ buf[i] = 'Z';
+ break;
+ default:
+ buf[i] = '-';
+ break;
+ }
+ }
+ }
+ sprintf(buf+3,"\r\n");
+ return 5;
+}
+/*
+//Function as i2c_master_send, and return 1 if operation is successful.
+static int i2c_write_bytes(struct i2c_client *client, uint8_t *data, uint16_t len)
+{
+ struct i2c_msg msg;
+ int ret=-1;
+
+ msg.flags = !I2C_M_RD;
+ msg.addr = client->addr;
+ msg.len = len;
+ msg.buf = data;
+
+ ret=i2c_transfer(client->adapter, &msg,1);
+ return ret;
+}
+
+static bool gsensor_i2c_test(struct i2c_client * client)
+{
+ int ret, retry;
+ uint8_t test_data[1] = { 0 }; //only write a data address.
+
+ for(retry=0; retry < 2; retry++)
+ {
+ ret =i2c_write_bytes(client, test_data, 1); //Test i2c.
+ if (ret == 1)
+ break;
+ msleep(5);
+ }
+
+ return ret==1 ? true : false;
+}
+*/
+/**
+ * gsensor_detect - Device detection callback for automatic device creation
+ * return value:
+ * = 0; success;
+ * < 0; err
+ */
+ /*
+static int gsensor_detect(struct i2c_client *client, struct i2c_board_info *info)
+{
+ struct i2c_adapter *adapter = client->adapter;
+ int ret;
+
+ dprintk(DEBUG_INIT, "%s enter \n", __func__);
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
+
+ if(twi_id == adapter->nr){
+ pr_info("%s: addr= %x\n",__func__,client->addr);
+
+ ret = gsensor_i2c_test(client);
+ if(!ret){
+ pr_info("%s:I2C connection might be something wrong or maybe the other gsensor equipment! \n",__func__);
+ return -ENODEV;
+ }else{
+ pr_info("I2C connection sucess!\n");
+ strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE);
+ return 0;
+ }
+
+ }else{
+ return -ENODEV;
+ }
+}
+*/
+int mc32x0_set_image (struct i2c_client *client)
+{
+ int comres = 0;
+ unsigned char data;
+
+
+ data = i2c_smbus_read_byte_data(client, 0x3B);
+ //comres = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, 0x3B, &data, 1 );
+ if((data == 0x19)||(data == 0x29))
+ {
+ McubeID = 0x22;
+ }
+ else if((data == 0x90)||(data == 0xA8))
+ {
+ McubeID = 0x11;
+ }
+ else
+ {
+ McubeID = 0;
+ }
+
+ if (0x88 == data)
+ {
+ McubeID = 0x11;
+ is_mc3250 = 1;
+ }
+
+ if (0x39 == data)
+ {
+ McubeID = 0x22;
+ is_new_mc34x0 = 1;
+ }
+ else if (0xB8 == data)
+ {
+ McubeID = 0x11;
+ is_new_mc34x0 = 1;
+ }
+
+
+ if(McubeID &MCUBE_8G_14BIT)
+ {
+ //#ifdef MCUBE_8G_14BIT
+ data = MC32X0_MODE_DEF;
+ //comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Mode_Feature_REG, &data, 1 );
+ i2c_smbus_write_byte_data(client, MC32X0_Mode_Feature_REG,data);
+ data = 0x00;
+ //comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Sleep_Count_REG, &data, 1 );
+ i2c_smbus_write_byte_data(client, MC32X0_Sleep_Count_REG,data);
+ data = 0x00;
+ //comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Sample_Rate_REG, &data, 1 );
+ i2c_smbus_write_byte_data(client, MC32X0_Sample_Rate_REG,data);
+ data = 0x00;
+ //comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Tap_Detection_Enable_REG, &data, 1 );
+ i2c_smbus_write_byte_data(client, MC32X0_Tap_Detection_Enable_REG,data);
+ data = 0x3F;
+ //comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_RANGE_Control_REG, &data, 1 );
+ i2c_smbus_write_byte_data(client, MC32X0_RANGE_Control_REG,data);
+ data = 0x00;
+ //comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Interrupt_Enable_REG, &data, 1 );
+ i2c_smbus_write_byte_data(client, MC32X0_Interrupt_Enable_REG,data);
+#ifdef DOT_CALI
+ gsensor_gain.x = gsensor_gain.y = gsensor_gain.z = 1024;
+#endif
+ //#endif
+ }
+ else if(McubeID &MCUBE_1_5G_8BIT)
+ {
+ #ifdef MCUBE_1_5G_8BIT
+ data = MC32X0_MODE_DEF;
+ //comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Mode_Feature_REG, &data, 1 );
+ i2c_smbus_write_byte_data(client, MC32X0_Mode_Feature_REG,data);
+ data = 0x00;
+ //comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Sleep_Count_REG, &data, 1 );
+ i2c_smbus_write_byte_data(client, MC32X0_Sleep_Count_REG,data);
+ data = 0x00;
+ //comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Sample_Rate_REG, &data, 1 );
+ i2c_smbus_write_byte_data(client, MC32X0_Sample_Rate_REG,data);
+ data = 0x02;
+ //comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_RANGE_Control_REG, &data, 1 );
+ i2c_smbus_write_byte_data(client, MC32X0_RANGE_Control_REG,data);
+ data = 0x00;
+ //comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Tap_Detection_Enable_REG, &data, 1 );
+ i2c_smbus_write_byte_data(client, MC32X0_Tap_Detection_Enable_REG,data);
+ data = 0x00;
+ //comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Interrupt_Enable_REG, &data, 1 );
+ i2c_smbus_write_byte_data(client, MC32X0_Interrupt_Enable_REG,data);
+#ifdef DOT_CALI
+ gsensor_gain.x = gsensor_gain.y = gsensor_gain.z = 86;
+#endif
+ #endif
+ }
+
+ data = 0x41;
+ //comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Mode_Feature_REG, &data, 1 );
+ i2c_smbus_write_byte_data(client, MC32X0_Mode_Feature_REG,data);
+ //MC32X0_rbm(0,0);
+ return comres;
+}
+
+static ssize_t mc32x0_map_store(struct device *dev, struct device_attribute *attr,const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct mc32x0_data *data;
+ int i;
+ data = i2c_get_clientdata(client);
+
+ if(count < 3) return -EINVAL;
+
+ for(i = 0; i< 3; i++)
+ {
+ switch(buf[i])
+ {
+ case 'x':
+ data->map[i] = ABS_X;
+ data->inv[i] = 1;
+ break;
+ case 'y':
+ data->map[i] = ABS_Y;
+ data->inv[i] = 1;
+ break;
+ case 'z':
+ data->map[i] = ABS_Z;
+ data->inv[i] = 1;
+ break;
+ case 'X':
+ data->map[i] = ABS_X;
+ data->inv[i] = -1;
+ break;
+ case 'Y':
+ data->map[i] = ABS_Y;
+ data->inv[i] = -1;
+ break;
+ case 'Z':
+ data->map[i] = ABS_Z;
+ data->inv[i] = -1;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ return count;
+}
+
+static int mc32x0_enable(struct mc32x0_data *data, int enable);
+
+static ssize_t mc32x0_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = container_of(mc32x0_device.parent, struct i2c_client, dev);
+
+ struct mc32x0_data *mc32x0 = i2c_get_clientdata(client);
+
+ return sprintf(buf, "%d\n", mc32x0->enabled);
+}
+
+static ssize_t mc32x0_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ bool new_enable;
+
+ struct i2c_client *client = container_of(mc32x0_device.parent, struct i2c_client, dev);
+
+ struct mc32x0_data *mc32x0 = i2c_get_clientdata(client);
+
+ if (sysfs_streq(buf, "1"))
+ new_enable = true;
+ else if (sysfs_streq(buf, "0"))
+ new_enable = false;
+ else {
+ pr_debug("%s: invalid value %d\n", __func__, *buf);
+ return -EINVAL;
+ }
+
+ mc32x0_enable(mc32x0, new_enable);
+
+ return count;
+}
+
+static ssize_t mc32x0_delay_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", 1000/l_sensorconfig.sensor_samp);
+}
+
+static ssize_t mc32x0_delay_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+
+ error = strict_strtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (data > GSENSOR_DURATION_MAX)
+ data = GSENSOR_DURATION_MAX;
+ if (data < GSENSOR_DURATION_MIN)
+ data = GSENSOR_DURATION_MIN;
+ l_sensorconfig.sensor_samp = 1000/data;
+
+ return count;
+}
+
+static DEVICE_ATTR(map, 0660, mc32x0_map_show, mc32x0_map_store);
+static DEVICE_ATTR(enable, 0660, mc32x0_enable_show, mc32x0_enable_store);
+static DEVICE_ATTR(delay, 0660, mc32x0_delay_show, mc32x0_delay_store);
+
+static struct attribute* mc32x0_attrs[] =
+{
+ &dev_attr_map.attr,
+ &dev_attr_enable.attr,
+ &dev_attr_delay.attr,
+ NULL
+};
+
+static const struct attribute_group mc32x0_group =
+{
+ .attrs = mc32x0_attrs,
+};
+
+static int mc32x0_chip_init(struct i2c_client *client)
+{
+
+ mc32x0_set_image(client);
+
+ return McubeID?0:-1;
+}
+
+int mc32x0_set_mode(struct i2c_client *client, unsigned char mode)
+{
+
+ int comres=0;
+ unsigned char data;
+
+
+ if (mode<4) {
+ data = 0x40|mode;
+ i2c_smbus_write_byte_data(client, MC32X0_Mode_Feature_REG,data);
+ }
+ return comres;
+
+}
+
+
+
+#ifdef DOT_CALI
+struct file *openFile(const char *path,int flag,int mode)
+{
+ struct file *fp;
+
+ fp=filp_open(path, flag, mode);
+ if (IS_ERR(fp) || !fp->f_op)
+ {
+ GSE_LOG("Calibration File filp_open return NULL\n");
+ return NULL;
+ }
+ else
+ {
+
+ return fp;
+ }
+}
+
+int readFile(struct file *fp,char *buf,int readlen)
+{
+ if (fp->f_op && fp->f_op->read)
+ return fp->f_op->read(fp,buf,readlen, &fp->f_pos);
+ else
+ return -1;
+}
+
+int writeFile(struct file *fp,char *buf,int writelen)
+{
+ if (fp->f_op && fp->f_op->write)
+ return fp->f_op->write(fp,buf,writelen, &fp->f_pos);
+ else
+ return -1;
+}
+
+int closeFile(struct file *fp)
+{
+ filp_close(fp,NULL);
+ return 0;
+}
+
+void initKernelEnv(void)
+{
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ printk(KERN_INFO "initKernelEnv\n");
+}
+
+ int MC32X0_WriteCalibration(struct i2c_client *client, int dat[MC32X0_AXES_NUM])
+{
+ int err;
+ u8 buf[9];
+ s16 tmp, x_gain, y_gain, z_gain ;
+ s32 x_off, y_off, z_off;
+ int temp_cali_dat[MC32X0_AXES_NUM] = { 0 };
+ //const struct mc3xx0_hwmsen_convert *pCvt = NULL;
+
+ //pCvt = &mc3xx0_cvt[mc3xx0_current_placement];
+
+ temp_cali_dat[pCvt->map[MC3XX0_AXIS_X]] = pCvt->sign[MC3XX0_AXIS_X] * dat[MC3XX0_AXIS_X];
+ temp_cali_dat[pCvt->map[MC3XX0_AXIS_Y]] = pCvt->sign[MC3XX0_AXIS_Y] * dat[MC3XX0_AXIS_Y];
+ temp_cali_dat[pCvt->map[MC3XX0_AXIS_Z]] = pCvt->sign[MC3XX0_AXIS_Z] * dat[MC3XX0_AXIS_Z];
+/*
+ temp_cali_dat[MC3XX0_AXIS_X] = ((temp_cali_dat[MC3XX0_AXIS_X] * gsensor_gain.x) / GRAVITY_1G_VALUE);
+ temp_cali_dat[MC3XX0_AXIS_Y] = ((temp_cali_dat[MC3XX0_AXIS_Y] * gsensor_gain.y) / GRAVITY_1G_VALUE);
+ temp_cali_dat[MC3XX0_AXIS_Z] = ((temp_cali_dat[MC3XX0_AXIS_Z] * gsensor_gain.z) / GRAVITY_1G_VALUE);
+*/
+ if (is_new_mc34x0)
+ {
+ temp_cali_dat[MC3XX0_AXIS_X] = -temp_cali_dat[MC3XX0_AXIS_X];
+ temp_cali_dat[MC3XX0_AXIS_Y] = -temp_cali_dat[MC3XX0_AXIS_Y];
+ }
+ else if (is_mc3250)
+ {
+ s16 temp = 0;
+
+ temp = temp_cali_dat[MC3XX0_AXIS_X];
+
+ temp_cali_dat[MC3XX0_AXIS_X] = -temp_cali_dat[MC3XX0_AXIS_Y];
+ temp_cali_dat[MC3XX0_AXIS_Y] = temp;
+ }
+
+ dat[MC3XX0_AXIS_X] = temp_cali_dat[MC3XX0_AXIS_X];
+ dat[MC3XX0_AXIS_Y] = temp_cali_dat[MC3XX0_AXIS_Y];
+ dat[MC3XX0_AXIS_Z] = temp_cali_dat[MC3XX0_AXIS_Z];
+
+#if 0 //modify by zwx
+
+ GSE_LOG("UPDATE dat: (%+3d %+3d %+3d)\n",
+ dat[MC32X0_AXIS_X], dat[MC32X0_AXIS_Y], dat[MC32X0_AXIS_Z]);
+
+ /*calculate the real offset expected by caller*/
+ //cali_temp[MC32X0_AXIS_X] = dat[MC32X0_AXIS_X];
+ //cali_temp[MC32X0_AXIS_Y] = dat[MC32X0_AXIS_Y];
+ //cali_temp[MC32X0_AXIS_Z] = dat[MC32X0_AXIS_Z];
+ //cali[MC32X0_AXIS_Z]= cali[MC32X0_AXIS_Z]-gsensor_gain.z;
+
+
+#endif
+// read register 0x21~0x28
+#if 1 //zwx
+ //if ((err = mc32x0_read_block(client, 0x21, buf, 3)))
+ //if ((err = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, 0x21, &buf[0],3)))
+ err = i2c_smbus_read_i2c_block_data(client , 0x21 , 3 , &buf[0]);
+
+ //if ((err = mc32x0_read_block(client, 0x24, &buf[3], 3)))
+ //if ((err = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, 0x24, &buf[3],3)))
+ err = i2c_smbus_read_i2c_block_data(client , 0x24 , 3 , &buf[3]);
+
+ //if ((err = mc32x0_read_block(client, 0x27, &buf[6], 3)))
+ //if ((err = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, 0x27, &buf[6],3)))
+ err = i2c_smbus_read_i2c_block_data(client , 0x27 , 3 , &buf[6]);
+
+#else
+ buf[0] = 0x21;
+ err = mc32x0_rx_data(client, &buf[0], 3);
+ buf[3] = 0x24;
+ err = mc32x0_rx_data(client, &buf[3], 3);
+ buf[6] = 0x27;
+ err = mc32x0_rx_data(client, &buf[6], 3);
+#endif
+#if 1
+ // get x,y,z offset
+ tmp = ((buf[1] & 0x3f) << 8) + buf[0];
+ if (tmp & 0x2000)
+ tmp |= 0xc000;
+ x_off = tmp;
+
+ tmp = ((buf[3] & 0x3f) << 8) + buf[2];
+ if (tmp & 0x2000)
+ tmp |= 0xc000;
+ y_off = tmp;
+
+ tmp = ((buf[5] & 0x3f) << 8) + buf[4];
+ if (tmp & 0x2000)
+ tmp |= 0xc000;
+ z_off = tmp;
+
+ // get x,y,z gain
+ x_gain = ((buf[1] >> 7) << 8) + buf[6];
+ y_gain = ((buf[3] >> 7) << 8) + buf[7];
+ z_gain = ((buf[5] >> 7) << 8) + buf[8];
+
+ // prepare new offset
+ x_off = x_off + 16 * dat[MC32X0_AXIS_X] * 256 * 128 / 3 / gsensor_gain.x / (40 + x_gain);
+ y_off = y_off + 16 * dat[MC32X0_AXIS_Y] * 256 * 128 / 3 / gsensor_gain.y / (40 + y_gain);
+ z_off = z_off + 16 * dat[MC32X0_AXIS_Z] * 256 * 128 / 3 / gsensor_gain.z / (40 + z_gain);
+
+ //storege the cerrunt offset data with DOT format
+ offset_data[0] = x_off;
+ offset_data[1] = y_off;
+ offset_data[2] = z_off;
+
+ //storege the cerrunt Gain data with GOT format
+ gain_data[0] = 256*8*128/3/(40+x_gain);
+ gain_data[1] = 256*8*128/3/(40+y_gain);
+ gain_data[2] = 256*8*128/3/(40+z_gain);
+ printk("%d %d ======================\n\n ",gain_data[0],x_gain);
+#endif
+ buf[0]=0x43;
+ //mc32x0_write_block(client, 0x07, buf, 1);
+ //mc32x0_write_reg(client,0x07,0x43);
+ //p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x07, &buf[0], 1 );
+ i2c_smbus_write_byte_data(client, 0x07,buf[0]);
+ buf[0] = x_off & 0xff;
+ buf[1] = ((x_off >> 8) & 0x3f) | (x_gain & 0x0100 ? 0x80 : 0);
+ buf[2] = y_off & 0xff;
+ buf[3] = ((y_off >> 8) & 0x3f) | (y_gain & 0x0100 ? 0x80 : 0);
+ buf[4] = z_off & 0xff;
+ buf[5] = ((z_off >> 8) & 0x3f) | (z_gain & 0x0100 ? 0x80 : 0);
+
+
+ //mc32x0_write_block(client, 0x21, buf, 6);
+ //p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x21, &buf[0], 6 );
+ i2c_smbus_write_i2c_block_data(client, 0x21, 2,&buf[0]);
+ i2c_smbus_write_i2c_block_data(client, 0x21+2, 2,&buf[2]);
+ i2c_smbus_write_i2c_block_data(client, 0x21+4, 2,&buf[4]);
+
+
+ buf[0]=0x41;
+ //mc32x0_write_block(client, 0x07, buf, 1);
+ //p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x07, &buf[0], 1 );
+ i2c_smbus_write_byte_data(client, 0x07,buf[0]);
+ //mc32x0_write_reg(client,0x07,0x41);
+
+ return err;
+
+}
+/*
+int mcube_read_cali_file(struct i2c_client *client)
+{
+ int cali_data[3];
+ int err =0;
+
+ printk("%s %d\n",__func__,__LINE__);
+ //MCUBE_BACKUP_FILE
+ READ_FROM_BACKUP = false;
+ //MCUBE_BACKUP_FILE
+ initKernelEnv();
+ fd_file = openFile(CALIB_PATH,O_RDONLY,0);
+ //MCUBE_BACKUP_FILE
+ if (fd_file == NULL)
+ {
+ fd_file = openFile(BACKUP_CALIB_PATH, O_RDONLY, 0);
+ if(fd_file != NULL)
+ {
+ READ_FROM_BACKUP = true;
+ }
+ }
+ //MCUBE_BACKUP_FILE
+ if (fd_file == NULL)
+ {
+ GSE_LOG("fail to open\n");
+ cali_data[0] = 0;
+ cali_data[1] = 0;
+ cali_data[2] = 0;
+ return 1;
+ }
+ else
+ {
+ printk("%s %d\n",__func__,__LINE__);
+ memset(backup_buf,0,64);
+ if ((err = readFile(fd_file,backup_buf,128))>0)
+ GSE_LOG("buf:%s\n",backup_buf);
+ else
+ GSE_LOG("read file error %d\n",err);
+ printk("%s %d\n",__func__,__LINE__);
+
+ set_fs(oldfs);
+ closeFile(fd_file);
+
+ sscanf(backup_buf, "%d %d %d",&cali_data[MC32X0_AXIS_X], &cali_data[MC32X0_AXIS_Y], &cali_data[MC32X0_AXIS_Z]);
+ GSE_LOG("cali_data: %d %d %d\n", cali_data[MC32X0_AXIS_X], cali_data[MC32X0_AXIS_Y], cali_data[MC32X0_AXIS_Z]);
+
+ //cali_data1[MC32X0_AXIS_X] = cali_data[MC32X0_AXIS_X] * gsensor_gain.x / GRAVITY_EARTH_1000;
+ //cali_data1[MC32X0_AXIS_Y] = cali_data[MC32X0_AXIS_Y] * gsensor_gain.y / GRAVITY_EARTH_1000;
+ //cali_data1[MC32X0_AXIS_Z] = cali_data[MC32X0_AXIS_Z] * gsensor_gain.z / GRAVITY_EARTH_1000;
+ //cali_data[MC32X0_AXIS_X]=-cali_data[MC32X0_AXIS_X];
+ //cali_data[MC32X0_AXIS_Y]=-cali_data[MC32X0_AXIS_Y];
+ //cali_data[MC32X0_AXIS_Z]=-cali_data[MC32X0_AXIS_Z];
+
+ //GSE_LOG("cali_data1: %d %d %d\n", cali_data1[MC32X0_AXIS_X], cali_data1[MC32X0_AXIS_Y], cali_data1[MC32X0_AXIS_Z]);
+ printk("%s %d\n",__func__,__LINE__);
+ MC32X0_WriteCalibration(client,cali_data);
+ }
+
+ return 0;
+}
+*/
+
+void MC32X0_rbm(struct i2c_client *client, int enable)
+{
+ //int err;
+ char buf1[3];
+ if(enable == 1 )
+ {
+#if 1
+ buf1[0] = 0x43;
+ //err = mc32x0_write_block(client, 0x07, buf1, 0x01);
+ //err = p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x07, &buf1[0], 1 );
+ i2c_smbus_write_byte_data(client, 0x07,buf1[0]);
+ buf1[0] = 0x02;
+ //err = mc32x0_write_block(client, 0x14, buf1, 0x01);
+ //err = p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x14, &buf1[0], 1 );
+ i2c_smbus_write_byte_data(client, 0x14,buf1[0]);
+ buf1[0] = 0x41;
+ //err = mc32x0_write_block(client, 0x07, buf1, 0x01);
+ //err = p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x07, &buf1[0], 1 );
+ i2c_smbus_write_byte_data(client, 0x07,buf1[0]);
+#else
+ err = mc32x0_write_reg(client,0x07,0x43);
+ err = mc32x0_write_reg(client,0x14,0x02);
+ err = mc32x0_write_reg(client,0x07,0x41);
+#endif
+ enable_RBM_calibration =1;
+
+ GSE_LOG("set rbm!!\n");
+
+ msleep(10);
+ }
+ else if(enable == 0 )
+ {
+#if 1
+ buf1[0] = 0x43;
+ //err = mc32x0_write_block(client, 0x07, buf1, 0x01);
+ //err = p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x07, &buf1[0], 1 );
+ i2c_smbus_write_byte_data(client, 0x07,buf1[0]);
+
+ buf1[0] = 0x00;
+ //err = mc32x0_write_block(client, 0x14, buf1, 0x01);
+ //err = p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x14, &buf1[0], 1 );
+ i2c_smbus_write_byte_data(client, 0x14,buf1[0]);
+ buf1[0] = 0x41;
+ //err = mc32x0_write_block(client, 0x07, buf1, 0x01);
+ //err = p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x07, &buf1[0], 1 );
+ i2c_smbus_write_byte_data(client, 0x07,buf1[0]);
+#else
+ err = mc32x0_write_reg(client,0x07,0x43);
+ err = mc32x0_write_reg(client,0x14,0x00);
+ err = mc32x0_write_reg(client,0x07,0x41);
+#endif
+ enable_RBM_calibration =0;
+
+ GSE_LOG("clear rbm!!\n");
+
+ msleep(10);
+ }
+}
+
+/*----------------------------------------------------------------------------*/
+ int MC32X0_ReadData_RBM(struct i2c_client *client,int data[MC32X0_AXES_NUM])
+{
+ //u8 uData;
+ u8 addr = 0x0d;
+ u8 rbm_buf[MC32X0_DATA_LEN] = {0};
+ int err = 0;
+
+
+ //err = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, addr, &rbm_buf[0],6);
+ err = i2c_smbus_read_i2c_block_data(client , addr , 6 , rbm_buf);
+ //err = mc32x0_read_block(client, addr, rbm_buf, 0x06);
+
+ data[MC32X0_AXIS_X] = (s16)((rbm_buf[0]) | (rbm_buf[1] << 8));
+ data[MC32X0_AXIS_Y] = (s16)((rbm_buf[2]) | (rbm_buf[3] << 8));
+ data[MC32X0_AXIS_Z] = (s16)((rbm_buf[4]) | (rbm_buf[5] << 8));
+
+ GSE_LOG("rbm_buf<<<<<[%02x %02x %02x %02x %02x %02x]\n",rbm_buf[0], rbm_buf[2], rbm_buf[2], rbm_buf[3], rbm_buf[4], rbm_buf[5]);
+ GSE_LOG("RBM<<<<<[%04x %04x %04x]\n", data[MC32X0_AXIS_X], data[MC32X0_AXIS_Y], data[MC32X0_AXIS_Z]);
+ GSE_LOG("RBM<<<<<[%04d %04d %04d]\n", data[MC32X0_AXIS_X], data[MC32X0_AXIS_Y], data[MC32X0_AXIS_Z]);
+ return err;
+}
+
+
+ int MC32X0_ReadRBMData(struct i2c_client *client, char *buf)
+{
+ //struct mc32x0_data *mc32x0 = i2c_get_clientdata(client);
+ int res = 0;
+ int data[3];
+
+ if (!buf)
+ {
+ return EINVAL;
+ }
+
+ mc32x0_set_mode(client,MC32X0_WAKE);
+/*
+ if(mc32x0->status == mc32x0_CLOSE)
+ {
+ res = mc32x0_start(client, 0);
+ if(res)
+ {
+ GSE_ERR("Power on mc32x0 error %d!\n", res);
+ }
+ }
+*/
+ if((res = MC32X0_ReadData_RBM(client,data)))
+ {
+ GSE_ERR("%s I2C error: ret value=%d",__func__, res);
+ return EIO;
+ }
+ else
+ {
+ sprintf(buf, "%04x %04x %04x", data[MC32X0_AXIS_X],
+ data[MC32X0_AXIS_Y], data[MC32X0_AXIS_Z]);
+
+ }
+
+ return 0;
+}
+ int MC32X0_ReadOffset(struct i2c_client *client,s16 ofs[MC32X0_AXES_NUM])
+{
+ int err;
+ u8 off_data[6];
+
+
+ if(McubeID &MCUBE_8G_14BIT)
+ {
+
+ //if ((err = mc32x0_read_block(client, MC32X0_XOUT_EX_L_REG, off_data, MC32X0_DATA_LEN)))
+ //if ((err = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, MC32X0_XOUT_EX_L_REG, &off_data[0],MC32X0_DATA_LEN)))
+ err = i2c_smbus_read_i2c_block_data(client , MC32X0_XOUT_EX_L_REG , MC32X0_DATA_LEN , off_data);
+
+ ofs[MC32X0_AXIS_X] = ((s16)(off_data[0]))|((s16)(off_data[1])<<8);
+ ofs[MC32X0_AXIS_Y] = ((s16)(off_data[2]))|((s16)(off_data[3])<<8);
+ ofs[MC32X0_AXIS_Z] = ((s16)(off_data[4]))|((s16)(off_data[5])<<8);
+ }
+ else if(McubeID &MCUBE_1_5G_8BIT)
+ {
+ //if ((err = mc32x0_read_block(client, 0, off_data, 3)))
+ //if ((err = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, 0, &off_data[0],3)))
+ err = i2c_smbus_read_i2c_block_data(client , 0 , 3 , off_data);
+
+ ofs[MC32X0_AXIS_X] = (s8)off_data[0];
+ ofs[MC32X0_AXIS_Y] = (s8)off_data[1];
+ ofs[MC32X0_AXIS_Z] = (s8)off_data[2];
+ }
+
+ GSE_LOG("MC32X0_ReadOffset %d %d %d \n",ofs[MC32X0_AXIS_X] ,ofs[MC32X0_AXIS_Y],ofs[MC32X0_AXIS_Z]);
+
+ return 0;
+}
+/*----------------------------------------------------------------------------*/
+ int MC32X0_ResetCalibration(struct i2c_client *client)
+{
+
+ u8 buf[6];
+ s16 tmp;
+ int err;
+#if 1 //zwx
+ buf[0] = 0x43;
+ //if(err = mc32x0_write_block(client, 0x07, buf, 1))
+ //if(err = p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x07, &buf[0], 1 ))
+ if((err = i2c_smbus_write_byte_data(client, 0x07,buf[0])))
+ {
+ GSE_ERR("error 0x07: %d\n", err);
+ }
+
+
+ //if(err = mc32x0_write_block(client, 0x21, offset_buf, 6)) // add by liang for writing offset register as OTP value
+ //if(err = p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x21, &offset_buf[0], 6 ))
+ if((err = i2c_smbus_write_i2c_block_data(client, 0x21, 6,offset_buf)))
+ {
+ GSE_ERR("error: %d\n", err);
+ }
+
+ buf[0] = 0x41;
+ //if(err = mc32x0_write_block(client, 0x07, buf, 1))
+ //if(err = p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x07, &buf[0], 1 ))
+ if((err = i2c_smbus_write_byte_data(client, 0x07,buf[0])))
+ {
+ GSE_ERR("error: %d\n", err);
+ }
+#else
+ mc32x0_write_reg(client,0x07,0x43);
+
+ mc32x0_write_block(client, 0x21, offset_buf, 6);
+
+ mc32x0_write_reg(client,0x07,0x41);
+#endif
+ msleep(20);
+
+ tmp = ((offset_buf[1] & 0x3f) << 8) + offset_buf[0]; // add by Liang for set offset_buf as OTP value
+ if (tmp & 0x2000)
+ tmp |= 0xc000;
+ offset_data[0] = tmp;
+
+ tmp = ((offset_buf[3] & 0x3f) << 8) + offset_buf[2]; // add by Liang for set offset_buf as OTP value
+ if (tmp & 0x2000)
+ tmp |= 0xc000;
+ offset_data[1] = tmp;
+
+ tmp = ((offset_buf[5] & 0x3f) << 8) + offset_buf[4]; // add by Liang for set offset_buf as OTP value
+ if (tmp & 0x2000)
+ tmp |= 0xc000;
+ offset_data[2] = tmp;
+
+ //memset(mc32x0->cali_sw, 0x00, sizeof(mc32x0->cali_sw));
+ return 0;
+
+}
+/*----------------------------------------------------------------------------*/
+ int MC32X0_ReadCalibration(struct i2c_client *client,int dat[MC32X0_AXES_NUM])
+{
+
+ signed short MC_offset[MC32X0_AXES_NUM+1]; /*+1: for 4-byte alignment*/
+ int err;
+ memset(MC_offset, 0, sizeof(MC_offset));
+ if ((err = MC32X0_ReadOffset(client, MC_offset))) {
+ GSE_ERR("read offset fail, %d\n", err);
+ return err;
+ }
+
+ dat[MC32X0_AXIS_X] = MC_offset[MC32X0_AXIS_X];
+ dat[MC32X0_AXIS_Y] = MC_offset[MC32X0_AXIS_Y];
+ dat[MC32X0_AXIS_Z] = MC_offset[MC32X0_AXIS_Z];
+ //modify by zwx
+ //GSE_LOG("MC32X0_ReadCalibration %d %d %d \n",dat[mc32x0->cvt.map[MC32X0_AXIS_X]] ,dat[mc32x0->cvt.map[MC32X0_AXIS_Y]],dat[mc32x0->cvt.map[MC32X0_AXIS_Z]]);
+
+ return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+
+ int MC32X0_ReadData(struct i2c_client *client, s16 buffer[MC32X0_AXES_NUM])
+{
+ unsigned char buf[6];
+ signed char buf1[6];
+ char rbm_buf[6];
+ int ret;
+ //int err = 0;
+
+ #ifdef SUPPORT_VIRTUAL_Z_SENSOR
+ int tempX=0; + int tempY=0; + int tempZ=0; + #endif
+
+ if ( enable_RBM_calibration == 0)
+ {
+ //err = hwmsen_read_block(client, addr, buf, 0x06);
+ }
+ else if (enable_RBM_calibration == 1)
+ {
+ memset(rbm_buf, 0, 6);
+ //rbm_buf[0] = mc32x0_REG_RBM_DATA;
+ //ret = mc32x0_rx_data(client, &rbm_buf[0], 6);
+ //ret = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, 0x0d, &rbm_buf[0],6);
+ i2c_smbus_read_i2c_block_data(client , 0x0d , 2 , &rbm_buf[0]);
+ i2c_smbus_read_i2c_block_data(client , 0x0d+2 , 2 , &rbm_buf[2]);
+ i2c_smbus_read_i2c_block_data(client , 0x0d+4 , 2 , &rbm_buf[4]);
+ }
+
+ if ( enable_RBM_calibration == 0)
+ {
+
+ if(McubeID &MC32X0_HIGH_END)
+ {
+ #ifdef MC32X0_HIGH_END
+ ret = i2c_smbus_read_i2c_block_data(client , MC32X0_XOUT_EX_L_REG , 6 , buf);
+ //ret = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, MC32X0_XOUT_EX_L_REG, &buf[0],6);
+
+ buffer[0] = (signed short)((buf[0])|(buf[1]<<8));
+ buffer[1] = (signed short)((buf[2])|(buf[3]<<8));
+ buffer[2] = (signed short)((buf[4])|(buf[5]<<8));
+ #endif
+ }
+ else if(McubeID &MC32X0_LOW_END)
+ {
+ #ifdef MC32X0_LOW_END
+ ret = i2c_smbus_read_i2c_block_data(client , MC32X0_XOUT_REG , 3 , buf1);
+ //ret = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, MC32X0_XOUT_REG, &buf[0],3);
+
+ buffer[0] = (signed short)buf1[0];
+ buffer[1] = (signed short)buf1[1];
+ buffer[2] = (signed short)buf1[2];
+ #endif
+ }
+ #ifdef SUPPORT_VIRTUAL_Z_SENSOR //add 2013-10-23
+ if (g_virtual_z) + { + //printk("%s 1\n", __FUNCTION__); + + tempX = buffer[MC32X0_AXIS_X]; + tempY = buffer[MC32X0_AXIS_Y]; + tempZ = buffer[MC32X0_AXIS_Z]; + //printk(" %d:Verify_Z_Railed() %d\n", (int)buffer[MC32X0_AXIS_Z], Verify_Z_Railed((int)buffer[MC32X0_AXIS_Z], LOW_RESOLUTION)); + if(1 == Verify_Z_Railed((int)buffer[MC32X0_AXIS_Z], LOW_RESOLUTION)) // z-railed + { + Railed = 1; + + GSE_LOG("%s: Z railed", __func__); + //printk("%s: Z railed \n", __func__); + if (G_2_REVERSE_VIRTUAL_Z == 1)
+ buffer[MC32X0_AXIS_Z] = (s8) ( gsensor_gain.z - (abs(tempX) + abs(tempY))); + else + buffer[MC32X0_AXIS_Z] = (s8) -( gsensor_gain.z - (abs(tempX) + abs(tempY))); + } + else + { + Railed = 0; + } + } + #endif
+ mcprintkreg("MC32X0_ReadData : %d %d %d \n",buffer[0],buffer[1],buffer[2]);
+ }
+ else if (enable_RBM_calibration == 1)
+ {
+ buffer[MC32X0_AXIS_X] = (s16)((rbm_buf[0]) | (rbm_buf[1] << 8));
+ buffer[MC32X0_AXIS_Y] = (s16)((rbm_buf[2]) | (rbm_buf[3] << 8));
+ buffer[MC32X0_AXIS_Z] = (s16)((rbm_buf[4]) | (rbm_buf[5] << 8));
+
+ GSE_LOG("%s RBM<<<<<[%08d %08d %08d]\n", __func__,buffer[MC32X0_AXIS_X], buffer[MC32X0_AXIS_Y], buffer[MC32X0_AXIS_Z]);
+ if(gain_data[0] == 0)
+ {
+ buffer[MC32X0_AXIS_X] = 0;
+ buffer[MC32X0_AXIS_Y] = 0;
+ buffer[MC32X0_AXIS_Z] = 0;
+ return 0;
+ }
+ buffer[MC32X0_AXIS_X] = (buffer[MC32X0_AXIS_X] + offset_data[0]/2)*gsensor_gain.x/gain_data[0];
+ buffer[MC32X0_AXIS_Y] = (buffer[MC32X0_AXIS_Y] + offset_data[1]/2)*gsensor_gain.y/gain_data[1];
+ buffer[MC32X0_AXIS_Z] = (buffer[MC32X0_AXIS_Z] + offset_data[2]/2)*gsensor_gain.z/gain_data[2];
+
+ #ifdef SUPPORT_VIRTUAL_Z_SENSOR // add 2013-10-23
+ if (g_virtual_z) + { + tempX = buffer[MC32X0_AXIS_X]; + tempY = buffer[MC32X0_AXIS_Y]; + tempZ = buffer[MC32X0_AXIS_Z]; + //printk("%s 2\n", __FUNCTION__); + GSE_LOG("Original RBM<<<<<[%08d %08d %08d]\n", buffer[MC32X0_AXIS_X], buffer[MC32X0_AXIS_Y], buffer[MC32X0_AXIS_Z]); + printk("Verify_Z_Railed() %d\n", Verify_Z_Railed((int)buffer[MC32X0_AXIS_Z], RBM_RESOLUTION)); + if(1 == Verify_Z_Railed(buffer[MC32X0_AXIS_Z], RBM_RESOLUTION)) // z-railed + { + GSE_LOG("%s: Z Railed in RBM mode",__FUNCTION__); + //printk("%s: Z Railed in RBM mode\n",__FUNCTION__); + if (G_2_REVERSE_VIRTUAL_Z == 1)
+ buffer[MC32X0_AXIS_Z] = (s16) ( gsensor_gain.z - (abs(tempX) + abs(tempY))); + else + buffer[MC32X0_AXIS_Z] = (s16) -( gsensor_gain.z - (abs(tempX) + abs(tempY))); + } + GSE_LOG("RBM<<<<<[%08d %08d %08d]\n", buffer[MC32X0_AXIS_X], buffer[MC32X0_AXIS_Y], buffer[MC32X0_AXIS_Z]); + } + #endif
+
+ GSE_LOG("%s offset_data <<<<<[%d %d %d]\n", __func__,offset_data[0], offset_data[1], offset_data[2]);
+
+ GSE_LOG("%s gsensor_gain <<<<<[%d %d %d]\n", __func__,gsensor_gain.x, gsensor_gain.y, gsensor_gain.z);
+
+ GSE_LOG("%s gain_data <<<<<[%d %d %d]\n", __func__,gain_data[0], gain_data[1], gain_data[2]);
+
+ GSE_LOG("%s RBM->RAW <<<<<[%d %d %d]\n", __func__,buffer[MC32X0_AXIS_X], buffer[MC32X0_AXIS_Y], buffer[MC32X0_AXIS_Z]);
+ }
+
+ return 0;
+}
+
+int MC32X0_ReadRawData(struct i2c_client *client, char * buf)
+{
+
+
+ int res = 0;
+ s16 raw_buf[3];
+
+ if (!buf)
+ {
+ return EINVAL;
+ }
+
+ //mc32x0_power_up(mc32x0);
+ mc32x0_set_mode(client, MC32X0_WAKE);
+ if((res = MC32X0_ReadData(client,&raw_buf[0])))
+ {
+ printk("%s %d\n",__FUNCTION__, __LINE__);
+ GSE_ERR("I2C error: ret value=%d", res);
+ return EIO;
+ }
+ else
+ {
+ //const struct mc3xx0_hwmsen_convert *pCvt = &mc3xx0_cvt[mc3xx0_current_placement];
+ GSE_LOG("UPDATE dat: (%+3d %+3d %+3d)\n",
+ raw_buf[MC32X0_AXIS_X], raw_buf[MC32X0_AXIS_Y], raw_buf[MC32X0_AXIS_Z]);
+
+ //G_RAW_DATA[MC32X0_AXIS_X] = raw_buf[0];
+ //G_RAW_DATA[MC32X0_AXIS_Y] = raw_buf[1];
+ //G_RAW_DATA[MC32X0_AXIS_Z] = raw_buf[2];
+ //G_RAW_DATA[MC32X0_AXIS_Z] = G_RAW_DATA[MC32X0_AXIS_Z] + gsensor_gain.z;
+/*
+ raw_buf[MC3XX0_AXIS_X] = ((raw_buf[MC3XX0_AXIS_X] * GRAVITY_1G_VALUE) / gsensor_gain.x);
+ raw_buf[MC3XX0_AXIS_Y] = ((raw_buf[MC3XX0_AXIS_Y] * GRAVITY_1G_VALUE) / gsensor_gain.y);
+ raw_buf[MC3XX0_AXIS_Z] = ((raw_buf[MC3XX0_AXIS_Z] * GRAVITY_1G_VALUE) / gsensor_gain.z);
+*/
+ if (is_new_mc34x0)
+ {
+ raw_buf[MC3XX0_AXIS_X] = -raw_buf[MC3XX0_AXIS_X];
+ raw_buf[MC3XX0_AXIS_Y] = -raw_buf[MC3XX0_AXIS_Y];
+ }
+ else if (is_mc3250)
+ {
+ s16 temp = 0;
+
+ temp = raw_buf[MC3XX0_AXIS_X];
+
+ raw_buf[MC3XX0_AXIS_X] = raw_buf[MC3XX0_AXIS_Y];
+ raw_buf[MC3XX0_AXIS_Y] = -temp;
+ }
+
+ G_RAW_DATA[MC3XX0_AXIS_X] = pCvt->sign[MC3XX0_AXIS_X] * raw_buf[pCvt->map[MC3XX0_AXIS_X]];
+ G_RAW_DATA[MC3XX0_AXIS_Y] = pCvt->sign[MC3XX0_AXIS_Y] * raw_buf[pCvt->map[MC3XX0_AXIS_Y]];
+ G_RAW_DATA[MC3XX0_AXIS_Z] = pCvt->sign[MC3XX0_AXIS_Z] * raw_buf[pCvt->map[MC3XX0_AXIS_Z]];
+
+ G_RAW_DATA[MC32X0_AXIS_Z] += gsensor_gain.z*(pCvt->sign[MC3XX0_AXIS_Z])*(1);//-=GRAVITY_1G_VALUE;
+
+ //printk("%s %d\n",__FUNCTION__, __LINE__);
+ sprintf(buf, "%04x %04x %04x", G_RAW_DATA[MC32X0_AXIS_X],
+ G_RAW_DATA[MC32X0_AXIS_Y], G_RAW_DATA[MC32X0_AXIS_Z]);
+ GSE_LOG("G_RAW_DATA: (%+3d %+3d %+3d)\n",
+ G_RAW_DATA[MC32X0_AXIS_X], G_RAW_DATA[MC32X0_AXIS_Y], G_RAW_DATA[MC32X0_AXIS_Z]);
+ }
+ return 0;
+}
+
+int mc32x0_reset (struct i2c_client *client)
+{
+
+ s16 tmp, x_gain, y_gain, z_gain ;
+ s32 x_off, y_off, z_off;
+ u8 buf[3];
+ int err;
+ //mc32x0_write_reg(client,0x1b,0x6d);
+ buf[0]=0x6d;
+ //p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x1b, &buf[0], 1 );
+ i2c_smbus_write_byte_data(client, 0x1b,buf[0]);
+
+ //mc32x0_write_reg(client,0x1b,0x43);
+ buf[0]=0x43;
+ //p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x1b, &buf[0], 1 );
+ i2c_smbus_write_byte_data(client, 0x1b,buf[0]);
+ msleep(5);
+
+ //mc32x0_write_reg(client,0x07,0x43);
+ buf[0]=0x43;
+ //p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x07, &buf[0], 1 );
+ i2c_smbus_write_byte_data(client, 0x07,buf[0]);
+ //mc32x0_write_reg(client,0x1C,0x80);
+ buf[0]=0x80;
+ //p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x1C, &buf[0], 1 );
+ i2c_smbus_write_byte_data(client, 0x1c,buf[0]);
+ //mc32x0_write_reg(client,0x17,0x80);
+ buf[0]=0x80;
+ //p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x17, &buf[0], 1 );
+ i2c_smbus_write_byte_data(client, 0x17,buf[0]);
+ msleep(5);
+ //mc32x0_write_reg(client,0x1C,0x00);
+ buf[0]=0x00;
+ //p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x1C, &buf[0], 1 );
+ i2c_smbus_write_byte_data(client, 0x1c,buf[0]);
+ //mc32x0_write_reg(client,0x17,0x00);
+ buf[0]=0x00;
+ //p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x17, &buf[0], 1 );
+ i2c_smbus_write_byte_data(client, 0x17,buf[0]);
+ msleep(5);
+
+
+/*
+ if ((err = mc32x0_read_block(new_client, 0x21, offset_buf, 6))) //add by Liang for storeage OTP offsef register value
+ {
+ GSE_ERR("error: %d\n", err);
+ return err;
+ }
+*/
+ memset(offset_buf, 0, 9);
+ //offset_buf[0] = 0x21;
+ //err = mc32x0_rx_data(client, offset_buf, 9);
+ //err = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, 0x21, &offset_buf[0],9);
+ err = i2c_smbus_read_i2c_block_data(client , 0x21 , 9 , offset_buf);
+
+
+ tmp = ((offset_buf[1] & 0x3f) << 8) + offset_buf[0];
+ if (tmp & 0x2000)
+ tmp |= 0xc000;
+ x_off = tmp;
+
+ tmp = ((offset_buf[3] & 0x3f) << 8) + offset_buf[2];
+ if (tmp & 0x2000)
+ tmp |= 0xc000;
+ y_off = tmp;
+
+ tmp = ((offset_buf[5] & 0x3f) << 8) + offset_buf[4];
+ if (tmp & 0x2000)
+ tmp |= 0xc000;
+ z_off = tmp;
+
+ // get x,y,z gain
+ x_gain = ((offset_buf[1] >> 7) << 8) + offset_buf[6];
+ y_gain = ((offset_buf[3] >> 7) << 8) + offset_buf[7];
+ z_gain = ((offset_buf[5] >> 7) << 8) + offset_buf[8];
+
+
+ //storege the cerrunt offset data with DOT format
+ offset_data[0] = x_off;
+ offset_data[1] = y_off;
+ offset_data[2] = z_off;
+
+ //storege the cerrunt Gain data with GOT format
+ gain_data[0] = 256*8*128/3/(40+x_gain);
+ gain_data[1] = 256*8*128/3/(40+y_gain);
+ gain_data[2] = 256*8*128/3/(40+z_gain);
+ printk("offser gain = %d %d %d %d %d %d======================\n\n ",
+ gain_data[0],gain_data[1],gain_data[2],offset_data[0],offset_data[1],offset_data[2]);
+
+ return 0;
+}
+#endif
+
+int mc32x0_read_accel_xyz(struct i2c_client *client, s16 * acc)
+{
+ int comres;
+ s16 raw_data[MC3XX0_AXIS_NUM] = { 0 };
+ //const struct mc3xx0_hwmsen_convert *pCvt = &mc3xx0_cvt[mc3xx0_current_placement];
+#ifdef DOT_CALI
+ s16 raw_buf[6];
+
+
+ comres = MC32X0_ReadData(client,&raw_buf[0]);
+
+ acc[0] = raw_buf[0];
+ acc[1] = raw_buf[1];
+ acc[2] = raw_buf[2];
+#else
+ unsigned char raw_buf[6];
+ signed char raw_buf1[3];
+ if(McubeID &MC32X0_HIGH_END)
+ {
+ #ifdef MC32X0_HIGH_END
+ comres = i2c_smbus_read_i2c_block_data(client , MC32X0_XOUT_EX_L_REG , 6 , raw_buf);
+ //comres = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, MC32X0_XOUT_EX_L_REG, &data[0],6);
+
+ acc[0] = (signed short)((raw_buf[0])|(raw_buf[1]<<8));
+ acc[1] = (signed short)((raw_buf[2])|(raw_buf[3]<<8));
+ acc[2] = (signed short)((raw_buf[4])|(raw_buf[5]<<8));
+ #endif
+ }
+ else if(McubeID &MC32X0_LOW_END)
+ {
+ #ifdef MC32X0_LOW_END
+ comres = i2c_smbus_read_i2c_block_data(client , MC32X0_XOUT_REG , 3 , raw_buf1);
+ //comres = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, MC32X0_XOUT_REG, &data[0],3);
+
+ acc[0] = (signed short)raw_buf1[0];
+ acc[1] = (signed short)raw_buf1[1];
+ acc[2] = (signed short)raw_buf1[2];
+ #endif
+ }
+#endif
+
+ raw_data[MC3XX0_AXIS_X] = acc[MC3XX0_AXIS_X];
+ raw_data[MC3XX0_AXIS_Y] = acc[MC3XX0_AXIS_Y];
+ raw_data[MC3XX0_AXIS_Z] = acc[MC3XX0_AXIS_Z];
+/*
+ raw_data[MC3XX0_AXIS_X] = ((raw_data[MC3XX0_AXIS_X] * GRAVITY_1G_VALUE) / gsensor_gain.x);
+ raw_data[MC3XX0_AXIS_Y] = ((raw_data[MC3XX0_AXIS_Y] * GRAVITY_1G_VALUE) / gsensor_gain.y);
+ raw_data[MC3XX0_AXIS_Z] = ((raw_data[MC3XX0_AXIS_Z] * GRAVITY_1G_VALUE) / gsensor_gain.z);
+*/
+ if (is_new_mc34x0)
+ {
+ raw_data[MC3XX0_AXIS_X] = -raw_data[MC3XX0_AXIS_X];
+ raw_data[MC3XX0_AXIS_Y] = -raw_data[MC3XX0_AXIS_Y];
+ }
+ else if (is_mc3250)
+ {
+ s16 temp = 0;
+
+ temp = raw_data[MC3XX0_AXIS_X];
+
+ raw_data[MC3XX0_AXIS_X] = raw_data[MC3XX0_AXIS_Y];
+ raw_data[MC3XX0_AXIS_Y] = -temp;
+ }
+
+ acc[MC3XX0_AXIS_X] = pCvt->sign[MC3XX0_AXIS_X] * raw_data[pCvt->map[MC3XX0_AXIS_X]];
+ acc[MC3XX0_AXIS_Y] = pCvt->sign[MC3XX0_AXIS_Y] * raw_data[pCvt->map[MC3XX0_AXIS_Y]];
+ acc[MC3XX0_AXIS_Z] = pCvt->sign[MC3XX0_AXIS_Z] * raw_data[pCvt->map[MC3XX0_AXIS_Z]];
+
+ return comres;
+
+}
+
+static int mc32x0_measure(struct i2c_client *client, struct acceleration *accel)
+{
+
+ s16 raw[3];
+
+#ifdef DOT_CALI
+ //int ret;
+#endif
+
+
+#ifdef DOT_CALI
+ if( load_cali_flg > 0)
+ {
+ /*ret =mcube_read_cali_file(client);
+ if(ret == 0)
+ load_cali_flg = ret;
+ else
+ load_cali_flg --;
+ GSE_LOG("load_cali %d\n",ret); */
+ MC32X0_WriteCalibration(client,l_sensorconfig.offset);
+ load_cali_flg = 0;
+ }
+#endif
+ /* read acceleration data */
+ mc32x0_read_accel_xyz(client,&raw[0]);
+
+ accel->x = raw[0] ;
+ accel->y = raw[1] ;
+ accel->z = raw[2] ;
+ return 0;
+}
+
+static void mc32x0_work_func(struct work_struct *work)
+{
+ struct mc32x0_data *data = container_of(work, struct mc32x0_data, work);
+ struct acceleration accel = {0};
+
+ mc32x0_measure(data->client, &accel);
+
+ //printk(KERN_ERR"mc32x0_measure: acc.x=%d, acc.y=%d, acc.z=%d\n", data->inv[0]*accel.x,data->inv[1]*accel.y, data->inv[2]*accel.z);
+
+ //input_report_abs(data->input_dev, data->map[0], data->inv[0]*accel.x);
+ //input_report_abs(data->input_dev, data->map[1], data->inv[1]*accel.y);
+ //input_report_abs(data->input_dev, data->map[2], data->inv[2]*accel.z);
+
+ //accel.x = (accel.x&0x00FF) | ((accel.y&0xFF)<<8) | ((accel.z&0xFF)<<16);
+
+ input_report_abs(data->input_dev, ABS_X, accel.x);
+ input_report_abs(data->input_dev, ABS_Y, accel.y);
+ input_report_abs(data->input_dev, ABS_Z, accel.z);
+ input_sync(data->input_dev);
+
+ queue_delayed_work(data->mc32x0_wq, &data->work, msecs_to_jiffies(sample_rate_2_memsec(data->sensor_samp)));
+}
+/*
+static enum hrtimer_restart mc32x0_timer_func(struct hrtimer *timer)
+{
+ struct mc32x0_data *data = container_of(timer, struct mc32x0_data, timer);
+
+ queue_work(data->mc32x0_wq, &data->work);
+ hrtimer_start(&data->timer, ktime_set(0, sensor_duration*1000000), HRTIMER_MODE_REL);
+
+ return HRTIMER_NORESTART;
+}
+*/
+static int mc32x0_enable(struct mc32x0_data *data, int enable)
+{
+ if(enable){
+ msleep(10);
+ mc32x0_chip_init(data->client);
+ queue_delayed_work(data->mc32x0_wq, &data->work, msecs_to_jiffies(sample_rate_2_memsec(data->sensor_samp)));//hrtimer_start(&data->timer, ktime_set(0, asensor_duration*1000000), HRTIMER_MODE_REL);
+ data->enabled = true;
+ }else{
+ cancel_delayed_work_sync(&l_sensorconfig.work);//hrtimer_cancel(&data->timer);
+ data->enabled = false;
+ }
+ return 0;
+}
+/*
+//MCUBE_BACKUP_FILE
+static void mcube_copy_file(const char *dstFilePath)
+{
+
+ int err =0;
+ initKernelEnv();
+
+ fd_file = openFile(dstFilePath,O_RDWR,0);
+ if (fd_file == NULL)
+ {
+ GSE_LOG("open %s fail\n",dstFilePath);
+ return;
+ }
+
+ if ((err = writeFile(fd_file,backup_buf,64))>0)
+ GSE_LOG("buf:%s\n",backup_buf);
+ else
+ GSE_LOG("write file error %d\n",err);
+
+ set_fs(oldfs); ;
+ closeFile(fd_file);
+
+}
+//MCUBE_BACKUP_FILE
+*/
+
+extern int wmt_setsyspara(char *varname, char *varval);
+static void update_var(void)
+{
+ char varbuf[64];
+ int varlen;
+
+ memset(varbuf, 0, sizeof(varbuf));
+ varlen = sizeof(varbuf);
+
+ sprintf(varbuf, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
+ l_sensorconfig.op,
+ l_sensorconfig.int_gpio,
+ l_sensorconfig.samp,
+ (pCvt->map[MC3XX0_AXIS_X]),
+ (pCvt->sign[MC3XX0_AXIS_X]),
+ (pCvt->map[MC3XX0_AXIS_Y]),
+ (pCvt->sign[MC3XX0_AXIS_Y]),
+ (pCvt->map[MC3XX0_AXIS_Z]),
+ (pCvt->sign[MC3XX0_AXIS_Z]),
+ l_sensorconfig.offset[0],
+ l_sensorconfig.offset[1],
+ l_sensorconfig.offset[2]
+ );
+
+ wmt_setsyspara("wmt.io.mc3230sensor",varbuf);
+}
+
+static long mc32x0_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ //int intBuf[SENSOR_DATA_SIZE];
+ int ret = 0;
+ //float convert_para=0.0f;
+ short enable = 0;
+ short delay = 0;
+ //short val=1000/l_sensorconfig.sensor_samp;
+ unsigned int uval ;
+#ifdef DOT_CALI
+ void __user *data1;
+ char strbuf[256];
+ //int cali[3];
+ SENSOR_DATA sensor_data;
+ struct i2c_client *client = container_of(mc32x0_device.parent, struct i2c_client, dev);
+ //struct mc32x0_data* this = (struct mc32x0_data *)i2c_get_clientdata(client); /* ?õô????????????. */
+#endif
+
+ switch (cmd) {
+ case ECS_IOCTL_APP_SET_AFLAG:
+ // enable/disable sensor
+
+ if (copy_from_user(&enable, (short*)arg, sizeof(short)))
+ {
+ errlog("Can't get enable flag!!!\n");
+ ret = -EFAULT;
+ goto errioctl;
+ }
+ if ((enable >=0) && (enable <=1))
+ {
+ dbg("driver: disable/enable(%d) gsensor. l_sensorconfig.sensor_samp=%d\n", enable, l_sensorconfig.sensor_samp);
+ + if (enable != l_sensorconfig.sensor_enable)
+ {
+
+ l_sensorconfig.sensor_enable = enable;
+ + }
+ } else {
+ errlog("Wrong enable argument!!!\n");
+ ret = -EFAULT;
+ goto errioctl;
+ }
+ break;
+ case ECS_IOCTL_APP_SET_DELAY://IOCTL_SENSOR_SET_DELAY_ACCEL:
+ /*if(copy_from_user((void *)&sensor_duration, (void __user *) arg, sizeof(short))!=0){
+ printk("copy from error in %s.\n",__func__);
+ }*/
+
+ // set the rate of g-sensor
+ if (copy_from_user(&delay,(short*)arg, sizeof(short)))
+ {
+ errlog("Can't get set delay!!!\n");
+ ret = -EFAULT;
+ goto errioctl;
+ }
+ dbg("Get delay=%d \n", delay);
+
+ if ((delay >=0) && (delay < 20))
+ {
+ delay = 20;
+ } else if (delay > 200)
+ {
+ delay = 200;
+ }
+ if (delay > 0)
+ {
+ l_sensorconfig.sensor_samp = 1000/delay;
+ } else {
+ errlog("error delay argument(delay=%d)!!!\n",delay);
+ ret = -EFAULT;
+ goto errioctl;
+ }
+
+ break;
+/*
+ case IOCTL_SENSOR_GET_DELAY_ACCEL:
+
+ if(copy_to_user((void __user *) arg, (const void *)&val, sizeof(short))!=0){
+ printk("copy to error in %s.\n",__func__);
+ }
+
+ break;*/
+ case WMT_IOCTL_SENSOR_GET_DRVID:
+ uval = MC3230_DRVID;
+ if (copy_to_user((unsigned int*)arg, &uval, sizeof(unsigned int)))
+ {
+ return -EFAULT;
+ }
+ dbg("mc32x0_driver_id:%d\n",uval);
+ break;
+ case WMT_IOCTL_SENOR_GET_RESOLUTION:
+ if(McubeID &MCUBE_1_5G_8BIT)
+ uval = (8<<8) | 3; //mc3230:8 bit ,+/-1.5g
+ if (copy_to_user((unsigned int *)arg, &uval, sizeof(unsigned int))) + { + return -EFAULT; + } + printk("<<<<<<<resolution:0x%x\n",uval);
+ break;
+ /*case IOCTL_SENSOR_GET_STATE_ACCEL:
+ if(copy_to_user((void __user *) arg, (const void *)&sensor_state_flag, sizeof(short))!=0){
+ printk("copy to error in %s.\n",__func__);
+ }
+
+ break;
+
+ case IOCTL_SENSOR_SET_STATE_ACCEL:
+ if(copy_from_user((void *)&sensor_state_flag, (void __user *) arg, sizeof(short))!=0){
+ printk("copy from error in %s.\n",__func__);
+ }
+
+ break;
+ case IOCTL_SENSOR_GET_NAME:
+ if(copy_to_user((void __user *) arg,(const void *)mc32x0_DISPLAY_NAME, sizeof(mc32x0_DISPLAY_NAME))!=0){
+ printk("copy to error in %s.\n",__func__);
+ }
+ break;
+
+ case IOCTL_SENSOR_GET_VENDOR:
+ if(copy_to_user((void __user *) arg,(const void *)mc32x0_DIPLAY_VENDOR, sizeof(mc32x0_DIPLAY_VENDOR))!=0){
+ printk("copy to error in %s.\n",__func__);
+ }
+ break;
+
+ case IOCTL_SENSOR_GET_CONVERT_PARA:
+ convert_para = mc32x0_CONVERT_PARAMETER;
+ if(copy_to_user((void __user *) arg,(const void *)&convert_para,sizeof(float))!=0){
+ printk("copy to error in %s.\n",__func__);
+ }
+ break;
+ */
+
+ #ifdef DOT_CALI
+ case GSENSOR_IOCTL_READ_SENSORDATA:
+ case GSENSOR_IOCTL_READ_RAW_DATA:
+ GSE_LOG("fwq GSENSOR_IOCTL_READ_RAW_DATA\n");
+ MC32X0_ReadRawData(client,strbuf);
+ if (copy_to_user((void __user *) arg, &strbuf, strlen(strbuf)+1)) {
+ printk("failed to copy sense data to user space.");
+ return -EFAULT;
+ }
+
+
+ break;
+
+
+ case GSENSOR_MCUBE_IOCTL_SET_CALI:
+ GSE_LOG("fwq GSENSOR_MCUBE_IOCTL_SET_CALI!!\n");
+ data1 = (void __user *)arg;
+
+
+ //data = (unsigned char*)arg;
+
+
+ if(data1 == NULL)
+ {
+ ret = -EINVAL;
+ break;
+ }
+ if(copy_from_user(&sensor_data, data1, sizeof(sensor_data)))
+ {
+ ret = -EFAULT;
+ break;
+ }
+ //if(atomic_read(&this->suspend))
+ //{
+ // GSE_ERR("Perform calibration in suspend state!!\n");
+ // err = -EINVAL;
+ //}
+ else
+ {
+ //this->cali_sw[MC32X0_AXIS_X] += sensor_data.x;
+ //this->cali_sw[MC32X0_AXIS_Y] += sensor_data.y;
+ //this->cali_sw[MC32X0_AXIS_Z] += sensor_data.z;
+
+ l_sensorconfig.offset[MC32X0_AXIS_X] = sensor_data.x;
+ l_sensorconfig.offset[MC32X0_AXIS_Y] = sensor_data.y;
+ l_sensorconfig.offset[MC32X0_AXIS_Z] = sensor_data.z;
+
+ GSE_LOG("GSENSOR_MCUBE_IOCTL_SET_CALI %d %d %d %d %d %d!!\n", l_sensorconfig.offset[MC32X0_AXIS_X], l_sensorconfig.offset[MC32X0_AXIS_Y],l_sensorconfig.offset[MC32X0_AXIS_Z] ,sensor_data.x, sensor_data.y ,sensor_data.z);
+
+ update_var();
+ ret = MC32X0_WriteCalibration(client, l_sensorconfig.offset);
+ }
+
+ break;
+
+ case GSENSOR_IOCTL_CLR_CALI:
+ GSE_LOG("fwq GSENSOR_IOCTL_CLR_CALI!!\n");
+ l_sensorconfig.offset[0] = 0;
+ l_sensorconfig.offset[1] = 0; + l_sensorconfig.offset[2] = 0; + + update_var();
+ ret = MC32X0_ResetCalibration(client);
+ break;
+
+ case GSENSOR_IOCTL_GET_CALI:
+ GSE_LOG("fwq mc32x0 GSENSOR_IOCTL_GET_CALI\n");
+
+ data1 = (unsigned char*)arg;
+
+ if(data1 == NULL)
+ {
+ ret = -EINVAL;
+ break;
+ }
+
+ if((ret = MC32X0_ReadCalibration(client,l_sensorconfig.offset)))
+ {
+ GSE_LOG("fwq mc32x0 MC32X0_ReadCalibration error!!!!\n");
+ break;
+ }
+
+ sensor_data.x = l_sensorconfig.offset[0];//this->cali_sw[MC32X0_AXIS_X];
+ sensor_data.y = l_sensorconfig.offset[1];//this->cali_sw[MC32X0_AXIS_Y];
+ sensor_data.z = l_sensorconfig.offset[2];//this->cali_sw[MC32X0_AXIS_Z];
+ // if(copy_to_user(data, &sensor_data, sizeof(sensor_data)))
+
+ if(copy_to_user(data1, &sensor_data, sizeof(sensor_data)))
+ {
+ ret = -EFAULT;
+ break;
+ }
+ break;
+ // add by liang ****
+ //add in Sensors_io.h
+ //#define GSENSOR_IOCTL_SET_CALI_MODE _IOW(GSENSOR, 0x0e, int)
+ case GSENSOR_IOCTL_SET_CALI_MODE:
+ GSE_LOG("fwq mc32x0 GSENSOR_IOCTL_SET_CALI_MODE\n");
+ break;
+
+ case GSENSOR_MCUBE_IOCTL_READ_RBM_DATA:
+ GSE_LOG("fwq GSENSOR_MCUBE_IOCTL_READ_RBM_DATA\n");
+ data1 = (void __user *) arg;
+ if(data1 == NULL)
+ {
+ ret = -EINVAL;
+ break;
+ }
+ MC32X0_ReadRBMData(client,(char *)&strbuf);
+ if(copy_to_user(data1, &strbuf, strlen(strbuf)+1))
+ {
+ ret = -EFAULT;
+ break;
+ }
+ break;
+
+ case GSENSOR_MCUBE_IOCTL_SET_RBM_MODE:
+ GSE_LOG("fwq GSENSOR_MCUBE_IOCTL_SET_RBM_MODE\n");
+ //MCUBE_BACKUP_FILE
+ /*if(READ_FROM_BACKUP==true)
+ {
+
+ mcube_copy_file(CALIB_PATH);
+
+ READ_FROM_BACKUP = false;
+ }*/
+ //MCUBE_BACKUP_FILE
+ MC32X0_rbm(client, 1);
+
+ break;
+
+ case GSENSOR_MCUBE_IOCTL_CLEAR_RBM_MODE:
+ GSE_LOG("fwq GSENSOR_MCUBE_IOCTL_CLEAR_RBM_MODE\n");
+
+ MC32X0_rbm(client, 0);
+
+ break;
+
+ case GSENSOR_MCUBE_IOCTL_REGISTER_MAP:
+ GSE_LOG("fwq GSENSOR_MCUBE_IOCTL_REGISTER_MAP\n");
+
+ //MC32X0_Read_Reg_Map(client);
+
+ break;
+#endif
+
+
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+errioctl:
+
+ return ret;
+}
+
+
+static int mc32x0_open(struct inode *inode, struct file *filp)
+{
+ /*int ret;
+ ret = nonseekable_open(inode, filp);*/
+ return 0;
+}
+
+static int mc32x0_release(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static struct file_operations sensor_fops =
+{
+ .owner = THIS_MODULE,
+ .open = mc32x0_open,
+ .release = mc32x0_release,
+ .unlocked_ioctl = mc32x0_ioctl,
+};
+
+//#ifdef CONFIG_HAS_EARLYSUSPEND
+static int mc32x0_i2c_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ /*struct mc32x0_data *data;
+ char mc32x0_address;
+ char mc32x0_data;
+
+ //printk("mc32x0_early_suspend 2 \n");
+
+ data = container_of(handler, struct mc32x0_data, early_suspend);
+
+ hrtimer_cancel(&data->timer);
+ */
+ cancel_delayed_work_sync(&l_sensorconfig.work);
+ mc32x0_set_mode(l_sensorconfig.client,MC32X0_STANDBY);
+ return 0;
+}
+
+static int mc32x0_i2c_resume(struct platform_device *pdev)
+{
+ struct mc32x0_data *data = &l_sensorconfig;
+ //char mc32x0_address;
+ //char mc32x0_data;
+
+ //printk("mc32x0_early_resume 2\n");
+
+ //data = container_of(handler, struct mc32x0_data, early_suspend);
+
+ //Add 20130722
+ mc32x0_chip_init(data->client);
+ MC32X0_ResetCalibration(data->client);
+ MC32X0_WriteCalibration(data->client,l_sensorconfig.offset);//mcube_read_cali_file(data->client);
+ //before
+
+ mc32x0_set_mode(data->client,MC32X0_WAKE);
+
+ queue_delayed_work(data->mc32x0_wq, &data->work, msecs_to_jiffies(sample_rate_2_memsec(data->sensor_samp)));
+ //hrtimer_start(&data->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
+ return 0;
+}
+//#endif
+
+static struct miscdevice mc32x0_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "sensor_ctrl",
+ .fops = &sensor_fops,
+};
+
+static int sensor_writeproc( struct file *file,
+ const char *buffer,
+ unsigned long count,
+ void *data )
+{
+
+ //int inputval = -1;
+ int enable, sample = -1;
+ char tembuf[8];
+ //unsigned int amsr = 0;
+ int test = 0;
+
+ mutex_lock(&l_sensorconfig.lock);
+ memset(tembuf, 0, sizeof(tembuf));
+ // get sensor level and set sensor level
+ if (sscanf(buffer, "isdbg=%d\n", &l_sensorconfig.isdbg))
+ {
+ // only set the dbg flag
+ } else if (sscanf(buffer, "samp=%d\n", &sample))
+ {
+ if (sample > 0)
+ {
+ if (sample != l_sensorconfig.sensor_samp)
+ {
+ // should do sth
+ }
+ //printk(KERN_ALERT "sensor samp=%d(amsr:%d) has been set.\n", sample, amsr);
+ } else {
+ klog("Wrong sample argumnet of sensor.\n");
+ }
+ } else if (sscanf(buffer, "enable=%d\n", &enable))
+ {
+ if ((enable < 0) || (enable > 1))
+ {
+ dbg("The argument to enable/disable g-sensor should be 0 or 1 !!!\n");
+ } else if (enable != l_sensorconfig.sensor_enable)
+ {
+ //mma_enable_disable(enable);
+ l_sensorconfig.sensor_enable = enable;
+ }
+ } else if (sscanf(buffer, "sensor_test=%d\n", &test))
+ { // for test begin
+ l_sensorconfig.test_pass = 0;
+ } else if (sscanf(buffer, "sensor_testend=%d\n", &test))
+ { // Don nothing only to be compatible the before testing program
+ }
+ mutex_unlock(&l_sensorconfig.lock);
+ return count;
+}
+
+static int sensor_readproc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+
+ len = sprintf(page,
+ "test_pass=%d\nisdbg=%d\nrate=%d\nenable=%d\n",
+ l_sensorconfig.test_pass,
+ l_sensorconfig.isdbg,
+ l_sensorconfig.sensor_samp,
+ l_sensorconfig.sensor_enable
+ );
+ return len;
+}
+
+static int mc32x0_probe(struct platform_device *pdev)
+{
+ int ret = 0;
+ struct mc32x0_data *data = &l_sensorconfig;
+ struct i2c_client *client = data->client;
+
+#ifdef DOT_CALI
+ load_cali_flg = 30;
+#endif
+ data->sensor_proc = create_proc_entry(GSENSOR_PROC_NAME, 0666, NULL/*&proc_root*/);
+ if (data->sensor_proc != NULL)
+ { + data->sensor_proc->write_proc = sensor_writeproc;
+ data->sensor_proc->read_proc = sensor_readproc;
+ }
+
+ data->mc32x0_wq = create_singlethread_workqueue("mc32x0_wq");
+ if (!data->mc32x0_wq )
+ {
+ ret = -ENOMEM;
+ goto err_create_workqueue_failed;
+ }
+
+ INIT_DELAYED_WORK(&data->work, mc32x0_work_func);
+ //INIT_WORK(&data->work, mc32x0_work_func);
+ mutex_init(&data->lock);
+
+
+ data->input_dev = input_allocate_device();
+ if (!data->input_dev) {
+ ret = -ENOMEM;
+ goto exit_input_dev_alloc_failed;
+ }
+
+
+ dev.client=client;
+
+ i2c_set_clientdata(client, data);
+ #ifdef DOT_CALI
+ mc32x0_reset(client);
+ #endif
+
+ set_bit(EV_ABS, data->input_dev->evbit);
+ data->map[0] = G_0;
+ data->map[1] = G_1;
+ data->map[2] = G_2;
+ data->inv[0] = G_0_REVERSE;
+ data->inv[1] = G_1_REVERSE;
+ data->inv[2] = G_2_REVERSE;
+
+ input_set_abs_params(data->input_dev, ABS_X, -32*8, 32*8, INPUT_FUZZ, INPUT_FLAT);
+ input_set_abs_params(data->input_dev, ABS_Y, -32*8, 32*8, INPUT_FUZZ, INPUT_FLAT);
+ input_set_abs_params(data->input_dev, ABS_Z, -32*8, 32*8, INPUT_FUZZ, INPUT_FLAT);
+
+ data->input_dev->name = "g-sensor";
+
+
+ ret = input_register_device(data->input_dev);
+ if (ret) {
+ goto exit_input_register_device_failed;
+ }
+ mc32x0_device.parent = &client->dev;
+ ret = misc_register(&mc32x0_device);
+ if (ret) {
+ goto exit_misc_device_register_failed;
+ }
+
+ ret = sysfs_create_group(&client->dev.kobj, &mc32x0_group);
+/*
+ if (!data->use_irq){
+ hrtimer_init(&data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ data->timer.function = mc32x0_timer_func;
+ hrtimer_start(&data->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
+ }
+*/
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ data->early_suspend.suspend = mc32x0_early_suspend;
+ data->early_suspend.resume = mc32x0_early_resume;
+ register_early_suspend(&data->early_suspend);
+#endif
+ data->enabled = true;
+ queue_delayed_work(data->mc32x0_wq, &data->work, msecs_to_jiffies(sample_rate_2_memsec(data->sensor_samp)));
+ strcpy(mc32x0_on_off_str,"gsensor_int2");
+ dprintk(DEBUG_INIT,"mc32x0 probe ok \n");
+
+ return 0;
+exit_misc_device_register_failed:
+exit_input_register_device_failed:
+ input_free_device(data->input_dev);
+exit_input_dev_alloc_failed:
+ destroy_workqueue(data->mc32x0_wq);
+err_create_workqueue_failed:
+ kfree(data);
+ printk("mc32x0 probe failed \n");
+ return ret;
+
+}
+
+static int mc32x0_remove(struct platform_device *pdev)
+{
+ /*struct mc32x0_data *data = i2c_get_clientdata(client);
+
+ hrtimer_cancel(&data->timer);
+ input_unregister_device(data->input_dev);
+ //gpio_release(mc32x0_pin_hd, 2);
+ misc_deregister(&mc32x0_device);
+ sysfs_remove_group(&client->dev.kobj, &mc32x0_group);
+ kfree(data);*/
+
+ if (NULL != l_sensorconfig.mc32x0_wq)
+ { + cancel_delayed_work_sync(&l_sensorconfig.work); + flush_workqueue(l_sensorconfig.mc32x0_wq);
+ destroy_workqueue(l_sensorconfig.mc32x0_wq);
+ l_sensorconfig.mc32x0_wq = NULL;
+ } + if (l_sensorconfig.sensor_proc != NULL) + { + remove_proc_entry(GSENSOR_PROC_NAME, NULL); + l_sensorconfig.sensor_proc = NULL; + } + misc_deregister(&mc32x0_device);
+ input_unregister_device(l_sensorconfig.input_dev);
+ sysfs_remove_group(&l_sensorconfig.client->dev.kobj, &mc32x0_group);
+ return 0;
+}
+
+static void mc32x0_shutdown(struct platform_device *pdev)
+{
+ struct mc32x0_data *data = &l_sensorconfig;//i2c_get_clientdata(client);
+ if(data->enabled)
+ mc32x0_enable(data,0);
+}
+/*
+static const struct i2c_device_id mc32x0_id[] = {
+ { SENSOR_NAME, 0 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, mc32x0_id);
+
+static struct i2c_driver mc32x0_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = SENSOR_NAME,
+ },
+ .id_table = mc32x0_id,
+ .probe = mc32x0_probe,
+ .remove = mc32x0_remove,
+ .shutdown = mc32x0_shutdown,
+ .detect = gsensor_detect,
+ .address_list = normal_i2c,
+};
+*/
+extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
+static int get_axisset(void)
+{
+ char varbuf[64];
+ int n;
+ int varlen;
+ //int tmpoff[3] = {0};
+ memset(varbuf, 0, sizeof(varbuf));
+ varlen = sizeof(varbuf);
+
+ pCvt = (struct mc3xx0_hwmsen_convert *)kzalloc(sizeof(struct mc3xx0_hwmsen_convert), GFP_KERNEL);
+
+ if (wmt_getsyspara("wmt.io.mc3230.virtualz", varbuf, &varlen)) {
+ errlog("Can't get gsensor config in u-boot!!!!\n");
+ //return -1;
+ } else {
+ sscanf(varbuf, "%d", &g_virtual_z);
+
+ }
+ printk("%s g_virtual_z %d\n", __FUNCTION__, g_virtual_z);
+ memset(varbuf, 0, sizeof(varbuf));
+ if (wmt_getsyspara("wmt.io.mc3230sensor", varbuf, &varlen)) {
+ errlog("Can't get gsensor config in u-boot!!!!\n");
+ return -1; //open it for no env just,not insmod such module 2014-6-30
+ } else {
+ n = sscanf(varbuf, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
+ &l_sensorconfig.op,
+ &l_sensorconfig.int_gpio,
+ &l_sensorconfig.samp,
+ &(pCvt->map[MC3XX0_AXIS_X]),
+ &(pCvt->sign[MC3XX0_AXIS_X]),
+ &(pCvt->map[MC3XX0_AXIS_Y]),
+ &(pCvt->sign[MC3XX0_AXIS_Y]),
+ &(pCvt->map[MC3XX0_AXIS_Z]),
+ &(pCvt->sign[MC3XX0_AXIS_Z]),
+ &(l_sensorconfig.offset[0]),
+ &(l_sensorconfig.offset[1]),
+ &(l_sensorconfig.offset[2])
+ );
+ if (n != 12) {
+ printk(KERN_ERR "gsensor format is error in u-boot!!!\n");
+ return -1;
+ }
+ l_sensorconfig.sensor_samp = l_sensorconfig.samp;
+
+
+ dbg("get the sensor config: %d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d\n",
+ l_sensorconfig.op,
+ l_sensorconfig.int_gpio,
+ l_sensorconfig.samp,
+ pCvt->map[MC3XX0_AXIS_X],
+ pCvt->sign[MC3XX0_AXIS_X],
+ pCvt->map[MC3XX0_AXIS_Y],
+ pCvt->sign[MC3XX0_AXIS_Y],
+ pCvt->map[MC3XX0_AXIS_Z],
+ pCvt->sign[MC3XX0_AXIS_Z],
+ l_sensorconfig.offset[0],
+ l_sensorconfig.offset[1],
+ l_sensorconfig.offset[2]
+ );
+ }
+ return 0;
+}
+
+static void mc32x0_platform_release(struct device *device)
+{
+ return;
+}
+
+static struct platform_device mc32x0_pdevice = {
+ .name = GSENSOR_NAME,
+ .id = 0,
+ .dev = {
+ .release = mc32x0_platform_release,
+ },
+};
+
+static struct platform_driver mc32x0_pdriver = {
+ .probe = mc32x0_probe,
+ .remove = mc32x0_remove,
+ .suspend = mc32x0_i2c_suspend,
+ .resume = mc32x0_i2c_resume,
+ .shutdown = mc32x0_shutdown,
+ .driver = {
+ .name = GSENSOR_NAME,
+ },
+};
+
+
+static int __init mc32x0_init(void)
+{
+ struct i2c_client *this_client;
+ int ret = 0;
+
+ dprintk(DEBUG_INIT, "======%s=========. \n", __func__);
+ // parse g-sensor u-boot arg + ret = get_axisset();
+ if (ret < 0)
+ {
+ printk("<<<<<%s user choose to no sensor chip!\n", __func__);
+ return ret;
+ }
+ if (!(this_client = sensor_i2c_register_device(0, MC32X0_I2C_ADDR, GSENSOR_NAME)))
+ { + printk(KERN_ERR"Can't register gsensor i2c device!\n"); + return -1; + } + + if (mc32x0_chip_init(this_client))
+ { + printk(KERN_ERR"Failed to init MC32X0!\n");
+ sensor_i2c_unregister_device(this_client); + return -1; + }
+
+ //printk(KERN_ERR"McubeID:%d\n",McubeID);
+ l_sensorconfig.client = this_client;
+
+ l_dev_class = class_create(THIS_MODULE, GSENSOR_NAME);
+ if (IS_ERR(l_dev_class)){ + ret = PTR_ERR(l_dev_class); + printk(KERN_ERR "Can't class_create gsensor device !!\n"); + return ret; + } + if((ret = platform_device_register(&mc32x0_pdevice)))
+ { + klog("Can't register mc3230 platform devcie!!!\n"); + return ret; + } + if ((ret = platform_driver_register(&mc32x0_pdriver)) != 0)
+ { + errlog("Can't register mc3230 platform driver!!!\n"); + return ret; + }
+ return ret;
+}
+
+static void __exit mc32x0_exit(void)
+{
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&l_sensorconfig.earlysuspend); +#endif + platform_driver_unregister(&mc32x0_pdriver);
+ platform_device_unregister(&mc32x0_pdevice);
+ sensor_i2c_unregister_device(l_sensorconfig.client);
+ class_destroy(l_dev_class);
+}
+
+//*********************************************************************************************************
+MODULE_AUTHOR("Long Chen <lchen@mcube-inc.com>");
+MODULE_DESCRIPTION("mc32x0 driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.1");
+
+module_init(mc32x0_init);
+module_exit(mc32x0_exit);
+
diff --git a/drivers/input/sensor/mc3230_gsensor/mc32x0_driver.c b/drivers/input/sensor/mc3230_gsensor/mc32x0_driver.c new file mode 100755 index 00000000..19c81b97 --- /dev/null +++ b/drivers/input/sensor/mc3230_gsensor/mc32x0_driver.c @@ -0,0 +1,505 @@ +/*
+ * Copyright (C) 2011 MCUBE, Inc.
+ *
+ * Initial Code:
+ * Tan Liang
+ */
+
+
+
+
+
+#include <linux/delay.h> +
+#include "mc32x0_driver.h"
+
+
+mc32x0_t *p_mc32x0; /**< pointer to MC32X0 device structure */
+
+
+/** API Initialization routine
+ \param *mc32x0 pointer to MC32X0 structured type
+ \return result of communication routines
+ */
+
+int mcube_mc32x0_init(mc32x0_t *mc32x0)
+{
+ int comres=0;
+ unsigned char data;
+
+ p_mc32x0 = mc32x0; /* assign mc32x0 ptr */
+ p_mc32x0->dev_addr = MC32X0_I2C_ADDR; /* preset I2C_addr */
+ comres += p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, MC32X0_CHIP_ID, &data, 1); /* read Chip Id */
+
+ p_mc32x0->chip_id = data;
+
+ // init other reg
+ data = 0x63;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x1b, &data, 1);
+ data = 0x43;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x1b, &data, 1);
+ msleep(5);
+
+ data = 0x43;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x07, &data, 1);
+ data = 0x80;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x1c, &data, 1);
+ data = 0x80;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x17, &data, 1);
+ msleep(5);
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x1c, &data, 1);
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, 0x17, &data, 1);
+
+ return comres;
+}
+
+int mc32x0_set_image (void)
+{
+ int comres;
+ unsigned char data;
+ if (p_mc32x0==0)
+ return E_NULL_PTR;
+
+#ifdef MCUBE_2G_10BIT_TAP
+ data = MC32X0_MODE_DEF;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Mode_Feature_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Sleep_Count_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Sample_Rate_REG, &data, 1 );
+
+ data = 0x80;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Tap_Detection_Enable_REG, &data, 1 );
+
+ data = 0x05;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_TAP_Dwell_Reject_REG, &data, 1 );
+
+ data = 0x33;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_RANGE_Control_REG, &data, 1 );
+
+ data = 0x07;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_TAP_Threshold_REG, &data, 1 );
+
+ data = 0x04;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Interrupt_Enable_REG, &data, 1 );
+
+#endif
+
+#ifdef MCUBE_2G_10BIT
+ data = MC32X0_MODE_DEF;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Mode_Feature_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Sleep_Count_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Sample_Rate_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Tap_Detection_Enable_REG, &data, 1 );
+
+ data = 0x33;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_RANGE_Control_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Interrupt_Enable_REG, &data, 1 );
+
+#endif
+
+#ifdef MCUBE_8G_14BIT_TAP
+ data = MC32X0_MODE_DEF;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Mode_Feature_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Sleep_Count_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Sample_Rate_REG, &data, 1 );
+
+ data = 0x80;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Tap_Detection_Enable_REG, &data, 1 );
+
+ data = 0x05;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_TAP_Dwell_Reject_REG, &data, 1 );
+
+ data = 0x3F;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_RANGE_Control_REG, &data, 1 );
+
+ data = 0x07;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_TAP_Threshold_REG, &data, 1 );
+
+ data = 0x04;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Interrupt_Enable_REG, &data, 1 );
+
+#endif
+
+#ifdef MCUBE_8G_14BIT
+ data = MC32X0_MODE_DEF;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Mode_Feature_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Sleep_Count_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Sample_Rate_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Tap_Detection_Enable_REG, &data, 1 );
+
+ data = 0x3F;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_RANGE_Control_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Interrupt_Enable_REG, &data, 1 );
+
+#endif
+
+
+
+#ifdef MCUBE_1_5G_8BIT
+ data = MC32X0_MODE_DEF;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Mode_Feature_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Sleep_Count_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Sample_Rate_REG, &data, 1 );
+
+ data = 0x02;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_RANGE_Control_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Tap_Detection_Enable_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Interrupt_Enable_REG, &data, 1 );
+
+#endif
+
+
+#ifdef MCUBE_1_5G_8BIT_TAP
+ data = MC32X0_MODE_DEF;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Mode_Feature_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Sleep_Count_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Sample_Rate_REG, &data, 1 );
+
+ data = 0x80;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Tap_Detection_Enable_REG, &data, 1 );
+
+ data = 0x02;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_RANGE_Control_REG, &data, 1 );
+
+ data = 0x03;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_TAP_Dwell_Reject_REG, &data, 1 );
+
+ data = 0x07;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_TAP_Threshold_REG, &data, 1 );
+
+ data = 0x04;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Interrupt_Enable_REG, &data, 1 );
+
+#endif
+
+
+#ifdef MCUBE_1_5G_6BIT
+
+ data = MC32X0_MODE_DEF;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Mode_Feature_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Sleep_Count_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Sample_Rate_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_RANGE_Control_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Tap_Detection_Enable_REG, &data, 1 );
+
+ data = 0x00;
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_Interrupt_Enable_REG, &data, 1 );
+
+
+#endif
+
+
+
+ return comres;
+}
+
+
+int mc32x0_get_offset(unsigned char *offset)
+{
+ return 0;
+}
+
+
+int mc32x0_set_offset(unsigned char offset)
+{
+ return 0;
+}
+
+
+
+
+/** set mc32x0s range
+ \param range
+
+ \see MC32X0_RANGE_2G
+ \see MC32X0_RANGE_4G
+ \see MC32X0_RANGE_8G
+*/
+int mc32x0_set_range(char range)
+{
+ int comres = 0;
+ unsigned char data;
+
+ if (p_mc32x0==0)
+ return E_NULL_PTR;
+
+ if (range<3) {
+ comres = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, MC32X0_RANGE__REG, &data, 1);
+ data = MC32X0_SET_BITSLICE(data, MC32X0_RANGE, range);
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_RANGE__REG, &data, 1);
+
+ }
+ return comres;
+
+}
+
+
+/* readout select range from MC32X0
+ \param *range pointer to range setting
+ \return result of bus communication function
+ \see MC32X0_RANGE_2G, MC32X0_RANGE_4G, MC32X0_RANGE_8G
+ \see mc32x0_set_range()
+*/
+int mc32x0_get_range(unsigned char *range)
+{
+
+ int comres = 0;
+ unsigned char data;
+
+ if (p_mc32x0==0)
+ return E_NULL_PTR;
+ comres = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, MC32X0_RANGE__REG, &data, 1);
+ data = MC32X0_GET_BITSLICE(data, MC32X0_RANGE);
+
+ *range = data;
+
+
+ return comres;
+
+}
+
+
+
+int mc32x0_set_mode(unsigned char mode) {
+
+ int comres=0;
+ unsigned char data;
+
+ if (p_mc32x0==0)
+ return E_NULL_PTR;
+
+ if (mode<4) {
+ data = MC32X0_MODE_DEF;
+ data = MC32X0_SET_BITSLICE(data, MC32X0_MODE, mode);
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_MODE__REG, &data, 1 );
+
+ p_mc32x0->mode = mode;
+ }
+ return comres;
+
+}
+
+
+
+int mc32x0_get_mode(unsigned char *mode)
+{
+ if (p_mc32x0==0)
+ return E_NULL_PTR;
+ *mode = p_mc32x0->mode;
+ return 0;
+}
+
+
+int mc32x0_set_bandwidth(char bw)
+{
+ int comres = 0;
+ unsigned char data;
+
+
+ if (p_mc32x0==0)
+ return E_NULL_PTR;
+
+ if (bw<7) {
+
+ comres = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, MC32X0_BANDWIDTH__REG, &data, 1 );
+ data = MC32X0_SET_BITSLICE(data, MC32X0_BANDWIDTH, bw);
+ comres += p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, MC32X0_BANDWIDTH__REG, &data, 1 );
+
+ }
+
+ return comres;
+
+
+}
+
+int mc32x0_get_bandwidth(unsigned char *bw) {
+ int comres = 1;
+ if (p_mc32x0==0)
+ return E_NULL_PTR;
+
+ comres = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, MC32X0_BANDWIDTH__REG, bw, 1 );
+
+ *bw = MC32X0_GET_BITSLICE(*bw, MC32X0_BANDWIDTH);
+
+ return comres;
+
+}
+
+
+int mc32x0_read_accel_x(short *a_x)
+{
+ int comres;
+ unsigned char data[2];
+
+
+ if (p_mc32x0==0)
+ return E_NULL_PTR;
+
+ comres = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, MC32X0_XOUT_EX_L_REG, &data[0],2);
+
+ *a_x = ((short)data[0])|(((short)data[1])<<8);
+
+ return comres;
+
+}
+
+
+
+int mc32x0_read_accel_y(short *a_y)
+{
+ int comres;
+ unsigned char data[2];
+
+
+ if (p_mc32x0==0)
+ return E_NULL_PTR;
+
+ comres = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, MC32X0_YOUT_EX_L_REG, &data[0],2);
+
+ *a_y = ((short)data[0])|(((short)data[1])<<8);
+
+ return comres;
+}
+
+
+int mc32x0_read_accel_z(short *a_z)
+{
+ int comres;
+ unsigned char data[2];
+
+ if (p_mc32x0==0)
+ return E_NULL_PTR;
+
+ comres = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, MC32X0_ZOUT_EX_L_REG, &data[0],2);
+
+ *a_z = ((short)data[0])|(((short)data[1])<<8);
+
+ return comres;
+}
+
+
+int mc32x0_read_accel_xyz(mc32x0acc_t * acc)
+{
+ int comres;
+ unsigned char data[6];
+
+
+ if (p_mc32x0==0)
+ return E_NULL_PTR;
+
+#ifdef MC32X0_HIGH_END
+ comres = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, MC32X0_XOUT_EX_L_REG, &data[0],6);
+
+ acc->x = ((signed short)data[0])|(((signed short)data[1])<<8);
+ acc->y = ((signed short)data[2])|(((signed short)data[3])<<8);
+ acc->z = ((signed short)data[4])|(((signed short)data[5])<<8);
+#endif
+
+#ifdef MC32X0_LOW_END
+ comres = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, MC32X0_XOUT_REG, &data[0],3);
+
+#ifndef MCUBE_1_5G_6BIT
+ acc->x = (signed char)data[0];
+ acc->y = (signed char)data[1];
+ acc->z = (signed char)data[2];
+#else
+ acc->x = (signed short)GET_REAL_VALUE(data[0],6);
+ acc->y = (signed short)GET_REAL_VALUE(data[1],6);
+ acc->z = (signed short)GET_REAL_VALUE(data[2],6);
+#endif
+
+#endif
+
+
+
+
+ return comres;
+
+}
+
+
+
+int mc32x0_get_interrupt_status(unsigned char * ist)
+{
+
+ int comres=0;
+ if (p_mc32x0==0)
+ return E_NULL_PTR;
+ comres = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, MC32X0_Tilt_Status_REG, ist, 1);
+ return comres;
+}
+
+
+
+int mc32x0_read_reg(unsigned char addr, unsigned char *data, unsigned char len)
+{
+
+ int comres;
+ if (p_mc32x0==0)
+ return E_NULL_PTR;
+
+ comres = p_mc32x0->MC32X0_BUS_READ_FUNC(p_mc32x0->dev_addr, addr, data, len);
+ return comres;
+
+}
+
+
+int mc32x0_write_reg(unsigned char addr, unsigned char *data, unsigned char len)
+{
+
+ int comres;
+
+ if (p_mc32x0==0)
+ return E_NULL_PTR;
+
+ comres = p_mc32x0->MC32X0_BUS_WRITE_FUNC(p_mc32x0->dev_addr, addr, data, len);
+
+ return comres;
+
+}
+
diff --git a/drivers/input/sensor/mc3230_gsensor/mc32x0_driver.h b/drivers/input/sensor/mc3230_gsensor/mc32x0_driver.h new file mode 100755 index 00000000..0aca80e8 --- /dev/null +++ b/drivers/input/sensor/mc3230_gsensor/mc32x0_driver.h @@ -0,0 +1,219 @@ +/*
+ * Copyright (C) 2011 MCUBE, Inc.
+ *
+ * Initial Code:
+ * Tan Liang
+ */
+
+
+
+#ifndef __MC32X0_H__
+#define __MC32X0_H__
+
+
+
+#define MC32X0_WR_FUNC_PTR char (* bus_write)(unsigned char, unsigned char *, unsigned char)
+
+#define MC32X0_BUS_WRITE_FUNC(dev_addr, reg_addr, reg_data, wr_len)\
+ bus_write(reg_addr, reg_data, wr_len)
+
+#define MC32X0_RD_FUNC_PTR char (* bus_read)( unsigned char, unsigned char *, unsigned char)
+
+#define MC32X0_BUS_READ_FUNC(dev_addr, reg_addr, reg_data, r_len)\
+ bus_read(reg_addr, reg_data, r_len)
+
+#define GET_REAL_VALUE(rv, bn) \
+ ((rv & (0x01 << (bn - 1))) ? (- (rv & ~(0xffff << (bn - 1)))) : (rv & ~(0xffff << (bn - 1))))
+
+
+
+//#define MC32X0_HIGH_END
+/*******MC3210/20 define this**********/
+
+//#define MCUBE_2G_10BIT_TAP
+//#define MCUBE_2G_10BIT
+//#define MCUBE_8G_14BIT_TAP
+//#define MCUBE_8G_14BIT
+
+
+
+//#define MC32X0_LOW_END
+/*******MC3230 define this**********/
+
+//#define MCUBE_1_5G_8BIT
+//#define MCUBE_1_5G_8BIT_TAP
+
+
+
+
+
+/** MC32X0 I2C Address
+*/
+
+#define MC32X0_I2C_ADDR 0x4c // 0x98 >> 1
+
+
+
+/*
+ MC32X0 API error codes
+*/
+
+#define E_NULL_PTR (char)-127
+
+/*
+ *
+ * register definitions
+ *
+ */
+
+#define MC32X0_XOUT_REG 0x00
+#define MC32X0_YOUT_REG 0x01
+#define MC32X0_ZOUT_REG 0x02
+#define MC32X0_Tilt_Status_REG 0x03
+#define MC32X0_Sampling_Rate_Status_REG 0x04
+#define MC32X0_Sleep_Count_REG 0x05
+#define MC32X0_Interrupt_Enable_REG 0x06
+#define MC32X0_Mode_Feature_REG 0x07
+#define MC32X0_Sample_Rate_REG 0x08
+#define MC32X0_Tap_Detection_Enable_REG 0x09
+#define MC32X0_TAP_Dwell_Reject_REG 0x0a
+#define MC32X0_DROP_Control_Register_REG 0x0b
+#define MC32X0_SHAKE_Debounce_REG 0x0c
+#define MC32X0_XOUT_EX_L_REG 0x0d
+#define MC32X0_XOUT_EX_H_REG 0x0e
+#define MC32X0_YOUT_EX_L_REG 0x0f
+#define MC32X0_YOUT_EX_H_REG 0x10
+#define MC32X0_ZOUT_EX_L_REG 0x11
+#define MC32X0_ZOUT_EX_H_REG 0x12
+#define MC32X0_CHIP_ID 0x18
+#define MC32X0_RANGE_Control_REG 0x20
+#define MC32X0_SHAKE_Threshold_REG 0x2B
+#define MC32X0_UD_Z_TH_REG 0x2C
+#define MC32X0_UD_X_TH_REG 0x2D
+#define MC32X0_RL_Z_TH_REG 0x2E
+#define MC32X0_RL_Y_TH_REG 0x2F
+#define MC32X0_FB_Z_TH_REG 0x30
+#define MC32X0_DROP_Threshold_REG 0x31
+#define MC32X0_TAP_Threshold_REG 0x32
+
+
+
+
+/** MC32X0 acceleration data
+ \brief Structure containing acceleration values for x,y and z-axis in signed short
+
+*/
+
+typedef struct {
+ short x, /**< holds x-axis acceleration data sign extended. Range -512 to 511. */
+ y, /**< holds y-axis acceleration data sign extended. Range -512 to 511. */
+ z; /**< holds z-axis acceleration data sign extended. Range -512 to 511. */
+} mc32x0acc_t;
+
+/* RANGE */
+
+#define MC32X0_RANGE__POS 2
+#define MC32X0_RANGE__LEN 2
+#define MC32X0_RANGE__MSK 0x0c
+#define MC32X0_RANGE__REG MC32X0_RANGE_Control_REG
+
+/* MODE */
+
+#define MC32X0_MODE__POS 0
+#define MC32X0_MODE__LEN 2
+#define MC32X0_MODE__MSK 0x03
+#define MC32X0_MODE__REG MC32X0_Mode_Feature_REG
+
+#define MC32X0_MODE_DEF 0x43
+
+
+/* BANDWIDTH */
+
+#define MC32X0_BANDWIDTH__POS 4
+#define MC32X0_BANDWIDTH__LEN 3
+#define MC32X0_BANDWIDTH__MSK 0x70
+#define MC32X0_BANDWIDTH__REG MC32X0_RANGE_Control_REG
+
+
+#define MC32X0_GET_BITSLICE(regvar, bitname)\
+ (regvar & bitname##__MSK) >> bitname##__POS
+
+
+#define MC32X0_SET_BITSLICE(regvar, bitname, val)\
+ (regvar & ~bitname##__MSK) | ((val<<bitname##__POS)&bitname##__MSK)
+
+
+
+
+
+
+#define MC32X0_RANGE_2G 0
+#define MC32X0_RANGE_4G 1
+#define MC32X0_RANGE_8G 2
+
+
+#define MC32X0_WAKE 1
+#define MC32X0_SNIFF 2
+#define MC32X0_STANDBY 3
+
+
+#define MC32X0_LOW_PASS_512HZ 0
+#define MC32X0_LOW_PASS_256HZ 1
+#define MC32X0_LOW_PASS_128HZ 2
+#define MC32X0_LOW_PASS_64HZ 3
+#define MC32X0_LOW_PASS_32HZ 4
+#define MC32X0_LOW_PASS_16HZ 5
+#define MC32X0_LOW_PASS_8HZ 6
+
+
+
+
+
+typedef struct {
+ unsigned char mode; /**< save current MC32X0 operation mode */
+ unsigned char chip_id; /**< save MC32X0's chip id which has to be 0x00/0x01 after calling mc32x0_init() */
+ unsigned char dev_addr; /**< initializes MC32X0's I2C device address 0x4c */
+ MC32X0_WR_FUNC_PTR; /**< function pointer to the SPI/I2C write function */
+ MC32X0_RD_FUNC_PTR; /**< function pointer to the SPI/I2C read function */
+} mc32x0_t;
+
+
+
+/* Function prototypes */
+
+
+
+
+int mcube_mc32x0_init(mc32x0_t *mc32x0);
+
+int mc32x0_set_image (struct i2c_client *client) ;
+
+int mc32x0_set_range(char);
+
+int mc32x0_get_range(unsigned char*);
+
+int mc32x0_set_mode(struct i2c_client *client, unsigned char mode);
+
+int mc32x0_get_mode(unsigned char *);
+
+int mc32x0_set_bandwidth(char);
+
+int mc32x0_get_bandwidth(unsigned char *);
+
+int mc32x0_read_accel_x(short *);
+
+int mc32x0_read_accel_y(short *);
+
+int mc32x0_read_accel_z(short *);
+
+int mc32x0_read_accel_xyz(struct i2c_client *client, s16 * acc);
+
+int mc32x0_get_interrupt_status(unsigned char *);
+
+int mc32x0_read_reg(unsigned char , unsigned char *, unsigned char);
+
+int mc32x0_write_reg(unsigned char , unsigned char*, unsigned char );
+
+
+#endif
+
|