2108 lines
62 KiB
C
2108 lines
62 KiB
C
|
/* drivers/hwmon/sc7660.c
|
|||
|
*
|
|||
|
*allwinner platform
|
|||
|
|
|||
|
*
|
|||
|
* 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/module.h>
|
|||
|
#include <linux/init.h>
|
|||
|
#include <linux/i2c.h>
|
|||
|
#include <linux/mutex.h>
|
|||
|
#include <linux/delay.h>
|
|||
|
#include <linux/interrupt.h>
|
|||
|
#include <linux/irq.h>
|
|||
|
#include <linux/hwmon-sysfs.h>
|
|||
|
|
|||
|
#include <linux/err.h>
|
|||
|
#include <linux/hwmon.h>
|
|||
|
#include <linux/fs.h>
|
|||
|
#include <linux/input-polldev.h>
|
|||
|
#include <linux/device.h>
|
|||
|
#include "../init-input.h"
|
|||
|
#include <linux/errno.h>
|
|||
|
#include <linux/fs.h>
|
|||
|
#include <linux/miscdevice.h>
|
|||
|
#include <linux/uaccess.h>
|
|||
|
#include <linux/kernel.h>
|
|||
|
#include <linux/module.h>
|
|||
|
#include <linux/moduleparam.h>
|
|||
|
#include <linux/device.h>
|
|||
|
#include <linux/gpio.h>
|
|||
|
#include <linux/interrupt.h>
|
|||
|
#include <linux/slab.h>
|
|||
|
#include <linux/ioctl.h>
|
|||
|
#include <linux/platform_device.h>
|
|||
|
#include <linux/regulator/consumer.h>
|
|||
|
|
|||
|
#include <linux/hrtimer.h>
|
|||
|
#include <linux/ktime.h>
|
|||
|
//#include <mach/system.h>
|
|||
|
//#include <mach/hardware.h>
|
|||
|
//#undef CONFIG_HAS_EARLYSUSPEND
|
|||
|
#undef CONFIG_PM
|
|||
|
|
|||
|
#ifdef CONFIG_HAS_EARLYSUSPEND
|
|||
|
#include <linux/earlysuspend.h>
|
|||
|
#endif
|
|||
|
|
|||
|
#if defined(CONFIG_HAS_EARLYSUSPEND) || defined(CONFIG_PM)
|
|||
|
#include <linux/pm.h>
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
* Defines
|
|||
|
*/
|
|||
|
#define assert(expr)\
|
|||
|
if (!(expr)) {\
|
|||
|
printk("Assertion failed! %s,%d,%s,%s\n",\
|
|||
|
__FILE__, __LINE__, __func__, #expr);\
|
|||
|
}
|
|||
|
|
|||
|
#define sc7660_DRV_NAME "sc7660"
|
|||
|
#define SENSOR_NAME sc7660_DRV_NAME
|
|||
|
|
|||
|
|
|||
|
#define POLL_INTERVAL_MAX 1000
|
|||
|
#define POLL_INTERVAL 50
|
|||
|
#define INPUT_FUZZ 2
|
|||
|
#define INPUT_FLAT 2
|
|||
|
#define TIANJU_FILTER
|
|||
|
|
|||
|
#define sc7660_REG_CTRL 0x20
|
|||
|
#define sc7660_REG_DATA 0x00
|
|||
|
|
|||
|
/* sc7660 control bit */
|
|||
|
#define sc7660_CTRL_PWRON 0x47 /* power on */
|
|||
|
#define sc7660_CTRL_PWRDN 0x00 /* power donw */
|
|||
|
|
|||
|
|
|||
|
#define MODE_CHANGE_DELAY_MS 100
|
|||
|
|
|||
|
|
|||
|
|
|||
|
#define CALIBRATION_NUM 40
|
|||
|
#define AXIS_X_Y_RANGE_LIMIT 200
|
|||
|
#define AXIS_X_Y_AVG_LIMIT 400
|
|||
|
#define AXIS_Z_RANGE 200
|
|||
|
#define AXIS_Z_DFT_G 1000
|
|||
|
#define GOTO_CALI 100
|
|||
|
#define FAILTO_CALI 101
|
|||
|
|
|||
|
#define SC7660_ENABLE 1
|
|||
|
#define SC7660_XOUT_L 0x28
|
|||
|
#define SC7660_XOUT_H 0x29
|
|||
|
#define SC7660_YOUT_L 0x2A
|
|||
|
#define SC7660_YOUT_H 0x2B
|
|||
|
#define SC7660_ZOUT_L 0x2C
|
|||
|
#define SC7660_ZOUT_H 0x2D
|
|||
|
#define SC7660_MODE 0x20
|
|||
|
#define SC7660_MODE1 0x21
|
|||
|
#define SC7660_MODE2 0x22
|
|||
|
#define SC7660_MODE3 0x23
|
|||
|
#define SC7660_BOOT 0x24
|
|||
|
#define SC7660_STATUS 0x27
|
|||
|
|
|||
|
#define GSENSOR_REG_CALI
|
|||
|
/*
|
|||
|
#ifdef GSENSOR_REG_CALI
|
|||
|
static int reg[29] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, \
|
|||
|
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, \
|
|||
|
0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A};
|
|||
|
static int reg_data[29] = {0};
|
|||
|
#endif
|
|||
|
*/
|
|||
|
|
|||
|
static struct device *hwmon_dev = NULL;
|
|||
|
static struct i2c_client *sc7660_i2c_client = NULL;
|
|||
|
static struct input_polled_dev *sc7660_idev = NULL;
|
|||
|
|
|||
|
struct sc7660_data_s {
|
|||
|
struct i2c_client *client;
|
|||
|
struct input_polled_dev *pollDev;
|
|||
|
struct mutex interval_mutex;
|
|||
|
|
|||
|
struct delayed_work dwork;//allen
|
|||
|
int time_of_cali;
|
|||
|
atomic_t enable;
|
|||
|
|
|||
|
#ifdef CONFIG_HAS_EARLYSUSPEND
|
|||
|
struct early_suspend early_suspend;
|
|||
|
#endif
|
|||
|
#if defined(CONFIG_PM) || defined(CONFIG_HAS_EARLYSUSPEND)
|
|||
|
volatile int suspend_indator;
|
|||
|
#endif
|
|||
|
struct hrtimer hr_timer;
|
|||
|
struct work_struct wq_hrtimer;
|
|||
|
ktime_t ktime;
|
|||
|
|
|||
|
} sc7660_data;
|
|||
|
|
|||
|
/* Addresses to scan */
|
|||
|
static const unsigned short normal_i2c[] = {0x1D,I2C_CLIENT_END};
|
|||
|
static __u32 twi_id = 0;
|
|||
|
static struct sensor_config_info gsensor_info = {
|
|||
|
.input_type = GSENSOR_TYPE,
|
|||
|
};
|
|||
|
|
|||
|
enum {
|
|||
|
DEBUG_INIT = 1U << 0,
|
|||
|
DEBUG_CONTROL_INFO = 1U << 1,
|
|||
|
DEBUG_DATA_INFO = 1U << 2,
|
|||
|
DEBUG_SUSPEND = 1U << 3,
|
|||
|
};
|
|||
|
static u32 debug_mask = 0x0;
|
|||
|
#define dprintk(level_mask, fmt, arg...) if (unlikely(debug_mask & level_mask)) \
|
|||
|
printk(KERN_DEBUG fmt , ## arg)
|
|||
|
|
|||
|
module_param_named(debug_mask, debug_mask, int, S_IRUGO);
|
|||
|
|
|||
|
#ifdef CONFIG_HAS_EARLYSUSPEND
|
|||
|
static void sc7660_early_suspend(struct early_suspend *h);
|
|||
|
static void sc7660_late_resume(struct early_suspend *h);
|
|||
|
#endif
|
|||
|
|
|||
|
static struct workqueue_struct *sc7660_workqueue = NULL;
|
|||
|
|
|||
|
struct SC7660_acc{
|
|||
|
int x;
|
|||
|
int y;
|
|||
|
int z;
|
|||
|
} ;
|
|||
|
|
|||
|
struct Cali_Data {
|
|||
|
//mis p and n
|
|||
|
unsigned char xpmis; //x axis positive mismatch to write
|
|||
|
unsigned char xnmis; //x axis negtive mismatch to write
|
|||
|
unsigned char ypmis;
|
|||
|
unsigned char ynmis;
|
|||
|
unsigned char zpmis;
|
|||
|
unsigned char znmis;
|
|||
|
//off p and n
|
|||
|
unsigned char xpoff; //x axis positive offset to write
|
|||
|
unsigned char xnoff; //x axis negtive offset to write
|
|||
|
unsigned char ypoff;
|
|||
|
unsigned char ynoff;
|
|||
|
unsigned char zpoff;
|
|||
|
unsigned char znoff;
|
|||
|
//mid mis and off
|
|||
|
unsigned char xmmis; //x axis middle mismatch to write
|
|||
|
unsigned char ymmis; //y axis middle mismatch to write
|
|||
|
unsigned char zmmis; //z axis middle mismatch to write
|
|||
|
unsigned char xmoff; //x axis middle offset to write
|
|||
|
unsigned char ymoff; //y axis middle offset to write
|
|||
|
unsigned char zmoff; //z axis middle offset to write
|
|||
|
//output p and n
|
|||
|
signed int xpoutput; //x axis output of positive mismatch
|
|||
|
signed int xnoutput; //x axis output of negtive mismatch
|
|||
|
signed int ypoutput;
|
|||
|
signed int ynoutput;
|
|||
|
signed int zpoutput;
|
|||
|
signed int znoutput;
|
|||
|
//output
|
|||
|
signed int xfoutput; //x axis the best or the temporary output
|
|||
|
signed int yfoutput; //y axis the best or the temporary output
|
|||
|
signed int zfoutput; //z axis the best or the temporary output
|
|||
|
//final and temp flag
|
|||
|
unsigned char xfinalf; //x axis final flag:if 1,calibration finished
|
|||
|
unsigned char yfinalf; //y axis final flag:if 1,calibration finished
|
|||
|
unsigned char zfinalf; //z axis final flag:if 1,calibration finished
|
|||
|
unsigned char xtempf; //x axis temp flag:if 1,the step calibration finished
|
|||
|
unsigned char ytempf; //y axis temp flag:if 1,the step calibration finished
|
|||
|
unsigned char ztempf; //z axis temp flag:if 1,the step calibration finished
|
|||
|
|
|||
|
unsigned char xaddmis; //x axis mismtach register address
|
|||
|
unsigned char yaddmis; //y axis mismtach register address
|
|||
|
unsigned char zaddmis; //z axis mismtach register address
|
|||
|
unsigned char xaddoff; //x axis offset register address
|
|||
|
unsigned char yaddoff; //y axis offset register address
|
|||
|
unsigned char zaddoff; //z axis offset register address
|
|||
|
|
|||
|
|
|||
|
unsigned char (*MisDataSpaceConvert)(unsigned char continuous); //mismatch space convert function pointer
|
|||
|
unsigned char (*OffDataSpaceConvert)(unsigned char continuous); //offset space convert function pointer
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
static int sc7660_acc_get_data( int *xyz);
|
|||
|
static void sc7660_reset(void);
|
|||
|
|
|||
|
static char Read_Reg(unsigned char reg)
|
|||
|
{
|
|||
|
char ret;
|
|||
|
ret = i2c_smbus_read_byte_data(sc7660_i2c_client, reg);
|
|||
|
return ret;
|
|||
|
}
|
|||
|
/*
|
|||
|
static signed char Read_Output(char reg)
|
|||
|
{
|
|||
|
|
|||
|
char ret = 0;
|
|||
|
char acc_buf[6];
|
|||
|
int index = 0;
|
|||
|
|
|||
|
while(1)
|
|||
|
{
|
|||
|
|
|||
|
msleep(15);
|
|||
|
ret = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_STATUS);
|
|||
|
|
|||
|
if( (ret & 0x08) != 0 )
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
index++;
|
|||
|
|
|||
|
if(index > 40)
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
acc_buf[0] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_XOUT_L);
|
|||
|
acc_buf[1] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_XOUT_H);
|
|||
|
|
|||
|
acc_buf[2] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_YOUT_L);
|
|||
|
acc_buf[3] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_YOUT_H);
|
|||
|
|
|||
|
acc_buf[4] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_ZOUT_L);
|
|||
|
acc_buf[5] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_ZOUT_H);
|
|||
|
|
|||
|
if(reg == 0x29)
|
|||
|
{
|
|||
|
return acc_buf[1];
|
|||
|
}
|
|||
|
else if(reg == 0x2b)
|
|||
|
{
|
|||
|
return acc_buf[3];
|
|||
|
}
|
|||
|
else if(reg == 0x2d)
|
|||
|
{
|
|||
|
return acc_buf[5];
|
|||
|
}
|
|||
|
else
|
|||
|
return 0;
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
*/
|
|||
|
static void Read_Output_3axis(unsigned char *acc_buf)
|
|||
|
{
|
|||
|
char buffer[3] = {0};
|
|||
|
int index = 0;
|
|||
|
//int ret = 0;
|
|||
|
while(1){
|
|||
|
msleep(20);
|
|||
|
*buffer = SC7660_STATUS;
|
|||
|
//ret = sensor_rx_data(sc7660_client, buffer,1);
|
|||
|
buffer[0] = Read_Reg(0x27);
|
|||
|
if( (buffer[0] & 0x08) != 0 ){break;}
|
|||
|
index++;
|
|||
|
if(index > 40)break;
|
|||
|
}
|
|||
|
//6 register data be read out
|
|||
|
acc_buf[0] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_XOUT_L);
|
|||
|
acc_buf[1] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_XOUT_H);
|
|||
|
|
|||
|
acc_buf[2] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_YOUT_L);
|
|||
|
acc_buf[3] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_YOUT_H);
|
|||
|
|
|||
|
acc_buf[4] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_ZOUT_L);
|
|||
|
acc_buf[5] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_ZOUT_H);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
static void Write_Input(char addr, char thedata)
|
|||
|
{
|
|||
|
int result;
|
|||
|
//result = sensor_write_reg(sc7660_i2c_client, addr, thedata);
|
|||
|
result = i2c_smbus_write_byte_data(sc7660_i2c_client, addr, thedata);
|
|||
|
}
|
|||
|
|
|||
|
static void tilt_3axis_mtp(signed int x,signed int y,signed int z){
|
|||
|
char buffer[6] = {0};
|
|||
|
unsigned char buffer0[6] = {0};
|
|||
|
unsigned char buffer1[6] = {0};
|
|||
|
signed char mtpread[3]={0};
|
|||
|
signed int xoutp,youtp,zoutp;
|
|||
|
signed int xoutpt,youtpt,zoutpt;
|
|||
|
signed char xtilt,ytilt,ztilt;
|
|||
|
xoutp=youtp=zoutp=0;
|
|||
|
xoutpt=youtpt=zoutpt=0;
|
|||
|
xtilt=ytilt=ztilt=0;
|
|||
|
Read_Output_3axis(buffer0);
|
|||
|
Read_Output_3axis(buffer1);
|
|||
|
|
|||
|
xoutpt = ((signed int)((buffer1[1]<<8)|buffer1[0]))>>4;
|
|||
|
youtpt = ((signed int)((buffer1[3]<<8)|buffer1[2]))>>4;
|
|||
|
zoutpt = ((signed int)((buffer1[5]<<8)|buffer1[4]))>>4;
|
|||
|
|
|||
|
xoutp = xoutpt-x*16;
|
|||
|
youtp = youtpt-y*16;
|
|||
|
zoutp = zoutpt-z*16;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
buffer[0] = Read_Reg(0x10);
|
|||
|
mtpread[0]=(signed char)buffer[0];
|
|||
|
|
|||
|
buffer[0] = Read_Reg(0x11);
|
|||
|
mtpread[1]=(signed char)buffer[0];
|
|||
|
|
|||
|
buffer[0] = Read_Reg(0x12);
|
|||
|
mtpread[2]=(signed char)buffer[0];
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//calculate the new tilt mtp value
|
|||
|
xtilt=(signed char)(xoutp/8)+ mtpread[0];
|
|||
|
ytilt=(signed char)(youtp/8)+ mtpread[1];
|
|||
|
ztilt=(signed char)(zoutp/8)+ mtpread[2];
|
|||
|
|
|||
|
|
|||
|
//write the new into mtp
|
|||
|
Write_Input(0x10,xtilt);
|
|||
|
Write_Input(0x11,ytilt);
|
|||
|
Write_Input(0x12,ztilt);
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
//input:two data
|
|||
|
//0 for not near zero
|
|||
|
//1 for first data
|
|||
|
//2 for second data
|
|||
|
/*
|
|||
|
static char IsNearZero(unsigned int Pos, unsigned int Neg, unsigned char error)
|
|||
|
{
|
|||
|
if(abs(Pos) < error)
|
|||
|
return 1;
|
|||
|
if(abs(Neg) < error)
|
|||
|
return 2;
|
|||
|
return 0;
|
|||
|
}
|
|||
|
*/
|
|||
|
|
|||
|
|
|||
|
/*
|
|||
|
static unsigned char forword_MisDataSpaceConvert(unsigned char continuous)
|
|||
|
{
|
|||
|
if(continuous >= 128)
|
|||
|
return continuous - 128;
|
|||
|
else
|
|||
|
return 255 - continuous;
|
|||
|
}
|
|||
|
*/
|
|||
|
|
|||
|
static unsigned char reverse_MisDataSpaceConvert(unsigned char continuous)
|
|||
|
{
|
|||
|
if(continuous >= 128)
|
|||
|
return continuous;
|
|||
|
else
|
|||
|
return 127 - continuous;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
static unsigned char reverse_OffDataSpaceConvert(unsigned char continuous)
|
|||
|
{
|
|||
|
return 127 - continuous;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
static unsigned char forword_OffDataSpaceConvert(unsigned char continuous)
|
|||
|
{
|
|||
|
return continuous;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//set finalflag xfinalf-yfinalf-zfinalf upto the relative output
|
|||
|
static void check_output_set_finalflag(struct Cali_Data *pcalidata,unsigned char err){
|
|||
|
|
|||
|
if(abs(pcalidata->xfoutput) < err){
|
|||
|
//printk("line:%d Xcali finish!Final=%d\n",__LINE__,pcalidata->xfoutput);
|
|||
|
pcalidata->xfinalf=1;
|
|||
|
}
|
|||
|
if(abs(pcalidata->yfoutput) < err){
|
|||
|
//printk("line:%d Xcali finish!Final=%d\n",__LINE__,pcalidata->yfoutput);
|
|||
|
pcalidata->yfinalf=1;
|
|||
|
}
|
|||
|
if(abs(pcalidata->zfoutput) < err){
|
|||
|
//printk("line:%d Xcali finish!Final=%d\n",__LINE__,pcalidata->zfoutput);
|
|||
|
pcalidata->zfinalf=1;
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
static void check_finalflag_set_tempflag(struct Cali_Data *pcalidata){
|
|||
|
if(pcalidata->xfinalf){pcalidata->xtempf=1;}
|
|||
|
if(pcalidata->yfinalf){pcalidata->ytempf=1;}
|
|||
|
if(pcalidata->zfinalf){pcalidata->ztempf=1;}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static unsigned char check_flag_is_return(struct Cali_Data *pcalidata){
|
|||
|
if((pcalidata->xfinalf) && (pcalidata->yfinalf) && (pcalidata->zfinalf))
|
|||
|
{
|
|||
|
|
|||
|
return 1;
|
|||
|
}
|
|||
|
else return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
static void updata_midmis_address(struct Cali_Data *pcalidata){
|
|||
|
if(pcalidata->xtempf==0){
|
|||
|
pcalidata->xmmis=(unsigned char)(((unsigned int)(pcalidata->xpmis) + (unsigned int)(pcalidata->xnmis))/2);
|
|||
|
pcalidata->MisDataSpaceConvert = reverse_MisDataSpaceConvert;
|
|||
|
Write_Input(pcalidata->xaddmis, (*(pcalidata->MisDataSpaceConvert))(pcalidata->xmmis));
|
|||
|
}
|
|||
|
if(pcalidata->ytempf==0){
|
|||
|
pcalidata->ymmis=(unsigned char)(((unsigned int)(pcalidata->ypmis) + (unsigned int)(pcalidata->ynmis))/2);
|
|||
|
//pcalidata->MisDataSpaceConvert = forword_MisDataSpaceConvert;
|
|||
|
pcalidata->MisDataSpaceConvert = reverse_MisDataSpaceConvert;
|
|||
|
Write_Input(pcalidata->yaddmis, (*(pcalidata->MisDataSpaceConvert))(pcalidata->ymmis));
|
|||
|
}
|
|||
|
if(pcalidata->ztempf==0){
|
|||
|
pcalidata->zmmis=(unsigned char)(((unsigned int)(pcalidata->zpmis) + (unsigned int)(pcalidata->znmis))/2);
|
|||
|
pcalidata->MisDataSpaceConvert = reverse_MisDataSpaceConvert;
|
|||
|
Write_Input(pcalidata->zaddmis, (*(pcalidata->MisDataSpaceConvert))(pcalidata->zmmis));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static void updata_midoff_address(struct Cali_Data *pcalidata){
|
|||
|
if(pcalidata->xtempf==0){
|
|||
|
pcalidata->xmoff=(unsigned char)(((unsigned int)(pcalidata->xpoff) + (unsigned int)(pcalidata->xnoff))/2);
|
|||
|
pcalidata->OffDataSpaceConvert = reverse_OffDataSpaceConvert;
|
|||
|
Write_Input(pcalidata->xaddoff, (*(pcalidata->OffDataSpaceConvert))(pcalidata->xmoff));
|
|||
|
}
|
|||
|
if(pcalidata->ytempf==0){
|
|||
|
pcalidata->ymoff=(unsigned char)(((unsigned int)(pcalidata->ypoff) + (unsigned int)(pcalidata->ynoff))/2);
|
|||
|
//pcalidata->OffDataSpaceConvert = forword_OffDataSpaceConvert;
|
|||
|
pcalidata->OffDataSpaceConvert = reverse_OffDataSpaceConvert;
|
|||
|
Write_Input(pcalidata->yaddoff, (*(pcalidata->OffDataSpaceConvert))(pcalidata->ymoff));
|
|||
|
}
|
|||
|
if(pcalidata->ztempf==0){
|
|||
|
pcalidata->zmoff=(unsigned char)(((unsigned int)(pcalidata->zpoff) + (unsigned int)(pcalidata->znoff))/2);
|
|||
|
pcalidata->OffDataSpaceConvert = forword_OffDataSpaceConvert;
|
|||
|
Write_Input(pcalidata->zaddoff, (*(pcalidata->OffDataSpaceConvert))(pcalidata->zmoff));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
static void updata_mmis_pnfoutput_set_tempflag( struct Cali_Data *pcalidata,
|
|||
|
unsigned char *buf,
|
|||
|
signed int xrel,
|
|||
|
signed int yrel,
|
|||
|
signed int zrel){
|
|||
|
//output 2 struct data
|
|||
|
pcalidata->xfoutput=(signed int)((signed char)buf[1])-xrel;
|
|||
|
pcalidata->yfoutput=(signed int)((signed char)buf[3])-yrel;
|
|||
|
pcalidata->zfoutput=(signed int)((signed char)buf[5])-zrel;
|
|||
|
|
|||
|
if(abs(pcalidata->xfoutput)<25)pcalidata->xtempf=1;
|
|||
|
if(abs(pcalidata->yfoutput)<25)pcalidata->ytempf=1;
|
|||
|
if(abs(pcalidata->zfoutput)<25)pcalidata->ztempf=1;
|
|||
|
|
|||
|
if(pcalidata->xtempf==0)
|
|||
|
{
|
|||
|
if(pcalidata->xfoutput>0){
|
|||
|
pcalidata->xpoutput = pcalidata->xfoutput;
|
|||
|
pcalidata->xpmis = pcalidata->xmmis;
|
|||
|
}
|
|||
|
else{
|
|||
|
pcalidata->xnoutput = pcalidata->xfoutput;
|
|||
|
pcalidata->xnmis = pcalidata->xmmis;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if(pcalidata->ytempf==0)
|
|||
|
{
|
|||
|
if(pcalidata->yfoutput>0){
|
|||
|
pcalidata->ypoutput = pcalidata->yfoutput;
|
|||
|
pcalidata->ypmis = pcalidata->ymmis;
|
|||
|
}
|
|||
|
else{
|
|||
|
pcalidata->ynoutput = pcalidata->yfoutput;
|
|||
|
pcalidata->ynmis = pcalidata->ymmis;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if(pcalidata->ztempf==0)
|
|||
|
{
|
|||
|
if(pcalidata->zfoutput>0){
|
|||
|
pcalidata->zpoutput = pcalidata->zfoutput;
|
|||
|
pcalidata->zpmis = pcalidata->zmmis;
|
|||
|
}
|
|||
|
else{
|
|||
|
pcalidata->znoutput = pcalidata->zfoutput;
|
|||
|
pcalidata->znmis = pcalidata->zmmis;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
static void updata_moff_pnfoutput_set_tempflag( struct Cali_Data *pcalidata,
|
|||
|
unsigned char *buf,
|
|||
|
signed int xrel,
|
|||
|
signed int yrel,
|
|||
|
signed int zrel){
|
|||
|
|
|||
|
pcalidata->xfoutput=(signed int)((signed char)buf[1])-xrel;
|
|||
|
pcalidata->yfoutput=(signed int)((signed char)buf[3])-yrel;
|
|||
|
pcalidata->zfoutput=(signed int)((signed char)buf[5])-zrel;
|
|||
|
|
|||
|
if(abs(pcalidata->xfoutput)<3)pcalidata->xtempf=1;
|
|||
|
if(abs(pcalidata->yfoutput)<3)pcalidata->ytempf=1;
|
|||
|
if(abs(pcalidata->zfoutput)<3)pcalidata->ztempf=1;
|
|||
|
|
|||
|
if(pcalidata->xtempf==0)
|
|||
|
{
|
|||
|
if(pcalidata->xfoutput>0){
|
|||
|
pcalidata->xpoutput = pcalidata->xfoutput;
|
|||
|
pcalidata->xpoff = pcalidata->xmoff;
|
|||
|
}
|
|||
|
else{
|
|||
|
pcalidata->xnoutput = pcalidata->xfoutput;
|
|||
|
pcalidata->xnoff = pcalidata->xmoff;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if(pcalidata->ytempf==0)
|
|||
|
{
|
|||
|
if(pcalidata->yfoutput>0){
|
|||
|
pcalidata->ypoutput = pcalidata->yfoutput;
|
|||
|
pcalidata->ypoff = pcalidata->ymoff;
|
|||
|
}
|
|||
|
else{
|
|||
|
pcalidata->ynoutput = pcalidata->yfoutput;
|
|||
|
pcalidata->ynoff = pcalidata->ymoff;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if(pcalidata->ztempf==0)
|
|||
|
{
|
|||
|
if(pcalidata->zfoutput>0){
|
|||
|
pcalidata->zpoutput = pcalidata->zfoutput;
|
|||
|
pcalidata->zpoff = pcalidata->zmoff;
|
|||
|
}
|
|||
|
else{
|
|||
|
pcalidata->znoutput = pcalidata->zfoutput;
|
|||
|
pcalidata->znoff = pcalidata->zmoff;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
int auto_calibration_instant(signed int x, signed int y, signed int z){
|
|||
|
|
|||
|
|
|||
|
unsigned char count=0,cyclecount=0;
|
|||
|
unsigned char acc_buf[6];
|
|||
|
|
|||
|
struct Cali_Data calidata={0};
|
|||
|
|
|||
|
|
|||
|
calidata.xaddmis = 0x41;//0x40; x and y mismatch addr swap
|
|||
|
calidata.yaddmis = 0x40;//0x41;
|
|||
|
calidata.zaddmis = 0x42;
|
|||
|
calidata.xaddoff = 0x47;
|
|||
|
calidata.yaddoff = 0x48;
|
|||
|
calidata.zaddoff = 0x49;
|
|||
|
#ifdef PRINT
|
|||
|
printf("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
|
|||
|
(UINT)calidata.xfinalf,(UINT)calidata.xtempf,
|
|||
|
(UINT)calidata.yfinalf,(UINT)calidata.ytempf,
|
|||
|
(UINT)calidata.zfinalf,(UINT)calidata.ztempf
|
|||
|
);
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Read_Output_3axis(acc_buf);
|
|||
|
calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
|
|||
|
calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
|
|||
|
calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
|
|||
|
check_output_set_finalflag(&calidata,2);
|
|||
|
if(check_flag_is_return(&calidata)){
|
|||
|
printk("step1:=file=%s,line=%d,calibration ok \n",__FILE__,__LINE__);
|
|||
|
return 1;
|
|||
|
}
|
|||
|
#ifdef PRINT
|
|||
|
printf("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
|
|||
|
(UINT)calidata.xfinalf,(UINT)calidata.xtempf,
|
|||
|
(UINT)calidata.yfinalf,(UINT)calidata.ytempf,
|
|||
|
(UINT)calidata.zfinalf,(UINT)calidata.ztempf
|
|||
|
);
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
if(calidata.xfinalf==0){
|
|||
|
Write_Input(calidata.xaddoff, 0x3f);//cali mis under off=0x3f
|
|||
|
Write_Input(0x10, 0); //tilt clear
|
|||
|
calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
|
|||
|
Write_Input(calidata.xaddmis, (*(calidata.MisDataSpaceConvert))(255)); // x mis to max
|
|||
|
}
|
|||
|
if(calidata.yfinalf==0){
|
|||
|
Write_Input(calidata.yaddoff, 0x3f);//cali mis under off=0x3f
|
|||
|
Write_Input(0x11, 0); //tilt clear
|
|||
|
//calidata.MisDataSpaceConvert = forword_MisDataSpaceConvert;
|
|||
|
calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
|
|||
|
Write_Input(calidata.yaddmis, (*(calidata.MisDataSpaceConvert))(255)); // y mis to max
|
|||
|
}
|
|||
|
if(calidata.zfinalf==0){
|
|||
|
Write_Input(calidata.zaddoff, 0x3f);//cali mis under off=0x3f
|
|||
|
Write_Input(0x12, 0); //tilt clear
|
|||
|
calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
|
|||
|
Write_Input(calidata.zaddmis, (*(calidata.MisDataSpaceConvert))(255)); // z mis to max
|
|||
|
}
|
|||
|
|
|||
|
Read_Output_3axis(acc_buf);
|
|||
|
calidata.xpoutput=calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
|
|||
|
calidata.ypoutput=calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
|
|||
|
calidata.zpoutput=calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
|
|||
|
if((calidata.xpoutput<-25)||(calidata.ypoutput<-25)||(calidata.zpoutput<-25)){
|
|||
|
printk("step2:=file=%s,line=%d calibration failed\n",__FILE__,__LINE__);
|
|||
|
printk("calidata.xpoutput = 0x%4x calidata.ypoutput = 0x%4x calidata.zpoutput = 0x%4x\n",calidata.xpoutput,calidata.ypoutput,calidata.zpoutput);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if(calidata.xfinalf==0){
|
|||
|
calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
|
|||
|
Write_Input(calidata.xaddmis, (*(calidata.MisDataSpaceConvert))(0));
|
|||
|
}
|
|||
|
if(calidata.yfinalf==0){
|
|||
|
//calidata.MisDataSpaceConvert = forword_MisDataSpaceConvert;
|
|||
|
calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
|
|||
|
Write_Input(calidata.yaddmis, (*(calidata.MisDataSpaceConvert))(0));
|
|||
|
}
|
|||
|
if(calidata.zfinalf==0){
|
|||
|
calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
|
|||
|
Write_Input(calidata.zaddmis, (*(calidata.MisDataSpaceConvert))(0));
|
|||
|
}
|
|||
|
Read_Output_3axis(acc_buf);
|
|||
|
calidata.xnoutput=calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
|
|||
|
calidata.ynoutput=calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
|
|||
|
calidata.znoutput=calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
|
|||
|
if((calidata.xnoutput>25)||(calidata.ynoutput>25)||(calidata.znoutput>25)){
|
|||
|
printk("step2:=file=%s,line=%d calibration failed\n",__FILE__,__LINE__);
|
|||
|
printk("calidata.xnoutput = 0x%4x calidata.ynoutput = 0x%4x calidata.znoutput = 0x%4x\n",calidata.xnoutput,calidata.ynoutput,calidata.znoutput);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
if(abs(calidata.xpoutput)<=abs(calidata.xnoutput)){
|
|||
|
calidata.xfoutput=calidata.xpoutput;
|
|||
|
calidata.xmmis=255;
|
|||
|
}
|
|||
|
else{
|
|||
|
calidata.xfoutput=calidata.xnoutput;
|
|||
|
calidata.xmmis=0;
|
|||
|
}
|
|||
|
if(abs(calidata.ypoutput)<=abs(calidata.ynoutput)){
|
|||
|
calidata.yfoutput=calidata.ypoutput;
|
|||
|
calidata.ymmis=255;
|
|||
|
}
|
|||
|
else{
|
|||
|
calidata.yfoutput=calidata.ynoutput;
|
|||
|
calidata.ymmis=0;
|
|||
|
}
|
|||
|
if(abs(calidata.zpoutput)<=abs(calidata.znoutput)){
|
|||
|
calidata.zfoutput=calidata.zpoutput;
|
|||
|
calidata.zmmis=255;
|
|||
|
}
|
|||
|
else{
|
|||
|
calidata.zfoutput=calidata.znoutput;
|
|||
|
calidata.zmmis=0;
|
|||
|
}
|
|||
|
|
|||
|
if(calidata.xfinalf==0){
|
|||
|
calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
|
|||
|
Write_Input(calidata.xaddmis, (*(calidata.MisDataSpaceConvert))(calidata.xmmis));
|
|||
|
}
|
|||
|
if(calidata.yfinalf==0){
|
|||
|
//calidata.MisDataSpaceConvert = forword_MisDataSpaceConvert;
|
|||
|
calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
|
|||
|
Write_Input(calidata.yaddmis, (*(calidata.MisDataSpaceConvert))(calidata.ymmis));
|
|||
|
}
|
|||
|
if(calidata.zfinalf==0){
|
|||
|
calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
|
|||
|
Write_Input(calidata.zaddmis, (*(calidata.MisDataSpaceConvert))(calidata.zmmis));
|
|||
|
}
|
|||
|
check_output_set_finalflag(&calidata,2);
|
|||
|
//if the smaller output <25,the step3 mis is finished
|
|||
|
if(abs(calidata.xfoutput)<25) calidata.xtempf=1;
|
|||
|
if(abs(calidata.yfoutput)<25) calidata.ytempf=1;
|
|||
|
if(abs(calidata.zfoutput)<25) calidata.ztempf=1;
|
|||
|
|
|||
|
calidata.xpmis=calidata.ypmis=calidata.zpmis=255;
|
|||
|
calidata.xnmis=calidata.ynmis=calidata.znmis=0;
|
|||
|
check_finalflag_set_tempflag(&calidata);
|
|||
|
#ifdef PRINT
|
|||
|
printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
|
|||
|
(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
|
|||
|
(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
|
|||
|
(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
|
|||
|
);
|
|||
|
#endif
|
|||
|
cyclecount=0;
|
|||
|
while(1){
|
|||
|
if(++cyclecount>20)break;//if some errs happened,the cyclecount exceeded
|
|||
|
|
|||
|
if((calidata.xtempf)&&(calidata.ytempf)&&(calidata.ztempf))break;
|
|||
|
updata_midmis_address(&calidata);
|
|||
|
Read_Output_3axis(acc_buf);
|
|||
|
calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
|
|||
|
calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
|
|||
|
calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
|
|||
|
#ifdef PRINT
|
|||
|
printk("xp%4d=%4d,xm%4d=%4d,xn%4d=%4d, yp%4d=%4d,ym%4d=%4d,yn%4d=%4d, zp%4d=%4d,zm%4d=%4d,zn%4d=%4d\n\r",
|
|||
|
calidata.xpoutput,(unsigned int)calidata.xpmis,
|
|||
|
calidata.xfoutput,(unsigned int)calidata.xmmis,
|
|||
|
calidata.xnoutput,(unsigned int)calidata.xnmis,
|
|||
|
calidata.ypoutput,(unsigned int)calidata.ypmis,
|
|||
|
calidata.yfoutput,(unsigned int)calidata.ymmis,
|
|||
|
calidata.ynoutput,(unsigned int)calidata.ynmis,
|
|||
|
calidata.zpoutput,(unsigned int)calidata.zpmis,
|
|||
|
calidata.zfoutput,(unsigned int)calidata.zmmis,
|
|||
|
calidata.znoutput,(unsigned int)calidata.znmis
|
|||
|
);
|
|||
|
#endif
|
|||
|
updata_mmis_pnfoutput_set_tempflag(&calidata,acc_buf,x,y,z);
|
|||
|
check_output_set_finalflag(&calidata,2);
|
|||
|
if(check_flag_is_return(&calidata))return 1;
|
|||
|
}
|
|||
|
#ifdef PRINT
|
|||
|
printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
|
|||
|
(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
|
|||
|
(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
|
|||
|
(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
|
|||
|
);
|
|||
|
#endif
|
|||
|
|
|||
|
calidata.xtempf=calidata.ytempf=calidata.ztempf=1;
|
|||
|
if((calidata.xmmis>0)&&(calidata.xmmis<255))calidata.xtempf=0;
|
|||
|
if((calidata.ymmis>0)&&(calidata.ymmis<255))calidata.ytempf=0;
|
|||
|
if((calidata.zmmis>0)&&(calidata.zmmis<255))calidata.ztempf=0;
|
|||
|
calidata.xpmis=calidata.xnmis=calidata.xmmis;
|
|||
|
calidata.ypmis=calidata.ynmis=calidata.ymmis;
|
|||
|
calidata.zpmis=calidata.znmis=calidata.zmmis;
|
|||
|
for(count = 0; count < 3; count++)
|
|||
|
{
|
|||
|
if(calidata.xtempf==0){
|
|||
|
calidata.xpmis = calidata.xmmis + count - 1;
|
|||
|
if((calidata.xpmis>calidata.xmmis)&&(calidata.xpmis==128))calidata.xpmis = calidata.xmmis + count-1 + 1;
|
|||
|
if((calidata.xpmis<calidata.xmmis)&&(calidata.xpmis==127))calidata.xpmis = calidata.xmmis + count-1 - 1;
|
|||
|
calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
|
|||
|
Write_Input(calidata.xaddmis, (*(calidata.MisDataSpaceConvert))(calidata.xpmis));
|
|||
|
}
|
|||
|
if(calidata.ytempf==0){
|
|||
|
calidata.ypmis = calidata.ymmis + count - 1;
|
|||
|
if((calidata.ypmis>calidata.ymmis)&&(calidata.ypmis==128))calidata.ypmis = calidata.ymmis + count-1 + 1;
|
|||
|
if((calidata.ypmis<calidata.ymmis)&&(calidata.ypmis==127))calidata.ypmis = calidata.ymmis + count-1 - 1;
|
|||
|
//calidata.MisDataSpaceConvert = forword_MisDataSpaceConvert;
|
|||
|
calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
|
|||
|
Write_Input(calidata.yaddmis, (*(calidata.MisDataSpaceConvert))(calidata.ypmis));
|
|||
|
}
|
|||
|
if(calidata.ztempf==0){
|
|||
|
calidata.zpmis = calidata.zmmis + count - 1;
|
|||
|
if((calidata.zpmis>calidata.zmmis)&&(calidata.zpmis==128))calidata.zpmis = calidata.zmmis + count-1 + 1;
|
|||
|
if((calidata.zpmis<calidata.zmmis)&&(calidata.zpmis==127))calidata.zpmis = calidata.zmmis + count-1 - 1;
|
|||
|
calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
|
|||
|
Write_Input(calidata.zaddmis, (*(calidata.MisDataSpaceConvert))(calidata.zpmis));
|
|||
|
}
|
|||
|
Read_Output_3axis(acc_buf);
|
|||
|
if(abs((signed int)((signed char)acc_buf[1])-x)<abs(calidata.xfoutput)){
|
|||
|
calidata.xnmis=calidata.xpmis;
|
|||
|
calidata.xfoutput= (signed int)((signed char)acc_buf[1])-x;
|
|||
|
}
|
|||
|
if(abs((signed int)((signed char)acc_buf[3])-y)<abs(calidata.yfoutput)){
|
|||
|
calidata.ynmis=calidata.ypmis;
|
|||
|
calidata.yfoutput= (signed int)((signed char)acc_buf[3])-y;
|
|||
|
}
|
|||
|
if(abs((signed int)((signed char)acc_buf[5])-z)<abs(calidata.zfoutput)){
|
|||
|
calidata.znmis=calidata.zpmis;
|
|||
|
calidata.zfoutput= (signed int)((signed char)acc_buf[5])-z;
|
|||
|
}
|
|||
|
if(calidata.xtempf==0){
|
|||
|
calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
|
|||
|
Write_Input(calidata.xaddmis, (*(calidata.MisDataSpaceConvert))(calidata.xnmis));
|
|||
|
}
|
|||
|
if(calidata.ytempf==0){
|
|||
|
//calidata.MisDataSpaceConvert = forword_MisDataSpaceConvert;
|
|||
|
calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
|
|||
|
Write_Input(calidata.yaddmis, (*(calidata.MisDataSpaceConvert))(calidata.ynmis));
|
|||
|
}
|
|||
|
if(calidata.ztempf==0){
|
|||
|
calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
|
|||
|
Write_Input(calidata.zaddmis, (*(calidata.MisDataSpaceConvert))(calidata.znmis));
|
|||
|
}
|
|||
|
#ifdef PRINT
|
|||
|
printk("L%4d:xf=%4d,xmis=%4d,yf=%4d,ymis=%4d,zf=%4d,zmis=%4d\n\r",__LINE__,
|
|||
|
(signed int)((signed char)acc_buf[1])-x,(unsigned int)calidata.xpmis,
|
|||
|
(signed int)((signed char)acc_buf[3])-y,(unsigned int)calidata.ypmis,
|
|||
|
(signed int)((signed char)acc_buf[5])-z,(unsigned int)calidata.zpmis
|
|||
|
);
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
calidata.xpoff=calidata.ypoff=calidata.zpoff=0x7f;
|
|||
|
calidata.xnoff=calidata.ynoff=calidata.znoff=0;
|
|||
|
calidata.xtempf=calidata.ytempf=calidata.ztempf=0;
|
|||
|
#ifdef PRINT
|
|||
|
printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
|
|||
|
(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
|
|||
|
(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
|
|||
|
(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
|
|||
|
);
|
|||
|
#endif
|
|||
|
check_finalflag_set_tempflag(&calidata);
|
|||
|
#ifdef PRINT
|
|||
|
printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
|
|||
|
(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
|
|||
|
(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
|
|||
|
(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
|
|||
|
);
|
|||
|
#endif
|
|||
|
|
|||
|
if(calidata.xtempf==0){
|
|||
|
calidata.OffDataSpaceConvert = reverse_OffDataSpaceConvert;
|
|||
|
Write_Input(calidata.xaddoff, (*(calidata.OffDataSpaceConvert))(calidata.xpoff)); // x off to max
|
|||
|
}
|
|||
|
if(calidata.ytempf==0){
|
|||
|
//calidata.OffDataSpaceConvert = forword_OffDataSpaceConvert;
|
|||
|
calidata.OffDataSpaceConvert = reverse_OffDataSpaceConvert;
|
|||
|
Write_Input(calidata.yaddoff, (*(calidata.OffDataSpaceConvert))(calidata.xpoff)); // y off to max
|
|||
|
}
|
|||
|
if(calidata.ztempf==0){
|
|||
|
calidata.OffDataSpaceConvert = forword_OffDataSpaceConvert;
|
|||
|
Write_Input(calidata.zaddoff, (*(calidata.OffDataSpaceConvert))(calidata.xpoff)); // z off to max
|
|||
|
}
|
|||
|
Read_Output_3axis(acc_buf);
|
|||
|
calidata.xpoutput=calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
|
|||
|
calidata.ypoutput=calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
|
|||
|
calidata.zpoutput=calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
|
|||
|
#ifdef PRINT
|
|||
|
printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
|
|||
|
(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
|
|||
|
(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
|
|||
|
(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
|
|||
|
);
|
|||
|
#endif
|
|||
|
check_output_set_finalflag(&calidata,2);
|
|||
|
#ifdef PRINT
|
|||
|
printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
|
|||
|
(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
|
|||
|
(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
|
|||
|
(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
|
|||
|
);
|
|||
|
#endif
|
|||
|
|
|||
|
if(calidata.xtempf==0){
|
|||
|
calidata.OffDataSpaceConvert = reverse_OffDataSpaceConvert;
|
|||
|
Write_Input(calidata.xaddoff, (*(calidata.OffDataSpaceConvert))(calidata.xnoff)); // x off to min
|
|||
|
}
|
|||
|
if(calidata.ytempf==0){
|
|||
|
//calidata.OffDataSpaceConvert = forword_OffDataSpaceConvert;
|
|||
|
calidata.OffDataSpaceConvert = reverse_OffDataSpaceConvert;
|
|||
|
Write_Input(calidata.yaddoff, (*(calidata.OffDataSpaceConvert))(calidata.ynoff)); // y off to min
|
|||
|
}
|
|||
|
if(calidata.ztempf==0){
|
|||
|
calidata.OffDataSpaceConvert = forword_OffDataSpaceConvert;
|
|||
|
Write_Input(calidata.zaddoff, (*(calidata.OffDataSpaceConvert))(calidata.znoff)); // z off to min
|
|||
|
}
|
|||
|
Read_Output_3axis(acc_buf);
|
|||
|
calidata.xnoutput=calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
|
|||
|
calidata.ynoutput=calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
|
|||
|
calidata.znoutput=calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
|
|||
|
#ifdef PRINT
|
|||
|
printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
|
|||
|
(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
|
|||
|
(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
|
|||
|
(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
|
|||
|
);
|
|||
|
#endif
|
|||
|
check_output_set_finalflag(&calidata,2);
|
|||
|
#ifdef PRINT
|
|||
|
printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
|
|||
|
(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
|
|||
|
(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
|
|||
|
(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
|
|||
|
);
|
|||
|
#endif
|
|||
|
if(abs(calidata.xpoutput)<=abs(calidata.xnoutput)){
|
|||
|
calidata.xfoutput=calidata.xpoutput;
|
|||
|
calidata.xmoff=calidata.xpoff;
|
|||
|
}
|
|||
|
else{
|
|||
|
calidata.xfoutput=calidata.xnoutput;
|
|||
|
calidata.xmoff=calidata.xnoff;
|
|||
|
}
|
|||
|
if(abs(calidata.ypoutput)<=abs(calidata.ynoutput)){
|
|||
|
calidata.yfoutput=calidata.ypoutput;
|
|||
|
calidata.ymoff=calidata.ypoff;
|
|||
|
}
|
|||
|
else{
|
|||
|
calidata.yfoutput=calidata.ynoutput;
|
|||
|
calidata.ymoff=calidata.ynoff;
|
|||
|
}
|
|||
|
if(abs(calidata.zpoutput)<=abs(calidata.znoutput)){
|
|||
|
calidata.zfoutput=calidata.zpoutput;
|
|||
|
calidata.zmoff=calidata.zpoff;
|
|||
|
}
|
|||
|
else{
|
|||
|
calidata.zfoutput=calidata.znoutput;
|
|||
|
calidata.zmoff=calidata.znoff;
|
|||
|
}
|
|||
|
if(calidata.xtempf==0){
|
|||
|
calidata.OffDataSpaceConvert = reverse_OffDataSpaceConvert;
|
|||
|
Write_Input(calidata.xaddoff, (*(calidata.OffDataSpaceConvert))(calidata.xmoff));
|
|||
|
}
|
|||
|
if(calidata.ytempf==0){
|
|||
|
//calidata.OffDataSpaceConvert = forword_OffDataSpaceConvert;
|
|||
|
calidata.OffDataSpaceConvert = reverse_OffDataSpaceConvert;
|
|||
|
Write_Input(calidata.yaddoff, (*(calidata.OffDataSpaceConvert))(calidata.ymoff));
|
|||
|
}
|
|||
|
if(calidata.ztempf==0){
|
|||
|
calidata.OffDataSpaceConvert = forword_OffDataSpaceConvert;
|
|||
|
Write_Input(calidata.zaddoff, (*(calidata.OffDataSpaceConvert))(calidata.zmoff));
|
|||
|
}
|
|||
|
if((calidata.xpoutput>0 && calidata.xnoutput>0)||(calidata.xpoutput<0 && calidata.xnoutput<0)){
|
|||
|
calidata.xfinalf=1;
|
|||
|
}
|
|||
|
|
|||
|
if((calidata.ypoutput>0 && calidata.ynoutput>0)||(calidata.ypoutput<0 && calidata.ynoutput<0)){
|
|||
|
calidata.yfinalf=1;
|
|||
|
}
|
|||
|
|
|||
|
if((calidata.zpoutput>0 && calidata.znoutput>0)||(calidata.zpoutput<0 && calidata.znoutput<0)){
|
|||
|
calidata.zfinalf=1;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
check_finalflag_set_tempflag(&calidata);
|
|||
|
#ifdef PRINT
|
|||
|
printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
|
|||
|
(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
|
|||
|
(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
|
|||
|
(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
|
|||
|
);
|
|||
|
#endif
|
|||
|
cyclecount=0;
|
|||
|
while(1){
|
|||
|
if(++cyclecount>20)break;
|
|||
|
|
|||
|
if((calidata.xtempf)&&(calidata.ytempf)&&(calidata.ztempf))break;
|
|||
|
updata_midoff_address(&calidata);
|
|||
|
Read_Output_3axis(acc_buf);
|
|||
|
calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
|
|||
|
calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
|
|||
|
calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
|
|||
|
#ifdef PRINT
|
|||
|
printk("xp%4d=%4d,xm%4d=%4d,xn%4d=%4d, yp%4d=%4d,ym%4d=%4d,yn%4d=%4d, zp%4d=%4d,zm%4d=%4d,zn%4d=%4d\n\r",
|
|||
|
calidata.xpoutput,(unsigned int)calidata.xpoff,
|
|||
|
calidata.xfoutput,(unsigned int)calidata.xmoff,
|
|||
|
calidata.xnoutput,(unsigned int)calidata.xnoff,
|
|||
|
calidata.ypoutput,(unsigned int)calidata.ypoff,
|
|||
|
calidata.yfoutput,(unsigned int)calidata.ymoff,
|
|||
|
calidata.ynoutput,(unsigned int)calidata.ynoff,
|
|||
|
calidata.zpoutput,(unsigned int)calidata.zpoff,
|
|||
|
calidata.zfoutput,(unsigned int)calidata.zmoff,
|
|||
|
calidata.znoutput,(unsigned int)calidata.znoff
|
|||
|
);
|
|||
|
#endif
|
|||
|
updata_moff_pnfoutput_set_tempflag(&calidata,acc_buf,x,y,z);
|
|||
|
check_output_set_finalflag(&calidata,2);
|
|||
|
if(check_flag_is_return(&calidata))return 1;
|
|||
|
}
|
|||
|
#ifdef PRINT
|
|||
|
printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
|
|||
|
(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
|
|||
|
(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
|
|||
|
(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
|
|||
|
);
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
|
|||
|
return 1;
|
|||
|
}
|
|||
|
|
|||
|
int auto_calibration_instant_mtp(signed int x, signed int y, signed int z){
|
|||
|
unsigned char readbuf[3]={0};
|
|||
|
unsigned char buffer[6] = {0};
|
|||
|
char reg_13;
|
|||
|
|
|||
|
signed int xoutp,youtp,zoutp;
|
|||
|
unsigned char xfinalf,yfinalf,zfinalf;
|
|||
|
xoutp=youtp=zoutp=0;
|
|||
|
xfinalf=yfinalf=zfinalf=0;
|
|||
|
reg_13= 0;
|
|||
|
Write_Input(0x1e, 0x05);
|
|||
|
if(auto_calibration_instant(x,y,z)==0)return 0;
|
|||
|
|
|||
|
//msleep(20);
|
|||
|
tilt_3axis_mtp(x,y,z);
|
|||
|
Read_Output_3axis(buffer);
|
|||
|
xoutp=(signed int)((signed char)buffer[1])-x;
|
|||
|
youtp=(signed int)((signed char)buffer[3])-y;
|
|||
|
zoutp=(signed int)((signed char)buffer[5])-z;
|
|||
|
|
|||
|
if(abs(xoutp) < 2){xfinalf=1;}
|
|||
|
if(abs(youtp) < 2){yfinalf=1;}
|
|||
|
if(abs(zoutp) < 2){zfinalf=1;}
|
|||
|
|
|||
|
|
|||
|
//*tbuffer = 0x10;
|
|||
|
//sensor_rx_data(sc7660_client, tbuffer,1);
|
|||
|
readbuf[0]= Read_Reg(0x10);
|
|||
|
//*tbuffer = 0x40;
|
|||
|
//sensor_rx_data(sc7660_client, tbuffer,1);
|
|||
|
readbuf[1]= Read_Reg(0x40);
|
|||
|
//*tbuffer = 0x47;
|
|||
|
//sensor_rx_data(sc7660_client, tbuffer,1);
|
|||
|
readbuf[2]= Read_Reg(0x47);
|
|||
|
printk("L%4d:xtilt=%4d,xmis=%4d,xoff=%4d\n\r",__LINE__,
|
|||
|
(unsigned int)readbuf[0],
|
|||
|
(unsigned int)readbuf[1],
|
|||
|
(unsigned int)readbuf[2]
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//*tbuffer = 0x11;
|
|||
|
//sensor_rx_data(sc7660_client, tbuffer,1);
|
|||
|
readbuf[0]= Read_Reg(0x11);
|
|||
|
//*tbuffer = 0x41;
|
|||
|
//sensor_rx_data(sc7660_client, tbuffer,1);
|
|||
|
readbuf[1]= Read_Reg(0x41);
|
|||
|
//*tbuffer = 0x48;
|
|||
|
//sensor_rx_data(sc7660_client, tbuffer,1);
|
|||
|
readbuf[2]= Read_Reg(0x48);
|
|||
|
printk("L%4d:ytilt=%4d,ymis=%4d,yoff=%4d\n\r",__LINE__,
|
|||
|
(unsigned int)readbuf[0],
|
|||
|
(unsigned int)readbuf[1],
|
|||
|
(unsigned int)readbuf[2]
|
|||
|
);
|
|||
|
|
|||
|
|
|||
|
readbuf[0]= Read_Reg(0x12);
|
|||
|
|
|||
|
readbuf[1]= Read_Reg(0x42);
|
|||
|
|
|||
|
readbuf[2]= Read_Reg(0x49);
|
|||
|
printk("L%4d:ztilt=%4d,zmis=%4d,zoff=%4d\n\r",__LINE__,
|
|||
|
(unsigned int)readbuf[0],
|
|||
|
(unsigned int)readbuf[1],
|
|||
|
(unsigned int)readbuf[2]
|
|||
|
);
|
|||
|
|
|||
|
if(xfinalf && yfinalf && zfinalf)
|
|||
|
{
|
|||
|
Write_Input(0x13,0x01);//allen MTP
|
|||
|
reg_13 = Read_Reg(0x13);
|
|||
|
printk("line %d reg_13 = %x\n",__LINE__,reg_13);
|
|||
|
Write_Input(0x1e, 0x15);
|
|||
|
mdelay(300);
|
|||
|
reg_13 = Read_Reg(0x13);
|
|||
|
printk("line %d reg_13 = %x\n",__LINE__,reg_13);
|
|||
|
Write_Input(0x1e, 05);
|
|||
|
|
|||
|
printk(KERN_INFO "run calibration finished\n");
|
|||
|
|
|||
|
return 1;
|
|||
|
}
|
|||
|
else
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
static ssize_t SC7660_3_axis_Calibration(struct device *dev, struct device_attribute *attr ,const char *buf, size_t count)
|
|||
|
{
|
|||
|
int adj_ok;
|
|||
|
Write_Input(0x22, 0x77);
|
|||
|
Write_Input(0x1e, 0x05); //supply the rivilege for MTP
|
|||
|
mdelay(100);
|
|||
|
adj_ok = auto_calibration_instant_mtp(0,0,-64);
|
|||
|
if(adj_ok )
|
|||
|
{
|
|||
|
Write_Input(0x1e, 0x15); //save the modifyed register value
|
|||
|
mdelay(200);
|
|||
|
Write_Input(0x1e, 0);
|
|||
|
printk(KERN_INFO "run calibration success\n");
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printk(KERN_INFO "run calibration failed\n");
|
|||
|
}
|
|||
|
Write_Input(0x22, 0x47);
|
|||
|
mdelay(5);
|
|||
|
return 1;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* gsensor_detect - Device detection callback for automatic device creation
|
|||
|
* return value:
|
|||
|
* = 0; success;
|
|||
|
* < 0; err
|
|||
|
*/
|
|||
|
static int sc7660_gsensor_detect(struct i2c_client *client, struct i2c_board_info *info)
|
|||
|
{
|
|||
|
struct i2c_adapter *adapter = client->adapter;
|
|||
|
//__s32 ret = 0;
|
|||
|
|
|||
|
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
|
|||
|
return -ENODEV;
|
|||
|
|
|||
|
if(twi_id == adapter->nr){
|
|||
|
printk("%s: addr= %x\n",__func__,client->addr);
|
|||
|
/*
|
|||
|
ret = gsensor_i2c_test(client);
|
|||
|
if(!ret){
|
|||
|
pr_info("%s:I2C connection might be something wrong or maybe the other gsensor equipment! \n",__func__);
|
|||
|
return -ENODEV;
|
|||
|
}else
|
|||
|
*/
|
|||
|
{
|
|||
|
dprintk(DEBUG_INIT, "%s: I2C connection sucess!\n", __func__);
|
|||
|
strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE);
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
}else{
|
|||
|
dprintk(DEBUG_INIT, "%s: I2C connection error!\n", __func__);
|
|||
|
return -ENODEV;
|
|||
|
}
|
|||
|
}
|
|||
|
static ssize_t sc7660_delay_show(struct device *dev,
|
|||
|
struct device_attribute *attr, char *buf)
|
|||
|
{
|
|||
|
struct i2c_client *client = sc7660_i2c_client;
|
|||
|
struct sc7660_data_s *sc7660 = NULL;
|
|||
|
|
|||
|
sc7660 = i2c_get_clientdata(client);
|
|||
|
return sprintf(buf, "%d\n", sc7660->pollDev->poll_interval);
|
|||
|
}
|
|||
|
|
|||
|
static ssize_t sc7660_delay_store(struct device *dev,
|
|||
|
struct device_attribute *attr,
|
|||
|
const char *buf, size_t count)
|
|||
|
{
|
|||
|
unsigned long data;
|
|||
|
//int error;
|
|||
|
struct i2c_client *client = sc7660_i2c_client;
|
|||
|
struct sc7660_data_s *sc7660 = NULL;
|
|||
|
|
|||
|
sc7660 = i2c_get_clientdata(client);
|
|||
|
dprintk(DEBUG_INIT, "delay store %d\n", __LINE__);
|
|||
|
|
|||
|
data = simple_strtoul(buf, NULL, 10);
|
|||
|
//error = strict_strtoul(buf, 10, &data);
|
|||
|
//if (error)
|
|||
|
// return error;
|
|||
|
|
|||
|
if (data > POLL_INTERVAL_MAX)
|
|||
|
data = POLL_INTERVAL_MAX;
|
|||
|
|
|||
|
mutex_lock(&sc7660->interval_mutex);
|
|||
|
sc7660->pollDev->poll_interval = data;
|
|||
|
mutex_unlock(&sc7660->interval_mutex);
|
|||
|
|
|||
|
if (atomic_read(&sc7660_data.enable)) {
|
|||
|
sc7660_data.ktime = ktime_set(0, sc7660->pollDev->poll_interval * NSEC_PER_MSEC);
|
|||
|
hrtimer_start(&sc7660_data.hr_timer, sc7660_data.ktime, HRTIMER_MODE_REL);
|
|||
|
}
|
|||
|
|
|||
|
return count;
|
|||
|
}
|
|||
|
|
|||
|
static ssize_t sc7660_enable_show(struct device *dev,
|
|||
|
struct device_attribute *attr, char *buf)
|
|||
|
{
|
|||
|
struct i2c_client *client = sc7660_i2c_client;
|
|||
|
struct sc7660_data_s *sc7660 = NULL;
|
|||
|
|
|||
|
sc7660 = i2c_get_clientdata(client);
|
|||
|
|
|||
|
return sprintf(buf, "%d\n",atomic_read(&sc7660_data.enable));
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
static ssize_t sc7660_enable_store(struct device *dev,
|
|||
|
struct device_attribute *attr,
|
|||
|
const char *buf, size_t count)
|
|||
|
{
|
|||
|
unsigned long data;
|
|||
|
int error;
|
|||
|
|
|||
|
struct i2c_client *client = sc7660_i2c_client;
|
|||
|
struct sc7660_data_s *sc7660 = NULL;
|
|||
|
|
|||
|
sc7660 = i2c_get_clientdata(client);
|
|||
|
|
|||
|
printk(KERN_INFO "%s: buf=%s\n", __func__, buf);
|
|||
|
data = simple_strtoul(buf, NULL, 10);
|
|||
|
//error = strict_strtoul(buf, 10, &data);
|
|||
|
|
|||
|
//if(error) {
|
|||
|
// pr_err("%s strict_strtoul error\n", __FUNCTION__);
|
|||
|
// goto exit;
|
|||
|
//}
|
|||
|
|
|||
|
if(data) {
|
|||
|
printk(KERN_INFO "%s: sc7660_CTRL_PWRON\n", __func__);
|
|||
|
error = i2c_smbus_write_byte_data(sc7660_i2c_client, sc7660_REG_CTRL,sc7660_CTRL_PWRON);
|
|||
|
atomic_set(&sc7660_data.enable, 1);
|
|||
|
assert(error==0);
|
|||
|
//
|
|||
|
printk(KERN_INFO "%s: sc7660 delay %d\n", __func__, sc7660->pollDev->poll_interval);
|
|||
|
sc7660_data.ktime = ktime_set(0, sc7660->pollDev->poll_interval * NSEC_PER_MSEC);
|
|||
|
hrtimer_start(&sc7660_data.hr_timer, ktime_set(0, 0), HRTIMER_MODE_REL);
|
|||
|
//sc7660_idev->input->open(sc7660_idev->input);
|
|||
|
} else {
|
|||
|
printk(KERN_INFO "%s: sc7660_CTRL_PWRDN\n", __func__);
|
|||
|
//sc7660_idev->input->close(sc7660_idev->input);
|
|||
|
hrtimer_cancel(&sc7660_data.hr_timer);
|
|||
|
atomic_set(&sc7660_data.enable, 0);
|
|||
|
error = i2c_smbus_write_byte_data(sc7660_i2c_client, sc7660_REG_CTRL,sc7660_CTRL_PWRDN);
|
|||
|
assert(error==0);
|
|||
|
}
|
|||
|
|
|||
|
return count;
|
|||
|
|
|||
|
//exit:
|
|||
|
// return error;
|
|||
|
}
|
|||
|
|
|||
|
#if 0
|
|||
|
static ssize_t SC7660_reg13_reset(struct device *dev,
|
|||
|
struct device_attribute *attr,
|
|||
|
const char *buf, size_t count)
|
|||
|
{
|
|||
|
|
|||
|
int result = 0;
|
|||
|
result = i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1e,0x05);
|
|||
|
mdelay(100);
|
|||
|
result = i2c_smbus_write_byte_data(sc7660_i2c_client, 0x13, 0x00);
|
|||
|
|
|||
|
result = i2c_smbus_write_byte_data(sc7660_i2c_client,0x1e, 0x15);
|
|||
|
mdelay(300);
|
|||
|
|
|||
|
if(result)
|
|||
|
printk("%s:fail to write sensor_register\n",__func__);
|
|||
|
|
|||
|
return count;
|
|||
|
}
|
|||
|
#endif
|
|||
|
|
|||
|
static ssize_t SC7660_register_store(struct device *dev,
|
|||
|
struct device_attribute *attr,
|
|||
|
const char *buf, size_t count)
|
|||
|
{
|
|||
|
unsigned int address, value;
|
|||
|
int result = 0;
|
|||
|
sscanf(buf, "0x%x=0x%x", &address, &value);
|
|||
|
|
|||
|
result = i2c_smbus_write_byte_data(sc7660_i2c_client, address,value);
|
|||
|
|
|||
|
if(result)
|
|||
|
printk("%s:fail to write sensor_register\n",__func__);
|
|||
|
|
|||
|
return count;
|
|||
|
}
|
|||
|
|
|||
|
static ssize_t SC7660_register_show(struct device *dev,
|
|||
|
struct device_attribute *attr, char *buf)
|
|||
|
{
|
|||
|
size_t count = 0;
|
|||
|
//u8 reg[0x5b];
|
|||
|
char i;
|
|||
|
int buffer[3] = {0};
|
|||
|
i = 0x0f;
|
|||
|
*buffer = i;
|
|||
|
buffer[0] = i2c_smbus_read_byte_data(sc7660_i2c_client,i );
|
|||
|
count += sprintf(buf, "0x%x: 0x%x\n", i, buffer[0]);
|
|||
|
for(i=0x10;i<0x5a;i++)
|
|||
|
{
|
|||
|
*buffer = i;
|
|||
|
buffer[0]=i2c_smbus_read_byte_data(sc7660_i2c_client, i);
|
|||
|
count += sprintf(&buf[count],"0x%x: 0x%x\n", i, buffer[0]);
|
|||
|
}
|
|||
|
return count;
|
|||
|
}
|
|||
|
#if 0
|
|||
|
static DEVICE_ATTR(enable, S_IRUGO,
|
|||
|
sc7660_enable_show, sc7660_enable_store);
|
|||
|
|
|||
|
static DEVICE_ATTR(delay, S_IRUGO,
|
|||
|
sc7660_delay_show, sc7660_delay_store);
|
|||
|
|
|||
|
static DEVICE_ATTR(reg, S_IRUGO,
|
|||
|
SC7660_register_show, SC7660_register_store);
|
|||
|
|
|||
|
static DEVICE_ATTR(reg13_reset, S_IRUGO,
|
|||
|
SC7660_reg13_reset, NULL);
|
|||
|
|
|||
|
static DEVICE_ATTR(calibration_run, S_IRUGO,//S_IWUSR|S_IWGRP, //calibration_run
|
|||
|
NULL, SC7660_3_axis_Calibration);
|
|||
|
#endif
|
|||
|
static DEVICE_ATTR(enable, 0644,
|
|||
|
sc7660_enable_show, sc7660_enable_store);
|
|||
|
|
|||
|
static DEVICE_ATTR(delay, 0644,
|
|||
|
sc7660_delay_show, sc7660_delay_store);
|
|||
|
|
|||
|
static DEVICE_ATTR(reg, 0644,
|
|||
|
SC7660_register_show, SC7660_register_store);
|
|||
|
|
|||
|
//static DEVICE_ATTR(reg13_reset, 0644,
|
|||
|
// SC7660_reg13_reset, NULL);
|
|||
|
|
|||
|
static DEVICE_ATTR(calibration_run, 0644,//S_IWUSR|S_IWGRP, //calibration_run
|
|||
|
NULL, SC7660_3_axis_Calibration);
|
|||
|
|
|||
|
static struct attribute *sc7660_attributes[] = {
|
|||
|
// &dev_attr_reg13_reset.attr,
|
|||
|
&dev_attr_reg.attr,
|
|||
|
&dev_attr_enable.attr,
|
|||
|
&dev_attr_delay.attr,
|
|||
|
&dev_attr_calibration_run.attr,
|
|||
|
NULL
|
|||
|
};
|
|||
|
|
|||
|
static struct attribute_group sc7660_attribute_group = {
|
|||
|
.attrs = sc7660_attributes
|
|||
|
};
|
|||
|
|
|||
|
#if 0
|
|||
|
static int report_abs(void)
|
|||
|
{
|
|||
|
s8 xyz[6] = {0, 0, 0};
|
|||
|
s16 x = 0, y = 0, z = 0;
|
|||
|
s8 ret = 0;
|
|||
|
s16 conut = 0;
|
|||
|
while(1)
|
|||
|
{
|
|||
|
|
|||
|
ret = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_STATUS);
|
|||
|
if ((ret& 0x08) != 0 ){
|
|||
|
break;
|
|||
|
}
|
|||
|
msleep(1);
|
|||
|
conut++;
|
|||
|
if(conut > 40)
|
|||
|
break;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
xyz[0] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_XOUT_L);
|
|||
|
xyz[1] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_XOUT_H);
|
|||
|
|
|||
|
xyz[2] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_YOUT_L);
|
|||
|
xyz[3] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_YOUT_H);
|
|||
|
|
|||
|
xyz[4] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_ZOUT_L);
|
|||
|
xyz[5] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_ZOUT_H);
|
|||
|
|
|||
|
//x = ((xyz[1]) << 8) | xyz[0];
|
|||
|
//y = ((xyz[3]) << 8) | xyz[2];
|
|||
|
//z = ((xyz[5]) << 8) | xyz[4];
|
|||
|
|
|||
|
x = xyz[1];
|
|||
|
y = xyz[3];
|
|||
|
z = xyz[5];
|
|||
|
|
|||
|
|
|||
|
input_report_abs(sc7660_idev->input, ABS_X, x);
|
|||
|
input_report_abs(sc7660_idev->input, ABS_Y, y);
|
|||
|
input_report_abs(sc7660_idev->input, ABS_Z, z);
|
|||
|
|
|||
|
input_sync(sc7660_idev->input);
|
|||
|
return 1;
|
|||
|
}
|
|||
|
|
|||
|
#endif
|
|||
|
|
|||
|
static void sc7660_dev_poll(struct input_polled_dev *dev)
|
|||
|
{
|
|||
|
#ifdef CONFIG_HAS_EARLYSUSPEND
|
|||
|
if(0 == sc7660_data.suspend_indator){
|
|||
|
//report_abs();
|
|||
|
}
|
|||
|
#else
|
|||
|
{
|
|||
|
//report_abs();
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
/*
|
|||
|
* I2C init/probing/exit functions
|
|||
|
*/
|
|||
|
|
|||
|
////////////////////////////////djq////////////////////////////////////
|
|||
|
static int sc7660_acc_get_data( int *xyz)
|
|||
|
{
|
|||
|
u8 acc_data[6];
|
|||
|
/* x,y,z hardware data */
|
|||
|
int hw_d[3] = { 0 };
|
|||
|
signed short temp_data[3];
|
|||
|
int count = 0;
|
|||
|
u8 buf[3];
|
|||
|
buf[0] = SC7660_STATUS;
|
|||
|
while(1)
|
|||
|
{
|
|||
|
|
|||
|
buf[0]=i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_STATUS);
|
|||
|
if ((buf[0] & 0x08) != 0 ){
|
|||
|
break;
|
|||
|
}
|
|||
|
msleep(1);
|
|||
|
count++;
|
|||
|
if(count > 40)
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
buf[0]=i2c_smbus_read_byte_data(sc7660_i2c_client,SC7660_XOUT_L);
|
|||
|
acc_data[0] = buf[0];
|
|||
|
buf[0]=i2c_smbus_read_byte_data(sc7660_i2c_client,SC7660_XOUT_H);
|
|||
|
|
|||
|
acc_data[1] = buf[0];
|
|||
|
|
|||
|
|
|||
|
buf[0]=i2c_smbus_read_byte_data(sc7660_i2c_client,SC7660_YOUT_L);
|
|||
|
acc_data[2] = buf[0];
|
|||
|
buf[0]=i2c_smbus_read_byte_data(sc7660_i2c_client,SC7660_YOUT_H);
|
|||
|
acc_data[3] = buf[0];
|
|||
|
|
|||
|
|
|||
|
buf[0]=i2c_smbus_read_byte_data(sc7660_i2c_client,SC7660_ZOUT_L);
|
|||
|
acc_data[4] = buf[0];
|
|||
|
buf[0]=i2c_smbus_read_byte_data(sc7660_i2c_client,SC7660_ZOUT_H);
|
|||
|
acc_data[5] = buf[0];
|
|||
|
|
|||
|
/* 12-bit */
|
|||
|
temp_data[0] = (signed short)( (acc_data[1] << 8 | acc_data[0]) >> 4 );
|
|||
|
temp_data[1] = (signed short)( (acc_data[3] << 8 | acc_data[2]) >> 4 );
|
|||
|
temp_data[2] = (signed short)( (acc_data[5] << 8 | acc_data[4]) >> 4 );
|
|||
|
|
|||
|
hw_d[0] = (temp_data[0] & 0x0800) ? (temp_data[0] | 0xFFFFF800) : (temp_data[0]);
|
|||
|
hw_d[1] = (temp_data[1] & 0x0800) ? (temp_data[1] | 0xFFFFF800) : (temp_data[1]);
|
|||
|
hw_d[2] = (temp_data[2] & 0x0800) ? (temp_data[2] | 0xFFFFF800) : (temp_data[2]);
|
|||
|
|
|||
|
|
|||
|
|
|||
|
xyz[0] = (hw_d[0] ) * 1000;
|
|||
|
xyz[1] = (hw_d[1] ) * 1000;
|
|||
|
xyz[2] = (hw_d[2] ) * 1000;
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static int sc7660_acc_hw_init(void)
|
|||
|
{
|
|||
|
char ret;
|
|||
|
ret = i2c_smbus_write_byte_data(sc7660_i2c_client, SC7660_MODE, 0x77);
|
|||
|
if(ret < 0)
|
|||
|
{
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
static int sc7660_acc_cali(struct i2c_client *client)
|
|||
|
{
|
|||
|
struct sc7660_data_s *data = (struct sc7660_data_s *) i2c_get_clientdata(client);
|
|||
|
|
|||
|
queue_delayed_work(sc7660_workqueue,
|
|||
|
&data->dwork,
|
|||
|
msecs_to_jiffies(1000));
|
|||
|
|
|||
|
printk("cali !!!\n");
|
|||
|
sc7660_acc_hw_init();
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
static void sc7660_work_handler(struct work_struct *work)
|
|||
|
{
|
|||
|
|
|||
|
int xyz[3] = {0, 0, 0};
|
|||
|
int ret =0;
|
|||
|
int adj_ok;
|
|||
|
|
|||
|
int auto_count = 0;
|
|||
|
int max_x=0, max_y=0, max_z=0, min_x=0, min_y=0, min_z=0;
|
|||
|
int sum_x = 0, sum_y = 0, sum_z = 0;
|
|||
|
|
|||
|
struct sc7660_data_s *data =
|
|||
|
container_of(work, struct sc7660_data_s, dwork.work);
|
|||
|
|
|||
|
while (1) {
|
|||
|
|
|||
|
ret = sc7660_acc_get_data(xyz);
|
|||
|
if(ret == -1)
|
|||
|
{
|
|||
|
printk("Line %d:error!\n",__LINE__);
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
xyz[0] /= 1024;
|
|||
|
xyz[1] /= 1024;
|
|||
|
xyz[2] /= 1024;
|
|||
|
|
|||
|
if (auto_count == 0) {
|
|||
|
max_x = min_x = xyz[0];
|
|||
|
max_y = min_y = xyz[1];
|
|||
|
max_z = min_z = xyz[2];
|
|||
|
}
|
|||
|
|
|||
|
max_x = max_x > xyz[0] ? max_x : xyz[0];
|
|||
|
max_y = max_y > xyz[1] ? max_y : xyz[1];
|
|||
|
max_z = max_z > xyz[2] ? max_z : xyz[2];
|
|||
|
min_x = min_x > xyz[0] ? xyz[0] : min_x;
|
|||
|
min_y = min_y > xyz[1] ? xyz[1] : min_y;
|
|||
|
min_z = min_z > xyz[2] ? xyz[2] : min_z;
|
|||
|
|
|||
|
sum_x = sum_x + xyz[0];
|
|||
|
sum_y = sum_y + xyz[1];
|
|||
|
sum_z = sum_z + xyz[2];
|
|||
|
|
|||
|
|
|||
|
printk("x : %d y : %d z : %d sum_z = %d,auto_count = %d\n",xyz[0], xyz[1], xyz[2],sum_z, auto_count);
|
|||
|
|
|||
|
if (auto_count > CALIBRATION_NUM-1) {
|
|||
|
printk("x-x : %d\n", max_x - min_x);
|
|||
|
printk("y-y : %d\n", max_y - min_y);
|
|||
|
printk("z-z : %d\n", max_z - min_z);
|
|||
|
|
|||
|
if (max_x - min_x < AXIS_X_Y_RANGE_LIMIT
|
|||
|
&& max_y - min_y < AXIS_X_Y_RANGE_LIMIT
|
|||
|
&& max_z - min_z < AXIS_X_Y_RANGE_LIMIT ) {
|
|||
|
printk("sum-x-before : %d\n", sum_x);
|
|||
|
printk("sum-y-before : %d\n", sum_y);
|
|||
|
printk("sum-z-before : %d\n", sum_z);
|
|||
|
|
|||
|
//ok
|
|||
|
sum_x /= CALIBRATION_NUM;
|
|||
|
sum_y /= CALIBRATION_NUM;
|
|||
|
sum_z /= CALIBRATION_NUM;
|
|||
|
printk("sum-x : %d\n", sum_x);
|
|||
|
printk("sum-y : %d\n", sum_y);
|
|||
|
printk("sum-z : %d\n", sum_z);
|
|||
|
|
|||
|
//if (sum_x < AXIS_X_Y_AVG_LIMIT && sum_y < AXIS_X_Y_AVG_LIMIT) {
|
|||
|
if(1){
|
|||
|
if (sum_z > AXIS_Z_RANGE) {
|
|||
|
//auto_SC7660_3_axis_Calibration( 0, 0, 64);
|
|||
|
adj_ok = auto_calibration_instant_mtp(0,0,64);
|
|||
|
auto_count = GOTO_CALI;
|
|||
|
}
|
|||
|
else if ( sum_z < -AXIS_Z_RANGE) {
|
|||
|
//auto_SC7660_3_axis_Calibration( 0, 0, -64);
|
|||
|
adj_ok = auto_calibration_instant_mtp(0,0,-64);
|
|||
|
auto_count = GOTO_CALI;
|
|||
|
}
|
|||
|
else {
|
|||
|
printk("Line %d:error!\n",__LINE__);
|
|||
|
auto_count = FAILTO_CALI;
|
|||
|
}
|
|||
|
}
|
|||
|
else if( sum_x < AXIS_X_Y_AVG_LIMIT || sum_y < AXIS_X_Y_AVG_LIMIT) {
|
|||
|
if ( sum_z > AXIS_Z_DFT_G - AXIS_Z_RANGE && sum_z < AXIS_Z_DFT_G + AXIS_Z_RANGE) {
|
|||
|
//auto_SC7660_3_axis_Calibration( 0, 0, 64);
|
|||
|
auto_count = GOTO_CALI;
|
|||
|
}
|
|||
|
else if ( sum_z < -(AXIS_Z_DFT_G - AXIS_Z_RANGE) && sum_z > -(AXIS_Z_DFT_G + AXIS_Z_RANGE)) {
|
|||
|
//auto_SC7660_3_axis_Calibration( 0, 0, -64);
|
|||
|
auto_count = GOTO_CALI;
|
|||
|
}
|
|||
|
else {
|
|||
|
auto_count = FAILTO_CALI;
|
|||
|
printk("Line %d:error!\n",__LINE__);
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
auto_count = FAILTO_CALI;
|
|||
|
printk("Line %d:error!\n",__LINE__);
|
|||
|
}
|
|||
|
if(adj_ok==1)
|
|||
|
{
|
|||
|
printk("Calibration succeed\n");
|
|||
|
Write_Input( 0x1e, 0x05);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
printk("Calibration failed\n");
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
auto_count = FAILTO_CALI;
|
|||
|
printk("Line %d:error!\n",__LINE__);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if(auto_count == GOTO_CALI){
|
|||
|
break;
|
|||
|
}
|
|||
|
|
|||
|
if (auto_count == FAILTO_CALI) {
|
|||
|
sum_x = sum_y = sum_z = max_x = max_y = max_z = min_x = min_y = min_z = 0;
|
|||
|
auto_count = -1;
|
|||
|
data->time_of_cali++;
|
|||
|
if (data->time_of_cali > 1) {
|
|||
|
printk("calibration failed !!\n");
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
auto_count++;
|
|||
|
msleep(20);
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
static enum hrtimer_restart my_hrtimer_callback(struct hrtimer *timer)
|
|||
|
{
|
|||
|
schedule_work(&sc7660_data.wq_hrtimer);
|
|||
|
hrtimer_forward_now(&sc7660_data.hr_timer, sc7660_data.ktime);
|
|||
|
return HRTIMER_RESTART;
|
|||
|
}
|
|||
|
|
|||
|
static void wq_func_hrtimer(struct work_struct *work)
|
|||
|
{
|
|||
|
s8 xyz[6] = {0, 0, 0};
|
|||
|
s16 x = 0, y = 0, z = 0;
|
|||
|
|
|||
|
xyz[0] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_XOUT_L);
|
|||
|
xyz[1] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_XOUT_H);
|
|||
|
xyz[2] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_YOUT_L);
|
|||
|
xyz[3] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_YOUT_H);
|
|||
|
xyz[4] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_ZOUT_L);
|
|||
|
xyz[5] = i2c_smbus_read_byte_data(sc7660_i2c_client, SC7660_ZOUT_H);
|
|||
|
|
|||
|
x = xyz[1];
|
|||
|
y = xyz[3];
|
|||
|
z = xyz[5];
|
|||
|
|
|||
|
if (x == 0 && y == 0 && z == 0) {
|
|||
|
pr_err("sc7660 gsensor x y z all 0!!!\n");
|
|||
|
sc7660_reset();
|
|||
|
return;
|
|||
|
}
|
|||
|
input_report_abs(sc7660_idev->input, ABS_X, x);
|
|||
|
input_report_abs(sc7660_idev->input, ABS_Y, y);
|
|||
|
input_report_abs(sc7660_idev->input, ABS_Z, z);
|
|||
|
input_sync(sc7660_idev->input);
|
|||
|
}
|
|||
|
|
|||
|
static int sc7660_probe(struct i2c_client *client,
|
|||
|
const struct i2c_device_id *id)
|
|||
|
{
|
|||
|
char reg_cali;
|
|||
|
|
|||
|
int result;
|
|||
|
struct i2c_adapter *adapter;
|
|||
|
struct sc7660_data_s* data = &sc7660_data;
|
|||
|
|
|||
|
printk( "sc7660 probe\n");
|
|||
|
sc7660_i2c_client = client;
|
|||
|
adapter = to_i2c_adapter(client->dev.parent);
|
|||
|
result = i2c_check_functionality(adapter,
|
|||
|
I2C_FUNC_SMBUS_BYTE |
|
|||
|
I2C_FUNC_SMBUS_BYTE_DATA);
|
|||
|
assert(result);
|
|||
|
|
|||
|
hwmon_dev = hwmon_device_register(&client->dev);
|
|||
|
assert(!(IS_ERR(hwmon_dev)));
|
|||
|
|
|||
|
/*input poll device register */
|
|||
|
sc7660_idev = input_allocate_polled_device();
|
|||
|
if (!sc7660_idev) {
|
|||
|
dev_err(&client->dev, "alloc poll device failed!\n");
|
|||
|
result = -ENOMEM;
|
|||
|
return result;
|
|||
|
}
|
|||
|
sc7660_idev->poll = sc7660_dev_poll;
|
|||
|
sc7660_idev->poll_interval = POLL_INTERVAL;
|
|||
|
sc7660_idev->poll_interval_max = POLL_INTERVAL_MAX;
|
|||
|
sc7660_idev->input->name = sc7660_DRV_NAME;
|
|||
|
sc7660_idev->input->id.bustype = BUS_I2C;
|
|||
|
sc7660_idev->input->evbit[0] = BIT_MASK(EV_ABS);
|
|||
|
mutex_init(&data->interval_mutex);
|
|||
|
input_set_capability(sc7660_idev->input, EV_ABS, ABS_MISC);
|
|||
|
input_set_abs_params(sc7660_idev->input, ABS_X, -512, 512, INPUT_FUZZ, INPUT_FLAT);
|
|||
|
input_set_abs_params(sc7660_idev->input, ABS_Y, -512, 512, INPUT_FUZZ, INPUT_FLAT);
|
|||
|
input_set_abs_params(sc7660_idev->input, ABS_Z, -512, 512, INPUT_FUZZ, INPUT_FLAT);
|
|||
|
|
|||
|
result = input_register_polled_device(sc7660_idev);
|
|||
|
if (result) {
|
|||
|
dev_err(&client->dev, "register poll device failed!\n");
|
|||
|
return result;
|
|||
|
}
|
|||
|
result = sysfs_create_group(&sc7660_idev->input->dev.kobj, &sc7660_attribute_group);
|
|||
|
|
|||
|
if(result) {
|
|||
|
dev_err(&client->dev, "create sys failed\n");
|
|||
|
}
|
|||
|
|
|||
|
data->client = client;
|
|||
|
data->pollDev = sc7660_idev;
|
|||
|
i2c_set_clientdata(client, data);
|
|||
|
|
|||
|
#ifdef CONFIG_HAS_EARLYSUSPEND
|
|||
|
sc7660_data.early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
|
|||
|
sc7660_data.early_suspend.suspend = sc7660_early_suspend;
|
|||
|
sc7660_data.early_suspend.resume = sc7660_late_resume;
|
|||
|
register_early_suspend(&sc7660_data.early_suspend);
|
|||
|
sc7660_data.suspend_indator = 0;
|
|||
|
#endif
|
|||
|
|
|||
|
//result = i2c_smbus_write_byte_data(sc7660_i2c_client, sc7660_REG_CTRL, sc7660_CTRL_PWRON);
|
|||
|
//assert(result==0);
|
|||
|
|
|||
|
reg_cali = i2c_smbus_read_byte_data(sc7660_i2c_client, 0x13);
|
|||
|
printk("line %d reg_cali = 0x%x \n",__LINE__,reg_cali);
|
|||
|
|
|||
|
|
|||
|
if (0) {
|
|||
|
//if ((reg_cali & 0x1) == 0) {
|
|||
|
|
|||
|
if (sc7660_workqueue == NULL) {
|
|||
|
sc7660_workqueue = create_workqueue("sc7660_acc");
|
|||
|
if (sc7660_workqueue == NULL) {
|
|||
|
printk("line %d workque fail!!!!!!!!!!!!!!\n",__LINE__);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
INIT_DELAYED_WORK(&(data->dwork), sc7660_work_handler);
|
|||
|
sc7660_acc_cali(client);
|
|||
|
}
|
|||
|
else {
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
hrtimer_init(&sc7660_data.hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
|
|||
|
sc7660_data.hr_timer.function = my_hrtimer_callback;
|
|||
|
INIT_WORK(&sc7660_data.wq_hrtimer, wq_func_hrtimer);
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
static int sc7660_remove(struct i2c_client *client)
|
|||
|
{
|
|||
|
int result;
|
|||
|
result = i2c_smbus_write_byte_data(sc7660_i2c_client, sc7660_REG_CTRL, sc7660_CTRL_PWRDN);
|
|||
|
assert(result==0);
|
|||
|
hwmon_device_unregister(hwmon_dev);
|
|||
|
#ifdef CONFIG_HAS_EARLYSUSPEND
|
|||
|
unregister_early_suspend(&sc7660_data.early_suspend);
|
|||
|
#endif
|
|||
|
sysfs_remove_group(&sc7660_idev->input->dev.kobj, &sc7660_attribute_group);
|
|||
|
input_unregister_polled_device(sc7660_idev);
|
|||
|
input_free_polled_device(sc7660_idev);
|
|||
|
i2c_set_clientdata(sc7660_i2c_client, NULL);
|
|||
|
|
|||
|
return result;
|
|||
|
}
|
|||
|
|
|||
|
#ifdef CONFIG_HAS_EARLYSUSPEND
|
|||
|
static void sc7660_early_suspend(struct early_suspend *h)
|
|||
|
{
|
|||
|
int result;
|
|||
|
printk( "sc7660 early suspend\n");
|
|||
|
sc7660_data.suspend_indator = 1;
|
|||
|
result = i2c_smbus_write_byte_data(sc7660_i2c_client, sc7660_REG_CTRL, sc7660_CTRL_PWRDN);
|
|||
|
assert(result==0);
|
|||
|
#ifdef GSENSOR_REG_CALI
|
|||
|
{
|
|||
|
int i = 0;
|
|||
|
for(i = 0; i < sizeof(reg)/sizeof(reg[0]); i++) {
|
|||
|
reg_data[i] = i2c_smbus_read_byte_data(sc7660_i2c_client, reg[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
static void sc7660_late_resume(struct early_suspend *h)
|
|||
|
{
|
|||
|
int result;
|
|||
|
int val_reg;
|
|||
|
int MTPSETTING,B57H,B1BH,i;
|
|||
|
printk("sc7660 late resume\n");
|
|||
|
sc7660_data.suspend_indator = 0;
|
|||
|
val_reg = i2c_smbus_read_byte_data(sc7660_i2c_client,0x0f);
|
|||
|
if(val_reg != 0x11)
|
|||
|
{
|
|||
|
for(i=0;i<3;i++)
|
|||
|
{
|
|||
|
MTPSETTING = 0x07;
|
|||
|
B57H = 0x00;
|
|||
|
B1BH = 0x08;
|
|||
|
sc7660_i2c_client->addr=0x18;
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x59,MTPSETTING);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x1e,0x05);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x1b,B1BH);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x57,B57H);
|
|||
|
sc7660_i2c_client->addr=0x19;
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x59,MTPSETTING);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x1e,0x05);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x1b,B1BH);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x57,B57H);
|
|||
|
sc7660_i2c_client->addr=0x1a;
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x59,MTPSETTING);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x1e,0x05);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x1b,B1BH);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x57,B57H);
|
|||
|
sc7660_i2c_client->addr=0x1b;
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x59,MTPSETTING);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x1e,0x05);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x1b,B1BH);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x57,B57H);
|
|||
|
sc7660_i2c_client->addr=0x1c;
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x59,MTPSETTING);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x1e,0x05);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x1b,B1BH);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x57,B57H);
|
|||
|
sc7660_i2c_client->addr=0x1d;
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x59,MTPSETTING);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x1e,0x05);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x1b,B1BH);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x57,B57H);
|
|||
|
sc7660_i2c_client->addr=0x1e;
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x59,MTPSETTING);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x1e,0x05);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x1b,B1BH);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x57,B57H);
|
|||
|
sc7660_i2c_client->addr=0x1f;
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x59,MTPSETTING);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x1e,0x05);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x1b,B1BH);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x57,B57H);
|
|||
|
}
|
|||
|
sc7660_i2c_client->addr=0x1d;
|
|||
|
msleep(100);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x24,0x80);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client,0x1e,0x05);
|
|||
|
val_reg = i2c_smbus_read_byte_data(sc7660_i2c_client,0x0f);
|
|||
|
if(val_reg != 0x11)
|
|||
|
printk("momkey sc7660 resume fail! regchip_id=0x%x\n", val_reg);
|
|||
|
}
|
|||
|
|
|||
|
result = i2c_smbus_write_byte_data(sc7660_i2c_client, sc7660_REG_CTRL, sc7660_CTRL_PWRON);
|
|||
|
assert(result==0);
|
|||
|
#ifdef GSENSOR_REG_CALI
|
|||
|
{
|
|||
|
int i = 0;
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1E, 0x05);
|
|||
|
for(i = 0; i < sizeof(reg)/sizeof(reg[0]); i++) {
|
|||
|
if(reg_data[i] != i2c_smbus_read_byte_data(sc7660_i2c_client, reg[i])){
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, reg[i], reg_data[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
#endif
|
|||
|
return;
|
|||
|
}
|
|||
|
#else
|
|||
|
#ifdef CONFIG_PM
|
|||
|
static int sc7660_resume(struct i2c_client *client)
|
|||
|
{
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
static int sc7660_suspend(struct i2c_client *client, pm_message_t mesg)
|
|||
|
{
|
|||
|
return 0;
|
|||
|
}
|
|||
|
#endif
|
|||
|
#endif /* CONFIG_HAS_EARLYSUSPEND */
|
|||
|
|
|||
|
static void sc7660_reset(void)
|
|||
|
{
|
|||
|
int result;
|
|||
|
int val_reg;
|
|||
|
int MTPSETTING, B57H, B1BH, i;
|
|||
|
printk("sc7660 reset power down\n");
|
|||
|
result = i2c_smbus_write_byte_data(sc7660_i2c_client, sc7660_REG_CTRL, sc7660_CTRL_PWRDN);
|
|||
|
assert(result == 0);
|
|||
|
msleep(50);
|
|||
|
|
|||
|
printk("sc7660 reset power on\n");
|
|||
|
val_reg = i2c_smbus_read_byte_data(sc7660_i2c_client, 0x0f);
|
|||
|
if (val_reg != 0x11) {
|
|||
|
for (i = 0; i < 3; i++) {
|
|||
|
MTPSETTING = 0x07;
|
|||
|
B57H = 0x00;
|
|||
|
B1BH = 0x08;
|
|||
|
sc7660_i2c_client->addr = 0x18;
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x59, MTPSETTING);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1e, 0x05);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1b, B1BH);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x57, B57H);
|
|||
|
sc7660_i2c_client->addr = 0x19;
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x59, MTPSETTING);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1e, 0x05);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1b, B1BH);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x57, B57H);
|
|||
|
sc7660_i2c_client->addr = 0x1a;
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x59, MTPSETTING);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1e, 0x05);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1b, B1BH);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x57, B57H);
|
|||
|
sc7660_i2c_client->addr = 0x1b;
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x59, MTPSETTING);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1e, 0x05);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1b, B1BH);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x57, B57H);
|
|||
|
sc7660_i2c_client->addr = 0x1c;
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x59, MTPSETTING);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1e, 0x05);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1b, B1BH);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x57, B57H);
|
|||
|
sc7660_i2c_client->addr = 0x1d;
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x59, MTPSETTING);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1e, 0x05);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1b, B1BH);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x57, B57H);
|
|||
|
sc7660_i2c_client->addr = 0x1e;
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x59, MTPSETTING);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1e, 0x05);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1b, B1BH);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x57, B57H);
|
|||
|
sc7660_i2c_client->addr = 0x1f;
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x59, MTPSETTING);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1e, 0x05);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1b, B1BH);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x57, B57H);
|
|||
|
}
|
|||
|
sc7660_i2c_client->addr = 0x1d;
|
|||
|
msleep(100);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x24, 0x80);
|
|||
|
i2c_smbus_write_byte_data(sc7660_i2c_client, 0x1e, 0x05);
|
|||
|
val_reg = i2c_smbus_read_byte_data(sc7660_i2c_client, 0x0f);
|
|||
|
if (val_reg != 0x11)
|
|||
|
printk("momkey sc7660 resume fail! regchip_id=0x%x\n", val_reg);
|
|||
|
}
|
|||
|
|
|||
|
result = i2c_smbus_write_byte_data(sc7660_i2c_client, sc7660_REG_CTRL, sc7660_CTRL_PWRON);
|
|||
|
assert(result == 0);
|
|||
|
}
|
|||
|
|
|||
|
static const struct i2c_device_id sc7660_id[] = {
|
|||
|
{ sc7660_DRV_NAME, 1 },
|
|||
|
{ }
|
|||
|
};
|
|||
|
MODULE_DEVICE_TABLE(i2c, sc7660_id);
|
|||
|
|
|||
|
static struct i2c_driver sc7660_driver = {
|
|||
|
.class = I2C_CLASS_HWMON,
|
|||
|
.driver = {
|
|||
|
.name = sc7660_DRV_NAME,
|
|||
|
.owner = THIS_MODULE,
|
|||
|
},
|
|||
|
.probe = sc7660_probe,
|
|||
|
.remove = sc7660_remove,
|
|||
|
#ifdef CONFIG_HAS_EARLYSUSPEND
|
|||
|
#else
|
|||
|
#ifdef CONFIG_PM
|
|||
|
.suspend = sc7660_suspend,
|
|||
|
.resume = sc7660_resume,
|
|||
|
#endif
|
|||
|
#endif
|
|||
|
.id_table = sc7660_id,
|
|||
|
.detect = sc7660_gsensor_detect,
|
|||
|
.address_list = normal_i2c,
|
|||
|
};
|
|||
|
|
|||
|
static int __init sc7660_init(void)
|
|||
|
{
|
|||
|
int ret = -1;
|
|||
|
|
|||
|
printk("function=%s=========LINE=%d. \n", __func__,__LINE__);
|
|||
|
|
|||
|
if(input_sensor_startup(&(gsensor_info.input_type))){
|
|||
|
printk("%s: err.\n", __func__);
|
|||
|
return -1;
|
|||
|
} else
|
|||
|
ret = input_sensor_init(&(gsensor_info.input_type));
|
|||
|
|
|||
|
if (0 != ret){
|
|||
|
printk("%s:gsensor.init_platform_resource err. \n", __func__);
|
|||
|
}
|
|||
|
|
|||
|
twi_id = gsensor_info.twi_id;
|
|||
|
input_set_power_enable(&(gsensor_info.input_type),1);
|
|||
|
|
|||
|
ret = i2c_add_driver(&sc7660_driver);
|
|||
|
if (ret < 0) {
|
|||
|
printk( "add sc7660 i2c driver failed\n");
|
|||
|
return -ENODEV;
|
|||
|
}
|
|||
|
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
static void __exit sc7660_exit(void)
|
|||
|
{
|
|||
|
printk("remove sc7660 i2c driver.\n");
|
|||
|
i2c_del_driver(&sc7660_driver);
|
|||
|
input_sensor_free(&(gsensor_info.input_type));
|
|||
|
}
|
|||
|
|
|||
|
MODULE_AUTHOR("djq");
|
|||
|
MODULE_DESCRIPTION("sc7660 Sensor driver");
|
|||
|
MODULE_LICENSE("GPL");
|
|||
|
MODULE_VERSION("1.1");
|
|||
|
|
|||
|
module_init(sc7660_init);
|
|||
|
module_exit(sc7660_exit);
|
|||
|
|