input: sensors: fromdos and remove trailing whitespace
authorHuang, Tao <huangtao@rock-chips.com>
Wed, 16 Nov 2016 02:25:18 +0000 (10:25 +0800)
committerHuang, Tao <huangtao@rock-chips.com>
Wed, 16 Nov 2016 03:32:49 +0000 (11:32 +0800)
Change-Id: I6799f2538f95953d1565ac805497161ce6043855
Signed-off-by: Huang, Tao <huangtao@rock-chips.com>
25 files changed:
drivers/input/sensors/Makefile
drivers/input/sensors/accel/dmard10.c
drivers/input/sensors/accel/lsm303d.c
drivers/input/sensors/angle/Makefile
drivers/input/sensors/compass/ak09911.c
drivers/input/sensors/compass/ak8963.c
drivers/input/sensors/compass/ak8975.c
drivers/input/sensors/gyro/ewtsa.c
drivers/input/sensors/gyro/l3g20d.c
drivers/input/sensors/gyro/l3g4200d.c
drivers/input/sensors/lsensor/cm3217.c
drivers/input/sensors/lsensor/cm3232.c
drivers/input/sensors/lsensor/isl29023.c
drivers/input/sensors/lsensor/ls_al3006.c
drivers/input/sensors/lsensor/ls_ap321xx.c
drivers/input/sensors/lsensor/ls_stk3171.c
drivers/input/sensors/lsensor/ls_us5152.c
drivers/input/sensors/pressure/pr_ms5607.c
drivers/input/sensors/psensor/ps_al3006.c
drivers/input/sensors/psensor/ps_ap321xx.c
drivers/input/sensors/psensor/ps_stk3171.c
drivers/input/sensors/sensor-dev.c
drivers/input/sensors/sensor-i2c.c
drivers/input/sensors/temperature/tmp_ms5607.c
include/linux/sensor-dev.h

index 100e65c..ffd1651 100755 (executable)
@@ -1,14 +1,14 @@
-# sensor drivers\r
-obj-$(CONFIG_ANGLE_DEVICE)                    += angle/\r
-obj-$(CONFIG_GSENSOR_DEVICE)                   += accel/\r
-obj-$(CONFIG_COMPASS_DEVICE)                   += compass/\r
-obj-$(CONFIG_GYROSCOPE_DEVICE)                 += gyro/\r
-obj-$(CONFIG_LIGHT_DEVICE)                             += lsensor/\r
-obj-$(CONFIG_PROXIMITY_DEVICE)                 += psensor/\r
-obj-$(CONFIG_TEMPERATURE_DEVICE)               += temperature/\r
-obj-$(CONFIG_PRESSURE_DEVICE)                  += pressure/\r
-obj-$(CONFIG_HALL_DEVICE)                      += hall/\r
-\r
-\r
-obj-$(CONFIG_SENSOR_DEVICE)                            += sensor-i2c.o\r
-obj-$(CONFIG_SENSOR_DEVICE)                            += sensor-dev.o\r
+# sensor drivers
+obj-$(CONFIG_ANGLE_DEVICE)                    += angle/
+obj-$(CONFIG_GSENSOR_DEVICE)                   += accel/
+obj-$(CONFIG_COMPASS_DEVICE)                   += compass/
+obj-$(CONFIG_GYROSCOPE_DEVICE)                 += gyro/
+obj-$(CONFIG_LIGHT_DEVICE)                             += lsensor/
+obj-$(CONFIG_PROXIMITY_DEVICE)                 += psensor/
+obj-$(CONFIG_TEMPERATURE_DEVICE)               += temperature/
+obj-$(CONFIG_PRESSURE_DEVICE)                  += pressure/
+obj-$(CONFIG_HALL_DEVICE)                      += hall/
+
+
+obj-$(CONFIG_SENSOR_DEVICE)                            += sensor-i2c.o
+obj-$(CONFIG_SENSOR_DEVICE)                            += sensor-dev.o
index f695818..db1545a 100755 (executable)
-/* drivers/input/sensors/access/dmard10.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: guoyi <gy@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-/* Default register settings */\r
-#define RBUFF_SIZE             12      /* Rx buffer size */\r
-\r
-#define REG_ACTR                               0x00\r
-#define REG_WDAL                               0x01\r
-#define REG_TAPNS                              0x0f\r
-#define REG_MISC2                              0x1f\r
-#define REG_AFEM                               0x0c\r
-#define REG_CKSEL                              0x0d\r
-#define REG_INTC                               0x0e\r
-#define REG_STADR                              0x12\r
-#define REG_STAINT                             0x1C\r
-#define REG_PD                                 0x21\r
-#define REG_TCGYZ                              0x26\r
-#define REG_X_OUT                              0x41\r
-\r
-#define MODE_Off                               0x00\r
-#define MODE_ResetAtOff                        0x01\r
-#define MODE_Standby                   0x02\r
-#define MODE_ResetAtStandby            0x03\r
-#define MODE_Active                            0x06\r
-#define MODE_Trigger                   0x0a\r
-#define MODE_ReadOTP                   0x12\r
-#define MODE_WriteOTP                  0x22\r
-#define MODE_WriteOTPBuf               0x42\r
-#define MODE_ResetDataPath             0x82\r
-\r
-#define VALUE_STADR                                    0x55\r
-#define VALUE_STAINT                           0xAA\r
-#define VALUE_AFEM_AFEN_Normal         0x8f// AFEN set 1 , ATM[2:0]=b'000(normal),EN_Z/Y/X/T=1\r
-#define VALUE_AFEM_Normal                      0x0f// AFEN set 0 , ATM[2:0]=b'000(normal),EN_Z/Y/X/T=1\r
-#define VALUE_INTC                                     0x00// INTC[6:5]=b'00 \r
-#define VALUE_INTC_Interrupt_En                0x20// INTC[6:5]=b'01 (Data ready interrupt enable, active high at INT0)\r
-#define VALUE_CKSEL_ODR_0_204          0x04// ODR[3:0]=b'0000 (0.78125Hz), CCK[3:0]=b'0100 (204.8kHZ)\r
-#define VALUE_CKSEL_ODR_1_204          0x14// ODR[3:0]=b'0001 (1.5625Hz), CCK[3:0]=b'0100 (204.8kHZ)\r
-#define VALUE_CKSEL_ODR_3_204          0x24// ODR[3:0]=b'0010 (3.125Hz), CCK[3:0]=b'0100 (204.8kHZ)\r
-#define VALUE_CKSEL_ODR_6_204          0x34// ODR[3:0]=b'0011 (6.25Hz), CCK[3:0]=b'0100 (204.8kHZ)\r
-#define VALUE_CKSEL_ODR_12_204         0x44// ODR[3:0]=b'0100 (12.5Hz), CCK[3:0]=b'0100 (204.8kHZ)\r
-#define VALUE_CKSEL_ODR_25_204         0x54// ODR[3:0]=b'0101 (25Hz), CCK[3:0]=b'0100 (204.8kHZ)\r
-#define VALUE_CKSEL_ODR_50_204         0x64// ODR[3:0]=b'0110 (50Hz), CCK[3:0]=b'0100 (204.8kHZ)\r
-#define VALUE_CKSEL_ODR_100_204                0x74// ODR[3:0]=b'0111 (100Hz), CCK[3:0]=b'0100 (204.8kHZ)\r
-\r
-#define VALUE_TAPNS_NoFilter   0x00    // TAP1/TAP2    NO FILTER\r
-#define VALUE_TAPNS_Ave_2              0x11    // TAP1/TAP2    Average 2\r
-#define VALUE_TAPNS_Ave_4              0x22    // TAP1/TAP2    Average 4\r
-#define VALUE_TAPNS_Ave_8              0x33    // TAP1/TAP2    Average 8\r
-#define VALUE_TAPNS_Ave_16             0x44    // TAP1/TAP2    Average 16\r
-#define VALUE_TAPNS_Ave_32             0x55    // TAP1/TAP2    Average 32\r
-#define VALUE_MISC2_OSCA_EN            0x08\r
-#define VALUE_PD_RST                   0x52\r
-\r
-\r
-//#define DMARD10_REG_INTSU        0x47\r
-//#define DMARD10_REG_MODE        0x44\r
-//#define DMARD10_REG_SR               0x44\r
-\r
-\r
-#define DMARD10_REG_DS      0X49\r
-#define DMARD10_REG_ID       0X0F\r
-#define DMARD10_REG_IT       0X4D\r
-#define DMARD10_REG_INTSRC1_C       0X4A\r
-#define DMARD10_REG_INTSRC1_S       0X4B\r
-#define MMAIO                          0xA1\r
-\r
-// IOCTLs for DMARD10 library \r
-#define ECS_IOCTL_INIT                  _IO(MMAIO, 0x01)\r
-#define ECS_IOCTL_RESET                _IO(MMAIO, 0x04)\r
-#define ECS_IOCTL_CLOSE                        _IO(MMAIO, 0x02)\r
-#define ECS_IOCTL_START                        _IO(MMAIO, 0x03)\r
-#define ECS_IOCTL_GETDATA               _IOR(MMAIO, 0x08, char[RBUFF_SIZE+1])\r
-#define SENSOR_CALIBRATION             _IOWR(MMAIO, 0x05 , int[SENSOR_DATA_SIZE])\r
-        \r
-// IOCTLs for APPs \r
-#define ECS_IOCTL_APP_SET_RATE         _IOW(MMAIO, 0x10, char)\r
-\r
- //rate\r
-#define DMARD10_RANGE                                          2000000\r
-\r
-#define DMARD10_RATE_32         32\r
-/*\r
-#define DMARD10_RATE_64         64\r
-#define DMARD10_RATE_120        128\r
-#define DMARD10_RATE_MIN               DMARD10_RATE_1\r
-#define DMARD10_RATE_MAX               DMARD10_RATE_120\r
-*/\r
-/*status*/\r
-#define DMARD10_OPEN               1\r
-#define DMARD10_CLOSE              0\r
-#define DMARD10_NORMAL            2\r
-#define DMARD10_LOWPOWER          3\r
-\r
-\r
-\r
-#define DMARD10_IIC_ADDR           0x18  \r
-#define DMARD10_REG_LEN         11\r
-\r
-\r
-#define DMARD10_FATOR  15 \r
-\r
-\r
-#define DMARD10_X_OUT          0x41\r
-#define SENSOR_DATA_SIZE 3\r
-#define DMARD10_SENSOR_RATE_1   0\r
-#define DMARD10_SENSOR_RATE_2   1\r
-#define DMARD10_SENSOR_RATE_3   2\r
-#define DMARD10_SENSOR_RATE_4   3\r
-\r
-#define POWER_OR_RATE 1\r
-#define SW_RESET 1\r
-#define DMARD10_INTERRUPUT 1\r
-#define DMARD10_POWERDOWN 0 \r
-#define DMARD10_POWERON 1 \r
-\r
-//g-senor layout configuration, choose one of the following configuration\r
-\r
-#define AVG_NUM                        16\r
-#define SENSOR_DATA_SIZE               3 \r
-#define DEFAULT_SENSITIVITY            1024\r
-\r
-\r
-\r
-#define DMARD10_ENABLE         1\r
-\r
-#define DMARD10_REG_X_OUT       0x12\r
-#define DMARD10_REG_Y_OUT       0x1\r
-#define DMARD10_REG_Z_OUT       0x2\r
-#define DMARD10_REG_TILT        0x3\r
-#define DMARD10_REG_SRST        0x4\r
-#define DMARD10_REG_SPCNT       0x5\r
-#define DMARD10_REG_INTSU       0x6\r
-#define DMARD10_REG_MODE        0x7\r
-#define DMARD10_REG_SR          0x8\r
-#define DMARD10_REG_PDET        0x9\r
-#define DMARD10_REG_PD          0xa\r
-\r
-#define DMARD10_RANGE                  4000000\r
-#define DMARD10_PRECISION       10\r
-#define DMARD10_BOUNDARY        (0x1 << (DMARD10_PRECISION  - 1)) \r
-#define DMARD10_GRAVITY_STEP    (DMARD10_RANGE / DMARD10_BOUNDARY)\r
-\r
-\r
-struct sensor_axis_average {\r
-               int x_average;\r
-               int y_average;\r
-               int z_average;\r
-               int count;\r
-};\r
-\r
-static struct sensor_axis_average axis_average;\r
-int gsensor_reset(struct i2c_client *client){\r
-       struct sensor_private_data *sensor =\r
-           (struct sensor_private_data *) i2c_get_clientdata(client);  \r
-       \r
-       char buffer[7], buffer2[2];\r
-       /* 1. check D10 , VALUE_STADR = 0x55 , VALUE_STAINT = 0xAA */\r
-       buffer[0] = REG_STADR;\r
-       buffer2[0] = REG_STAINT;\r
-       \r
-       sensor_rx_data(client, buffer, 2);\r
-       sensor_rx_data(client, buffer2, 2);\r
-               \r
-       if( buffer[0] == VALUE_STADR || buffer2[0] == VALUE_STAINT){\r
-               DBG(KERN_INFO " REG_STADR_VALUE = %d , REG_STAINT_VALUE = %d\n", buffer[0], buffer2[0]);\r
-               DBG(KERN_INFO " %s DMT_DEVICE_NAME registered I2C driver!\n",__FUNCTION__);\r
-       }\r
-       else{\r
-               DBG(KERN_INFO " %s gsensor I2C err @@@ REG_STADR_VALUE = %d , REG_STAINT_VALUE = %d \n", __func__, buffer[0], buffer2[0]);\r
-               return -1;\r
-       }\r
-       /* 2. Powerdown reset */\r
-       buffer[0] = REG_PD;\r
-       buffer[1] = VALUE_PD_RST;\r
-       sensor_tx_data(client, buffer, 2);\r
-       /* 3. ACTR => Standby mode => Download OTP to parameter reg => Standby mode => Reset data path => Standby mode */\r
-       buffer[0] = REG_ACTR;\r
-       buffer[1] = MODE_Standby;\r
-       buffer[2] = MODE_ReadOTP;\r
-       buffer[3] = MODE_Standby;\r
-       buffer[4] = MODE_ResetDataPath;\r
-       buffer[5] = MODE_Standby;\r
-       sensor_tx_data(client, buffer, 6);\r
-       /* 4. OSCA_EN = 1 ,TSTO = b'000(INT1 = normal, TEST0 = normal) */\r
-       buffer[0] = REG_MISC2;\r
-       buffer[1] = VALUE_MISC2_OSCA_EN;\r
-       sensor_tx_data(client, buffer, 2);\r
-       /* 5. AFEN = 1(AFE will powerdown after ADC) */\r
-       buffer[0] = REG_AFEM;\r
-       buffer[1] = VALUE_AFEM_AFEN_Normal;     \r
-       buffer[2] = VALUE_CKSEL_ODR_100_204;    \r
-       buffer[3] = VALUE_INTC; \r
-       buffer[4] = VALUE_TAPNS_Ave_2;\r
-       buffer[5] = 0x00;       // DLYC, no delay timing\r
-       buffer[6] = 0x07;       // INTD=1 (push-pull), INTA=1 (active high), AUTOT=1 (enable T)\r
-       sensor_tx_data(client, buffer, 7);\r
-       /* 6. write TCGYZ & TCGX */\r
-       buffer[0] = REG_WDAL;   // REG:0x01\r
-       buffer[1] = 0x00;               // set TC of Y,Z gain value\r
-       buffer[2] = 0x00;               // set TC of X gain value\r
-       buffer[3] = 0x03;               // Temperature coefficient of X,Y,Z gain\r
-       sensor_tx_data(client, buffer, 4);\r
-       \r
-       buffer[0] = REG_ACTR;                   // REG:0x00\r
-       buffer[1] = MODE_Standby;               // Standby\r
-       buffer[2] = MODE_WriteOTPBuf;   // WriteOTPBuf \r
-       buffer[3] = MODE_Standby;               // Standby\r
-       \r
-       /* 7. Activation mode */\r
-       buffer[0] = REG_ACTR;\r
-       buffer[1] = MODE_Active;\r
-       sensor_tx_data(client, buffer, 2);\r
-       printk("\n dmard10 gsensor _reset SUCCESS!!\n");\r
-       return 0;\r
-}\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
-       struct sensor_private_data *sensor =\r
-           (struct sensor_private_data *) i2c_get_clientdata(client);  \r
-       int result = 0;\r
-       int status = 0;\r
-               gsensor_reset(client);\r
-       sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
-       //register setting according to chip datasheet          \r
-       if(enable)\r
-       {       \r
-               status = DMARD10_ENABLE;        //dmard10\r
-               sensor->ops->ctrl_data |= status;       \r
-       }\r
-       else\r
-       {\r
-               status = ~DMARD10_ENABLE;       //dmard10\r
-               sensor->ops->ctrl_data &= status;\r
-       }\r
-\r
-       DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
-       result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
-       if(result)\r
-               printk("%s:fail to active sensor\n",__func__);\r
-       \r
-       return result;\r
-\r
-}\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{      \r
-       struct sensor_private_data *sensor =\r
-           (struct sensor_private_data *) i2c_get_clientdata(client);  \r
-       int result = 0;\r
-       \r
-       result = sensor->ops->active(client,0,0);\r
-       if(result)\r
-       {\r
-               printk("%s:line=%d,error\n",__func__,__LINE__);\r
-               return result;\r
-       }\r
-       \r
-       sensor->status_cur = SENSOR_OFF;\r
-\r
-       DBG("%s:DMARD10_REG_TILT=0x%x\n",__func__,sensor_read_reg(client, DMARD10_REG_TILT));\r
-\r
-       result = sensor_write_reg(client, DMARD10_REG_SR, (0x01<<5)| 0x02);     //32 Samples/Second Active and Auto-Sleep Mode\r
-       if(result)\r
-       {\r
-               printk("%s:line=%d,error\n",__func__,__LINE__);\r
-               return result;\r
-       }\r
-\r
-       if(sensor->pdata->irq_enable)   //open interrupt\r
-       {\r
-               result = sensor_write_reg(client, DMARD10_REG_INTSU, 1<<4);//enable int,GINT=1\r
-               if(result)\r
-               {\r
-                       printk("%s:line=%d,error\n",__func__,__LINE__);\r
-                       return result;\r
-               }\r
-       }\r
-       \r
-       sensor->ops->ctrl_data = 1<<6;  //Interrupt output INT is push-pull\r
-       result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
-       if(result)\r
-       {\r
-               printk("%s:line=%d,error\n",__func__,__LINE__);\r
-               return result;\r
-       }\r
-\r
-       \r
-       memset(&axis_average, 0, sizeof(struct sensor_axis_average));\r
-\r
-       return result;\r
-}\r
-\r
-\r
-static int sensor_convert_data(struct i2c_client *client, char high_byte, char low_byte)\r
-{\r
-    s64 result;\r
-       \r
-        \r
-               result = ((int)high_byte << 8)|((int)low_byte);\r
-       \r
-               if (result < DMARD10_BOUNDARY){\r
-                       result = result* DMARD10_GRAVITY_STEP;\r
-               }else{\r
-                       result = ~( ((~result & (0x7fff>>(16-DMARD10_PRECISION)) ) + 1)* DMARD10_GRAVITY_STEP) + 1;\r
-               }\r
-                       \r
-               return result;\r
-\r
-}\r
-\r
-static int gsensor_report_value(struct i2c_client *client, struct sensor_axis *axis)\r
-{\r
-       struct sensor_private_data *sensor =\r
-           (struct sensor_private_data *) i2c_get_clientdata(client);  \r
-\r
-       /* Report acceleration sensor information */\r
-       input_report_abs(sensor->input_dev, ABS_X, axis->x);\r
-       input_report_abs(sensor->input_dev, ABS_Y, axis->y);\r
-       input_report_abs(sensor->input_dev, ABS_Z, axis->z);\r
-       input_sync(sensor->input_dev);\r
-       DBG("Gsensor x==%d  y==%d z==%d\n",axis->x,axis->y,axis->z);\r
-\r
-       return 0;\r
-}\r
-#define DMARD10_COUNT_AVERAGE 2\r
-#define GSENSOR_MIN            2\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
-       struct sensor_private_data *sensor =\r
-               (struct sensor_private_data *) i2c_get_clientdata(client);      \r
-       struct sensor_platform_data *pdata = sensor->pdata;\r
-       int ret = 0;\r
-       int x,y,z;\r
-       struct sensor_axis axis;\r
-       char buffer[8] = {0};   \r
-       char value = 0;\r
-       \r
-       if(sensor->ops->read_len < 3)   //sensor->ops->read_len = 3\r
-       {\r
-               printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
-               return -1;\r
-       }\r
-       \r
-       memset(buffer, 0, 8);\r
-       /* Data bytes from hardware xL, xH, yL, yH, zL, zH */   \r
-       do {\r
-               *buffer = sensor->ops->read_reg;\r
-               ret = sensor_rx_data(client, buffer, sensor->ops->read_len);\r
-               if (ret < 0)\r
-               return ret;\r
-       } while (0);\r
-\r
-       //this gsensor need 6 bytes buffer\r
-       x = sensor_convert_data(sensor->client, buffer[3], buffer[2]);  //buffer[1]:high bit \r
-       y = sensor_convert_data(sensor->client, buffer[5], buffer[4]);\r
-       z = sensor_convert_data(sensor->client, buffer[7], buffer[6]);          \r
-               \r
-       axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;\r
-       axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z; \r
-       axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;\r
-\r
-       \r
-       axis_average.x_average += axis.x;\r
-       axis_average.y_average += axis.y;\r
-       axis_average.z_average += axis.z;\r
-       axis_average.count++;\r
-       \r
-       if(axis_average.count >= DMARD10_COUNT_AVERAGE)\r
-       {\r
-               axis.x = axis_average.x_average / axis_average.count;   \r
-               axis.y = axis_average.y_average / axis_average.count;   \r
-               axis.z = axis_average.z_average / axis_average.count;\r
-               \r
-               DBG( "%s: axis = %d  %d  %d \n", __func__, axis.x, axis.y, axis.z);\r
-               \r
-               memset(&axis_average, 0, sizeof(struct sensor_axis_average));\r
-               \r
-               //Report event only while value is changed to save some power\r
-               if((abs(sensor->axis.x - axis.x) > GSENSOR_MIN) || (abs(sensor->axis.y - axis.y) > GSENSOR_MIN) || (abs(sensor->axis.z - axis.z) > GSENSOR_MIN))\r
-               {\r
-                       gsensor_report_value(client, &axis);\r
-\r
-                       /* »¥³âµØ»º´æÊý¾Ý. */\r
-                       mutex_lock(&(sensor->data_mutex) );\r
-                       sensor->axis = axis;\r
-                       mutex_unlock(&(sensor->data_mutex) );\r
-               }\r
-       }\r
-       \r
-       if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0))    //read sensor intterupt status register\r
-       {\r
-               \r
-               value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
-               DBG("%s:sensor int status :0x%x\n",__func__,value);\r
-       }\r
-       \r
-       return ret;\r
-}\r
-\r
-\r
-struct sensor_operate gsensor_dmard10_ops = {\r
-       .name                           = "gs_dmard10",\r
-       .type                           = SENSOR_TYPE_ACCEL,                    //sensor type and it should be correct\r
-       .id_i2c                         = ACCEL_ID_DMARD10,                     //i2c id number\r
-       .read_reg                       = DMARD10_REG_X_OUT,                    //read data\r
-       .read_len                       = 8,                                    //data length\r
-       .id_reg                         = SENSOR_UNKNOW_DATA,                   //read device id from this register\r
-       .id_data                        = SENSOR_UNKNOW_DATA,                   //device id\r
-       .precision                      = DMARD10_PRECISION,                    //12 bit\r
-       .ctrl_reg                       = DMARD10_REG_MODE,                     //enable or disable     \r
-       .int_status_reg         = SENSOR_UNKNOW_DATA,                   //intterupt status register\r
-       .range                          = {-DMARD10_RANGE,DMARD10_RANGE},       //range\r
-       .trig                           = IRQF_TRIGGER_LOW|IRQF_ONESHOT,                \r
-       .active                         = sensor_active,        \r
-       .init                           = sensor_init,\r
-       .report                         = sensor_report_value,\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *gsensor_get_ops(void)\r
-{\r
-       return &gsensor_dmard10_ops;\r
-}\r
-\r
-\r
-static int __init gsensor_dmard10_init(void)\r
-{\r
-       struct sensor_operate *ops = gsensor_get_ops();\r
-       int result = 0;\r
-       int type = ops->type;\r
-       result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);      \r
-       return result;\r
-}\r
-\r
-static void __exit gsensor_dmard10_exit(void)\r
-{\r
-       struct sensor_operate *ops = gsensor_get_ops();\r
-       int type = ops->type;\r
-       sensor_unregister_slave(type, NULL, NULL, gsensor_get_ops);\r
-}\r
-\r
-\r
-module_init(gsensor_dmard10_init);\r
-module_exit(gsensor_dmard10_exit);\r
-\r
-\r
-\r
+/* drivers/input/sensors/access/dmard10.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: guoyi <gy@rock-chips.com>
+ *
+ * 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/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+/* Default register settings */
+#define RBUFF_SIZE             12      /* Rx buffer size */
+
+#define REG_ACTR                               0x00
+#define REG_WDAL                               0x01
+#define REG_TAPNS                              0x0f
+#define REG_MISC2                              0x1f
+#define REG_AFEM                               0x0c
+#define REG_CKSEL                              0x0d
+#define REG_INTC                               0x0e
+#define REG_STADR                              0x12
+#define REG_STAINT                             0x1C
+#define REG_PD                                 0x21
+#define REG_TCGYZ                              0x26
+#define REG_X_OUT                              0x41
+
+#define MODE_Off                               0x00
+#define MODE_ResetAtOff                        0x01
+#define MODE_Standby                   0x02
+#define MODE_ResetAtStandby            0x03
+#define MODE_Active                            0x06
+#define MODE_Trigger                   0x0a
+#define MODE_ReadOTP                   0x12
+#define MODE_WriteOTP                  0x22
+#define MODE_WriteOTPBuf               0x42
+#define MODE_ResetDataPath             0x82
+
+#define VALUE_STADR                                    0x55
+#define VALUE_STAINT                           0xAA
+#define VALUE_AFEM_AFEN_Normal         0x8f// AFEN set 1 , ATM[2:0]=b'000(normal),EN_Z/Y/X/T=1
+#define VALUE_AFEM_Normal                      0x0f// AFEN set 0 , ATM[2:0]=b'000(normal),EN_Z/Y/X/T=1
+#define VALUE_INTC                                     0x00// INTC[6:5]=b'00
+#define VALUE_INTC_Interrupt_En                0x20// INTC[6:5]=b'01 (Data ready interrupt enable, active high at INT0)
+#define VALUE_CKSEL_ODR_0_204          0x04// ODR[3:0]=b'0000 (0.78125Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_1_204          0x14// ODR[3:0]=b'0001 (1.5625Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_3_204          0x24// ODR[3:0]=b'0010 (3.125Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_6_204          0x34// ODR[3:0]=b'0011 (6.25Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_12_204         0x44// ODR[3:0]=b'0100 (12.5Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_25_204         0x54// ODR[3:0]=b'0101 (25Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_50_204         0x64// ODR[3:0]=b'0110 (50Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_100_204                0x74// ODR[3:0]=b'0111 (100Hz), CCK[3:0]=b'0100 (204.8kHZ)
+
+#define VALUE_TAPNS_NoFilter   0x00    // TAP1/TAP2    NO FILTER
+#define VALUE_TAPNS_Ave_2              0x11    // TAP1/TAP2    Average 2
+#define VALUE_TAPNS_Ave_4              0x22    // TAP1/TAP2    Average 4
+#define VALUE_TAPNS_Ave_8              0x33    // TAP1/TAP2    Average 8
+#define VALUE_TAPNS_Ave_16             0x44    // TAP1/TAP2    Average 16
+#define VALUE_TAPNS_Ave_32             0x55    // TAP1/TAP2    Average 32
+#define VALUE_MISC2_OSCA_EN            0x08
+#define VALUE_PD_RST                   0x52
+
+
+//#define DMARD10_REG_INTSU        0x47
+//#define DMARD10_REG_MODE        0x44
+//#define DMARD10_REG_SR               0x44
+
+
+#define DMARD10_REG_DS      0X49
+#define DMARD10_REG_ID       0X0F
+#define DMARD10_REG_IT       0X4D
+#define DMARD10_REG_INTSRC1_C       0X4A
+#define DMARD10_REG_INTSRC1_S       0X4B
+#define MMAIO                          0xA1
+
+// IOCTLs for DMARD10 library
+#define ECS_IOCTL_INIT                  _IO(MMAIO, 0x01)
+#define ECS_IOCTL_RESET                _IO(MMAIO, 0x04)
+#define ECS_IOCTL_CLOSE                        _IO(MMAIO, 0x02)
+#define ECS_IOCTL_START                        _IO(MMAIO, 0x03)
+#define ECS_IOCTL_GETDATA               _IOR(MMAIO, 0x08, char[RBUFF_SIZE+1])
+#define SENSOR_CALIBRATION             _IOWR(MMAIO, 0x05 , int[SENSOR_DATA_SIZE])
+
+// IOCTLs for APPs
+#define ECS_IOCTL_APP_SET_RATE         _IOW(MMAIO, 0x10, char)
+
+ //rate
+#define DMARD10_RANGE                                          2000000
+
+#define DMARD10_RATE_32         32
+/*
+#define DMARD10_RATE_64         64
+#define DMARD10_RATE_120        128
+#define DMARD10_RATE_MIN               DMARD10_RATE_1
+#define DMARD10_RATE_MAX               DMARD10_RATE_120
+*/
+/*status*/
+#define DMARD10_OPEN               1
+#define DMARD10_CLOSE              0
+#define DMARD10_NORMAL            2
+#define DMARD10_LOWPOWER          3
+
+
+
+#define DMARD10_IIC_ADDR           0x18
+#define DMARD10_REG_LEN         11
+
+
+#define DMARD10_FATOR  15
+
+
+#define DMARD10_X_OUT          0x41
+#define SENSOR_DATA_SIZE 3
+#define DMARD10_SENSOR_RATE_1   0
+#define DMARD10_SENSOR_RATE_2   1
+#define DMARD10_SENSOR_RATE_3   2
+#define DMARD10_SENSOR_RATE_4   3
+
+#define POWER_OR_RATE 1
+#define SW_RESET 1
+#define DMARD10_INTERRUPUT 1
+#define DMARD10_POWERDOWN 0
+#define DMARD10_POWERON 1
+
+//g-senor layout configuration, choose one of the following configuration
+
+#define AVG_NUM                        16
+#define SENSOR_DATA_SIZE               3
+#define DEFAULT_SENSITIVITY            1024
+
+
+
+#define DMARD10_ENABLE         1
+
+#define DMARD10_REG_X_OUT       0x12
+#define DMARD10_REG_Y_OUT       0x1
+#define DMARD10_REG_Z_OUT       0x2
+#define DMARD10_REG_TILT        0x3
+#define DMARD10_REG_SRST        0x4
+#define DMARD10_REG_SPCNT       0x5
+#define DMARD10_REG_INTSU       0x6
+#define DMARD10_REG_MODE        0x7
+#define DMARD10_REG_SR          0x8
+#define DMARD10_REG_PDET        0x9
+#define DMARD10_REG_PD          0xa
+
+#define DMARD10_RANGE                  4000000
+#define DMARD10_PRECISION       10
+#define DMARD10_BOUNDARY        (0x1 << (DMARD10_PRECISION  - 1))
+#define DMARD10_GRAVITY_STEP    (DMARD10_RANGE / DMARD10_BOUNDARY)
+
+
+struct sensor_axis_average {
+               int x_average;
+               int y_average;
+               int z_average;
+               int count;
+};
+
+static struct sensor_axis_average axis_average;
+int gsensor_reset(struct i2c_client *client){
+       struct sensor_private_data *sensor =
+           (struct sensor_private_data *) i2c_get_clientdata(client);
+
+       char buffer[7], buffer2[2];
+       /* 1. check D10 , VALUE_STADR = 0x55 , VALUE_STAINT = 0xAA */
+       buffer[0] = REG_STADR;
+       buffer2[0] = REG_STAINT;
+
+       sensor_rx_data(client, buffer, 2);
+       sensor_rx_data(client, buffer2, 2);
+
+       if( buffer[0] == VALUE_STADR || buffer2[0] == VALUE_STAINT){
+               DBG(KERN_INFO " REG_STADR_VALUE = %d , REG_STAINT_VALUE = %d\n", buffer[0], buffer2[0]);
+               DBG(KERN_INFO " %s DMT_DEVICE_NAME registered I2C driver!\n",__FUNCTION__);
+       }
+       else{
+               DBG(KERN_INFO " %s gsensor I2C err @@@ REG_STADR_VALUE = %d , REG_STAINT_VALUE = %d \n", __func__, buffer[0], buffer2[0]);
+               return -1;
+       }
+       /* 2. Powerdown reset */
+       buffer[0] = REG_PD;
+       buffer[1] = VALUE_PD_RST;
+       sensor_tx_data(client, buffer, 2);
+       /* 3. ACTR => Standby mode => Download OTP to parameter reg => Standby mode => Reset data path => Standby mode */
+       buffer[0] = REG_ACTR;
+       buffer[1] = MODE_Standby;
+       buffer[2] = MODE_ReadOTP;
+       buffer[3] = MODE_Standby;
+       buffer[4] = MODE_ResetDataPath;
+       buffer[5] = MODE_Standby;
+       sensor_tx_data(client, buffer, 6);
+       /* 4. OSCA_EN = 1 ,TSTO = b'000(INT1 = normal, TEST0 = normal) */
+       buffer[0] = REG_MISC2;
+       buffer[1] = VALUE_MISC2_OSCA_EN;
+       sensor_tx_data(client, buffer, 2);
+       /* 5. AFEN = 1(AFE will powerdown after ADC) */
+       buffer[0] = REG_AFEM;
+       buffer[1] = VALUE_AFEM_AFEN_Normal;
+       buffer[2] = VALUE_CKSEL_ODR_100_204;
+       buffer[3] = VALUE_INTC;
+       buffer[4] = VALUE_TAPNS_Ave_2;
+       buffer[5] = 0x00;       // DLYC, no delay timing
+       buffer[6] = 0x07;       // INTD=1 (push-pull), INTA=1 (active high), AUTOT=1 (enable T)
+       sensor_tx_data(client, buffer, 7);
+       /* 6. write TCGYZ & TCGX */
+       buffer[0] = REG_WDAL;   // REG:0x01
+       buffer[1] = 0x00;               // set TC of Y,Z gain value
+       buffer[2] = 0x00;               // set TC of X gain value
+       buffer[3] = 0x03;               // Temperature coefficient of X,Y,Z gain
+       sensor_tx_data(client, buffer, 4);
+
+       buffer[0] = REG_ACTR;                   // REG:0x00
+       buffer[1] = MODE_Standby;               // Standby
+       buffer[2] = MODE_WriteOTPBuf;   // WriteOTPBuf
+       buffer[3] = MODE_Standby;               // Standby
+
+       /* 7. Activation mode */
+       buffer[0] = REG_ACTR;
+       buffer[1] = MODE_Active;
+       sensor_tx_data(client, buffer, 2);
+       printk("\n dmard10 gsensor _reset SUCCESS!!\n");
+       return 0;
+}
+
+/****************operate according to sensor chip:start************/
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+       struct sensor_private_data *sensor =
+           (struct sensor_private_data *) i2c_get_clientdata(client);
+       int result = 0;
+       int status = 0;
+               gsensor_reset(client);
+       sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
+       //register setting according to chip datasheet
+       if(enable)
+       {
+               status = DMARD10_ENABLE;        //dmard10
+               sensor->ops->ctrl_data |= status;
+       }
+       else
+       {
+               status = ~DMARD10_ENABLE;       //dmard10
+               sensor->ops->ctrl_data &= status;
+       }
+
+       DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
+       result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+       if(result)
+               printk("%s:fail to active sensor\n",__func__);
+
+       return result;
+
+}
+
+static int sensor_init(struct i2c_client *client)
+{
+       struct sensor_private_data *sensor =
+           (struct sensor_private_data *) i2c_get_clientdata(client);
+       int result = 0;
+
+       result = sensor->ops->active(client,0,0);
+       if(result)
+       {
+               printk("%s:line=%d,error\n",__func__,__LINE__);
+               return result;
+       }
+
+       sensor->status_cur = SENSOR_OFF;
+
+       DBG("%s:DMARD10_REG_TILT=0x%x\n",__func__,sensor_read_reg(client, DMARD10_REG_TILT));
+
+       result = sensor_write_reg(client, DMARD10_REG_SR, (0x01<<5)| 0x02);     //32 Samples/Second Active and Auto-Sleep Mode
+       if(result)
+       {
+               printk("%s:line=%d,error\n",__func__,__LINE__);
+               return result;
+       }
+
+       if(sensor->pdata->irq_enable)   //open interrupt
+       {
+               result = sensor_write_reg(client, DMARD10_REG_INTSU, 1<<4);//enable int,GINT=1
+               if(result)
+               {
+                       printk("%s:line=%d,error\n",__func__,__LINE__);
+                       return result;
+               }
+       }
+
+       sensor->ops->ctrl_data = 1<<6;  //Interrupt output INT is push-pull
+       result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+       if(result)
+       {
+               printk("%s:line=%d,error\n",__func__,__LINE__);
+               return result;
+       }
+
+
+       memset(&axis_average, 0, sizeof(struct sensor_axis_average));
+
+       return result;
+}
+
+
+static int sensor_convert_data(struct i2c_client *client, char high_byte, char low_byte)
+{
+    s64 result;
+
+
+               result = ((int)high_byte << 8)|((int)low_byte);
+
+               if (result < DMARD10_BOUNDARY){
+                       result = result* DMARD10_GRAVITY_STEP;
+               }else{
+                       result = ~( ((~result & (0x7fff>>(16-DMARD10_PRECISION)) ) + 1)* DMARD10_GRAVITY_STEP) + 1;
+               }
+
+               return result;
+
+}
+
+static int gsensor_report_value(struct i2c_client *client, struct sensor_axis *axis)
+{
+       struct sensor_private_data *sensor =
+           (struct sensor_private_data *) i2c_get_clientdata(client);
+
+       /* Report acceleration sensor information */
+       input_report_abs(sensor->input_dev, ABS_X, axis->x);
+       input_report_abs(sensor->input_dev, ABS_Y, axis->y);
+       input_report_abs(sensor->input_dev, ABS_Z, axis->z);
+       input_sync(sensor->input_dev);
+       DBG("Gsensor x==%d  y==%d z==%d\n",axis->x,axis->y,axis->z);
+
+       return 0;
+}
+#define DMARD10_COUNT_AVERAGE 2
+#define GSENSOR_MIN            2
+static int sensor_report_value(struct i2c_client *client)
+{
+       struct sensor_private_data *sensor =
+               (struct sensor_private_data *) i2c_get_clientdata(client);
+       struct sensor_platform_data *pdata = sensor->pdata;
+       int ret = 0;
+       int x,y,z;
+       struct sensor_axis axis;
+       char buffer[8] = {0};
+       char value = 0;
+
+       if(sensor->ops->read_len < 3)   //sensor->ops->read_len = 3
+       {
+               printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
+               return -1;
+       }
+
+       memset(buffer, 0, 8);
+       /* Data bytes from hardware xL, xH, yL, yH, zL, zH */
+       do {
+               *buffer = sensor->ops->read_reg;
+               ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
+               if (ret < 0)
+               return ret;
+       } while (0);
+
+       //this gsensor need 6 bytes buffer
+       x = sensor_convert_data(sensor->client, buffer[3], buffer[2]);  //buffer[1]:high bit
+       y = sensor_convert_data(sensor->client, buffer[5], buffer[4]);
+       z = sensor_convert_data(sensor->client, buffer[7], buffer[6]);
+
+       axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;
+       axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;
+       axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;
+
+
+       axis_average.x_average += axis.x;
+       axis_average.y_average += axis.y;
+       axis_average.z_average += axis.z;
+       axis_average.count++;
+
+       if(axis_average.count >= DMARD10_COUNT_AVERAGE)
+       {
+               axis.x = axis_average.x_average / axis_average.count;
+               axis.y = axis_average.y_average / axis_average.count;
+               axis.z = axis_average.z_average / axis_average.count;
+
+               DBG( "%s: axis = %d  %d  %d \n", __func__, axis.x, axis.y, axis.z);
+
+               memset(&axis_average, 0, sizeof(struct sensor_axis_average));
+
+               //Report event only while value is changed to save some power
+               if((abs(sensor->axis.x - axis.x) > GSENSOR_MIN) || (abs(sensor->axis.y - axis.y) > GSENSOR_MIN) || (abs(sensor->axis.z - axis.z) > GSENSOR_MIN))
+               {
+                       gsensor_report_value(client, &axis);
+
+                       /* »¥³âµØ»º´æÊý¾Ý. */
+                       mutex_lock(&(sensor->data_mutex) );
+                       sensor->axis = axis;
+                       mutex_unlock(&(sensor->data_mutex) );
+               }
+       }
+
+       if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0))    //read sensor intterupt status register
+       {
+
+               value = sensor_read_reg(client, sensor->ops->int_status_reg);
+               DBG("%s:sensor int status :0x%x\n",__func__,value);
+       }
+
+       return ret;
+}
+
+
+struct sensor_operate gsensor_dmard10_ops = {
+       .name                           = "gs_dmard10",
+       .type                           = SENSOR_TYPE_ACCEL,                    //sensor type and it should be correct
+       .id_i2c                         = ACCEL_ID_DMARD10,                     //i2c id number
+       .read_reg                       = DMARD10_REG_X_OUT,                    //read data
+       .read_len                       = 8,                                    //data length
+       .id_reg                         = SENSOR_UNKNOW_DATA,                   //read device id from this register
+       .id_data                        = SENSOR_UNKNOW_DATA,                   //device id
+       .precision                      = DMARD10_PRECISION,                    //12 bit
+       .ctrl_reg                       = DMARD10_REG_MODE,                     //enable or disable
+       .int_status_reg         = SENSOR_UNKNOW_DATA,                   //intterupt status register
+       .range                          = {-DMARD10_RANGE,DMARD10_RANGE},       //range
+       .trig                           = IRQF_TRIGGER_LOW|IRQF_ONESHOT,
+       .active                         = sensor_active,
+       .init                           = sensor_init,
+       .report                         = sensor_report_value,
+};
+
+/****************operate according to sensor chip:end************/
+
+//function name should not be changed
+static struct sensor_operate *gsensor_get_ops(void)
+{
+       return &gsensor_dmard10_ops;
+}
+
+
+static int __init gsensor_dmard10_init(void)
+{
+       struct sensor_operate *ops = gsensor_get_ops();
+       int result = 0;
+       int type = ops->type;
+       result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);
+       return result;
+}
+
+static void __exit gsensor_dmard10_exit(void)
+{
+       struct sensor_operate *ops = gsensor_get_ops();
+       int type = ops->type;
+       sensor_unregister_slave(type, NULL, NULL, gsensor_get_ops);
+}
+
+
+module_init(gsensor_dmard10_init);
+module_exit(gsensor_dmard10_exit);
+
+
+
index 013ac39..defb31d 100755 (executable)
-/* drivers/input/sensors/access/kxtik.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: Bruins <xwj@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-\r
-#define LSM303D_WHO_AM_I               (0x0F)\r
-\r
-/* full scale setting - register & mask */\r
-#define LSM303D_CTRL_REG0              (0x1F)\r
-#define LSM303D_CTRL_REG1              (0x20)\r
-#define LSM303D_CTRL_REG2              (0x21)\r
-#define LSM303D_CTRL_REG3              (0x22)\r
-#define LSM303D_CTRL_REG4              (0x23)\r
-#define LSM303D_CTRL_REG5              (0x24)\r
-#define LSM303D_CTRL_REG6              (0x25)\r
-#define LSM303D_CTRL_REG7              (0x26)\r
-#define LSM303D_STATUS_REG             (0x27)\r
-#define LSM303D_OUT_X_L                        (0x28)\r
-#define LSM303D_OUT_X_H                        (0x29)\r
-#define LSM303D_OUT_Y_L                        (0x2a)\r
-#define LSM303D_OUT_Y_H                        (0x2b)\r
-#define LSM303D_OUT_Z_L                        (0x2c)\r
-#define LSM303D_OUT_Z_H                        (0x2d)\r
-#define LSM303D_FIFO_CTRL_REG          (0x2E)\r
-#define LSM303D_FIFO_SRC_REG           (0X2F)\r
-\r
-#define LSM303D_IG_CFG1                        (0x30)\r
-#define LSM303D_IG_SRC1                        (0x31)\r
-#define LSM303D_IG_THS1                        (0x32)\r
-#define LSM303D_IG_DURATION1           (0x33)\r
-\r
-#define LSM303D_IG_CFG2                        (0x34)\r
-#define LSM303D_IG_SRC2                        (0x35)\r
-#define LSM303D_IG_THS2                        (0x36)\r
-#define LSM303D_IG_DURATION2           (0x37)\r
-\r
-\r
-#define LSM303D_DEVID                  (0x49)  //chip id\r
-#define LSM303D_ACC_DISABLE            (0x08)\r
-\r
-#define LSM303D_RANGE                  2000000\r
-\r
-/* LSM303D */\r
-#define LSM303D_PRECISION              16\r
-#define LSM303D_BOUNDARY                       (0x1 << (LSM303D_PRECISION - 1))\r
-#define LSM303D_GRAVITY_STEP           (LSM303D_RANGE / LSM303D_BOUNDARY)\r
-\r
-#define ODR3P25                                0x10  /* 3.25Hz output data rate */\r
-#define ODR6P25                                0x20  /* 6.25Hz output data rate */\r
-#define ODR12P5                                0x30  /* 12.5Hz output data rate */\r
-#define ODR25                          0x40  /* 25Hz output data rate */\r
-#define ODR50                          0x50  /* 50Hz output data rate */\r
-#define ODR100                         0x60  /* 100Hz output data rate */\r
-#define ODR200                         0x70  /* 200Hz output data rate */\r
-#define ODR400                         0x80  /* 400Hz output data rate */\r
-#define ODR800                         0x90  /* 800Hz output data rate */\r
-#define ODR1600                                0xA0  /* 1600Hz output data rate */\r
-\r
-\r
-struct sensor_reg_data {\r
-       char reg;\r
-       char data;\r
-};\r
-\r
-/****************operate according to sensor chip:start************/\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
-       struct sensor_private_data *sensor =\r
-           (struct sensor_private_data *) i2c_get_clientdata(client);  \r
-       int result = 0;\r
-       int status = 0;\r
-               \r
-       sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
-\r
-       sensor->ops->ctrl_data |= ODR100;       //100HZ,if 0 then power down\r
-       \r
-       //register setting according to chip datasheet          \r
-       if(!enable)\r
-       {       \r
-               status = LSM303D_ACC_DISABLE;   //lis3dh        \r
-               sensor->ops->ctrl_data |= status;       \r
-       }\r
-       else\r
-       {\r
-               status = ~LSM303D_ACC_DISABLE;  //lis3dh\r
-               sensor->ops->ctrl_data &= status;\r
-       }\r
-\r
-       DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
-       result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
-       if(result)\r
-               printk("%s:fail to active sensor\n",__func__);\r
-       \r
-       return result;\r
-\r
-}\r
-\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{      \r
-       struct sensor_private_data *sensor =\r
-           (struct sensor_private_data *) i2c_get_clientdata(client);  \r
-       int result = 0;\r
-       int i;\r
-\r
-       struct sensor_reg_data reg_data[] = \r
-       {\r
-               {LSM303D_CTRL_REG0,0x00},\r
-               {LSM303D_CTRL_REG1,0x07},\r
-               {LSM303D_CTRL_REG2,0x00},\r
-               {LSM303D_CTRL_REG3,0x00},\r
-               {LSM303D_CTRL_REG4,0x00},\r
-               {LSM303D_CTRL_REG5,0x78},               //High resolution output mode:11,\r
-               {LSM303D_CTRL_REG6,0x20},\r
-               {LSM303D_CTRL_REG7,0x00},\r
-               {LSM303D_FIFO_CTRL_REG,0x00},\r
-               {LSM303D_IG_CFG1,0xFF},         //6 direction position recognition      \r
-               {LSM303D_IG_THS1,0x7F},         //Interrupt 1 threshold \r
-               {LSM303D_IG_DURATION1,0x7F},    //Duration value 0x00->ox7f\r
-                       \r
-       /*\r
-               {LSM303D_CTRL_REG7,0x00},               \r
-               {LSM303D_CTRL_REG4,0x08},               //High resolution output mode: 1, Normal mode   \r
-               {LSM303D_CTRL_REG6,0x40},       \r
-               \r
-               {LSM303D_FIFO_CTRL_REG,0x00},   //      \r
-               {LSM303D_IG_CFG1,0xFF},                 //6 direction position recognition      \r
-               {LSM303D_IG_THS1,0x7F},                 //Interrupt 1 threshold \r
-               {LSM303D_IG_DURATION1,0x7F},    //Duration value 0x00->ox7f\r
-               */\r
-       };  \r
-       \r
-       result = sensor->ops->active(client,0,0);\r
-       if(result)\r
-       {\r
-               printk("%s:line=%d,error\n",__func__,__LINE__);\r
-               return result;\r
-       }\r
-\r
-       sensor->status_cur = SENSOR_OFF;\r
-       \r
-       for(i=0;i<(sizeof(reg_data)/sizeof(struct sensor_reg_data));i++)\r
-       {\r
-               result = sensor_write_reg(client, reg_data[i].reg, reg_data[i].data);\r
-               if(result)\r
-               {\r
-                       printk("%s:line=%d,i=%d,error\n",__func__,__LINE__,i);\r
-                       return result;\r
-               }\r
-       }\r
-\r
-       \r
-       if(sensor->pdata->irq_enable)\r
-       {\r
-\r
-               result = sensor_write_reg(client, LSM303D_CTRL_REG3, 0x20);     \r
-               if(result)\r
-               {\r
-                       printk("%s:line=%d,error\n",__func__,__LINE__);\r
-                       return result;\r
-               }\r
-\r
-               i = sensor_read_reg(client,LSM303D_CTRL_REG5);\r
-               \r
-               result = sensor_write_reg(client, LSM303D_CTRL_REG5, (i|0x01));\r
-               if(result)\r
-               {\r
-                       printk("%s:line=%d,error\n",__func__,__LINE__);\r
-                       return result;\r
-               }\r
-\r
-       }\r
-       \r
-       return result;\r
-}\r
-\r
-\r
-static int sensor_convert_data(struct i2c_client *client, char high_byte, char low_byte)\r
-{\r
-       s64 result;\r
-       struct sensor_private_data *sensor =\r
-           (struct sensor_private_data *) i2c_get_clientdata(client);  \r
-       \r
-       switch (sensor->devid) {        \r
-               case LSM303D_DEVID:             \r
-                       result = ((int)high_byte << 8) | (int)low_byte;\r
-                       if (result < LSM303D_BOUNDARY)\r
-                               result = result* LSM303D_GRAVITY_STEP;\r
-               else\r
-                               result = ~( ((~result & (0x7fff>>(16-LSM303D_PRECISION)) ) + 1) \r
-                                               * LSM303D_GRAVITY_STEP) + 1;\r
-                       break;\r
-\r
-               default:\r
-                       printk(KERN_ERR "%s: devid wasn't set correctly\n",__func__);\r
-                       return -EFAULT;\r
-    }\r
-\r
-    return (int)result;\r
-}\r
-\r
-static int gsensor_report_value(struct i2c_client *client, struct sensor_axis *axis)\r
-{\r
-       struct sensor_private_data *sensor =\r
-               (struct sensor_private_data *) i2c_get_clientdata(client);      \r
-\r
-       /* Report acceleration sensor information */\r
-       input_report_abs(sensor->input_dev, ABS_X, axis->x);\r
-       input_report_abs(sensor->input_dev, ABS_Y, axis->y);\r
-       input_report_abs(sensor->input_dev, ABS_Z, axis->z);\r
-       input_sync(sensor->input_dev);\r
-       DBG("Gsensor x==%d  y==%d z==%d\n",axis->x,axis->y,axis->z);\r
-\r
-       return 0;\r
-}\r
-\r
-#define GSENSOR_MIN  10\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
-       struct sensor_private_data *sensor =\r
-                       (struct sensor_private_data *) i2c_get_clientdata(client);      \r
-       struct sensor_platform_data *pdata = sensor->pdata;\r
-       int ret = 0;\r
-       int x,y,z;\r
-       struct sensor_axis axis;        \r
-       char buffer[6] = {0};   \r
-       char value = 0;\r
-       \r
-       if(sensor->ops->read_len < 6)   //sensor->ops->read_len = 6\r
-       {\r
-               printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
-               return -1;\r
-       }\r
-       \r
-       memset(buffer, 0, 6);\r
-\r
-       value = sensor_read_reg(client, LSM303D_STATUS_REG);\r
-       if((value & 0x0f) == 0)\r
-       {\r
-               printk("%s:line=%d,value=0x%x,data is not ready\n",__func__,__LINE__,value);\r
-               return -1;\r
-       }\r
-               \r
-       \r
-       /* Data bytes from hardware xL, xH, yL, yH, zL, zH */   \r
-       do {\r
-               *buffer = sensor->ops->read_reg;\r
-               ret = sensor_rx_data(client, buffer, sensor->ops->read_len);\r
-               if (ret < 0)\r
-               return ret;\r
-       } while (0);\r
-\r
-       //this gsensor need 6 bytes buffer\r
-       x = sensor_convert_data(sensor->client, buffer[1], buffer[0]);  //buffer[1]:high bit \r
-       y = sensor_convert_data(sensor->client, buffer[3], buffer[2]);\r
-       z = sensor_convert_data(sensor->client, buffer[5], buffer[4]);          \r
-\r
-       axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;\r
-       axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;     \r
-       axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;\r
-\r
-       DBG( "%s: axis = %d  %d  %d \n", __func__, axis.x, axis.y, axis.z);\r
-       //printk( "%s: axis = %d  %d  %d \n", __func__, axis.x, axis.y, axis.z);\r
-\r
-       //Report event  only while value is changed to save some power\r
-       if((abs(sensor->axis.x - axis.x) > GSENSOR_MIN) || (abs(sensor->axis.y - axis.y) > GSENSOR_MIN) || (abs(sensor->axis.z - axis.z) > GSENSOR_MIN))\r
-       {\r
-               gsensor_report_value(client, &axis);\r
-\r
-               /* »¥³âµØ»º´æÊý¾Ý. */\r
-               mutex_lock(&(sensor->data_mutex) );\r
-               sensor->axis = axis;\r
-               mutex_unlock(&(sensor->data_mutex) );\r
-       }\r
-\r
-       if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0))    //read sensor intterupt status register\r
-       {\r
-               \r
-               value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
-               DBG("%s:sensor int status :0x%x\n",__func__,value);\r
-       }\r
-       \r
-       return ret;\r
-}\r
-\r
-struct sensor_operate gsensor_lsm303d_ops = {\r
-       .name                           = "lsm303d",\r
-       .type                           = SENSOR_TYPE_ACCEL,            //sensor type and it should be correct\r
-       .id_i2c                         = ACCEL_ID_LSM303D,             //i2c id number\r
-       .read_reg                       = (LSM303D_OUT_X_L | 0x80),     //read data\r
-       .read_len                       = 6,                            //data length\r
-       .id_reg                         = LSM303D_WHO_AM_I,             //read device id from this register\r
-       .id_data                        = LSM303D_DEVID,                        //device id\r
-       .precision                      = LSM303D_PRECISION,            //16 bits\r
-       .ctrl_reg                       = LSM303D_CTRL_REG1,            //enable or disable \r
-       .int_status_reg                 = LSM303D_IG_SRC1,              //intterupt status register\r
-       .range                          = {-LSM303D_RANGE,LSM303D_RANGE},       //range\r
-       .trig                           = (IRQF_TRIGGER_LOW|IRQF_ONESHOT),              \r
-       .active                         = sensor_active,        \r
-       .init                           = sensor_init,\r
-       .report                         = sensor_report_value,\r
-};\r
-\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *gsensor_get_ops(void)\r
-{\r
-       return &gsensor_lsm303d_ops;\r
-}\r
-\r
-\r
-static int __init gsensor_lis3dh_init(void)\r
-{\r
-       struct sensor_operate *ops = gsensor_get_ops();\r
-       int result = 0;\r
-       int type = ops->type;\r
-       result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);\r
-       return result;\r
-}\r
-\r
-static void __exit gsensor_lis3dh_exit(void)\r
-{\r
-       struct sensor_operate *ops = gsensor_get_ops();\r
-       int type = ops->type;\r
-       sensor_unregister_slave(type, NULL, NULL, gsensor_get_ops);\r
-}\r
-\r
-\r
-module_init(gsensor_lis3dh_init);\r
-module_exit(gsensor_lis3dh_exit);\r
-\r
-\r
-\r
-\r
+/* drivers/input/sensors/access/kxtik.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: Bruins <xwj@rock-chips.com>
+ *
+ * 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/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+
+#define LSM303D_WHO_AM_I               (0x0F)
+
+/* full scale setting - register & mask */
+#define LSM303D_CTRL_REG0              (0x1F)
+#define LSM303D_CTRL_REG1              (0x20)
+#define LSM303D_CTRL_REG2              (0x21)
+#define LSM303D_CTRL_REG3              (0x22)
+#define LSM303D_CTRL_REG4              (0x23)
+#define LSM303D_CTRL_REG5              (0x24)
+#define LSM303D_CTRL_REG6              (0x25)
+#define LSM303D_CTRL_REG7              (0x26)
+#define LSM303D_STATUS_REG             (0x27)
+#define LSM303D_OUT_X_L                        (0x28)
+#define LSM303D_OUT_X_H                        (0x29)
+#define LSM303D_OUT_Y_L                        (0x2a)
+#define LSM303D_OUT_Y_H                        (0x2b)
+#define LSM303D_OUT_Z_L                        (0x2c)
+#define LSM303D_OUT_Z_H                        (0x2d)
+#define LSM303D_FIFO_CTRL_REG          (0x2E)
+#define LSM303D_FIFO_SRC_REG           (0X2F)
+
+#define LSM303D_IG_CFG1                        (0x30)
+#define LSM303D_IG_SRC1                        (0x31)
+#define LSM303D_IG_THS1                        (0x32)
+#define LSM303D_IG_DURATION1           (0x33)
+
+#define LSM303D_IG_CFG2                        (0x34)
+#define LSM303D_IG_SRC2                        (0x35)
+#define LSM303D_IG_THS2                        (0x36)
+#define LSM303D_IG_DURATION2           (0x37)
+
+
+#define LSM303D_DEVID                  (0x49)  //chip id
+#define LSM303D_ACC_DISABLE            (0x08)
+
+#define LSM303D_RANGE                  2000000
+
+/* LSM303D */
+#define LSM303D_PRECISION              16
+#define LSM303D_BOUNDARY                       (0x1 << (LSM303D_PRECISION - 1))
+#define LSM303D_GRAVITY_STEP           (LSM303D_RANGE / LSM303D_BOUNDARY)
+
+#define ODR3P25                                0x10  /* 3.25Hz output data rate */
+#define ODR6P25                                0x20  /* 6.25Hz output data rate */
+#define ODR12P5                                0x30  /* 12.5Hz output data rate */
+#define ODR25                          0x40  /* 25Hz output data rate */
+#define ODR50                          0x50  /* 50Hz output data rate */
+#define ODR100                         0x60  /* 100Hz output data rate */
+#define ODR200                         0x70  /* 200Hz output data rate */
+#define ODR400                         0x80  /* 400Hz output data rate */
+#define ODR800                         0x90  /* 800Hz output data rate */
+#define ODR1600                                0xA0  /* 1600Hz output data rate */
+
+
+struct sensor_reg_data {
+       char reg;
+       char data;
+};
+
+/****************operate according to sensor chip:start************/
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+       struct sensor_private_data *sensor =
+           (struct sensor_private_data *) i2c_get_clientdata(client);
+       int result = 0;
+       int status = 0;
+
+       sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
+
+       sensor->ops->ctrl_data |= ODR100;       //100HZ,if 0 then power down
+
+       //register setting according to chip datasheet
+       if(!enable)
+       {
+               status = LSM303D_ACC_DISABLE;   //lis3dh
+               sensor->ops->ctrl_data |= status;
+       }
+       else
+       {
+               status = ~LSM303D_ACC_DISABLE;  //lis3dh
+               sensor->ops->ctrl_data &= status;
+       }
+
+       DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
+       result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+       if(result)
+               printk("%s:fail to active sensor\n",__func__);
+
+       return result;
+
+}
+
+
+static int sensor_init(struct i2c_client *client)
+{
+       struct sensor_private_data *sensor =
+           (struct sensor_private_data *) i2c_get_clientdata(client);
+       int result = 0;
+       int i;
+
+       struct sensor_reg_data reg_data[] =
+       {
+               {LSM303D_CTRL_REG0,0x00},
+               {LSM303D_CTRL_REG1,0x07},
+               {LSM303D_CTRL_REG2,0x00},
+               {LSM303D_CTRL_REG3,0x00},
+               {LSM303D_CTRL_REG4,0x00},
+               {LSM303D_CTRL_REG5,0x78},               //High resolution output mode:11,
+               {LSM303D_CTRL_REG6,0x20},
+               {LSM303D_CTRL_REG7,0x00},
+               {LSM303D_FIFO_CTRL_REG,0x00},
+               {LSM303D_IG_CFG1,0xFF},         //6 direction position recognition
+               {LSM303D_IG_THS1,0x7F},         //Interrupt 1 threshold
+               {LSM303D_IG_DURATION1,0x7F},    //Duration value 0x00->ox7f
+
+       /*
+               {LSM303D_CTRL_REG7,0x00},
+               {LSM303D_CTRL_REG4,0x08},               //High resolution output mode: 1, Normal mode
+               {LSM303D_CTRL_REG6,0x40},
+
+               {LSM303D_FIFO_CTRL_REG,0x00},   //
+               {LSM303D_IG_CFG1,0xFF},                 //6 direction position recognition
+               {LSM303D_IG_THS1,0x7F},                 //Interrupt 1 threshold
+               {LSM303D_IG_DURATION1,0x7F},    //Duration value 0x00->ox7f
+               */
+       };
+
+       result = sensor->ops->active(client,0,0);
+       if(result)
+       {
+               printk("%s:line=%d,error\n",__func__,__LINE__);
+               return result;
+       }
+
+       sensor->status_cur = SENSOR_OFF;
+
+       for(i=0;i<(sizeof(reg_data)/sizeof(struct sensor_reg_data));i++)
+       {
+               result = sensor_write_reg(client, reg_data[i].reg, reg_data[i].data);
+               if(result)
+               {
+                       printk("%s:line=%d,i=%d,error\n",__func__,__LINE__,i);
+                       return result;
+               }
+       }
+
+
+       if(sensor->pdata->irq_enable)
+       {
+
+               result = sensor_write_reg(client, LSM303D_CTRL_REG3, 0x20);
+               if(result)
+               {
+                       printk("%s:line=%d,error\n",__func__,__LINE__);
+                       return result;
+               }
+
+               i = sensor_read_reg(client,LSM303D_CTRL_REG5);
+
+               result = sensor_write_reg(client, LSM303D_CTRL_REG5, (i|0x01));
+               if(result)
+               {
+                       printk("%s:line=%d,error\n",__func__,__LINE__);
+                       return result;
+               }
+
+       }
+
+       return result;
+}
+
+
+static int sensor_convert_data(struct i2c_client *client, char high_byte, char low_byte)
+{
+       s64 result;
+       struct sensor_private_data *sensor =
+           (struct sensor_private_data *) i2c_get_clientdata(client);
+
+       switch (sensor->devid) {
+               case LSM303D_DEVID:
+                       result = ((int)high_byte << 8) | (int)low_byte;
+                       if (result < LSM303D_BOUNDARY)
+                               result = result* LSM303D_GRAVITY_STEP;
+               else
+                               result = ~( ((~result & (0x7fff>>(16-LSM303D_PRECISION)) ) + 1)
+                                               * LSM303D_GRAVITY_STEP) + 1;
+                       break;
+
+               default:
+                       printk(KERN_ERR "%s: devid wasn't set correctly\n",__func__);
+                       return -EFAULT;
+    }
+
+    return (int)result;
+}
+
+static int gsensor_report_value(struct i2c_client *client, struct sensor_axis *axis)
+{
+       struct sensor_private_data *sensor =
+               (struct sensor_private_data *) i2c_get_clientdata(client);
+
+       /* Report acceleration sensor information */
+       input_report_abs(sensor->input_dev, ABS_X, axis->x);
+       input_report_abs(sensor->input_dev, ABS_Y, axis->y);
+       input_report_abs(sensor->input_dev, ABS_Z, axis->z);
+       input_sync(sensor->input_dev);
+       DBG("Gsensor x==%d  y==%d z==%d\n",axis->x,axis->y,axis->z);
+
+       return 0;
+}
+
+#define GSENSOR_MIN  10
+static int sensor_report_value(struct i2c_client *client)
+{
+       struct sensor_private_data *sensor =
+                       (struct sensor_private_data *) i2c_get_clientdata(client);
+       struct sensor_platform_data *pdata = sensor->pdata;
+       int ret = 0;
+       int x,y,z;
+       struct sensor_axis axis;
+       char buffer[6] = {0};
+       char value = 0;
+
+       if(sensor->ops->read_len < 6)   //sensor->ops->read_len = 6
+       {
+               printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
+               return -1;
+       }
+
+       memset(buffer, 0, 6);
+
+       value = sensor_read_reg(client, LSM303D_STATUS_REG);
+       if((value & 0x0f) == 0)
+       {
+               printk("%s:line=%d,value=0x%x,data is not ready\n",__func__,__LINE__,value);
+               return -1;
+       }
+
+
+       /* Data bytes from hardware xL, xH, yL, yH, zL, zH */
+       do {
+               *buffer = sensor->ops->read_reg;
+               ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
+               if (ret < 0)
+               return ret;
+       } while (0);
+
+       //this gsensor need 6 bytes buffer
+       x = sensor_convert_data(sensor->client, buffer[1], buffer[0]);  //buffer[1]:high bit
+       y = sensor_convert_data(sensor->client, buffer[3], buffer[2]);
+       z = sensor_convert_data(sensor->client, buffer[5], buffer[4]);
+
+       axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;
+       axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;
+       axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;
+
+       DBG( "%s: axis = %d  %d  %d \n", __func__, axis.x, axis.y, axis.z);
+       //printk( "%s: axis = %d  %d  %d \n", __func__, axis.x, axis.y, axis.z);
+
+       //Report event  only while value is changed to save some power
+       if((abs(sensor->axis.x - axis.x) > GSENSOR_MIN) || (abs(sensor->axis.y - axis.y) > GSENSOR_MIN) || (abs(sensor->axis.z - axis.z) > GSENSOR_MIN))
+       {
+               gsensor_report_value(client, &axis);
+
+               /* »¥³âµØ»º´æÊý¾Ý. */
+               mutex_lock(&(sensor->data_mutex) );
+               sensor->axis = axis;
+               mutex_unlock(&(sensor->data_mutex) );
+       }
+
+       if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0))    //read sensor intterupt status register
+       {
+
+               value = sensor_read_reg(client, sensor->ops->int_status_reg);
+               DBG("%s:sensor int status :0x%x\n",__func__,value);
+       }
+
+       return ret;
+}
+
+struct sensor_operate gsensor_lsm303d_ops = {
+       .name                           = "lsm303d",
+       .type                           = SENSOR_TYPE_ACCEL,            //sensor type and it should be correct
+       .id_i2c                         = ACCEL_ID_LSM303D,             //i2c id number
+       .read_reg                       = (LSM303D_OUT_X_L | 0x80),     //read data
+       .read_len                       = 6,                            //data length
+       .id_reg                         = LSM303D_WHO_AM_I,             //read device id from this register
+       .id_data                        = LSM303D_DEVID,                        //device id
+       .precision                      = LSM303D_PRECISION,            //16 bits
+       .ctrl_reg                       = LSM303D_CTRL_REG1,            //enable or disable
+       .int_status_reg                 = LSM303D_IG_SRC1,              //intterupt status register
+       .range                          = {-LSM303D_RANGE,LSM303D_RANGE},       //range
+       .trig                           = (IRQF_TRIGGER_LOW|IRQF_ONESHOT),
+       .active                         = sensor_active,
+       .init                           = sensor_init,
+       .report                         = sensor_report_value,
+};
+
+
+/****************operate according to sensor chip:end************/
+
+//function name should not be changed
+static struct sensor_operate *gsensor_get_ops(void)
+{
+       return &gsensor_lsm303d_ops;
+}
+
+
+static int __init gsensor_lis3dh_init(void)
+{
+       struct sensor_operate *ops = gsensor_get_ops();
+       int result = 0;
+       int type = ops->type;
+       result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);
+       return result;
+}
+
+static void __exit gsensor_lis3dh_exit(void)
+{
+       struct sensor_operate *ops = gsensor_get_ops();
+       int type = ops->type;
+       sensor_unregister_slave(type, NULL, NULL, gsensor_get_ops);
+}
+
+
+module_init(gsensor_lis3dh_init);
+module_exit(gsensor_lis3dh_exit);
+
+
+
+
index 104642d..bf01de2 100755 (executable)
@@ -1,2 +1,2 @@
-obj-$(CONFIG_ANGLE_KXTIK)      += angle_kxtik.o\r
-obj-$(CONFIG_ANGLE_LIS3DH)     += angle_lis3dh.o\r
+obj-$(CONFIG_ANGLE_KXTIK)      += angle_kxtik.o
+obj-$(CONFIG_ANGLE_LIS3DH)     += angle_lis3dh.o
index 15e52c5..1c5bdf6 100755 (executable)
-/* drivers/input/sensors/access/akm09911.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-\r
-\r
-#define SENSOR_DATA_SIZE       9\r
-#define YPR_DATA_SIZE          16\r
-#define RWBUF_SIZE             16\r
-\r
-#define ACC_DATA_FLAG          0\r
-#define MAG_DATA_FLAG          1\r
-#define ORI_DATA_FLAG          2\r
-#define AKM_NUM_SENSORS                3\r
-\r
-#define ACC_DATA_READY         (1<<(ACC_DATA_FLAG))\r
-#define MAG_DATA_READY         (1<<(MAG_DATA_FLAG))\r
-#define ORI_DATA_READY         (1<<(ORI_DATA_FLAG))\r
-\r
-/*Constant definitions of the AK09911.*/\r
-#define AK09911_MEASUREMENT_TIME_US    10000\r
-\r
-#define AK09911_MODE_SNG_MEASURE       0x01\r
-#define AK09911_MODE_SELF_TEST         0x10\r
-#define AK09911_MODE_FUSE_ACCESS       0x1F\r
-#define AK09911_MODE_POWERDOWN         0x00\r
-#define AK09911_RESET_DATA             0x01\r
-\r
-\r
-/* Device specific constant values */\r
-#define AK09911_REG_WIA1                       0x00\r
-#define AK09911_REG_WIA2                       0x01\r
-#define AK09911_REG_INFO1                      0x02\r
-#define AK09911_REG_INFO2                      0x03\r
-#define AK09911_REG_ST1                                0x10\r
-#define AK09911_REG_HXL                                0x11\r
-#define AK09911_REG_HXH                                0x12\r
-#define AK09911_REG_HYL                                0x13\r
-#define AK09911_REG_HYH                                0x14\r
-#define AK09911_REG_HZL                                0x15\r
-#define AK09911_REG_HZH                                0x16\r
-#define AK09911_REG_TMPS                       0x17\r
-#define AK09911_REG_ST2                                0x18\r
-#define AK09911_REG_CNTL1                      0x30\r
-#define AK09911_REG_CNTL2                      0x31\r
-#define AK09911_REG_CNTL3                      0x32\r
-\r
-\r
-#define AK09911_FUSE_ASAX                      0x60\r
-#define AK09911_FUSE_ASAY                      0x61\r
-#define AK09911_FUSE_ASAZ                      0x62\r
-\r
-#define AK09911_INFO_SIZE                      2\r
-#define AK09911_CONF_SIZE                      3\r
-\r
-\r
-\r
-#define COMPASS_IOCTL_MAGIC                   'c'\r
-\r
-/* IOCTLs for AKM library */\r
-#define ECS_IOCTL_WRITE                 _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*)\r
-#define ECS_IOCTL_READ                  _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*)\r
-#define ECS_IOCTL_RESET                _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */\r
-#define ECS_IOCTL_SET_MODE              _IOW(COMPASS_IOCTL_MAGIC, 0x04, short)\r
-#define ECS_IOCTL_GETDATA               _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[8])\r
-#define ECS_IOCTL_SET_YPR               _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12])\r
-#define ECS_IOCTL_GET_OPEN_STATUS       _IOR(COMPASS_IOCTL_MAGIC, 0x07, int)\r
-#define ECS_IOCTL_GET_CLOSE_STATUS      _IOR(COMPASS_IOCTL_MAGIC, 0x08, int)\r
-#define ECS_IOCTL_GET_LAYOUT           _IOR(COMPASS_IOCTL_MAGIC, 0x09, char)\r
-#define ECS_IOCTL_GET_ACCEL            _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3])\r
-#define ECS_IOCTL_GET_OUTBIT           _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char)\r
-#define ECS_IOCTL_GET_INFO                     _IOR(COMPASS_IOCTL_MAGIC, 0x0C, short)\r
-#define ECS_IOCTL_GET_CONF                     _IOR(COMPASS_IOCTL_MAGIC, 0x0D, short)\r
-#define ECS_IOCTL_GET_PLATFORM_DATA     _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data)\r
-#define ECS_IOCTL_GET_DELAY             _IOR(COMPASS_IOCTL_MAGIC, 0x30, short)\r
-\r
-\r
-\r
-#define AK09911_DEVICE_ID              0x05\r
-static struct i2c_client *this_client;\r
-static struct miscdevice compass_dev_device;\r
-\r
-static short g_akm_rbuf[12];\r
-static char g_sensor_info[AK09911_INFO_SIZE];\r
-static char g_sensor_conf[AK09911_CONF_SIZE];\r
-\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
-       struct sensor_private_data *sensor =\r
-           (struct sensor_private_data *) i2c_get_clientdata(client);  \r
-       int result = 0;\r
-               \r
-       //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
-       \r
-       //register setting according to chip datasheet          \r
-       if(enable)\r
-       {       \r
-               sensor->ops->ctrl_data = AK09911_MODE_SNG_MEASURE;      \r
-       }\r
-       else\r
-       {\r
-               sensor->ops->ctrl_data = AK09911_MODE_POWERDOWN;\r
-       }\r
-\r
-       DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
-       result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
-       if(result)\r
-               printk("%s:fail to active sensor\n",__func__);\r
-       \r
-       return result;\r
-\r
-}\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{      \r
-       struct sensor_private_data *sensor =\r
-           (struct sensor_private_data *) i2c_get_clientdata(client);  \r
-       int result = 0;\r
-\r
-       this_client = client;   \r
-\r
-       result = sensor->ops->active(client,0,0);\r
-       if(result)\r
-       {\r
-               printk("%s:line=%d,error\n",__func__,__LINE__);\r
-               return result;\r
-       }\r
-       \r
-       sensor->status_cur = SENSOR_OFF;\r
-\r
-       result = misc_register(&compass_dev_device);\r
-       if (result < 0) {\r
-               printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name);\r
-               result = -1;\r
-       }\r
-\r
-       g_sensor_info[0] = AK09911_REG_WIA1;\r
-       result = sensor_rx_data(client, g_sensor_info, AK09911_INFO_SIZE);\r
-       if(result)\r
-       {\r
-               printk("%s:line=%d,error\n",__func__,__LINE__);\r
-               return result;\r
-       }\r
-\r
-       \r
-       g_sensor_conf[0] = AK09911_FUSE_ASAX;\r
-       result = sensor_rx_data(client, g_sensor_conf, AK09911_CONF_SIZE);\r
-       if(result)\r
-       {\r
-               printk("%s:line=%d,error\n",__func__,__LINE__);\r
-               return result;\r
-       }\r
-       \r
-       DBG("%s:status_cur=%d\n",__func__, sensor->status_cur);\r
-       return result;\r
-}\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
-       struct sensor_private_data *sensor =\r
-               (struct sensor_private_data *) i2c_get_clientdata(client);      \r
-       char buffer[SENSOR_DATA_SIZE] = {0};    \r
-       unsigned char *stat;\r
-       unsigned char *stat2;   \r
-       int ret = 0;    \r
-       char value = 0;\r
-       int i;\r
-\r
-       if(sensor->ops->read_len < SENSOR_DATA_SIZE)    //sensor->ops->read_len = 8\r
-       {\r
-               printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
-               return -1;\r
-       }\r
-       \r
-       memset(buffer, 0, SENSOR_DATA_SIZE);\r
-       \r
-       /* Data bytes from hardware xL, xH, yL, yH, zL, zH */   \r
-       do {\r
-               *buffer = sensor->ops->read_reg;\r
-               ret = sensor_rx_data(client, buffer, sensor->ops->read_len);\r
-               if (ret < 0)\r
-               return ret;\r
-       } while (0);\r
-\r
-       stat = &buffer[0];\r
-       stat2 = &buffer[7];\r
-       \r
-       /*\r
+/* drivers/input/sensors/access/akm09911.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * 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/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+
+
+#define SENSOR_DATA_SIZE       9
+#define YPR_DATA_SIZE          16
+#define RWBUF_SIZE             16
+
+#define ACC_DATA_FLAG          0
+#define MAG_DATA_FLAG          1
+#define ORI_DATA_FLAG          2
+#define AKM_NUM_SENSORS                3
+
+#define ACC_DATA_READY         (1<<(ACC_DATA_FLAG))
+#define MAG_DATA_READY         (1<<(MAG_DATA_FLAG))
+#define ORI_DATA_READY         (1<<(ORI_DATA_FLAG))
+
+/*Constant definitions of the AK09911.*/
+#define AK09911_MEASUREMENT_TIME_US    10000
+
+#define AK09911_MODE_SNG_MEASURE       0x01
+#define AK09911_MODE_SELF_TEST         0x10
+#define AK09911_MODE_FUSE_ACCESS       0x1F
+#define AK09911_MODE_POWERDOWN         0x00
+#define AK09911_RESET_DATA             0x01
+
+
+/* Device specific constant values */
+#define AK09911_REG_WIA1                       0x00
+#define AK09911_REG_WIA2                       0x01
+#define AK09911_REG_INFO1                      0x02
+#define AK09911_REG_INFO2                      0x03
+#define AK09911_REG_ST1                                0x10
+#define AK09911_REG_HXL                                0x11
+#define AK09911_REG_HXH                                0x12
+#define AK09911_REG_HYL                                0x13
+#define AK09911_REG_HYH                                0x14
+#define AK09911_REG_HZL                                0x15
+#define AK09911_REG_HZH                                0x16
+#define AK09911_REG_TMPS                       0x17
+#define AK09911_REG_ST2                                0x18
+#define AK09911_REG_CNTL1                      0x30
+#define AK09911_REG_CNTL2                      0x31
+#define AK09911_REG_CNTL3                      0x32
+
+
+#define AK09911_FUSE_ASAX                      0x60
+#define AK09911_FUSE_ASAY                      0x61
+#define AK09911_FUSE_ASAZ                      0x62
+
+#define AK09911_INFO_SIZE                      2
+#define AK09911_CONF_SIZE                      3
+
+
+
+#define COMPASS_IOCTL_MAGIC                   'c'
+
+/* IOCTLs for AKM library */
+#define ECS_IOCTL_WRITE                 _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*)
+#define ECS_IOCTL_READ                  _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*)
+#define ECS_IOCTL_RESET                _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */
+#define ECS_IOCTL_SET_MODE              _IOW(COMPASS_IOCTL_MAGIC, 0x04, short)
+#define ECS_IOCTL_GETDATA               _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[8])
+#define ECS_IOCTL_SET_YPR               _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12])
+#define ECS_IOCTL_GET_OPEN_STATUS       _IOR(COMPASS_IOCTL_MAGIC, 0x07, int)
+#define ECS_IOCTL_GET_CLOSE_STATUS      _IOR(COMPASS_IOCTL_MAGIC, 0x08, int)
+#define ECS_IOCTL_GET_LAYOUT           _IOR(COMPASS_IOCTL_MAGIC, 0x09, char)
+#define ECS_IOCTL_GET_ACCEL            _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3])
+#define ECS_IOCTL_GET_OUTBIT           _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char)
+#define ECS_IOCTL_GET_INFO                     _IOR(COMPASS_IOCTL_MAGIC, 0x0C, short)
+#define ECS_IOCTL_GET_CONF                     _IOR(COMPASS_IOCTL_MAGIC, 0x0D, short)
+#define ECS_IOCTL_GET_PLATFORM_DATA     _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data)
+#define ECS_IOCTL_GET_DELAY             _IOR(COMPASS_IOCTL_MAGIC, 0x30, short)
+
+
+
+#define AK09911_DEVICE_ID              0x05
+static struct i2c_client *this_client;
+static struct miscdevice compass_dev_device;
+
+static short g_akm_rbuf[12];
+static char g_sensor_info[AK09911_INFO_SIZE];
+static char g_sensor_conf[AK09911_CONF_SIZE];
+
+
+/****************operate according to sensor chip:start************/
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+       struct sensor_private_data *sensor =
+           (struct sensor_private_data *) i2c_get_clientdata(client);
+       int result = 0;
+
+       //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
+
+       //register setting according to chip datasheet
+       if(enable)
+       {
+               sensor->ops->ctrl_data = AK09911_MODE_SNG_MEASURE;
+       }
+       else
+       {
+               sensor->ops->ctrl_data = AK09911_MODE_POWERDOWN;
+       }
+
+       DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
+       result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+       if(result)
+               printk("%s:fail to active sensor\n",__func__);
+
+       return result;
+
+}
+
+static int sensor_init(struct i2c_client *client)
+{
+       struct sensor_private_data *sensor =
+           (struct sensor_private_data *) i2c_get_clientdata(client);
+       int result = 0;
+
+       this_client = client;
+
+       result = sensor->ops->active(client,0,0);
+       if(result)
+       {
+               printk("%s:line=%d,error\n",__func__,__LINE__);
+               return result;
+       }
+
+       sensor->status_cur = SENSOR_OFF;
+
+       result = misc_register(&compass_dev_device);
+       if (result < 0) {
+               printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name);
+               result = -1;
+       }
+
+       g_sensor_info[0] = AK09911_REG_WIA1;
+       result = sensor_rx_data(client, g_sensor_info, AK09911_INFO_SIZE);
+       if(result)
+       {
+               printk("%s:line=%d,error\n",__func__,__LINE__);
+               return result;
+       }
+
+
+       g_sensor_conf[0] = AK09911_FUSE_ASAX;
+       result = sensor_rx_data(client, g_sensor_conf, AK09911_CONF_SIZE);
+       if(result)
+       {
+               printk("%s:line=%d,error\n",__func__,__LINE__);
+               return result;
+       }
+
+       DBG("%s:status_cur=%d\n",__func__, sensor->status_cur);
+       return result;
+}
+
+static int sensor_report_value(struct i2c_client *client)
+{
+       struct sensor_private_data *sensor =
+               (struct sensor_private_data *) i2c_get_clientdata(client);
+       char buffer[SENSOR_DATA_SIZE] = {0};
+       unsigned char *stat;
+       unsigned char *stat2;
+       int ret = 0;
+       char value = 0;
+       int i;
+
+       if(sensor->ops->read_len < SENSOR_DATA_SIZE)    //sensor->ops->read_len = 8
+       {
+               printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
+               return -1;
+       }
+
+       memset(buffer, 0, SENSOR_DATA_SIZE);
+
+       /* Data bytes from hardware xL, xH, yL, yH, zL, zH */
+       do {
+               *buffer = sensor->ops->read_reg;
+               ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
+               if (ret < 0)
+               return ret;
+       } while (0);
+
+       stat = &buffer[0];
+       stat2 = &buffer[7];
+
+       /*
         * ST : data ready -
         * Measurement has been completed and data is ready to be read.
-        */\r
-       if ((*stat & 0x01) != 0x01) {\r
-               DBG(KERN_ERR "%s:ST is not set\n",__func__);\r
-               return -1;\r
-       }\r
-#if 0\r
+        */
+       if ((*stat & 0x01) != 0x01) {
+               DBG(KERN_ERR "%s:ST is not set\n",__func__);
+               return -1;
+       }
+#if 0
        /*
         * ST2 : data error -
         * occurs when data read is started outside of a readable period;
@@ -236,12 +236,12 @@ static int sensor_report_value(struct i2c_client *client)
         * corrupted.
         * DERR bit is self-clearing when ST2 register is read.
         */
-       if (*stat2 & 0x04)\r
-       {\r
-               DBG(KERN_ERR "%s:compass data error\n",__func__);\r
-               return -2;\r
-       }\r
-       \r
+       if (*stat2 & 0x04)
+       {
+               DBG(KERN_ERR "%s:compass data error\n",__func__);
+               return -2;
+       }
+
        /*
         * ST2 : overflow -
         * the sum of the absolute values of all axis |X|+|Y|+|Z| < 2400uT.
@@ -251,544 +251,544 @@ static int sensor_report_value(struct i2c_client *client)
         * An error is returned.
         * HOFL bit clears when a new measurement starts.
         */
-       if (*stat2 & 0x08)\r
-       {       \r
-               DBG(KERN_ERR "%s:compass data overflow\n",__func__);\r
-               return -3;\r
-       }\r
-#endif\r
-       /* »¥³âµØ»º´æÊý¾Ý. */\r
-       mutex_lock(&sensor->data_mutex);        \r
-       memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);\r
-       mutex_unlock(&sensor->data_mutex);\r
-       DBG("%s:",__func__);\r
-       for(i=0; i<sensor->ops->read_len; i++)\r
-               DBG("0x%x,",buffer[i]);\r
-       DBG("\n");\r
-\r
-       if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0))    //read sensor intterupt status register\r
-       {\r
-               \r
-               value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
-               DBG("%s:sensor int status :0x%x\n",__func__,value);\r
-       }\r
-\r
-       \r
-       //trigger next measurement \r
-       ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
-       if(ret)\r
-       {\r
-               printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data);\r
-               return ret;\r
-       }\r
-\r
-       return ret;\r
-}\r
-\r
-static void compass_set_YPR(int *rbuf)\r
-{\r
-       struct sensor_private_data *sensor =\r
-           (struct sensor_private_data *) i2c_get_clientdata(this_client);     \r
-\r
-       /* No events are reported */\r
-       if (!rbuf[0]) {\r
-               printk("%s:Don't waste a time.",__func__);\r
-               return;\r
-       }\r
-\r
-       DBG("%s:buf[0]=0x%x\n",__func__, rbuf[0]);\r
-       \r
-       /* Report magnetic sensor information */\r
-       if (atomic_read(&sensor->flags.m_flag) && (rbuf[0] & ORI_DATA_READY)) {\r
-               input_report_abs(sensor->input_dev, ABS_RX, rbuf[9]);\r
-               input_report_abs(sensor->input_dev, ABS_RY, rbuf[10]);\r
-               input_report_abs(sensor->input_dev, ABS_RZ, rbuf[11]);\r
-               input_report_abs(sensor->input_dev, ABS_RUDDER, rbuf[4]);\r
-               DBG("%s:m_flag:x=%d,y=%d,z=%d,RUDDER=%d\n",__func__,rbuf[9], rbuf[10], rbuf[11], rbuf[4]);\r
-       }\r
-       \r
-       /* Report acceleration sensor information */\r
-       if (atomic_read(&sensor->flags.a_flag) && (rbuf[0] & ACC_DATA_READY)) {\r
-               input_report_abs(sensor->input_dev, ABS_X, rbuf[1]);\r
-               input_report_abs(sensor->input_dev, ABS_Y, rbuf[2]);\r
-               input_report_abs(sensor->input_dev, ABS_Z, rbuf[3]);\r
-               input_report_abs(sensor->input_dev, ABS_WHEEL, rbuf[4]);\r
-               \r
-               DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[1], rbuf[2], rbuf[3], rbuf[4]);\r
-       }\r
-       \r
-       /* Report magnetic vector information */\r
-       if (atomic_read(&sensor->flags.mv_flag) && (rbuf[0] & MAG_DATA_READY)) {\r
-               input_report_abs(sensor->input_dev, ABS_HAT0X, rbuf[5]);\r
-               input_report_abs(sensor->input_dev, ABS_HAT0Y, rbuf[6]);\r
-               input_report_abs(sensor->input_dev, ABS_BRAKE, rbuf[7]);        \r
-               input_report_abs(sensor->input_dev, ABS_HAT1X, rbuf[8]);\r
-       \r
-               DBG("%s:mv_flag:x=%d,y=%d,z=%d,status=%d\n",__func__,rbuf[5], rbuf[6], rbuf[7], rbuf[8]);\r
-       }\r
-       \r
-       input_sync(sensor->input_dev);\r
-\r
-       memcpy(g_akm_rbuf, rbuf, 12);   //used for ECS_IOCTL_GET_ACCEL\r
-}\r
-\r
-\r
-\r
-static int compass_dev_open(struct inode *inode, struct file *file)\r
-{\r
-       struct sensor_private_data* sensor = \r
-               (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
-       int result = 0;\r
-       DBG("%s\n",__func__);\r
-\r
-       return result;\r
-}\r
-\r
-\r
-static int compass_dev_release(struct inode *inode, struct file *file)\r
-{\r
-       struct sensor_private_data* sensor = \r
-               (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
-       int result = 0; \r
-       DBG("%s\n",__func__);\r
-\r
-       return result;\r
-}\r
-\r
-static int compass_akm_set_mode(struct i2c_client *client, char mode)\r
-{\r
-       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
-       int result = 0; \r
-\r
-       switch(mode & 0x1f)\r
-       {\r
-               case AK09911_MODE_SNG_MEASURE:\r
-               case AK09911_MODE_SELF_TEST:    \r
-               case AK09911_MODE_FUSE_ACCESS:                  \r
-                       if(sensor->status_cur == SENSOR_OFF)\r
-                       {\r
-                               if(sensor->pdata->irq_enable)\r
-                               {\r
-                                       //DBG("%s:enable irq=%d\n",__func__,client->irq);\r
-                                       //enable_irq(client->irq);\r
-                               }       \r
-                               else\r
-                               {\r
-                                       schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
-                               }\r
-                               \r
-                               sensor->status_cur = SENSOR_ON;\r
-                       }\r
-\r
-                       break;\r
-\r
-               case AK09911_MODE_POWERDOWN:    \r
-                       if(sensor->status_cur == SENSOR_ON)\r
-                       {\r
-                               if(sensor->pdata->irq_enable)\r
-                               {       \r
-                                       //DBG("%s:disable irq=%d\n",__func__,client->irq);\r
-                                       //disable_irq_nosync(client->irq);//disable irq\r
-                               }\r
-                               else\r
-                               cancel_delayed_work_sync(&sensor->delaywork);   \r
-\r
-                               sensor->status_cur = SENSOR_OFF;\r
-                       }\r
-                       break;\r
-\r
-       }\r
-       \r
-       switch(mode & 0x1f)\r
-       {\r
-               case AK09911_MODE_SNG_MEASURE:          \r
-                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SNG_MEASURE);\r
-                       if(result)\r
-                       printk("%s:i2c error,mode=%d\n",__func__,mode);                         \r
-                       break;\r
-               case AK09911_MODE_SELF_TEST:                    \r
-                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SELF_TEST);\r
-                       if(result)\r
-                       printk("%s:i2c error,mode=%d\n",__func__,mode);\r
-                       break;\r
-               case AK09911_MODE_FUSE_ACCESS:\r
-                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_FUSE_ACCESS);\r
-                       if(result)\r
-                       printk("%s:i2c error,mode=%d\n",__func__,mode);\r
-                       break;\r
-               case AK09911_MODE_POWERDOWN:\r
-                       /* Set powerdown mode */\r
-                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_POWERDOWN);\r
-                       if(result)\r
-                       printk("%s:i2c error,mode=%d\n",__func__,mode);\r
-                       udelay(100);\r
-                       break;\r
-               default:\r
-                       printk("%s: Unknown mode(%d)", __func__, mode);\r
-                       result = -EINVAL;\r
-                       break;\r
-       }\r
-       DBG("%s:mode=0x%x\n",__func__,mode);\r
-       return result;\r
-\r
-}\r
-\r
-static int compass_akm_reset(struct i2c_client *client)\r
-{\r
-       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
-       int result = 0; \r
-       \r
-       if(sensor->pdata->reset_pin > 0)\r
-       {\r
-               gpio_direction_output(sensor->pdata->reset_pin, GPIO_LOW);\r
-               udelay(10);\r
-               gpio_direction_output(sensor->pdata->reset_pin, GPIO_HIGH);\r
-       }\r
-       else    \r
-       {\r
-               /* Set measure mode */\r
-               result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SNG_MEASURE);\r
-               if(result)\r
-               printk("%s:fail to Set measure mode\n",__func__);\r
-       }\r
-       \r
-       udelay(100);\r
-       \r
-       return result;\r
-\r
-}\r
-\r
-\r
-\r
-static int compass_akm_get_openstatus(void)\r
-{      \r
-       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
-       wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0));\r
-       return atomic_read(&sensor->flags.open_flag);\r
-}\r
-\r
-static int compass_akm_get_closestatus(void)\r
-{      \r
-       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
-       wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0));\r
-       return atomic_read(&sensor->flags.open_flag);\r
-}\r
-\r
-\r
-/* ioctl - I/O control */\r
-static long compass_dev_ioctl(struct file *file,\r
-                         unsigned int cmd, unsigned long arg)\r
-{\r
-    struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);\r
-       struct i2c_client *client = this_client;\r
-       void __user *argp = (void __user *)arg;\r
-       int result = 0;\r
-       struct akm_platform_data compass;\r
-               \r
-       /* NOTE: In this function the size of "char" should be 1-byte. */\r
-       char compass_data[SENSOR_DATA_SIZE];    /* for GETDATA */\r
-       char rwbuf[RWBUF_SIZE];                 /* for READ/WRITE */\r
-       char mode;                              /* for SET_MODE*/\r
-       int value[YPR_DATA_SIZE];               /* for SET_YPR */\r
-       int status;                             /* for OPEN/CLOSE_STATUS */\r
-       int ret = -1;                           /* Return value. */\r
-       \r
-       //int8_t sensor_buf[SENSOR_DATA_SIZE];  /* for GETDATA */\r
-       //int32_t ypr_buf[YPR_DATA_SIZE];       /* for SET_YPR */\r
-       int16_t acc_buf[3];                     /* for GET_ACCEL */\r
-       int64_t delay[AKM_NUM_SENSORS];         /* for GET_DELAY */\r
-       char layout;            /* for GET_LAYOUT */\r
-       char outbit;            /* for GET_OUTBIT */\r
-\r
-       switch (cmd) {\r
-       case ECS_IOCTL_WRITE:\r
-       case ECS_IOCTL_READ:\r
-               if (argp == NULL) {\r
-                       return -EINVAL;\r
-               }\r
-               if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) {\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_SET_MODE:\r
-               if (argp == NULL) {\r
-                       return -EINVAL;\r
-               }\r
-               if (copy_from_user(&mode, argp, sizeof(mode))) {\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_SET_YPR:\r
-               if (argp == NULL) {\r
-                       return -EINVAL;\r
-               }\r
-               if (copy_from_user(&value, argp, sizeof(value))) {\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_GETDATA:\r
-       case ECS_IOCTL_GET_OPEN_STATUS:\r
-       case ECS_IOCTL_GET_CLOSE_STATUS:\r
-       case ECS_IOCTL_GET_DELAY:\r
-       case ECS_IOCTL_GET_LAYOUT:\r
-       case ECS_IOCTL_GET_OUTBIT:\r
-       case ECS_IOCTL_GET_ACCEL:\r
-       case ECS_IOCTL_GET_INFO:\r
-       case ECS_IOCTL_GET_CONF:\r
-               /* Just check buffer pointer */\r
-               if (argp == NULL) {\r
-                       printk("%s:invalid argument\n",__func__);\r
-                       return -EINVAL;\r
-               }\r
-               break;\r
-       default:\r
-               break;\r
-       }\r
-\r
-       switch (cmd) {\r
-       case ECS_IOCTL_WRITE:\r
-               DBG("%s:ECS_IOCTL_WRITE start\n",__func__);\r
-               mutex_lock(&sensor->operation_mutex);\r
-               if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) {                    \r
-                       mutex_unlock(&sensor->operation_mutex);\r
-                       return -EINVAL;\r
-               }\r
-               ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]);\r
-               if (ret < 0) {  \r
-                       mutex_unlock(&sensor->operation_mutex);         \r
-                       printk("%s:fait to tx data\n",__func__);\r
-                       return ret;\r
-               }                       \r
-               mutex_unlock(&sensor->operation_mutex);\r
-               break;\r
-       case ECS_IOCTL_READ:                            \r
-               DBG("%s:ECS_IOCTL_READ start\n",__func__);\r
-               mutex_lock(&sensor->operation_mutex);\r
-               if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) {            \r
-                       mutex_unlock(&sensor->operation_mutex);                 \r
-                       printk("%s:data is error\n",__func__);\r
-                       return -EINVAL;\r
-               }\r
-               ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]);\r
-               if (ret < 0) {  \r
-                       mutex_unlock(&sensor->operation_mutex);         \r
-                       printk("%s:fait to rx data\n",__func__);\r
-                       return ret;\r
-               }               \r
-               mutex_unlock(&sensor->operation_mutex);\r
-               break;\r
-       case ECS_IOCTL_SET_MODE:\r
-               DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__);          \r
-               mutex_lock(&sensor->operation_mutex);\r
-               if(sensor->ops->ctrl_data != mode)\r
-               {\r
-                       ret = compass_akm_set_mode(client, mode);\r
-                       if (ret < 0) {\r
-                               printk("%s:fait to set mode\n",__func__);               \r
-                               mutex_unlock(&sensor->operation_mutex);\r
-                               return ret;\r
-                       }\r
-                       \r
-                       sensor->ops->ctrl_data = mode;\r
-               }\r
-               mutex_unlock(&sensor->operation_mutex);\r
-               break;\r
-       case ECS_IOCTL_GETDATA:\r
-                       DBG("%s:ECS_IOCTL_GETDATA start\n",__func__);\r
-                       mutex_lock(&sensor->data_mutex);        \r
-                       memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE);    //get data from buffer\r
-                       mutex_unlock(&sensor->data_mutex);\r
-                       break;\r
-       case ECS_IOCTL_SET_YPR:                 \r
-                       DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__);\r
-                       mutex_lock(&sensor->data_mutex);\r
-                       compass_set_YPR(value);         \r
-                       mutex_unlock(&sensor->data_mutex);\r
-               break;\r
-       case ECS_IOCTL_GET_OPEN_STATUS:\r
-               status = compass_akm_get_openstatus();  \r
-               DBG("%s:openstatus=%d\n",__func__,status);\r
-               break;\r
-       case ECS_IOCTL_GET_CLOSE_STATUS:\r
-               status = compass_akm_get_closestatus(); \r
-               DBG("%s:closestatus=%d\n",__func__,status);\r
-               break;\r
-       case ECS_IOCTL_GET_DELAY:\r
-               DBG("%s:ECS_IOCTL_GET_DELAY start\n",__func__);\r
-               mutex_lock(&sensor->operation_mutex);\r
-               delay[0] = sensor->flags.delay;\r
-               delay[1] = sensor->flags.delay;\r
-               delay[2] = sensor->flags.delay;\r
-               mutex_unlock(&sensor->operation_mutex);\r
-               break;\r
-       \r
-       case ECS_IOCTL_GET_PLATFORM_DATA:                       \r
-               DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__);\r
-       //      memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout));\r
-       //      memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name));\r
-               ret = copy_to_user(argp, &compass, sizeof(compass));\r
-               if(ret < 0)\r
-               {\r
-                       printk("%s:error,ret=%d\n",__FUNCTION__, ret);\r
-                       return ret;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_GET_LAYOUT:\r
-               DBG("%s:ECS_IOCTL_GET_LAYOUT start\n",__func__);\r
+       if (*stat2 & 0x08)
+       {
+               DBG(KERN_ERR "%s:compass data overflow\n",__func__);
+               return -3;
+       }
+#endif
+       /* »¥³âµØ»º´æÊý¾Ý. */
+       mutex_lock(&sensor->data_mutex);
+       memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);
+       mutex_unlock(&sensor->data_mutex);
+       DBG("%s:",__func__);
+       for(i=0; i<sensor->ops->read_len; i++)
+               DBG("0x%x,",buffer[i]);
+       DBG("\n");
+
+       if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0))    //read sensor intterupt status register
+       {
+
+               value = sensor_read_reg(client, sensor->ops->int_status_reg);
+               DBG("%s:sensor int status :0x%x\n",__func__,value);
+       }
+
+
+       //trigger next measurement
+       ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+       if(ret)
+       {
+               printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data);
+               return ret;
+       }
+
+       return ret;
+}
+
+static void compass_set_YPR(int *rbuf)
+{
+       struct sensor_private_data *sensor =
+           (struct sensor_private_data *) i2c_get_clientdata(this_client);
+
+       /* No events are reported */
+       if (!rbuf[0]) {
+               printk("%s:Don't waste a time.",__func__);
+               return;
+       }
+
+       DBG("%s:buf[0]=0x%x\n",__func__, rbuf[0]);
+
+       /* Report magnetic sensor information */
+       if (atomic_read(&sensor->flags.m_flag) && (rbuf[0] & ORI_DATA_READY)) {
+               input_report_abs(sensor->input_dev, ABS_RX, rbuf[9]);
+               input_report_abs(sensor->input_dev, ABS_RY, rbuf[10]);
+               input_report_abs(sensor->input_dev, ABS_RZ, rbuf[11]);
+               input_report_abs(sensor->input_dev, ABS_RUDDER, rbuf[4]);
+               DBG("%s:m_flag:x=%d,y=%d,z=%d,RUDDER=%d\n",__func__,rbuf[9], rbuf[10], rbuf[11], rbuf[4]);
+       }
+
+       /* Report acceleration sensor information */
+       if (atomic_read(&sensor->flags.a_flag) && (rbuf[0] & ACC_DATA_READY)) {
+               input_report_abs(sensor->input_dev, ABS_X, rbuf[1]);
+               input_report_abs(sensor->input_dev, ABS_Y, rbuf[2]);
+               input_report_abs(sensor->input_dev, ABS_Z, rbuf[3]);
+               input_report_abs(sensor->input_dev, ABS_WHEEL, rbuf[4]);
+
+               DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[1], rbuf[2], rbuf[3], rbuf[4]);
+       }
+
+       /* Report magnetic vector information */
+       if (atomic_read(&sensor->flags.mv_flag) && (rbuf[0] & MAG_DATA_READY)) {
+               input_report_abs(sensor->input_dev, ABS_HAT0X, rbuf[5]);
+               input_report_abs(sensor->input_dev, ABS_HAT0Y, rbuf[6]);
+               input_report_abs(sensor->input_dev, ABS_BRAKE, rbuf[7]);
+               input_report_abs(sensor->input_dev, ABS_HAT1X, rbuf[8]);
+
+               DBG("%s:mv_flag:x=%d,y=%d,z=%d,status=%d\n",__func__,rbuf[5], rbuf[6], rbuf[7], rbuf[8]);
+       }
+
+       input_sync(sensor->input_dev);
+
+       memcpy(g_akm_rbuf, rbuf, 12);   //used for ECS_IOCTL_GET_ACCEL
+}
+
+
+
+static int compass_dev_open(struct inode *inode, struct file *file)
+{
+       struct sensor_private_data* sensor =
+               (struct sensor_private_data *)i2c_get_clientdata(this_client);
+       int result = 0;
+       DBG("%s\n",__func__);
+
+       return result;
+}
+
+
+static int compass_dev_release(struct inode *inode, struct file *file)
+{
+       struct sensor_private_data* sensor =
+               (struct sensor_private_data *)i2c_get_clientdata(this_client);
+       int result = 0;
+       DBG("%s\n",__func__);
+
+       return result;
+}
+
+static int compass_akm_set_mode(struct i2c_client *client, char mode)
+{
+       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
+       int result = 0;
+
+       switch(mode & 0x1f)
+       {
+               case AK09911_MODE_SNG_MEASURE:
+               case AK09911_MODE_SELF_TEST:
+               case AK09911_MODE_FUSE_ACCESS:
+                       if(sensor->status_cur == SENSOR_OFF)
+                       {
+                               if(sensor->pdata->irq_enable)
+                               {
+                                       //DBG("%s:enable irq=%d\n",__func__,client->irq);
+                                       //enable_irq(client->irq);
+                               }
+                               else
+                               {
+                                       schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));
+                               }
+
+                               sensor->status_cur = SENSOR_ON;
+                       }
+
+                       break;
+
+               case AK09911_MODE_POWERDOWN:
+                       if(sensor->status_cur == SENSOR_ON)
+                       {
+                               if(sensor->pdata->irq_enable)
+                               {
+                                       //DBG("%s:disable irq=%d\n",__func__,client->irq);
+                                       //disable_irq_nosync(client->irq);//disable irq
+                               }
+                               else
+                               cancel_delayed_work_sync(&sensor->delaywork);
+
+                               sensor->status_cur = SENSOR_OFF;
+                       }
+                       break;
+
+       }
+
+       switch(mode & 0x1f)
+       {
+               case AK09911_MODE_SNG_MEASURE:
+                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SNG_MEASURE);
+                       if(result)
+                       printk("%s:i2c error,mode=%d\n",__func__,mode);
+                       break;
+               case AK09911_MODE_SELF_TEST:
+                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SELF_TEST);
+                       if(result)
+                       printk("%s:i2c error,mode=%d\n",__func__,mode);
+                       break;
+               case AK09911_MODE_FUSE_ACCESS:
+                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_FUSE_ACCESS);
+                       if(result)
+                       printk("%s:i2c error,mode=%d\n",__func__,mode);
+                       break;
+               case AK09911_MODE_POWERDOWN:
+                       /* Set powerdown mode */
+                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_POWERDOWN);
+                       if(result)
+                       printk("%s:i2c error,mode=%d\n",__func__,mode);
+                       udelay(100);
+                       break;
+               default:
+                       printk("%s: Unknown mode(%d)", __func__, mode);
+                       result = -EINVAL;
+                       break;
+       }
+       DBG("%s:mode=0x%x\n",__func__,mode);
+       return result;
+
+}
+
+static int compass_akm_reset(struct i2c_client *client)
+{
+       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
+       int result = 0;
+
+       if(sensor->pdata->reset_pin > 0)
+       {
+               gpio_direction_output(sensor->pdata->reset_pin, GPIO_LOW);
+               udelay(10);
+               gpio_direction_output(sensor->pdata->reset_pin, GPIO_HIGH);
+       }
+       else
+       {
+               /* Set measure mode */
+               result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK09911_MODE_SNG_MEASURE);
+               if(result)
+               printk("%s:fail to Set measure mode\n",__func__);
+       }
+
+       udelay(100);
+
+       return result;
+
+}
+
+
+
+static int compass_akm_get_openstatus(void)
+{
+       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
+       wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0));
+       return atomic_read(&sensor->flags.open_flag);
+}
+
+static int compass_akm_get_closestatus(void)
+{
+       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
+       wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0));
+       return atomic_read(&sensor->flags.open_flag);
+}
+
+
+/* ioctl - I/O control */
+static long compass_dev_ioctl(struct file *file,
+                         unsigned int cmd, unsigned long arg)
+{
+    struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
+       struct i2c_client *client = this_client;
+       void __user *argp = (void __user *)arg;
+       int result = 0;
+       struct akm_platform_data compass;
+
+       /* NOTE: In this function the size of "char" should be 1-byte. */
+       char compass_data[SENSOR_DATA_SIZE];    /* for GETDATA */
+       char rwbuf[RWBUF_SIZE];                 /* for READ/WRITE */
+       char mode;                              /* for SET_MODE*/
+       int value[YPR_DATA_SIZE];               /* for SET_YPR */
+       int status;                             /* for OPEN/CLOSE_STATUS */
+       int ret = -1;                           /* Return value. */
+
+       //int8_t sensor_buf[SENSOR_DATA_SIZE];  /* for GETDATA */
+       //int32_t ypr_buf[YPR_DATA_SIZE];       /* for SET_YPR */
+       int16_t acc_buf[3];                     /* for GET_ACCEL */
+       int64_t delay[AKM_NUM_SENSORS];         /* for GET_DELAY */
+       char layout;            /* for GET_LAYOUT */
+       char outbit;            /* for GET_OUTBIT */
+
+       switch (cmd) {
+       case ECS_IOCTL_WRITE:
+       case ECS_IOCTL_READ:
+               if (argp == NULL) {
+                       return -EINVAL;
+               }
+               if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) {
+                       return -EFAULT;
+               }
+               break;
+       case ECS_IOCTL_SET_MODE:
+               if (argp == NULL) {
+                       return -EINVAL;
+               }
+               if (copy_from_user(&mode, argp, sizeof(mode))) {
+                       return -EFAULT;
+               }
+               break;
+       case ECS_IOCTL_SET_YPR:
+               if (argp == NULL) {
+                       return -EINVAL;
+               }
+               if (copy_from_user(&value, argp, sizeof(value))) {
+                       return -EFAULT;
+               }
+               break;
+       case ECS_IOCTL_GETDATA:
+       case ECS_IOCTL_GET_OPEN_STATUS:
+       case ECS_IOCTL_GET_CLOSE_STATUS:
+       case ECS_IOCTL_GET_DELAY:
+       case ECS_IOCTL_GET_LAYOUT:
+       case ECS_IOCTL_GET_OUTBIT:
+       case ECS_IOCTL_GET_ACCEL:
+       case ECS_IOCTL_GET_INFO:
+       case ECS_IOCTL_GET_CONF:
+               /* Just check buffer pointer */
+               if (argp == NULL) {
+                       printk("%s:invalid argument\n",__func__);
+                       return -EINVAL;
+               }
+               break;
+       default:
+               break;
+       }
+
+       switch (cmd) {
+       case ECS_IOCTL_WRITE:
+               DBG("%s:ECS_IOCTL_WRITE start\n",__func__);
+               mutex_lock(&sensor->operation_mutex);
+               if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) {
+                       mutex_unlock(&sensor->operation_mutex);
+                       return -EINVAL;
+               }
+               ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]);
+               if (ret < 0) {
+                       mutex_unlock(&sensor->operation_mutex);
+                       printk("%s:fait to tx data\n",__func__);
+                       return ret;
+               }
+               mutex_unlock(&sensor->operation_mutex);
+               break;
+       case ECS_IOCTL_READ:
+               DBG("%s:ECS_IOCTL_READ start\n",__func__);
+               mutex_lock(&sensor->operation_mutex);
+               if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) {
+                       mutex_unlock(&sensor->operation_mutex);
+                       printk("%s:data is error\n",__func__);
+                       return -EINVAL;
+               }
+               ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]);
+               if (ret < 0) {
+                       mutex_unlock(&sensor->operation_mutex);
+                       printk("%s:fait to rx data\n",__func__);
+                       return ret;
+               }
+               mutex_unlock(&sensor->operation_mutex);
+               break;
+       case ECS_IOCTL_SET_MODE:
+               DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__);
+               mutex_lock(&sensor->operation_mutex);
+               if(sensor->ops->ctrl_data != mode)
+               {
+                       ret = compass_akm_set_mode(client, mode);
+                       if (ret < 0) {
+                               printk("%s:fait to set mode\n",__func__);
+                               mutex_unlock(&sensor->operation_mutex);
+                               return ret;
+                       }
+
+                       sensor->ops->ctrl_data = mode;
+               }
+               mutex_unlock(&sensor->operation_mutex);
+               break;
+       case ECS_IOCTL_GETDATA:
+                       DBG("%s:ECS_IOCTL_GETDATA start\n",__func__);
+                       mutex_lock(&sensor->data_mutex);
+                       memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE);    //get data from buffer
+                       mutex_unlock(&sensor->data_mutex);
+                       break;
+       case ECS_IOCTL_SET_YPR:
+                       DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__);
+                       mutex_lock(&sensor->data_mutex);
+                       compass_set_YPR(value);
+                       mutex_unlock(&sensor->data_mutex);
+               break;
+       case ECS_IOCTL_GET_OPEN_STATUS:
+               status = compass_akm_get_openstatus();
+               DBG("%s:openstatus=%d\n",__func__,status);
+               break;
+       case ECS_IOCTL_GET_CLOSE_STATUS:
+               status = compass_akm_get_closestatus();
+               DBG("%s:closestatus=%d\n",__func__,status);
+               break;
+       case ECS_IOCTL_GET_DELAY:
+               DBG("%s:ECS_IOCTL_GET_DELAY start\n",__func__);
+               mutex_lock(&sensor->operation_mutex);
+               delay[0] = sensor->flags.delay;
+               delay[1] = sensor->flags.delay;
+               delay[2] = sensor->flags.delay;
+               mutex_unlock(&sensor->operation_mutex);
+               break;
+
+       case ECS_IOCTL_GET_PLATFORM_DATA:
+               DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__);
+       //      memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout));
+       //      memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name));
+               ret = copy_to_user(argp, &compass, sizeof(compass));
+               if(ret < 0)
+               {
+                       printk("%s:error,ret=%d\n",__FUNCTION__, ret);
+                       return ret;
+               }
+               break;
+       case ECS_IOCTL_GET_LAYOUT:
+               DBG("%s:ECS_IOCTL_GET_LAYOUT start\n",__func__);
                if((sensor->pdata->layout >= 1) && (sensor->pdata->layout <=8 ))
                layout = sensor->pdata->layout;
                else
                layout = 1;
-               break;\r
-       case ECS_IOCTL_GET_OUTBIT:\r
-               DBG("%s:ECS_IOCTL_GET_OUTBIT start\n",__func__);\r
-               outbit = 1;     //sensor->pdata->outbit;\r
-               break;\r
-       case ECS_IOCTL_RESET:\r
-               DBG("%s:ECS_IOCTL_RESET start\n",__func__);\r
-               ret = compass_akm_reset(client);\r
-               if (ret < 0)\r
-                       return ret;\r
-               break;\r
-       case ECS_IOCTL_GET_ACCEL:\r
-               DBG("%s:ECS_IOCTL_GET_ACCEL start,no accel data\n",__func__);\r
-               mutex_lock(&sensor->operation_mutex);\r
-               acc_buf[0] = g_akm_rbuf[6];\r
-               acc_buf[1] = g_akm_rbuf[7];\r
-               acc_buf[2] = g_akm_rbuf[8];\r
-               mutex_unlock(&sensor->operation_mutex);\r
-               break;\r
-       case ECS_IOCTL_GET_INFO:\r
-               ret = copy_to_user(argp, g_sensor_info, sizeof(g_sensor_info));\r
-               if(ret < 0)\r
-               {\r
-                       printk("%s:error,ret=%d\n",__FUNCTION__, ret);\r
-                       return ret;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_GET_CONF:\r
-               ret = copy_to_user(argp, g_sensor_conf, sizeof(g_sensor_conf));\r
-               if(ret < 0)\r
-               {\r
-                       printk("%s:error,ret=%d\n",__FUNCTION__, ret);\r
-                       return ret;\r
-               }\r
-               break;\r
-\r
-       default:\r
-               return -ENOTTY;\r
-       }\r
-\r
-       switch (cmd) {\r
-       case ECS_IOCTL_READ:\r
-               if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) {\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_GETDATA:\r
-               if (copy_to_user(argp, &compass_data, sizeof(compass_data))) {\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_GET_OPEN_STATUS:\r
-       case ECS_IOCTL_GET_CLOSE_STATUS:\r
-               if (copy_to_user(argp, &status, sizeof(status))) {\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_GET_DELAY:\r
-               if (copy_to_user(argp, &delay, sizeof(delay))) {\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_GET_LAYOUT:\r
-               if (copy_to_user(argp, &layout, sizeof(layout))) {\r
-                       printk("%s:error:%d\n",__FUNCTION__,__LINE__);\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_GET_OUTBIT:\r
-               if (copy_to_user(argp, &outbit, sizeof(outbit))) {\r
-                       printk("%s:error:%d\n",__FUNCTION__,__LINE__);\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_GET_ACCEL:\r
-               if (copy_to_user(argp, &acc_buf, sizeof(acc_buf))) {\r
-                       printk("%s:error:%d\n",__FUNCTION__,__LINE__);\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
-       default:\r
-               break;\r
-       }\r
-\r
-       return result;\r
-}\r
-\r
-static struct file_operations compass_dev_fops =\r
-{\r
-       .owner = THIS_MODULE,\r
-       .open = compass_dev_open,\r
-       .release = compass_dev_release, \r
-       .unlocked_ioctl = compass_dev_ioctl,\r
-};\r
-\r
-\r
-static struct miscdevice compass_dev_device =\r
-{      \r
-       .minor = MISC_DYNAMIC_MINOR,\r
-       .name = "akm_dev",\r
-       .fops = &compass_dev_fops,\r
-};\r
-\r
-struct sensor_operate compass_akm09911_ops = {\r
-       .name                           = "akm09911",\r
-       .type                           = SENSOR_TYPE_COMPASS,  //it is important\r
-       .id_i2c                         = COMPASS_ID_AK09911,\r
-       .read_reg                       = AK09911_REG_ST1,      //read data\r
-       .read_len                       = SENSOR_DATA_SIZE,     //data length\r
-       .id_reg                         = AK09911_REG_WIA2,     //read id\r
-       .id_data                        = AK09911_DEVICE_ID,\r
-       .precision                      = 8,                    //12 bits\r
-       .ctrl_reg                       = AK09911_REG_CNTL2,    //enable or disable \r
-       .int_status_reg                 = SENSOR_UNKNOW_DATA,   //not exist\r
-       .range                          = {-0xffff,0xffff},\r
-       .trig                           = IRQF_TRIGGER_RISING,  //if LEVEL interrupt then IRQF_ONESHOT\r
-       .active                         = sensor_active,        \r
-       .init                           = sensor_init,\r
-       .report                         = sensor_report_value,  \r
-       .misc_dev                       = NULL,                 //private misc support\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *compass_get_ops(void)\r
-{\r
-       return &compass_akm09911_ops; \r
-}\r
-\r
-\r
-static int __init compass_akm09911_init(void)\r
-{\r
-       struct sensor_operate *ops = compass_get_ops();\r
-       int result = 0;\r
-       int type = ops->type;\r
-       result = sensor_register_slave(type, NULL, NULL, compass_get_ops);\r
-                               \r
-       return result;\r
-}\r
-\r
-static void __exit compass_akm09911_exit(void)\r
-{\r
-       struct sensor_operate *ops = compass_get_ops();\r
-       int type = ops->type;\r
-       sensor_unregister_slave(type, NULL, NULL, compass_get_ops);\r
-}\r
-\r
-\r
-module_init(compass_akm09911_init);\r
-module_exit(compass_akm09911_exit);\r
-\r
-\r
+               break;
+       case ECS_IOCTL_GET_OUTBIT:
+               DBG("%s:ECS_IOCTL_GET_OUTBIT start\n",__func__);
+               outbit = 1;     //sensor->pdata->outbit;
+               break;
+       case ECS_IOCTL_RESET:
+               DBG("%s:ECS_IOCTL_RESET start\n",__func__);
+               ret = compass_akm_reset(client);
+               if (ret < 0)
+                       return ret;
+               break;
+       case ECS_IOCTL_GET_ACCEL:
+               DBG("%s:ECS_IOCTL_GET_ACCEL start,no accel data\n",__func__);
+               mutex_lock(&sensor->operation_mutex);
+               acc_buf[0] = g_akm_rbuf[6];
+               acc_buf[1] = g_akm_rbuf[7];
+               acc_buf[2] = g_akm_rbuf[8];
+               mutex_unlock(&sensor->operation_mutex);
+               break;
+       case ECS_IOCTL_GET_INFO:
+               ret = copy_to_user(argp, g_sensor_info, sizeof(g_sensor_info));
+               if(ret < 0)
+               {
+                       printk("%s:error,ret=%d\n",__FUNCTION__, ret);
+                       return ret;
+               }
+               break;
+       case ECS_IOCTL_GET_CONF:
+               ret = copy_to_user(argp, g_sensor_conf, sizeof(g_sensor_conf));
+               if(ret < 0)
+               {
+                       printk("%s:error,ret=%d\n",__FUNCTION__, ret);
+                       return ret;
+               }
+               break;
+
+       default:
+               return -ENOTTY;
+       }
+
+       switch (cmd) {
+       case ECS_IOCTL_READ:
+               if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) {
+                       return -EFAULT;
+               }
+               break;
+       case ECS_IOCTL_GETDATA:
+               if (copy_to_user(argp, &compass_data, sizeof(compass_data))) {
+                       return -EFAULT;
+               }
+               break;
+       case ECS_IOCTL_GET_OPEN_STATUS:
+       case ECS_IOCTL_GET_CLOSE_STATUS:
+               if (copy_to_user(argp, &status, sizeof(status))) {
+                       return -EFAULT;
+               }
+               break;
+       case ECS_IOCTL_GET_DELAY:
+               if (copy_to_user(argp, &delay, sizeof(delay))) {
+                       return -EFAULT;
+               }
+               break;
+       case ECS_IOCTL_GET_LAYOUT:
+               if (copy_to_user(argp, &layout, sizeof(layout))) {
+                       printk("%s:error:%d\n",__FUNCTION__,__LINE__);
+                       return -EFAULT;
+               }
+               break;
+       case ECS_IOCTL_GET_OUTBIT:
+               if (copy_to_user(argp, &outbit, sizeof(outbit))) {
+                       printk("%s:error:%d\n",__FUNCTION__,__LINE__);
+                       return -EFAULT;
+               }
+               break;
+       case ECS_IOCTL_GET_ACCEL:
+               if (copy_to_user(argp, &acc_buf, sizeof(acc_buf))) {
+                       printk("%s:error:%d\n",__FUNCTION__,__LINE__);
+                       return -EFAULT;
+               }
+               break;
+       default:
+               break;
+       }
+
+       return result;
+}
+
+static struct file_operations compass_dev_fops =
+{
+       .owner = THIS_MODULE,
+       .open = compass_dev_open,
+       .release = compass_dev_release,
+       .unlocked_ioctl = compass_dev_ioctl,
+};
+
+
+static struct miscdevice compass_dev_device =
+{
+       .minor = MISC_DYNAMIC_MINOR,
+       .name = "akm_dev",
+       .fops = &compass_dev_fops,
+};
+
+struct sensor_operate compass_akm09911_ops = {
+       .name                           = "akm09911",
+       .type                           = SENSOR_TYPE_COMPASS,  //it is important
+       .id_i2c                         = COMPASS_ID_AK09911,
+       .read_reg                       = AK09911_REG_ST1,      //read data
+       .read_len                       = SENSOR_DATA_SIZE,     //data length
+       .id_reg                         = AK09911_REG_WIA2,     //read id
+       .id_data                        = AK09911_DEVICE_ID,
+       .precision                      = 8,                    //12 bits
+       .ctrl_reg                       = AK09911_REG_CNTL2,    //enable or disable
+       .int_status_reg                 = SENSOR_UNKNOW_DATA,   //not exist
+       .range                          = {-0xffff,0xffff},
+       .trig                           = IRQF_TRIGGER_RISING,  //if LEVEL interrupt then IRQF_ONESHOT
+       .active                         = sensor_active,
+       .init                           = sensor_init,
+       .report                         = sensor_report_value,
+       .misc_dev                       = NULL,                 //private misc support
+};
+
+/****************operate according to sensor chip:end************/
+
+//function name should not be changed
+static struct sensor_operate *compass_get_ops(void)
+{
+       return &compass_akm09911_ops;
+}
+
+
+static int __init compass_akm09911_init(void)
+{
+       struct sensor_operate *ops = compass_get_ops();
+       int result = 0;
+       int type = ops->type;
+       result = sensor_register_slave(type, NULL, NULL, compass_get_ops);
+
+       return result;
+}
+
+static void __exit compass_akm09911_exit(void)
+{
+       struct sensor_operate *ops = compass_get_ops();
+       int type = ops->type;
+       sensor_unregister_slave(type, NULL, NULL, compass_get_ops);
+}
+
+
+module_init(compass_akm09911_init);
+module_exit(compass_akm09911_exit);
+
+
index 227e941..d919aae 100644 (file)
-/* drivers/input/sensors/access/akm8963.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
+/* drivers/input/sensors/access/akm8963.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * 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/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
 #define AKM_SENSOR_INFO_SIZE 2
 #define AKM_SENSOR_CONF_SIZE 3
-#define SENSOR_DATA_SIZE       8\r
-#define YPR_DATA_SIZE          12\r
-#define RWBUF_SIZE             16\r
-\r
-#define ACC_DATA_FLAG          0\r
-#define MAG_DATA_FLAG          1\r
-#define ORI_DATA_FLAG          2\r
-#define AKM_NUM_SENSORS                3\r
-\r
-#define ACC_DATA_READY         (1<<(ACC_DATA_FLAG))\r
-#define MAG_DATA_READY         (1<<(MAG_DATA_FLAG))\r
-#define ORI_DATA_READY         (1<<(ORI_DATA_FLAG))\r
-\r
-/*! \name AK8963 constant definition\r
- \anchor AK8963_Def\r
- Constant definitions of the AK8963.*/\r
-#define AK8963_MEASUREMENT_TIME_US     10000\r
-\r
-/*! \name AK8963 operation mode\r
- \anchor AK8963_Mode\r
- Defines an operation mode of the AK8963.*/\r
-/*! @{*/\r
-#define AK8963_MODE_SNG_MEASURE        0x01\r
-#define        AK8963_MODE_SELF_TEST   0x08\r
-#define        AK8963_MODE_FUSE_ACCESS 0x0F\r
-#define        AK8963_MODE_POWERDOWN   0x00\r
-\r
-/*! @}*/\r
-\r
-/*! \name AK8963 register address\r
-\anchor AK8963_REG\r
-Defines a register address of the AK8963.*/\r
-/*! @{*/\r
-#define AK8963_REG_WIA         0x00\r
-#define AK8963_REG_INFO                0x01\r
-#define AK8963_REG_ST1         0x02\r
-#define AK8963_REG_HXL         0x03\r
-#define AK8963_REG_HXH         0x04\r
-#define AK8963_REG_HYL         0x05\r
-#define AK8963_REG_HYH         0x06\r
-#define AK8963_REG_HZL         0x07\r
-#define AK8963_REG_HZH         0x08\r
-#define AK8963_REG_ST2         0x09\r
-#define AK8963_REG_CNTL1       0x0A\r
-#define AK8963_REG_CNTL2       0x0B\r
-#define AK8963_REG_ASTC                0x0C\r
-#define AK8963_REG_TS1         0x0D\r
-#define AK8963_REG_TS2         0x0E\r
-#define AK8963_REG_I2CDIS      0x0F\r
+#define SENSOR_DATA_SIZE       8
+#define YPR_DATA_SIZE          12
+#define RWBUF_SIZE             16
+
+#define ACC_DATA_FLAG          0
+#define MAG_DATA_FLAG          1
+#define ORI_DATA_FLAG          2
+#define AKM_NUM_SENSORS                3
+
+#define ACC_DATA_READY         (1<<(ACC_DATA_FLAG))
+#define MAG_DATA_READY         (1<<(MAG_DATA_FLAG))
+#define ORI_DATA_READY         (1<<(ORI_DATA_FLAG))
+
+/*! \name AK8963 constant definition
+ \anchor AK8963_Def
+ Constant definitions of the AK8963.*/
+#define AK8963_MEASUREMENT_TIME_US     10000
+
+/*! \name AK8963 operation mode
+ \anchor AK8963_Mode
+ Defines an operation mode of the AK8963.*/
+/*! @{*/
+#define AK8963_MODE_SNG_MEASURE        0x01
+#define        AK8963_MODE_SELF_TEST   0x08
+#define        AK8963_MODE_FUSE_ACCESS 0x0F
+#define        AK8963_MODE_POWERDOWN   0x00
+
+/*! @}*/
+
+/*! \name AK8963 register address
+\anchor AK8963_REG
+Defines a register address of the AK8963.*/
+/*! @{*/
+#define AK8963_REG_WIA         0x00
+#define AK8963_REG_INFO                0x01
+#define AK8963_REG_ST1         0x02
+#define AK8963_REG_HXL         0x03
+#define AK8963_REG_HXH         0x04
+#define AK8963_REG_HYL         0x05
+#define AK8963_REG_HYH         0x06
+#define AK8963_REG_HZL         0x07
+#define AK8963_REG_HZH         0x08
+#define AK8963_REG_ST2         0x09
+#define AK8963_REG_CNTL1       0x0A
+#define AK8963_REG_CNTL2       0x0B
+#define AK8963_REG_ASTC                0x0C
+#define AK8963_REG_TS1         0x0D
+#define AK8963_REG_TS2         0x0E
+#define AK8963_REG_I2CDIS      0x0F
 
 #define AK8963_WIA_VALUE               0x48
 
-/*! @}*/\r
-\r
-/*! \name AK8963 fuse-rom address\r
-\anchor AK8963_FUSE\r
-Defines a read-only address of the fuse ROM of the AK8963.*/\r
-/*! @{*/\r
-#define AK8963_FUSE_ASAX       0x10\r
-#define AK8963_FUSE_ASAY       0x11\r
-#define AK8963_FUSE_ASAZ       0x12\r
-/*! @}*/\r
-\r
-#define AK8963_INFO_DATA       (0x03<<3)\r
-\r
-\r
-#define COMPASS_IOCTL_MAGIC                   'c'\r
-\r
-/* IOCTLs for AKM library */\r
-#define ECS_IOCTL_WRITE                 _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*)\r
-#define ECS_IOCTL_READ                  _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*)\r
-#define ECS_IOCTL_RESET                _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */\r
-#define ECS_IOCTL_SET_MODE              _IOW(COMPASS_IOCTL_MAGIC, 0x04, short)\r
-#define ECS_IOCTL_GETDATA               _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[SENSOR_DATA_SIZE])\r
-#define ECS_IOCTL_SET_YPR               _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12])\r
-#define ECS_IOCTL_GET_OPEN_STATUS       _IOR(COMPASS_IOCTL_MAGIC, 0x07, int)\r
-#define ECS_IOCTL_GET_CLOSE_STATUS      _IOR(COMPASS_IOCTL_MAGIC, 0x08, int)\r
-#define ECS_IOCTL_GET_LAYOUT           _IOR(COMPASS_IOCTL_MAGIC, 0x09, char)\r
-#define ECS_IOCTL_GET_ACCEL            _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3])\r
-#define ECS_IOCTL_GET_OUTBIT           _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char)\r
-#define ECS_IOCTL_GET_DELAY             _IOR(COMPASS_IOCTL_MAGIC, 0x30, short)\r
-#define ECS_IOCTL_GET_PROJECT_NAME      _IOR(COMPASS_IOCTL_MAGIC, 0x0D, char[64])\r
-#define ECS_IOCTL_GET_MATRIX            _IOR(COMPASS_IOCTL_MAGIC, 0x0E, short [4][3][3])\r
-#define ECS_IOCTL_GET_PLATFORM_DATA     _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data)\r
+/*! @}*/
+
+/*! \name AK8963 fuse-rom address
+\anchor AK8963_FUSE
+Defines a read-only address of the fuse ROM of the AK8963.*/
+/*! @{*/
+#define AK8963_FUSE_ASAX       0x10
+#define AK8963_FUSE_ASAY       0x11
+#define AK8963_FUSE_ASAZ       0x12
+/*! @}*/
+
+#define AK8963_INFO_DATA       (0x03<<3)
+
+
+#define COMPASS_IOCTL_MAGIC                   'c'
+
+/* IOCTLs for AKM library */
+#define ECS_IOCTL_WRITE                 _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*)
+#define ECS_IOCTL_READ                  _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*)
+#define ECS_IOCTL_RESET                _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */
+#define ECS_IOCTL_SET_MODE              _IOW(COMPASS_IOCTL_MAGIC, 0x04, short)
+#define ECS_IOCTL_GETDATA               _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[SENSOR_DATA_SIZE])
+#define ECS_IOCTL_SET_YPR               _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12])
+#define ECS_IOCTL_GET_OPEN_STATUS       _IOR(COMPASS_IOCTL_MAGIC, 0x07, int)
+#define ECS_IOCTL_GET_CLOSE_STATUS      _IOR(COMPASS_IOCTL_MAGIC, 0x08, int)
+#define ECS_IOCTL_GET_LAYOUT           _IOR(COMPASS_IOCTL_MAGIC, 0x09, char)
+#define ECS_IOCTL_GET_ACCEL            _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3])
+#define ECS_IOCTL_GET_OUTBIT           _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char)
+#define ECS_IOCTL_GET_DELAY             _IOR(COMPASS_IOCTL_MAGIC, 0x30, short)
+#define ECS_IOCTL_GET_PROJECT_NAME      _IOR(COMPASS_IOCTL_MAGIC, 0x0D, char[64])
+#define ECS_IOCTL_GET_MATRIX            _IOR(COMPASS_IOCTL_MAGIC, 0x0E, short [4][3][3])
+#define ECS_IOCTL_GET_PLATFORM_DATA     _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data)
 #define ECS_IOCTL_GET_INFO                     _IOR(COMPASS_IOCTL_MAGIC, 0x27, unsigned char[AKM_SENSOR_INFO_SIZE])
 #define ECS_IOCTL_GET_CONF                     _IOR(COMPASS_IOCTL_MAGIC, 0x28, unsigned char[AKM_SENSOR_CONF_SIZE])
-\r
-#define AK8963_DEVICE_ID               0x48\r
-static struct i2c_client *this_client;\r
-static struct miscdevice compass_dev_device;\r
-\r
-static short g_akm_rbuf[12];\r
-\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
-       struct sensor_private_data *sensor =\r
-           (struct sensor_private_data *) i2c_get_clientdata(client);  \r
-       int result = 0;\r
-               \r
-       //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
-       \r
-       //register setting according to chip datasheet          \r
-       if(enable)\r
-       {       \r
-               sensor->ops->ctrl_data = AK8963_MODE_SNG_MEASURE;       \r
-       }\r
-       else\r
-       {\r
-               sensor->ops->ctrl_data = AK8963_MODE_POWERDOWN;\r
-       }\r
-\r
-       DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
-       result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
-       if(result)\r
-               printk("%s:fail to active sensor\n",__func__);\r
-       \r
-       return result;\r
-\r
-}\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{      \r
-       struct sensor_private_data *sensor =\r
-           (struct sensor_private_data *) i2c_get_clientdata(client);  \r
-       int result = 0;\r
-       char info = 0;\r
-\r
-       this_client = client;   \r
-\r
-       result = sensor->ops->active(client,0,0);\r
-       if(result)\r
-       {\r
-               printk("%s:line=%d,error\n",__func__,__LINE__);\r
-               return result;\r
-       }\r
-       \r
-       sensor->status_cur = SENSOR_OFF;\r
-\r
-       info = sensor_read_reg(client, AK8963_REG_INFO);        \r
-       if((info & (0x0f<<3)) != AK8963_INFO_DATA)\r
-       {\r
-               printk("%s:info=0x%x,it is not %s\n",__func__, info, sensor->ops->name);\r
-               return -1;\r
-       }\r
-\r
-       result = misc_register(&compass_dev_device);\r
-       if (result < 0) {\r
-               printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name);\r
-               result = -1;\r
-       }\r
-       \r
-       DBG("%s:status_cur=%d\n",__func__, sensor->status_cur);\r
-       return result;\r
-}\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
-       struct sensor_private_data *sensor =\r
-               (struct sensor_private_data *) i2c_get_clientdata(client);      \r
-       char buffer[8] = {0};   \r
-       unsigned char *stat;\r
-       unsigned char *stat2;   \r
-       int ret = 0;    \r
-       char value = 0;\r
-       int i;\r
-\r
-       if(sensor->ops->read_len < 8)   //sensor->ops->read_len = 8\r
-       {\r
-               printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
-               return -1;\r
-       }\r
-       \r
-       memset(buffer, 0, 8);\r
-       \r
-       /* Data bytes from hardware xL, xH, yL, yH, zL, zH */   \r
-       do {\r
-               *buffer = sensor->ops->read_reg;\r
-               ret = sensor_rx_data(client, buffer, sensor->ops->read_len);\r
-               if (ret < 0)\r
-               return ret;\r
-       } while (0);\r
-\r
-       stat = &buffer[0];\r
-       stat2 = &buffer[7];\r
-       \r
-       /*\r
+
+#define AK8963_DEVICE_ID               0x48
+static struct i2c_client *this_client;
+static struct miscdevice compass_dev_device;
+
+static short g_akm_rbuf[12];
+
+
+/****************operate according to sensor chip:start************/
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+       struct sensor_private_data *sensor =
+           (struct sensor_private_data *) i2c_get_clientdata(client);
+       int result = 0;
+
+       //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
+
+       //register setting according to chip datasheet
+       if(enable)
+       {
+               sensor->ops->ctrl_data = AK8963_MODE_SNG_MEASURE;
+       }
+       else
+       {
+               sensor->ops->ctrl_data = AK8963_MODE_POWERDOWN;
+       }
+
+       DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
+       result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+       if(result)
+               printk("%s:fail to active sensor\n",__func__);
+
+       return result;
+
+}
+
+static int sensor_init(struct i2c_client *client)
+{
+       struct sensor_private_data *sensor =
+           (struct sensor_private_data *) i2c_get_clientdata(client);
+       int result = 0;
+       char info = 0;
+
+       this_client = client;
+
+       result = sensor->ops->active(client,0,0);
+       if(result)
+       {
+               printk("%s:line=%d,error\n",__func__,__LINE__);
+               return result;
+       }
+
+       sensor->status_cur = SENSOR_OFF;
+
+       info = sensor_read_reg(client, AK8963_REG_INFO);
+       if((info & (0x0f<<3)) != AK8963_INFO_DATA)
+       {
+               printk("%s:info=0x%x,it is not %s\n",__func__, info, sensor->ops->name);
+               return -1;
+       }
+
+       result = misc_register(&compass_dev_device);
+       if (result < 0) {
+               printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name);
+               result = -1;
+       }
+
+       DBG("%s:status_cur=%d\n",__func__, sensor->status_cur);
+       return result;
+}
+
+static int sensor_report_value(struct i2c_client *client)
+{
+       struct sensor_private_data *sensor =
+               (struct sensor_private_data *) i2c_get_clientdata(client);
+       char buffer[8] = {0};
+       unsigned char *stat;
+       unsigned char *stat2;
+       int ret = 0;
+       char value = 0;
+       int i;
+
+       if(sensor->ops->read_len < 8)   //sensor->ops->read_len = 8
+       {
+               printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
+               return -1;
+       }
+
+       memset(buffer, 0, 8);
+
+       /* Data bytes from hardware xL, xH, yL, yH, zL, zH */
+       do {
+               *buffer = sensor->ops->read_reg;
+               ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
+               if (ret < 0)
+               return ret;
+       } while (0);
+
+       stat = &buffer[0];
+       stat2 = &buffer[7];
+
+       /*
         * ST : data ready -
         * Measurement has been completed and data is ready to be read.
-        */\r
-       if ((*stat & 0x01) != 0x01) {\r
-               DBG(KERN_ERR "%s:ST is not set\n",__func__);\r
-               return -1;\r
-       }\r
+        */
+       if ((*stat & 0x01) != 0x01) {
+               DBG(KERN_ERR "%s:ST is not set\n",__func__);
+               return -1;
+       }
 
        /*
         * ST2 : data error -
@@ -240,12 +240,12 @@ static int sensor_report_value(struct i2c_client *client)
         * corrupted.
         * DERR bit is self-clearing when ST2 register is read.
         */
-       if (*stat2 & 0x04)\r
-       {\r
-               DBG(KERN_ERR "%s:compass data error\n",__func__);\r
-               return -2;\r
-       }\r
-       \r
+       if (*stat2 & 0x04)
+       {
+               DBG(KERN_ERR "%s:compass data error\n",__func__);
+               return -2;
+       }
+
        /*
         * ST2 : overflow -
         * the sum of the absolute values of all axis |X|+|Y|+|Z| < 2400uT.
@@ -255,54 +255,54 @@ static int sensor_report_value(struct i2c_client *client)
         * An error is returned.
         * HOFL bit clears when a new measurement starts.
         */
-       if (*stat2 & 0x08)\r
-       {       \r
-               DBG(KERN_ERR "%s:compass data overflow\n",__func__);\r
-               return -3;\r
-       }\r
-       \r
-       /* »¥³âµØ»º´æÊý¾Ý. */\r
-       mutex_lock(&sensor->data_mutex);        \r
-       memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);\r
-       mutex_unlock(&sensor->data_mutex);\r
-       DBG("%s:",__func__);\r
-       for(i=0; i<sensor->ops->read_len; i++)\r
-               DBG("0x%x,",buffer[i]);\r
-       DBG("\n");\r
-\r
-       if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0))    //read sensor intterupt status register\r
-       {\r
-               \r
-               value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
-               DBG("%s:sensor int status :0x%x\n",__func__,value);\r
-       }\r
-\r
-       \r
-       //trigger next measurement \r
-       ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
-       if(ret)\r
-       {\r
-               printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data);\r
-               return ret;\r
-       }\r
-\r
-       return ret;\r
-}\r
-\r
-static void compass_set_YPR(int *rbuf)\r
-{\r
-       struct sensor_private_data *sensor =\r
-           (struct sensor_private_data *) i2c_get_clientdata(this_client);     \r
-\r
-       /* No events are reported */\r
-       if (!rbuf[0]) {\r
-               printk("%s:Don't waste a time.",__func__);\r
-               return;\r
-       }\r
-\r
-       DBG("%s:buf[0]=0x%x\n",__func__, rbuf[0]);\r
-       \r
-       /* Report magnetic sensor information */\r
+       if (*stat2 & 0x08)
+       {
+               DBG(KERN_ERR "%s:compass data overflow\n",__func__);
+               return -3;
+       }
+
+       /* »¥³âµØ»º´æÊý¾Ý. */
+       mutex_lock(&sensor->data_mutex);
+       memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);
+       mutex_unlock(&sensor->data_mutex);
+       DBG("%s:",__func__);
+       for(i=0; i<sensor->ops->read_len; i++)
+               DBG("0x%x,",buffer[i]);
+       DBG("\n");
+
+       if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0))    //read sensor intterupt status register
+       {
+
+               value = sensor_read_reg(client, sensor->ops->int_status_reg);
+               DBG("%s:sensor int status :0x%x\n",__func__,value);
+       }
+
+
+       //trigger next measurement
+       ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+       if(ret)
+       {
+               printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data);
+               return ret;
+       }
+
+       return ret;
+}
+
+static void compass_set_YPR(int *rbuf)
+{
+       struct sensor_private_data *sensor =
+           (struct sensor_private_data *) i2c_get_clientdata(this_client);
+
+       /* No events are reported */
+       if (!rbuf[0]) {
+               printk("%s:Don't waste a time.",__func__);
+               return;
+       }
+
+       DBG("%s:buf[0]=0x%x\n",__func__, rbuf[0]);
+
+       /* Report magnetic sensor information */
        if (atomic_read(&sensor->flags.m_flag) && (rbuf[0] & ORI_DATA_READY)) {
                input_report_abs(sensor->input_dev, ABS_RX, rbuf[9]);
                input_report_abs(sensor->input_dev, ABS_RY, rbuf[10]);
@@ -310,18 +310,18 @@ static void compass_set_YPR(int *rbuf)
                input_report_abs(sensor->input_dev, ABS_RUDDER, rbuf[4]);
                DBG("%s:m_flag:x=%d,y=%d,z=%d,RUDDER=%d\n", __func__, rbuf[9], rbuf[10], rbuf[11], rbuf[4]);
        }
-       \r
-       /* Report acceleration sensor information */\r
-       if (atomic_read(&sensor->flags.a_flag) && (rbuf[0] & ACC_DATA_READY)) {\r
-               input_report_abs(sensor->input_dev, ABS_X, rbuf[1]);\r
-               input_report_abs(sensor->input_dev, ABS_Y, rbuf[2]);\r
-               input_report_abs(sensor->input_dev, ABS_Z, rbuf[3]);\r
-               input_report_abs(sensor->input_dev, ABS_WHEEL, rbuf[4]);\r
-               \r
-               DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[1], rbuf[2], rbuf[3], rbuf[4]);\r
-       }\r
-       \r
-       /* Report magnetic vector information */\r
+
+       /* Report acceleration sensor information */
+       if (atomic_read(&sensor->flags.a_flag) && (rbuf[0] & ACC_DATA_READY)) {
+               input_report_abs(sensor->input_dev, ABS_X, rbuf[1]);
+               input_report_abs(sensor->input_dev, ABS_Y, rbuf[2]);
+               input_report_abs(sensor->input_dev, ABS_Z, rbuf[3]);
+               input_report_abs(sensor->input_dev, ABS_WHEEL, rbuf[4]);
+
+               DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[1], rbuf[2], rbuf[3], rbuf[4]);
+       }
+
+       /* Report magnetic vector information */
        if (atomic_read(&sensor->flags.mv_flag) && (rbuf[0] & MAG_DATA_READY)) {
                input_report_abs(sensor->input_dev, ABS_HAT0X, rbuf[5]);
                input_report_abs(sensor->input_dev, ABS_HAT0Y, rbuf[6]);
@@ -330,225 +330,225 @@ static void compass_set_YPR(int *rbuf)
 
                DBG("%s:mv_flag:x=%d,y=%d,z=%d,status=%d\n", __func__, rbuf[5], rbuf[6], rbuf[7], rbuf[8]);
        }
-       \r
-       input_sync(sensor->input_dev);\r
-\r
-       memcpy(g_akm_rbuf, rbuf, 12);   //used for ECS_IOCTL_GET_ACCEL\r
-}\r
-\r
-\r
-\r
-static int compass_dev_open(struct inode *inode, struct file *file)\r
-{\r
-       int result = 0;\r
-       DBG("%s\n",__func__);\r
-\r
-       return result;\r
-}\r
-\r
-\r
-static int compass_dev_release(struct inode *inode, struct file *file)\r
-{\r
-       int result = 0; \r
-       DBG("%s\n",__func__);\r
-\r
-       return result;\r
-}\r
-\r
-static int compass_akm_set_mode(struct i2c_client *client, char mode)\r
-{\r
-       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
-       int result = 0; \r
-\r
-       switch(mode & 0x0f)\r
-       {\r
-               case AK8963_MODE_SNG_MEASURE:\r
-               case AK8963_MODE_SELF_TEST:     \r
-               case AK8963_MODE_FUSE_ACCESS:                   \r
-                       if(sensor->status_cur == SENSOR_OFF)\r
-                       {\r
-                               if(sensor->pdata->irq_enable)\r
-                               {\r
-                                       //DBG("%s:enable irq=%d\n",__func__,client->irq);\r
-                                       //enable_irq(client->irq);\r
-                               }       \r
-                               else\r
-                               {\r
-                                       schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
-                               }\r
-                               \r
-                               sensor->status_cur = SENSOR_ON;\r
-                       }\r
-\r
-                       break;\r
-\r
-               case AK8963_MODE_POWERDOWN:     \r
-                       if(sensor->status_cur == SENSOR_ON)\r
-                       {\r
-                               if(sensor->pdata->irq_enable)\r
-                               {       \r
-                                       //DBG("%s:disable irq=%d\n",__func__,client->irq);\r
-                                       //disable_irq_nosync(client->irq);//disable irq\r
-                               }\r
-                               else\r
-                               cancel_delayed_work_sync(&sensor->delaywork);   \r
-\r
-                               sensor->status_cur = SENSOR_OFF;\r
-                       }\r
-                       break;\r
-\r
-       }\r
-       \r
-       switch(mode & 0x0f)\r
-       {\r
-               case AK8963_MODE_SNG_MEASURE:           \r
-                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode);\r
-                       if(result)\r
-                       printk("%s:i2c error,mode=%d\n",__func__,mode);                         \r
-                       break;\r
-               case AK8963_MODE_SELF_TEST:                     \r
-                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode);\r
-                       if(result)\r
-                       printk("%s:i2c error,mode=%d\n",__func__,mode);\r
-                       break;\r
-               case AK8963_MODE_FUSE_ACCESS:\r
-                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode);\r
-                       if(result)\r
-                       printk("%s:i2c error,mode=%d\n",__func__,mode);\r
-                       break;\r
-               case AK8963_MODE_POWERDOWN:\r
-                       /* Set powerdown mode */\r
-                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8963_MODE_POWERDOWN);\r
-                       if(result)\r
-                       printk("%s:i2c error,mode=%d\n",__func__,mode);\r
-                       udelay(100);\r
-                       break;\r
-               default:\r
-                       printk("%s: Unknown mode(%d)", __func__, mode);\r
-                       result = -EINVAL;\r
-                       break;\r
-       }\r
-       DBG("%s:mode=0x%x\n",__func__,mode);\r
-       return result;\r
-\r
-}\r
-\r
-static int compass_akm_reset(struct i2c_client *client)\r
-{\r
-       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
-       int result = 0; \r
-       \r
-       if(sensor->pdata->reset_pin > 0)\r
-       {\r
-               gpio_direction_output(sensor->pdata->reset_pin, GPIO_LOW);\r
-               udelay(10);\r
-               gpio_direction_output(sensor->pdata->reset_pin, GPIO_HIGH);\r
-       }\r
-       else    \r
-       {\r
-               /* Set measure mode */\r
-               result = sensor_write_reg(client, AK8963_REG_CNTL2, AK8963_MODE_SNG_MEASURE);\r
-               if(result)\r
-               printk("%s:fail to Set measure mode\n",__func__);\r
-       }\r
-       \r
-       udelay(100);\r
-       \r
-       return result;\r
-\r
-}\r
-\r
-\r
-\r
-static int compass_akm_get_openstatus(void)\r
-{      \r
-       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
-       wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0));\r
-       return atomic_read(&sensor->flags.open_flag);\r
-}\r
-\r
-static int compass_akm_get_closestatus(void)\r
-{      \r
-       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
-       wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0));\r
-       return atomic_read(&sensor->flags.open_flag);\r
-}\r
-\r
-\r
-/* ioctl - I/O control */\r
-static long compass_dev_ioctl(struct file *file,\r
-                         unsigned int cmd, unsigned long arg)\r
-{\r
-    struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);\r
-       struct i2c_client *client = this_client;\r
-       void __user *argp = (void __user *)arg;\r
-       int result = 0;\r
-       struct akm_platform_data compass;\r
+
+       input_sync(sensor->input_dev);
+
+       memcpy(g_akm_rbuf, rbuf, 12);   //used for ECS_IOCTL_GET_ACCEL
+}
+
+
+
+static int compass_dev_open(struct inode *inode, struct file *file)
+{
+       int result = 0;
+       DBG("%s\n",__func__);
+
+       return result;
+}
+
+
+static int compass_dev_release(struct inode *inode, struct file *file)
+{
+       int result = 0;
+       DBG("%s\n",__func__);
+
+       return result;
+}
+
+static int compass_akm_set_mode(struct i2c_client *client, char mode)
+{
+       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
+       int result = 0;
+
+       switch(mode & 0x0f)
+       {
+               case AK8963_MODE_SNG_MEASURE:
+               case AK8963_MODE_SELF_TEST:
+               case AK8963_MODE_FUSE_ACCESS:
+                       if(sensor->status_cur == SENSOR_OFF)
+                       {
+                               if(sensor->pdata->irq_enable)
+                               {
+                                       //DBG("%s:enable irq=%d\n",__func__,client->irq);
+                                       //enable_irq(client->irq);
+                               }
+                               else
+                               {
+                                       schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));
+                               }
+
+                               sensor->status_cur = SENSOR_ON;
+                       }
+
+                       break;
+
+               case AK8963_MODE_POWERDOWN:
+                       if(sensor->status_cur == SENSOR_ON)
+                       {
+                               if(sensor->pdata->irq_enable)
+                               {
+                                       //DBG("%s:disable irq=%d\n",__func__,client->irq);
+                                       //disable_irq_nosync(client->irq);//disable irq
+                               }
+                               else
+                               cancel_delayed_work_sync(&sensor->delaywork);
+
+                               sensor->status_cur = SENSOR_OFF;
+                       }
+                       break;
+
+       }
+
+       switch(mode & 0x0f)
+       {
+               case AK8963_MODE_SNG_MEASURE:
+                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode);
+                       if(result)
+                       printk("%s:i2c error,mode=%d\n",__func__,mode);
+                       break;
+               case AK8963_MODE_SELF_TEST:
+                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode);
+                       if(result)
+                       printk("%s:i2c error,mode=%d\n",__func__,mode);
+                       break;
+               case AK8963_MODE_FUSE_ACCESS:
+                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, mode);
+                       if(result)
+                       printk("%s:i2c error,mode=%d\n",__func__,mode);
+                       break;
+               case AK8963_MODE_POWERDOWN:
+                       /* Set powerdown mode */
+                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8963_MODE_POWERDOWN);
+                       if(result)
+                       printk("%s:i2c error,mode=%d\n",__func__,mode);
+                       udelay(100);
+                       break;
+               default:
+                       printk("%s: Unknown mode(%d)", __func__, mode);
+                       result = -EINVAL;
+                       break;
+       }
+       DBG("%s:mode=0x%x\n",__func__,mode);
+       return result;
+
+}
+
+static int compass_akm_reset(struct i2c_client *client)
+{
+       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
+       int result = 0;
+
+       if(sensor->pdata->reset_pin > 0)
+       {
+               gpio_direction_output(sensor->pdata->reset_pin, GPIO_LOW);
+               udelay(10);
+               gpio_direction_output(sensor->pdata->reset_pin, GPIO_HIGH);
+       }
+       else
+       {
+               /* Set measure mode */
+               result = sensor_write_reg(client, AK8963_REG_CNTL2, AK8963_MODE_SNG_MEASURE);
+               if(result)
+               printk("%s:fail to Set measure mode\n",__func__);
+       }
+
+       udelay(100);
+
+       return result;
+
+}
+
+
+
+static int compass_akm_get_openstatus(void)
+{
+       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
+       wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0));
+       return atomic_read(&sensor->flags.open_flag);
+}
+
+static int compass_akm_get_closestatus(void)
+{
+       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
+       wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0));
+       return atomic_read(&sensor->flags.open_flag);
+}
+
+
+/* ioctl - I/O control */
+static long compass_dev_ioctl(struct file *file,
+                         unsigned int cmd, unsigned long arg)
+{
+    struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
+       struct i2c_client *client = this_client;
+       void __user *argp = (void __user *)arg;
+       int result = 0;
+       struct akm_platform_data compass;
        unsigned char sense_info[AKM_SENSOR_INFO_SIZE];
        unsigned char sense_conf[AKM_SENSOR_CONF_SIZE];
 
-       /* NOTE: In this function the size of "char" should be 1-byte. */\r
-       char compass_data[SENSOR_DATA_SIZE];    /* for GETDATA */\r
-       char rwbuf[RWBUF_SIZE];                 /* for READ/WRITE */\r
-       char mode;                              /* for SET_MODE*/\r
-       int value[12];                  /* for SET_YPR */\r
-       int status;                             /* for OPEN/CLOSE_STATUS */\r
-       int ret = -1;                           /* Return value. */\r
-       \r
-       //int8_t sensor_buf[SENSOR_DATA_SIZE];  /* for GETDATA */\r
-       //int32_t ypr_buf[YPR_DATA_SIZE];       /* for SET_YPR */\r
-       int16_t acc_buf[3];                     /* for GET_ACCEL */\r
-       int64_t delay[AKM_NUM_SENSORS];         /* for GET_DELAY */\r
-\r
-       char layout;            /* for GET_LAYOUT */\r
-       char outbit;            /* for GET_OUTBIT */\r
-\r
-       switch (cmd) {\r
-       case ECS_IOCTL_WRITE:\r
-       case ECS_IOCTL_READ:\r
-               if (argp == NULL) {\r
-                       return -EINVAL;\r
-               }\r
-               if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) {\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_SET_MODE:\r
-               if (argp == NULL) {\r
-                       return -EINVAL;\r
-               }\r
-               if (copy_from_user(&mode, argp, sizeof(mode))) {\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_SET_YPR:\r
-               if (argp == NULL) {\r
-                       return -EINVAL;\r
-               }\r
-               if (copy_from_user(&value, argp, sizeof(value))) {\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
+       /* NOTE: In this function the size of "char" should be 1-byte. */
+       char compass_data[SENSOR_DATA_SIZE];    /* for GETDATA */
+       char rwbuf[RWBUF_SIZE];                 /* for READ/WRITE */
+       char mode;                              /* for SET_MODE*/
+       int value[12];                  /* for SET_YPR */
+       int status;                             /* for OPEN/CLOSE_STATUS */
+       int ret = -1;                           /* Return value. */
+
+       //int8_t sensor_buf[SENSOR_DATA_SIZE];  /* for GETDATA */
+       //int32_t ypr_buf[YPR_DATA_SIZE];       /* for SET_YPR */
+       int16_t acc_buf[3];                     /* for GET_ACCEL */
+       int64_t delay[AKM_NUM_SENSORS];         /* for GET_DELAY */
+
+       char layout;            /* for GET_LAYOUT */
+       char outbit;            /* for GET_OUTBIT */
+
+       switch (cmd) {
+       case ECS_IOCTL_WRITE:
+       case ECS_IOCTL_READ:
+               if (argp == NULL) {
+                       return -EINVAL;
+               }
+               if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) {
+                       return -EFAULT;
+               }
+               break;
+       case ECS_IOCTL_SET_MODE:
+               if (argp == NULL) {
+                       return -EINVAL;
+               }
+               if (copy_from_user(&mode, argp, sizeof(mode))) {
+                       return -EFAULT;
+               }
+               break;
+       case ECS_IOCTL_SET_YPR:
+               if (argp == NULL) {
+                       return -EINVAL;
+               }
+               if (copy_from_user(&value, argp, sizeof(value))) {
+                       return -EFAULT;
+               }
+               break;
        case ECS_IOCTL_GET_INFO:
        case ECS_IOCTL_GET_CONF:
-       case ECS_IOCTL_GETDATA:\r
-       case ECS_IOCTL_GET_OPEN_STATUS:\r
-       case ECS_IOCTL_GET_CLOSE_STATUS:\r
-       case ECS_IOCTL_GET_DELAY:\r
-       case ECS_IOCTL_GET_LAYOUT:\r
-       case ECS_IOCTL_GET_OUTBIT:\r
-       case ECS_IOCTL_GET_ACCEL:\r
-               /* Just check buffer pointer */\r
-               if (argp == NULL) {\r
-                       printk("%s:invalid argument\n",__func__);\r
-                       return -EINVAL;\r
-               }\r
-               break;\r
-       default:\r
-               break;\r
-       }\r
-\r
-       switch (cmd) {\r
+       case ECS_IOCTL_GETDATA:
+       case ECS_IOCTL_GET_OPEN_STATUS:
+       case ECS_IOCTL_GET_CLOSE_STATUS:
+       case ECS_IOCTL_GET_DELAY:
+       case ECS_IOCTL_GET_LAYOUT:
+       case ECS_IOCTL_GET_OUTBIT:
+       case ECS_IOCTL_GET_ACCEL:
+               /* Just check buffer pointer */
+               if (argp == NULL) {
+                       printk("%s:invalid argument\n",__func__);
+                       return -EINVAL;
+               }
+               break;
+       default:
+               break;
+       }
+
+       switch (cmd) {
        case ECS_IOCTL_GET_INFO:
                sense_info[0] = AK8963_REG_WIA;
                mutex_lock(&sensor->operation_mutex);
@@ -575,160 +575,160 @@ static long compass_dev_ioctl(struct file *file,
                        return ret;
                }
                break;
-       case ECS_IOCTL_WRITE:\r
-               DBG("%s:ECS_IOCTL_WRITE start\n",__func__);\r
-               mutex_lock(&sensor->operation_mutex);\r
-               if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) {                    \r
-                       mutex_unlock(&sensor->operation_mutex);\r
-                       return -EINVAL;\r
-               }\r
-               ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]);\r
-               if (ret < 0) {  \r
-                       mutex_unlock(&sensor->operation_mutex);         \r
-                       printk("%s:fait to tx data\n",__func__);\r
-                       return ret;\r
-               }                       \r
-               mutex_unlock(&sensor->operation_mutex);\r
-               break;\r
-       case ECS_IOCTL_READ:                            \r
-               DBG("%s:ECS_IOCTL_READ start\n",__func__);\r
-               mutex_lock(&sensor->operation_mutex);\r
-               if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) {            \r
-                       mutex_unlock(&sensor->operation_mutex);                 \r
-                       printk("%s:data is error\n",__func__);\r
-                       return -EINVAL;\r
-               }\r
-               ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]);\r
-               if (ret < 0) {  \r
-                       mutex_unlock(&sensor->operation_mutex);         \r
-                       printk("%s:fait to rx data\n",__func__);\r
-                       return ret;\r
-               }               \r
-               mutex_unlock(&sensor->operation_mutex);\r
-               break;\r
-       case ECS_IOCTL_SET_MODE:\r
-               DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__);          \r
-               mutex_lock(&sensor->operation_mutex);\r
-               if(sensor->ops->ctrl_data != mode)\r
-               {\r
-                       ret = compass_akm_set_mode(client, mode);\r
-                       if (ret < 0) {\r
-                               printk("%s:fait to set mode\n",__func__);               \r
-                               mutex_unlock(&sensor->operation_mutex);\r
-                               return ret;\r
-                       }\r
-                       \r
-                       sensor->ops->ctrl_data = mode;\r
-               }\r
-               mutex_unlock(&sensor->operation_mutex);\r
-               break;\r
-       case ECS_IOCTL_GETDATA:\r
-                       DBG("%s:ECS_IOCTL_GETDATA start\n",__func__);\r
-                       mutex_lock(&sensor->data_mutex);        \r
-                       memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE);    //get data from buffer\r
-                       mutex_unlock(&sensor->data_mutex);\r
-                       break;\r
-       case ECS_IOCTL_SET_YPR:                 \r
-                       DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__);\r
-                       mutex_lock(&sensor->data_mutex);\r
-                       compass_set_YPR(value);         \r
-                       mutex_unlock(&sensor->data_mutex);\r
-               break;\r
-       case ECS_IOCTL_GET_OPEN_STATUS:\r
-               status = compass_akm_get_openstatus();  \r
-               DBG("%s:openstatus=%d\n",__func__,status);\r
-               break;\r
-       case ECS_IOCTL_GET_CLOSE_STATUS:\r
-               status = compass_akm_get_closestatus(); \r
-               DBG("%s:closestatus=%d\n",__func__,status);\r
-               break;\r
-       case ECS_IOCTL_GET_DELAY:\r
-               DBG("%s:ECS_IOCTL_GET_DELAY start\n",__func__);\r
-               mutex_lock(&sensor->operation_mutex);\r
-               delay[0] = sensor->flags.delay;\r
-               delay[1] = sensor->flags.delay;\r
-               delay[2] = sensor->flags.delay;\r
-               mutex_unlock(&sensor->operation_mutex);\r
-               break;\r
-       \r
-       case ECS_IOCTL_GET_PLATFORM_DATA:                       \r
-               DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__);\r
-               //memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout));\r
-               //memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name));\r
-               ret = copy_to_user(argp, &compass, sizeof(compass));\r
-               if(ret < 0)\r
-               {\r
-                       printk("%s:error,ret=%d\n",__FUNCTION__, ret);\r
-                       return ret;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_GET_LAYOUT:\r
-               DBG("%s:ECS_IOCTL_GET_LAYOUT start\n",__func__);\r
-               layout = sensor->pdata->layout;\r
-               break;\r
-       case ECS_IOCTL_GET_OUTBIT:\r
-               DBG("%s:ECS_IOCTL_GET_OUTBIT start\n",__func__);\r
-               outbit = 1; //sensor->pdata->outbit;\r
-               break;\r
-       case ECS_IOCTL_RESET:\r
-               DBG("%s:ECS_IOCTL_RESET start\n",__func__);\r
-               ret = compass_akm_reset(client);\r
-               if (ret < 0)\r
-                       return ret;\r
-               break;\r
-       case ECS_IOCTL_GET_ACCEL:\r
-               DBG("%s:ECS_IOCTL_GET_ACCEL start,no accel data\n",__func__);\r
-               mutex_lock(&sensor->operation_mutex);\r
-               acc_buf[0] = g_akm_rbuf[6];\r
-               acc_buf[1] = g_akm_rbuf[7];\r
-               acc_buf[2] = g_akm_rbuf[8];\r
-               mutex_unlock(&sensor->operation_mutex);\r
-               break;\r
-\r
-       default:\r
-               return -ENOTTY;\r
-       }\r
-\r
-       switch (cmd) {\r
-       case ECS_IOCTL_READ:\r
-               if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) {\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_GETDATA:\r
-               if (copy_to_user(argp, &compass_data, sizeof(compass_data))) {\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_GET_OPEN_STATUS:\r
-       case ECS_IOCTL_GET_CLOSE_STATUS:\r
-               if (copy_to_user(argp, &status, sizeof(status))) {\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_GET_DELAY:\r
-               if (copy_to_user(argp, &delay, sizeof(delay))) {\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_GET_LAYOUT:\r
-               if (copy_to_user(argp, &layout, sizeof(layout))) {\r
-                       printk("%s:error:%d\n",__FUNCTION__,__LINE__);\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_GET_OUTBIT:\r
-               if (copy_to_user(argp, &outbit, sizeof(outbit))) {\r
-                       printk("%s:error:%d\n",__FUNCTION__,__LINE__);\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
-       case ECS_IOCTL_GET_ACCEL:\r
-               if (copy_to_user(argp, &acc_buf, sizeof(acc_buf))) {\r
-                       printk("%s:error:%d\n",__FUNCTION__,__LINE__);\r
-                       return -EFAULT;\r
-               }\r
-               break;\r
+       case ECS_IOCTL_WRITE:
+               DBG("%s:ECS_IOCTL_WRITE start\n",__func__);
+               mutex_lock(&sensor->operation_mutex);
+               if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) {
+                       mutex_unlock(&sensor->operation_mutex);
+                       return -EINVAL;
+               }
+               ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]);
+               if (ret < 0) {
+                       mutex_unlock(&sensor->operation_mutex);
+                       printk("%s:fait to tx data\n",__func__);
+                       return ret;
+               }
+               mutex_unlock(&sensor->operation_mutex);
+               break;
+       case ECS_IOCTL_READ:
+               DBG("%s:ECS_IOCTL_READ start\n",__func__);
+               mutex_lock(&sensor->operation_mutex);
+               if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) {
+                       mutex_unlock(&sensor->operation_mutex);
+                       printk("%s:data is error\n",__func__);
+                       return -EINVAL;
+               }
+               ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]);
+               if (ret < 0) {
+                       mutex_unlock(&sensor->operation_mutex);
+                       printk("%s:fait to rx data\n",__func__);
+                       return ret;
+               }
+               mutex_unlock(&sensor->operation_mutex);
+               break;
+       case ECS_IOCTL_SET_MODE:
+               DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__);
+               mutex_lock(&sensor->operation_mutex);
+               if(sensor->ops->ctrl_data != mode)
+               {
+                       ret = compass_akm_set_mode(client, mode);
+                       if (ret < 0) {
+                               printk("%s:fait to set mode\n",__func__);
+                               mutex_unlock(&sensor->operation_mutex);
+                               return ret;
+                       }
+
+                       sensor->ops->ctrl_data = mode;
+               }
+               mutex_unlock(&sensor->operation_mutex);
+               break;
+       case ECS_IOCTL_GETDATA:
+                       DBG("%s:ECS_IOCTL_GETDATA start\n",__func__);
+                       mutex_lock(&sensor->data_mutex);
+                       memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE);    //get data from buffer
+                       mutex_unlock(&sensor->data_mutex);
+                       break;
+       case ECS_IOCTL_SET_YPR:
+                       DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__);
+                       mutex_lock(&sensor->data_mutex);
+                       compass_set_YPR(value);
+                       mutex_unlock(&sensor->data_mutex);
+               break;
+       case ECS_IOCTL_GET_OPEN_STATUS:
+               status = compass_akm_get_openstatus();
+               DBG("%s:openstatus=%d\n",__func__,status);
+               break;
+       case ECS_IOCTL_GET_CLOSE_STATUS:
+               status = compass_akm_get_closestatus();
+               DBG("%s:closestatus=%d\n",__func__,status);
+               break;
+       case ECS_IOCTL_GET_DELAY:
+               DBG("%s:ECS_IOCTL_GET_DELAY start\n",__func__);
+               mutex_lock(&sensor->operation_mutex);
+               delay[0] = sensor->flags.delay;
+               delay[1] = sensor->flags.delay;
+               delay[2] = sensor->flags.delay;
+               mutex_unlock(&sensor->operation_mutex);
+               break;
+
+       case ECS_IOCTL_GET_PLATFORM_DATA:
+               DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__);
+               //memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout));
+               //memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name));
+               ret = copy_to_user(argp, &compass, sizeof(compass));
+               if(ret < 0)
+               {
+                       printk("%s:error,ret=%d\n",__FUNCTION__, ret);
+                       return ret;
+               }
+               break;
+       case ECS_IOCTL_GET_LAYOUT:
+               DBG("%s:ECS_IOCTL_GET_LAYOUT start\n",__func__);
+               layout = sensor->pdata->layout;
+               break;
+       case ECS_IOCTL_GET_OUTBIT:
+               DBG("%s:ECS_IOCTL_GET_OUTBIT start\n",__func__);
+               outbit = 1; //sensor->pdata->outbit;
+               break;
+       case ECS_IOCTL_RESET:
+               DBG("%s:ECS_IOCTL_RESET start\n",__func__);
+               ret = compass_akm_reset(client);
+               if (ret < 0)
+                       return ret;
+               break;
+       case ECS_IOCTL_GET_ACCEL:
+               DBG("%s:ECS_IOCTL_GET_ACCEL start,no accel data\n",__func__);
+               mutex_lock(&sensor->operation_mutex);
+               acc_buf[0] = g_akm_rbuf[6];
+               acc_buf[1] = g_akm_rbuf[7];
+               acc_buf[2] = g_akm_rbuf[8];
+               mutex_unlock(&sensor->operation_mutex);
+               break;
+
+       default:
+               return -ENOTTY;
+       }
+
+       switch (cmd) {
+       case ECS_IOCTL_READ:
+               if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) {
+                       return -EFAULT;
+               }
+               break;
+       case ECS_IOCTL_GETDATA:
+               if (copy_to_user(argp, &compass_data, sizeof(compass_data))) {
+                       return -EFAULT;
+               }
+               break;
+       case ECS_IOCTL_GET_OPEN_STATUS:
+       case ECS_IOCTL_GET_CLOSE_STATUS:
+               if (copy_to_user(argp, &status, sizeof(status))) {
+                       return -EFAULT;
+               }
+               break;
+       case ECS_IOCTL_GET_DELAY:
+               if (copy_to_user(argp, &delay, sizeof(delay))) {
+                       return -EFAULT;
+               }
+               break;
+       case ECS_IOCTL_GET_LAYOUT:
+               if (copy_to_user(argp, &layout, sizeof(layout))) {
+                       printk("%s:error:%d\n",__FUNCTION__,__LINE__);
+                       return -EFAULT;
+               }
+               break;
+       case ECS_IOCTL_GET_OUTBIT:
+               if (copy_to_user(argp, &outbit, sizeof(outbit))) {
+                       printk("%s:error:%d\n",__FUNCTION__,__LINE__);
+                       return -EFAULT;
+               }
+               break;
+       case ECS_IOCTL_GET_ACCEL:
+               if (copy_to_user(argp, &acc_buf, sizeof(acc_buf))) {
+                       printk("%s:error:%d\n",__FUNCTION__,__LINE__);
+                       return -EFAULT;
+               }
+               break;
        case ECS_IOCTL_GET_INFO:
                if (copy_to_user(argp, &sense_info,     sizeof(sense_info))) {
                        printk("%s:error:%d\n", __FUNCTION__, __LINE__);
@@ -741,76 +741,76 @@ static long compass_dev_ioctl(struct file *file,
                        return -EFAULT;
                }
                break;
-       default:\r
-               break;\r
-       }\r
-\r
-       return result;\r
-}\r
-\r
-static struct file_operations compass_dev_fops =\r
-{\r
-       .owner = THIS_MODULE,\r
-       .open = compass_dev_open,\r
-       .release = compass_dev_release, \r
-       .unlocked_ioctl = compass_dev_ioctl,\r
-};\r
-\r
-\r
-static struct miscdevice compass_dev_device =\r
-{      \r
-       .minor = MISC_DYNAMIC_MINOR,\r
-       .name = "akm8963_dev",\r
-       .fops = &compass_dev_fops,\r
-};\r
-\r
-struct sensor_operate compass_akm8963_ops = {\r
-       .name                           = "akm8963",\r
-       .type                           = SENSOR_TYPE_COMPASS,  //it is important\r
-       .id_i2c                         = COMPASS_ID_AK8963,\r
-       .read_reg                       = AK8963_REG_ST1,       //read data\r
-       .read_len                       = SENSOR_DATA_SIZE,     //data length\r
-       .id_reg                         = AK8963_REG_WIA,       //read id\r
-       .id_data                        = AK8963_DEVICE_ID,\r
-       .precision                      = 8,                    //12 bits\r
-       .ctrl_reg                       = AK8963_REG_CNTL1,     //enable or disable \r
-       .int_status_reg                 = SENSOR_UNKNOW_DATA,   //not exist\r
-       .range                          = {-0xffff,0xffff},\r
-       .trig                           = IRQF_TRIGGER_RISING,  //if LEVEL interrupt then IRQF_ONESHOT\r
-       .active                         = sensor_active,        \r
-       .init                           = sensor_init,\r
-       .report                         = sensor_report_value,  \r
-       .misc_dev                       = NULL,                 //private misc support\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *compass_get_ops(void)\r
-{\r
-       return &compass_akm8963_ops; \r
-}\r
-\r
-\r
-static int __init compass_akm8963_init(void)\r
-{\r
-       struct sensor_operate *ops = compass_get_ops();\r
-       int result = 0;\r
-       int type = ops->type;\r
-       result = sensor_register_slave(type, NULL, NULL, compass_get_ops);\r
-                               \r
-       return result;\r
-}\r
-\r
-static void __exit compass_akm8963_exit(void)\r
-{\r
-       struct sensor_operate *ops = compass_get_ops();\r
-       int type = ops->type;\r
-       sensor_unregister_slave(type, NULL, NULL, compass_get_ops);\r
-}\r
-\r
-\r
-module_init(compass_akm8963_init);\r
-module_exit(compass_akm8963_exit);\r
-\r
-\r
+       default:
+               break;
+       }
+
+       return result;
+}
+
+static struct file_operations compass_dev_fops =
+{
+       .owner = THIS_MODULE,
+       .open = compass_dev_open,
+       .release = compass_dev_release,
+       .unlocked_ioctl = compass_dev_ioctl,
+};
+
+
+static struct miscdevice compass_dev_device =
+{
+       .minor = MISC_DYNAMIC_MINOR,
+       .name = "akm8963_dev",
+       .fops = &compass_dev_fops,
+};
+
+struct sensor_operate compass_akm8963_ops = {
+       .name                           = "akm8963",
+       .type                           = SENSOR_TYPE_COMPASS,  //it is important
+       .id_i2c                         = COMPASS_ID_AK8963,
+       .read_reg                       = AK8963_REG_ST1,       //read data
+       .read_len                       = SENSOR_DATA_SIZE,     //data length
+       .id_reg                         = AK8963_REG_WIA,       //read id
+       .id_data                        = AK8963_DEVICE_ID,
+       .precision                      = 8,                    //12 bits
+       .ctrl_reg                       = AK8963_REG_CNTL1,     //enable or disable
+       .int_status_reg                 = SENSOR_UNKNOW_DATA,   //not exist
+       .range                          = {-0xffff,0xffff},
+       .trig                           = IRQF_TRIGGER_RISING,  //if LEVEL interrupt then IRQF_ONESHOT
+       .active                         = sensor_active,
+       .init                           = sensor_init,
+       .report                         = sensor_report_value,
+       .misc_dev                       = NULL,                 //private misc support
+};
+
+/****************operate according to sensor chip:end************/
+
+//function name should not be changed
+static struct sensor_operate *compass_get_ops(void)
+{
+       return &compass_akm8963_ops;
+}
+
+
+static int __init compass_akm8963_init(void)
+{
+       struct sensor_operate *ops = compass_get_ops();
+       int result = 0;
+       int type = ops->type;
+       result = sensor_register_slave(type, NULL, NULL, compass_get_ops);
+
+       return result;
+}
+
+static void __exit compass_akm8963_exit(void)
+{
+       struct sensor_operate *ops = compass_get_ops();
+       int type = ops->type;
+       sensor_unregister_slave(type, NULL, NULL, compass_get_ops);
+}
+
+
+module_init(compass_akm8963_init);
+module_exit(compass_akm8963_exit);
+
+
index 62e3891..f609e17 100755 (executable)
-/* drivers/input/sensors/access/akm8975.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: luowei <lw@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-\r
-#include <linux/sensor-dev.h>\r
-\r
-#define SENSOR_DATA_SIZE               8\r
-\r
-\r
-/*! \name AK8975 operation mode\r
- \anchor AK8975_Mode\r
- Defines an operation mode of the AK8975.*/\r
-/*! @{*/\r
-#define AK8975_MODE_SNG_MEASURE        0x01\r
-#define        AK8975_MODE_SELF_TEST   0x08\r
-#define        AK8975_MODE_FUSE_ACCESS 0x0F\r
-#define        AK8975_MODE_POWERDOWN   0x00\r
-/*! @}*/\r
-\r
-#define SENSOR_DATA_SIZE               8       /* Rx buffer size, i.e from ST1 to ST2 */\r
-#define RWBUF_SIZE                     16      /* Read/Write buffer size.*/\r
-\r
-\r
-/*! \name AK8975 register address\r
-\anchor AK8975_REG\r
-Defines a register address of the AK8975.*/\r
-/*! @{*/\r
-#define AK8975_REG_WIA         0x00\r
-#define AK8975_REG_INFO                0x01\r
-#define AK8975_REG_ST1         0x02\r
-#define AK8975_REG_HXL         0x03\r
-#define AK8975_REG_HXH         0x04\r
-#define AK8975_REG_HYL         0x05\r
-#define AK8975_REG_HYH         0x06\r
-#define AK8975_REG_HZL         0x07\r
-#define AK8975_REG_HZH         0x08\r
-#define AK8975_REG_ST2         0x09\r
-#define AK8975_REG_CNTL                0x0A\r
-#define AK8975_REG_RSV         0x0B\r
-#define AK8975_REG_ASTC                0x0C\r
-#define AK8975_REG_TS1         0x0D\r
-#define AK8975_REG_TS2         0x0E\r
-#define AK8975_REG_I2CDIS      0x0F\r
-/*! @}*/\r
-\r
-/*! \name AK8975 fuse-rom address\r
-\anchor AK8975_FUSE\r
-Defines a read-only address of the fuse ROM of the AK8975.*/\r
-/*! @{*/\r
-#define AK8975_FUSE_ASAX       0x10\r
-#define AK8975_FUSE_ASAY       0x11\r
-#define AK8975_FUSE_ASAZ       0x12\r
-/*! @}*/\r
-\r
-#define AK8975_INFO_DATA       (0x01<<3)\r
-\r
-\r
-#define COMPASS_IOCTL_MAGIC                   'c'\r
-\r
-/* IOCTLs for AKM library */\r
-#define ECS_IOCTL_WRITE                 _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*)\r
-#define ECS_IOCTL_READ                  _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*)\r
-#define ECS_IOCTL_RESET                _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */\r
-#define ECS_IOCTL_SET_MODE              _IOW(COMPASS_IOCTL_MAGIC, 0x04, short)\r
-#define ECS_IOCTL_GETDATA               _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[SENSOR_DATA_SIZE])\r
-#define ECS_IOCTL_SET_YPR               _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12])\r
-#define ECS_IOCTL_GET_OPEN_STATUS       _IOR(COMPASS_IOCTL_MAGIC, 0x07, int)\r
-#define ECS_IOCTL_GET_CLOSE_STATUS      _IOR(COMPASS_IOCTL_MAGIC, 0x08, int)\r
-#define ECS_IOCTL_GET_LAYOUT           _IOR(COMPASS_IOCTL_MAGIC, 0x09, char)\r
-#define ECS_IOCTL_GET_ACCEL            _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3])\r
-#define ECS_IOCTL_GET_OUTBIT           _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char)\r
-#define ECS_IOCTL_GET_DELAY             _IOR(COMPASS_IOCTL_MAGIC, 0x30, short)\r
-#define ECS_IOCTL_GET_PROJECT_NAME      _IOR(COMPASS_IOCTL_MAGIC, 0x0D, char[64])\r
-#define ECS_IOCTL_GET_MATRIX            _IOR(COMPASS_IOCTL_MAGIC, 0x0E, short [4][3][3])\r
-#define ECS_IOCTL_GET_PLATFORM_DATA     _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data)\r
-\r
-\r
-#define AK8975_DEVICE_ID               0x48\r
-static struct i2c_client *this_client;\r
-static struct miscdevice compass_dev_device;\r
-\r
-\r
-\r
-\r
-/****************operate according to sensor chip:start************/\r
-\r
-static int sensor_active(struct i2c_client *client, int enable, int rate)\r
-{\r
-       struct sensor_private_data *sensor =\r
-           (struct sensor_private_data *) i2c_get_clientdata(client);  \r
-       int result = 0;\r
-               \r
-       //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
-       \r
-       //register setting according to chip datasheet          \r
-       if(enable)\r
-       {       \r
-               sensor->ops->ctrl_data = AK8975_MODE_SNG_MEASURE;       \r
-       }\r
-       else\r
-       {\r
-               sensor->ops->ctrl_data = AK8975_MODE_POWERDOWN;\r
-       }\r
-\r
-       DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
-       result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
-       if(result)\r
-               printk("%s:fail to active sensor\n",__func__);\r
-       \r
-       return result;\r
-\r
-}\r
-\r
-static int sensor_init(struct i2c_client *client)\r
-{      \r
-       struct sensor_private_data *sensor =\r
-           (struct sensor_private_data *) i2c_get_clientdata(client);  \r
-       int result = 0;\r
-       int info = 0;\r
-\r
-       this_client = client;   \r
-\r
-       result = sensor->ops->active(client,0,0);\r
-       if(result)\r
-       {\r
-               printk("%s:line=%d,error\n",__func__,__LINE__);\r
-               return result;\r
-       }\r
-       \r
-       sensor->status_cur = SENSOR_OFF;\r
-       \r
-       info = sensor_read_reg(client, AK8975_REG_INFO);\r
-       if((info & (0x0f<<3)) != AK8975_INFO_DATA)\r
-       \r
-       {\r
-               printk("%s:info=0x%x,it is not %s\n",__func__, info, sensor->ops->name);\r
-               return -1;\r
-       }\r
-\r
-       result = misc_register(&compass_dev_device);\r
-       if (result < 0) {\r
-               printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name);\r
-               result = -1;\r
-       }\r
-       \r
-       DBG("%s:status_cur=%d\n",__func__, sensor->status_cur);\r
-       return result;\r
-}\r
-\r
-static int sensor_report_value(struct i2c_client *client)\r
-{\r
-       struct sensor_private_data *sensor =\r
-               (struct sensor_private_data *) i2c_get_clientdata(client);      \r
-       char buffer[8] = {0};   \r
-       unsigned char *stat;\r
-       unsigned char *stat2;   \r
-       int ret = 0;    \r
-       char value = 0;\r
-       int i;\r
-\r
-       if(sensor->ops->read_len < 8)   //sensor->ops->read_len = 8\r
-       {\r
-               printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
-               return -1;\r
-       }\r
-       \r
-       memset(buffer, 0, 8);\r
-       \r
-       /* Data bytes from hardware xL, xH, yL, yH, zL, zH */   \r
-       do {\r
-               *buffer = sensor->ops->read_reg;\r
-               ret = sensor_rx_data(client, buffer, sensor->ops->read_len);\r
-               if (ret < 0)\r
-               return ret;\r
-       } while (0);\r
-\r
-       stat = &buffer[0];\r
-       stat2 = &buffer[7];\r
-       \r
-       /*\r
+/* drivers/input/sensors/access/akm8975.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: luowei <lw@rock-chips.com>
+ *
+ * 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/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#include <linux/sensor-dev.h>
+
+#define SENSOR_DATA_SIZE               8
+
+
+/*! \name AK8975 operation mode
+ \anchor AK8975_Mode
+ Defines an operation mode of the AK8975.*/
+/*! @{*/
+#define AK8975_MODE_SNG_MEASURE        0x01
+#define        AK8975_MODE_SELF_TEST   0x08
+#define        AK8975_MODE_FUSE_ACCESS 0x0F
+#define        AK8975_MODE_POWERDOWN   0x00
+/*! @}*/
+
+#define SENSOR_DATA_SIZE               8       /* Rx buffer size, i.e from ST1 to ST2 */
+#define RWBUF_SIZE                     16      /* Read/Write buffer size.*/
+
+
+/*! \name AK8975 register address
+\anchor AK8975_REG
+Defines a register address of the AK8975.*/
+/*! @{*/
+#define AK8975_REG_WIA         0x00
+#define AK8975_REG_INFO                0x01
+#define AK8975_REG_ST1         0x02
+#define AK8975_REG_HXL         0x03
+#define AK8975_REG_HXH         0x04
+#define AK8975_REG_HYL         0x05
+#define AK8975_REG_HYH         0x06
+#define AK8975_REG_HZL         0x07
+#define AK8975_REG_HZH         0x08
+#define AK8975_REG_ST2         0x09
+#define AK8975_REG_CNTL                0x0A
+#define AK8975_REG_RSV         0x0B
+#define AK8975_REG_ASTC                0x0C
+#define AK8975_REG_TS1         0x0D
+#define AK8975_REG_TS2         0x0E
+#define AK8975_REG_I2CDIS      0x0F
+/*! @}*/
+
+/*! \name AK8975 fuse-rom address
+\anchor AK8975_FUSE
+Defines a read-only address of the fuse ROM of the AK8975.*/
+/*! @{*/
+#define AK8975_FUSE_ASAX       0x10
+#define AK8975_FUSE_ASAY       0x11
+#define AK8975_FUSE_ASAZ       0x12
+/*! @}*/
+
+#define AK8975_INFO_DATA       (0x01<<3)
+
+
+#define COMPASS_IOCTL_MAGIC                   'c'
+
+/* IOCTLs for AKM library */
+#define ECS_IOCTL_WRITE                 _IOW(COMPASS_IOCTL_MAGIC, 0x01, char*)
+#define ECS_IOCTL_READ                  _IOWR(COMPASS_IOCTL_MAGIC, 0x02, char*)
+#define ECS_IOCTL_RESET                _IO(COMPASS_IOCTL_MAGIC, 0x03) /* NOT used in AK8975 */
+#define ECS_IOCTL_SET_MODE              _IOW(COMPASS_IOCTL_MAGIC, 0x04, short)
+#define ECS_IOCTL_GETDATA               _IOR(COMPASS_IOCTL_MAGIC, 0x05, char[SENSOR_DATA_SIZE])
+#define ECS_IOCTL_SET_YPR               _IOW(COMPASS_IOCTL_MAGIC, 0x06, short[12])
+#define ECS_IOCTL_GET_OPEN_STATUS       _IOR(COMPASS_IOCTL_MAGIC, 0x07, int)
+#define ECS_IOCTL_GET_CLOSE_STATUS      _IOR(COMPASS_IOCTL_MAGIC, 0x08, int)
+#define ECS_IOCTL_GET_LAYOUT           _IOR(COMPASS_IOCTL_MAGIC, 0x09, char)
+#define ECS_IOCTL_GET_ACCEL            _IOR(COMPASS_IOCTL_MAGIC, 0x0A, short[3])
+#define ECS_IOCTL_GET_OUTBIT           _IOR(COMPASS_IOCTL_MAGIC, 0x0B, char)
+#define ECS_IOCTL_GET_DELAY             _IOR(COMPASS_IOCTL_MAGIC, 0x30, short)
+#define ECS_IOCTL_GET_PROJECT_NAME      _IOR(COMPASS_IOCTL_MAGIC, 0x0D, char[64])
+#define ECS_IOCTL_GET_MATRIX            _IOR(COMPASS_IOCTL_MAGIC, 0x0E, short [4][3][3])
+#define ECS_IOCTL_GET_PLATFORM_DATA     _IOR(COMPASS_IOCTL_MAGIC, 0x0E, struct akm_platform_data)
+
+
+#define AK8975_DEVICE_ID               0x48
+static struct i2c_client *this_client;
+static struct miscdevice compass_dev_device;
+
+
+
+
+/****************operate according to sensor chip:start************/
+
+static int sensor_active(struct i2c_client *client, int enable, int rate)
+{
+       struct sensor_private_data *sensor =
+           (struct sensor_private_data *) i2c_get_clientdata(client);
+       int result = 0;
+
+       //sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
+
+       //register setting according to chip datasheet
+       if(enable)
+       {
+               sensor->ops->ctrl_data = AK8975_MODE_SNG_MEASURE;
+       }
+       else
+       {
+               sensor->ops->ctrl_data = AK8975_MODE_POWERDOWN;
+       }
+
+       DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
+       result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+       if(result)
+               printk("%s:fail to active sensor\n",__func__);
+
+       return result;
+
+}
+
+static int sensor_init(struct i2c_client *client)
+{
+       struct sensor_private_data *sensor =
+           (struct sensor_private_data *) i2c_get_clientdata(client);
+       int result = 0;
+       int info = 0;
+
+       this_client = client;
+
+       result = sensor->ops->active(client,0,0);
+       if(result)
+       {
+               printk("%s:line=%d,error\n",__func__,__LINE__);
+               return result;
+       }
+
+       sensor->status_cur = SENSOR_OFF;
+
+       info = sensor_read_reg(client, AK8975_REG_INFO);
+       if((info & (0x0f<<3)) != AK8975_INFO_DATA)
+
+       {
+               printk("%s:info=0x%x,it is not %s\n",__func__, info, sensor->ops->name);
+               return -1;
+       }
+
+       result = misc_register(&compass_dev_device);
+       if (result < 0) {
+               printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name);
+               result = -1;
+       }
+
+       DBG("%s:status_cur=%d\n",__func__, sensor->status_cur);
+       return result;
+}
+
+static int sensor_report_value(struct i2c_client *client)
+{
+       struct sensor_private_data *sensor =
+               (struct sensor_private_data *) i2c_get_clientdata(client);
+       char buffer[8] = {0};
+       unsigned char *stat;
+       unsigned char *stat2;
+       int ret = 0;
+       char value = 0;
+       int i;
+
+       if(sensor->ops->read_len < 8)   //sensor->ops->read_len = 8
+       {
+               printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
+               return -1;
+       }
+
+       memset(buffer, 0, 8);
+
+       /* Data bytes from hardware xL, xH, yL, yH, zL, zH */
+       do {
+               *buffer = sensor->ops->read_reg;
+               ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
+               if (ret < 0)
+               return ret;
+       } while (0);
+
+       stat = &buffer[0];
+       stat2 = &buffer[7];
+
+       /*
         * ST : data ready -
         * Measurement has been completed and data is ready to be read.
-        */\r
-       if ((*stat & 0x01) != 0x01) {\r
-               DBG(KERN_ERR "%s:ST is not set\n",__func__);\r
-               return -1;\r
-       }\r
+        */
+       if ((*stat & 0x01) != 0x01) {
+               DBG(KERN_ERR "%s:ST is not set\n",__func__);
+               return -1;
+       }
 
        /*
         * ST2 : data error -
@@ -224,12 +224,12 @@ static int sensor_report_value(struct i2c_client *client)
         * corrupted.
         * DERR bit is self-clearing when ST2 register is read.
         */
-       if (*stat2 & 0x04)\r
-       {\r
-               DBG(KERN_ERR "%s:compass data error\n",__func__);\r
-               return -2;\r
-       }\r
-       \r
+       if (*stat2 & 0x04)
+       {
+               DBG(KERN_ERR "%s:compass data error\n",__func__);
+               return -2;
+       }
+
        /*
         * ST2 : overflow -
         * the sum of the absolute values of all axis |X|+|Y|+|Z| < 2400uT.
@@ -239,416 +239,416 @@ static int sensor_report_value(struct i2c_client *client)
         * An error is returned.
         * HOFL bit clears when a new measurement starts.
         */
-       if (*stat2 & 0x08)\r
-       {       \r
-               DBG(KERN_ERR "%s:compass data overflow\n",__func__);\r
-               return -3;\r
-       }\r
-       \r
-       /* »¥³âµØ»º´æÊý¾Ý. */\r
-       mutex_lock(&sensor->data_mutex);        \r
-       memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);\r
-       mutex_unlock(&sensor->data_mutex);\r
-       DBG("%s:",__func__);\r
-       for(i=0; i<sensor->ops->read_len; i++)\r
-               DBG("0x%x,",buffer[i]);\r
-       DBG("\n");\r
-\r
-       if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0))    //read sensor intterupt status register\r
-       {\r
-               \r
-               value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
-               DBG("%s:sensor int status :0x%x\n",__func__,value);\r
-       }\r
-\r
-       \r
-       //trigger next measurement \r
-       ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
-       if(ret)\r
-       {\r
-               printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data);\r
-               return ret;\r
-       }\r
-\r
-       return ret;\r
-}\r
-\r
-static void compass_set_YPR(short *rbuf)\r
-{\r
-       struct sensor_private_data *sensor =\r
-           (struct sensor_private_data *) i2c_get_clientdata(this_client);     \r
-       \r
-       /* Report magnetic sensor information */\r
-       if (atomic_read(&sensor->flags.m_flag)) {\r
-               input_report_abs(sensor->input_dev, ABS_RX, rbuf[0]);\r
-               input_report_abs(sensor->input_dev, ABS_RY, rbuf[1]);\r
-               input_report_abs(sensor->input_dev, ABS_RZ, rbuf[2]);\r
-               input_report_abs(sensor->input_dev, ABS_RUDDER, rbuf[4]);\r
-               DBG("%s:m_flag:x=%d,y=%d,z=%d,RUDDER=%d\n",__func__,rbuf[0], rbuf[1], rbuf[2], rbuf[4]);\r
-       }\r
-       \r
-       /* Report acceleration sensor information */\r
-       if (atomic_read(&sensor->flags.a_flag)) {\r
-               input_report_abs(sensor->input_dev, ABS_X, rbuf[6]);\r
-               input_report_abs(sensor->input_dev, ABS_Y, rbuf[7]);\r
-               input_report_abs(sensor->input_dev, ABS_Z, rbuf[8]);\r
-               input_report_abs(sensor->input_dev, ABS_WHEEL, rbuf[5]);\r
-               \r
-               DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[6], rbuf[7], rbuf[8], rbuf[5]);\r
-       }\r
-       \r
-       /* Report magnetic vector information */\r
-       if (atomic_read(&sensor->flags.mv_flag)) {\r
-               input_report_abs(sensor->input_dev, ABS_HAT0X, rbuf[9]);\r
-               input_report_abs(sensor->input_dev, ABS_HAT0Y, rbuf[10]);\r
-               input_report_abs(sensor->input_dev, ABS_BRAKE, rbuf[11]);\r
-       \r
-               DBG("%s:mv_flag:x=%d,y=%d,BRAKE=%d\n",__func__,rbuf[9], rbuf[10], rbuf[11]);\r
-       }\r
-       \r
-       input_sync(sensor->input_dev);\r
-}\r
-\r
-\r
-static int compass_dev_open(struct inode *inode, struct file *file)\r
-{\r
-       int result = 0;\r
-       DBG("%s\n",__func__);\r
-\r
-       return result;\r
-}\r
-\r
-\r
-static int compass_dev_release(struct inode *inode, struct file *file)\r
-{\r
-       int result = 0; \r
-       DBG("%s\n",__func__);\r
-\r
-       return result;\r
-}\r
-\r
-static int compass_akm_set_mode(struct i2c_client *client, char mode)\r
-{\r
-       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
-       int result = 0; \r
-\r
-       switch(mode)\r
-       {\r
-               case AK8975_MODE_SNG_MEASURE:\r
-               case AK8975_MODE_SELF_TEST:     \r
-               case AK8975_MODE_FUSE_ACCESS:                   \r
-                       if(sensor->status_cur == SENSOR_OFF)\r
-                       {\r
-                               if(sensor->pdata->irq_enable)\r
-                               {\r
-                                       //DBG("%s:enable irq=%d\n",__func__,client->irq);\r
-                                       //enable_irq(client->irq);\r
-                               }       \r
-                               else\r
-                               {\r
-                                       schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));\r
-                               }\r
-                               \r
-                               sensor->status_cur = SENSOR_ON;\r
-                       }\r
-\r
-                       break;\r
-\r
-               case AK8975_MODE_POWERDOWN:     \r
-                       if(sensor->status_cur == SENSOR_ON)\r
-                       {\r
-                               if(sensor->pdata->irq_enable)\r
-                               {       \r
-                                       //DBG("%s:disable irq=%d\n",__func__,client->irq);\r
-                                       //disable_irq_nosync(client->irq);//disable irq\r
-                               }\r
-                               else\r
-                               cancel_delayed_work_sync(&sensor->delaywork);   \r
-\r
-                               sensor->status_cur = SENSOR_OFF;\r
-                       }\r
-                       break;\r
-\r
-       }\r
-       \r
-       switch(mode)\r
-       {\r
-               case AK8975_MODE_SNG_MEASURE:           \r
-                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_SNG_MEASURE);\r
-                       if(result)\r
-                       printk("%s:i2c error,mode=%d\n",__func__,mode);                         \r
-                       break;\r
-               case AK8975_MODE_SELF_TEST:                     \r
-                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_SELF_TEST);\r
-                       if(result)\r
-                       printk("%s:i2c error,mode=%d\n",__func__,mode);\r
-                       break;\r
-               case AK8975_MODE_FUSE_ACCESS:\r
-                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_FUSE_ACCESS);\r
-                       if(result)\r
-                       printk("%s:i2c error,mode=%d\n",__func__,mode);\r
-                       break;\r
-               case AK8975_MODE_POWERDOWN:\r
-                       /* Set powerdown mode */\r
-                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_POWERDOWN);\r
-                       if(result)\r
-                       printk("%s:i2c error,mode=%d\n",__func__,mode);\r
-                       udelay(100);\r
-                       break;\r
-               default:\r
-                       printk("%s: Unknown mode(%d)", __func__, mode);\r
-                       result = -EINVAL;\r
-                       break;\r
-       }\r
-       DBG("%s:mode=%d\n",__func__,mode);\r
-       return result;\r
-\r
-}\r
-\r
-\r
-static int compass_akm_get_openstatus(void)\r
-{\r
-       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
-       wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0));\r
-       return atomic_read(&sensor->flags.open_flag);\r
-}\r
-\r
-static int compass_akm_get_closestatus(void)\r
-{\r
-       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
-       wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0));\r
-       return atomic_read(&sensor->flags.open_flag);\r
-}\r
-\r
-\r
-/* ioctl - I/O control */\r
-static long compass_dev_ioctl(struct file *file,\r
-                         unsigned int cmd, unsigned long arg)\r
-{\r
-       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);\r
-       struct i2c_client *client = this_client;\r
-       void __user *argp = (void __user *)arg;\r
-       int result = 0;\r
-       struct akm_platform_data compass;\r
-               \r
-       /* NOTE: In this function the size of "char" should be 1-byte. */\r
-       char compass_data[SENSOR_DATA_SIZE];/* for GETDATA */\r
-       char rwbuf[RWBUF_SIZE];         /* for READ/WRITE */\r
-       char mode;                                      /* for SET_MODE*/\r
-       short value[12];                        /* for SET_YPR */\r
-       short delay;                            /* for GET_DELAY */\r
-       int status;                                     /* for OPEN/CLOSE_STATUS */\r
-       int ret = -1;                           /* Return value. */\r
-       \r
-       switch (cmd) {\r
-               case ECS_IOCTL_WRITE:\r
-               case ECS_IOCTL_READ:\r
-                       if (argp == NULL) {\r
-                               return -EINVAL;\r
-                       }\r
-                       if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) {\r
-                               return -EFAULT;\r
-                       }\r
-                       break;\r
-               case ECS_IOCTL_SET_MODE:\r
-                       if (argp == NULL) {\r
-                               return -EINVAL;\r
-                       }\r
-                       if (copy_from_user(&mode, argp, sizeof(mode))) {\r
-                               return -EFAULT;\r
-                       }\r
-                       break;\r
-               case ECS_IOCTL_SET_YPR:\r
-                       if (argp == NULL) {\r
-                               return -EINVAL;\r
-                       }\r
-                       if (copy_from_user(&value, argp, sizeof(value))) {\r
-                               return -EFAULT;\r
-                       }\r
-                       break;\r
-               default:\r
-                       break;\r
-       }\r
-       \r
-       switch (cmd) {\r
-               case ECS_IOCTL_WRITE:\r
-                       DBG("%s:ECS_IOCTL_WRITE start\n",__func__);\r
-                       mutex_lock(&sensor->operation_mutex);\r
-                       if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) {                    \r
-                               mutex_unlock(&sensor->operation_mutex);\r
-                               return -EINVAL;\r
-                       }\r
-                       ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]);\r
-                       if (ret < 0) {  \r
-                               mutex_unlock(&sensor->operation_mutex);         \r
-                               printk("%s:fait to tx data\n",__func__);\r
-                               return ret;\r
-                       }                       \r
-                       mutex_unlock(&sensor->operation_mutex);\r
-                       break;\r
-               case ECS_IOCTL_READ:                            \r
-                       DBG("%s:ECS_IOCTL_READ start\n",__func__);\r
-                       mutex_lock(&sensor->operation_mutex);\r
-                       if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) {            \r
-                               mutex_unlock(&sensor->operation_mutex);                 \r
-                               printk("%s:data is error\n",__func__);\r
-                               return -EINVAL;\r
-                       }\r
-                       ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]);\r
-                       if (ret < 0) {  \r
-                               mutex_unlock(&sensor->operation_mutex);         \r
-                               printk("%s:fait to rx data\n",__func__);\r
-                               return ret;\r
-                       }               \r
-                       mutex_unlock(&sensor->operation_mutex);\r
-                       break;\r
-               case ECS_IOCTL_SET_MODE:                \r
-                       DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__);          \r
-                       mutex_lock(&sensor->operation_mutex);\r
-                       if(sensor->ops->ctrl_data != mode)\r
-                       {\r
-                               ret = compass_akm_set_mode(client, mode);\r
-                               if (ret < 0) {\r
-                                       printk("%s:fait to set mode\n",__func__);               \r
-                                       mutex_unlock(&sensor->operation_mutex);\r
-                                       return ret;\r
-                               }\r
-                               \r
-                               sensor->ops->ctrl_data = mode;\r
-                       }\r
-                       mutex_unlock(&sensor->operation_mutex);\r
-                       break;\r
-               case ECS_IOCTL_GETDATA:         \r
-                       DBG("%s:ECS_IOCTL_GETDATA start\n",__func__);\r
-                       mutex_lock(&sensor->data_mutex);        \r
-                       memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE);    //get data from buffer\r
-                       mutex_unlock(&sensor->data_mutex);\r
-                       break;\r
-               case ECS_IOCTL_SET_YPR:                 \r
-                       DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__);\r
-                       mutex_lock(&sensor->data_mutex);\r
-                       compass_set_YPR(value);         \r
-                       mutex_unlock(&sensor->data_mutex);\r
-                       break;\r
-               case ECS_IOCTL_GET_OPEN_STATUS:\r
-                       status = compass_akm_get_openstatus();  \r
-                       DBG("%s:openstatus=%d\n",__func__,status);\r
-                       break;\r
+       if (*stat2 & 0x08)
+       {
+               DBG(KERN_ERR "%s:compass data overflow\n",__func__);
+               return -3;
+       }
+
+       /* »¥³âµØ»º´æÊý¾Ý. */
+       mutex_lock(&sensor->data_mutex);
+       memcpy(sensor->sensor_data, buffer, sensor->ops->read_len);
+       mutex_unlock(&sensor->data_mutex);
+       DBG("%s:",__func__);
+       for(i=0; i<sensor->ops->read_len; i++)
+               DBG("0x%x,",buffer[i]);
+       DBG("\n");
+
+       if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0))    //read sensor intterupt status register
+       {
+
+               value = sensor_read_reg(client, sensor->ops->int_status_reg);
+               DBG("%s:sensor int status :0x%x\n",__func__,value);
+       }
+
+
+       //trigger next measurement
+       ret = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+       if(ret)
+       {
+               printk(KERN_ERR "%s:fail to set ctrl_data:0x%x\n",__func__,sensor->ops->ctrl_data);
+               return ret;
+       }
+
+       return ret;
+}
+
+static void compass_set_YPR(short *rbuf)
+{
+       struct sensor_private_data *sensor =
+           (struct sensor_private_data *) i2c_get_clientdata(this_client);
+
+       /* Report magnetic sensor information */
+       if (atomic_read(&sensor->flags.m_flag)) {
+               input_report_abs(sensor->input_dev, ABS_RX, rbuf[0]);
+               input_report_abs(sensor->input_dev, ABS_RY, rbuf[1]);
+               input_report_abs(sensor->input_dev, ABS_RZ, rbuf[2]);
+               input_report_abs(sensor->input_dev, ABS_RUDDER, rbuf[4]);
+               DBG("%s:m_flag:x=%d,y=%d,z=%d,RUDDER=%d\n",__func__,rbuf[0], rbuf[1], rbuf[2], rbuf[4]);
+       }
+
+       /* Report acceleration sensor information */
+       if (atomic_read(&sensor->flags.a_flag)) {
+               input_report_abs(sensor->input_dev, ABS_X, rbuf[6]);
+               input_report_abs(sensor->input_dev, ABS_Y, rbuf[7]);
+               input_report_abs(sensor->input_dev, ABS_Z, rbuf[8]);
+               input_report_abs(sensor->input_dev, ABS_WHEEL, rbuf[5]);
+
+               DBG("%s:a_flag:x=%d,y=%d,z=%d,WHEEL=%d\n",__func__,rbuf[6], rbuf[7], rbuf[8], rbuf[5]);
+       }
+
+       /* Report magnetic vector information */
+       if (atomic_read(&sensor->flags.mv_flag)) {
+               input_report_abs(sensor->input_dev, ABS_HAT0X, rbuf[9]);
+               input_report_abs(sensor->input_dev, ABS_HAT0Y, rbuf[10]);
+               input_report_abs(sensor->input_dev, ABS_BRAKE, rbuf[11]);
+
+               DBG("%s:mv_flag:x=%d,y=%d,BRAKE=%d\n",__func__,rbuf[9], rbuf[10], rbuf[11]);
+       }
+
+       input_sync(sensor->input_dev);
+}
+
+
+static int compass_dev_open(struct inode *inode, struct file *file)
+{
+       int result = 0;
+       DBG("%s\n",__func__);
+
+       return result;
+}
+
+
+static int compass_dev_release(struct inode *inode, struct file *file)
+{
+       int result = 0;
+       DBG("%s\n",__func__);
+
+       return result;
+}
+
+static int compass_akm_set_mode(struct i2c_client *client, char mode)
+{
+       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
+       int result = 0;
+
+       switch(mode)
+       {
+               case AK8975_MODE_SNG_MEASURE:
+               case AK8975_MODE_SELF_TEST:
+               case AK8975_MODE_FUSE_ACCESS:
+                       if(sensor->status_cur == SENSOR_OFF)
+                       {
+                               if(sensor->pdata->irq_enable)
+                               {
+                                       //DBG("%s:enable irq=%d\n",__func__,client->irq);
+                                       //enable_irq(client->irq);
+                               }
+                               else
+                               {
+                                       schedule_delayed_work(&sensor->delaywork, msecs_to_jiffies(sensor->pdata->poll_delay_ms));
+                               }
+
+                               sensor->status_cur = SENSOR_ON;
+                       }
+
+                       break;
+
+               case AK8975_MODE_POWERDOWN:
+                       if(sensor->status_cur == SENSOR_ON)
+                       {
+                               if(sensor->pdata->irq_enable)
+                               {
+                                       //DBG("%s:disable irq=%d\n",__func__,client->irq);
+                                       //disable_irq_nosync(client->irq);//disable irq
+                               }
+                               else
+                               cancel_delayed_work_sync(&sensor->delaywork);
+
+                               sensor->status_cur = SENSOR_OFF;
+                       }
+                       break;
+
+       }
+
+       switch(mode)
+       {
+               case AK8975_MODE_SNG_MEASURE:
+                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_SNG_MEASURE);
+                       if(result)
+                       printk("%s:i2c error,mode=%d\n",__func__,mode);
+                       break;
+               case AK8975_MODE_SELF_TEST:
+                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_SELF_TEST);
+                       if(result)
+                       printk("%s:i2c error,mode=%d\n",__func__,mode);
+                       break;
+               case AK8975_MODE_FUSE_ACCESS:
+                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_FUSE_ACCESS);
+                       if(result)
+                       printk("%s:i2c error,mode=%d\n",__func__,mode);
+                       break;
+               case AK8975_MODE_POWERDOWN:
+                       /* Set powerdown mode */
+                       result = sensor_write_reg(client, sensor->ops->ctrl_reg, AK8975_MODE_POWERDOWN);
+                       if(result)
+                       printk("%s:i2c error,mode=%d\n",__func__,mode);
+                       udelay(100);
+                       break;
+               default:
+                       printk("%s: Unknown mode(%d)", __func__, mode);
+                       result = -EINVAL;
+                       break;
+       }
+       DBG("%s:mode=%d\n",__func__,mode);
+       return result;
+
+}
+
+
+static int compass_akm_get_openstatus(void)
+{
+       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
+       wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) != 0));
+       return atomic_read(&sensor->flags.open_flag);
+}
+
+static int compass_akm_get_closestatus(void)
+{
+       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
+       wait_event_interruptible(sensor->flags.open_wq, (atomic_read(&sensor->flags.open_flag) <= 0));
+       return atomic_read(&sensor->flags.open_flag);
+}
+
+
+/* ioctl - I/O control */
+static long compass_dev_ioctl(struct file *file,
+                         unsigned int cmd, unsigned long arg)
+{
+       struct sensor_private_data* sensor = (struct sensor_private_data *)i2c_get_clientdata(this_client);
+       struct i2c_client *client = this_client;
+       void __user *argp = (void __user *)arg;
+       int result = 0;
+       struct akm_platform_data compass;
+
+       /* NOTE: In this function the size of "char" should be 1-byte. */
+       char compass_data[SENSOR_DATA_SIZE];/* for GETDATA */
+       char rwbuf[RWBUF_SIZE];         /* for READ/WRITE */
+       char mode;                                      /* for SET_MODE*/
+       short value[12];                        /* for SET_YPR */
+       short delay;                            /* for GET_DELAY */
+       int status;                                     /* for OPEN/CLOSE_STATUS */
+       int ret = -1;                           /* Return value. */
+
+       switch (cmd) {
+               case ECS_IOCTL_WRITE:
+               case ECS_IOCTL_READ:
+                       if (argp == NULL) {
+                               return -EINVAL;
+                       }
+                       if (copy_from_user(&rwbuf, argp, sizeof(rwbuf))) {
+                               return -EFAULT;
+                       }
+                       break;
+               case ECS_IOCTL_SET_MODE:
+                       if (argp == NULL) {
+                               return -EINVAL;
+                       }
+                       if (copy_from_user(&mode, argp, sizeof(mode))) {
+                               return -EFAULT;
+                       }
+                       break;
+               case ECS_IOCTL_SET_YPR:
+                       if (argp == NULL) {
+                               return -EINVAL;
+                       }
+                       if (copy_from_user(&value, argp, sizeof(value))) {
+                               return -EFAULT;
+                       }
+                       break;
+               default:
+                       break;
+       }
+
+       switch (cmd) {
+               case ECS_IOCTL_WRITE:
+                       DBG("%s:ECS_IOCTL_WRITE start\n",__func__);
+                       mutex_lock(&sensor->operation_mutex);
+                       if ((rwbuf[0] < 2) || (rwbuf[0] > (RWBUF_SIZE-1))) {
+                               mutex_unlock(&sensor->operation_mutex);
+                               return -EINVAL;
+                       }
+                       ret = sensor_tx_data(client, &rwbuf[1], rwbuf[0]);
+                       if (ret < 0) {
+                               mutex_unlock(&sensor->operation_mutex);
+                               printk("%s:fait to tx data\n",__func__);
+                               return ret;
+                       }
+                       mutex_unlock(&sensor->operation_mutex);
+                       break;
+               case ECS_IOCTL_READ:
+                       DBG("%s:ECS_IOCTL_READ start\n",__func__);
+                       mutex_lock(&sensor->operation_mutex);
+                       if ((rwbuf[0] < 1) || (rwbuf[0] > (RWBUF_SIZE-1))) {
+                               mutex_unlock(&sensor->operation_mutex);
+                               printk("%s:data is error\n",__func__);
+                               return -EINVAL;
+                       }
+                       ret = sensor_rx_data(client, &rwbuf[1], rwbuf[0]);
+                       if (ret < 0) {
+                               mutex_unlock(&sensor->operation_mutex);
+                               printk("%s:fait to rx data\n",__func__);
+                               return ret;
+                       }
+                       mutex_unlock(&sensor->operation_mutex);
+                       break;
+               case ECS_IOCTL_SET_MODE:
+                       DBG("%s:ECS_IOCTL_SET_MODE start\n",__func__);
+                       mutex_lock(&sensor->operation_mutex);
+                       if(sensor->ops->ctrl_data != mode)
+                       {
+                               ret = compass_akm_set_mode(client, mode);
+                               if (ret < 0) {
+                                       printk("%s:fait to set mode\n",__func__);
+                                       mutex_unlock(&sensor->operation_mutex);
+                                       return ret;
+                               }
+
+                               sensor->ops->ctrl_data = mode;
+                       }
+                       mutex_unlock(&sensor->operation_mutex);
+                       break;
+               case ECS_IOCTL_GETDATA:
+                       DBG("%s:ECS_IOCTL_GETDATA start\n",__func__);
+                       mutex_lock(&sensor->data_mutex);
+                       memcpy(compass_data, sensor->sensor_data, SENSOR_DATA_SIZE);    //get data from buffer
+                       mutex_unlock(&sensor->data_mutex);
+                       break;
+               case ECS_IOCTL_SET_YPR:
+                       DBG("%s:ECS_IOCTL_SET_YPR start\n",__func__);
+                       mutex_lock(&sensor->data_mutex);
+                       compass_set_YPR(value);
+                       mutex_unlock(&sensor->data_mutex);
+                       break;
+               case ECS_IOCTL_GET_OPEN_STATUS:
+                       status = compass_akm_get_openstatus();
+                       DBG("%s:openstatus=%d\n",__func__,status);
+                       break;
                case ECS_IOCTL_GET_CLOSE_STATUS:
-                       status = compass_akm_get_closestatus(); \r
-                       DBG("%s:closestatus=%d\n",__func__,status);\r
-                       break;\r
-               case ECS_IOCTL_GET_DELAY:\r
-                       delay = sensor->flags.delay;\r
-                       break;\r
-               case ECS_IOCTL_GET_PLATFORM_DATA:                       \r
-                       DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__);\r
-                       //memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout));\r
-                       //memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name));\r
-                       ret = copy_to_user(argp, &compass, sizeof(compass));\r
-                       if(ret < 0)\r
-                       {\r
-                               printk("%s:error,ret=%d\n",__FUNCTION__, ret);\r
-                               return ret;\r
-                       }\r
-                       break;\r
-                       \r
-               default:\r
-                       return -ENOTTY;\r
-       }\r
-       \r
-       switch (cmd) {\r
-               case ECS_IOCTL_READ:\r
-                       if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) {\r
-                               return -EFAULT;\r
-                       }\r
-                       break;\r
-               case ECS_IOCTL_GETDATA:\r
-                       if (copy_to_user(argp, &compass_data, sizeof(compass_data))) {\r
-                               return -EFAULT;\r
-                       }\r
-                       break;\r
-               case ECS_IOCTL_GET_OPEN_STATUS:\r
-               case ECS_IOCTL_GET_CLOSE_STATUS:\r
-                       if (copy_to_user(argp, &status, sizeof(status))) {\r
-                               return -EFAULT;\r
-                       }\r
-                       break;\r
-               case ECS_IOCTL_GET_DELAY:\r
-                       if (copy_to_user(argp, &delay, sizeof(delay))) {\r
-                               return -EFAULT;\r
-                       }\r
-                       break;\r
-               default:\r
-                       break;\r
-       }\r
-\r
-       return result;\r
-}\r
-\r
-static struct file_operations compass_dev_fops =\r
-{\r
-       .owner = THIS_MODULE,\r
-       .open = compass_dev_open,\r
-       .release = compass_dev_release, \r
-       .unlocked_ioctl = compass_dev_ioctl,\r
-};\r
-\r
-\r
-static struct miscdevice compass_dev_device =\r
-{      \r
-       .minor = MISC_DYNAMIC_MINOR,\r
-       .name = "akm8975_dev",\r
-       .fops = &compass_dev_fops,\r
-};\r
-\r
-struct sensor_operate compass_akm8975_ops = {\r
-       .name                           = "akm8975",\r
-       .type                           = SENSOR_TYPE_COMPASS,  //it is important\r
-       .id_i2c                         = COMPASS_ID_AK8975,\r
-       .read_reg                       = AK8975_REG_ST1,       //read data\r
-       .read_len                       = SENSOR_DATA_SIZE,     //data length\r
-       .id_reg                         = AK8975_REG_WIA,       //read id\r
-       .id_data                        = AK8975_DEVICE_ID,\r
-       .precision                      = 8,                    //12 bits\r
-       .ctrl_reg                       = AK8975_REG_CNTL,      //enable or disable \r
-       .int_status_reg                 = SENSOR_UNKNOW_DATA,   //not exist\r
-       .range                          = {-0xffff,0xffff},\r
-       .trig                           = IRQF_TRIGGER_RISING,  //if LEVEL interrupt then IRQF_ONESHOT\r
-       .active                         = sensor_active,        \r
-       .init                           = sensor_init,\r
-       .report                         = sensor_report_value,  \r
-       .misc_dev                       = NULL,                 //private misc support\r
-};\r
-\r
-/****************operate according to sensor chip:end************/\r
-\r
-//function name should not be changed\r
-static struct sensor_operate *compass_get_ops(void)\r
-{\r
-       return &compass_akm8975_ops; \r
-}\r
-\r
-\r
-static int __init compass_akm8975_init(void)\r
-{\r
-       struct sensor_operate *ops = compass_get_ops();\r
-       int result = 0;\r
-       int type = ops->type;\r
-       result = sensor_register_slave(type, NULL, NULL, compass_get_ops);\r
-                               \r
-       return result;\r
-}\r
-\r
-static void __exit compass_akm8975_exit(void)\r
-{\r
-       struct sensor_operate *ops = compass_get_ops();\r
-       int type = ops->type;\r
-       sensor_unregister_slave(type, NULL, NULL, compass_get_ops);\r
-}\r
-\r
-\r
-module_init(compass_akm8975_init);\r
-module_exit(compass_akm8975_exit);\r
-\r
-\r
+                       status = compass_akm_get_closestatus();
+                       DBG("%s:closestatus=%d\n",__func__,status);
+                       break;
+               case ECS_IOCTL_GET_DELAY:
+                       delay = sensor->flags.delay;
+                       break;
+               case ECS_IOCTL_GET_PLATFORM_DATA:
+                       DBG("%s:ECS_IOCTL_GET_PLATFORM_DATA start\n",__func__);
+                       //memcpy(compass.m_layout, sensor->pdata->m_layout, sizeof(sensor->pdata->m_layout));
+                       //memcpy(compass.project_name, sensor->pdata->project_name, sizeof(sensor->pdata->project_name));
+                       ret = copy_to_user(argp, &compass, sizeof(compass));
+                       if(ret < 0)
+                       {
+                               printk("%s:error,ret=%d\n",__FUNCTION__, ret);
+                               return ret;
+                       }
+                       break;
+
+               default:
+                       return -ENOTTY;
+       }
+
+       switch (cmd) {
+               case ECS_IOCTL_READ:
+                       if (copy_to_user(argp, &rwbuf, rwbuf[0]+1)) {
+                               return -EFAULT;
+                       }
+                       break;
+               case ECS_IOCTL_GETDATA:
+                       if (copy_to_user(argp, &compass_data, sizeof(compass_data))) {
+                               return -EFAULT;
+                       }
+                       break;
+               case ECS_IOCTL_GET_OPEN_STATUS:
+               case ECS_IOCTL_GET_CLOSE_STATUS:
+                       if (copy_to_user(argp, &status, sizeof(status))) {
+                               return -EFAULT;
+                       }
+                       break;
+               case ECS_IOCTL_GET_DELAY:
+                       if (copy_to_user(argp, &delay, sizeof(delay))) {
+                               return -EFAULT;
+                       }
+                       break;
+               default:
+                       break;
+       }
+
+       return result;
+}
+
+static struct file_operations compass_dev_fops =
+{
+       .owner = THIS_MODULE,
+       .open = compass_dev_open,
+       .release = compass_dev_release,
+       .unlocked_ioctl = compass_dev_ioctl,
+};
+
+
+static struct miscdevice compass_dev_device =
+{
+       .minor = MISC_DYNAMIC_MINOR,
+       .name = "akm8975_dev",
+       .fops = &compass_dev_fops,
+};
+
+struct sensor_operate compass_akm8975_ops = {
+       .name                           = "akm8975",
+       .type                           = SENSOR_TYPE_COMPASS,  //it is important
+       .id_i2c                         = COMPASS_ID_AK8975,
+       .read_reg                       = AK8975_REG_ST1,       //read data
+       .read_len                       = SENSOR_DATA_SIZE,     //data length
+       .id_reg                         = AK8975_REG_WIA,       //read id
+       .id_data                        = AK8975_DEVICE_ID,
+       .precision                      = 8,                    //12 bits
+       .ctrl_reg                       = AK8975_REG_CNTL,      //enable or disable
+       .int_status_reg                 = SENSOR_UNKNOW_DATA,   //not exist
+       .range                          = {-0xffff,0xffff},
+       .trig                           = IRQF_TRIGGER_RISING,  //if LEVEL interrupt then IRQF_ONESHOT
+       .active                         = sensor_active,
+       .init                           = sensor_init,
+       .report                         = sensor_report_value,
+       .misc_dev                       = NULL,                 //private misc support
+};
+
+/****************operate according to sensor chip:end************/
+
+//function name should not be changed
+static struct sensor_operate *compass_get_ops(void)
+{
+       return &compass_akm8975_ops;
+}
+
+
+static int __init compass_akm8975_init(void)
+{
+       struct sensor_operate *ops = compass_get_ops();
+       int result = 0;
+       int type = ops->type;
+       result = sensor_register_slave(type, NULL, NULL, compass_get_ops);
+
+       return result;
+}
+
+static void __exit compass_akm8975_exit(void)
+{
+       struct sensor_operate *ops = compass_get_ops();
+       int type = ops->type;
+       sensor_unregister_slave(type, NULL, NULL, compass_get_ops);
+}
+
+
+module_init(compass_akm8975_init);
+module_exit(compass_akm8975_exit);
+
+
index 78684d6..2670515 100755 (executable)
-/* drivers/input/sensors/gyro/Ewtsa.c\r
- *\r
- * Copyright (C) 2012-2015 ROCKCHIP.\r
- * Author: zhangaihui <zah@rock-chips.com>\r
- *\r
- * This software is licensed under the terms of the GNU General Public\r
- * License version 2, as published by the Free Software Foundation, and\r
- * may be copied, distributed, and modified under those terms.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- */\r
-#include <linux/interrupt.h>\r
-#include <linux/i2c.h>\r
-#include <linux/slab.h>\r
-#include <linux/irq.h>\r
-#include <linux/miscdevice.h>\r
-#include <linux/gpio.h>\r
-#include <asm/uaccess.h>\r
-#include <asm/atomic.h>\r
-#include <linux/delay.h>\r
-#include <linux/input.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/freezer.h>\r
-#include <linux/of_gpio.h>\r
-#ifdef CONFIG_HAS_EARLYSUSPEND\r
-#include <linux/earlysuspend.h>\r
-#endif\r
-#include <linux/sensor-dev.h>\r
-\r
-/** This define controls compilation of the master device interface */\r
-/*#define EWTSA_MASTER_DEVICE*/\r
-/* configurable */\r
-#define GYRO_MOUNT_SWAP_XY      0   /* swap X, Y */\r
-#define GYRO_MOUNT_REVERSE_X    0   /* reverse X */\r
-#define GYRO_MOUNT_REVERSE_Y    0   /* reverse Y */\r
-#define GYRO_MOUNT_REVERSE_Z    0   /* reverse Z */\r
-\r
-/* macro defines */\r
-/*#define CHIP_ID                 0x68*/\r
-#define DEVICE_NAME             "ewtsa"\r
-#define EWTSA_ON                1\r
-#define EWTSA_OFF               0\r
-#define SLEEP_PIN               14\r
-#define DRDY_PIN                12\r
-#define DIAG_PIN                11\r
-#define MAX_VALUE               32768\r
-\r
-/* ewtsa_delay parameter */\r
-#define DELAY_THRES_MIN         1\r
-#define DELAY_THRES_1           4\r
-#define DELAY_THRES_2           9   /* msec x 90% */\r
-#define DELAY_THRES_3           18\r
-#define DELAY_THRES_4           45\r
-#define DELAY_THRES_5           90\r
-#define DELAY_THRES_6           128\r
-#define DELAY_THRES_MAX         255\r
-#define DELAY_DLPF_2            2\r
-#define DELAY_DLPF_3            3\r
-#define DELAY_DLPF_4            4\r
-#define DELAY_DLPF_5            5\r
-#define DELAY_DLPF_6            6\r
-#define DELAY_INTMIN_THRES      9\r
-\r
-#define DATA_RATE_1             0x01\r
-\r
-/* ewtsa_sleep parameter */\r
-#define SLEEP_OFF               0\r
-#define SLEEP_ON                1\r
-\r
-/* event mode */\r
-#define EWTSA_POLLING_MODE    0\r
-#define EWTSA_INTERUPT_MODE   1\r
-\r
-/* ewtsa register address */\r
-#define REG_SMPL                0x15\r
-#define REG_FS_DLPF             0x16\r
-#define REG_INT_CFG             0x17\r
-#define REG_INT_STATUS          0x1A\r
-#define REG_SELF_O_C            0x29\r
-#define REG_PWR_MGM             0x3E\r
-#define REG_MBURST_ALL          0xFF\r
-#define GYRO_DATA_REG            0x1D\r
-\r
-/* ewtsa register param */\r
-#define SELF_O_C_ENABLE         0x00\r
-#define SELF_O_C_DISABLE        0x01\r
-#define SLEEP_CTRL_ACTIVATE     0x40\r
-#define SLEEP_CTRL_SLEEP        0x00\r
-#define INT_CFG_INT_ENABLE      0x01\r
-#define INT_CFG_INT_DISABLE     0x00\r
-\r
-/* ewtsa interrupt control */\r
-#define EWSTA_INT_CLEAR         0x00\r
-#define EWSTA_INT_SKIP          0x01\r
-\r
-/* wait time(ms)*/\r
-#define EWTSA_BOOST_TIME_0      500\r
-\r
-/* sleep setting range */\r
-#define EWTSA_SLP_MIN 0\r
-#define EWTSA_SLP_MAX 1\r
-\r
-/* delay setting range */\r
-#define EWTSA_DLY_MIN 1\r
-#define EWTSA_DLY_MAX 255\r
-\r
-/* range setting range */\r
-#define EWTSA_RNG_MIN 0\r
-#define EWTSA_RNG_MAX 3\r
-\r
-/* soc setting range */\r
-#define EWTSA_SOC_MIN 0\r
-#define EWTSA_SOC_MAX 1\r
-\r
-/* event setting range */\r
-#define EWTSA_EVE_MIN 0\r
-#define EWTSA_EVE_MAX 1\r
-\r
-/* init param */\r
-#define SLEEP_INIT_VAL       (SLEEP_ON)\r
-#define DELAY_INIT_VAL       10\r
-#define RANGE_INIT_VAL       2 /*range 1000*/\r
-#define DLPF_INIT_VAL        (DELAY_DLPF_2)\r
-#define CALIB_FUNC_INIT_VAL  (EWTSA_ON)\r
-\r
-/*config store counter num*/\r
-#define CONFIG_COUNTER_MIN (6+9)\r
-#define CONFIG_COUNTER_MAX (32+9)\r
-\r
-/*command name */\r
-#define COMMAND_NAME_SOC 0\r
-#define COMMAND_NAME_DLY 1\r
-#define COMMAND_NAME_RNG 2\r
-#define COMMAND_NAME_EVE 3\r
-#define COMMAND_NAME_SLP 4\r
-#define COMMAND_NAME_NUM 5\r
-\r
-#define EWTSA_delay  DELAY_INIT_VAL\r
-#define EWTSA_range    RANGE_INIT_VAL\r
-#define EWTSA_calib    EWTSA_ON\r
-\r
-/****************operate according to sensor chip:start************/\r
-static int i2c_read_byte(struct i2c_client *thisClient, unsigned char regAddr, char *pReadData)\r
+/* drivers/input/sensors/gyro/Ewtsa.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: zhangaihui <zah@rock-chips.com>
+ *
+ * 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/interrupt.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/gpio.h>
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/delay.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/freezer.h>
+#include <linux/of_gpio.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/sensor-dev.h>
+
+/** This define controls compilation of the master device interface */
+/*#define EWTSA_MASTER_DEVICE*/
+/* configurable */
+#define GYRO_MOUNT_SWAP_XY      0   /* swap X, Y */
+#define GYRO_MOUNT_REVERSE_X    0   /* reverse X */
+#define GYRO_MOUNT_REVERSE_Y    0   /* reverse Y */
+#define GYRO_MOUNT_REVERSE_Z    0   /* reverse Z */
+
+/* macro defines */
+/*#define CHIP_ID                 0x68*/
+#define DEVICE_NAME             "ewtsa"
+#define EWTSA_ON                1
+#define EWTSA_OFF               0
+#define SLEEP_PIN               14
+#define DRDY_PIN                12
+#define DIAG_PIN                11
+#define MAX_VALUE               32768
+
+/* ewtsa_delay parameter */
+#define DELAY_THRES_MIN         1
+#define DELAY_THRES_1           4
+#define DELAY_THRES_2           9   /* msec x 90% */
+#define DELAY_THRES_3           18
+#define DELAY_THRES_4           45
+#define DELAY_THRES_5           90
+#define DELAY_THRES_6           128
+#define DELAY_THRES_MAX         255
+#define DELAY_DLPF_2            2
+#define DELAY_DLPF_3            3
+#define DELAY_DLPF_4            4
+#define DELAY_DLPF_5            5
+#define DELAY_DLPF_6            6
+#define DELAY_INTMIN_THRES      9
+
+#define DATA_RATE_1             0x01
+
+/* ewtsa_sleep parameter */
+#define SLEEP_OFF               0
+#define SLEEP_ON                1
+
+/* event mode */
+#define EWTSA_POLLING_MODE    0
+#define EWTSA_INTERUPT_MODE   1
+
+/* ewtsa register address */
+#define REG_SMPL                0x15
+#define REG_FS_DLPF             0x16
+#define REG_INT_CFG             0x17
+#define REG_INT_STATUS          0x1A
+#define REG_SELF_O_C            0x29
+#define REG_PWR_MGM             0x3E
+#define REG_MBURST_ALL          0xFF
+#define GYRO_DATA_REG            0x1D
+
+/* ewtsa register param */
+#define SELF_O_C_ENABLE         0x00
+#define SELF_O_C_DISABLE        0x01
+#define SLEEP_CTRL_ACTIVATE     0x40
+#define SLEEP_CTRL_SLEEP        0x00
+#define INT_CFG_INT_ENABLE      0x01
+#define INT_CFG_INT_DISABLE     0x00
+
+/* ewtsa interrupt control */
+#define EWSTA_INT_CLEAR         0x00
+#define EWSTA_INT_SKIP          0x01
+
+/* wait time(ms)*/
+#define EWTSA_BOOST_TIME_0      500
+
+/* sleep setting range */
+#define EWTSA_SLP_MIN 0
+#define EWTSA_SLP_MAX 1
+
+/* delay setting range */
+#define EWTSA_DLY_MIN 1
+#define EWTSA_DLY_MAX 255
+
+/* range setting range */
+#define EWTSA_RNG_MIN 0
+#define EWTSA_RNG_MAX 3
+
+/* soc setting range */
+#define EWTSA_SOC_MIN 0
+#define EWTSA_SOC_MAX 1
+
+/* event setting range */
+#define EWTSA_EVE_MIN 0
+#define EWTSA_EVE_MAX 1
+
+/* init param */
+#define SLEEP_INIT_VAL       (SLEEP_ON)
+#define DELAY_INIT_VAL       10
+#define RANGE_INIT_VAL       2 /*range 1000*/
+#define DLPF_INIT_VAL        (DELAY_DLPF_2)
+#define CALIB_FUNC_INIT_VAL  (EWTSA_ON)
+
+/*config store counter num*/
+#define CONFIG_COUNTER_MIN (6+9)
+#define CONFIG_COUNTER_MAX (32+9)
+
+/*command name */
+#define COMMAND_NAME_SOC 0
+#define COMMAND_NAME_DLY 1
+#define COMMAND_NAME_RNG 2
+#define COMMAND_NAME_EVE 3
+#define COMMAND_NAME_SLP 4
+#define COMMAND_NAME_NUM 5
+
+#define EWTSA_delay  DELAY_INIT_VAL
+#define EWTSA_range    RANGE_INIT_VAL
+#define EWTSA_calib    EWTSA_ON
+
+/****************operate according to sensor chip:start************/
+static int i2c_read_byte(struct i2c_client *thisClient, unsigned char regAddr, char *pReadData)
 {
     int    ret = 0;
-       
+
     ret = i2c_master_send( thisClient, (char*)&regAddr, 1);
     if(ret < 0)
     {
-        printk("EWTSA send cAddress=0x%x error!\n", regAddr);\r
+        printk("EWTSA send cAddress=0x%x error!\n", regAddr);
         return ret;
     }
     ret = i2c_master_recv( thisClient, (char*)pReadData, 1);
     if(ret < 0)
     {
-        printk("EWTSAread *pReadData=0x%x error!\n", *pReadData);\r
+        printk("EWTSAread *pReadData=0x%x error!\n", *pReadData);
         return ret;
     }
 
     return 1;
-}\r
-static int i2c_write_byte(struct i2c_client *thisClient, unsigned char regAddr, unsigned char writeData)\r
+}
+static int i2c_write_byte(struct i2c_client *thisClient, unsigned char regAddr, unsigned char writeData)
 {
     char    write_data[2] = {0};
     int    ret=0;
-    
+
     write_data[0] = regAddr;
     write_data[1] = writeData;
-    
+
     ret = i2c_master_send(thisClient, write_data, 2);
-    if (ret < 0) 
+    if (ret < 0)
     {
         ret = i2c_master_send(thisClient, write_data, 2);
-        if (ret < 0) 
+        if (ret < 0)
         {
-            printk("EWTSA send regAddr=0x%x error!\n", regAddr);\r
+            printk("EWTSA send regAddr=0x%x error!\n", regAddr);
             return ret;
         }
         return 1;
     }
-    
+
     return 1;
-}\r
-\r
-static int ewtsa_system_restart(struct i2c_client *client)\r
+}
+
+static int ewtsa_system_restart(struct i2c_client *client)
 {
     int             err;
-     char   reg;\r
-     char   smpl , dlpf;\r
-\r
-    err = i2c_write_byte(client, ( unsigned char)REG_SELF_O_C, ( unsigned char)SELF_O_C_DISABLE);\r
+     char   reg;
+     char   smpl , dlpf;
+
+    err = i2c_write_byte(client, ( unsigned char)REG_SELF_O_C, ( unsigned char)SELF_O_C_DISABLE);
     if (err < 0) {
         return err;
     }
 
     ///Set SMPL register
-        if (EWTSA_delay <= ( unsigned char)DELAY_THRES_2) {\r
-            smpl = ( unsigned char)DELAY_INTMIN_THRES;\r
+        if (EWTSA_delay <= ( unsigned char)DELAY_THRES_2) {
+            smpl = ( unsigned char)DELAY_INTMIN_THRES;
         }else{
-            smpl = ( unsigned char)(EWTSA_delay - ( unsigned char)1);\r
-        }\r
-    err = i2c_write_byte(client, ( unsigned char)REG_SMPL, ( unsigned char)smpl);\r
+            smpl = ( unsigned char)(EWTSA_delay - ( unsigned char)1);
+        }
+    err = i2c_write_byte(client, ( unsigned char)REG_SMPL, ( unsigned char)smpl);
     if (err < 0) {
         return err;
     }
 
     ///Set DLPF register
-    if (EWTSA_delay >= ( unsigned char)DELAY_THRES_6){\r
-        dlpf = ( unsigned char)DELAY_DLPF_6;\r
-    }else if (EWTSA_delay >= ( unsigned char)DELAY_THRES_5) {\r
-        dlpf = ( unsigned char)DELAY_DLPF_5;\r
-    }else if (EWTSA_delay >= ( unsigned char)DELAY_THRES_4){\r
-        dlpf = ( unsigned char)DELAY_DLPF_4;\r
-    }else if (EWTSA_delay >= ( unsigned char)DELAY_THRES_3) {\r
-        dlpf = ( unsigned char)DELAY_DLPF_3;\r
+    if (EWTSA_delay >= ( unsigned char)DELAY_THRES_6){
+        dlpf = ( unsigned char)DELAY_DLPF_6;
+    }else if (EWTSA_delay >= ( unsigned char)DELAY_THRES_5) {
+        dlpf = ( unsigned char)DELAY_DLPF_5;
+    }else if (EWTSA_delay >= ( unsigned char)DELAY_THRES_4){
+        dlpf = ( unsigned char)DELAY_DLPF_4;
+    }else if (EWTSA_delay >= ( unsigned char)DELAY_THRES_3) {
+        dlpf = ( unsigned char)DELAY_DLPF_3;
     }else{
-        dlpf = ( unsigned char)DELAY_DLPF_2;\r
+        dlpf = ( unsigned char)DELAY_DLPF_2;
     }
 
-    reg = ( unsigned char)(( unsigned char)(EWTSA_range << 3) | dlpf | ( unsigned char)0x80 ) ;\r
-\r
-    err = i2c_write_byte(client, REG_FS_DLPF, reg);\r
+