1 /* MPU6050 motion sensor driver
3 * This software is licensed under the terms of the GNU General Public
4 * License version 2, as published by the Free Software Foundation, and
5 * may be copied, distributed, and modified under those terms.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
14 #include <linux/interrupt.h>
15 #include <linux/i2c.h>
16 #include <linux/slab.h>
17 #include <linux/irq.h>
18 #include <linux/miscdevice.h>
19 #include <asm/uaccess.h>
20 #include <linux/delay.h>
21 #include <linux/input.h>
22 #include <linux/workqueue.h>
23 #include <linux/kobject.h>
24 #include <linux/earlysuspend.h>
25 #include <linux/platform_device.h>
26 #include <asm/atomic.h>
29 #include <linux/hwmsensor.h>
30 #include <linux/hwmsen_dev.h>
31 #include <linux/sensors_io.h>
33 #include <linux/hwmsen_helper.h>
35 #include <mach/mt_typedefs.h>
36 #include <mach/mt_gpio.h>
37 #include <mach/mt_pm_ldo.h>
39 #define POWER_NONE_MACRO MT65XX_POWER_NONE
41 /*----------------------------------------------------------------------------*/
43 /*----------------------------------------------------------------------------*/
44 #define CONFIG_MPU6050_LOWPASS /*apply low pass filter on output*/
45 #define SW_CALIBRATION
46 /*----------------------------------------------------------------------------*/
47 #define MPU6050_AXIS_X 0
48 #define MPU6050_AXIS_Y 1
49 #define MPU6050_AXIS_Z 2
50 #define MPU6050_AXES_NUM 3
51 #define MPU6050_DATA_LEN 6
52 #define MPU6050_DEV_NAME "MPU6050G" /* name must different with gyro mpu6050 */
53 /*----------------------------------------------------------------------------*/
54 static const struct i2c_device_id mpu6050_i2c_id
[] = {{MPU6050_DEV_NAME
,0},{}};
55 static struct i2c_board_info __initdata i2c_mpu6050
={ I2C_BOARD_INFO(MPU6050_DEV_NAME
, (MPU6050_I2C_SLAVE_ADDR
>>1))};
57 /*----------------------------------------------------------------------------*/
58 static int mpu6050_i2c_probe(struct i2c_client
*client
, const struct i2c_device_id
*id
);
59 static int mpu6050_i2c_remove(struct i2c_client
*client
);
60 static int mpu6050_i2c_detect(struct i2c_client
*client
, struct i2c_board_info
*info
);
61 #ifndef CONFIG_HAS_EARLYSUSPEND
62 static int mpu6050_suspend(struct i2c_client
*client
, pm_message_t msg
) ;
63 static int mpu6050_resume(struct i2c_client
*client
);
65 /*----------------------------------------------------------------------------*/
68 MPU6050_TRC_FILTER
= 0x01,
69 MPU6050_TRC_RAWDATA
= 0x02,
70 MPU6050_TRC_IOCTL
= 0x04,
71 MPU6050_TRC_CALI
= 0X08,
72 MPU6050_TRC_INFO
= 0X10,
74 /*----------------------------------------------------------------------------*/
80 /*----------------------------------------------------------------------------*/
81 struct data_resolution
83 struct scale_factor scalefactor
;
86 /*----------------------------------------------------------------------------*/
87 #define C_MAX_FIR_LENGTH (32)
88 /*----------------------------------------------------------------------------*/
91 s16 raw
[C_MAX_FIR_LENGTH
][MPU6050_AXES_NUM
];
92 int sum
[MPU6050_AXES_NUM
];
96 /*----------------------------------------------------------------------------*/
97 struct mpu6050_i2c_data
99 struct i2c_client
*client
;
101 struct hwmsen_convert cvt
;
104 struct data_resolution
*reso
;
109 s16 cali_sw
[MPU6050_AXES_NUM
+1];
112 s8 offset
[MPU6050_AXES_NUM
+1]; /*+1: for 4-byte alignment*/
113 s16 data
[MPU6050_AXES_NUM
+1];
115 #if defined(CONFIG_MPU6050_LOWPASS)
118 struct data_filter fir
;
121 #if defined(CONFIG_HAS_EARLYSUSPEND)
122 struct early_suspend early_drv
;
126 /*----------------------------------------------------------------------------*/
127 static struct i2c_driver mpu6050_i2c_driver
= {
129 .name
= MPU6050_DEV_NAME
,
131 .probe
= mpu6050_i2c_probe
,
132 .remove
= mpu6050_i2c_remove
,
133 .detect
= mpu6050_i2c_detect
,
134 #if !defined(CONFIG_HAS_EARLYSUSPEND)
135 .suspend
= mpu6050_suspend
,
136 .resume
= mpu6050_resume
,
138 .id_table
= mpu6050_i2c_id
,
141 /*----------------------------------------------------------------------------*/
142 static struct i2c_client
*mpu6050_i2c_client
= NULL
;
143 static struct platform_driver mpu6050_gsensor_driver
;
144 static struct mpu6050_i2c_data
*obj_i2c_data
= NULL
;
145 static bool sensor_power
= false;
146 static GSENSOR_VECTOR3D gsensor_gain
;
147 static char selftestRes
[8]= {0};
150 /*----------------------------------------------------------------------------*/
151 #define GSE_TAG "[Gsensor] "
152 #define GSE_FUN(f) printk(GSE_TAG"%s\n", __FUNCTION__)
153 #define GSE_ERR(fmt, args...) printk(GSE_TAG"%s %d : "fmt, __FUNCTION__, __LINE__, ##args)
154 #define GSE_LOG(fmt, args...) printk(GSE_TAG fmt, ##args)
155 /*----------------------------------------------------------------------------*/
156 static struct data_resolution mpu6050_data_resolution
[] = {
157 /*8 combination by {FULL_RES,RANGE}*/
158 {{ 0, 6}, 16384}, /*+/-2g in 16-bit resolution: 0.06 mg/LSB*/
159 {{ 0, 12}, 8192}, /*+/-4g in 16-bit resolution: 0.12 mg/LSB*/
160 {{ 0, 24}, 4096}, /*+/-8g in 16-bit resolution: 0.24 mg/LSB*/
161 {{ 0, 5}, 2048}, /*+/-16g in 16-bit resolution: 0.49 mg/LSB*/
163 /*----------------------------------------------------------------------------*/
164 static struct data_resolution mpu6050_offset_resolution
= {{ 0, 5}, 2048};
166 static unsigned int power_on
= 0;
168 extern int MPU6050_gyro_power(void);
169 extern int MPU6050_gyro_mode(void);
172 int MPU6050_gse_power( void)
176 EXPORT_SYMBOL(MPU6050_gse_power
);
178 int MPU6050_gse_mode(void)
182 EXPORT_SYMBOL(MPU6050_gse_mode
);
185 int MPU6050_i2c_master_send(u8
*buf
, u8 len
)
188 if (NULL
== mpu6050_i2c_client
)
190 GSE_ERR("MPU6050_i2c_master_send null ptr!!\n");
194 res
= i2c_master_send(mpu6050_i2c_client
, buf
, len
);
199 EXPORT_SYMBOL(MPU6050_i2c_master_send
);
201 int MPU6050_i2c_master_recv(u8
*buf
, u8 len
)
204 if (NULL
== mpu6050_i2c_client
)
206 GSE_ERR("MPU6050_i2c_master_recv null ptr!!\n");
210 res
= i2c_master_recv(mpu6050_i2c_client
, buf
, len
);
215 EXPORT_SYMBOL(MPU6050_i2c_master_recv
);
216 /*----------------------------------------------------------------------------*/
217 static int mpu_i2c_read_block(struct i2c_client
*client
, u8 addr
, u8
*data
, u8 len
){
219 struct i2c_msg msgs
[2] = {
221 .addr
= client
->addr
, .flags
= 0,
222 .len
= 1, .buf
= &beg
225 .addr
= client
->addr
, .flags
= I2C_M_RD
,
226 .len
= len
, .buf
= data
,
233 else if (len
> C_I2C_FIFO_SIZE
) {
234 GSE_ERR(" length %d exceeds %d\n", len
, C_I2C_FIFO_SIZE
);
238 err
= i2c_transfer(client
->adapter
, msgs
, sizeof(msgs
)/sizeof(msgs
[0]));
240 GSE_ERR("i2c_transfer error: (%d %p %d) %d\n",
241 addr
, data
, len
, err
);
249 int MPU6050_hwmsen_read_block(u8 addr
, u8
*buf
, u8 len
)
251 if (NULL
== mpu6050_i2c_client
)
253 GSE_ERR("MPU6050_hwmsen_read_block null ptr!!\n");
254 return MPU6050_ERR_I2C
;
256 return mpu_i2c_read_block(mpu6050_i2c_client
, addr
, buf
, len
);
258 EXPORT_SYMBOL(MPU6050_hwmsen_read_block
);
261 int MPU6050_hwmsen_read_byte(u8 addr
, u8
*buf
)
263 if (NULL
== mpu6050_i2c_client
)
265 GSE_ERR("MPU6050_hwmsen_read_byte null ptr!!\n");
266 return MPU6050_ERR_I2C
;
268 return mpu_i2c_read_block(mpu6050_i2c_client
, addr
, buf
, 1);
270 EXPORT_SYMBOL(MPU6050_hwmsen_read_byte
);
271 /*--------------------mpu6050 power control function----------------------------------*/
272 static void MPU6050_power(struct acc_hw
*hw
, unsigned int on
)
276 if (hw
->power_id
!= POWER_NONE_MACRO
) // have externel LDO
278 GSE_LOG("power %s\n", on
? "on" : "off");
279 if (power_on
== on
) // power status not change
281 GSE_LOG("ignore power control: %d\n", on
);
283 else if (on
) // power on
285 if (!hwPowerOn(hw
->power_id
, hw
->power_vol
, "MPU6050G"))
287 GSE_ERR("power on fails!!\n");
292 if (MPU6050_gyro_power() == false)
294 if (!hwPowerDown(hw
->power_id
, "MPU6050G"))
296 GSE_ERR("power off fail!!\n");
304 /*----------------------------------------------------------------------------*/
305 static int MPU6050_SetPowerMode(struct i2c_client
*client
, bool enable
)
309 //u8 addr = MPU6050_REG_POWER_CTL;
310 struct mpu6050_i2c_data
*obj
= i2c_get_clientdata(client
);
313 if (enable
== sensor_power
)
315 GSE_LOG("Sensor power status is newest!\n");
316 return MPU6050_SUCCESS
;
319 databuf
[0] = MPU6050_REG_POWER_CTL
;
320 res
= i2c_master_send(client
, databuf
, 0x1);
323 return MPU6050_ERR_I2C
;
330 res = i2c_master_recv(client, databuf, 1);
333 return MPU6050_ERR_I2C;
337 databuf
[0] &= ~MPU6050_SLEEP
;
341 if (MPU6050_gyro_mode() == false)
343 databuf
[0] |= MPU6050_SLEEP
;
350 databuf
[1] = databuf
[0];
351 databuf
[0] = MPU6050_REG_POWER_CTL
;
353 res
= i2c_master_send(client
, databuf
, 0x2);
357 GSE_LOG("set power mode failed!\n");
358 return MPU6050_ERR_I2C
;
360 else if (atomic_read(&obj
->trace
) & MPU6050_TRC_INFO
)
362 GSE_LOG("set power mode ok %d!\n", databuf
[1]);
367 sensor_power
= enable
;
368 return MPU6050_SUCCESS
;
370 /*----------------------------------------------------------------------------*/
371 static int MPU6050_SetDataResolution(struct mpu6050_i2c_data
*obj
)
376 if ((err
= mpu_i2c_read_block(obj
->client
, MPU6050_REG_DATA_FORMAT
, &dat
, 1)))
378 GSE_ERR("write data format fail!!\n");
382 /*the data_reso is combined by 3 bits: {FULL_RES, DATA_RANGE}*/
384 reso
= (dat
& MPU6050_RANGE_16G
) >> 3;
386 if (reso
< sizeof(mpu6050_data_resolution
)/sizeof(mpu6050_data_resolution
[0]))
388 obj
->reso
= &mpu6050_data_resolution
[reso
];
396 /*----------------------------------------------------------------------------*/
397 static int MPU6050_ReadData(struct i2c_client
*client
, s16 data
[MPU6050_AXES_NUM
])
399 struct mpu6050_i2c_data
*priv
= i2c_get_clientdata(client
);
400 u8 buf
[MPU6050_DATA_LEN
] = {0};
410 /* write then burst read */
411 mpu_i2c_read_block(client
, MPU6050_REG_DATAX0
, buf
, MPU6050_DATA_LEN
);
413 data
[MPU6050_AXIS_X
] = (s16
)((buf
[MPU6050_AXIS_X
*2] << 8) |
414 (buf
[MPU6050_AXIS_X
*2+1] ));
415 data
[MPU6050_AXIS_Y
] = (s16
)((buf
[MPU6050_AXIS_Y
*2] << 8) |
416 (buf
[MPU6050_AXIS_Y
*2+1] ));
417 data
[MPU6050_AXIS_Z
] = (s16
)((buf
[MPU6050_AXIS_Z
*2] << 8) |
418 (buf
[MPU6050_AXIS_Z
*2+1] ));
420 if (atomic_read(&priv
->trace
) & MPU6050_TRC_RAWDATA
)
422 GSE_LOG("[%08X %08X %08X] => [%5d %5d %5d]\n", data
[MPU6050_AXIS_X
], data
[MPU6050_AXIS_Y
], data
[MPU6050_AXIS_Z
],
423 data
[MPU6050_AXIS_X
], data
[MPU6050_AXIS_Y
], data
[MPU6050_AXIS_Z
]);
425 #ifdef CONFIG_MPU6050_LOWPASS
426 if (atomic_read(&priv
->filter
))
428 if (atomic_read(&priv
->fir_en
) && !atomic_read(&priv
->suspend
))
430 int idx
, firlen
= atomic_read(&priv
->firlen
);
431 if (priv
->fir
.num
< firlen
)
433 priv
->fir
.raw
[priv
->fir
.num
][MPU6050_AXIS_X
] = data
[MPU6050_AXIS_X
];
434 priv
->fir
.raw
[priv
->fir
.num
][MPU6050_AXIS_Y
] = data
[MPU6050_AXIS_Y
];
435 priv
->fir
.raw
[priv
->fir
.num
][MPU6050_AXIS_Z
] = data
[MPU6050_AXIS_Z
];
436 priv
->fir
.sum
[MPU6050_AXIS_X
] += data
[MPU6050_AXIS_X
];
437 priv
->fir
.sum
[MPU6050_AXIS_Y
] += data
[MPU6050_AXIS_Y
];
438 priv
->fir
.sum
[MPU6050_AXIS_Z
] += data
[MPU6050_AXIS_Z
];
439 if (atomic_read(&priv
->trace
) & MPU6050_TRC_FILTER
)
441 GSE_LOG("add [%2d] [%5d %5d %5d] => [%5d %5d %5d]\n", priv
->fir
.num
,
442 priv
->fir
.raw
[priv
->fir
.num
][MPU6050_AXIS_X
], priv
->fir
.raw
[priv
->fir
.num
][MPU6050_AXIS_Y
], priv
->fir
.raw
[priv
->fir
.num
][MPU6050_AXIS_Z
],
443 priv
->fir
.sum
[MPU6050_AXIS_X
], priv
->fir
.sum
[MPU6050_AXIS_Y
], priv
->fir
.sum
[MPU6050_AXIS_Z
]);
450 idx
= priv
->fir
.idx
% firlen
;
451 priv
->fir
.sum
[MPU6050_AXIS_X
] -= priv
->fir
.raw
[idx
][MPU6050_AXIS_X
];
452 priv
->fir
.sum
[MPU6050_AXIS_Y
] -= priv
->fir
.raw
[idx
][MPU6050_AXIS_Y
];
453 priv
->fir
.sum
[MPU6050_AXIS_Z
] -= priv
->fir
.raw
[idx
][MPU6050_AXIS_Z
];
454 priv
->fir
.raw
[idx
][MPU6050_AXIS_X
] = data
[MPU6050_AXIS_X
];
455 priv
->fir
.raw
[idx
][MPU6050_AXIS_Y
] = data
[MPU6050_AXIS_Y
];
456 priv
->fir
.raw
[idx
][MPU6050_AXIS_Z
] = data
[MPU6050_AXIS_Z
];
457 priv
->fir
.sum
[MPU6050_AXIS_X
] += data
[MPU6050_AXIS_X
];
458 priv
->fir
.sum
[MPU6050_AXIS_Y
] += data
[MPU6050_AXIS_Y
];
459 priv
->fir
.sum
[MPU6050_AXIS_Z
] += data
[MPU6050_AXIS_Z
];
461 data
[MPU6050_AXIS_X
] = priv
->fir
.sum
[MPU6050_AXIS_X
]/firlen
;
462 data
[MPU6050_AXIS_Y
] = priv
->fir
.sum
[MPU6050_AXIS_Y
]/firlen
;
463 data
[MPU6050_AXIS_Z
] = priv
->fir
.sum
[MPU6050_AXIS_Z
]/firlen
;
464 if (atomic_read(&priv
->trace
) & MPU6050_TRC_FILTER
)
466 GSE_LOG("add [%2d] [%5d %5d %5d] => [%5d %5d %5d] : [%5d %5d %5d]\n", idx
,
467 priv
->fir
.raw
[idx
][MPU6050_AXIS_X
], priv
->fir
.raw
[idx
][MPU6050_AXIS_Y
], priv
->fir
.raw
[idx
][MPU6050_AXIS_Z
],
468 priv
->fir
.sum
[MPU6050_AXIS_X
], priv
->fir
.sum
[MPU6050_AXIS_Y
], priv
->fir
.sum
[MPU6050_AXIS_Z
],
469 data
[MPU6050_AXIS_X
], data
[MPU6050_AXIS_Y
], data
[MPU6050_AXIS_Z
]);
478 /*----------------------------------------------------------------------------*/
479 static int MPU6050_ReadOffset(struct i2c_client
*client
, s8 ofs
[MPU6050_AXES_NUM
])
482 #ifdef SW_CALIBRATION
483 ofs
[0]=ofs
[1]=ofs
[2]=0x0;
485 if ((err
= mpu_i2c_read_block(client
, MPU6050_REG_OFSX
, ofs
, MPU6050_AXES_NUM
)))
487 GSE_ERR("error: %d\n", err
);
490 //GSE_LOG("offesx=%x, y=%x, z=%x",ofs[0],ofs[1],ofs[2]);
494 /*----------------------------------------------------------------------------*/
495 static int MPU6050_ResetCalibration(struct i2c_client
*client
)
497 struct mpu6050_i2c_data
*obj
= i2c_get_clientdata(client
);
498 #ifndef SW_CALIBRATION
499 s8 ofs
[MPU6050_AXES_NUM
] = {0x00, 0x00, 0x00};
502 #ifdef SW_CALIBRATION
506 if ((err
= hwmsen_write_block(client
, MPU6050_REG_OFSX
, ofs
, MPU6050_AXES_NUM
)))
508 GSE_ERR("error: %d\n", err
);
512 memset(obj
->cali_sw
, 0x00, sizeof(obj
->cali_sw
));
513 memset(obj
->offset
, 0x00, sizeof(obj
->offset
));
517 /*----------------------------------------------------------------------------*/
518 static int MPU6050_ReadCalibration(struct i2c_client
*client
, int dat
[MPU6050_AXES_NUM
])
520 struct mpu6050_i2c_data
*obj
= i2c_get_clientdata(client
);
521 #ifdef SW_CALIBRATION
526 #ifdef SW_CALIBRATION
527 mul
= 0;//only SW Calibration, disable HW Calibration
530 if ((err
= MPU6050_ReadOffset(client
, obj
->offset
)))
532 GSE_ERR("read offset fail, %d\n", err
);
535 mul
= obj
->reso
->sensitivity
/mpu6050_offset_resolution
.sensitivity
;
538 dat
[obj
->cvt
.map
[MPU6050_AXIS_X
]] = obj
->cvt
.sign
[MPU6050_AXIS_X
]*(obj
->offset
[MPU6050_AXIS_X
]*mul
+ obj
->cali_sw
[MPU6050_AXIS_X
]);
539 dat
[obj
->cvt
.map
[MPU6050_AXIS_Y
]] = obj
->cvt
.sign
[MPU6050_AXIS_Y
]*(obj
->offset
[MPU6050_AXIS_Y
]*mul
+ obj
->cali_sw
[MPU6050_AXIS_Y
]);
540 dat
[obj
->cvt
.map
[MPU6050_AXIS_Z
]] = obj
->cvt
.sign
[MPU6050_AXIS_Z
]*(obj
->offset
[MPU6050_AXIS_Z
]*mul
+ obj
->cali_sw
[MPU6050_AXIS_Z
]);
544 /*----------------------------------------------------------------------------*/
545 static int MPU6050_ReadCalibrationEx(struct i2c_client
*client
, int act
[MPU6050_AXES_NUM
], int raw
[MPU6050_AXES_NUM
])
547 /*raw: the raw calibration data; act: the actual calibration data*/
548 struct mpu6050_i2c_data
*obj
= i2c_get_clientdata(client
);
549 #ifdef SW_CALIBRATION
554 #ifdef SW_CALIBRATION
555 mul
= 0;//only SW Calibration, disable HW Calibration
558 if ((err
= MPU6050_ReadOffset(client
, obj
->offset
)))
560 GSE_ERR("read offset fail, %d\n", err
);
563 mul
= obj
->reso
->sensitivity
/mpu6050_offset_resolution
.sensitivity
;
566 raw
[MPU6050_AXIS_X
] = obj
->offset
[MPU6050_AXIS_X
]*mul
+ obj
->cali_sw
[MPU6050_AXIS_X
];
567 raw
[MPU6050_AXIS_Y
] = obj
->offset
[MPU6050_AXIS_Y
]*mul
+ obj
->cali_sw
[MPU6050_AXIS_Y
];
568 raw
[MPU6050_AXIS_Z
] = obj
->offset
[MPU6050_AXIS_Z
]*mul
+ obj
->cali_sw
[MPU6050_AXIS_Z
];
570 act
[obj
->cvt
.map
[MPU6050_AXIS_X
]] = obj
->cvt
.sign
[MPU6050_AXIS_X
]*raw
[MPU6050_AXIS_X
];
571 act
[obj
->cvt
.map
[MPU6050_AXIS_Y
]] = obj
->cvt
.sign
[MPU6050_AXIS_Y
]*raw
[MPU6050_AXIS_Y
];
572 act
[obj
->cvt
.map
[MPU6050_AXIS_Z
]] = obj
->cvt
.sign
[MPU6050_AXIS_Z
]*raw
[MPU6050_AXIS_Z
];
576 /*----------------------------------------------------------------------------*/
577 static int MPU6050_WriteCalibration(struct i2c_client
*client
, int dat
[MPU6050_AXES_NUM
])
579 struct mpu6050_i2c_data
*obj
= i2c_get_clientdata(client
);
581 int cali
[MPU6050_AXES_NUM
], raw
[MPU6050_AXES_NUM
];
582 #ifndef SW_CALIBRATION
583 int lsb
= mpu6050_offset_resolution
.sensitivity
;
584 int divisor
= obj
->reso
->sensitivity
/lsb
;
586 if ((err
= MPU6050_ReadCalibrationEx(client
, cali
, raw
))) /*offset will be updated in obj->offset*/
588 GSE_ERR("read offset fail, %d\n", err
);
592 GSE_LOG("OLDOFF: (%+3d %+3d %+3d): (%+3d %+3d %+3d) / (%+3d %+3d %+3d)\n",
593 raw
[MPU6050_AXIS_X
], raw
[MPU6050_AXIS_Y
], raw
[MPU6050_AXIS_Z
],
594 obj
->offset
[MPU6050_AXIS_X
], obj
->offset
[MPU6050_AXIS_Y
], obj
->offset
[MPU6050_AXIS_Z
],
595 obj
->cali_sw
[MPU6050_AXIS_X
], obj
->cali_sw
[MPU6050_AXIS_Y
], obj
->cali_sw
[MPU6050_AXIS_Z
]);
597 /*calculate the real offset expected by caller*/
598 cali
[MPU6050_AXIS_X
] += dat
[MPU6050_AXIS_X
];
599 cali
[MPU6050_AXIS_Y
] += dat
[MPU6050_AXIS_Y
];
600 cali
[MPU6050_AXIS_Z
] += dat
[MPU6050_AXIS_Z
];
602 GSE_LOG("UPDATE: (%+3d %+3d %+3d)\n",
603 dat
[MPU6050_AXIS_X
], dat
[MPU6050_AXIS_Y
], dat
[MPU6050_AXIS_Z
]);
604 #ifdef SW_CALIBRATION
605 obj
->cali_sw
[MPU6050_AXIS_X
] = obj
->cvt
.sign
[MPU6050_AXIS_X
]*(cali
[obj
->cvt
.map
[MPU6050_AXIS_X
]]);
606 obj
->cali_sw
[MPU6050_AXIS_Y
] = obj
->cvt
.sign
[MPU6050_AXIS_Y
]*(cali
[obj
->cvt
.map
[MPU6050_AXIS_Y
]]);
607 obj
->cali_sw
[MPU6050_AXIS_Z
] = obj
->cvt
.sign
[MPU6050_AXIS_Z
]*(cali
[obj
->cvt
.map
[MPU6050_AXIS_Z
]]);
610 obj
->offset
[MPU6050_AXIS_X
] = (s8
)(obj
->cvt
.sign
[MPU6050_AXIS_X
]*(cali
[obj
->cvt
.map
[MPU6050_AXIS_X
]])/(divisor
));
611 obj
->offset
[MPU6050_AXIS_Y
] = (s8
)(obj
->cvt
.sign
[MPU6050_AXIS_Y
]*(cali
[obj
->cvt
.map
[MPU6050_AXIS_Y
]])/(divisor
));
612 obj
->offset
[MPU6050_AXIS_Z
] = (s8
)(obj
->cvt
.sign
[MPU6050_AXIS_Z
]*(cali
[obj
->cvt
.map
[MPU6050_AXIS_Z
]])/(divisor
));
614 /*convert software calibration using standard calibration*/
615 obj
->cali_sw
[MPU6050_AXIS_X
] = obj
->cvt
.sign
[MPU6050_AXIS_X
]*(cali
[obj
->cvt
.map
[MPU6050_AXIS_X
]])%(divisor
);
616 obj
->cali_sw
[MPU6050_AXIS_Y
] = obj
->cvt
.sign
[MPU6050_AXIS_Y
]*(cali
[obj
->cvt
.map
[MPU6050_AXIS_Y
]])%(divisor
);
617 obj
->cali_sw
[MPU6050_AXIS_Z
] = obj
->cvt
.sign
[MPU6050_AXIS_Z
]*(cali
[obj
->cvt
.map
[MPU6050_AXIS_Z
]])%(divisor
);
619 GSE_LOG("NEWOFF: (%+3d %+3d %+3d): (%+3d %+3d %+3d) / (%+3d %+3d %+3d)\n",
620 obj
->offset
[MPU6050_AXIS_X
]*divisor
+ obj
->cali_sw
[MPU6050_AXIS_X
],
621 obj
->offset
[MPU6050_AXIS_Y
]*divisor
+ obj
->cali_sw
[MPU6050_AXIS_Y
],
622 obj
->offset
[MPU6050_AXIS_Z
]*divisor
+ obj
->cali_sw
[MPU6050_AXIS_Z
],
623 obj
->offset
[MPU6050_AXIS_X
], obj
->offset
[MPU6050_AXIS_Y
], obj
->offset
[MPU6050_AXIS_Z
],
624 obj
->cali_sw
[MPU6050_AXIS_X
], obj
->cali_sw
[MPU6050_AXIS_Y
], obj
->cali_sw
[MPU6050_AXIS_Z
]);
626 if ((err
= hwmsen_write_block(obj
->client
, MPU6050_REG_OFSX
, obj
->offset
, MPU6050_AXES_NUM
)))
628 GSE_ERR("write offset fail: %d\n", err
);
635 /*----------------------------------------------------------------------------*/
636 static int MPU6050_CheckDeviceID(struct i2c_client
*client
)
641 memset(databuf
, 0, sizeof(u8
)*10);
642 databuf
[0] = MPU6050_REG_DEVID
;
644 res
= i2c_master_send(client
, databuf
, 0x1);
647 goto exit_MPU6050_CheckDeviceID
;
653 res
= i2c_master_recv(client
, databuf
, 0x01);
656 goto exit_MPU6050_CheckDeviceID
;
659 GSE_LOG("MPU6050_CheckDeviceID 0x%x\n", databuf
[0]);
661 exit_MPU6050_CheckDeviceID
:
664 return MPU6050_ERR_I2C
;
666 return MPU6050_SUCCESS
;
669 /*----------------------------------------------------------------------------*/
670 static int MPU6050_SetDataFormat(struct i2c_client
*client
, u8 dataformat
)
672 struct mpu6050_i2c_data
*obj
= i2c_get_clientdata(client
);
676 memset(databuf
, 0, sizeof(u8
)*2);
677 databuf
[0] = MPU6050_REG_DATA_FORMAT
;
678 res
= i2c_master_send(client
, databuf
, 0x1);
681 return MPU6050_ERR_I2C
;
687 res
= i2c_master_recv(client
, databuf
, 0x01);
690 return MPU6050_ERR_I2C
;
694 databuf
[1] = databuf
[0] | dataformat
;
695 databuf
[0] = MPU6050_REG_DATA_FORMAT
;
696 res
= i2c_master_send(client
, databuf
, 0x2);
700 return MPU6050_ERR_I2C
;
702 return MPU6050_SetDataResolution(obj
);
704 /*----------------------------------------------------------------------------*/
705 static int MPU6050_SetBWRate(struct i2c_client
*client
, u8 bwrate
)
707 struct mpu6050_i2c_data
*obj
= i2c_get_clientdata(client
);
711 if( (obj
->bandwidth
!= bwrate
) || (atomic_read(&obj
->suspend
)) )
713 memset(databuf
, 0, sizeof(u8
)*10);
716 databuf
[0] = MPU6050_REG_BW_RATE
;
717 res
= i2c_master_send(client
, databuf
, 0x1);
720 return MPU6050_ERR_I2C
;
726 res
= i2c_master_recv(client
, databuf
, 0x01);
729 return MPU6050_ERR_I2C
;
734 databuf
[1] = databuf
[0] | bwrate
;
735 databuf
[0] = MPU6050_REG_BW_RATE
;
737 res
= i2c_master_send(client
, databuf
, 0x2);
741 return MPU6050_ERR_I2C
;
744 obj
->bandwidth
= bwrate
;
747 return MPU6050_SUCCESS
;
750 /*----------------------------------------------------------------------------*/
751 static int MPU6050_Dev_Reset(struct i2c_client
*client
)
756 memset(databuf
, 0, sizeof(u8
)*10);
759 databuf
[0] = MPU6050_REG_POWER_CTL
;
760 res
= i2c_master_send(client
, databuf
, 0x1);
763 return MPU6050_ERR_I2C
;
769 res
= i2c_master_recv(client
, databuf
, 0x01);
772 return MPU6050_ERR_I2C
;
777 databuf
[1] = databuf
[0] | MPU6050_DEV_RESET
;
778 databuf
[0] = MPU6050_REG_POWER_CTL
;
780 res
= i2c_master_send(client
, databuf
, 0x2);
784 return MPU6050_ERR_I2C
;
789 databuf
[0] = MPU6050_REG_POWER_CTL
;
790 res
= i2c_master_send(client
, databuf
, 0x1);
795 res
= i2c_master_recv(client
, databuf
, 0x01);
797 printk("[Gsensor] check reset bit");
799 }while((databuf
[0]&MPU6050_DEV_RESET
) != 0);
802 return MPU6050_SUCCESS
;
806 /*----------------------------------------------------------------------------*/
807 static int MPU6050_Reset(struct i2c_client
*client
)
813 databuf
[1] = 0x7; /* reset gyro, g-sensor, temperature */
814 databuf
[0] = MPU6050_REG_RESET
;
816 res
= i2c_master_send(client
, databuf
, 0x2);
820 return MPU6050_ERR_I2C
;
824 return MPU6050_SUCCESS
;
828 /*----------------------------------------------------------------------------*/
829 static int MPU6050_SetIntEnable(struct i2c_client
*client
, u8 intenable
)
834 memset(databuf
, 0, sizeof(u8
)*2);
835 databuf
[0] = MPU6050_REG_INT_ENABLE
;
836 databuf
[1] = intenable
;
838 res
= i2c_master_send(client
, databuf
, 0x2);
842 return MPU6050_ERR_I2C
;
845 return MPU6050_SUCCESS
;
847 /*----------------------------------------------------------------------------*/
848 static int mpu6050_gpio_config(void)
850 //because we donot use EINT to support low power
851 // config to GPIO input mode + PD
853 //set to GPIO_GSE_1_EINT_PIN
855 mt_set_gpio_mode(GPIO_GSE_1_EINT_PIN, GPIO_GSE_1_EINT_PIN_M_GPIO);
856 mt_set_gpio_dir(GPIO_GSE_1_EINT_PIN, GPIO_DIR_IN);
857 mt_set_gpio_pull_enable(GPIO_GSE_1_EINT_PIN, GPIO_PULL_ENABLE);
858 mt_set_gpio_pull_select(GPIO_GSE_1_EINT_PIN, GPIO_PULL_DOWN);
860 //set to GPIO_GSE_2_EINT_PIN
862 mt_set_gpio_mode(GPIO_GSE_2_EINT_PIN, GPIO_GSE_2_EINT_PIN_M_GPIO);
863 mt_set_gpio_dir(GPIO_GSE_2_EINT_PIN, GPIO_DIR_IN);
864 mt_set_gpio_pull_enable(GPIO_GSE_2_EINT_PIN, GPIO_PULL_ENABLE);
865 mt_set_gpio_pull_select(GPIO_GSE_2_EINT_PIN, GPIO_PULL_DOWN);
870 static int mpu6050_init_client(struct i2c_client
*client
, int reset_cali
)
872 struct mpu6050_i2c_data
*obj
= i2c_get_clientdata(client
);
874 bool sensor_power_org
;
876 mpu6050_gpio_config();
878 sensor_power_org
= sensor_power
;
879 res
= MPU6050_SetPowerMode(client
, true);
880 if (res
!= MPU6050_SUCCESS
)
882 GSE_ERR("set power error\n");
885 res
= MPU6050_CheckDeviceID(client
);
886 if (res
!= MPU6050_SUCCESS
)
888 GSE_ERR("Check ID error\n");
892 res
= MPU6050_SetBWRate(client
, MPU6050_BW_184HZ
);
893 if (res
!= MPU6050_SUCCESS
) //0x2C->BW=100Hz
895 GSE_ERR("set power error\n");
899 res
= MPU6050_SetDataFormat(client
, MPU6050_RANGE_16G
);
900 if (res
!= MPU6050_SUCCESS
) //0x2C->BW=100Hz
902 GSE_ERR("set data format error\n");
906 gsensor_gain
.x
= gsensor_gain
.y
= gsensor_gain
.z
= obj
->reso
->sensitivity
;
908 res
= MPU6050_SetIntEnable(client
, 0x00);//disable INT
909 if (res
!= MPU6050_SUCCESS
)
911 GSE_ERR("mpu6050_SetIntEnable error\n");
917 /*reset calibration only in power on*/
918 res
= MPU6050_ResetCalibration(client
);
919 if (res
!= MPU6050_SUCCESS
)
925 res
= MPU6050_SetPowerMode(client
, sensor_power_org
);
926 if (res
!= MPU6050_SUCCESS
)
928 GSE_ERR("set power error\n");
932 #ifdef CONFIG_MPU6050_LOWPASS
933 memset(&obj
->fir
, 0x00, sizeof(obj
->fir
));
936 return MPU6050_SUCCESS
;
938 /*----------------------------------------------------------------------------*/
939 static int MPU6050_ReadAllReg(struct i2c_client
*client
, char *buf
, int bufsize
)
941 u8 total_len
= 0x5C; //(0x75-0x19);
944 u8 buff
[total_len
+1];
949 if (sensor_power
== FALSE
)
951 err
= MPU6050_SetPowerMode(client
, true);
954 GSE_ERR("Power on mpu6050 error %d!\n", err
);
958 mpu_i2c_read_block(client
, addr
, buff
, total_len
);
960 for ( i
=0; i
<=total_len
; i
++)
962 GSE_LOG("MPU6050 reg=0x%x, data=0x%x \n",(addr
+i
), buff
[i
]);
967 /*----------------------------------------------------------------------------*/
968 static int MPU6050_ReadChipInfo(struct i2c_client
*client
, char *buf
, int bufsize
)
972 memset(databuf
, 0, sizeof(u8
)*10);
974 if ((NULL
== buf
)||(bufsize
<=30))
985 sprintf(buf
, "MPU6050 Chip");
988 /*----------------------------------------------------------------------------*/
989 static int MPU6050_ReadSensorData(struct i2c_client
*client
, char *buf
, int bufsize
)
991 struct mpu6050_i2c_data
*obj
= obj_i2c_data
; //(struct mpu6050_i2c_data*)i2c_get_clientdata(client);
992 int acc
[MPU6050_AXES_NUM
];
994 client
= obj
->client
;
996 if (atomic_read(&obj
->suspend
))
1011 if (sensor_power
== FALSE
)
1013 res
= MPU6050_SetPowerMode(client
, true);
1016 GSE_ERR("Power on mpu6050 error %d!\n", res
);
1020 if ((res
= MPU6050_ReadData(client
, obj
->data
)))
1022 GSE_ERR("I2C error: ret value=%d", res
);
1027 obj
->data
[MPU6050_AXIS_X
] += obj
->cali_sw
[MPU6050_AXIS_X
];
1028 obj
->data
[MPU6050_AXIS_Y
] += obj
->cali_sw
[MPU6050_AXIS_Y
];
1029 obj
->data
[MPU6050_AXIS_Z
] += obj
->cali_sw
[MPU6050_AXIS_Z
];
1031 /*remap coordinate*/
1032 acc
[obj
->cvt
.map
[MPU6050_AXIS_X
]] = obj
->cvt
.sign
[MPU6050_AXIS_X
]*obj
->data
[MPU6050_AXIS_X
];
1033 acc
[obj
->cvt
.map
[MPU6050_AXIS_Y
]] = obj
->cvt
.sign
[MPU6050_AXIS_Y
]*obj
->data
[MPU6050_AXIS_Y
];
1034 acc
[obj
->cvt
.map
[MPU6050_AXIS_Z
]] = obj
->cvt
.sign
[MPU6050_AXIS_Z
]*obj
->data
[MPU6050_AXIS_Z
];
1037 acc
[MPU6050_AXIS_X
] = acc
[MPU6050_AXIS_X
] * GRAVITY_EARTH_1000
/ obj
->reso
->sensitivity
;
1038 acc
[MPU6050_AXIS_Y
] = acc
[MPU6050_AXIS_Y
] * GRAVITY_EARTH_1000
/ obj
->reso
->sensitivity
;
1039 acc
[MPU6050_AXIS_Z
] = acc
[MPU6050_AXIS_Z
] * GRAVITY_EARTH_1000
/ obj
->reso
->sensitivity
;
1041 sprintf(buf
, "%04x %04x %04x", acc
[MPU6050_AXIS_X
], acc
[MPU6050_AXIS_Y
], acc
[MPU6050_AXIS_Z
]);
1042 if (atomic_read(&obj
->trace
) & MPU6050_TRC_IOCTL
)
1044 GSE_LOG("gsensor data: %s!\n", buf
);
1050 /*----------------------------------------------------------------------------*/
1051 static int MPU6050_ReadRawData(struct i2c_client
*client
, char *buf
)
1053 struct mpu6050_i2c_data
*obj
= (struct mpu6050_i2c_data
*)i2c_get_clientdata(client
);
1056 if (!buf
|| !client
)
1062 if (atomic_read(&obj
->suspend
))
1067 if ((res
= MPU6050_ReadData(client
, obj
->data
)))
1069 GSE_ERR("I2C error: ret value=%d", res
);
1074 sprintf(buf
, "%04x %04x %04x", obj
->data
[MPU6050_AXIS_X
],
1075 obj
->data
[MPU6050_AXIS_Y
], obj
->data
[MPU6050_AXIS_Z
]);
1081 /*----------------------------------------------------------------------------*/
1082 static int MPU6050_InitSelfTest(struct i2c_client
*client
)
1087 res
= MPU6050_SetPowerMode(client
, true);
1088 if (res
!= MPU6050_SUCCESS
)
1090 GSE_ERR("set power error\n");
1094 res
= MPU6050_SetBWRate(client
, MPU6050_BW_184HZ
);
1095 if (res
!= MPU6050_SUCCESS
) //0x2C->BW=100Hz
1100 res
= mpu_i2c_read_block(client
, MPU6050_REG_DATA_FORMAT
, &data
, 1);
1102 if (res
!= MPU6050_SUCCESS
)
1107 return MPU6050_SUCCESS
;
1109 /*----------------------------------------------------------------------------*/
1110 static int MPU6050_JudgeTestResult(struct i2c_client
*client
, s32 prv
[MPU6050_AXES_NUM
], s32 nxt
[MPU6050_AXES_NUM
])
1118 struct criteria self
[4][3] = {
1119 {{ 0, 540}, { 0, 540}, { 0, 875}},
1120 {{ 0, 270}, { 0, 270}, { 0, 438}},
1121 {{ 0, 135}, { 0, 135}, { 0, 219}},
1122 {{ 0, 67}, { 0, 67}, { 0, 110}},
1124 struct criteria (*ptr
)[3] = NULL
;
1127 if ((res
= mpu_i2c_read_block(client
, MPU6050_REG_DATA_FORMAT
, &format
, 1)))
1130 format
= format
& MPU6050_RANGE_16G
;
1134 case MPU6050_RANGE_2G
:
1135 GSE_LOG("format use self[0]\n");
1139 case MPU6050_RANGE_4G
:
1140 GSE_LOG("format use self[1]\n");
1144 case MPU6050_RANGE_8G
:
1145 GSE_LOG("format use self[2]\n");
1149 case MPU6050_RANGE_16G
:
1150 GSE_LOG("format use self[3]\n");
1155 GSE_LOG("format unknow use \n");
1161 GSE_ERR("null pointer\n");
1164 GSE_LOG("format=0x%x\n",format
);
1166 GSE_LOG("X diff is %ld\n",abs(nxt
[MPU6050_AXIS_X
] - prv
[MPU6050_AXIS_X
]));
1167 GSE_LOG("Y diff is %ld\n",abs(nxt
[MPU6050_AXIS_Y
] - prv
[MPU6050_AXIS_Y
]));
1168 GSE_LOG("Z diff is %ld\n",abs(nxt
[MPU6050_AXIS_Z
] - prv
[MPU6050_AXIS_Z
]));
1171 if ((abs(nxt
[MPU6050_AXIS_X
] - prv
[MPU6050_AXIS_X
]) > (*ptr
)[MPU6050_AXIS_X
].max
) ||
1172 (abs(nxt
[MPU6050_AXIS_X
] - prv
[MPU6050_AXIS_X
]) < (*ptr
)[MPU6050_AXIS_X
].min
))
1174 GSE_ERR("X is over range\n");
1177 if ((abs(nxt
[MPU6050_AXIS_Y
] - prv
[MPU6050_AXIS_Y
]) > (*ptr
)[MPU6050_AXIS_Y
].max
) ||
1178 (abs(nxt
[MPU6050_AXIS_Y
] - prv
[MPU6050_AXIS_Y
]) < (*ptr
)[MPU6050_AXIS_Y
].min
))
1180 GSE_ERR("Y is over range\n");
1183 if ((abs(nxt
[MPU6050_AXIS_Z
] - prv
[MPU6050_AXIS_Z
]) > (*ptr
)[MPU6050_AXIS_Z
].max
) ||
1184 (abs(nxt
[MPU6050_AXIS_Z
] - prv
[MPU6050_AXIS_Z
]) < (*ptr
)[MPU6050_AXIS_Z
].min
))
1186 GSE_ERR("Z is over range\n");
1191 /*----------------------------------------------------------------------------*/
1192 static ssize_t
show_chipinfo_value(struct device_driver
*ddri
, char *buf
)
1194 struct i2c_client
*client
= mpu6050_i2c_client
;
1195 char strbuf
[MPU6050_BUFSIZE
];
1198 GSE_ERR("i2c client is null!!\n");
1202 if (sensor_power
== false)
1204 MPU6050_SetPowerMode(client
, true);
1207 MPU6050_ReadAllReg(client
, strbuf
, MPU6050_BUFSIZE
);
1209 MPU6050_ReadChipInfo(client
, strbuf
, MPU6050_BUFSIZE
);
1210 return snprintf(buf
, PAGE_SIZE
, "%s\n", strbuf
);
1212 /*----------------------------------------------------------------------------*/
1213 static ssize_t
show_sensordata_value(struct device_driver
*ddri
, char *buf
)
1215 struct i2c_client
*client
= mpu6050_i2c_client
;
1216 char strbuf
[MPU6050_BUFSIZE
];
1220 GSE_ERR("i2c client is null!!\n");
1223 MPU6050_ReadSensorData(client
, strbuf
, MPU6050_BUFSIZE
);
1224 return snprintf(buf
, PAGE_SIZE
, "%s\n", strbuf
);
1226 /*----------------------------------------------------------------------------*/
1227 static ssize_t
show_cali_value(struct device_driver
*ddri
, char *buf
)
1229 struct i2c_client
*client
= mpu6050_i2c_client
;
1230 struct mpu6050_i2c_data
*obj
;
1231 int err
, len
= 0, mul
;
1232 int tmp
[MPU6050_AXES_NUM
];
1236 GSE_ERR("i2c client is null!!\n");
1240 obj
= i2c_get_clientdata(client
);
1243 if ((err
= MPU6050_ReadOffset(client
, obj
->offset
)))
1247 else if ((err
= MPU6050_ReadCalibration(client
, tmp
)))
1253 mul
= obj
->reso
->sensitivity
/mpu6050_offset_resolution
.sensitivity
;
1254 len
+= snprintf(buf
+len
, PAGE_SIZE
-len
, "[HW ][%d] (%+3d, %+3d, %+3d) : (0x%02X, 0x%02X, 0x%02X)\n", mul
,
1255 obj
->offset
[MPU6050_AXIS_X
], obj
->offset
[MPU6050_AXIS_Y
], obj
->offset
[MPU6050_AXIS_Z
],
1256 obj
->offset
[MPU6050_AXIS_X
], obj
->offset
[MPU6050_AXIS_Y
], obj
->offset
[MPU6050_AXIS_Z
]);
1257 len
+= snprintf(buf
+len
, PAGE_SIZE
-len
, "[SW ][%d] (%+3d, %+3d, %+3d)\n", 1,
1258 obj
->cali_sw
[MPU6050_AXIS_X
], obj
->cali_sw
[MPU6050_AXIS_Y
], obj
->cali_sw
[MPU6050_AXIS_Z
]);
1260 len
+= snprintf(buf
+len
, PAGE_SIZE
-len
, "[ALL] (%+3d, %+3d, %+3d) : (%+3d, %+3d, %+3d)\n",
1261 obj
->offset
[MPU6050_AXIS_X
]*mul
+ obj
->cali_sw
[MPU6050_AXIS_X
],
1262 obj
->offset
[MPU6050_AXIS_Y
]*mul
+ obj
->cali_sw
[MPU6050_AXIS_Y
],
1263 obj
->offset
[MPU6050_AXIS_Z
]*mul
+ obj
->cali_sw
[MPU6050_AXIS_Z
],
1264 tmp
[MPU6050_AXIS_X
], tmp
[MPU6050_AXIS_Y
], tmp
[MPU6050_AXIS_Z
]);
1269 /*----------------------------------------------------------------------------*/
1270 static ssize_t
store_cali_value(struct device_driver
*ddri
, const char *buf
, size_t count
)
1272 struct i2c_client
*client
= mpu6050_i2c_client
;
1274 int dat
[MPU6050_AXES_NUM
];
1276 if (!strncmp(buf
, "rst", 3))
1278 if ((err
= MPU6050_ResetCalibration(client
)))
1280 GSE_ERR("reset offset err = %d\n", err
);
1283 else if (3 == sscanf(buf
, "0x%02X 0x%02X 0x%02X", &x
, &y
, &z
))
1285 dat
[MPU6050_AXIS_X
] = x
;
1286 dat
[MPU6050_AXIS_Y
] = y
;
1287 dat
[MPU6050_AXIS_Z
] = z
;
1288 if ((err
= MPU6050_WriteCalibration(client
, dat
)))
1290 GSE_ERR("write calibration err = %d\n", err
);
1295 GSE_ERR("invalid format\n");
1300 /*----------------------------------------------------------------------------*/
1301 static ssize_t
show_self_value(struct device_driver
*ddri
, char *buf
)
1303 struct i2c_client
*client
= mpu6050_i2c_client
;
1307 GSE_ERR("i2c client is null!!\n");
1311 return snprintf(buf
, 8, "%s\n", selftestRes
);
1313 /*----------------------------------------------------------------------------*/
1314 static ssize_t
store_self_value(struct device_driver
*ddri
, const char *buf
, size_t count
)
1315 { /*write anything to this register will trigger the process*/
1318 s16 raw
[MPU6050_AXES_NUM
];
1321 struct i2c_client
*client
= mpu6050_i2c_client
;
1323 struct item
*prv
= NULL
, *nxt
= NULL
;
1324 s32 avg_prv
[MPU6050_AXES_NUM
] = {0, 0, 0};
1325 s32 avg_nxt
[MPU6050_AXES_NUM
] = {0, 0, 0};
1328 if (1 != sscanf(buf
, "%d", &num
))
1330 GSE_ERR("parse number fail\n");
1335 GSE_ERR("invalid data count\n");
1339 prv
= kzalloc(sizeof(*prv
) * num
, GFP_KERNEL
);
1340 nxt
= kzalloc(sizeof(*nxt
) * num
, GFP_KERNEL
);
1347 GSE_LOG("NORMAL:\n");
1348 MPU6050_SetPowerMode(client
,true);
1350 for (idx
= 0; idx
< num
; idx
++)
1352 if ((res
= MPU6050_ReadData(client
, prv
[idx
].raw
)))
1354 GSE_ERR("read data fail: %d\n", res
);
1358 avg_prv
[MPU6050_AXIS_X
] += prv
[idx
].raw
[MPU6050_AXIS_X
];
1359 avg_prv
[MPU6050_AXIS_Y
] += prv
[idx
].raw
[MPU6050_AXIS_Y
];
1360 avg_prv
[MPU6050_AXIS_Z
] += prv
[idx
].raw
[MPU6050_AXIS_Z
];
1361 GSE_LOG("[%5d %5d %5d]\n", prv
[idx
].raw
[MPU6050_AXIS_X
], prv
[idx
].raw
[MPU6050_AXIS_Y
], prv
[idx
].raw
[MPU6050_AXIS_Z
]);
1364 avg_prv
[MPU6050_AXIS_X
] /= num
;
1365 avg_prv
[MPU6050_AXIS_Y
] /= num
;
1366 avg_prv
[MPU6050_AXIS_Z
] /= num
;
1368 /*initial setting for self test*/
1369 GSE_LOG("SELFTEST:\n");
1370 for (idx
= 0; idx
< num
; idx
++)
1372 if ((res
= MPU6050_ReadData(client
, nxt
[idx
].raw
)))
1374 GSE_ERR("read data fail: %d\n", res
);
1377 avg_nxt
[MPU6050_AXIS_X
] += nxt
[idx
].raw
[MPU6050_AXIS_X
];
1378 avg_nxt
[MPU6050_AXIS_Y
] += nxt
[idx
].raw
[MPU6050_AXIS_Y
];
1379 avg_nxt
[MPU6050_AXIS_Z
] += nxt
[idx
].raw
[MPU6050_AXIS_Z
];
1380 GSE_LOG("[%5d %5d %5d]\n", nxt
[idx
].raw
[MPU6050_AXIS_X
], nxt
[idx
].raw
[MPU6050_AXIS_Y
], nxt
[idx
].raw
[MPU6050_AXIS_Z
]);
1383 avg_nxt
[MPU6050_AXIS_X
] /= num
;
1384 avg_nxt
[MPU6050_AXIS_Y
] /= num
;
1385 avg_nxt
[MPU6050_AXIS_Z
] /= num
;
1387 GSE_LOG("X: %5d - %5d = %5d \n", avg_nxt
[MPU6050_AXIS_X
], avg_prv
[MPU6050_AXIS_X
], avg_nxt
[MPU6050_AXIS_X
] - avg_prv
[MPU6050_AXIS_X
]);
1388 GSE_LOG("Y: %5d - %5d = %5d \n", avg_nxt
[MPU6050_AXIS_Y
], avg_prv
[MPU6050_AXIS_Y
], avg_nxt
[MPU6050_AXIS_Y
] - avg_prv
[MPU6050_AXIS_Y
]);
1389 GSE_LOG("Z: %5d - %5d = %5d \n", avg_nxt
[MPU6050_AXIS_Z
], avg_prv
[MPU6050_AXIS_Z
], avg_nxt
[MPU6050_AXIS_Z
] - avg_prv
[MPU6050_AXIS_Z
]);
1391 if (!MPU6050_JudgeTestResult(client
, avg_prv
, avg_nxt
))
1393 GSE_LOG("SELFTEST : PASS\n");
1394 strcpy(selftestRes
,"y");
1398 GSE_LOG("SELFTEST : FAIL\n");
1399 strcpy(selftestRes
,"n");
1403 /*restore the setting*/
1404 mpu6050_init_client(client
, 0);
1409 /*----------------------------------------------------------------------------*/
1410 static ssize_t
show_selftest_value(struct device_driver
*ddri
, char *buf
)
1412 struct i2c_client
*client
= mpu6050_i2c_client
;
1413 struct mpu6050_i2c_data
*obj
;
1417 GSE_ERR("i2c client is null!!\n");
1421 obj
= i2c_get_clientdata(client
);
1422 return snprintf(buf
, PAGE_SIZE
, "%d\n", atomic_read(&obj
->selftest
));
1424 /*----------------------------------------------------------------------------*/
1425 static ssize_t
store_selftest_value(struct device_driver
*ddri
, const char *buf
, size_t count
)
1427 struct mpu6050_i2c_data
*obj
= obj_i2c_data
;
1432 GSE_ERR("i2c data obj is null!!\n");
1437 if (1 == sscanf(buf
, "%d", &tmp
))
1439 if (atomic_read(&obj
->selftest
) && !tmp
)
1441 /*enable -> disable*/
1442 mpu6050_init_client(obj
->client
, 0);
1444 else if (!atomic_read(&obj
->selftest
) && tmp
)
1446 /*disable -> enable*/
1447 MPU6050_InitSelfTest(obj
->client
);
1450 GSE_LOG("selftest: %d => %d\n", atomic_read(&obj
->selftest
), tmp
);
1451 atomic_set(&obj
->selftest
, tmp
);
1455 GSE_ERR("invalid content: '%s', length = %d\n", buf
, count
);
1459 /*----------------------------------------------------------------------------*/
1460 static ssize_t
show_firlen_value(struct device_driver
*ddri
, char *buf
)
1462 #ifdef CONFIG_MPU6050_LOWPASS
1463 struct i2c_client
*client
= mpu6050_i2c_client
;
1464 struct mpu6050_i2c_data
*obj
= i2c_get_clientdata(client
);
1465 if (atomic_read(&obj
->firlen
))
1467 int idx
, len
= atomic_read(&obj
->firlen
);
1468 GSE_LOG("len = %2d, idx = %2d\n", obj
->fir
.num
, obj
->fir
.idx
);
1470 for (idx
= 0; idx
< len
; idx
++)
1472 GSE_LOG("[%5d %5d %5d]\n", obj
->fir
.raw
[idx
][MPU6050_AXIS_X
], obj
->fir
.raw
[idx
][MPU6050_AXIS_Y
], obj
->fir
.raw
[idx
][MPU6050_AXIS_Z
]);
1475 GSE_LOG("sum = [%5d %5d %5d]\n", obj
->fir
.sum
[MPU6050_AXIS_X
], obj
->fir
.sum
[MPU6050_AXIS_Y
], obj
->fir
.sum
[MPU6050_AXIS_Z
]);
1476 GSE_LOG("avg = [%5d %5d %5d]\n", obj
->fir
.sum
[MPU6050_AXIS_X
]/len
, obj
->fir
.sum
[MPU6050_AXIS_Y
]/len
, obj
->fir
.sum
[MPU6050_AXIS_Z
]/len
);
1478 return snprintf(buf
, PAGE_SIZE
, "%d\n", atomic_read(&obj
->firlen
));
1480 return snprintf(buf
, PAGE_SIZE
, "not support\n");
1483 /*----------------------------------------------------------------------------*/
1484 static ssize_t
store_firlen_value(struct device_driver
*ddri
, const char *buf
, size_t count
)
1486 #ifdef CONFIG_MPU6050_LOWPASS
1487 struct i2c_client
*client
= mpu6050_i2c_client
;
1488 struct mpu6050_i2c_data
*obj
= i2c_get_clientdata(client
);
1491 if (1 != sscanf(buf
, "%d", &firlen
))
1493 GSE_ERR("invallid format\n");
1495 else if (firlen
> C_MAX_FIR_LENGTH
)
1497 GSE_ERR("exceeds maximum filter length\n");
1501 atomic_set(&obj
->firlen
, firlen
);
1504 atomic_set(&obj
->fir_en
, 0);
1508 memset(&obj
->fir
, 0x00, sizeof(obj
->fir
));
1509 atomic_set(&obj
->fir_en
, 1);
1515 /*----------------------------------------------------------------------------*/
1516 static ssize_t
show_trace_value(struct device_driver
*ddri
, char *buf
)
1519 struct mpu6050_i2c_data
*obj
= obj_i2c_data
;
1522 GSE_ERR("i2c_data obj is null!!\n");
1526 res
= snprintf(buf
, PAGE_SIZE
, "0x%04X\n", atomic_read(&obj
->trace
));
1529 /*----------------------------------------------------------------------------*/
1530 static ssize_t
store_trace_value(struct device_driver
*ddri
, const char *buf
, size_t count
)
1532 struct mpu6050_i2c_data
*obj
= obj_i2c_data
;
1536 GSE_ERR("i2c_data obj is null!!\n");
1540 if (1 == sscanf(buf
, "0x%x", &trace
))
1542 atomic_set(&obj
->trace
, trace
);
1546 GSE_ERR("invalid content: '%s', length = %d\n", buf
, count
);
1551 /*----------------------------------------------------------------------------*/
1552 static ssize_t
show_status_value(struct device_driver
*ddri
, char *buf
)
1555 struct mpu6050_i2c_data
*obj
= obj_i2c_data
;
1558 GSE_ERR("i2c_data obj is null!!\n");
1564 len
+= snprintf(buf
+len
, PAGE_SIZE
-len
, "CUST: %d %d (%d %d)\n",
1565 obj
->hw
->i2c_num
, obj
->hw
->direction
, obj
->hw
->power_id
, obj
->hw
->power_vol
);
1569 len
+= snprintf(buf
+len
, PAGE_SIZE
-len
, "CUST: NULL\n");
1573 /*----------------------------------------------------------------------------*/
1574 static DRIVER_ATTR(chipinfo
, S_IRUGO
, show_chipinfo_value
, NULL
);
1575 static DRIVER_ATTR(sensordata
, S_IRUGO
, show_sensordata_value
, NULL
);
1576 static DRIVER_ATTR(cali
, S_IWUSR
| S_IRUGO
, show_cali_value
, store_cali_value
);
1577 static DRIVER_ATTR(self
, S_IWUSR
| S_IRUGO
, show_selftest_value
, store_selftest_value
);
1578 static DRIVER_ATTR(selftest
, S_IWUSR
| S_IRUGO
, show_self_value
, store_self_value
);
1579 static DRIVER_ATTR(firlen
, S_IWUSR
| S_IRUGO
, show_firlen_value
, store_firlen_value
);
1580 static DRIVER_ATTR(trace
, S_IWUSR
| S_IRUGO
, show_trace_value
, store_trace_value
);
1581 static DRIVER_ATTR(status
, S_IRUGO
, show_status_value
, NULL
);
1582 /*----------------------------------------------------------------------------*/
1583 static struct driver_attribute
*mpu6050_attr_list
[] = {
1584 &driver_attr_chipinfo
, /*chip information*/
1585 &driver_attr_sensordata
, /*dump sensor data*/
1586 &driver_attr_cali
, /*show calibration data*/
1587 &driver_attr_self
, /*self test demo*/
1588 &driver_attr_selftest
, /*self control: 0: disable, 1: enable*/
1589 &driver_attr_firlen
, /*filter length: 0: disable, others: enable*/
1590 &driver_attr_trace
, /*trace log*/
1591 &driver_attr_status
,
1593 /*----------------------------------------------------------------------------*/
1594 static int mpu6050_create_attr(struct device_driver
*driver
)
1597 int num
= (int)(sizeof(mpu6050_attr_list
)/sizeof(mpu6050_attr_list
[0]));
1603 for (idx
= 0; idx
< num
; idx
++)
1605 if (0 != (err
= driver_create_file(driver
, mpu6050_attr_list
[idx
])))
1607 GSE_ERR("driver_create_file (%s) = %d\n", mpu6050_attr_list
[idx
]->attr
.name
, err
);
1613 /*----------------------------------------------------------------------------*/
1614 static int mpu6050_delete_attr(struct device_driver
*driver
)
1617 int num
= (int)(sizeof(mpu6050_attr_list
)/sizeof(mpu6050_attr_list
[0]));
1624 for (idx
= 0; idx
< num
; idx
++)
1626 driver_remove_file(driver
, mpu6050_attr_list
[idx
]);
1632 /*----------------------------------------------------------------------------*/
1633 int gsensor_operate(void* self
, uint32_t command
, void* buff_in
, int size_in
,
1634 void* buff_out
, int size_out
, int* actualout
)
1637 int value
, sample_delay
;
1638 struct mpu6050_i2c_data
*priv
= (struct mpu6050_i2c_data
*)self
;
1639 hwm_sensor_data
* gsensor_data
;
1640 char buff
[MPU6050_BUFSIZE
];
1646 if ((buff_in
== NULL
) || (size_in
< sizeof(int)))
1648 GSE_ERR("Set delay parameter error!\n");
1653 value
= *(int *)buff_in
;
1657 sample_delay
= MPU6050_BW_184HZ
;
1659 else if(value
<= 10)
1661 sample_delay
= MPU6050_BW_94HZ
;
1665 sample_delay
= MPU6050_BW_44HZ
;
1667 GSE_LOG("Set delay parameter value:%d \n", value
);
1670 err
= MPU6050_SetBWRate(priv
->client
, sample_delay
);
1671 if (err
!= MPU6050_SUCCESS
) //0x2C->BW=100Hz
1673 GSE_ERR("Set delay parameter error!\n");
1678 atomic_set(&priv
->filter
, 0);
1682 #if defined(CONFIG_MPU6050_LOWPASS)
1685 priv
->fir
.sum
[MPU6050_AXIS_X
] = 0;
1686 priv
->fir
.sum
[MPU6050_AXIS_Y
] = 0;
1687 priv
->fir
.sum
[MPU6050_AXIS_Z
] = 0;
1689 atomic_set(&priv
->filter
, 1);
1695 if ((buff_in
== NULL
) || (size_in
< sizeof(int)))
1697 GSE_ERR("Enable sensor parameter error!\n");
1702 value
= *(int *)buff_in
;
1703 if (((value
== 0) && (sensor_power
== false)) ||((value
== 1) && (sensor_power
== true)))
1705 GSE_LOG("Gsensor device have updated!\n");
1709 err
= MPU6050_SetPowerMode( priv
->client
, !sensor_power
);
1714 case SENSOR_GET_DATA
:
1715 if ((buff_out
== NULL
) || (size_out
< sizeof(hwm_sensor_data
)))
1717 GSE_ERR("get sensor data parameter error!\n");
1722 gsensor_data
= (hwm_sensor_data
*)buff_out
;
1723 err
= MPU6050_ReadSensorData(priv
->client
, buff
, MPU6050_BUFSIZE
);
1726 sscanf(buff
, "%x %x %x", &gsensor_data
->values
[0],
1727 &gsensor_data
->values
[1], &gsensor_data
->values
[2]);
1728 gsensor_data
->status
= SENSOR_STATUS_ACCURACY_MEDIUM
;
1729 gsensor_data
->value_divide
= 1000;
1734 GSE_ERR("gsensor operate function no this parameter %d!\n", command
);
1742 /******************************************************************************
1743 * Function Configuration
1744 ******************************************************************************/
1745 static int mpu6050_open(struct inode
*inode
, struct file
*file
)
1747 file
->private_data
= mpu6050_i2c_client
;
1749 if (file
->private_data
== NULL
)
1751 GSE_ERR("null pointer!!\n");
1754 return nonseekable_open(inode
, file
);
1756 /*----------------------------------------------------------------------------*/
1757 static int mpu6050_release(struct inode
*inode
, struct file
*file
)
1759 file
->private_data
= NULL
;
1762 /*----------------------------------------------------------------------------*/
1763 static long mpu6050_unlocked_ioctl(struct file
*file
, unsigned int cmd
,
1766 struct i2c_client
*client
= (struct i2c_client
*)file
->private_data
;
1767 struct mpu6050_i2c_data
*obj
= (struct mpu6050_i2c_data
*)i2c_get_clientdata(client
);
1768 char strbuf
[MPU6050_BUFSIZE
];
1770 SENSOR_DATA sensor_data
;
1774 if (_IOC_DIR(cmd
) & _IOC_READ
)
1776 err
= !access_ok(VERIFY_WRITE
, (void __user
*)arg
, _IOC_SIZE(cmd
));
1778 else if (_IOC_DIR(cmd
) & _IOC_WRITE
)
1780 err
= !access_ok(VERIFY_READ
, (void __user
*)arg
, _IOC_SIZE(cmd
));
1785 GSE_ERR("access error: %08X, (%2d, %2d)\n", cmd
, _IOC_DIR(cmd
), _IOC_SIZE(cmd
));
1791 case GSENSOR_IOCTL_INIT
:
1792 mpu6050_init_client(client
, 0);
1795 case GSENSOR_IOCTL_READ_CHIPINFO
:
1796 data
= (void __user
*) arg
;
1803 MPU6050_ReadChipInfo(client
, strbuf
, MPU6050_BUFSIZE
);
1804 if (copy_to_user(data
, strbuf
, strlen(strbuf
)+1))
1811 case GSENSOR_IOCTL_READ_SENSORDATA
:
1812 data
= (void __user
*) arg
;
1819 MPU6050_ReadSensorData(client
, strbuf
, MPU6050_BUFSIZE
);
1820 if (copy_to_user(data
, strbuf
, strlen(strbuf
)+1))
1827 case GSENSOR_IOCTL_READ_GAIN
:
1828 data
= (void __user
*) arg
;
1835 if (copy_to_user(data
, &gsensor_gain
, sizeof(GSENSOR_VECTOR3D
)))
1842 case GSENSOR_IOCTL_READ_RAW_DATA
:
1843 data
= (void __user
*) arg
;
1850 if (atomic_read(&obj
->suspend
))
1856 MPU6050_ReadRawData(client
, strbuf
);
1857 if (copy_to_user(data
, strbuf
, strlen(strbuf
)+1))
1865 case GSENSOR_IOCTL_SET_CALI
:
1866 data
= (void __user
*)arg
;
1872 if (copy_from_user(&sensor_data
, data
, sizeof(sensor_data
)))
1877 if (atomic_read(&obj
->suspend
))
1879 GSE_ERR("Perform calibration in suspend state!!\n");
1884 cali
[MPU6050_AXIS_X
] = sensor_data
.x
* obj
->reso
->sensitivity
/ GRAVITY_EARTH_1000
;
1885 cali
[MPU6050_AXIS_Y
] = sensor_data
.y
* obj
->reso
->sensitivity
/ GRAVITY_EARTH_1000
;
1886 cali
[MPU6050_AXIS_Z
] = sensor_data
.z
* obj
->reso
->sensitivity
/ GRAVITY_EARTH_1000
;
1887 err
= MPU6050_WriteCalibration(client
, cali
);
1891 case GSENSOR_IOCTL_CLR_CALI
:
1892 err
= MPU6050_ResetCalibration(client
);
1895 case GSENSOR_IOCTL_GET_CALI
:
1896 data
= (void __user
*)arg
;
1902 if ((err
= MPU6050_ReadCalibration(client
, cali
)))
1907 sensor_data
.x
= cali
[MPU6050_AXIS_X
] * GRAVITY_EARTH_1000
/ obj
->reso
->sensitivity
;
1908 sensor_data
.y
= cali
[MPU6050_AXIS_Y
] * GRAVITY_EARTH_1000
/ obj
->reso
->sensitivity
;
1909 sensor_data
.z
= cali
[MPU6050_AXIS_Z
] * GRAVITY_EARTH_1000
/ obj
->reso
->sensitivity
;
1910 if (copy_to_user(data
, &sensor_data
, sizeof(sensor_data
)))
1919 GSE_ERR("unknown IOCTL: 0x%08x\n", cmd
);
1929 /*----------------------------------------------------------------------------*/
1930 static struct file_operations mpu6050_fops
= {
1931 .open
= mpu6050_open
,
1932 .release
= mpu6050_release
,
1933 .unlocked_ioctl
= mpu6050_unlocked_ioctl
,
1935 /*----------------------------------------------------------------------------*/
1936 static struct miscdevice mpu6050_device
= {
1937 .minor
= MISC_DYNAMIC_MINOR
,
1939 .fops
= &mpu6050_fops
,
1941 /*----------------------------------------------------------------------------*/
1942 #ifndef CONFIG_HAS_EARLYSUSPEND
1943 /*----------------------------------------------------------------------------*/
1944 static int mpu6050_suspend(struct i2c_client
*client
, pm_message_t msg
)
1946 struct mpu6050_i2c_data
*obj
= i2c_get_clientdata(client
);
1950 if (msg
.event
== PM_EVENT_SUSPEND
)
1954 GSE_ERR("null pointer!!\n");
1957 atomic_set(&obj
->suspend
, 1);
1959 if ((err
= MPU6050_SetPowerMode(obj
->client
, false)))
1961 GSE_ERR("write power control fail!!\n");
1964 MPU6050_power(obj
->hw
, 0);
1965 GSE_LOG("mpu6050_suspend ok\n");
1969 /*----------------------------------------------------------------------------*/
1970 static int mpu6050_resume(struct i2c_client
*client
)
1972 struct mpu6050_i2c_data
*obj
= i2c_get_clientdata(client
);
1978 GSE_ERR("null pointer!!\n");
1982 MPU6050_power(obj
->hw
, 1);
1984 if ((err
= mpu6050_init_client(client
, 0)))
1986 GSE_ERR("initialize client fail!!\n");
1989 atomic_set(&obj
->suspend
, 0);
1990 GSE_LOG("mpu6050_resume ok\n");
1994 /*----------------------------------------------------------------------------*/
1995 #else /*CONFIG_HAS_EARLY_SUSPEND is defined*/
1996 /*----------------------------------------------------------------------------*/
1997 static void mpu6050_early_suspend(struct early_suspend
*h
)
1999 struct mpu6050_i2c_data
*obj
= container_of(h
, struct mpu6050_i2c_data
, early_drv
);
2005 GSE_ERR("null pointer!!\n");
2008 atomic_set(&obj
->suspend
, 1);
2010 if ((err
= MPU6050_SetPowerMode(obj
->client
, false)))
2012 GSE_ERR("write power control fail!!\n");
2017 if (MPU6050_gyro_mode() == false)
2019 MPU6050_Dev_Reset(obj->client);
2020 MPU6050_Reset(obj->client);
2026 sensor_power
= false;
2028 MPU6050_power(obj
->hw
, 0);
2030 /*----------------------------------------------------------------------------*/
2031 static void mpu6050_late_resume(struct early_suspend
*h
)
2033 struct mpu6050_i2c_data
*obj
= container_of(h
, struct mpu6050_i2c_data
, early_drv
);
2039 GSE_ERR("null pointer!!\n");
2043 MPU6050_power(obj
->hw
, 1);
2045 if ((err
= mpu6050_init_client(obj
->client
, 0)))
2047 GSE_ERR("initialize client fail!!\n");
2050 atomic_set(&obj
->suspend
, 0);
2052 /*----------------------------------------------------------------------------*/
2053 #endif /*CONFIG_HAS_EARLYSUSPEND*/
2054 /*----------------------------------------------------------------------------*/
2055 static int mpu6050_i2c_detect(struct i2c_client
*client
, struct i2c_board_info
*info
)
2057 strcpy(info
->type
, MPU6050_DEV_NAME
);
2060 /*----------------------------------------------------------------------------*/
2061 static int mpu6050_i2c_probe(struct i2c_client
*client
, const struct i2c_device_id
*id
)
2063 struct i2c_client
*new_client
;
2064 struct mpu6050_i2c_data
*obj
;
2065 struct hwmsen_object sobj
;
2069 if (!(obj
= kzalloc(sizeof(*obj
), GFP_KERNEL
)))
2075 memset(obj
, 0, sizeof(struct mpu6050_i2c_data
));
2077 obj
->hw
= get_cust_acc_hw();
2079 if ((err
= hwmsen_get_convert(obj
->hw
->direction
, &obj
->cvt
)))
2081 GSE_ERR("invalid direction: %d\n", obj
->hw
->direction
);
2086 obj
->client
= client
;
2087 obj
->client
->timing
= 400;
2089 new_client
= obj
->client
;
2090 i2c_set_clientdata(new_client
,obj
);
2092 atomic_set(&obj
->trace
, 0);
2093 atomic_set(&obj
->suspend
, 0);
2095 #ifdef CONFIG_MPU6050_LOWPASS
2096 if (obj
->hw
->firlen
> C_MAX_FIR_LENGTH
)
2098 atomic_set(&obj
->firlen
, C_MAX_FIR_LENGTH
);
2102 atomic_set(&obj
->firlen
, obj
->hw
->firlen
);
2105 if (atomic_read(&obj
->firlen
) > 0)
2107 atomic_set(&obj
->fir_en
, 1);
2112 mpu6050_i2c_client
= new_client
;
2113 MPU6050_Dev_Reset(new_client
);
2114 MPU6050_Reset(new_client
);
2116 if ((err
= mpu6050_init_client(new_client
, 1)))
2118 goto exit_init_failed
;
2122 if ((err
= misc_register(&mpu6050_device
)))
2124 GSE_ERR("mpu6050_device register failed\n");
2125 goto exit_misc_device_register_failed
;
2129 if ((err
= mpu6050_create_attr(&mpu6050_gsensor_driver
.driver
)))
2131 GSE_ERR("create attribute err = %d\n", err
);
2132 goto exit_create_attr_failed
;
2137 sobj
.sensor_operate
= gsensor_operate
;
2138 if ((err
= hwmsen_attach(ID_ACCELEROMETER
, &sobj
)))
2140 GSE_ERR("attach fail = %d\n", err
);
2144 #ifdef CONFIG_HAS_EARLYSUSPEND
2145 obj
->early_drv
.level
= EARLY_SUSPEND_LEVEL_STOP_DRAWING
- 2,
2146 obj
->early_drv
.suspend
= mpu6050_early_suspend
,
2147 obj
->early_drv
.resume
= mpu6050_late_resume
,
2148 register_early_suspend(&obj
->early_drv
);
2151 GSE_LOG("%s: OK\n", __func__
);
2154 exit_create_attr_failed
:
2155 misc_deregister(&mpu6050_device
);
2156 exit_misc_device_register_failed
:
2158 //i2c_detach_client(new_client);
2162 GSE_ERR("%s: err = %d\n", __func__
, err
);
2166 /*----------------------------------------------------------------------------*/
2167 static int mpu6050_i2c_remove(struct i2c_client
*client
)
2171 if ((err
= mpu6050_delete_attr(&mpu6050_gsensor_driver
.driver
)))
2173 GSE_ERR("mpu6050_delete_attr fail: %d\n", err
);
2176 if ((err
= misc_deregister(&mpu6050_device
)))
2178 GSE_ERR("misc_deregister fail: %d\n", err
);
2181 if ((err
= hwmsen_detach(ID_ACCELEROMETER
)))
2183 GSE_ERR("hwmsen_detach fail: %d\n", err
);
2186 mpu6050_i2c_client
= NULL
;
2187 i2c_unregister_device(client
);
2188 kfree(i2c_get_clientdata(client
));
2191 /*----------------------------------------------------------------------------*/
2192 static int mpu6050_probe(struct platform_device
*pdev
)
2194 struct acc_hw
*hw
= get_cust_acc_hw();
2197 MPU6050_power(hw
, 1);
2198 if (i2c_add_driver(&mpu6050_i2c_driver
))
2200 GSE_ERR("add driver error\n");
2205 /*----------------------------------------------------------------------------*/
2206 static int mpu6050_remove(struct platform_device
*pdev
)
2208 struct acc_hw
*hw
= get_cust_acc_hw();
2211 MPU6050_power(hw
, 0);
2212 i2c_del_driver(&mpu6050_i2c_driver
);
2215 /*----------------------------------------------------------------------------*/
2216 static struct platform_driver mpu6050_gsensor_driver
= {
2217 .probe
= mpu6050_probe
,
2218 .remove
= mpu6050_remove
,
2224 /*----------------------------------------------------------------------------*/
2225 static int __init
mpu6050gse_init(void)
2227 struct acc_hw
*hw
= get_cust_acc_hw();
2228 GSE_LOG("%s: i2c_number=%d\n", __func__
,hw
->i2c_num
);
2229 i2c_register_board_info(hw
->i2c_num
, &i2c_mpu6050
, 1);
2230 if (platform_driver_register(&mpu6050_gsensor_driver
))
2232 GSE_ERR("failed to register driver");
2237 /*----------------------------------------------------------------------------*/
2238 static void __exit
mpu6050gse_exit(void)
2241 platform_driver_unregister(&mpu6050_gsensor_driver
);
2243 /*----------------------------------------------------------------------------*/
2244 module_init(mpu6050gse_init
);
2245 module_exit(mpu6050gse_exit
);
2246 /*----------------------------------------------------------------------------*/
2247 MODULE_LICENSE("GPL");
2248 MODULE_DESCRIPTION("MPU6050 gse driver");
2249 MODULE_AUTHOR("Yucong.Xiong@mediatek.com");