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