sensors:add akm8963 support,need update HAL
authorluowei <lw@rock-chips.com>
Sat, 9 Mar 2013 07:57:37 +0000 (15:57 +0800)
committerluowei <lw@rock-chips.com>
Sat, 9 Mar 2013 07:57:37 +0000 (15:57 +0800)
arch/arm/plat-rk/include/plat/board.h
drivers/input/sensors/compass/Kconfig
drivers/input/sensors/compass/Makefile
drivers/input/sensors/compass/ak8963.c [new file with mode: 0755]
drivers/input/sensors/compass/ak8975.c
drivers/input/sensors/sensor-dev.c
include/linux/sensor-dev.h

index 781964b007e498c8bd6d6227b598b1d9ab0773ff..bcdf8f2d48692ca0bc31f9c89f70ee7e3457a10f 100755 (executable)
@@ -187,6 +187,16 @@ struct akm8975_platform_data {
        int gpio_DRDY;
 };
 
+struct akm_platform_data {
+       short m_layout[4][3][3];
+       char project_name[64];
+       char layout;
+       char outbit;
+       int gpio_DRDY;
+       int gpio_RST;
+};
+
+
 struct sensor_platform_data {
        int type;
        int irq;
index 72ab06c0c34fa0c46464c1ad70a1c54337c7f70d..bbd576c2df46b4e669160e11899221fe7a723c7f 100755 (executable)
@@ -23,6 +23,16 @@ config COMPASS_AK8975
   To compile this driver as a module, choose M here: the module
   will be called ak8975.
 
+config COMPASS_AK8963
+  tristate "Asahi Kasei AK8963 3-Axis Magnetometer"
+  depends on I2C
+  help
+  Say yes here to build support for Asahi Kasei AK8963 3-Axis Magnetometer.
+
+  To compile this driver as a module, choose M here: the module
+  will be called ak8963.
+
+
 config COMPASS_MMC328X
   tristate "Mmc328x 3-Axis Magnetometer"
   depends on I2C
index dfd09bfa3ea5489216a9fb8852ca221656c0d906..73e1db629109c1a3d9bce04ee9e6c1b068c10daf 100755 (executable)
@@ -1,6 +1,6 @@
 #
 # Makefile for industrial I/O Magnetometer sensors
 #
-obj-$(CONFIG_COMPASS_AK8975) := ak8975.o 
-obj-$(CONFIG_COMPASS_AK8973) := ak8973.o 
-obj-$(CONFIG_COMPASS_MMC328X) := mmc328x.o 
\ No newline at end of file
+obj-$(CONFIG_COMPASS_AK8975)   += ak8975.o 
+obj-$(CONFIG_COMPASS_AK8963)   += ak8963.o
+obj-$(CONFIG_COMPASS_MMC328X)  += mmc328x.o 
\ No newline at end of file
diff --git a/drivers/input/sensors/compass/ak8963.c b/drivers/input/sensors/compass/ak8963.c
new file mode 100755 (executable)
index 0000000..bf3af24
--- /dev/null
@@ -0,0 +1,789 @@
+/* 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 <mach/gpio.h>\r
+#include <mach/board.h> \r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+#include <linux/earlysuspend.h>\r
+#endif\r
+#include <linux/sensor-dev.h>\r
+\r
+#define SENSOR_DATA_SIZE               8\r
+\r
+#if 0\r
+#define SENSOR_DEBUG_TYPE SENSOR_TYPE_COMPASS\r
+#define DBG(x...) if(sensor->pdata->type == SENSOR_DEBUG_TYPE) printk(x)\r
+#else\r
+#define DBG(x...)\r
+#endif\r
+\r
+#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
+/*! @}*/\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
+\r
+\r
+\r
+#define AK8963_DEVICE_ID               0x48\r
+static struct i2c_client *this_client;\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
+               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
+#ifdef SENSOR_DEBUG_TYPE       \r
+       int i;\r
+#endif                 \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
+        * 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
+
+       /*
+        * ST2 : data error -
+        * occurs when data read is started outside of a readable period;
+        * data read would not be correct.
+        * Valid in continuous measurement mode only.
+        * In single measurement mode this error should not occour but we
+        * stil account for it and return an error, since the data would be
+        * 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
+       /*
+        * ST2 : overflow -
+        * the sum of the absolute values of all axis |X|+|Y|+|Z| < 2400uT.
+        * This is likely to happen in presence of an external magnetic
+        * disturbance; it indicates, the sensor data is incorrect and should
+        * be ignored.
+        * 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
+#ifdef SENSOR_DEBUG_TYPE       \r
+       DBG("%s:",__func__);\r
+       for(i=0; i<sensor->ops->read_len; i++)\r
+               DBG("0x%x,",buffer[i]);\r
+       DBG("\n");\r
+#endif \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
+#ifdef SENSOR_DEBUG_TYPE\r
+       struct sensor_private_data* sensor = \r
+               (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
+#endif\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
+#ifdef SENSOR_DEBUG_TYPE\r
+       struct sensor_private_data* sensor = \r
+               (struct sensor_private_data *)i2c_get_clientdata(this_client); \r
+#endif\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
+               \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[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
+       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_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 = 1;     //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
+       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
+       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
+               goto error;\r
+       }\r
+error:                         \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
index 3d2448f5893f5be8008b95980ee1bdf08175a48b..cecf15fb5f5a390067fabeb413cd2ae51507c92e 100755 (executable)
@@ -30,7 +30,7 @@
 #ifdef CONFIG_HAS_EARLYSUSPEND\r
 #include <linux/earlysuspend.h>\r
 #endif\r
-#include <linux/akm8975.h>\r
+\r
 #include <linux/sensor-dev.h>\r
 \r
 #define SENSOR_DATA_SIZE               8\r
 #define DBG(x...)\r
 #endif\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
 \r
-static atomic_t m_flag;\r
-static atomic_t a_flag;\r
-static atomic_t mv_flag;\r
-static atomic_t open_flag;\r
-static short akmd_delay = 100;\r
-static DECLARE_WAIT_QUEUE_HEAD(open_wq);\r
+\r
 \r
 \r
 /****************operate according to sensor chip:start************/\r
@@ -89,6 +150,7 @@ static int sensor_init(struct i2c_client *client)
        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
@@ -100,15 +162,15 @@ static int sensor_init(struct i2c_client *client)
        }\r
        \r
        sensor->status_cur = SENSOR_OFF;\r
-#if 0  \r
-       sensor->ops->ctrl_data = 0;\r
-       result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
-       if(result)\r
+       \r
+       info = sensor_read_reg(client, AK8975_REG_INFO);\r
+       if((info & (0x0f<<3)) != AK8975_INFO_DATA)\r
+       \r
        {\r
-               printk("%s:line=%d,error\n",__func__,__LINE__);\r
-               return result;\r
+               printk("%s:info=0x%x,it is not %s\n",__func__, info, sensor->ops->name);\r
+               result = -1;\r
        }\r
-#endif\r
+       \r
        DBG("%s:status_cur=%d\n",__func__, sensor->status_cur);\r
        return result;\r
 }\r
@@ -191,7 +253,7 @@ static int sensor_report_value(struct i2c_client *client)
 #ifdef SENSOR_DEBUG_TYPE       \r
        DBG("%s:",__func__);\r
        for(i=0; i<sensor->ops->read_len; i++)\r
-               DBG("%d,",buffer[i]);\r
+               DBG("0x%x,",buffer[i]);\r
        DBG("\n");\r
 #endif \r
 \r
@@ -220,7 +282,7 @@ static void compass_set_YPR(short *rbuf)
            (struct sensor_private_data *) i2c_get_clientdata(this_client);     \r
        \r
        /* Report magnetic sensor information */\r
-       if (atomic_read(&m_flag)) {\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
@@ -229,7 +291,7 @@ static void compass_set_YPR(short *rbuf)
        }\r
        \r
        /* Report acceleration sensor information */\r
-       if (atomic_read(&a_flag)) {\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
@@ -239,7 +301,7 @@ static void compass_set_YPR(short *rbuf)
        }\r
        \r
        /* Report magnetic vector information */\r
-       if (atomic_read(&mv_flag)) {\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
@@ -251,131 +313,6 @@ static void compass_set_YPR(short *rbuf)
 }\r
 \r
 \r
-\r
-static int compass_aot_open(struct inode *inode, struct file *file)\r
-{\r
-#ifdef SENSOR_DEBUG_TYPE\r
-       struct sensor_private_data* sensor =\r
-                       (struct sensor_private_data *)i2c_get_clientdata(this_client);\r
-#endif\r
-       int result = 0;\r
-       int flag = 0;\r
-       flag = atomic_read(&open_flag);\r
-       if(!flag)\r
-       {       \r
-               atomic_set(&open_flag, 1);\r
-               wake_up(&open_wq);\r
-       }\r
-\r
-       DBG("%s\n", __func__);\r
-       return result;\r
-}\r
-\r
-\r
-static int compass_aot_release(struct inode *inode, struct file *file)\r
-{      \r
-#ifdef SENSOR_DEBUG_TYPE\r
-       struct sensor_private_data* sensor =\r
-                       (struct sensor_private_data *)i2c_get_clientdata(this_client);  \r
-#endif\r
-       //struct i2c_client *client = this_client;\r
-       int result = 0;\r
-       int flag = 0;\r
-       flag = atomic_read(&open_flag);\r
-       if(flag)\r
-       {\r
-               atomic_set(&open_flag, 0);\r
-               wake_up(&open_wq);      \r
-       }\r
-       \r
-       DBG("%s\n", __func__);\r
-       return result;\r
-}\r
-\r
-\r
-/* ioctl - I/O control */\r
-static long compass_aot_ioctl(struct file *file,\r
-                         unsigned int cmd, unsigned long arg)\r
-{\r
-#ifdef SENSOR_DEBUG_TYPE\r
-       struct sensor_private_data* sensor = \r
-                       (struct sensor_private_data *)i2c_get_clientdata(this_client);  \r
-#endif\r
-       void __user *argp = (void __user *)arg;\r
-       int result = 0;\r
-       short flag;\r
-       \r
-       switch (cmd) {\r
-               case ECS_IOCTL_APP_SET_MFLAG:\r
-               case ECS_IOCTL_APP_SET_AFLAG:\r
-               case ECS_IOCTL_APP_SET_MVFLAG:\r
-                       if (copy_from_user(&flag, argp, sizeof(flag))) {\r
-                               return -EFAULT;\r
-                       }\r
-                       if (flag < 0 || flag > 1) {\r
-                               return -EINVAL;\r
-                       }\r
-                       break;\r
-               case ECS_IOCTL_APP_SET_DELAY:\r
-                       if (copy_from_user(&flag, argp, sizeof(flag))) {\r
-                               return -EFAULT;\r
-                       }\r
-                       break;\r
-               default:\r
-                       break;\r
-       }\r
-       \r
-       switch (cmd) {\r
-               case ECS_IOCTL_APP_SET_MFLAG:   \r
-                       atomic_set(&m_flag, flag);                      \r
-                       DBG("%s:ECS_IOCTL_APP_SET_MFLAG,flag=%d\n", __func__,flag);\r
-                       break;\r
-               case ECS_IOCTL_APP_GET_MFLAG:           \r
-                       flag = atomic_read(&m_flag);\r
-                       DBG("%s:ECS_IOCTL_APP_GET_MFLAG,flag=%d\n", __func__,flag);\r
-                       break;\r
-               case ECS_IOCTL_APP_SET_AFLAG:   \r
-                       atomic_set(&a_flag, flag);              \r
-                       DBG("%s:ECS_IOCTL_APP_SET_AFLAG,flag=%d\n", __func__,flag);\r
-                       break;\r
-               case ECS_IOCTL_APP_GET_AFLAG:\r
-                       flag = atomic_read(&a_flag);            \r
-                       DBG("%s:ECS_IOCTL_APP_GET_AFLAG,flag=%d\n", __func__,flag);\r
-                       break;\r
-               case ECS_IOCTL_APP_SET_MVFLAG:  \r
-                       atomic_set(&mv_flag, flag);             \r
-                       DBG("%s:ECS_IOCTL_APP_SET_MVFLAG,flag=%d\n", __func__,flag);\r
-                       break;\r
-               case ECS_IOCTL_APP_GET_MVFLAG:          \r
-                       flag = atomic_read(&mv_flag);           \r
-                       DBG("%s:ECS_IOCTL_APP_GET_MVFLAG,flag=%d\n", __func__,flag);\r
-                       break;\r
-               case ECS_IOCTL_APP_SET_DELAY:\r
-                       akmd_delay = flag;\r
-                       break;\r
-               case ECS_IOCTL_APP_GET_DELAY:\r
-                       flag = akmd_delay;\r
-                       break;\r
-               default:\r
-                       return -ENOTTY;\r
-       }\r
-       \r
-       switch (cmd) {\r
-               case ECS_IOCTL_APP_GET_MFLAG:\r
-               case ECS_IOCTL_APP_GET_AFLAG:\r
-               case ECS_IOCTL_APP_GET_MVFLAG:\r
-               case ECS_IOCTL_APP_GET_DELAY:\r
-                       if (copy_to_user(argp, &flag, sizeof(flag))) {\r
-                               return -EFAULT;\r
-                       }\r
-                       break;\r
-               default:\r
-                       break;\r
-       }\r
-\r
-       return result;\r
-}\r
-\r
 static int compass_dev_open(struct inode *inode, struct file *file)\r
 {\r
 #ifdef SENSOR_DEBUG_TYPE\r
@@ -482,14 +419,16 @@ static int compass_akm_set_mode(struct i2c_client *client, char mode)
 \r
 static int compass_akm_get_openstatus(void)\r
 {\r
-       wait_event_interruptible(open_wq, (atomic_read(&open_flag) != 0));\r
-       return atomic_read(&open_flag);\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
-       wait_event_interruptible(open_wq, (atomic_read(&open_flag) <= 0));\r
-       return atomic_read(&open_flag);\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
@@ -497,11 +436,11 @@ static int compass_akm_get_closestatus(void)
 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 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 akm8975_platform_data compass;\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
@@ -611,7 +550,7 @@ static long compass_dev_ioctl(struct file *file,
                        DBG("%s:closestatus=%d\n",__func__,status);\r
                        break;\r
                case ECS_IOCTL_GET_DELAY:\r
-                       delay = akmd_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
@@ -658,25 +597,6 @@ static long compass_dev_ioctl(struct file *file,
        return result;\r
 }\r
 \r
-\r
-static struct file_operations compass_aot_fops =\r
-{\r
-       .owner = THIS_MODULE,\r
-       .unlocked_ioctl = compass_aot_ioctl,\r
-       .open = compass_aot_open,\r
-       .release = compass_aot_release,\r
-};\r
-\r
-\r
-\r
-static struct miscdevice compass_aot_device =\r
-{      \r
-       .minor = MISC_DYNAMIC_MINOR,\r
-       .name = "akm8975_aot",\r
-       .fops = &compass_aot_fops,\r
-};\r
-\r
-\r
 static struct file_operations compass_dev_fops =\r
 {\r
        .owner = THIS_MODULE,\r
@@ -693,7 +613,7 @@ static struct miscdevice compass_dev_device =
        .fops = &compass_dev_fops,\r
 };\r
 \r
-struct sensor_operate akm8975_akm8975_ops = {\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
@@ -703,13 +623,13 @@ struct sensor_operate akm8975_akm8975_ops = {
        .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
+       .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                       = &compass_dev_device,  //private misc support\r
+       .misc_dev                       = NULL,                 //private misc support\r
 };\r
 \r
 /****************operate according to sensor chip:end************/\r
@@ -717,7 +637,7 @@ struct sensor_operate akm8975_akm8975_ops = {
 //function name should not be changed\r
 static struct sensor_operate *compass_get_ops(void)\r
 {\r
-       return &akm8975_akm8975_ops;\r
+       return &compass_akm8975_ops; \r
 }\r
 \r
 \r
@@ -728,21 +648,12 @@ static int __init compass_akm8975_init(void)
        int type = ops->type;\r
        result = sensor_register_slave(type, NULL, NULL, compass_get_ops);\r
 \r
-       result = misc_register(&compass_aot_device);\r
+       result = misc_register(&compass_dev_device);\r
        if (result < 0) {\r
-               printk("%s:fail to register misc device %s\n", __func__, compass_aot_device.name);\r
+               printk("%s:fail to register misc device %s\n", __func__, compass_dev_device.name);\r
                goto error;\r
        }\r
-\r
-       /* As default, report all information */\r
-       atomic_set(&m_flag, 1);\r
-       atomic_set(&a_flag, 1);\r
-       atomic_set(&mv_flag, 1);                        \r
-       atomic_set(&open_flag, 0);              \r
-       init_waitqueue_head(&open_wq);\r
-                       \r
-       DBG("%s\n",__func__);\r
-error:\r
+error:                         \r
        return result;\r
 }\r
 \r
index c172a17c014745998322fd849659c784d6404f7f..7fa69e758c1d520d2426c24d1ec0e500b89ed9db 100755 (executable)
@@ -31,7 +31,6 @@
 #ifdef CONFIG_HAS_EARLYSUSPEND\r
 #include <linux/earlysuspend.h>\r
 #endif\r
-#include <linux/akm8975.h>\r
 #include <linux/l3g4200d.h>\r
 #include <linux/sensor-dev.h>\r
 \r
 #define DBG(x...)\r
 #endif\r
 \r
-#define SENSOR_VERSION_AND_TIME  "sensor-dev.c v1.1 add pressure and temperature support 2013-2-27"\r
+#if 0\r
+sensor-dev.c v1.1 add pressure and temperature support 2013-2-27\r
+sensor-dev.c v1.2 add akm8963 support 2013-3-10\r
+#endif\r
+#define SENSOR_VERSION_AND_TIME  "sensor-dev.c v1.2 add akm8963 support 2013-3-10"\r
 \r
 \r
 struct sensor_private_data *g_sensor[SENSOR_NUM_TYPES];\r
@@ -562,36 +565,122 @@ static int  gsensor_class_init(void)
 \r
 static int compass_dev_open(struct inode *inode, struct file *file)\r
 {\r
-       //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS];\r
-       //struct i2c_client *client = sensor->client;\r
+       struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS];\r
+       //struct i2c_client *client = sensor->client;   \r
+\r
        int result = 0;\r
-       \r
-       //to do\r
+       int flag = 0;\r
+       flag = atomic_read(&sensor->flags.open_flag);\r
+       if(!flag)\r
+       {       \r
+               atomic_set(&sensor->flags.open_flag, 1);\r
+               wake_up(&sensor->flags.open_wq);\r
+       }\r
+\r
+       DBG("%s\n", __func__);\r
        return result;\r
 }\r
 \r
 \r
+\r
 static int compass_dev_release(struct inode *inode, struct file *file)\r
 {\r
-       //struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS];\r
-       //struct i2c_client *client = sensor->client;   \r
+       struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS];\r
+       //struct i2c_client *client = sensor->client;\r
+       //void __user *argp = (void __user *)arg;\r
        int result = 0;\r
-\r
-       //to do\r
+       int flag = 0;\r
+       flag = atomic_read(&sensor->flags.open_flag);\r
+       if(flag)\r
+       {\r
+               atomic_set(&sensor->flags.open_flag, 0);\r
+               wake_up(&sensor->flags.open_wq);        \r
+       }\r
+       \r
+       DBG("%s\n", __func__);\r
        return result;\r
 }\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 = g_sensor[SENSOR_TYPE_COMPASS];\r
-       //struct i2c_client *client = sensor->client;\r
-       //void __user *argp = (void __user *)arg;\r
+       struct sensor_private_data *sensor = g_sensor[SENSOR_TYPE_COMPASS];\r
+       struct i2c_client *client = sensor->client;\r
+       void __user *argp = (void __user *)arg;\r
        int result = 0;\r
+       short flag;\r
+       \r
+       switch (cmd) {\r
+               case ECS_IOCTL_APP_SET_MFLAG:\r
+               case ECS_IOCTL_APP_SET_AFLAG:\r
+               case ECS_IOCTL_APP_SET_MVFLAG:\r
+                       if (copy_from_user(&flag, argp, sizeof(flag))) {\r
+                               return -EFAULT;\r
+                       }\r
+                       if (flag < 0 || flag > 1) {\r
+                               return -EINVAL;\r
+                       }\r
+                       break;\r
+               case ECS_IOCTL_APP_SET_DELAY:\r
+                       if (copy_from_user(&flag, argp, sizeof(flag))) {\r
+                               return -EFAULT;\r
+                       }\r
+                       break;\r
+               default:\r
+                       break;\r
+       }\r
        \r
-       //to do\r
+       switch (cmd) {\r
+               case ECS_IOCTL_APP_SET_MFLAG:   \r
+                       atomic_set(&sensor->flags.m_flag, flag);                        \r
+                       DBG("%s:ECS_IOCTL_APP_SET_MFLAG,flag=%d\n", __func__,flag);\r
+                       break;\r
+               case ECS_IOCTL_APP_GET_MFLAG:           \r
+                       flag = atomic_read(&sensor->flags.m_flag);\r
+                       DBG("%s:ECS_IOCTL_APP_GET_MFLAG,flag=%d\n", __func__,flag);\r
+                       break;\r
+               case ECS_IOCTL_APP_SET_AFLAG:   \r
+                       atomic_set(&sensor->flags.a_flag, flag);                \r
+                       DBG("%s:ECS_IOCTL_APP_SET_AFLAG,flag=%d\n", __func__,flag);\r
+                       break;\r
+               case ECS_IOCTL_APP_GET_AFLAG:\r
+                       flag = atomic_read(&sensor->flags.a_flag);              \r
+                       DBG("%s:ECS_IOCTL_APP_GET_AFLAG,flag=%d\n", __func__,flag);\r
+                       break;\r
+               case ECS_IOCTL_APP_SET_MVFLAG:  \r
+                       atomic_set(&sensor->flags.mv_flag, flag);               \r
+                       DBG("%s:ECS_IOCTL_APP_SET_MVFLAG,flag=%d\n", __func__,flag);\r
+                       break;\r
+               case ECS_IOCTL_APP_GET_MVFLAG:          \r
+                       flag = atomic_read(&sensor->flags.mv_flag);             \r
+                       DBG("%s:ECS_IOCTL_APP_GET_MVFLAG,flag=%d\n", __func__,flag);\r
+                       break;\r
+               case ECS_IOCTL_APP_SET_DELAY:\r
+                       sensor->flags.delay = flag;\r
+                       break;\r
+               case ECS_IOCTL_APP_GET_DELAY:\r
+                       flag = sensor->flags.delay;\r
+                       break;\r
+               default:\r
+                       return -ENOTTY;\r
+       }\r
+       \r
+       switch (cmd) {\r
+               case ECS_IOCTL_APP_GET_MFLAG:\r
+               case ECS_IOCTL_APP_GET_AFLAG:\r
+               case ECS_IOCTL_APP_GET_MVFLAG:\r
+               case ECS_IOCTL_APP_GET_DELAY:\r
+                       if (copy_to_user(argp, &flag, sizeof(flag))) {\r
+                               return -EFAULT;\r
+                       }\r
+                       break;\r
+               default:\r
+                       break;\r
+       }\r
+\r
        return result;\r
 }\r
 \r
@@ -1399,6 +1488,12 @@ int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid)
                        goto out_free_memory;\r
        }\r
 \r
+       if(pdata->reset_pin)\r
+       gpio_request(pdata->reset_pin,"sensor_reset_pin");\r
+\r
+       if(pdata->power_pin)\r
+       gpio_request(pdata->power_pin,"sensor_power_pin");\r
+               \r
        memset(&(sensor->axis), 0, sizeof(struct sensor_axis) );\r
        atomic_set(&(sensor->data_ready), 0);\r
        init_waitqueue_head(&(sensor->data_ready_wq));\r
@@ -1407,6 +1502,14 @@ int sensor_probe(struct i2c_client *client, const struct i2c_device_id *devid)
        mutex_init(&sensor->sensor_mutex);\r
        mutex_init(&sensor->i2c_mutex);\r
 \r
+       /* As default, report all information */\r
+       atomic_set(&sensor->flags.m_flag, 1);\r
+       atomic_set(&sensor->flags.a_flag, 1);\r
+       atomic_set(&sensor->flags.mv_flag, 1);                  \r
+       atomic_set(&sensor->flags.open_flag, 0);                \r
+       init_waitqueue_head(&sensor->flags.open_wq);\r
+       sensor->flags.delay = 100;\r
+\r
        sensor->status_cur = SENSOR_OFF;\r
        sensor->axis.x = 0;\r
        sensor->axis.y = 0;\r
@@ -1559,7 +1662,7 @@ out_input_register_device_failed:
 out_free_memory:\r
        kfree(sensor);\r
 out_no_free:\r
-       dev_err(&client->adapter->dev, "%s failed %d\n", __func__, result);\r
+       dev_err(&client->adapter->dev, "%s failed %d\n\n", __func__, result);\r
        return result;\r
 \r
 }\r
@@ -1603,7 +1706,8 @@ static const struct i2c_device_id sensor_id[] = {
        {"gs_mxc6225", ACCEL_ID_MXC6225},\r
        /*compass*/\r
        {"compass", COMPASS_ID_ALL},\r
-       {"ak8975", COMPASS_ID_AK8975},\r
+       {"ak8975", COMPASS_ID_AK8975},  \r
+       {"ak8963", COMPASS_ID_AK8963},\r
        {"mmc314x", COMPASS_ID_MMC314X},\r
        /*gyroscope*/\r
        {"gyro", GYRO_ID_ALL},  \r
index 980069ae7f23c5b1b6aed83975dcaf57cc34ed4f..236fe8e97d8b86665164e0f8ebe9a09169487053 100755 (executable)
@@ -58,6 +58,7 @@ enum sensor_id {
 \r
        COMPASS_ID_ALL,\r
        COMPASS_ID_AK8975,\r
+       COMPASS_ID_AK8963,\r
        COMPASS_ID_AK8972,\r
        COMPASS_ID_AMI30X,\r
        COMPASS_ID_AMI306,\r
@@ -104,6 +105,16 @@ struct sensor_axis {
        int z;\r
 };\r
 \r
+struct sensor_flag {\r
+       atomic_t a_flag;        \r
+       atomic_t m_flag;        \r
+       atomic_t mv_flag;       \r
+       atomic_t open_flag;\r
+       long long delay;        \r
+       wait_queue_head_t open_wq;\r
+};\r
+\r
+\r
 struct sensor_operate {\r
        char *name;\r
        int type;\r
@@ -148,6 +159,7 @@ struct sensor_private_data {
        int status_cur;\r
        int start_count;\r
        int devid;\r
+       struct sensor_flag flags;\r
        struct i2c_device_id *i2c_id;\r
        struct sensor_platform_data *pdata;\r
        struct sensor_operate *ops; \r
@@ -169,27 +181,45 @@ extern int sensor_unregister_slave(int type,struct i2c_client *client,
                        struct sensor_operate *(*get_sensor_ops)(void));\r
 \r
 \r
-#define GSENSOR_IO                             0xA1\r
+#define GSENSOR_IOCTL_MAGIC                    'a'\r
 #define GBUFF_SIZE                             12      /* Rx buffer size */\r
 \r
 /* IOCTLs for MMA8452 library */\r
-#define GSENSOR_IOCTL_INIT                  _IO(GSENSOR_IO, 0x01)\r
-#define GSENSOR_IOCTL_RESET                    _IO(GSENSOR_IO, 0x04)\r
-#define GSENSOR_IOCTL_CLOSE                            _IO(GSENSOR_IO, 0x02)\r
-#define GSENSOR_IOCTL_START                        _IO(GSENSOR_IO, 0x03)\r
-#define GSENSOR_IOCTL_GETDATA               _IOR(GSENSOR_IO, 0x08, char[GBUFF_SIZE+1])\r
+#define GSENSOR_IOCTL_INIT                     _IO(GSENSOR_IOCTL_MAGIC, 0x01)\r
+#define GSENSOR_IOCTL_RESET                    _IO(GSENSOR_IOCTL_MAGIC, 0x04)\r
+#define GSENSOR_IOCTL_CLOSE                    _IO(GSENSOR_IOCTL_MAGIC, 0x02)\r
+#define GSENSOR_IOCTL_START                    _IO(GSENSOR_IOCTL_MAGIC, 0x03)\r
+#define GSENSOR_IOCTL_GETDATA                  _IOR(GSENSOR_IOCTL_MAGIC, 0x08, char[GBUFF_SIZE+1])\r
+/* IOCTLs for APPs */\r
+#define GSENSOR_IOCTL_APP_SET_RATE             _IOW(GSENSOR_IOCTL_MAGIC, 0x10, char)\r
+\r
+\r
+#define COMPASS_IOCTL_MAGIC                   'c'\r
 /* IOCTLs for APPs */\r
-#define GSENSOR_IOCTL_APP_SET_RATE                     _IOW(GSENSOR_IO, 0x10, char)\r
+#define ECS_IOCTL_APP_SET_MODE         _IOW(COMPASS_IOCTL_MAGIC, 0x10, short)\r
+#define ECS_IOCTL_APP_SET_MFLAG                _IOW(COMPASS_IOCTL_MAGIC, 0x11, short)\r
+#define ECS_IOCTL_APP_GET_MFLAG                _IOW(COMPASS_IOCTL_MAGIC, 0x12, short)\r
+#define ECS_IOCTL_APP_SET_AFLAG                _IOW(COMPASS_IOCTL_MAGIC, 0x13, short)\r
+#define ECS_IOCTL_APP_GET_AFLAG                _IOR(COMPASS_IOCTL_MAGIC, 0x14, short)\r
+#define ECS_IOCTL_APP_SET_TFLAG                _IOR(COMPASS_IOCTL_MAGIC, 0x15, short)/* NOT use */\r
+#define ECS_IOCTL_APP_GET_TFLAG                _IOR(COMPASS_IOCTL_MAGIC, 0x16, short)/* NOT use */\r
+#define ECS_IOCTL_APP_RESET_PEDOMETER   _IOW(COMPASS_IOCTL_MAGIC, 0x17)        /* NOT use */\r
+#define ECS_IOCTL_APP_SET_DELAY                _IOW(COMPASS_IOCTL_MAGIC, 0x18, short)\r
+#define ECS_IOCTL_APP_SET_MVFLAG       _IOW(COMPASS_IOCTL_MAGIC, 0x19, short)\r
+#define ECS_IOCTL_APP_GET_MVFLAG       _IOR(COMPASS_IOCTL_MAGIC, 0x1A, short)\r
+#define ECS_IOCTL_APP_GET_DELAY                _IOR(COMPASS_IOCTL_MAGIC, 0x1B, short)\r
+\r
+\r
 \r
 \r
 #define LIGHTSENSOR_IOCTL_MAGIC 'l'\r
 #define LIGHTSENSOR_IOCTL_GET_ENABLED          _IOR(LIGHTSENSOR_IOCTL_MAGIC, 1, int *) \r
-#define LIGHTSENSOR_IOCTL_ENABLE                       _IOW(LIGHTSENSOR_IOCTL_MAGIC, 2, int *) \r
-#define LIGHTSENSOR_IOCTL_DISABLE                      _IOW(LIGHTSENSOR_IOCTL_MAGIC, 3, int *)\r
+#define LIGHTSENSOR_IOCTL_ENABLE               _IOW(LIGHTSENSOR_IOCTL_MAGIC, 2, int *) \r
+#define LIGHTSENSOR_IOCTL_DISABLE              _IOW(LIGHTSENSOR_IOCTL_MAGIC, 3, int *)\r
 \r
-#define PSENSOR_IOCTL_MAGIC 'c'\r
-#define PSENSOR_IOCTL_GET_ENABLED                      _IOR(PSENSOR_IOCTL_MAGIC, 1, int *)\r
-#define PSENSOR_IOCTL_ENABLE                           _IOW(PSENSOR_IOCTL_MAGIC, 2, int *)\r
+#define PSENSOR_IOCTL_MAGIC 'p'\r
+#define PSENSOR_IOCTL_GET_ENABLED              _IOR(PSENSOR_IOCTL_MAGIC, 1, int *)\r
+#define PSENSOR_IOCTL_ENABLE                   _IOW(PSENSOR_IOCTL_MAGIC, 2, int *)\r
 #define PSENSOR_IOCTL_DISABLE                  _IOW(PSENSOR_IOCTL_MAGIC, 3, int *)\r
 \r
 \r