xref: /OK3568_Linux_fs/kernel/drivers/input/sensors/accel/sc7a20.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* drivers/input/sensors/access/sc7a20.c
2*4882a593Smuzhiyun  *
3*4882a593Smuzhiyun  * Copyright (C) 2012-2015 ROCKCHIP.
4*4882a593Smuzhiyun  * Author: luowei <lw@rock-chips.com>
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * This software is licensed under the terms of the GNU General Public
7*4882a593Smuzhiyun  * License version 2, as published by the Free Software Foundation, and
8*4882a593Smuzhiyun  * may be copied, distributed, and modified under those terms.
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  * This program is distributed in the hope that it will be useful,
11*4882a593Smuzhiyun  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12*4882a593Smuzhiyun  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13*4882a593Smuzhiyun  * GNU General Public License for more details.
14*4882a593Smuzhiyun  *
15*4882a593Smuzhiyun  */
16*4882a593Smuzhiyun #include <linux/interrupt.h>
17*4882a593Smuzhiyun #include <linux/i2c.h>
18*4882a593Smuzhiyun #include <linux/slab.h>
19*4882a593Smuzhiyun #include <linux/irq.h>
20*4882a593Smuzhiyun #include <linux/miscdevice.h>
21*4882a593Smuzhiyun #include <linux/gpio.h>
22*4882a593Smuzhiyun #include <linux/uaccess.h>
23*4882a593Smuzhiyun #include <asm/atomic.h>
24*4882a593Smuzhiyun #include <linux/delay.h>
25*4882a593Smuzhiyun #include <linux/input.h>
26*4882a593Smuzhiyun #include <linux/workqueue.h>
27*4882a593Smuzhiyun #include <linux/freezer.h>
28*4882a593Smuzhiyun #ifdef CONFIG_HAS_EARLYSUSPEND
29*4882a593Smuzhiyun #include <linux/earlysuspend.h>
30*4882a593Smuzhiyun #endif
31*4882a593Smuzhiyun #include <linux/sensor-dev.h>
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #define SC7A20_ENABLE			1
34*4882a593Smuzhiyun #define SC7A20_XOUT_L			0x28
35*4882a593Smuzhiyun #define SC7A20_XOUT_H			0x29
36*4882a593Smuzhiyun #define SC7A20_YOUT_L			0x2A
37*4882a593Smuzhiyun #define SC7A20_YOUT_H			0x2B
38*4882a593Smuzhiyun #define SC7A20_ZOUT_L			0x2C
39*4882a593Smuzhiyun #define SC7A20_ZOUT_H			0x2D
40*4882a593Smuzhiyun #define SC7A20_MODE			0x20
41*4882a593Smuzhiyun #define SC7A20_MODE1			0x21
42*4882a593Smuzhiyun #define SC7A20_MODE2			0x22
43*4882a593Smuzhiyun #define SC7A20_MODE3			0x23
44*4882a593Smuzhiyun #define SC7A20_BOOT			0x24
45*4882a593Smuzhiyun #define SC7A20_STATUS			0x27
46*4882a593Smuzhiyun #define SC7A20_50HZ			0x40
47*4882a593Smuzhiyun #define SC7A20_100HZ			0x50
48*4882a593Smuzhiyun #define SC7A20_200HZ			0x60
49*4882a593Smuzhiyun #define SC7A20_400HZ			0x70
50*4882a593Smuzhiyun #define SC7A20_RANGE			32768
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun #define CALIBRATION_NUM		20//40
55*4882a593Smuzhiyun #define AXIS_X_Y_RANGE_LIMIT	200
56*4882a593Smuzhiyun #define AXIS_X_Y_AVG_LIMIT	400
57*4882a593Smuzhiyun #define AXIS_Z_RANGE		200
58*4882a593Smuzhiyun #define AXIS_Z_DFT_G		1000
59*4882a593Smuzhiyun #define GOTO_CALI		100
60*4882a593Smuzhiyun #define FAILTO_CALI		101
61*4882a593Smuzhiyun /* LIS3DH */
62*4882a593Smuzhiyun #define SC7A20_PRECISION        12
63*4882a593Smuzhiyun #define SC7A20_BOUNDARY		(0x1 << (SC7A20_PRECISION - 1))
64*4882a593Smuzhiyun #define SC7A20_GRAVITY_STEP	(SC7A20_RANGE / SC7A20_BOUNDARY)
65*4882a593Smuzhiyun 
66*4882a593Smuzhiyun #define SC7A20_COUNT_AVERAGE	2
67*4882a593Smuzhiyun 
68*4882a593Smuzhiyun //#define CFG_GSENSOR_CALIBFILE   "/data/data/com.actions.sensor.calib/files/gsensor_calib.txt"
69*4882a593Smuzhiyun /*noCreateAttr:the initial is 1-->no create attr. if created, change noCreateAttr to 0.*/
70*4882a593Smuzhiyun static int noCreateAttr = 1;
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun //static int sc7a20_acc_get_data( int *xyz);
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun struct SC7A20_acc{
78*4882a593Smuzhiyun     int    x;
79*4882a593Smuzhiyun     int    y;
80*4882a593Smuzhiyun     int    z;
81*4882a593Smuzhiyun } ;
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun static struct SC7A20_acc offset1;
84*4882a593Smuzhiyun //static int calibrated;
85*4882a593Smuzhiyun static struct i2c_client *sc7a20_client;
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun struct sensor_axis_average {
88*4882a593Smuzhiyun 		long x_average;
89*4882a593Smuzhiyun 		long y_average;
90*4882a593Smuzhiyun 		long z_average;
91*4882a593Smuzhiyun 		int count;
92*4882a593Smuzhiyun };
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun struct Cali_Data {
95*4882a593Smuzhiyun 	//mis p and n
96*4882a593Smuzhiyun 	unsigned char xpmis; //x axis positive mismatch to write
97*4882a593Smuzhiyun 	unsigned char xnmis; //x axis negtive mismatch to write
98*4882a593Smuzhiyun 	unsigned char ypmis;
99*4882a593Smuzhiyun 	unsigned char ynmis;
100*4882a593Smuzhiyun 	unsigned char zpmis;
101*4882a593Smuzhiyun 	unsigned char znmis;
102*4882a593Smuzhiyun 	//off p and n
103*4882a593Smuzhiyun 	unsigned char xpoff; //x axis positive offset to write
104*4882a593Smuzhiyun 	unsigned char xnoff; //x axis negtive offset to write
105*4882a593Smuzhiyun 	unsigned char ypoff;
106*4882a593Smuzhiyun 	unsigned char ynoff;
107*4882a593Smuzhiyun 	unsigned char zpoff;
108*4882a593Smuzhiyun 	unsigned char znoff;
109*4882a593Smuzhiyun 	//mid mis and off
110*4882a593Smuzhiyun 	unsigned char xmmis; //x axis middle mismatch to write
111*4882a593Smuzhiyun 	unsigned char ymmis; //y axis middle mismatch to write
112*4882a593Smuzhiyun 	unsigned char zmmis; //z axis middle mismatch to write
113*4882a593Smuzhiyun 	unsigned char xmoff; //x axis middle offset to write
114*4882a593Smuzhiyun 	unsigned char ymoff; //y axis middle offset to write
115*4882a593Smuzhiyun 	unsigned char zmoff; //z axis middle offset to write
116*4882a593Smuzhiyun 	//output p and n
117*4882a593Smuzhiyun 	signed int xpoutput; //x axis output of positive mismatch
118*4882a593Smuzhiyun 	signed int xnoutput; //x axis output of negtive mismatch
119*4882a593Smuzhiyun 	signed int ypoutput;
120*4882a593Smuzhiyun 	signed int ynoutput;
121*4882a593Smuzhiyun 	signed int zpoutput;
122*4882a593Smuzhiyun 	signed int znoutput;
123*4882a593Smuzhiyun 	//output
124*4882a593Smuzhiyun 	signed int xfoutput; //x axis the best or the temporary output
125*4882a593Smuzhiyun 	signed int yfoutput; //y axis the best or the temporary output
126*4882a593Smuzhiyun 	signed int zfoutput; //z axis the best or the temporary output
127*4882a593Smuzhiyun 	//final and temp flag
128*4882a593Smuzhiyun 	unsigned char xfinalf; //x axis final flag:if 1,calibration finished
129*4882a593Smuzhiyun 	unsigned char yfinalf; //y axis final flag:if 1,calibration finished
130*4882a593Smuzhiyun 	unsigned char zfinalf; //z axis final flag:if 1,calibration finished
131*4882a593Smuzhiyun 	unsigned char xtempf;  //x axis temp flag:if 1,the step calibration finished
132*4882a593Smuzhiyun 	unsigned char ytempf;  //y axis temp flag:if 1,the step calibration finished
133*4882a593Smuzhiyun 	unsigned char ztempf;  //z axis temp flag:if 1,the step calibration finished
134*4882a593Smuzhiyun 
135*4882a593Smuzhiyun 	unsigned char xaddmis;	//x axis mismtach register address
136*4882a593Smuzhiyun 	unsigned char yaddmis;	//y axis mismtach register address
137*4882a593Smuzhiyun 	unsigned char zaddmis;	//z axis mismtach register address
138*4882a593Smuzhiyun 	unsigned char xaddoff;	//x axis offset register address
139*4882a593Smuzhiyun 	unsigned char yaddoff;	//y axis offset register address
140*4882a593Smuzhiyun 	unsigned char zaddoff;	//z axis offset register address
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun 	unsigned char (*MisDataSpaceConvert)(unsigned char continuous);	//mismatch space convert function pointer
144*4882a593Smuzhiyun 	unsigned char (*OffDataSpaceConvert)(unsigned char continuous);	//offset space convert function pointer
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun 
148*4882a593Smuzhiyun 
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun };
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun static struct sensor_axis_average axis_average;
156*4882a593Smuzhiyun 
Read_Reg_sc7a20(unsigned char reg)157*4882a593Smuzhiyun static unsigned char Read_Reg_sc7a20(unsigned char reg)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun 	char buffer[3]={0};
160*4882a593Smuzhiyun 	*buffer = reg;
161*4882a593Smuzhiyun 	sensor_rx_data(sc7a20_client, buffer,1);
162*4882a593Smuzhiyun 	return buffer[0];
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 
Read_Output(char reg)166*4882a593Smuzhiyun static signed char Read_Output(char reg)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	char buffer[3] = {0};
170*4882a593Smuzhiyun 	signed char acc_buf[6];
171*4882a593Smuzhiyun         int index = 0;
172*4882a593Smuzhiyun         int ret   = 0;
173*4882a593Smuzhiyun 
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun          while(1)
176*4882a593Smuzhiyun 	 {
177*4882a593Smuzhiyun 
178*4882a593Smuzhiyun 			msleep(15);
179*4882a593Smuzhiyun 			*buffer = SC7A20_STATUS;
180*4882a593Smuzhiyun 			ret = sensor_rx_data(sc7a20_client, buffer,1);
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun 			if( (buffer[0] & 0x08) != 0 )
183*4882a593Smuzhiyun 			{
184*4882a593Smuzhiyun 				break;
185*4882a593Smuzhiyun 			}
186*4882a593Smuzhiyun 			//msleep(1);
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun                         index++;
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun                         if(index > 40)
191*4882a593Smuzhiyun                                 break;
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	}
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	*buffer = SC7A20_XOUT_L;
197*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer,1);
198*4882a593Smuzhiyun 	*buffer = SC7A20_XOUT_H;
199*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer,1);
200*4882a593Smuzhiyun 	acc_buf[1] = buffer[0];
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun 	*buffer = SC7A20_YOUT_L;
204*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer,1);
205*4882a593Smuzhiyun 	*buffer = SC7A20_YOUT_H;
206*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer,1);
207*4882a593Smuzhiyun 	acc_buf[3] = buffer[0];
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 	*buffer = SC7A20_ZOUT_L;
210*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer,1);
211*4882a593Smuzhiyun 	*buffer = SC7A20_ZOUT_H;
212*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer,1);
213*4882a593Smuzhiyun 	acc_buf[5] = buffer[0];
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	if(reg == 0x29)
217*4882a593Smuzhiyun 	{
218*4882a593Smuzhiyun 		return acc_buf[1];
219*4882a593Smuzhiyun 	}
220*4882a593Smuzhiyun 	else if(reg == 0x2b)
221*4882a593Smuzhiyun 	{
222*4882a593Smuzhiyun 		return acc_buf[3];
223*4882a593Smuzhiyun 	}
224*4882a593Smuzhiyun 	else if(reg == 0x2d)
225*4882a593Smuzhiyun 	{
226*4882a593Smuzhiyun 		return acc_buf[5];
227*4882a593Smuzhiyun 	}
228*4882a593Smuzhiyun 	else
229*4882a593Smuzhiyun 		return 0;
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun }
233*4882a593Smuzhiyun 
Read_Output_3axis(unsigned char * acc_buf)234*4882a593Smuzhiyun static void Read_Output_3axis(unsigned char *acc_buf)
235*4882a593Smuzhiyun {
236*4882a593Smuzhiyun 	char buffer[3] = {0};
237*4882a593Smuzhiyun 	int index = 0;
238*4882a593Smuzhiyun 	int ret   = 0;
239*4882a593Smuzhiyun 	while(1){
240*4882a593Smuzhiyun 			msleep(20);
241*4882a593Smuzhiyun 			*buffer = SC7A20_STATUS;
242*4882a593Smuzhiyun 			//ret = sensor_rx_data(sc7a20_client, buffer,1);
243*4882a593Smuzhiyun 				buffer[0] = Read_Reg_sc7a20(0x27);
244*4882a593Smuzhiyun 			if( (buffer[0] & 0x08) != 0 ){break;}
245*4882a593Smuzhiyun       index++;
246*4882a593Smuzhiyun       if(index > 40)break;
247*4882a593Smuzhiyun 	}
248*4882a593Smuzhiyun 	//6 register data be read out
249*4882a593Smuzhiyun 	*buffer = SC7A20_XOUT_L;
250*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer,1);
251*4882a593Smuzhiyun 	acc_buf[0] = buffer[0];
252*4882a593Smuzhiyun 	*buffer = SC7A20_XOUT_H;
253*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer,1);
254*4882a593Smuzhiyun 	acc_buf[1] = buffer[0];
255*4882a593Smuzhiyun 
256*4882a593Smuzhiyun 	*buffer = SC7A20_YOUT_L;
257*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer,1);
258*4882a593Smuzhiyun 	acc_buf[2] = buffer[0];
259*4882a593Smuzhiyun 	*buffer = SC7A20_YOUT_H;
260*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer,1);
261*4882a593Smuzhiyun 	acc_buf[3] = buffer[0];
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	*buffer = SC7A20_ZOUT_L;
264*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer,1);
265*4882a593Smuzhiyun 	acc_buf[4] = buffer[0];
266*4882a593Smuzhiyun 	*buffer = SC7A20_ZOUT_H;
267*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer,1);
268*4882a593Smuzhiyun 	acc_buf[5] = buffer[0];
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun 
Write_Input(char addr,char thedata)271*4882a593Smuzhiyun static void Write_Input(char addr, char thedata)
272*4882a593Smuzhiyun {
273*4882a593Smuzhiyun 	int result;
274*4882a593Smuzhiyun 	result = sensor_write_reg(sc7a20_client, addr, thedata);
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun 
tilt_3axis_mtp(signed int x,signed int y,signed int z)279*4882a593Smuzhiyun static void tilt_3axis_mtp(signed int x,signed int y,signed int z){
280*4882a593Smuzhiyun 	char buffer[6] = {0};
281*4882a593Smuzhiyun 	unsigned char buffer0[6] = {0};
282*4882a593Smuzhiyun 	unsigned char buffer1[6] = {0};
283*4882a593Smuzhiyun 	signed char mtpread[3]={0};
284*4882a593Smuzhiyun 	signed int xoutp,youtp,zoutp;
285*4882a593Smuzhiyun 	signed int xoutpt,youtpt,zoutpt;
286*4882a593Smuzhiyun 	signed char xtilt,ytilt,ztilt;
287*4882a593Smuzhiyun 	xoutp=youtp=zoutp=0;
288*4882a593Smuzhiyun 	xoutpt=youtpt=zoutpt=0;
289*4882a593Smuzhiyun 	xtilt=ytilt=ztilt=0;
290*4882a593Smuzhiyun 	Read_Output_3axis(buffer0);
291*4882a593Smuzhiyun 	Read_Output_3axis(buffer1);
292*4882a593Smuzhiyun 	//calculate the tilt with 12 ADC data
293*4882a593Smuzhiyun 	xoutpt = ((signed int)((buffer1[1]<<8)|buffer1[0]))>>4;
294*4882a593Smuzhiyun 	youtpt = ((signed int)((buffer1[3]<<8)|buffer1[2]))>>4;
295*4882a593Smuzhiyun 	zoutpt = ((signed int)((buffer1[5]<<8)|buffer1[4]))>>4;
296*4882a593Smuzhiyun 	//with relative value
297*4882a593Smuzhiyun 	xoutp = xoutpt-x*16;
298*4882a593Smuzhiyun 	youtp = youtpt-y*16;
299*4882a593Smuzhiyun 	zoutp = zoutpt-z*16;
300*4882a593Smuzhiyun 
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 	//read out the tilt value in mtp to calculate the new
303*4882a593Smuzhiyun 	*buffer = 0x10;
304*4882a593Smuzhiyun 	sensor_rx_data(sc7a20_client, buffer,1);
305*4882a593Smuzhiyun 	mtpread[0]=(signed char)buffer[0];
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun 	*buffer = 0x11;
308*4882a593Smuzhiyun 	sensor_rx_data(sc7a20_client, buffer,1);
309*4882a593Smuzhiyun 	mtpread[1]=(signed char)buffer[0];
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	*buffer = 0x12;
312*4882a593Smuzhiyun 	sensor_rx_data(sc7a20_client, buffer,1);
313*4882a593Smuzhiyun 	mtpread[2]=(signed char)buffer[0];
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun //	mtpread[0]= (signed char)Read_One_Byte(0x3a, 0x10);
317*4882a593Smuzhiyun //	mtpread[1]= (signed char)Read_One_Byte(0x3a, 0x11);
318*4882a593Smuzhiyun //	mtpread[2]= (signed char)Read_One_Byte(0x3a, 0x12);
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun 	//calculate the new tilt mtp value
321*4882a593Smuzhiyun 	xtilt=(signed char)(xoutp/8)+ mtpread[0];
322*4882a593Smuzhiyun 	ytilt=(signed char)(youtp/8)+ mtpread[1];
323*4882a593Smuzhiyun 	ztilt=(signed char)(zoutp/8)+ mtpread[2];
324*4882a593Smuzhiyun 
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun 
327*4882a593Smuzhiyun 
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 	//write the new into mtp
330*4882a593Smuzhiyun 	Write_Input(0x10,xtilt);
331*4882a593Smuzhiyun 	Write_Input(0x11,ytilt);
332*4882a593Smuzhiyun 	Write_Input(0x12,ztilt);
333*4882a593Smuzhiyun 
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun }
336*4882a593Smuzhiyun 
337*4882a593Smuzhiyun 
338*4882a593Smuzhiyun //正向
339*4882a593Smuzhiyun //255-0 map to 7f-0-80-ff
340*4882a593Smuzhiyun //
341*4882a593Smuzhiyun //255 map to 127(0x7f)
342*4882a593Smuzhiyun //254 map to 126(0x7e)
343*4882a593Smuzhiyun //.   map to .
344*4882a593Smuzhiyun //129 map to 001(0x01)
345*4882a593Smuzhiyun //128 map to 000(0x00)
346*4882a593Smuzhiyun //127 map to 128(0x80)
347*4882a593Smuzhiyun //126 map to 129(0x81)
348*4882a593Smuzhiyun //.   map to .
349*4882a593Smuzhiyun //001 map to 254(0xfe)
350*4882a593Smuzhiyun //000 map to 255(0xff)
forword_MisDataSpaceConvert(unsigned char continuous)351*4882a593Smuzhiyun static unsigned char forword_MisDataSpaceConvert(unsigned char continuous)
352*4882a593Smuzhiyun {
353*4882a593Smuzhiyun 	if(continuous >= 128)
354*4882a593Smuzhiyun 		return continuous - 128;
355*4882a593Smuzhiyun 	else
356*4882a593Smuzhiyun 		return 255 - continuous;
357*4882a593Smuzhiyun }
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun //反向
360*4882a593Smuzhiyun //255-0 map to ff-80-00-7f
361*4882a593Smuzhiyun //
362*4882a593Smuzhiyun //255 map to 255(0xff)
363*4882a593Smuzhiyun //254 map to 254(0xfe)
364*4882a593Smuzhiyun //.   map to .
365*4882a593Smuzhiyun //129 map to 129(0x81)
366*4882a593Smuzhiyun //128 map to 128(0x80)
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun //127 map to 0(0x00)
369*4882a593Smuzhiyun //126 map to 1(0x01)
370*4882a593Smuzhiyun //.   map to .
371*4882a593Smuzhiyun //001 map to 126(0x7e)
372*4882a593Smuzhiyun //000 map to 127(0x7f)
reverse_MisDataSpaceConvert(unsigned char continuous)373*4882a593Smuzhiyun static unsigned char reverse_MisDataSpaceConvert(unsigned char continuous)
374*4882a593Smuzhiyun {
375*4882a593Smuzhiyun 	if(continuous >= 128)
376*4882a593Smuzhiyun 		return continuous;
377*4882a593Smuzhiyun 	else
378*4882a593Smuzhiyun 		return 127 - continuous;
379*4882a593Smuzhiyun }
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun 
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun //reverse
385*4882a593Smuzhiyun //7f-0 map to 0-7f
386*4882a593Smuzhiyun //
387*4882a593Smuzhiyun 
reverse_OffDataSpaceConvert(unsigned char continuous)388*4882a593Smuzhiyun static unsigned char reverse_OffDataSpaceConvert(unsigned char continuous)
389*4882a593Smuzhiyun {
390*4882a593Smuzhiyun 		return 127 - continuous;
391*4882a593Smuzhiyun }
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun //forword
394*4882a593Smuzhiyun //7f-0 map to 0-7f
395*4882a593Smuzhiyun //
396*4882a593Smuzhiyun 
forword_OffDataSpaceConvert(unsigned char continuous)397*4882a593Smuzhiyun static unsigned char forword_OffDataSpaceConvert(unsigned char continuous)
398*4882a593Smuzhiyun {
399*4882a593Smuzhiyun 		return continuous;
400*4882a593Smuzhiyun }
401*4882a593Smuzhiyun 
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun 
check_output_set_finalflag(struct Cali_Data * pcalidata,unsigned char err)412*4882a593Smuzhiyun static void check_output_set_finalflag(struct Cali_Data *pcalidata,unsigned char err){
413*4882a593Smuzhiyun 
414*4882a593Smuzhiyun 	if(abs(pcalidata->xfoutput) < err){
415*4882a593Smuzhiyun 		//printk("line:%d Xcali finish!Final=%d\n",__LINE__,pcalidata->xfoutput);
416*4882a593Smuzhiyun 		pcalidata->xfinalf=1;
417*4882a593Smuzhiyun 	}
418*4882a593Smuzhiyun 	if(abs(pcalidata->yfoutput) < err){
419*4882a593Smuzhiyun 		//printk("line:%d Xcali finish!Final=%d\n",__LINE__,pcalidata->yfoutput);
420*4882a593Smuzhiyun 		pcalidata->yfinalf=1;
421*4882a593Smuzhiyun 	}
422*4882a593Smuzhiyun 	if(abs(pcalidata->zfoutput) < err){
423*4882a593Smuzhiyun 		//printk("line:%d Xcali finish!Final=%d\n",__LINE__,pcalidata->zfoutput);
424*4882a593Smuzhiyun 		pcalidata->zfinalf=1;
425*4882a593Smuzhiyun 	}
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun }
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun 
432*4882a593Smuzhiyun //set the tempflag xtempf-ytempf-ztempf upto the finalflag
check_finalflag_set_tempflag(struct Cali_Data * pcalidata)433*4882a593Smuzhiyun static void check_finalflag_set_tempflag(struct Cali_Data *pcalidata){
434*4882a593Smuzhiyun 	if(pcalidata->xfinalf){pcalidata->xtempf=1;}
435*4882a593Smuzhiyun 	if(pcalidata->yfinalf){pcalidata->ytempf=1;}
436*4882a593Smuzhiyun 	if(pcalidata->zfinalf){pcalidata->ztempf=1;}
437*4882a593Smuzhiyun }
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun //return ornot,upto xfinalf-yfinalf-zfinalf
check_flag_is_return(struct Cali_Data * pcalidata)441*4882a593Smuzhiyun static unsigned char check_flag_is_return(struct Cali_Data *pcalidata){
442*4882a593Smuzhiyun 	if((pcalidata->xfinalf) && (pcalidata->yfinalf) && (pcalidata->zfinalf))
443*4882a593Smuzhiyun 	{
444*4882a593Smuzhiyun 		//printk("line:%d Allcali finish!\n",__LINE__);
445*4882a593Smuzhiyun 		return 1;//xyz cali ok
446*4882a593Smuzhiyun 	}
447*4882a593Smuzhiyun 	else return 0;
448*4882a593Smuzhiyun }
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun //updata middle mismatch register with the new mismatch
updata_midmis_address(struct Cali_Data * pcalidata)453*4882a593Smuzhiyun static void updata_midmis_address(struct Cali_Data *pcalidata){
454*4882a593Smuzhiyun 	if(pcalidata->xtempf==0){
455*4882a593Smuzhiyun 		pcalidata->xmmis=(unsigned char)(((unsigned int)(pcalidata->xpmis) + (unsigned int)(pcalidata->xnmis))/2);
456*4882a593Smuzhiyun 		pcalidata->MisDataSpaceConvert = reverse_MisDataSpaceConvert;
457*4882a593Smuzhiyun 		Write_Input(pcalidata->xaddmis, (*(pcalidata->MisDataSpaceConvert))(pcalidata->xmmis));
458*4882a593Smuzhiyun 	}
459*4882a593Smuzhiyun 	if(pcalidata->ytempf==0){
460*4882a593Smuzhiyun 		pcalidata->ymmis=(unsigned char)(((unsigned int)(pcalidata->ypmis) + (unsigned int)(pcalidata->ynmis))/2);
461*4882a593Smuzhiyun 		pcalidata->MisDataSpaceConvert = forword_MisDataSpaceConvert;
462*4882a593Smuzhiyun 		Write_Input(pcalidata->yaddmis, (*(pcalidata->MisDataSpaceConvert))(pcalidata->ymmis));
463*4882a593Smuzhiyun 	}
464*4882a593Smuzhiyun 	if(pcalidata->ztempf==0){
465*4882a593Smuzhiyun 		pcalidata->zmmis=(unsigned char)(((unsigned int)(pcalidata->zpmis) + (unsigned int)(pcalidata->znmis))/2);
466*4882a593Smuzhiyun 		pcalidata->MisDataSpaceConvert = reverse_MisDataSpaceConvert;
467*4882a593Smuzhiyun 		Write_Input(pcalidata->zaddmis, (*(pcalidata->MisDataSpaceConvert))(pcalidata->zmmis));
468*4882a593Smuzhiyun 	}
469*4882a593Smuzhiyun }
470*4882a593Smuzhiyun 
471*4882a593Smuzhiyun 
472*4882a593Smuzhiyun //updata middle offset register with the new offset
updata_midoff_address(struct Cali_Data * pcalidata)473*4882a593Smuzhiyun static void updata_midoff_address(struct Cali_Data *pcalidata){
474*4882a593Smuzhiyun 	if(pcalidata->xtempf==0){
475*4882a593Smuzhiyun 		pcalidata->xmoff=(unsigned char)(((unsigned int)(pcalidata->xpoff) + (unsigned int)(pcalidata->xnoff))/2);
476*4882a593Smuzhiyun 		pcalidata->OffDataSpaceConvert = reverse_OffDataSpaceConvert;
477*4882a593Smuzhiyun 		Write_Input(pcalidata->xaddoff, (*(pcalidata->OffDataSpaceConvert))(pcalidata->xmoff));
478*4882a593Smuzhiyun 	}
479*4882a593Smuzhiyun 	if(pcalidata->ytempf==0){
480*4882a593Smuzhiyun 		pcalidata->ymoff=(unsigned char)(((unsigned int)(pcalidata->ypoff) + (unsigned int)(pcalidata->ynoff))/2);
481*4882a593Smuzhiyun 		pcalidata->OffDataSpaceConvert = forword_OffDataSpaceConvert;
482*4882a593Smuzhiyun 		Write_Input(pcalidata->yaddoff, (*(pcalidata->OffDataSpaceConvert))(pcalidata->ymoff));
483*4882a593Smuzhiyun 	}
484*4882a593Smuzhiyun 	if(pcalidata->ztempf==0){
485*4882a593Smuzhiyun 		pcalidata->zmoff=(unsigned char)(((unsigned int)(pcalidata->zpoff) + (unsigned int)(pcalidata->znoff))/2);
486*4882a593Smuzhiyun 		pcalidata->OffDataSpaceConvert = forword_OffDataSpaceConvert;
487*4882a593Smuzhiyun 		Write_Input(pcalidata->zaddoff, (*(pcalidata->OffDataSpaceConvert))(pcalidata->zmoff));
488*4882a593Smuzhiyun 	}
489*4882a593Smuzhiyun }
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun 
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun 
updata_mmis_pnfoutput_set_tempflag(struct Cali_Data * pcalidata,unsigned char * buf,signed int xrel,signed int yrel,signed int zrel)494*4882a593Smuzhiyun static void updata_mmis_pnfoutput_set_tempflag(	struct Cali_Data *pcalidata,
495*4882a593Smuzhiyun 											unsigned char *buf,
496*4882a593Smuzhiyun 										  	signed int xrel,
497*4882a593Smuzhiyun 										  	signed int yrel,
498*4882a593Smuzhiyun 										  	signed int zrel){
499*4882a593Smuzhiyun 	//output 2 struct data
500*4882a593Smuzhiyun 	pcalidata->xfoutput=(signed int)((signed char)buf[1])-xrel;
501*4882a593Smuzhiyun 	pcalidata->yfoutput=(signed int)((signed char)buf[3])-yrel;
502*4882a593Smuzhiyun 	pcalidata->zfoutput=(signed int)((signed char)buf[5])-zrel;
503*4882a593Smuzhiyun 
504*4882a593Smuzhiyun 	if(abs(pcalidata->xfoutput)<25)pcalidata->xtempf=1;
505*4882a593Smuzhiyun 	if(abs(pcalidata->yfoutput)<25)pcalidata->ytempf=1;
506*4882a593Smuzhiyun 	if(abs(pcalidata->zfoutput)<25)pcalidata->ztempf=1;
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun 	if(pcalidata->xtempf==0)
509*4882a593Smuzhiyun 	{
510*4882a593Smuzhiyun 		if(pcalidata->xfoutput>0){
511*4882a593Smuzhiyun 			pcalidata->xpoutput = pcalidata->xfoutput;
512*4882a593Smuzhiyun 			pcalidata->xpmis = pcalidata->xmmis;
513*4882a593Smuzhiyun 		}
514*4882a593Smuzhiyun 		else{
515*4882a593Smuzhiyun 			pcalidata->xnoutput = pcalidata->xfoutput;
516*4882a593Smuzhiyun 			pcalidata->xnmis = pcalidata->xmmis;
517*4882a593Smuzhiyun 		}
518*4882a593Smuzhiyun 	}
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun 	if(pcalidata->ytempf==0)
521*4882a593Smuzhiyun 	{
522*4882a593Smuzhiyun 		if(pcalidata->yfoutput>0){
523*4882a593Smuzhiyun 			pcalidata->ypoutput = pcalidata->yfoutput;
524*4882a593Smuzhiyun 			pcalidata->ypmis = pcalidata->ymmis;
525*4882a593Smuzhiyun 		}
526*4882a593Smuzhiyun 		else{
527*4882a593Smuzhiyun 			pcalidata->ynoutput = pcalidata->yfoutput;
528*4882a593Smuzhiyun 			pcalidata->ynmis = pcalidata->ymmis;
529*4882a593Smuzhiyun 		}
530*4882a593Smuzhiyun 	}
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun 	if(pcalidata->ztempf==0)
533*4882a593Smuzhiyun 	{
534*4882a593Smuzhiyun 		if(pcalidata->zfoutput>0){
535*4882a593Smuzhiyun 			pcalidata->zpoutput = pcalidata->zfoutput;
536*4882a593Smuzhiyun 			pcalidata->zpmis = pcalidata->zmmis;
537*4882a593Smuzhiyun 		}
538*4882a593Smuzhiyun 		else{
539*4882a593Smuzhiyun 			pcalidata->znoutput = pcalidata->zfoutput;
540*4882a593Smuzhiyun 			pcalidata->znmis = pcalidata->zmmis;
541*4882a593Smuzhiyun 		}
542*4882a593Smuzhiyun 	}
543*4882a593Smuzhiyun }
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun 
updata_moff_pnfoutput_set_tempflag(struct Cali_Data * pcalidata,unsigned char * buf,signed int xrel,signed int yrel,signed int zrel)547*4882a593Smuzhiyun static void updata_moff_pnfoutput_set_tempflag(	struct Cali_Data *pcalidata,
548*4882a593Smuzhiyun 											unsigned char *buf,
549*4882a593Smuzhiyun 										  	signed int xrel,
550*4882a593Smuzhiyun 										  	signed int yrel,
551*4882a593Smuzhiyun 										  	signed int zrel){
552*4882a593Smuzhiyun 	//output 2 struct data
553*4882a593Smuzhiyun 	pcalidata->xfoutput=(signed int)((signed char)buf[1])-xrel;
554*4882a593Smuzhiyun 	pcalidata->yfoutput=(signed int)((signed char)buf[3])-yrel;
555*4882a593Smuzhiyun 	pcalidata->zfoutput=(signed int)((signed char)buf[5])-zrel;
556*4882a593Smuzhiyun 
557*4882a593Smuzhiyun 	if(abs(pcalidata->xfoutput)<3)pcalidata->xtempf=1;
558*4882a593Smuzhiyun 	if(abs(pcalidata->yfoutput)<3)pcalidata->ytempf=1;
559*4882a593Smuzhiyun 	if(abs(pcalidata->zfoutput)<3)pcalidata->ztempf=1;
560*4882a593Smuzhiyun 
561*4882a593Smuzhiyun 	if(pcalidata->xtempf==0)
562*4882a593Smuzhiyun 	{
563*4882a593Smuzhiyun 		if(pcalidata->xfoutput>0){
564*4882a593Smuzhiyun 			pcalidata->xpoutput = pcalidata->xfoutput;
565*4882a593Smuzhiyun 			pcalidata->xpoff = pcalidata->xmoff;
566*4882a593Smuzhiyun 		}
567*4882a593Smuzhiyun 		else{
568*4882a593Smuzhiyun 			pcalidata->xnoutput = pcalidata->xfoutput;
569*4882a593Smuzhiyun 			pcalidata->xnoff = pcalidata->xmoff;
570*4882a593Smuzhiyun 		}
571*4882a593Smuzhiyun 	}
572*4882a593Smuzhiyun 
573*4882a593Smuzhiyun 	if(pcalidata->ytempf==0)
574*4882a593Smuzhiyun 	{
575*4882a593Smuzhiyun 		if(pcalidata->yfoutput>0){
576*4882a593Smuzhiyun 			pcalidata->ypoutput = pcalidata->yfoutput;
577*4882a593Smuzhiyun 			pcalidata->ypoff = pcalidata->ymoff;
578*4882a593Smuzhiyun 		}
579*4882a593Smuzhiyun 		else{
580*4882a593Smuzhiyun 			pcalidata->ynoutput = pcalidata->yfoutput;
581*4882a593Smuzhiyun 			pcalidata->ynoff = pcalidata->ymoff;
582*4882a593Smuzhiyun 		}
583*4882a593Smuzhiyun 	}
584*4882a593Smuzhiyun 
585*4882a593Smuzhiyun 	if(pcalidata->ztempf==0)
586*4882a593Smuzhiyun 	{
587*4882a593Smuzhiyun 		if(pcalidata->zfoutput>0){
588*4882a593Smuzhiyun 			pcalidata->zpoutput = pcalidata->zfoutput;
589*4882a593Smuzhiyun 			pcalidata->zpoff = pcalidata->zmoff;
590*4882a593Smuzhiyun 		}
591*4882a593Smuzhiyun 		else{
592*4882a593Smuzhiyun 			pcalidata->znoutput = pcalidata->zfoutput;
593*4882a593Smuzhiyun 			pcalidata->znoff = pcalidata->zmoff;
594*4882a593Smuzhiyun 		}
595*4882a593Smuzhiyun 	}
596*4882a593Smuzhiyun }
597*4882a593Smuzhiyun 
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun 
auto_calibration_instant_sc7a20(signed int x,signed int y,signed int z)600*4882a593Smuzhiyun static int auto_calibration_instant_sc7a20(signed int x, signed int y, signed int z){
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun 
603*4882a593Smuzhiyun 	unsigned char count=0,cyclecount=0;
604*4882a593Smuzhiyun 	unsigned char acc_buf[6];
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun 	struct Cali_Data calidata={0};
607*4882a593Smuzhiyun 
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun //===========================================================================
610*4882a593Smuzhiyun //===========================================================================
611*4882a593Smuzhiyun //step0=initialization
612*4882a593Smuzhiyun 	calidata.xaddmis = 0x40;
613*4882a593Smuzhiyun 	calidata.yaddmis = 0x41;
614*4882a593Smuzhiyun 	calidata.zaddmis = 0x42;
615*4882a593Smuzhiyun 	calidata.xaddoff = 0x47;
616*4882a593Smuzhiyun 	calidata.yaddoff = 0x48;
617*4882a593Smuzhiyun 	calidata.zaddoff = 0x49;
618*4882a593Smuzhiyun #ifdef PRINT
619*4882a593Smuzhiyun 	printf("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
620*4882a593Smuzhiyun 				(UINT)calidata.xfinalf,(UINT)calidata.xtempf,
621*4882a593Smuzhiyun 				(UINT)calidata.yfinalf,(UINT)calidata.ytempf,
622*4882a593Smuzhiyun 				(UINT)calidata.zfinalf,(UINT)calidata.ztempf
623*4882a593Smuzhiyun 				);
624*4882a593Smuzhiyun #endif
625*4882a593Smuzhiyun 
626*4882a593Smuzhiyun 
627*4882a593Smuzhiyun 
628*4882a593Smuzhiyun 
629*4882a593Smuzhiyun //===========================================================================
630*4882a593Smuzhiyun //===========================================================================
631*4882a593Smuzhiyun //step1=if output is ok?
632*4882a593Smuzhiyun 	Read_Output_3axis(acc_buf);
633*4882a593Smuzhiyun 	calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
634*4882a593Smuzhiyun 	calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
635*4882a593Smuzhiyun 	calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
636*4882a593Smuzhiyun 	check_output_set_finalflag(&calidata,2);
637*4882a593Smuzhiyun 	if(check_flag_is_return(&calidata)){
638*4882a593Smuzhiyun 		printk("step1:=file=%s,line=%d\n",__FILE__,__LINE__);
639*4882a593Smuzhiyun 		return 1;
640*4882a593Smuzhiyun 	}
641*4882a593Smuzhiyun #ifdef PRINT
642*4882a593Smuzhiyun 	printf("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
643*4882a593Smuzhiyun 				(UINT)calidata.xfinalf,(UINT)calidata.xtempf,
644*4882a593Smuzhiyun 				(UINT)calidata.yfinalf,(UINT)calidata.ytempf,
645*4882a593Smuzhiyun 				(UINT)calidata.zfinalf,(UINT)calidata.ztempf
646*4882a593Smuzhiyun 				);
647*4882a593Smuzhiyun #endif
648*4882a593Smuzhiyun 
649*4882a593Smuzhiyun 
650*4882a593Smuzhiyun 
651*4882a593Smuzhiyun 
652*4882a593Smuzhiyun 
653*4882a593Smuzhiyun //===========================================================================
654*4882a593Smuzhiyun //===========================================================================
655*4882a593Smuzhiyun //step2=can cali?
656*4882a593Smuzhiyun //max output reasonable?
657*4882a593Smuzhiyun //	calidata.zfinalf=1;
658*4882a593Smuzhiyun 	if(calidata.xfinalf==0){
659*4882a593Smuzhiyun 		Write_Input(calidata.xaddoff, 0x3f);//cali mis under off=0x3f
660*4882a593Smuzhiyun 		Write_Input(0x10, 0); //tilt clear
661*4882a593Smuzhiyun 		calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
662*4882a593Smuzhiyun 		Write_Input(calidata.xaddmis, (*(calidata.MisDataSpaceConvert))(255)); // x mis to max
663*4882a593Smuzhiyun 	}
664*4882a593Smuzhiyun 	if(calidata.yfinalf==0){
665*4882a593Smuzhiyun 		Write_Input(calidata.yaddoff, 0x3f);//cali mis under off=0x3f
666*4882a593Smuzhiyun 		Write_Input(0x11, 0); //tilt clear
667*4882a593Smuzhiyun 		calidata.MisDataSpaceConvert = forword_MisDataSpaceConvert;
668*4882a593Smuzhiyun 		Write_Input(calidata.yaddmis, (*(calidata.MisDataSpaceConvert))(255)); // y mis to max
669*4882a593Smuzhiyun 	}
670*4882a593Smuzhiyun 	if(calidata.zfinalf==0){
671*4882a593Smuzhiyun 		Write_Input(calidata.zaddoff, 0x3f);//cali mis under off=0x3f
672*4882a593Smuzhiyun 		Write_Input(0x12, 0); //tilt clear
673*4882a593Smuzhiyun 		calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
674*4882a593Smuzhiyun 		Write_Input(calidata.zaddmis, (*(calidata.MisDataSpaceConvert))(255)); // z mis to max
675*4882a593Smuzhiyun 	}
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun 	Read_Output_3axis(acc_buf);
678*4882a593Smuzhiyun 	calidata.xpoutput=calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
679*4882a593Smuzhiyun 	calidata.ypoutput=calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
680*4882a593Smuzhiyun 	calidata.zpoutput=calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
681*4882a593Smuzhiyun 	printk("step 2 xnoutput = %d ynoutput = %d znoutput = %d \n",calidata.xnoutput,calidata.ynoutput,calidata.znoutput);
682*4882a593Smuzhiyun 	if((calidata.xpoutput<-25)||(calidata.ypoutput<-25)||(calidata.zpoutput<-25)){
683*4882a593Smuzhiyun 		printk("step2:=file=%s,line=%d\n",__FILE__,__LINE__);
684*4882a593Smuzhiyun                 sensor_write_reg(sc7a20_client,0x13,0x01);//allen
685*4882a593Smuzhiyun                 Write_Input(0x1e, 0x15);  //保存校准寄存器的修改
686*4882a593Smuzhiyun                 mdelay(300);
687*4882a593Smuzhiyun                 Write_Input(0x1e, 0);
688*4882a593Smuzhiyun 		return 0;
689*4882a593Smuzhiyun 	}//if the max output is smaller than -25,then errs
690*4882a593Smuzhiyun 
691*4882a593Smuzhiyun 	//min output reasonable?
692*4882a593Smuzhiyun 	if(calidata.xfinalf==0){
693*4882a593Smuzhiyun 		calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
694*4882a593Smuzhiyun 		Write_Input(calidata.xaddmis, (*(calidata.MisDataSpaceConvert))(0)); // x mis to min
695*4882a593Smuzhiyun 	}
696*4882a593Smuzhiyun 	if(calidata.yfinalf==0){
697*4882a593Smuzhiyun 		calidata.MisDataSpaceConvert = forword_MisDataSpaceConvert;
698*4882a593Smuzhiyun 		Write_Input(calidata.yaddmis, (*(calidata.MisDataSpaceConvert))(0)); // y mis to min
699*4882a593Smuzhiyun 	}
700*4882a593Smuzhiyun 	if(calidata.zfinalf==0){
701*4882a593Smuzhiyun 		calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
702*4882a593Smuzhiyun 		Write_Input(calidata.zaddmis, (*(calidata.MisDataSpaceConvert))(0)); // z mis to min
703*4882a593Smuzhiyun 	}
704*4882a593Smuzhiyun 	Read_Output_3axis(acc_buf);
705*4882a593Smuzhiyun 	calidata.xnoutput=calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
706*4882a593Smuzhiyun 	calidata.ynoutput=calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
707*4882a593Smuzhiyun 	calidata.znoutput=calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
708*4882a593Smuzhiyun 	printk("step 2 xnoutput = %d ynoutput = %d znoutput = %d \n",calidata.xnoutput,calidata.ynoutput,calidata.znoutput);
709*4882a593Smuzhiyun 	if((calidata.xnoutput>25)||(calidata.ynoutput>25)||(calidata.znoutput>25)){
710*4882a593Smuzhiyun 		printk("step2:=file=%s,line=%d\n",__FILE__,__LINE__);
711*4882a593Smuzhiyun                 sensor_write_reg(sc7a20_client,0x13,0x01);//allen
712*4882a593Smuzhiyun                 Write_Input(0x1e, 0x15);  //保存校准寄存器的修改
713*4882a593Smuzhiyun                 mdelay(300);
714*4882a593Smuzhiyun                 Write_Input(0x1e, 0);
715*4882a593Smuzhiyun 
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun 		return 0;
718*4882a593Smuzhiyun 	}
719*4882a593Smuzhiyun 
720*4882a593Smuzhiyun 	//get the the smaller output,maybe the calibration finished
721*4882a593Smuzhiyun 	if(abs(calidata.xpoutput)<=abs(calidata.xnoutput)){
722*4882a593Smuzhiyun 		calidata.xfoutput=calidata.xpoutput;
723*4882a593Smuzhiyun 		calidata.xmmis=255;
724*4882a593Smuzhiyun 	}
725*4882a593Smuzhiyun 	else{
726*4882a593Smuzhiyun 		calidata.xfoutput=calidata.xnoutput;
727*4882a593Smuzhiyun 		calidata.xmmis=0;
728*4882a593Smuzhiyun 	}
729*4882a593Smuzhiyun 	if(abs(calidata.ypoutput)<=abs(calidata.ynoutput)){
730*4882a593Smuzhiyun 		calidata.yfoutput=calidata.ypoutput;
731*4882a593Smuzhiyun 		calidata.ymmis=255;
732*4882a593Smuzhiyun 	}
733*4882a593Smuzhiyun 	else{
734*4882a593Smuzhiyun 		calidata.yfoutput=calidata.ynoutput;
735*4882a593Smuzhiyun 		calidata.ymmis=0;
736*4882a593Smuzhiyun 	}
737*4882a593Smuzhiyun 	if(abs(calidata.zpoutput)<=abs(calidata.znoutput)){
738*4882a593Smuzhiyun 		calidata.zfoutput=calidata.zpoutput;
739*4882a593Smuzhiyun 		calidata.zmmis=255;
740*4882a593Smuzhiyun 	}
741*4882a593Smuzhiyun 	else{
742*4882a593Smuzhiyun 		calidata.zfoutput=calidata.znoutput;
743*4882a593Smuzhiyun 		calidata.zmmis=0;
744*4882a593Smuzhiyun 	}
745*4882a593Smuzhiyun 	//write the mismatch of the smaller output into register
746*4882a593Smuzhiyun 	if(calidata.xfinalf==0){
747*4882a593Smuzhiyun 		calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
748*4882a593Smuzhiyun 		Write_Input(calidata.xaddmis, (*(calidata.MisDataSpaceConvert))(calidata.xmmis));
749*4882a593Smuzhiyun 	}
750*4882a593Smuzhiyun 	if(calidata.yfinalf==0){
751*4882a593Smuzhiyun 		calidata.MisDataSpaceConvert = forword_MisDataSpaceConvert;
752*4882a593Smuzhiyun 		Write_Input(calidata.yaddmis, (*(calidata.MisDataSpaceConvert))(calidata.ymmis));
753*4882a593Smuzhiyun 	}
754*4882a593Smuzhiyun 	if(calidata.zfinalf==0){
755*4882a593Smuzhiyun 		calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
756*4882a593Smuzhiyun 		Write_Input(calidata.zaddmis, (*(calidata.MisDataSpaceConvert))(calidata.zmmis));
757*4882a593Smuzhiyun 	}
758*4882a593Smuzhiyun 	check_output_set_finalflag(&calidata,2);
759*4882a593Smuzhiyun 	//if the smaller output <25,the step3 mis is finished
760*4882a593Smuzhiyun 	if(abs(calidata.xfoutput)<25) calidata.xtempf=1;
761*4882a593Smuzhiyun 	if(abs(calidata.yfoutput)<25) calidata.ytempf=1;
762*4882a593Smuzhiyun 	if(abs(calidata.zfoutput)<25) calidata.ztempf=1;
763*4882a593Smuzhiyun //can cali?
764*4882a593Smuzhiyun //===========================================================================
765*4882a593Smuzhiyun 
766*4882a593Smuzhiyun 
767*4882a593Smuzhiyun //===========================================================================
768*4882a593Smuzhiyun //===========================================================================
769*4882a593Smuzhiyun //step3=cali mis for zero in 25 LSB
770*4882a593Smuzhiyun 	calidata.xpmis=calidata.ypmis=calidata.zpmis=255;
771*4882a593Smuzhiyun 	calidata.xnmis=calidata.ynmis=calidata.znmis=0;
772*4882a593Smuzhiyun 	check_finalflag_set_tempflag(&calidata);
773*4882a593Smuzhiyun #ifdef PRINT
774*4882a593Smuzhiyun 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
775*4882a593Smuzhiyun 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
776*4882a593Smuzhiyun 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
777*4882a593Smuzhiyun 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
778*4882a593Smuzhiyun 				);
779*4882a593Smuzhiyun #endif
780*4882a593Smuzhiyun 	cyclecount=0;
781*4882a593Smuzhiyun 	while(1){
782*4882a593Smuzhiyun 		if(++cyclecount>20)break;//if some errs happened,the cyclecount exceeded
783*4882a593Smuzhiyun 
784*4882a593Smuzhiyun 		if((calidata.xtempf)&&(calidata.ytempf)&&(calidata.ztempf))break;
785*4882a593Smuzhiyun 		updata_midmis_address(&calidata);
786*4882a593Smuzhiyun 		Read_Output_3axis(acc_buf);
787*4882a593Smuzhiyun 		calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
788*4882a593Smuzhiyun 		calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
789*4882a593Smuzhiyun 		calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
790*4882a593Smuzhiyun #ifdef PRINT
791*4882a593Smuzhiyun 		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",
792*4882a593Smuzhiyun 				calidata.xpoutput,(unsigned int)calidata.xpmis,
793*4882a593Smuzhiyun 				calidata.xfoutput,(unsigned int)calidata.xmmis,
794*4882a593Smuzhiyun 				calidata.xnoutput,(unsigned int)calidata.xnmis,
795*4882a593Smuzhiyun 				calidata.ypoutput,(unsigned int)calidata.ypmis,
796*4882a593Smuzhiyun 				calidata.yfoutput,(unsigned int)calidata.ymmis,
797*4882a593Smuzhiyun 				calidata.ynoutput,(unsigned int)calidata.ynmis,
798*4882a593Smuzhiyun 				calidata.zpoutput,(unsigned int)calidata.zpmis,
799*4882a593Smuzhiyun 				calidata.zfoutput,(unsigned int)calidata.zmmis,
800*4882a593Smuzhiyun 				calidata.znoutput,(unsigned int)calidata.znmis
801*4882a593Smuzhiyun 				);
802*4882a593Smuzhiyun #endif
803*4882a593Smuzhiyun 		updata_mmis_pnfoutput_set_tempflag(&calidata,acc_buf,x,y,z);
804*4882a593Smuzhiyun 		check_output_set_finalflag(&calidata,2);
805*4882a593Smuzhiyun 		if(check_flag_is_return(&calidata))return 1;
806*4882a593Smuzhiyun 	}
807*4882a593Smuzhiyun #ifdef PRINT
808*4882a593Smuzhiyun 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
809*4882a593Smuzhiyun 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
810*4882a593Smuzhiyun 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
811*4882a593Smuzhiyun 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
812*4882a593Smuzhiyun 				);
813*4882a593Smuzhiyun #endif
814*4882a593Smuzhiyun //cali mis for zero in 25 LSB
815*4882a593Smuzhiyun //===========================================================================
816*4882a593Smuzhiyun 
817*4882a593Smuzhiyun 
818*4882a593Smuzhiyun //===========================================================================
819*4882a593Smuzhiyun //===========================================================================
820*4882a593Smuzhiyun //step4=cali mis for rel and the most fit
821*4882a593Smuzhiyun 	calidata.xtempf=calidata.ytempf=calidata.ztempf=1;
822*4882a593Smuzhiyun 	if((calidata.xmmis>0)&&(calidata.xmmis<255))calidata.xtempf=0;
823*4882a593Smuzhiyun 	if((calidata.ymmis>0)&&(calidata.ymmis<255))calidata.ytempf=0;
824*4882a593Smuzhiyun 	if((calidata.zmmis>0)&&(calidata.zmmis<255))calidata.ztempf=0;
825*4882a593Smuzhiyun 	calidata.xpmis=calidata.xnmis=calidata.xmmis;
826*4882a593Smuzhiyun 	calidata.ypmis=calidata.ynmis=calidata.ymmis;
827*4882a593Smuzhiyun 	calidata.zpmis=calidata.znmis=calidata.zmmis;
828*4882a593Smuzhiyun 	for(count = 0; count < 3; count++)
829*4882a593Smuzhiyun 	{
830*4882a593Smuzhiyun 		if(calidata.xtempf==0){
831*4882a593Smuzhiyun 			calidata.xpmis = calidata.xmmis + count - 1;
832*4882a593Smuzhiyun 			if((calidata.xpmis>calidata.xmmis)&&(calidata.xpmis==128))calidata.xpmis = calidata.xmmis + count-1 + 1;
833*4882a593Smuzhiyun 			if((calidata.xpmis<calidata.xmmis)&&(calidata.xpmis==127))calidata.xpmis = calidata.xmmis + count-1 - 1;
834*4882a593Smuzhiyun 			calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
835*4882a593Smuzhiyun 			Write_Input(calidata.xaddmis, (*(calidata.MisDataSpaceConvert))(calidata.xpmis));
836*4882a593Smuzhiyun 		}
837*4882a593Smuzhiyun 		if(calidata.ytempf==0){
838*4882a593Smuzhiyun 			calidata.ypmis = calidata.ymmis + count - 1;
839*4882a593Smuzhiyun 			if((calidata.ypmis>calidata.ymmis)&&(calidata.ypmis==128))calidata.ypmis = calidata.ymmis + count-1 + 1;
840*4882a593Smuzhiyun 			if((calidata.ypmis<calidata.ymmis)&&(calidata.ypmis==127))calidata.ypmis = calidata.ymmis + count-1 - 1;
841*4882a593Smuzhiyun 			calidata.MisDataSpaceConvert = forword_MisDataSpaceConvert;
842*4882a593Smuzhiyun 			Write_Input(calidata.yaddmis, (*(calidata.MisDataSpaceConvert))(calidata.ypmis));
843*4882a593Smuzhiyun 		}
844*4882a593Smuzhiyun 		if(calidata.ztempf==0){
845*4882a593Smuzhiyun 			calidata.zpmis = calidata.zmmis + count - 1;
846*4882a593Smuzhiyun 			if((calidata.zpmis>calidata.zmmis)&&(calidata.zpmis==128))calidata.zpmis = calidata.zmmis + count-1 + 1;
847*4882a593Smuzhiyun 			if((calidata.zpmis<calidata.zmmis)&&(calidata.zpmis==127))calidata.zpmis = calidata.zmmis + count-1 - 1;
848*4882a593Smuzhiyun 			calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
849*4882a593Smuzhiyun 			Write_Input(calidata.zaddmis, (*(calidata.MisDataSpaceConvert))(calidata.zpmis));
850*4882a593Smuzhiyun 		}
851*4882a593Smuzhiyun 		Read_Output_3axis(acc_buf);
852*4882a593Smuzhiyun 		if(abs((signed int)((signed char)acc_buf[1])-x)<abs(calidata.xfoutput)){
853*4882a593Smuzhiyun 			calidata.xnmis=calidata.xpmis;
854*4882a593Smuzhiyun 			calidata.xfoutput= (signed int)((signed char)acc_buf[1])-x;
855*4882a593Smuzhiyun 		}
856*4882a593Smuzhiyun 		if(abs((signed int)((signed char)acc_buf[3])-y)<abs(calidata.yfoutput)){
857*4882a593Smuzhiyun 			calidata.ynmis=calidata.ypmis;
858*4882a593Smuzhiyun 			calidata.yfoutput= (signed int)((signed char)acc_buf[3])-y;
859*4882a593Smuzhiyun 		}
860*4882a593Smuzhiyun 		if(abs((signed int)((signed char)acc_buf[5])-z)<abs(calidata.zfoutput)){
861*4882a593Smuzhiyun 			calidata.znmis=calidata.zpmis;
862*4882a593Smuzhiyun 			calidata.zfoutput= (signed int)((signed char)acc_buf[5])-z;
863*4882a593Smuzhiyun 		}
864*4882a593Smuzhiyun 		if(calidata.xtempf==0){
865*4882a593Smuzhiyun 			calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
866*4882a593Smuzhiyun 			Write_Input(calidata.xaddmis, (*(calidata.MisDataSpaceConvert))(calidata.xnmis));
867*4882a593Smuzhiyun 		}
868*4882a593Smuzhiyun 		if(calidata.ytempf==0){
869*4882a593Smuzhiyun 			calidata.MisDataSpaceConvert = forword_MisDataSpaceConvert;
870*4882a593Smuzhiyun 			Write_Input(calidata.yaddmis, (*(calidata.MisDataSpaceConvert))(calidata.ynmis));
871*4882a593Smuzhiyun 		}
872*4882a593Smuzhiyun 		if(calidata.ztempf==0){
873*4882a593Smuzhiyun 			calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
874*4882a593Smuzhiyun 			Write_Input(calidata.zaddmis, (*(calidata.MisDataSpaceConvert))(calidata.znmis));
875*4882a593Smuzhiyun 		}
876*4882a593Smuzhiyun #ifdef PRINT
877*4882a593Smuzhiyun 		printk("L%4d:xf=%4d,xmis=%4d,yf=%4d,ymis=%4d,zf=%4d,zmis=%4d\n\r",__LINE__,
878*4882a593Smuzhiyun 					(signed int)((signed char)acc_buf[1])-x,(unsigned int)calidata.xpmis,
879*4882a593Smuzhiyun 					(signed int)((signed char)acc_buf[3])-y,(unsigned int)calidata.ypmis,
880*4882a593Smuzhiyun 					(signed int)((signed char)acc_buf[5])-z,(unsigned int)calidata.zpmis
881*4882a593Smuzhiyun 					);
882*4882a593Smuzhiyun #endif
883*4882a593Smuzhiyun 
884*4882a593Smuzhiyun 
885*4882a593Smuzhiyun 
886*4882a593Smuzhiyun 
887*4882a593Smuzhiyun 	}
888*4882a593Smuzhiyun 	//Write_Input(AddMis, (*MisDataSpaceConvert)(FinaloutputMisConfiguration));
889*4882a593Smuzhiyun 
890*4882a593Smuzhiyun 
891*4882a593Smuzhiyun 
892*4882a593Smuzhiyun 
893*4882a593Smuzhiyun //===========================================================================
894*4882a593Smuzhiyun //===========================================================================
895*4882a593Smuzhiyun //step5=cali off for zero in 2 LSB
896*4882a593Smuzhiyun 	calidata.xpoff=calidata.ypoff=calidata.zpoff=0x7f;
897*4882a593Smuzhiyun 	calidata.xnoff=calidata.ynoff=calidata.znoff=0;
898*4882a593Smuzhiyun 	calidata.xtempf=calidata.ytempf=calidata.ztempf=0;
899*4882a593Smuzhiyun #ifdef PRINT
900*4882a593Smuzhiyun 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
901*4882a593Smuzhiyun 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
902*4882a593Smuzhiyun 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
903*4882a593Smuzhiyun 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
904*4882a593Smuzhiyun 				);
905*4882a593Smuzhiyun #endif
906*4882a593Smuzhiyun 	check_finalflag_set_tempflag(&calidata);
907*4882a593Smuzhiyun #ifdef PRINT
908*4882a593Smuzhiyun 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
909*4882a593Smuzhiyun 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
910*4882a593Smuzhiyun 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
911*4882a593Smuzhiyun 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
912*4882a593Smuzhiyun 				);
913*4882a593Smuzhiyun #endif
914*4882a593Smuzhiyun 	//offset max
915*4882a593Smuzhiyun 	if(calidata.xtempf==0){
916*4882a593Smuzhiyun 		calidata.OffDataSpaceConvert = reverse_OffDataSpaceConvert;
917*4882a593Smuzhiyun 		Write_Input(calidata.xaddoff, (*(calidata.OffDataSpaceConvert))(calidata.xpoff)); // x off to max
918*4882a593Smuzhiyun 	}
919*4882a593Smuzhiyun 	if(calidata.ytempf==0){
920*4882a593Smuzhiyun 		calidata.OffDataSpaceConvert = forword_OffDataSpaceConvert;
921*4882a593Smuzhiyun 		Write_Input(calidata.yaddoff, (*(calidata.OffDataSpaceConvert))(calidata.xpoff)); // y off to max
922*4882a593Smuzhiyun 	}
923*4882a593Smuzhiyun 	if(calidata.ztempf==0){
924*4882a593Smuzhiyun 		calidata.OffDataSpaceConvert = forword_OffDataSpaceConvert;
925*4882a593Smuzhiyun 		Write_Input(calidata.zaddoff, (*(calidata.OffDataSpaceConvert))(calidata.xpoff)); // z off to max
926*4882a593Smuzhiyun 	}
927*4882a593Smuzhiyun 	Read_Output_3axis(acc_buf);
928*4882a593Smuzhiyun 	calidata.xpoutput=calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
929*4882a593Smuzhiyun 	calidata.ypoutput=calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
930*4882a593Smuzhiyun 	calidata.zpoutput=calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
931*4882a593Smuzhiyun #ifdef PRINT
932*4882a593Smuzhiyun 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
933*4882a593Smuzhiyun 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
934*4882a593Smuzhiyun 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
935*4882a593Smuzhiyun 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
936*4882a593Smuzhiyun 				);
937*4882a593Smuzhiyun #endif
938*4882a593Smuzhiyun 	check_output_set_finalflag(&calidata,2);
939*4882a593Smuzhiyun #ifdef PRINT
940*4882a593Smuzhiyun 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
941*4882a593Smuzhiyun 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
942*4882a593Smuzhiyun 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
943*4882a593Smuzhiyun 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
944*4882a593Smuzhiyun 				);
945*4882a593Smuzhiyun #endif
946*4882a593Smuzhiyun 	//offset min
947*4882a593Smuzhiyun 	if(calidata.xtempf==0){
948*4882a593Smuzhiyun 		calidata.OffDataSpaceConvert = reverse_OffDataSpaceConvert;
949*4882a593Smuzhiyun 		Write_Input(calidata.xaddoff, (*(calidata.OffDataSpaceConvert))(calidata.xnoff)); // x off to min
950*4882a593Smuzhiyun 	}
951*4882a593Smuzhiyun 	if(calidata.ytempf==0){
952*4882a593Smuzhiyun 		calidata.OffDataSpaceConvert = forword_OffDataSpaceConvert;
953*4882a593Smuzhiyun 		Write_Input(calidata.yaddoff, (*(calidata.OffDataSpaceConvert))(calidata.ynoff)); // y off to min
954*4882a593Smuzhiyun 	}
955*4882a593Smuzhiyun 	if(calidata.ztempf==0){
956*4882a593Smuzhiyun 		calidata.OffDataSpaceConvert = forword_OffDataSpaceConvert;
957*4882a593Smuzhiyun 		Write_Input(calidata.zaddoff, (*(calidata.OffDataSpaceConvert))(calidata.znoff)); // z off to min
958*4882a593Smuzhiyun 	}
959*4882a593Smuzhiyun 	Read_Output_3axis(acc_buf);
960*4882a593Smuzhiyun 	calidata.xnoutput=calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
961*4882a593Smuzhiyun 	calidata.ynoutput=calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
962*4882a593Smuzhiyun 	calidata.znoutput=calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
963*4882a593Smuzhiyun #ifdef PRINT
964*4882a593Smuzhiyun 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
965*4882a593Smuzhiyun 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
966*4882a593Smuzhiyun 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
967*4882a593Smuzhiyun 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
968*4882a593Smuzhiyun 				);
969*4882a593Smuzhiyun #endif
970*4882a593Smuzhiyun 	check_output_set_finalflag(&calidata,2);
971*4882a593Smuzhiyun #ifdef PRINT
972*4882a593Smuzhiyun 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
973*4882a593Smuzhiyun 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
974*4882a593Smuzhiyun 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
975*4882a593Smuzhiyun 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
976*4882a593Smuzhiyun 				);
977*4882a593Smuzhiyun #endif
978*4882a593Smuzhiyun 	if(abs(calidata.xpoutput)<=abs(calidata.xnoutput)){
979*4882a593Smuzhiyun 		calidata.xfoutput=calidata.xpoutput;
980*4882a593Smuzhiyun 		calidata.xmoff=calidata.xpoff;
981*4882a593Smuzhiyun 	}
982*4882a593Smuzhiyun 	else{
983*4882a593Smuzhiyun 		calidata.xfoutput=calidata.xnoutput;
984*4882a593Smuzhiyun 		calidata.xmoff=calidata.xnoff;
985*4882a593Smuzhiyun 	}
986*4882a593Smuzhiyun 	if(abs(calidata.ypoutput)<=abs(calidata.ynoutput)){
987*4882a593Smuzhiyun 		calidata.yfoutput=calidata.ypoutput;
988*4882a593Smuzhiyun 		calidata.ymoff=calidata.ypoff;
989*4882a593Smuzhiyun 	}
990*4882a593Smuzhiyun 	else{
991*4882a593Smuzhiyun 		calidata.yfoutput=calidata.ynoutput;
992*4882a593Smuzhiyun 		calidata.ymoff=calidata.ynoff;
993*4882a593Smuzhiyun 	}
994*4882a593Smuzhiyun 	if(abs(calidata.zpoutput)<=abs(calidata.znoutput)){
995*4882a593Smuzhiyun 		calidata.zfoutput=calidata.zpoutput;
996*4882a593Smuzhiyun 		calidata.zmoff=calidata.zpoff;
997*4882a593Smuzhiyun 	}
998*4882a593Smuzhiyun 	else{
999*4882a593Smuzhiyun 		calidata.zfoutput=calidata.znoutput;
1000*4882a593Smuzhiyun 		calidata.zmoff=calidata.znoff;
1001*4882a593Smuzhiyun 	}
1002*4882a593Smuzhiyun 	if(calidata.xtempf==0){
1003*4882a593Smuzhiyun 		calidata.OffDataSpaceConvert = reverse_OffDataSpaceConvert;
1004*4882a593Smuzhiyun 		Write_Input(calidata.xaddoff, (*(calidata.OffDataSpaceConvert))(calidata.xmoff));
1005*4882a593Smuzhiyun 	}
1006*4882a593Smuzhiyun 	if(calidata.ytempf==0){
1007*4882a593Smuzhiyun 		calidata.OffDataSpaceConvert = forword_OffDataSpaceConvert;
1008*4882a593Smuzhiyun 		Write_Input(calidata.yaddoff, (*(calidata.OffDataSpaceConvert))(calidata.ymoff));
1009*4882a593Smuzhiyun 	}
1010*4882a593Smuzhiyun 	if(calidata.ztempf==0){
1011*4882a593Smuzhiyun 		calidata.OffDataSpaceConvert = forword_OffDataSpaceConvert;
1012*4882a593Smuzhiyun 		Write_Input(calidata.zaddoff, (*(calidata.OffDataSpaceConvert))(calidata.zmoff));
1013*4882a593Smuzhiyun 	}
1014*4882a593Smuzhiyun 	if((calidata.xpoutput>0 && calidata.xnoutput>0)||(calidata.xpoutput<0 && calidata.xnoutput<0)){
1015*4882a593Smuzhiyun 		calidata.xfinalf=1;
1016*4882a593Smuzhiyun 	}
1017*4882a593Smuzhiyun 
1018*4882a593Smuzhiyun 	if((calidata.ypoutput>0 && calidata.ynoutput>0)||(calidata.ypoutput<0 && calidata.ynoutput<0)){
1019*4882a593Smuzhiyun 		calidata.yfinalf=1;
1020*4882a593Smuzhiyun 	}
1021*4882a593Smuzhiyun 
1022*4882a593Smuzhiyun 	if((calidata.zpoutput>0 && calidata.znoutput>0)||(calidata.zpoutput<0 && calidata.znoutput<0)){
1023*4882a593Smuzhiyun 		calidata.zfinalf=1;
1024*4882a593Smuzhiyun 	}
1025*4882a593Smuzhiyun 
1026*4882a593Smuzhiyun 
1027*4882a593Smuzhiyun 	check_finalflag_set_tempflag(&calidata);
1028*4882a593Smuzhiyun #ifdef PRINT
1029*4882a593Smuzhiyun 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
1030*4882a593Smuzhiyun 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
1031*4882a593Smuzhiyun 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
1032*4882a593Smuzhiyun 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
1033*4882a593Smuzhiyun 				);
1034*4882a593Smuzhiyun #endif
1035*4882a593Smuzhiyun 	cyclecount=0;
1036*4882a593Smuzhiyun 	while(1){
1037*4882a593Smuzhiyun 		if(++cyclecount>20)break;
1038*4882a593Smuzhiyun 
1039*4882a593Smuzhiyun 		if((calidata.xtempf)&&(calidata.ytempf)&&(calidata.ztempf))break;
1040*4882a593Smuzhiyun 		updata_midoff_address(&calidata);
1041*4882a593Smuzhiyun 		Read_Output_3axis(acc_buf);
1042*4882a593Smuzhiyun 		calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
1043*4882a593Smuzhiyun 		calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
1044*4882a593Smuzhiyun 		calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
1045*4882a593Smuzhiyun #ifdef PRINT
1046*4882a593Smuzhiyun 		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",
1047*4882a593Smuzhiyun 				calidata.xpoutput,(unsigned int)calidata.xpoff,
1048*4882a593Smuzhiyun 				calidata.xfoutput,(unsigned int)calidata.xmoff,
1049*4882a593Smuzhiyun 				calidata.xnoutput,(unsigned int)calidata.xnoff,
1050*4882a593Smuzhiyun 				calidata.ypoutput,(unsigned int)calidata.ypoff,
1051*4882a593Smuzhiyun 				calidata.yfoutput,(unsigned int)calidata.ymoff,
1052*4882a593Smuzhiyun 				calidata.ynoutput,(unsigned int)calidata.ynoff,
1053*4882a593Smuzhiyun 				calidata.zpoutput,(unsigned int)calidata.zpoff,
1054*4882a593Smuzhiyun 				calidata.zfoutput,(unsigned int)calidata.zmoff,
1055*4882a593Smuzhiyun 				calidata.znoutput,(unsigned int)calidata.znoff
1056*4882a593Smuzhiyun 				);
1057*4882a593Smuzhiyun #endif
1058*4882a593Smuzhiyun 		updata_moff_pnfoutput_set_tempflag(&calidata,acc_buf,x,y,z);
1059*4882a593Smuzhiyun 		check_output_set_finalflag(&calidata,2);
1060*4882a593Smuzhiyun 		if(check_flag_is_return(&calidata))return 1;
1061*4882a593Smuzhiyun 	}
1062*4882a593Smuzhiyun #ifdef PRINT
1063*4882a593Smuzhiyun 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
1064*4882a593Smuzhiyun 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
1065*4882a593Smuzhiyun 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
1066*4882a593Smuzhiyun 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
1067*4882a593Smuzhiyun 				);
1068*4882a593Smuzhiyun #endif
1069*4882a593Smuzhiyun //cali mis for zero in 25 LSB
1070*4882a593Smuzhiyun //===========================================================================
1071*4882a593Smuzhiyun 
1072*4882a593Smuzhiyun 
1073*4882a593Smuzhiyun 
1074*4882a593Smuzhiyun 	return 1;
1075*4882a593Smuzhiyun }
1076*4882a593Smuzhiyun 
auto_calibration_instant_mtp_sc7a20(signed int x,signed int y,signed int z)1077*4882a593Smuzhiyun static int auto_calibration_instant_mtp_sc7a20(signed int x, signed int y, signed int z){
1078*4882a593Smuzhiyun 	unsigned char readbuf[3]={0};
1079*4882a593Smuzhiyun 	unsigned char buffer[6] = {0};
1080*4882a593Smuzhiyun 	//unsigned char tbuffer[6] = {0};
1081*4882a593Smuzhiyun 	signed int xoutp,youtp,zoutp;
1082*4882a593Smuzhiyun 	unsigned char xfinalf,yfinalf,zfinalf;
1083*4882a593Smuzhiyun         char reg_13= 0;
1084*4882a593Smuzhiyun 	xoutp=youtp=zoutp=0;
1085*4882a593Smuzhiyun 	xfinalf=yfinalf=zfinalf=0;
1086*4882a593Smuzhiyun 	if(auto_calibration_instant_sc7a20(x,y,z)==0)
1087*4882a593Smuzhiyun          {
1088*4882a593Smuzhiyun 		printk("auto_calibration_instant ==0 \n");
1089*4882a593Smuzhiyun 	   sensor_write_reg(sc7a20_client, 0x1e,0x05);
1090*4882a593Smuzhiyun            mdelay(100);
1091*4882a593Smuzhiyun            sensor_write_reg(sc7a20_client, 0x13,0x01);
1092*4882a593Smuzhiyun 
1093*4882a593Smuzhiyun            sensor_write_reg(sc7a20_client, 0x1e,0x15);
1094*4882a593Smuzhiyun            mdelay(300);
1095*4882a593Smuzhiyun            return 0;
1096*4882a593Smuzhiyun 	}
1097*4882a593Smuzhiyun 
1098*4882a593Smuzhiyun 	//msleep(20);
1099*4882a593Smuzhiyun 	tilt_3axis_mtp(x,y,z);
1100*4882a593Smuzhiyun 	Read_Output_3axis(buffer);
1101*4882a593Smuzhiyun 	xoutp=(signed int)((signed char)buffer[1])-x;
1102*4882a593Smuzhiyun 	youtp=(signed int)((signed char)buffer[3])-y;
1103*4882a593Smuzhiyun 	zoutp=(signed int)((signed char)buffer[5])-z;
1104*4882a593Smuzhiyun 
1105*4882a593Smuzhiyun 	if(abs(xoutp) < 2){xfinalf=1;}
1106*4882a593Smuzhiyun 	if(abs(youtp) < 2){yfinalf=1;}
1107*4882a593Smuzhiyun 	if(abs(zoutp) < 2){zfinalf=1;}
1108*4882a593Smuzhiyun 
1109*4882a593Smuzhiyun 
1110*4882a593Smuzhiyun 	//*tbuffer = 0x10;
1111*4882a593Smuzhiyun 	//sensor_rx_data(sc7a20_client, tbuffer,1);
1112*4882a593Smuzhiyun 	readbuf[0]= Read_Reg_sc7a20(0x10);
1113*4882a593Smuzhiyun 	//*tbuffer = 0x40;
1114*4882a593Smuzhiyun 	//sensor_rx_data(sc7a20_client, tbuffer,1);
1115*4882a593Smuzhiyun 	readbuf[1]= Read_Reg_sc7a20(0x40);
1116*4882a593Smuzhiyun 	//*tbuffer = 0x47;
1117*4882a593Smuzhiyun 	//sensor_rx_data(sc7a20_client, tbuffer,1);
1118*4882a593Smuzhiyun 	readbuf[2]= Read_Reg_sc7a20(0x47);
1119*4882a593Smuzhiyun 	printk("L%4d:xtilt=%4d,xmis=%4d,xoff=%4d\n\r",__LINE__,
1120*4882a593Smuzhiyun 			(unsigned int)readbuf[0],
1121*4882a593Smuzhiyun 			(unsigned int)readbuf[1],
1122*4882a593Smuzhiyun 			(unsigned int)readbuf[2]
1123*4882a593Smuzhiyun 			);
1124*4882a593Smuzhiyun 
1125*4882a593Smuzhiyun 
1126*4882a593Smuzhiyun 
1127*4882a593Smuzhiyun 	//*tbuffer = 0x11;
1128*4882a593Smuzhiyun 	//sensor_rx_data(sc7a20_client, tbuffer,1);
1129*4882a593Smuzhiyun 	readbuf[0]= Read_Reg_sc7a20(0x11);
1130*4882a593Smuzhiyun 	//*tbuffer = 0x41;
1131*4882a593Smuzhiyun 	//sensor_rx_data(sc7a20_client, tbuffer,1);
1132*4882a593Smuzhiyun 	readbuf[1]= Read_Reg_sc7a20(0x41);
1133*4882a593Smuzhiyun 	//*tbuffer = 0x48;
1134*4882a593Smuzhiyun 	//sensor_rx_data(sc7a20_client, tbuffer,1);
1135*4882a593Smuzhiyun 	readbuf[2]= Read_Reg_sc7a20(0x48);
1136*4882a593Smuzhiyun 	printk("L%4d:ytilt=%4d,ymis=%4d,yoff=%4d\n\r",__LINE__,
1137*4882a593Smuzhiyun 			(unsigned int)readbuf[0],
1138*4882a593Smuzhiyun 			(unsigned int)readbuf[1],
1139*4882a593Smuzhiyun 			(unsigned int)readbuf[2]
1140*4882a593Smuzhiyun 			);
1141*4882a593Smuzhiyun 
1142*4882a593Smuzhiyun 	//*tbuffer = 0x12;
1143*4882a593Smuzhiyun 	//sensor_rx_data(sc7a20_client, tbuffer,1);
1144*4882a593Smuzhiyun 	readbuf[0]= Read_Reg_sc7a20(0x12);
1145*4882a593Smuzhiyun 	//*tbuffer = 0x42;
1146*4882a593Smuzhiyun 	//sensor_rx_data(sc7a20_client, tbuffer,1);
1147*4882a593Smuzhiyun 	readbuf[1]= Read_Reg_sc7a20(0x42);
1148*4882a593Smuzhiyun 	//*tbuffer = 0x49;
1149*4882a593Smuzhiyun 	//sensor_rx_data(sc7a20_client, tbuffer,1);
1150*4882a593Smuzhiyun 	readbuf[2]= Read_Reg_sc7a20(0x49);
1151*4882a593Smuzhiyun 	printk("L%4d:ztilt=%4d,zmis=%4d,zoff=%4d\n\r",__LINE__,
1152*4882a593Smuzhiyun 			(unsigned int)readbuf[0],
1153*4882a593Smuzhiyun 			(unsigned int)readbuf[1],
1154*4882a593Smuzhiyun 			(unsigned int)readbuf[2]
1155*4882a593Smuzhiyun 			);
1156*4882a593Smuzhiyun 
1157*4882a593Smuzhiyun 	if(xfinalf && yfinalf && zfinalf)
1158*4882a593Smuzhiyun 	{
1159*4882a593Smuzhiyun 		sensor_write_reg(sc7a20_client,0x13,0x01);//allen MTP
1160*4882a593Smuzhiyun 		reg_13 = sensor_read_reg(sc7a20_client,0x13);
1161*4882a593Smuzhiyun 		printk("line %d  reg_13 = %x\n",__LINE__,reg_13);
1162*4882a593Smuzhiyun 		Write_Input(0x1e, 0x15);  //保存校准寄存器的修改
1163*4882a593Smuzhiyun 		mdelay(300);
1164*4882a593Smuzhiyun 		reg_13 = sensor_read_reg(sc7a20_client,0x13);
1165*4882a593Smuzhiyun 		printk("line %d  reg_13 = %x\n",__LINE__,reg_13);
1166*4882a593Smuzhiyun 		Write_Input(0x1e, 0);
1167*4882a593Smuzhiyun 
1168*4882a593Smuzhiyun 		printk(KERN_INFO "run calibration finished\n");
1169*4882a593Smuzhiyun 
1170*4882a593Smuzhiyun 		return 1;//xyz cali ok
1171*4882a593Smuzhiyun   	}
1172*4882a593Smuzhiyun 	else
1173*4882a593Smuzhiyun 	{
1174*4882a593Smuzhiyun 		sensor_write_reg(sc7a20_client,0x13,0x01);//allen MTP
1175*4882a593Smuzhiyun                 reg_13 = sensor_read_reg(sc7a20_client,0x13);
1176*4882a593Smuzhiyun                 printk("line %d  reg_13 = %x\n",__LINE__,reg_13);
1177*4882a593Smuzhiyun                 Write_Input(0x1e, 0x15);  //保存校准寄存器的修改
1178*4882a593Smuzhiyun                 mdelay(300);
1179*4882a593Smuzhiyun                 reg_13 = sensor_read_reg(sc7a20_client,0x13);
1180*4882a593Smuzhiyun                 printk("line %d  reg_13 = %x\n",__LINE__,reg_13);
1181*4882a593Smuzhiyun                 Write_Input(0x1e, 0);
1182*4882a593Smuzhiyun 		return 0;
1183*4882a593Smuzhiyun        }
1184*4882a593Smuzhiyun }
1185*4882a593Smuzhiyun 
1186*4882a593Smuzhiyun 
1187*4882a593Smuzhiyun 
1188*4882a593Smuzhiyun 
1189*4882a593Smuzhiyun 
SC7A20_3_axis_Calibration(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)1190*4882a593Smuzhiyun static ssize_t SC7A20_3_axis_Calibration(struct device *dev,struct device_attribute *attr ,const char *buf, size_t count)
1191*4882a593Smuzhiyun {
1192*4882a593Smuzhiyun 	//unsigned temp[3];
1193*4882a593Smuzhiyun 	//struct SC7A20_acc	acc={0,0,-64};
1194*4882a593Smuzhiyun 	unsigned adj_ok = 0;
1195*4882a593Smuzhiyun 
1196*4882a593Smuzhiyun 	Write_Input(0x1e, 0x05);   //为校准寄存器的修改开放权限
1197*4882a593Smuzhiyun 	Write_Input(0x20, 0x77);
1198*4882a593Smuzhiyun     adj_ok = auto_calibration_instant_mtp_sc7a20(0,0,-64);
1199*4882a593Smuzhiyun     if(adj_ok )
1200*4882a593Smuzhiyun    	 {
1201*4882a593Smuzhiyun 		Write_Input(0x1e, 0x15);  //保存校准寄存器的修改
1202*4882a593Smuzhiyun 		mdelay(5);
1203*4882a593Smuzhiyun 		printk(KERN_INFO "run calibration finished\n");
1204*4882a593Smuzhiyun 	}
1205*4882a593Smuzhiyun 	else
1206*4882a593Smuzhiyun 		printk(KERN_INFO "run calibration not finished\n");
1207*4882a593Smuzhiyun 
1208*4882a593Smuzhiyun     	mdelay(5);
1209*4882a593Smuzhiyun 	return 1;
1210*4882a593Smuzhiyun }
1211*4882a593Smuzhiyun 
1212*4882a593Smuzhiyun 
SC7A20_calibration_reset_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)1213*4882a593Smuzhiyun static ssize_t SC7A20_calibration_reset_store(struct device *dev,
1214*4882a593Smuzhiyun         struct device_attribute *attr,
1215*4882a593Smuzhiyun         const char *buf, size_t count)
1216*4882a593Smuzhiyun {
1217*4882a593Smuzhiyun 
1218*4882a593Smuzhiyun 	Read_Output(0x29);
1219*4882a593Smuzhiyun         //printk(KERN_INFO "reset calibration finished\n");
1220*4882a593Smuzhiyun         return count;
1221*4882a593Smuzhiyun }
1222*4882a593Smuzhiyun 
SC7A20_calibration_value_show(struct device * dev,struct device_attribute * attr,char * buf)1223*4882a593Smuzhiyun static ssize_t SC7A20_calibration_value_show(struct device *dev,
1224*4882a593Smuzhiyun         struct device_attribute *attr, char *buf)
1225*4882a593Smuzhiyun {
1226*4882a593Smuzhiyun     return sprintf(buf, "%d %d %d\n", offset1.x,offset1.y,offset1.z);
1227*4882a593Smuzhiyun }
1228*4882a593Smuzhiyun 
SC7A20_calibration_value_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)1229*4882a593Smuzhiyun static ssize_t SC7A20_calibration_value_store(struct device *dev,
1230*4882a593Smuzhiyun         struct device_attribute *attr,
1231*4882a593Smuzhiyun         const char *buf, size_t count)
1232*4882a593Smuzhiyun {
1233*4882a593Smuzhiyun     int data[3];
1234*4882a593Smuzhiyun     sscanf(buf, "%d %d %d", &data[0], &data[1], &data[2]);
1235*4882a593Smuzhiyun     offset1.x = data[0];
1236*4882a593Smuzhiyun     offset1.y = data[1];
1237*4882a593Smuzhiyun     offset1.z = data[2];
1238*4882a593Smuzhiyun     printk(KERN_INFO "set calibration finished\n");
1239*4882a593Smuzhiyun     return count;
1240*4882a593Smuzhiyun }
1241*4882a593Smuzhiyun 
SC7A20_register_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)1242*4882a593Smuzhiyun static ssize_t SC7A20_register_store(struct device *dev,
1243*4882a593Smuzhiyun         struct device_attribute *attr,
1244*4882a593Smuzhiyun         const char *buf, size_t count)
1245*4882a593Smuzhiyun {
1246*4882a593Smuzhiyun     int address, value;
1247*4882a593Smuzhiyun     int result = 0;
1248*4882a593Smuzhiyun     sscanf(buf, "0x%x=0x%x", &address, &value);
1249*4882a593Smuzhiyun 
1250*4882a593Smuzhiyun     result = sensor_write_reg(sc7a20_client, address,value);
1251*4882a593Smuzhiyun 
1252*4882a593Smuzhiyun     if(result)
1253*4882a593Smuzhiyun 		printk("%s:fail to write sensor_register\n",__func__);
1254*4882a593Smuzhiyun 
1255*4882a593Smuzhiyun     return count;
1256*4882a593Smuzhiyun }
1257*4882a593Smuzhiyun 
SC7A20_register_show(struct device * dev,struct device_attribute * attr,char * buf)1258*4882a593Smuzhiyun static ssize_t SC7A20_register_show(struct device *dev,
1259*4882a593Smuzhiyun         struct device_attribute *attr, char *buf)
1260*4882a593Smuzhiyun {
1261*4882a593Smuzhiyun     size_t count = 0;
1262*4882a593Smuzhiyun 
1263*4882a593Smuzhiyun 
1264*4882a593Smuzhiyun 
1265*4882a593Smuzhiyun 	char i;
1266*4882a593Smuzhiyun 	char buffer[3] = {0};
1267*4882a593Smuzhiyun 	i = 0x0f;
1268*4882a593Smuzhiyun     *buffer = i;
1269*4882a593Smuzhiyun     count = sensor_rx_data(sc7a20_client, &buffer[0], 1);
1270*4882a593Smuzhiyun     count += sprintf(buf, "0x%x: 0x%x\n", i, buffer[0]);
1271*4882a593Smuzhiyun     for(i=0x10;i<0x5a;i++)
1272*4882a593Smuzhiyun     {
1273*4882a593Smuzhiyun 		*buffer = i;
1274*4882a593Smuzhiyun 
1275*4882a593Smuzhiyun     	sensor_rx_data(sc7a20_client, &buffer[0], 1);
1276*4882a593Smuzhiyun 		count += sprintf(&buf[count],"0x%x: 0x%x\n", i, buffer[0]);
1277*4882a593Smuzhiyun     }
1278*4882a593Smuzhiyun     return count;
1279*4882a593Smuzhiyun }
1280*4882a593Smuzhiyun 
SC7A20_value_show(struct device * dev,struct device_attribute * attr,char * buf)1281*4882a593Smuzhiyun static ssize_t SC7A20_value_show(struct device *dev,
1282*4882a593Smuzhiyun         struct device_attribute *attr, char *buf)
1283*4882a593Smuzhiyun {
1284*4882a593Smuzhiyun     s16 x,y,z;
1285*4882a593Smuzhiyun     int ret;
1286*4882a593Smuzhiyun 	char buffer1[3],buffer2[3] = {0};
1287*4882a593Smuzhiyun 
1288*4882a593Smuzhiyun 	memset(buffer1, 0, 3);
1289*4882a593Smuzhiyun 	memset(buffer2, 0, 3);
1290*4882a593Smuzhiyun 
1291*4882a593Smuzhiyun 	*buffer1 = SC7A20_STATUS;
1292*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer1,1);
1293*4882a593Smuzhiyun 	buffer1[0] &= 0x08;
1294*4882a593Smuzhiyun 	if(!buffer1[0])
1295*4882a593Smuzhiyun 		return sprintf(buf, "SC7A20 data is not ready!\n");
1296*4882a593Smuzhiyun 
1297*4882a593Smuzhiyun 	*buffer1 = SC7A20_XOUT_L;
1298*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer1,1);
1299*4882a593Smuzhiyun     *buffer2 = SC7A20_XOUT_H;
1300*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer2,1);
1301*4882a593Smuzhiyun 	x = (((s16)((buffer2[0] << 8) + buffer1[0])) >>4);
1302*4882a593Smuzhiyun 
1303*4882a593Smuzhiyun 	*buffer1 = SC7A20_YOUT_L;
1304*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer1,1);
1305*4882a593Smuzhiyun 	*buffer2 = SC7A20_YOUT_H;
1306*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer2,1);
1307*4882a593Smuzhiyun     y = (((s16)((buffer2[0] << 8) + buffer1[0])) >>4);
1308*4882a593Smuzhiyun 
1309*4882a593Smuzhiyun 	*buffer1 = SC7A20_ZOUT_L;
1310*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer1,1);
1311*4882a593Smuzhiyun 	*buffer2 = SC7A20_ZOUT_H;
1312*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer2,1);
1313*4882a593Smuzhiyun 	z = (((s16)((buffer2[0] << 8) + buffer1[0])) >>4);
1314*4882a593Smuzhiyun 
1315*4882a593Smuzhiyun 	if (ret < 0)
1316*4882a593Smuzhiyun 		return sprintf(buf, "SC7A20_read_data failed!\n");
1317*4882a593Smuzhiyun 	else
1318*4882a593Smuzhiyun 		return sprintf(buf, "x=%4d(0x%4x),y=%4d(0x%4x),z=%4d(0x%4x)\n",x,x,y,y,z,z);
1319*4882a593Smuzhiyun 
1320*4882a593Smuzhiyun }
1321*4882a593Smuzhiyun 
1322*4882a593Smuzhiyun static DEVICE_ATTR(reg, 0664,
1323*4882a593Smuzhiyun         SC7A20_register_show, SC7A20_register_store);
1324*4882a593Smuzhiyun 
1325*4882a593Smuzhiyun static DEVICE_ATTR(calibration_run, 0664, //calibration_run
1326*4882a593Smuzhiyun         NULL, SC7A20_3_axis_Calibration);
1327*4882a593Smuzhiyun static DEVICE_ATTR(calibration_reset, 0664,
1328*4882a593Smuzhiyun         NULL, SC7A20_calibration_reset_store);
1329*4882a593Smuzhiyun static DEVICE_ATTR(calibration_value,0664,
1330*4882a593Smuzhiyun         SC7A20_calibration_value_show,
1331*4882a593Smuzhiyun         SC7A20_calibration_value_store);
1332*4882a593Smuzhiyun static DEVICE_ATTR(value, 0664,
1333*4882a593Smuzhiyun         SC7A20_value_show, NULL);
1334*4882a593Smuzhiyun 
1335*4882a593Smuzhiyun static struct attribute *SC7A20_attributes[] = {
1336*4882a593Smuzhiyun    	&dev_attr_value.attr,
1337*4882a593Smuzhiyun     &dev_attr_reg.attr,
1338*4882a593Smuzhiyun     &dev_attr_calibration_run.attr,
1339*4882a593Smuzhiyun     &dev_attr_calibration_reset.attr,
1340*4882a593Smuzhiyun     &dev_attr_calibration_value.attr,
1341*4882a593Smuzhiyun    	 NULL
1342*4882a593Smuzhiyun };
1343*4882a593Smuzhiyun 
1344*4882a593Smuzhiyun static struct attribute_group SC7A20_attribute_group = {
1345*4882a593Smuzhiyun     .attrs = SC7A20_attributes
1346*4882a593Smuzhiyun };
1347*4882a593Smuzhiyun 
1348*4882a593Smuzhiyun 
1349*4882a593Smuzhiyun 
1350*4882a593Smuzhiyun 
1351*4882a593Smuzhiyun /****************operate according to sensor chip:start************/
1352*4882a593Smuzhiyun 
sensor_active(struct i2c_client * client,int enable,int rate)1353*4882a593Smuzhiyun static int sensor_active(struct i2c_client *client, int enable, int rate)
1354*4882a593Smuzhiyun {
1355*4882a593Smuzhiyun 	struct sensor_private_data *sensor =
1356*4882a593Smuzhiyun 	    (struct sensor_private_data *) i2c_get_clientdata(client);
1357*4882a593Smuzhiyun 	int result = 0;
1358*4882a593Smuzhiyun 	int status = 0;
1359*4882a593Smuzhiyun 
1360*4882a593Smuzhiyun 	sensor->ops->ctrl_data = 0x07;
1361*4882a593Smuzhiyun 
1362*4882a593Smuzhiyun 	//register setting according to chip datasheet
1363*4882a593Smuzhiyun 	if(enable)
1364*4882a593Smuzhiyun 	{
1365*4882a593Smuzhiyun 		status = SC7A20_ENABLE;	//sc7a20
1366*4882a593Smuzhiyun 		sensor->ops->ctrl_data |= SC7A20_400HZ;
1367*4882a593Smuzhiyun 	}
1368*4882a593Smuzhiyun 	else
1369*4882a593Smuzhiyun 		status = ~SC7A20_ENABLE;	//sc7a20
1370*4882a593Smuzhiyun 
1371*4882a593Smuzhiyun 
1372*4882a593Smuzhiyun 	printk("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
1373*4882a593Smuzhiyun 	result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
1374*4882a593Smuzhiyun 	//sensor_write_reg(client, SC7A20_BOOT, 0x80);
1375*4882a593Smuzhiyun 	if(result)
1376*4882a593Smuzhiyun 		printk("%s:fail to active sensor\n",__func__);
1377*4882a593Smuzhiyun 
1378*4882a593Smuzhiyun 	return result;
1379*4882a593Smuzhiyun 
1380*4882a593Smuzhiyun }
1381*4882a593Smuzhiyun 
1382*4882a593Smuzhiyun 
1383*4882a593Smuzhiyun 
1384*4882a593Smuzhiyun 
1385*4882a593Smuzhiyun 
1386*4882a593Smuzhiyun 
1387*4882a593Smuzhiyun 
sensor_init(struct i2c_client * client)1388*4882a593Smuzhiyun static int sensor_init(struct i2c_client *client)
1389*4882a593Smuzhiyun {
1390*4882a593Smuzhiyun 	struct sensor_private_data *sensor =
1391*4882a593Smuzhiyun 	    (struct sensor_private_data *) i2c_get_clientdata(client);
1392*4882a593Smuzhiyun 	int result = 0;
1393*4882a593Smuzhiyun 	int ret;
1394*4882a593Smuzhiyun 	unsigned char chip_id[3] = {0,0,0};
1395*4882a593Smuzhiyun 	//char reg_cali;
1396*4882a593Smuzhiyun 
1397*4882a593Smuzhiyun 	//mutex_lock(&(sensor->allen_mutex) );//allen
1398*4882a593Smuzhiyun 
1399*4882a593Smuzhiyun 	printk("aaaaa %s:line=%d\n",__func__,__LINE__);
1400*4882a593Smuzhiyun 
1401*4882a593Smuzhiyun 	result = sensor->ops->active(client,0,0);
1402*4882a593Smuzhiyun 	if(result)
1403*4882a593Smuzhiyun 	{
1404*4882a593Smuzhiyun 		printk("%s:line=%d,error\n",__func__,__LINE__);
1405*4882a593Smuzhiyun 		return result;
1406*4882a593Smuzhiyun 	}
1407*4882a593Smuzhiyun 	sc7a20_client = client;
1408*4882a593Smuzhiyun 	sensor->status_cur = SENSOR_OFF;
1409*4882a593Smuzhiyun 	//sensor->time_of_cali =0;//allen
1410*4882a593Smuzhiyun     	offset1.x=offset1.y=offset1.z=0;
1411*4882a593Smuzhiyun 
1412*4882a593Smuzhiyun 
1413*4882a593Smuzhiyun 	*chip_id = 0x0f;
1414*4882a593Smuzhiyun 	ret = sensor_rx_data(client, chip_id,1);
1415*4882a593Smuzhiyun 	printk("sc7a20_chip_id is %d",chip_id[0]);
1416*4882a593Smuzhiyun 
1417*4882a593Smuzhiyun 	  sensor_write_reg(client, SC7A20_BOOT, 0x80);
1418*4882a593Smuzhiyun 	mdelay(20);
1419*4882a593Smuzhiyun 	 sensor_write_reg(client, SC7A20_MODE3, 0x88);
1420*4882a593Smuzhiyun 
1421*4882a593Smuzhiyun 	result = sensor_write_reg(client, SC7A20_MODE, 0x07);
1422*4882a593Smuzhiyun 
1423*4882a593Smuzhiyun 
1424*4882a593Smuzhiyun             //HR mode //sc7a20
1425*4882a593Smuzhiyun 
1426*4882a593Smuzhiyun 
1427*4882a593Smuzhiyun         //register_test();
1428*4882a593Smuzhiyun 	if(result)
1429*4882a593Smuzhiyun 	{
1430*4882a593Smuzhiyun 		printk("aaaaa %s:line=%d,error\n",__func__,__LINE__);
1431*4882a593Smuzhiyun 		return result;
1432*4882a593Smuzhiyun 	}
1433*4882a593Smuzhiyun 
1434*4882a593Smuzhiyun 
1435*4882a593Smuzhiyun 
1436*4882a593Smuzhiyun 	if(sensor->pdata->irq_enable)	//open interrupt
1437*4882a593Smuzhiyun 	{
1438*4882a593Smuzhiyun 		result = sensor_write_reg(client, SC7A20_MODE2, 0x10);
1439*4882a593Smuzhiyun             	result = sensor_write_reg(client, 0x25, 0x02);
1440*4882a593Smuzhiyun 
1441*4882a593Smuzhiyun 		if(result)
1442*4882a593Smuzhiyun 		{
1443*4882a593Smuzhiyun 			printk("%s:line=%d,error\n",__func__,__LINE__);
1444*4882a593Smuzhiyun 			return result;
1445*4882a593Smuzhiyun 		}
1446*4882a593Smuzhiyun 	}
1447*4882a593Smuzhiyun 	memset(&axis_average, 0, sizeof(struct sensor_axis_average));
1448*4882a593Smuzhiyun 
1449*4882a593Smuzhiyun     if(noCreateAttr)
1450*4882a593Smuzhiyun     {
1451*4882a593Smuzhiyun         struct input_dev* pInputDev;
1452*4882a593Smuzhiyun         pInputDev = input_allocate_device();
1453*4882a593Smuzhiyun 		if (!pInputDev) {
1454*4882a593Smuzhiyun 			dev_err(&client->dev,
1455*4882a593Smuzhiyun 				"Failed to allocate input device %s\n", sensor->input_dev->name);
1456*4882a593Smuzhiyun 			return -ENOMEM;
1457*4882a593Smuzhiyun 		}
1458*4882a593Smuzhiyun 
1459*4882a593Smuzhiyun 		pInputDev->name = "sc7a20";
1460*4882a593Smuzhiyun 		set_bit(EV_ABS, pInputDev->evbit);
1461*4882a593Smuzhiyun 
1462*4882a593Smuzhiyun 		/* x-axis acceleration */
1463*4882a593Smuzhiyun 		input_set_abs_params(pInputDev, ABS_X, sensor->ops->range[0], sensor->ops->range[1], 0, 0);
1464*4882a593Smuzhiyun 		/* y-axis acceleration */
1465*4882a593Smuzhiyun 		input_set_abs_params(pInputDev, ABS_Y, sensor->ops->range[0], sensor->ops->range[1], 0, 0);
1466*4882a593Smuzhiyun 		/* z-axis acceleration */
1467*4882a593Smuzhiyun 		input_set_abs_params(pInputDev, ABS_Z, sensor->ops->range[0], sensor->ops->range[1], 0, 0);
1468*4882a593Smuzhiyun 
1469*4882a593Smuzhiyun 
1470*4882a593Smuzhiyun 		ret = input_register_device(pInputDev);
1471*4882a593Smuzhiyun 		if (ret) {
1472*4882a593Smuzhiyun 			dev_err(&client->dev,
1473*4882a593Smuzhiyun 				"Unable to register input device %s\n", pInputDev->name);
1474*4882a593Smuzhiyun 			return -ENOMEM;
1475*4882a593Smuzhiyun 		}
1476*4882a593Smuzhiyun 
1477*4882a593Smuzhiyun 		DBG("Sys Attribute Register here %s is called for DA311.\n", __func__);
1478*4882a593Smuzhiyun 		ret = sysfs_create_group(&pInputDev->dev.kobj, &SC7A20_attribute_group);
1479*4882a593Smuzhiyun 		if (ret) {
1480*4882a593Smuzhiyun 			DBG("sc7a20 sysfs_create_group Error err=%d..", ret);
1481*4882a593Smuzhiyun 			ret = -EINVAL;
1482*4882a593Smuzhiyun 		}
1483*4882a593Smuzhiyun 
1484*4882a593Smuzhiyun 
1485*4882a593Smuzhiyun 
1486*4882a593Smuzhiyun 		noCreateAttr = 0;
1487*4882a593Smuzhiyun     }
1488*4882a593Smuzhiyun 
1489*4882a593Smuzhiyun 	return result;
1490*4882a593Smuzhiyun }
1491*4882a593Smuzhiyun 
1492*4882a593Smuzhiyun 
sensor_convert_data(struct i2c_client * client,char high_byte,char low_byte,s16 off)1493*4882a593Smuzhiyun static int sensor_convert_data(struct i2c_client *client, char high_byte, char low_byte ,s16 off)
1494*4882a593Smuzhiyun {
1495*4882a593Smuzhiyun     s64 result;
1496*4882a593Smuzhiyun 	result = (((s16)((high_byte << 8) + low_byte)) >>4);
1497*4882a593Smuzhiyun 	result -= off;
1498*4882a593Smuzhiyun 	if (result < SC7A20_BOUNDARY)
1499*4882a593Smuzhiyun 		result = result* SC7A20_GRAVITY_STEP;
1500*4882a593Smuzhiyun 	else
1501*4882a593Smuzhiyun 		result = ~( ((~result & (0x7ffff>>(20-SC7A20_PRECISION)) ) + 1)
1502*4882a593Smuzhiyun 	   			* SC7A20_GRAVITY_STEP) + 1;
1503*4882a593Smuzhiyun 
1504*4882a593Smuzhiyun     	return (int)result;
1505*4882a593Smuzhiyun }
1506*4882a593Smuzhiyun 
1507*4882a593Smuzhiyun 
gsensor_report_value(struct i2c_client * client,struct sensor_axis * axis)1508*4882a593Smuzhiyun static int gsensor_report_value(struct i2c_client *client, struct sensor_axis *axis)
1509*4882a593Smuzhiyun {
1510*4882a593Smuzhiyun 	struct sensor_private_data *sensor =
1511*4882a593Smuzhiyun 	    (struct sensor_private_data *) i2c_get_clientdata(client);
1512*4882a593Smuzhiyun 
1513*4882a593Smuzhiyun 	/* Report acceleration sensor information */
1514*4882a593Smuzhiyun 
1515*4882a593Smuzhiyun 	/* RK3326 platform board */
1516*4882a593Smuzhiyun #if defined (CONFIG_BOARD_RK3326_AK47)
1517*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_X,axis->y);
1518*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Y,axis->x);
1519*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Z,-axis->z);
1520*4882a593Smuzhiyun #elif defined (CONFIG_BOARD_RK3326_TH700)
1521*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_X,axis->y);
1522*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Y,axis->x);
1523*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Z,-axis->z);
1524*4882a593Smuzhiyun #elif defined (CONFIG_BOARD_RK3326_TH863B_10)
1525*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_X,axis->x);
1526*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Y,-axis->y);
1527*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Z,-axis->z);
1528*4882a593Smuzhiyun #elif defined (CONFIG_BOARD_RK3326_TH863B_8)
1529*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_X,axis->y);
1530*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Y,axis->x);
1531*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Z,-axis->z);
1532*4882a593Smuzhiyun #elif defined (CONFIG_BOARD_RK3326_TH863B_7)
1533*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_X,axis->x);
1534*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Y,-axis->y);
1535*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Z,-axis->z);
1536*4882a593Smuzhiyun #elif defined (CONFIG_BOARD_RK3326_TH863B_V31_7)
1537*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_X,axis->x);
1538*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Y,-axis->y);
1539*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Z,-axis->z);
1540*4882a593Smuzhiyun #elif defined(CONFIG_BOARD_RK3326_TH1021DN)
1541*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_X,axis->x);
1542*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Y,-axis->y);
1543*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Z,-axis->z);
1544*4882a593Smuzhiyun #elif defined(CONFIG_BOARD_RK3326_TH1021DN_V20)
1545*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_X,axis->x);
1546*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Y,-axis->y);
1547*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Z,-axis->z);
1548*4882a593Smuzhiyun #elif defined(CONFIG_BOARD_RK3326_TH7926_7)
1549*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_X,axis->y);
1550*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Y,axis->x);
1551*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Z,-axis->z);
1552*4882a593Smuzhiyun #elif defined(CONFIG_BOARD_RK3326_TH7926_9)
1553*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_X,axis->y);
1554*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Y,axis->x);
1555*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Z,-axis->z);
1556*4882a593Smuzhiyun #elif defined(CONFIG_BOARD_RK3326_MT1011)
1557*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_X,-axis->y);
1558*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Y,-axis->x);
1559*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Z,-axis->z);
1560*4882a593Smuzhiyun #elif defined(CONFIG_BOARD_RK3326_M1011QR)
1561*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_X,-axis->y);
1562*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Y,-axis->x);
1563*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Z,-axis->z);
1564*4882a593Smuzhiyun 
1565*4882a593Smuzhiyun 	/* RK3126C platform board */
1566*4882a593Smuzhiyun #elif defined(CONFIG_BOARD_RK3126C_AK47)
1567*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_X,axis->y);
1568*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Y,axis->x);
1569*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Z,-axis->z);
1570*4882a593Smuzhiyun #elif defined(CONFIG_BOARD_RK3126C_TH1021DN)
1571*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_X,axis->x);
1572*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Y,-axis->y);
1573*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Z,-axis->z);
1574*4882a593Smuzhiyun #elif defined(CONFIG_BOARD_RK3126C_TH863_7)
1575*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_X,-axis->x);
1576*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Y,axis->y);
1577*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Z,-axis->z);
1578*4882a593Smuzhiyun #elif defined(CONFIG_BOARD_RK3126C_TH863_8)
1579*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_X,axis->y);
1580*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Y,axis->x);
1581*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Z,-axis->z);
1582*4882a593Smuzhiyun #elif defined(CONFIG_BOARD_RK3126C_TH98V)
1583*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_X,axis->y);
1584*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Y,axis->x);
1585*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Z,-axis->z);
1586*4882a593Smuzhiyun #else
1587*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_X,axis->x);
1588*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Y,-axis->y);
1589*4882a593Smuzhiyun 	input_report_abs(sensor->input_dev, ABS_Z,-axis->z);
1590*4882a593Smuzhiyun #endif
1591*4882a593Smuzhiyun 
1592*4882a593Smuzhiyun 
1593*4882a593Smuzhiyun 	input_sync(sensor->input_dev);
1594*4882a593Smuzhiyun 	DBG("Gsensor x==%d  y==%d z==%d\n",axis->x,axis->y,axis->z);
1595*4882a593Smuzhiyun 
1596*4882a593Smuzhiyun 	return 0;
1597*4882a593Smuzhiyun }
1598*4882a593Smuzhiyun 
1599*4882a593Smuzhiyun #define GSENSOR_MIN  		2
sensor_report_value(struct i2c_client * client)1600*4882a593Smuzhiyun static int sensor_report_value(struct i2c_client *client)
1601*4882a593Smuzhiyun {
1602*4882a593Smuzhiyun 
1603*4882a593Smuzhiyun 	struct sensor_private_data *sensor =
1604*4882a593Smuzhiyun 		(struct sensor_private_data *) i2c_get_clientdata(client);
1605*4882a593Smuzhiyun 	struct sensor_platform_data *pdata = sensor->pdata;
1606*4882a593Smuzhiyun 	int ret = 0;
1607*4882a593Smuzhiyun 	int x,y,z;
1608*4882a593Smuzhiyun 	struct sensor_axis axis;
1609*4882a593Smuzhiyun 	char buffer1[3],buffer2[3] = {0};
1610*4882a593Smuzhiyun 	char value = 0;
1611*4882a593Smuzhiyun 	static int flag;
1612*4882a593Smuzhiyun 
1613*4882a593Smuzhiyun 	//SC7A20_load_user_calibration(client);
1614*4882a593Smuzhiyun 	memset(buffer1, 0, 3);
1615*4882a593Smuzhiyun 	memset(buffer2, 0, 3);
1616*4882a593Smuzhiyun 
1617*4882a593Smuzhiyun 	*buffer1 = SC7A20_STATUS;
1618*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer1,1);
1619*4882a593Smuzhiyun 	buffer1[0] &= 0x08;
1620*4882a593Smuzhiyun 	if(!buffer1[0])
1621*4882a593Smuzhiyun 		return ret;
1622*4882a593Smuzhiyun 
1623*4882a593Smuzhiyun 	*buffer1 = SC7A20_XOUT_L;
1624*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer1,1);
1625*4882a593Smuzhiyun         *buffer2 = SC7A20_XOUT_H;
1626*4882a593Smuzhiyun 	ret = sensor_rx_data(client, buffer2,1);
1627*4882a593Smuzhiyun 	if (ret < 0)
1628*4882a593Smuzhiyun 		return ret;
1629*4882a593Smuzhiyun 	x = sensor_convert_data(sensor->client, buffer2[0], buffer1[0],0);	//buffer[1]:high bit
1630*4882a593Smuzhiyun 
1631*4882a593Smuzhiyun 	*buffer1 = SC7A20_YOUT_L;
1632*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer1,1);
1633*4882a593Smuzhiyun 	*buffer2 = SC7A20_YOUT_H;
1634*4882a593Smuzhiyun 	ret = sensor_rx_data(client, buffer2,1);
1635*4882a593Smuzhiyun 	if (ret < 0)
1636*4882a593Smuzhiyun 		return ret;
1637*4882a593Smuzhiyun     y = sensor_convert_data(sensor->client, buffer2[0], buffer1[0],0);
1638*4882a593Smuzhiyun 
1639*4882a593Smuzhiyun 	*buffer1 = SC7A20_ZOUT_L;
1640*4882a593Smuzhiyun 	ret = sensor_rx_data(sc7a20_client, buffer1,1);
1641*4882a593Smuzhiyun 	*buffer2 = SC7A20_ZOUT_H;
1642*4882a593Smuzhiyun 	ret = sensor_rx_data(client, buffer2,1);
1643*4882a593Smuzhiyun 	if (ret < 0)
1644*4882a593Smuzhiyun 		return ret;
1645*4882a593Smuzhiyun 	z = sensor_convert_data(sensor->client, buffer2[0], buffer1[0],0);
1646*4882a593Smuzhiyun 
1647*4882a593Smuzhiyun 	axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;
1648*4882a593Smuzhiyun 	axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;
1649*4882a593Smuzhiyun 	axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;
1650*4882a593Smuzhiyun 
1651*4882a593Smuzhiyun #if 0
1652*4882a593Smuzhiyun 	axis_average.x_average += axis.x;
1653*4882a593Smuzhiyun 	axis_average.y_average += axis.y;
1654*4882a593Smuzhiyun 	axis_average.z_average += axis.z;
1655*4882a593Smuzhiyun 	axis_average.count++;
1656*4882a593Smuzhiyun 
1657*4882a593Smuzhiyun 	if(axis_average.count >= SC7A20_COUNT_AVERAGE)
1658*4882a593Smuzhiyun 	{
1659*4882a593Smuzhiyun 		axis.x = axis_average.x_average / axis_average.count;
1660*4882a593Smuzhiyun 		axis.y = axis_average.y_average / axis_average.count;
1661*4882a593Smuzhiyun 		axis.z = axis_average.z_average / axis_average.count;
1662*4882a593Smuzhiyun 
1663*4882a593Smuzhiyun 		DBG( "%s: axis = %d  %d  %d \n", __func__, axis.x, axis.y, axis.z);
1664*4882a593Smuzhiyun 
1665*4882a593Smuzhiyun 		memset(&axis_average, 0, sizeof(struct sensor_axis_average));
1666*4882a593Smuzhiyun 
1667*4882a593Smuzhiyun 		//Report event only while value is changed to save some power
1668*4882a593Smuzhiyun 		if((abs(sensor->axis.x - axis.x) > GSENSOR_MIN) || (abs(sensor->axis.y - axis.y) > GSENSOR_MIN) || (abs(sensor->axis.z - axis.z) > GSENSOR_MIN))
1669*4882a593Smuzhiyun 		{
1670*4882a593Smuzhiyun 			gsensor_report_value(client, &axis);
1671*4882a593Smuzhiyun 
1672*4882a593Smuzhiyun 			/* \BB\A5\B3\E2\B5ػ\BA\B4\E6\CA\FD\BE\DD. */
1673*4882a593Smuzhiyun 			mutex_lock(&(sensor->data_mutex) );
1674*4882a593Smuzhiyun 			sensor->axis = axis;
1675*4882a593Smuzhiyun 			mutex_unlock(&(sensor->data_mutex) );
1676*4882a593Smuzhiyun 		}
1677*4882a593Smuzhiyun 	}
1678*4882a593Smuzhiyun #else
1679*4882a593Smuzhiyun         /*
1680*4882a593Smuzhiyun          *input dev will ignore report data if data value is the same with last_value,
1681*4882a593Smuzhiyun          *sample rate will not enough by this way, so just avoid this case
1682*4882a593Smuzhiyun          */
1683*4882a593Smuzhiyun         if ((sensor->axis.x == axis.x) && (sensor->axis.y == axis.y) && (sensor->axis.z == axis.z)) {
1684*4882a593Smuzhiyun                 if (flag) {
1685*4882a593Smuzhiyun                         flag = 0;
1686*4882a593Smuzhiyun                         axis.x += 1;
1687*4882a593Smuzhiyun                         axis.y += 1;
1688*4882a593Smuzhiyun                         axis.z += 1;
1689*4882a593Smuzhiyun                 } else {
1690*4882a593Smuzhiyun                         flag = 1;
1691*4882a593Smuzhiyun                         axis.x -= 1;
1692*4882a593Smuzhiyun                         axis.y -= 1;
1693*4882a593Smuzhiyun                         axis.z -= 1;
1694*4882a593Smuzhiyun                 }
1695*4882a593Smuzhiyun         }
1696*4882a593Smuzhiyun 
1697*4882a593Smuzhiyun 	gsensor_report_value(client, &axis);
1698*4882a593Smuzhiyun 
1699*4882a593Smuzhiyun 	/* \BB\A5\B3\E2\B5ػ\BA\B4\E6\CA\FD\BE\DD. */
1700*4882a593Smuzhiyun 	mutex_lock(&(sensor->data_mutex) );
1701*4882a593Smuzhiyun 	sensor->axis = axis;
1702*4882a593Smuzhiyun 	mutex_unlock(&(sensor->data_mutex) );
1703*4882a593Smuzhiyun #endif
1704*4882a593Smuzhiyun 
1705*4882a593Smuzhiyun 	if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0))	//read sensor intterupt status register
1706*4882a593Smuzhiyun 	{
1707*4882a593Smuzhiyun 
1708*4882a593Smuzhiyun 		value = sensor_read_reg(client, sensor->ops->int_status_reg);
1709*4882a593Smuzhiyun 		DBG("%s:sensor int status :0x%x\n",__func__,value);
1710*4882a593Smuzhiyun 	}
1711*4882a593Smuzhiyun 
1712*4882a593Smuzhiyun 	return ret;
1713*4882a593Smuzhiyun }
1714*4882a593Smuzhiyun 
1715*4882a593Smuzhiyun 
1716*4882a593Smuzhiyun static struct sensor_operate gsensor_sc7a20_ops = {
1717*4882a593Smuzhiyun 	.name				= "gs_sc7a20",
1718*4882a593Smuzhiyun 	.type				= SENSOR_TYPE_ACCEL,			//sensor type and it should be correct
1719*4882a593Smuzhiyun 	.id_i2c				= ACCEL_ID_SC7A20,			//i2c id number
1720*4882a593Smuzhiyun 	.read_reg			= SC7A20_XOUT_H,			//read data
1721*4882a593Smuzhiyun 	.read_len			= 1,					//data length
1722*4882a593Smuzhiyun 	.id_reg				= SENSOR_UNKNOW_DATA,			//read device id from this register
1723*4882a593Smuzhiyun 	.id_data 			= SENSOR_UNKNOW_DATA,			//device id
1724*4882a593Smuzhiyun 	.precision			= SC7A20_PRECISION,			//12 bit
1725*4882a593Smuzhiyun 	.ctrl_reg 			= SC7A20_MODE,			        //enable or disable SC7A20_MODE
1726*4882a593Smuzhiyun 	.int_status_reg 		= SENSOR_UNKNOW_DATA,			//intterupt status register
1727*4882a593Smuzhiyun 	.range				= {-SC7A20_RANGE,SC7A20_RANGE},	//range
1728*4882a593Smuzhiyun 	.trig				= IRQF_TRIGGER_HIGH|IRQF_ONESHOT,
1729*4882a593Smuzhiyun 	.active				= sensor_active,
1730*4882a593Smuzhiyun 	.init				= sensor_init,
1731*4882a593Smuzhiyun 	.report 			= sensor_report_value,
1732*4882a593Smuzhiyun };
1733*4882a593Smuzhiyun 
1734*4882a593Smuzhiyun /****************operate according to sensor chip:end************/
gsensor_sc7a20_probe(struct i2c_client * client,const struct i2c_device_id * devid)1735*4882a593Smuzhiyun static int gsensor_sc7a20_probe(struct i2c_client *client,
1736*4882a593Smuzhiyun 				const struct i2c_device_id *devid)
1737*4882a593Smuzhiyun {
1738*4882a593Smuzhiyun 	return sensor_register_device(client, NULL, devid, &gsensor_sc7a20_ops);
1739*4882a593Smuzhiyun }
1740*4882a593Smuzhiyun 
gsensor_sc7a20_remove(struct i2c_client * client)1741*4882a593Smuzhiyun static int gsensor_sc7a20_remove(struct i2c_client *client)
1742*4882a593Smuzhiyun {
1743*4882a593Smuzhiyun 	return sensor_unregister_device(client, NULL, &gsensor_sc7a20_ops);
1744*4882a593Smuzhiyun }
1745*4882a593Smuzhiyun 
1746*4882a593Smuzhiyun static const struct i2c_device_id gsensor_sc7a20_id[] = {
1747*4882a593Smuzhiyun 	{"gs_sc7a20", ACCEL_ID_SC7A20},
1748*4882a593Smuzhiyun 	{}
1749*4882a593Smuzhiyun };
1750*4882a593Smuzhiyun 
1751*4882a593Smuzhiyun static struct i2c_driver gsensor_sc7a20_driver = {
1752*4882a593Smuzhiyun 	.probe = gsensor_sc7a20_probe,
1753*4882a593Smuzhiyun 	.remove = gsensor_sc7a20_remove,
1754*4882a593Smuzhiyun 	.shutdown = sensor_shutdown,
1755*4882a593Smuzhiyun 	.id_table = gsensor_sc7a20_id,
1756*4882a593Smuzhiyun 	.driver = {
1757*4882a593Smuzhiyun 		.name = "gsensor_sc7a20",
1758*4882a593Smuzhiyun 	#ifdef CONFIG_PM
1759*4882a593Smuzhiyun 		.pm = &sensor_pm_ops,
1760*4882a593Smuzhiyun 	#endif
1761*4882a593Smuzhiyun 	},
1762*4882a593Smuzhiyun };
1763*4882a593Smuzhiyun 
1764*4882a593Smuzhiyun module_i2c_driver(gsensor_sc7a20_driver);
1765*4882a593Smuzhiyun 
1766*4882a593Smuzhiyun MODULE_AUTHOR("luowei <lw@rock-chips.com>");
1767*4882a593Smuzhiyun MODULE_DESCRIPTION("sc7a20 3-Axis accelerometer driver");
1768*4882a593Smuzhiyun MODULE_LICENSE("GPL");
1769