sensor: add mpu6880's accel and gyro support.
authorguoyi <gy@rock-chips.com>
Wed, 14 Jan 2015 06:47:18 +0000 (14:47 +0800)
committerguoyi <gy@rock-chips.com>
Wed, 14 Jan 2015 06:58:31 +0000 (14:58 +0800)
arch/arm/boot/dts/rk3288-tb_8846.dts [changed mode: 0644->0755]
drivers/input/sensors/accel/Kconfig
drivers/input/sensors/accel/Makefile
drivers/input/sensors/accel/mpu6880_acc.c [new file with mode: 0644]
drivers/input/sensors/gyro/Kconfig
drivers/input/sensors/gyro/Makefile
drivers/input/sensors/gyro/mpu6880_gyro.c [new file with mode: 0644]
drivers/input/sensors/sensor-dev.c
include/linux/mpu6880.h [new file with mode: 0644]
include/linux/sensor-dev.h

old mode 100644 (file)
new mode 100755 (executable)
index 0c2c19a..7f5e809
                irq_gpio = <&gpio0 GPIO_A4 IRQ_TYPE_EDGE_FALLING>;
        };
 
+       /*
+       mpu6880_acc:mpu_acc@68{
+               compatible = "mpu6880_acc";
+               reg = <0x68>;
+               irq_enable = <0>;
+               poll_delay_ms = <30>;
+               type = <SENSOR_TYPE_ACCEL>;
+               layout = <7>;
+       };
+       mpu6880_gyro:mpu_gyro@68{
+               compatible = "mpu6880_gyro";
+               reg = <0x68>;
+               //irq-gpio = <&gpio7 GPIO_B0 IRQ_TYPE_LEVEL_LOW>;
+               irq_enable = <0>;
+               poll_delay_ms = <30>;
+               type = <SENSOR_TYPE_GYROSCOPE>;
+               layout = <7>;
+       };
+       */
 };
 
 &i2c1 {
        status = "okay";
-               
        mpu6050:mpu@68{
                compatible = "mpu6050";
                reg = <0x68>;
                irq-gpio = <&gpio8 GPIO_A0 IRQ_TYPE_LEVEL_LOW>;                 
                mpu-debug = <0>;
        };
-       
 
        ak8963:compass@0d{
                compatible = "mpu_ak8963";
index a19ee6e87a8aa36d1dd36d71385498c4a8e04ade..d37e937bf486f21696d951a48ac01775a038c0d0 100755 (executable)
@@ -16,6 +16,13 @@ config GS_MMA8452
        help     
          To have support for your specific gsesnor you will have to
          select the proper drivers which depend on this option.
+         
+config MPU6880_ACC
+  bool "Sensor mpu6880_acc"
+  default y
+       help     
+         To have support for your specific gsesnor you will have to
+         select the proper drivers which depend on this option.
 
 config GS_KXTIK
     bool "gsensor kxtik"
index e8ff359e35b471685852976387b8300e2bcabecc..87dbb03bac96e3589cea4a86d6ff1de7af4f454e 100755 (executable)
@@ -1,9 +1,10 @@
-obj-$(CONFIG_GS_KXTIK)                 += kxtik.o\r
-obj-$(CONFIG_GS_KXTJ9)                 += kxtj9.o\r
-obj-$(CONFIG_GS_MMA8452)       += mma8452.o\r
-obj-$(CONFIG_GS_LIS3DH)        += lis3dh.o\r
+obj-$(CONFIG_GS_KXTIK)                 += kxtik.o
+obj-$(CONFIG_GS_KXTJ9)                 += kxtj9.o
+obj-$(CONFIG_GS_MMA8452)       += mma8452.o
+obj-$(CONFIG_GS_LIS3DH)        += lis3dh.o
 obj-$(CONFIG_GS_MMA7660)       += mma7660.o
-obj-$(CONFIG_GS_MXC6225)    += mxc622x.o\r
-obj-$(CONFIG_GS_DMT10)      += dmard10.o\r
-obj-$(CONFIG_GS_LSM303D)    += lsm303d.o\r
-obj-$(CONFIG_GS_MC3230)    += mc3230.o\r
+obj-$(CONFIG_GS_MXC6225)    += mxc622x.o
+obj-$(CONFIG_GS_DMT10)      += dmard10.o
+obj-$(CONFIG_GS_LSM303D)    += lsm303d.o
+obj-$(CONFIG_GS_MC3230)    += mc3230.o
+obj-$(CONFIG_MPU6880_ACC)   += mpu6880_acc.o
diff --git a/drivers/input/sensors/accel/mpu6880_acc.c b/drivers/input/sensors/accel/mpu6880_acc.c
new file mode 100644 (file)
index 0000000..767ed43
--- /dev/null
@@ -0,0 +1,284 @@
+/* drivers/input/sensors/access/mpu6880_acc.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: oeh<oeh@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>
+#include <linux/mpu6880.h>
+
+
+
+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;
+       u8 pwrm1 = 0;   
+       
+       sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
+       pwrm1 = sensor_read_reg(client, MPU6880_PWR_MGMT_1);
+       //¹Ø±Õ
+       if(!enable)
+       {       
+               status = BIT_ACCEL_STBY;        
+               sensor->ops->ctrl_data |= status;       
+               //gyroºÍacc¶¼²»¹¤×÷ʱ£¬Ä£¿é½øÈëÐÝÃß
+               if(sensor->ops->ctrl_data & (BIT_ACCEL_STBY | BIT_GYRO_STBY) != 0)
+               {
+                       pwrm1 |= MPU6880_PWRM1_SLEEP;
+               }
+       }
+       else//´ò¿ª
+       {
+               status = ~BIT_ACCEL_STBY;       
+               sensor->ops->ctrl_data &= status;
+               pwrm1 &=~MPU6880_PWRM1_SLEEP;
+       }
+       result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
+       if(result)
+       {
+               printk("%s:fail to set pwrm2\n",__func__);
+               return -1;
+       }
+       msleep(20);
+
+       result = sensor_write_reg(client, MPU6880_PWR_MGMT_1,pwrm1);
+       if(result)
+       {
+               printk("%s:fail to set pwrm1\n",__func__);
+               return -1;
+       }
+       msleep(20);
+       
+       return result;
+
+}
+
+static int sensor_init(struct i2c_client *client)
+{
+       int res=0; 
+       u8 read_data = 0;
+       struct sensor_private_data *sensor =
+           (struct sensor_private_data *) i2c_get_clientdata(client);  
+
+       //¼ì²âICÊÇ·ñΪMPU6880
+       read_data = sensor_read_reg(client,sensor->ops->id_reg);
+       if(read_data != sensor->ops->id_data)
+       {
+               printk("%s:check id err,read_data:%d,ops->id_data:%d\n",__func__,read_data,sensor->ops->id_data);
+               return -1;
+       }
+       
+       //¼Ä´æÆ÷³õʼ»¯
+       res = sensor_write_reg(client, MPU6880_PWR_MGMT_1,0x80);
+       if (res) 
+       {
+               printk("set MPU6880_PWR_MGMT_1 error,res: %d!\n", res);
+               return res;
+       }
+       msleep(40);
+
+       res = sensor_write_reg(client, MPU6880_GYRO_CONFIG,0x18);  //config gyro for 2000dps
+       if (res) 
+       {
+               printk("set MPU6880_GYRO_CONFIG error,res: %d!\n", res);
+               return res;
+       }
+       msleep(10);
+
+       res = sensor_write_reg(client, MPU6880_ACCEL_CONFIG,0x00);  //config Accel for +_2G
+       if (res) 
+       {
+               printk("set MPU6880_ACCEL_CONFIG error,res: %d!\n", res);
+               return res;
+       }
+       msleep(10);
+
+       res = sensor_write_reg(client, MPU6880_ACCEL_CONFIG2,0x00);
+       if (res) 
+       {
+               printk("set MPU6880_ACCEL_CONFIG2 error,res: %d!\n", res);
+               return res;
+       }
+       res = sensor_write_reg(client, MPU6880_PWR_MGMT_2,0x3F); //set accl and gyro all axis into standby mode
+       if (res) 
+       {
+               printk("set MPU6880_PWR_MGMT_2 error,res: %d!\n", res);
+               return res;
+       }       
+       msleep(10);     
+       res = sensor_write_reg(client, MPU6880_PWR_MGMT_1,0x41);
+       if (res) 
+       {
+               printk("set MPU6880_PWR_MGMT_1 error,res: %d!\n", res);
+               return res;
+       }       
+       msleep(10); 
+
+       //ĬÈϹرÕ
+       res = sensor->ops->active(client,0,0);
+       if(res)
+       {
+               printk("%s:line=%d,error\n",__func__,__LINE__);
+               return res;
+       }
+       return res;
+}
+
+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;
+       short x,y,z;
+       struct sensor_axis axis;
+       u8 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);
+       
+       /* 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);
+
+       x = ((buffer[0] << 8) & 0xff00) + (buffer[1] & 0xFF);
+       y = ((buffer[2] << 8) & 0xff00) + (buffer[3] & 0xFF);
+       z = ((buffer[4] << 8) & 0xff00) + (buffer[5] & 0xFF);
+       
+       printk("mpu6880_acc: x:%d,y:%d,z:%d,-4:%d\n",x,y,z,-4);
+       printk("mpu6880_acc:orientation:\n%d %d %d\n%d %d %d\n%d %d %d\n",pdata->orientation[0],
+               pdata->orientation[1],pdata->orientation[2],pdata->orientation[3],pdata->orientation[4],
+               pdata->orientation[5],pdata->orientation[6],pdata->orientation[7],pdata->orientation[8]);
+       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;
+
+       //ΪÁ˲»ÐÞ¸Ähal²ã´úÂ룬Êý¾Ýת»»ºóÉϱ¨
+       axis.x = 61*axis.x;
+       axis.y = 61*axis.y;
+       axis.z = 61*axis.z;
+       
+       //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_mpu6880_ops = {
+       .name                           = "mpu6880_acc",
+       .type                           = SENSOR_TYPE_ACCEL,                    //sensor type and it should be correct
+       .id_i2c                         = ACCEL_ID_MPU6880,                             //i2c id number
+       .read_reg                       = MPU6880_ACCEL_XOUT_H,         //read data
+       .read_len                       = 6,                                                    //data length
+       .id_reg                         = MPU6880_WHOAMI,                       //read device id from this register
+       .id_data                        = MPU6880_DEVICE_ID,                    //device id
+       .precision                      = MPU6880_PRECISION,                    //16 bit
+       .ctrl_reg                       = MPU6880_PWR_MGMT_2,           //enable or disable     
+       .int_status_reg         = MPU6880_INT_STATUS,                   //intterupt status register
+       .range                          = {-32768*61,32768*61}, //range
+       .trig                           = IRQF_TRIGGER_HIGH |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_mpu6880_ops;
+}
+
+
+static int __init gsensor_mpu6880_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_mpu6880_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_mpu6880_init);
+module_exit(gsensor_mpu6880_exit);
+
+
+
index 43f28a0ece0209ff1dcef675b82802f2c6f907a2..98c1662a61f5c3d209211e257478d1dc71d96bf9 100755 (executable)
@@ -23,4 +23,8 @@ config GYRO_L3G20D
 config GYRO_EWTSA
   bool "gyroscope ewtsa"
        default y
+       
+config GYRO_MPU6880
+  bool "gyroscope mpu6880_gyro"
+       default y
 endif
index 4b2cc01fd4ef8f5a1ffd02e188f41c59fbb5175f..cc50f0a94282da09fdc576ab343c1fc0686f9ca7 100755 (executable)
@@ -3,4 +3,5 @@
 obj-$(CONFIG_GYRO_SENSOR_K3G)  += k3g.o
 obj-$(CONFIG_GYRO_L3G4200D)    += l3g4200d.o
 obj-$(CONFIG_GYRO_L3G20D)      += l3g20d.o
-obj-$(CONFIG_GYRO_EWTSA)       += ewtsa.o
\ No newline at end of file
+obj-$(CONFIG_GYRO_EWTSA)       += ewtsa.o
+obj-$(CONFIG_GYRO_MPU6880)    += mpu6880_gyro.o
\ No newline at end of file
diff --git a/drivers/input/sensors/gyro/mpu6880_gyro.c b/drivers/input/sensors/gyro/mpu6880_gyro.c
new file mode 100644 (file)
index 0000000..4a94b4c
--- /dev/null
@@ -0,0 +1,187 @@
+/* drivers/input/sensors/access/mpu6880_gyro.c
+ *
+ * Copyright (C) 2012-2015 ROCKCHIP.
+ * Author: ouenhui <oeh@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>
+#include <linux/mpu6880.h>
+
+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);
+
+       if(!enable)
+       {       
+               status = BIT_GYRO_STBY; 
+               sensor->ops->ctrl_data |= status;       
+       }
+       else
+       {
+               status = ~BIT_GYRO_STBY;        
+               sensor->ops->ctrl_data &= status;
+       }
+
+       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)
+{
+       int ret;
+       struct sensor_private_data *sensor =
+           (struct sensor_private_data *) i2c_get_clientdata(client);  
+       //ÒѾ­ÔÚmpu6880_accÖгõʼ»¯¼Ä´æÆ÷
+       ret = sensor->ops->active(client,0,0);
+       if(ret)
+       {
+               printk("%s:line=%d,error\n",__func__,__LINE__);
+               return ret;
+       }       
+       return ret;
+}
+
+static int gyro_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_rel(sensor->input_dev, ABS_RX, axis->x);
+       input_report_rel(sensor->input_dev, ABS_RY, axis->y);
+       input_report_rel(sensor->input_dev, ABS_RZ, axis->z);
+       input_sync(sensor->input_dev);
+       DBG("Gsensor x==%d  y==%d z==%d\n",axis->x,axis->y,axis->z);
+
+       return 0;
+}
+
+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;
+       short x,y,z;
+       struct sensor_axis axis;
+       u8 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);
+       
+       do {
+               *buffer = sensor->ops->read_reg;
+               ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
+               if (ret < 0)
+               return ret;
+       } while (0);
+
+       x = ((buffer[0] << 8) & 0xFF00) + (buffer[1] & 0xFF);
+       y = ((buffer[2] << 8) & 0xFF00) + (buffer[3] & 0xFF);
+       z = ((buffer[4] << 8) & 0xFF00) + (buffer[5] & 0xFF);
+       //printk("mpu6880_gyro: x:%d,y:%d,z:%d\n",x,y,z);
+       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;
+
+       gyro_report_value(client, &axis);
+
+       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 gyro_mpu6880_ops = {
+       .name                           = "mpu6880_gyro",
+       .type                           = SENSOR_TYPE_GYROSCOPE,                        //sensor type and it should be correct
+       .id_i2c                         = GYRO_ID_MPU6880,                              //i2c id number
+       .read_reg                       = MPU6880_GYRO_XOUT_H,          //read data
+       .read_len                       = 6,                                                    //data length
+       .id_reg                         = SENSOR_UNKNOW_DATA,                   //read device id from this register
+       .id_data                        = SENSOR_UNKNOW_DATA,                   //device id
+       .precision                      = MPU6880_PRECISION,                    //16 bit
+       .ctrl_reg                       = MPU6880_PWR_MGMT_2,           //enable or disable     
+       .int_status_reg         = MPU6880_INT_STATUS,                   //intterupt status register
+       .range                          = {-MPU6880_RANGE,MPU6880_RANGE},       //range
+       .trig                           = IRQF_TRIGGER_HIGH |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 *gyro_get_ops(void)
+{
+       return &gyro_mpu6880_ops;
+}
+
+
+static int __init gyro_mpu6880_init(void)
+{
+       struct sensor_operate *ops = gyro_get_ops();
+       int result = 0;
+       int type = ops->type;
+       result = sensor_register_slave(type, NULL, NULL, gyro_get_ops); 
+       return result;
+}
+
+static void __exit gyro_mpu6880_exit(void)
+{
+       struct sensor_operate *ops = gyro_get_ops();
+       int type = ops->type;
+       sensor_unregister_slave(type, NULL, NULL, gyro_get_ops);
+}
+
+//ºóÓÚmpu6880_acc×¢²á
+device_initcall_sync(gyro_mpu6880_init);
+module_exit(gyro_mpu6880_exit);
+
+
+
index 960d44f2ee030f35f7579bb2f0784d0694f53d73..252cb0269a3eb67850192046e24b8aca088cbf67 100755 (executable)
@@ -2098,6 +2098,7 @@ static const struct i2c_device_id sensor_id[] = {
        {"gs_dmard10", ACCEL_ID_DMARD10},\r
        {"gs_lsm303d", ACCEL_ID_LSM303D},\r
        {"gs_mc3230",ACCEL_ID_MC3230},\r
+       {"mpu6880_acc",ACCEL_ID_MPU6880},\r
        /*compass*/\r
        {"compass", COMPASS_ID_ALL},\r
        {"ak8975", COMPASS_ID_AK8975},  \r
@@ -2110,6 +2111,7 @@ static const struct i2c_device_id sensor_id[] = {
        {"l3g20d_gyro", GYRO_ID_L3G20D},\r
        {"ewtsa_gyro", GYRO_ID_EWTSA},\r
        {"k3g", GYRO_ID_K3G},\r
+       {"mpu6880_gyro",GYRO_ID_MPU6880},\r
        /*light sensor*/\r
        {"lightsensor", LIGHT_ID_ALL},  \r
        {"light_cm3217", LIGHT_ID_CM3217},\r
diff --git a/include/linux/mpu6880.h b/include/linux/mpu6880.h
new file mode 100644 (file)
index 0000000..4e4e602
--- /dev/null
@@ -0,0 +1,238 @@
+/*
+ * Definitions for mma8452 compass chip.
+ */
+#ifndef __MPU6880_H
+#define __MPU6880_H
+
+#include <linux/ioctl.h>
+/**add***/
+#define MPU6880_PRECISION              16
+#define MPU6880_RANGE                  2000000
+
+#define MPU6880_SMPLRT_DIV             0x19
+#define MPU6880_CONFIG                         0x1A
+#define MPU6880_GYRO_CONFIG            0x1B
+#define MPU6880_ACCEL_CONFIG   0x1C
+#define MPU6880_ACCEL_CONFIG2  0x1D
+#define MPU6880_LP_ACCEL_ODR   0x1E
+#define MPU6880_WOM_THRESH     0x1F
+#define MPU6880_FIFO_EN                        0x23
+#define MPU6880_INT_PIN_CFG            0x37
+#define MPU6880_INT_ENABLE             0x38
+#define MPU6880_DMP_INT_STATUS 0x39
+#define MPU6880_INT_STATUS             0x3A
+#define MPU6880_ACCEL_XOUT_H   0x3B
+#define MPU6880_TEMP_OUT_H     0x41
+#define MPU6880_GYRO_XOUT_H    0x43
+#define MPU6880_ACCEL_INTEL_CTRL 0x69
+#define MPU6880_USER_CTRL              0x6A
+#define MPU6880_PWR_MGMT_1             0x6B
+#define MPU6880_PWR_MGMT_2             0x6C
+#define MPU6880_PRGM_STRT_ADDRH     0x70
+#define MPU6880_FIFO_COUNTH            0x72
+#define MPU6880_FIFO_R_W               0x74
+#define MPU6880_WHOAMI                 0x75
+
+#define MPU6880_DEVICE_ID              0x78
+/*------------------------------
+       MPU6880_CONFIG
+--------------------------------*/
+#define DLPF_CFG_250HZ         0x00
+#define DLPF_CFG_184HZ         0x01
+#define DLPF_CFG_98HZ          0x02
+#define DLPF_CFG_41HZ          0x03
+#define DLPF_CFG_20HZ          0x04
+#define DLPF_CFG_10HZ          0x05
+#define DLPF_CFG_5HZ           0x06
+#define DLPF_CFG_3600HZ                0x07
+#define EXT_SYNC_SET_TEMP      0x08
+#define EXT_SYNC_SET_GYRO_X    0x10
+#define EXT_SYNC_SET_GYRO_Y    0x18
+#define EXT_SYNC_SET_GYRO_Z    0x20
+#define EXT_SYNC_SET_ACCEL_X   0x28
+#define EXT_SYNC_SET_ACCEL_Y   0x30
+#define EXT_SYNC_SET_ACCEL_Z   0x38
+
+
+/*------------------------------
+       MPU6880_GYRO_CONFIG
+--------------------------------*/
+#define GFSR_250DPS                    (0 <<3)
+#define GFSR_500DPS                    (1 <<3)
+#define GFSR_1000DPS           (2 <<3)
+#define GFSR_2000DPS           (3 <<3)
+
+/*------------------------------
+       MPU6880_ACCEL_CONFIG
+--------------------------------*/
+#define AFSR_2G                (0 <<3)
+#define AFSR_4G                (1 <<3)
+#define AFSR_8G                (2 <<3)
+#define AFSR_16G       (3 <<3)
+
+
+/*------------------------------
+       MPU6880_ACCEL_CONFIG2
+--------------------------------*/
+#define A_DLPF_CFG_460HZ               0x00
+#define A_DLPF_CFG_184HZ               0x01
+#define A_DLPF_CFG_92HZ                0x02
+#define A_DLPF_CFG_41HZ                0x03
+#define A_DLPF_CFG_20HZ                0x04
+#define A_DLPF_CFG_10HZ                0x05
+#define A_DLPF_CFG_5HZ                 0x06
+//#define A_DLPF_CFG_460HZ      0x07
+#define BIT_FIFO_SIZE_1K                 0x40
+#define BIT_ACCEL_FCHOICE_B            0x08
+
+
+/*------------------------------
+       MPU6880_LP_ACCEL_ODR
+--------------------------------*/
+#define LPA_CLK_P24HZ  0x0
+#define LPA_CLK_P49HZ  0x1
+#define LPA_CLK_P98HZ  0x2
+#define LPA_CLK_1P95HZ 0x3
+#define LPA_CLK_3P91HZ 0x4
+#define LPA_CLK_7P81HZ 0x5
+#define LPA_CLK_15P63HZ        0x6
+#define LPA_CLK_31P25HZ        0x7
+#define LPA_CLK_62P50HZ        0x8
+#define LPA_CLK_125HZ  0x9
+#define LPA_CLK_250HZ  0xa
+#define LPA_CLK_500HZ  0xb
+
+
+/*------------------------------
+       MPU6880_PWR_MGMT_1
+--------------------------------*/
+#define BIT_H_RESET                    (1<<7)
+#define BIT_SLEEP                      (1<<6)
+#define BIT_CYCLE                      (1<<5)
+#define BIT_GYRO_STANDBY       (1<<4)
+#define BIT_PD_PTAT                    (1<<3)
+#define BIT_CLKSEL                     (1<<0)
+
+#define CLKSEL_INTERNAL                0
+#define CLKSEL_PLL                     1
+
+/*------------------------------
+       MPU6880_PWR_MGMT_2
+--------------------------------*/
+#define BIT_ACCEL_STBY              0x38
+#define BIT_GYRO_STBY               0x07
+#define BITS_LPA_WAKE_CTRL 0xC0
+#define BITS_LPA_WAKE_1HZ 0x00
+#define BITS_LPA_WAKE_2HZ 0x40
+#define BITS_LPA_WAKE_20HZ 0x80
+
+#define MPU6880_PWRM1_SLEEP                            0x40
+#define MPU6880_PWRM1_GYRO_STANDBY             0x10
+#define MPU6880_PWRM2_ACCEL_DISABLE            0x38
+#define MPU6880_PWRM2_GYRO_DISABLE             0x07
+
+/*------------------------------
+       MPU6880_ACCEL_INTEL_CTRL
+--------------------------------*/
+#define BIT_ACCEL_INTEL_EN     0x80
+#define BIT_ACCEL_INTEL_MODE   0x40
+
+
+/*------------------------------
+       MPU6880_USER_CTRL
+--------------------------------*/
+#define BIT_FIFO_RST                    0x04
+#define BIT_DMP_RST                     0x08
+#define BIT_I2C_MST_EN                  0x20
+#define BIT_FIFO_EN                     0x40
+#define BIT_DMP_EN                      0x80
+
+
+/*------------------------------
+       MPU6880_FIFO_EN
+--------------------------------*/
+#define BIT_ACCEL_OUT           0x08
+#define BITS_GYRO_OUT           0x70
+
+
+/*------------------------------
+       MPU6880_INT_PIN_CFG
+--------------------------------*/
+#define BIT_BYPASS_EN           0x2
+
+/*------------------------------
+       MPU6880_INT_EN/INT_STATUS
+--------------------------------*/
+#define BIT_FIFO_OVERLOW       0x80
+#define BIT_MOT_INT                            0x40
+#define BIT_MPU_RDY                 0x04
+#define BIT_DMP_INT                 0x02
+#define BIT_RAW_RDY                 0x01
+
+
+#define DMP_START_ADDR           0x400
+
+
+
+#define AXIS_NUM 3
+#define AXIS_ADC_BYTE 2
+#define SENSOR_PACKET (AXIS_NUM * AXIS_ADC_BYTE)
+
+
+
+
+
+/*
+       self-test parameter
+*/
+
+#define DEF_ST_PRECISION            1000
+#define DEF_ST_MPU6500_ACCEL_LPF        2
+#define DEF_STABLE_TIME_ST 50
+#define DEF_SELFTEST_GYRO_FS            (0 << 3)
+#define DEF_SELFTEST_ACCEL_FS           (2 << 3)
+#define DEF_SELFTEST_6500_ACCEL_FS      (0 << 3)
+#define DEF_SW_SELFTEST_GYRO_FS        GFSR_2000DPS
+#define DEF_SW_SELFTEST_SENSITIVITY    \
+       (2000*DEF_ST_PRECISION)/32768
+
+#define DEF_SW_SELFTEST_SAMPLE_COUNT 75
+#define DEF_SW_SELFTEST_SAMPLE_TIME 75
+#define DEF_SW_ACCEL_CAL_SAMPLE_TIME 50
+#define DEF_SW_SKIP_COUNT 10
+
+#define DEF_ST_6500_STABLE_TIME         20
+#define BYTES_PER_SENSOR        (6)
+#define DEF_SELFTEST_SAMPLE_RATE             0
+#define DEF_GYRO_WAIT_TIME          50
+#define THREE_AXIS              (3)
+#define INIT_ST_SAMPLES          200
+#define FIFO_COUNT_BYTE         (2)
+#define DEF_ST_TRY_TIMES            2
+#define REG_6500_XG_ST_DATA     0x0
+#define REG_6500_XA_ST_DATA     0xD
+#define BITS_SELF_TEST_EN              0xE0
+
+#define DEF_ST_SCALE                    (1L << 15)
+
+/*---- MPU6500 Self Test Pass/Fail Criteria ----*/
+/* Gyro Offset Max Value (dps) */
+#define DEF_GYRO_OFFSET_MAX             20
+/* Gyro Self Test Absolute Limits ST_AL (dps) */
+#define DEF_GYRO_ST_AL                  60
+/* Accel Self Test Absolute Limits ST_AL (mg) */
+#define DEF_ACCEL_ST_AL_MIN             225
+#define DEF_ACCEL_ST_AL_MAX             675
+#define DEF_6500_ACCEL_ST_SHIFT_DELTA   500
+#define DEF_6500_GYRO_CT_SHIFT_DELTA    500
+#define DEF_ST_MPU6500_ACCEL_LPF        2
+#define DEF_ST_6500_ACCEL_FS_MG         2000UL
+#define DEF_SELFTEST_6500_ACCEL_FS      (0 << 3)
+
+#define DEF_SELFTEST_GYRO_SENS          (32768 / 250)
+
+
+#define  GSENSOR_DEV_PATH    "/dev/mma8452_daemon"
+
+#endif
+
index 16e916fcec48d108edc085f530cbc1fbe8412fb4..c10c76045a3bc10bd6a6ab303c445f67f8faa171 100755 (executable)
@@ -55,7 +55,7 @@ enum sensor_id {
        ACCEL_ID_DMARD10,\r
        ACCEL_ID_LSM303D,\r
        ACCEL_ID_MC3230,\r
-\r
+       ACCEL_ID_MPU6880,\r
        COMPASS_ID_ALL,\r
        COMPASS_ID_AK8975,\r
        COMPASS_ID_AK8963,\r
@@ -77,7 +77,7 @@ enum sensor_id {
     GYRO_ID_L3G20D,\r
        GYRO_ID_EWTSA,\r
        GYRO_ID_K3G,\r
-\r
+       GYRO_ID_MPU6880,\r
        LIGHT_ID_ALL,\r
        LIGHT_ID_CM3217,\r
        LIGHT_ID_CM3218,\r