xref: /OK3568_Linux_fs/kernel/drivers/input/sensors/accel/sc7a30.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /* drivers/input/sensors/access/sc7a30.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 <linux/atomic.h>
24 #include <linux/delay.h>
25 #include <linux/input.h>
26 #include <linux/workqueue.h>
27 #include <linux/freezer.h>
28 #include <linux/of_gpio.h>
29 #ifdef CONFIG_HAS_EARLYSUSPEND
30 #include <linux/earlysuspend.h>
31 #endif
32 #include <linux/sensor-dev.h>
33 #include <linux/ioctl.h>
34 #include <linux/wakelock.h>
35 
36 #define SC7A30_ENABLE			1
37 #define SC7A30_XOUT_L			0x28
38 #define SC7A30_XOUT_H			0x29
39 #define SC7A30_YOUT_L			0x2A
40 #define SC7A30_YOUT_H			0x2B
41 #define SC7A30_ZOUT_L			0x2C
42 #define SC7A30_ZOUT_H			0x2D
43 #define SC7A30_MODE			0x20
44 #define SC7A30_MODE1			0x21
45 #define SC7A30_MODE2			0x22
46 #define SC7A30_MODE3			0x23
47 #define SC7A30_BOOT			0x24
48 #define SC7A30_STATUS			0x27
49 #define SC7A30_50HZ			0x40
50 #define SC7A30_100HZ			0x50
51 #define SC7A30_200HZ			0x60
52 #define SC7A30_400HZ			0x70
53 #define SC7A30_RANGE			32768
54 
55 #define CALIBRATION_NUM		20//40
56 #define AXIS_X_Y_RANGE_LIMIT	200
57 #define AXIS_X_Y_AVG_LIMIT	400
58 #define AXIS_Z_RANGE		200
59 #define AXIS_Z_DFT_G		1000
60 #define GOTO_CALI		100
61 #define FAILTO_CALI		101
62 /* LIS3DH */
63 #define SC7A30_PRECISION        12
64 #define SC7A30_BOUNDARY		(0x1 << (SC7A30_PRECISION - 1))
65 #define SC7A30_GRAVITY_STEP	(SC7A30_RANGE / SC7A30_BOUNDARY)
66 
67 #define SC7A30_COUNT_AVERAGE	2
68 
69 #define CFG_GSENSOR_CALIBFILE   "/data/data/com.actions.sensor.calib/files/gsensor_calib.txt"
70 
71 struct SC7A30_acc {
72 	int    x;
73 	int    y;
74 	int    z;
75 };
76 
77 static struct SC7A30_acc offset;
78 static int calibrated;
79 static struct i2c_client *sc7a30_client;
80 
81 struct sensor_axis_average {
82 		long x_average;
83 		long y_average;
84 		long z_average;
85 		int count;
86 };
87 
88 struct Cali_Data {
89 	//mis p and n
90 	unsigned char xpmis; //x axis positive mismatch to write
91 	unsigned char xnmis; //x axis negtive mismatch to write
92 	unsigned char ypmis;
93 	unsigned char ynmis;
94 	unsigned char zpmis;
95 	unsigned char znmis;
96 	//off p and n
97 	unsigned char xpoff; //x axis positive offset to write
98 	unsigned char xnoff; //x axis negtive offset to write
99 	unsigned char ypoff;
100 	unsigned char ynoff;
101 	unsigned char zpoff;
102 	unsigned char znoff;
103 	//mid mis and off
104 	unsigned char xmmis; //x axis middle mismatch to write
105 	unsigned char ymmis; //y axis middle mismatch to write
106 	unsigned char zmmis; //z axis middle mismatch to write
107 	unsigned char xmoff; //x axis middle offset to write
108 	unsigned char ymoff; //y axis middle offset to write
109 	unsigned char zmoff; //z axis middle offset to write
110 	//output p and n
111 	signed int xpoutput; //x axis output of positive mismatch
112 	signed int xnoutput; //x axis output of negtive mismatch
113 	signed int ypoutput;
114 	signed int ynoutput;
115 	signed int zpoutput;
116 	signed int znoutput;
117 	//output
118 	signed int xfoutput; //x axis the best or the temporary output
119 	signed int yfoutput; //y axis the best or the temporary output
120 	signed int zfoutput; //z axis the best or the temporary output
121 	//final and temp flag
122 	unsigned char xfinalf; //x axis final flag:if 1,calibration finished
123 	unsigned char yfinalf; //y axis final flag:if 1,calibration finished
124 	unsigned char zfinalf; //z axis final flag:if 1,calibration finished
125 	unsigned char xtempf;  //x axis temp flag:if 1,the step calibration finished
126 	unsigned char ytempf;  //y axis temp flag:if 1,the step calibration finished
127 	unsigned char ztempf;  //z axis temp flag:if 1,the step calibration finished
128 
129 	unsigned char xaddmis;	//x axis mismtach register address
130 	unsigned char yaddmis;	//y axis mismtach register address
131 	unsigned char zaddmis;	//z axis mismtach register address
132 	unsigned char xaddoff;	//x axis offset register address
133 	unsigned char yaddoff;	//y axis offset register address
134 	unsigned char zaddoff;	//z axis offset register address
135 
136 	unsigned char (*MisDataSpaceConvert)(unsigned char continuous);	//mismatch space convert function pointer
137 	unsigned char (*OffDataSpaceConvert)(unsigned char continuous);	//offset space convert function pointer
138 };
139 
140 static struct sensor_axis_average axis_average;
141 
Read_Reg(unsigned char reg)142 static unsigned char Read_Reg(unsigned char reg)
143 {
144 	char buffer[3] = {0};
145 	*buffer = reg;
146 	sensor_rx_data(sc7a30_client, buffer, 1);
147 	return buffer[0];
148 }
149 
Read_Output_3axis(unsigned char * acc_buf)150 static void Read_Output_3axis(unsigned char *acc_buf)
151 {
152 	char buffer[3] = {0};
153 	int index = 0;
154 	int ret = 0;
155 	while(1){
156 			msleep(20);
157 			*buffer = SC7A30_STATUS;
158 			//ret = sensor_rx_data(sc7a30_client, buffer,1);
159 			buffer[0] = Read_Reg(0x27);
160 			if( (buffer[0] & 0x08) != 0 ) {break;}
161 	index++;
162 	if(index > 40)break;
163 	}
164 	//6 register data be read out
165 	*buffer = SC7A30_XOUT_L;
166 	ret = sensor_rx_data(sc7a30_client, buffer, 1);
167 	acc_buf[0] = buffer[0];
168 	*buffer = SC7A30_XOUT_H;
169 	ret = sensor_rx_data(sc7a30_client, buffer, 1);
170 	acc_buf[1] = buffer[0];
171 
172 	*buffer = SC7A30_YOUT_L;
173 	ret = sensor_rx_data(sc7a30_client, buffer, 1);
174 	acc_buf[2] = buffer[0];
175 	*buffer = SC7A30_YOUT_H;
176 	ret = sensor_rx_data(sc7a30_client, buffer, 1);
177 	acc_buf[3] = buffer[0];
178 
179 	*buffer = SC7A30_ZOUT_L;
180 	ret = sensor_rx_data(sc7a30_client, buffer,1);
181 	acc_buf[4] = buffer[0];
182 	*buffer = SC7A30_ZOUT_H;
183 	ret = sensor_rx_data(sc7a30_client, buffer, 1);
184 	acc_buf[5] = buffer[0];
185 }
186 
Write_Input(char addr,char thedata)187 static void Write_Input(char addr, char thedata)
188 {
189 	int result;
190 	result = sensor_write_reg(sc7a30_client, addr, thedata);
191 }
192 
tilt_3axis_mtp(signed int x,signed int y,signed int z)193 static void tilt_3axis_mtp(signed int x, signed int y, signed int z)
194 {
195 	char buffer[6] = {0};
196 	unsigned char buffer0[6] = {0};
197 	unsigned char buffer1[6] = {0};
198 	signed char mtpread[3]={0};
199 	signed int xoutp, youtp, zoutp;
200 	signed int xoutpt, youtpt, zoutpt;
201 	signed char xtilt, ytilt, ztilt;
202 	xoutp = youtp = zoutp = 0;
203 	xoutpt = youtpt = zoutpt = 0;
204 	xtilt = ytilt = ztilt = 0;
205 	Read_Output_3axis(buffer0);
206 	Read_Output_3axis(buffer1);
207 
208 	xoutpt = ((signed int)((buffer1[1]<<8)|buffer1[0]))>>4;
209 	youtpt = ((signed int)((buffer1[3]<<8)|buffer1[2]))>>4;
210 	zoutpt = ((signed int)((buffer1[5]<<8)|buffer1[4]))>>4;
211 
212 	xoutp = xoutpt-x*16;
213 	youtp = youtpt-y*16;
214 	zoutp = zoutpt-z*16;
215 
216 	*buffer = 0x10;
217 	sensor_rx_data(sc7a30_client, buffer, 1);
218 	mtpread[0]=(signed char)buffer[0];
219 
220 	*buffer = 0x11;
221 	sensor_rx_data(sc7a30_client, buffer, 1);
222 	mtpread[1]=(signed char)buffer[0];
223 
224 	*buffer = 0x12;
225 	sensor_rx_data(sc7a30_client, buffer, 1);
226 	mtpread[2]=(signed char)buffer[0];
227 
228 	xtilt=(signed char)(xoutp/8)+ mtpread[0];
229 	ytilt=(signed char)(youtp/8)+ mtpread[1];
230 	ztilt=(signed char)(zoutp/8)+ mtpread[2];
231 
232 	Write_Input(0x10, xtilt);
233 	Write_Input(0x11, ytilt);
234 	Write_Input(0x12, ztilt);
235 
236 }
237 
forword_MisDataSpaceConvert(unsigned char continuous)238 static unsigned char forword_MisDataSpaceConvert(unsigned char continuous)
239 {
240 	if (continuous >= 128)
241 		return continuous - 128;
242 	else
243 		return 255 - continuous;
244 }
245 
reverse_MisDataSpaceConvert(unsigned char continuous)246 static unsigned char reverse_MisDataSpaceConvert(unsigned char continuous)
247 {
248 	if (continuous >= 128)
249 		return continuous;
250 	else
251 		return 127 - continuous;
252 }
253 
reverse_OffDataSpaceConvert(unsigned char continuous)254 static unsigned char reverse_OffDataSpaceConvert(unsigned char continuous)
255 {
256 		return 127 - continuous;
257 }
258 
259 
forword_OffDataSpaceConvert(unsigned char continuous)260 static unsigned char forword_OffDataSpaceConvert(unsigned char continuous)
261 {
262 		return continuous;
263 }
264 
check_output_set_finalflag(struct Cali_Data * pcalidata,unsigned char err)265 static void check_output_set_finalflag(struct Cali_Data *pcalidata,unsigned char err)
266 {
267 
268 	if (abs(pcalidata->xfoutput) < err) {
269 		//printk("line:%d Xcali finish!Final=%d\n",__LINE__,pcalidata->xfoutput);
270 		pcalidata->xfinalf=1;
271 	}
272 	if (abs(pcalidata->yfoutput) < err) {
273 		//printk("line:%d Xcali finish!Final=%d\n",__LINE__,pcalidata->yfoutput);
274 		pcalidata->yfinalf=1;
275 	}
276 	if (abs(pcalidata->zfoutput) < err) {
277 		//printk("line:%d Xcali finish!Final=%d\n",__LINE__,pcalidata->zfoutput);
278 		pcalidata->zfinalf=1;
279 	}
280 
281 }
282 
check_finalflag_set_tempflag(struct Cali_Data * pcalidata)283 static void check_finalflag_set_tempflag(struct Cali_Data *pcalidata)
284 {
285 	if (pcalidata->xfinalf) { pcalidata->xtempf=1; }
286 	if (pcalidata->yfinalf) { pcalidata->ytempf=1; }
287 	if (pcalidata->zfinalf) { pcalidata->ztempf=1; }
288 }
289 
check_flag_is_return(struct Cali_Data * pcalidata)290 static unsigned char check_flag_is_return(struct Cali_Data *pcalidata)
291 {
292 	if ((pcalidata->xfinalf) && (pcalidata->yfinalf) && (pcalidata->zfinalf))
293 	{
294 		//printk("line:%d Allcali finish!\n",__LINE__);
295 		return 1;//xyz cali ok
296 	} else
297 		return 0;
298 }
299 
updata_midmis_address(struct Cali_Data * pcalidata)300 static void updata_midmis_address(struct Cali_Data *pcalidata)
301 {
302 	if(pcalidata->xtempf == 0) {
303 		pcalidata->xmmis = (unsigned char)(((unsigned int)(pcalidata->xpmis) + (unsigned int)(pcalidata->xnmis))/2);
304 		pcalidata->MisDataSpaceConvert = reverse_MisDataSpaceConvert;
305 		Write_Input(pcalidata->xaddmis, (*(pcalidata->MisDataSpaceConvert))(pcalidata->xmmis));
306 	}
307 	if(pcalidata->ytempf == 0) {
308 		pcalidata->ymmis = (unsigned char)(((unsigned int)(pcalidata->ypmis) + (unsigned int)(pcalidata->ynmis))/2);
309 		pcalidata->MisDataSpaceConvert = forword_MisDataSpaceConvert;
310 		Write_Input(pcalidata->yaddmis, (*(pcalidata->MisDataSpaceConvert))(pcalidata->ymmis));
311 	}
312 	if(pcalidata->ztempf == 0) {
313 		pcalidata->zmmis = (unsigned char)(((unsigned int)(pcalidata->zpmis) + (unsigned int)(pcalidata->znmis))/2);
314 		pcalidata->MisDataSpaceConvert = reverse_MisDataSpaceConvert;
315 		Write_Input(pcalidata->zaddmis, (*(pcalidata->MisDataSpaceConvert))(pcalidata->zmmis));
316 	}
317 }
318 
updata_midoff_address(struct Cali_Data * pcalidata)319 static void updata_midoff_address(struct Cali_Data *pcalidata)
320 {
321 	if (pcalidata->xtempf == 0) {
322 		pcalidata->xmoff = (unsigned char)(((unsigned int)(pcalidata->xpoff) + (unsigned int)(pcalidata->xnoff))/2);
323 		pcalidata->OffDataSpaceConvert = reverse_OffDataSpaceConvert;
324 		Write_Input(pcalidata->xaddoff, (*(pcalidata->OffDataSpaceConvert))(pcalidata->xmoff));
325 	}
326 	if (pcalidata->ytempf == 0) {
327 		pcalidata->ymoff = (unsigned char)(((unsigned int)(pcalidata->ypoff) + (unsigned int)(pcalidata->ynoff))/2);
328 		pcalidata->OffDataSpaceConvert = forword_OffDataSpaceConvert;
329 		Write_Input(pcalidata->yaddoff, (*(pcalidata->OffDataSpaceConvert))(pcalidata->ymoff));
330 	}
331 	if (pcalidata->ztempf == 0) {
332 		pcalidata->zmoff = (unsigned char)(((unsigned int)(pcalidata->zpoff) + (unsigned int)(pcalidata->znoff))/2);
333 		pcalidata->OffDataSpaceConvert = forword_OffDataSpaceConvert;
334 		Write_Input(pcalidata->zaddoff, (*(pcalidata->OffDataSpaceConvert))(pcalidata->zmoff));
335 	}
336 }
337 
updata_mmis_pnfoutput_set_tempflag(struct Cali_Data * pcalidata,unsigned char * buf,signed int xrel,signed int yrel,signed int zrel)338 static void updata_mmis_pnfoutput_set_tempflag( struct Cali_Data *pcalidata,
339 											unsigned char *buf,
340 										  	signed int xrel,
341 										  	signed int yrel,
342 										  	signed int zrel)
343 {
344 
345 	pcalidata->xfoutput = (signed int)((signed char)buf[1])-xrel;
346 	pcalidata->yfoutput = (signed int)((signed char)buf[3])-yrel;
347 	pcalidata->zfoutput  =(signed int)((signed char)buf[5])-zrel;
348 
349 	if (abs(pcalidata->xfoutput)<25)pcalidata->xtempf=1;
350 	if (abs(pcalidata->yfoutput)<25)pcalidata->ytempf=1;
351 	if (abs(pcalidata->zfoutput)<25)pcalidata->ztempf=1;
352 
353 	if (pcalidata->xtempf == 0)
354 	{
355 		if (pcalidata->xfoutput>0) {
356 			pcalidata->xpoutput = pcalidata->xfoutput;
357 			pcalidata->xpmis = pcalidata->xmmis;
358 		}
359 		else {
360 			pcalidata->xnoutput = pcalidata->xfoutput;
361 			pcalidata->xnmis = pcalidata->xmmis;
362 		}
363 	}
364 
365 	if (pcalidata->ytempf == 0)
366 	{
367 		if (pcalidata->yfoutput>0){
368 			pcalidata->ypoutput = pcalidata->yfoutput;
369 			pcalidata->ypmis = pcalidata->ymmis;
370 		}
371 		else{
372 			pcalidata->ynoutput = pcalidata->yfoutput;
373 			pcalidata->ynmis = pcalidata->ymmis;
374 		}
375 	}
376 
377 	if(pcalidata->ztempf==0)
378 	{
379 		if(pcalidata->zfoutput>0){
380 			pcalidata->zpoutput = pcalidata->zfoutput;
381 			pcalidata->zpmis = pcalidata->zmmis;
382 		}
383 		else{
384 			pcalidata->znoutput = pcalidata->zfoutput;
385 			pcalidata->znmis = pcalidata->zmmis;
386 		}
387 	}
388 }
389 
updata_moff_pnfoutput_set_tempflag(struct Cali_Data * pcalidata,unsigned char * buf,signed int xrel,signed int yrel,signed int zrel)390 static void updata_moff_pnfoutput_set_tempflag(	struct Cali_Data *pcalidata,
391 											unsigned char *buf,
392 										  	signed int xrel,
393 										  	signed int yrel,
394 										  	signed int zrel)
395 {
396 
397 	pcalidata->xfoutput = (signed int)((signed char)buf[1])-xrel;
398 	pcalidata->yfoutput = (signed int)((signed char)buf[3])-yrel;
399 	pcalidata->zfoutput = (signed int)((signed char)buf[5])-zrel;
400 
401 	if (abs(pcalidata->xfoutput)<3)pcalidata->xtempf = 1;
402 	if (abs(pcalidata->yfoutput)<3)pcalidata->ytempf = 1;
403 	if (abs(pcalidata->zfoutput)<3)pcalidata->ztempf = 1;
404 
405 	if (pcalidata->xtempf == 0)
406 	{
407 		if(pcalidata->xfoutput>0){
408 			pcalidata->xpoutput = pcalidata->xfoutput;
409 			pcalidata->xpoff = pcalidata->xmoff;
410 		} else {
411 			pcalidata->xnoutput = pcalidata->xfoutput;
412 			pcalidata->xnoff = pcalidata->xmoff;
413 		}
414 	}
415 
416 	if (pcalidata->ytempf == 0)
417 	{
418 		if(pcalidata->yfoutput>0){
419 			pcalidata->ypoutput = pcalidata->yfoutput;
420 			pcalidata->ypoff = pcalidata->ymoff;
421 		} else {
422 			pcalidata->ynoutput = pcalidata->yfoutput;
423 			pcalidata->ynoff = pcalidata->ymoff;
424 		}
425 	}
426 
427 	if (pcalidata->ztempf == 0)
428 	{
429 		if (pcalidata->zfoutput > 0) {
430 			pcalidata->zpoutput = pcalidata->zfoutput;
431 			pcalidata->zpoff = pcalidata->zmoff;
432 		} else {
433 			pcalidata->znoutput = pcalidata->zfoutput;
434 			pcalidata->znoff = pcalidata->zmoff;
435 		}
436 	}
437 }
438 
auto_calibration_instant(signed int x,signed int y,signed int z)439 static int auto_calibration_instant(signed int x, signed int y, signed int z)
440 {
441 
442 	unsigned char count=0,cyclecount=0;
443 	unsigned char acc_buf[6];
444 
445 	struct Cali_Data calidata={0};
446 
447 	calidata.xaddmis = 0x40;
448 	calidata.yaddmis = 0x41;
449 	calidata.zaddmis = 0x42;
450 	calidata.xaddoff = 0x47;
451 	calidata.yaddoff = 0x48;
452 	calidata.zaddoff = 0x49;
453 #ifdef PRINT
454 	printf("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
455 				(UINT)calidata.xfinalf,(UINT)calidata.xtempf,
456 				(UINT)calidata.yfinalf,(UINT)calidata.ytempf,
457 				(UINT)calidata.zfinalf,(UINT)calidata.ztempf
458 				);
459 #endif
460 
461 	Read_Output_3axis(acc_buf);
462 	calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
463 	calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
464 	calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
465 	check_output_set_finalflag(&calidata,2);
466 	if(check_flag_is_return(&calidata)){
467 		printk("step1:=file=%s,line=%d\n",__FILE__,__LINE__);
468 		return 1;
469 	}
470 #ifdef PRINT
471 	printf("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
472 				(UINT)calidata.xfinalf,(UINT)calidata.xtempf,
473 				(UINT)calidata.yfinalf,(UINT)calidata.ytempf,
474 				(UINT)calidata.zfinalf,(UINT)calidata.ztempf
475 				);
476 #endif
477 
478 	if (calidata.xfinalf == 0) {
479 		Write_Input(calidata.xaddoff, 0x3f);//cali mis under off=0x3f
480 		Write_Input(0x10, 0); //tilt clear
481 		calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
482 		Write_Input(calidata.xaddmis, (*(calidata.MisDataSpaceConvert))(255)); // x mis to max
483 	}
484 	if (calidata.yfinalf == 0) {
485 		Write_Input(calidata.yaddoff, 0x3f);//cali mis under off=0x3f
486 		Write_Input(0x11, 0); //tilt clear
487 		calidata.MisDataSpaceConvert = forword_MisDataSpaceConvert;
488 		Write_Input(calidata.yaddmis, (*(calidata.MisDataSpaceConvert))(255)); // y mis to max
489 	}
490 	if (calidata.zfinalf == 0){
491 		Write_Input(calidata.zaddoff, 0x3f);//cali mis under off=0x3f
492 		Write_Input(0x12, 0); //tilt clear
493 		calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
494 		Write_Input(calidata.zaddmis, (*(calidata.MisDataSpaceConvert))(255)); // z mis to max
495 	}
496 
497 	Read_Output_3axis(acc_buf);
498 	calidata.xpoutput=calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
499 	calidata.ypoutput=calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
500 	calidata.zpoutput=calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
501 	printk("step 2 xnoutput = %d ynoutput = %d znoutput = %d \n",calidata.xnoutput,calidata.ynoutput,calidata.znoutput);
502 	if ((calidata.xpoutput<-25) || (calidata.ypoutput<-25) || (calidata.zpoutput<-25)){
503 		printk("step2:=file=%s,line=%d\n",__FILE__,__LINE__);
504 		sensor_write_reg(sc7a30_client,0x13,0x01);//allen
505 		Write_Input(0x1e, 0x15);  //保存校准寄存器的修改
506 		mdelay(300);
507 		// Write_Input(0x1e, 0);
508 		return 0;
509 	}
510 
511 	if (calidata.xfinalf == 0) {
512 		calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
513 		Write_Input(calidata.xaddmis, (*(calidata.MisDataSpaceConvert))(0)); // x mis to min
514 	}
515 	if (calidata.yfinalf == 0) {
516 		calidata.MisDataSpaceConvert = forword_MisDataSpaceConvert;
517 		Write_Input(calidata.yaddmis, (*(calidata.MisDataSpaceConvert))(0)); // y mis to min
518 	}
519 	if (calidata.zfinalf == 0) {
520 		calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
521 		Write_Input(calidata.zaddmis, (*(calidata.MisDataSpaceConvert))(0)); // z mis to min
522 	}
523 	Read_Output_3axis(acc_buf);
524 	calidata.xnoutput=calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
525 	calidata.ynoutput=calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
526 	calidata.znoutput=calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
527 	printk("step 2 xnoutput = %d ynoutput = %d znoutput = %d \n",calidata.xnoutput,calidata.ynoutput,calidata.znoutput);
528 	if ((calidata.xnoutput>25) || (calidata.ynoutput>25) || (calidata.znoutput>25)) {
529 		printk("step2:=file=%s,line=%d\n",__FILE__,__LINE__);
530 		sensor_write_reg(sc7a30_client,0x13,0x01);
531 		Write_Input(0x1e, 0x15);
532 		mdelay(300);
533 
534 		return 0;
535 	}
536 
537 	if (abs(calidata.xpoutput)<=abs(calidata.xnoutput)) {
538 		calidata.xfoutput=calidata.xpoutput;
539 		calidata.xmmis=255;
540 	} else {
541 		calidata.xfoutput=calidata.xnoutput;
542 		calidata.xmmis=0;
543 	}
544 	if (abs(calidata.ypoutput)<=abs(calidata.ynoutput)) {
545 		calidata.yfoutput=calidata.ypoutput;
546 		calidata.ymmis=255;
547 	} else {
548 		calidata.yfoutput=calidata.ynoutput;
549 		calidata.ymmis=0;
550 	}
551 	if (abs(calidata.zpoutput)<=abs(calidata.znoutput)) {
552 		calidata.zfoutput=calidata.zpoutput;
553 		calidata.zmmis=255;
554 	} else {
555 		calidata.zfoutput=calidata.znoutput;
556 		calidata.zmmis=0;
557 	}
558 
559 	if (calidata.xfinalf == 0) {
560 		calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
561 		Write_Input(calidata.xaddmis, (*(calidata.MisDataSpaceConvert))(calidata.xmmis));
562 	}
563 	if (calidata.yfinalf == 0) {
564 		calidata.MisDataSpaceConvert = forword_MisDataSpaceConvert;
565 		Write_Input(calidata.yaddmis, (*(calidata.MisDataSpaceConvert))(calidata.ymmis));
566 	}
567 	if (calidata.zfinalf == 0) {
568 		calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
569 		Write_Input(calidata.zaddmis, (*(calidata.MisDataSpaceConvert))(calidata.zmmis));
570 	}
571 	check_output_set_finalflag(&calidata,2);
572 
573 	if(abs(calidata.xfoutput)<25) calidata.xtempf=1;
574 	if(abs(calidata.yfoutput)<25) calidata.ytempf=1;
575 	if(abs(calidata.zfoutput)<25) calidata.ztempf=1;
576 
577 	calidata.xpmis=calidata.ypmis=calidata.zpmis=255;
578 	calidata.xnmis=calidata.ynmis=calidata.znmis=0;
579 	check_finalflag_set_tempflag(&calidata);
580 #ifdef PRINT
581 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
582 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
583 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
584 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
585 				);
586 #endif
587 	cyclecount=0;
588 	while(1){
589 		if (++cyclecount > 20)
590 			break;
591 
592 		if((calidata.xtempf)&&(calidata.ytempf)&&(calidata.ztempf))break;
593 		updata_midmis_address(&calidata);
594 		Read_Output_3axis(acc_buf);
595 		calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
596 		calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
597 		calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
598 #ifdef PRINT
599 		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",
600 				calidata.xpoutput,(unsigned int)calidata.xpmis,
601 				calidata.xfoutput,(unsigned int)calidata.xmmis,
602 				calidata.xnoutput,(unsigned int)calidata.xnmis,
603 				calidata.ypoutput,(unsigned int)calidata.ypmis,
604 				calidata.yfoutput,(unsigned int)calidata.ymmis,
605 				calidata.ynoutput,(unsigned int)calidata.ynmis,
606 				calidata.zpoutput,(unsigned int)calidata.zpmis,
607 				calidata.zfoutput,(unsigned int)calidata.zmmis,
608 				calidata.znoutput,(unsigned int)calidata.znmis
609 				);
610 #endif
611 		updata_mmis_pnfoutput_set_tempflag(&calidata,acc_buf,x,y,z);
612 		check_output_set_finalflag(&calidata,2);
613 		if(check_flag_is_return(&calidata))return 1;
614 	}
615 #ifdef PRINT
616 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
617 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
618 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
619 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
620 				);
621 #endif
622 
623 	calidata.xtempf=calidata.ytempf=calidata.ztempf=1;
624 	if((calidata.xmmis>0)&&(calidata.xmmis<255))calidata.xtempf=0;
625 	if((calidata.ymmis>0)&&(calidata.ymmis<255))calidata.ytempf=0;
626 	if((calidata.zmmis>0)&&(calidata.zmmis<255))calidata.ztempf=0;
627 	calidata.xpmis=calidata.xnmis=calidata.xmmis;
628 	calidata.ypmis=calidata.ynmis=calidata.ymmis;
629 	calidata.zpmis=calidata.znmis=calidata.zmmis;
630 	for(count = 0; count < 3; count++)
631 	{
632 		if(calidata.xtempf==0){
633 			calidata.xpmis = calidata.xmmis + count - 1;
634 			if((calidata.xpmis>calidata.xmmis)&&(calidata.xpmis==128))calidata.xpmis = calidata.xmmis + count-1 + 1;
635 			if((calidata.xpmis<calidata.xmmis)&&(calidata.xpmis==127))calidata.xpmis = calidata.xmmis + count-1 - 1;
636 			calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
637 			Write_Input(calidata.xaddmis, (*(calidata.MisDataSpaceConvert))(calidata.xpmis));
638 		}
639 		if(calidata.ytempf==0){
640 			calidata.ypmis = calidata.ymmis + count - 1;
641 			if((calidata.ypmis>calidata.ymmis)&&(calidata.ypmis==128))calidata.ypmis = calidata.ymmis + count-1 + 1;
642 			if((calidata.ypmis<calidata.ymmis)&&(calidata.ypmis==127))calidata.ypmis = calidata.ymmis + count-1 - 1;
643 			calidata.MisDataSpaceConvert = forword_MisDataSpaceConvert;
644 			Write_Input(calidata.yaddmis, (*(calidata.MisDataSpaceConvert))(calidata.ypmis));
645 		}
646 		if(calidata.ztempf==0){
647 			calidata.zpmis = calidata.zmmis + count - 1;
648 			if((calidata.zpmis>calidata.zmmis)&&(calidata.zpmis==128))calidata.zpmis = calidata.zmmis + count-1 + 1;
649 			if((calidata.zpmis<calidata.zmmis)&&(calidata.zpmis==127))calidata.zpmis = calidata.zmmis + count-1 - 1;
650 			calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
651 			Write_Input(calidata.zaddmis, (*(calidata.MisDataSpaceConvert))(calidata.zpmis));
652 		}
653 		Read_Output_3axis(acc_buf);
654 		if(abs((signed int)((signed char)acc_buf[1])-x)<abs(calidata.xfoutput)){
655 			calidata.xnmis=calidata.xpmis;
656 			calidata.xfoutput= (signed int)((signed char)acc_buf[1])-x;
657 		}
658 		if(abs((signed int)((signed char)acc_buf[3])-y)<abs(calidata.yfoutput)){
659 			calidata.ynmis=calidata.ypmis;
660 			calidata.yfoutput= (signed int)((signed char)acc_buf[3])-y;
661 		}
662 		if(abs((signed int)((signed char)acc_buf[5])-z)<abs(calidata.zfoutput)){
663 			calidata.znmis=calidata.zpmis;
664 			calidata.zfoutput= (signed int)((signed char)acc_buf[5])-z;
665 		}
666 		if(calidata.xtempf==0){
667 			calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
668 			Write_Input(calidata.xaddmis, (*(calidata.MisDataSpaceConvert))(calidata.xnmis));
669 		}
670 		if(calidata.ytempf==0){
671 			calidata.MisDataSpaceConvert = forword_MisDataSpaceConvert;
672 			Write_Input(calidata.yaddmis, (*(calidata.MisDataSpaceConvert))(calidata.ynmis));
673 		}
674 		if(calidata.ztempf==0){
675 			calidata.MisDataSpaceConvert = reverse_MisDataSpaceConvert;
676 			Write_Input(calidata.zaddmis, (*(calidata.MisDataSpaceConvert))(calidata.znmis));
677 		}
678 #ifdef PRINT
679 		printk("L%4d:xf=%4d,xmis=%4d,yf=%4d,ymis=%4d,zf=%4d,zmis=%4d\n\r",__LINE__,
680 					(signed int)((signed char)acc_buf[1])-x,(unsigned int)calidata.xpmis,
681 					(signed int)((signed char)acc_buf[3])-y,(unsigned int)calidata.ypmis,
682 					(signed int)((signed char)acc_buf[5])-z,(unsigned int)calidata.zpmis
683 					);
684 #endif
685 
686 	}
687 	//Write_Input(AddMis, (*MisDataSpaceConvert)(FinaloutputMisConfiguration));
688 
689 	calidata.xpoff=calidata.ypoff=calidata.zpoff=0x7f;
690 	calidata.xnoff=calidata.ynoff=calidata.znoff=0;
691 	calidata.xtempf=calidata.ytempf=calidata.ztempf=0;
692 #ifdef PRINT
693 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
694 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
695 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
696 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
697 				);
698 #endif
699 	check_finalflag_set_tempflag(&calidata);
700 #ifdef PRINT
701 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
702 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
703 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
704 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
705 				);
706 #endif
707 	//offset max
708 	if(calidata.xtempf==0){
709 		calidata.OffDataSpaceConvert = reverse_OffDataSpaceConvert;
710 		Write_Input(calidata.xaddoff, (*(calidata.OffDataSpaceConvert))(calidata.xpoff)); // x off to max
711 	}
712 	if(calidata.ytempf==0){
713 		calidata.OffDataSpaceConvert = forword_OffDataSpaceConvert;
714 		Write_Input(calidata.yaddoff, (*(calidata.OffDataSpaceConvert))(calidata.xpoff)); // y off to max
715 	}
716 	if(calidata.ztempf==0){
717 		calidata.OffDataSpaceConvert = forword_OffDataSpaceConvert;
718 		Write_Input(calidata.zaddoff, (*(calidata.OffDataSpaceConvert))(calidata.xpoff)); // z off to max
719 	}
720 	Read_Output_3axis(acc_buf);
721 	calidata.xpoutput=calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
722 	calidata.ypoutput=calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
723 	calidata.zpoutput=calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
724 #ifdef PRINT
725 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
726 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
727 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
728 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
729 				);
730 #endif
731 	check_output_set_finalflag(&calidata,2);
732 #ifdef PRINT
733 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
734 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
735 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
736 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
737 				);
738 #endif
739 	//offset min
740 	if (calidata.xtempf == 0) {
741 		calidata.OffDataSpaceConvert = reverse_OffDataSpaceConvert;
742 		Write_Input(calidata.xaddoff, (*(calidata.OffDataSpaceConvert))(calidata.xnoff)); // x off to min
743 	}
744 	if (calidata.ytempf == 0) {
745 		calidata.OffDataSpaceConvert = forword_OffDataSpaceConvert;
746 		Write_Input(calidata.yaddoff, (*(calidata.OffDataSpaceConvert))(calidata.ynoff)); // y off to min
747 	}
748 	if (calidata.ztempf == 0) {
749 		calidata.OffDataSpaceConvert = forword_OffDataSpaceConvert;
750 		Write_Input(calidata.zaddoff, (*(calidata.OffDataSpaceConvert))(calidata.znoff)); // z off to min
751 	}
752 	Read_Output_3axis(acc_buf);
753 	calidata.xnoutput=calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
754 	calidata.ynoutput=calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
755 	calidata.znoutput=calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
756 #ifdef PRINT
757 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
758 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
759 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
760 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
761 				);
762 #endif
763 	check_output_set_finalflag(&calidata,2);
764 #ifdef PRINT
765 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
766 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
767 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
768 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
769 				);
770 #endif
771 	if (abs(calidata.xpoutput)<=abs(calidata.xnoutput)) {
772 		calidata.xfoutput=calidata.xpoutput;
773 		calidata.xmoff=calidata.xpoff;
774 	} else {
775 		calidata.xfoutput=calidata.xnoutput;
776 		calidata.xmoff=calidata.xnoff;
777 	}
778 	if (abs(calidata.ypoutput)<=abs(calidata.ynoutput)) {
779 		calidata.yfoutput=calidata.ypoutput;
780 		calidata.ymoff=calidata.ypoff;
781 	} else {
782 		calidata.yfoutput=calidata.ynoutput;
783 		calidata.ymoff=calidata.ynoff;
784 	}
785 	if (abs(calidata.zpoutput)<=abs(calidata.znoutput)) {
786 		calidata.zfoutput=calidata.zpoutput;
787 		calidata.zmoff=calidata.zpoff;
788 	} else {
789 		calidata.zfoutput=calidata.znoutput;
790 		calidata.zmoff=calidata.znoff;
791 	}
792 	if (calidata.xtempf==0) {
793 		calidata.OffDataSpaceConvert = reverse_OffDataSpaceConvert;
794 		Write_Input(calidata.xaddoff, (*(calidata.OffDataSpaceConvert))(calidata.xmoff));
795 	}
796 	if (calidata.ytempf==0) {
797 		calidata.OffDataSpaceConvert = forword_OffDataSpaceConvert;
798 		Write_Input(calidata.yaddoff, (*(calidata.OffDataSpaceConvert))(calidata.ymoff));
799 	}
800 	if (calidata.ztempf==0) {
801 		calidata.OffDataSpaceConvert = forword_OffDataSpaceConvert;
802 		Write_Input(calidata.zaddoff, (*(calidata.OffDataSpaceConvert))(calidata.zmoff));
803 	}
804 	if ((calidata.xpoutput>0 && calidata.xnoutput>0)||(calidata.xpoutput<0 && calidata.xnoutput<0)) {
805 		calidata.xfinalf=1;
806 	}
807 
808 	if((calidata.ypoutput>0 && calidata.ynoutput>0)||(calidata.ypoutput<0 && calidata.ynoutput<0)){
809 		calidata.yfinalf=1;
810 	}
811 
812 	if((calidata.zpoutput>0 && calidata.znoutput>0)||(calidata.zpoutput<0 && calidata.znoutput<0)){
813 		calidata.zfinalf=1;
814 	}
815 
816 	check_finalflag_set_tempflag(&calidata);
817 #ifdef PRINT
818 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
819 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
820 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
821 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
822 				);
823 #endif
824 	cyclecount=0;
825 	while(1){
826 		if(++cyclecount>20)break;
827 
828 		if((calidata.xtempf)&&(calidata.ytempf)&&(calidata.ztempf))break;
829 		updata_midoff_address(&calidata);
830 		Read_Output_3axis(acc_buf);
831 		calidata.xfoutput=(signed int)((signed char)acc_buf[1])-x;
832 		calidata.yfoutput=(signed int)((signed char)acc_buf[3])-y;
833 		calidata.zfoutput=(signed int)((signed char)acc_buf[5])-z;
834 #ifdef PRINT
835 		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",
836 				calidata.xpoutput,(unsigned int)calidata.xpoff,
837 				calidata.xfoutput,(unsigned int)calidata.xmoff,
838 				calidata.xnoutput,(unsigned int)calidata.xnoff,
839 				calidata.ypoutput,(unsigned int)calidata.ypoff,
840 				calidata.yfoutput,(unsigned int)calidata.ymoff,
841 				calidata.ynoutput,(unsigned int)calidata.ynoff,
842 				calidata.zpoutput,(unsigned int)calidata.zpoff,
843 				calidata.zfoutput,(unsigned int)calidata.zmoff,
844 				calidata.znoutput,(unsigned int)calidata.znoff
845 				);
846 #endif
847 		updata_moff_pnfoutput_set_tempflag(&calidata,acc_buf,x,y,z);
848 		check_output_set_finalflag(&calidata,2);
849 		if(check_flag_is_return(&calidata))return 1;
850 	}
851 #ifdef PRINT
852 	printk("L%4d:xff=%4d,xtf=%4d,yff=%4d,ytf=%4d,zff=%4d,ztf=%4d\n\r",__LINE__,
853 				(unsigned int)calidata.xfinalf,(unsigned int)calidata.xtempf,
854 				(unsigned int)calidata.yfinalf,(unsigned int)calidata.ytempf,
855 				(unsigned int)calidata.zfinalf,(unsigned int)calidata.ztempf
856 				);
857 #endif
858 
859 	return 1;
860 }
861 
auto_calibration_instant_mtp(signed int x,signed int y,signed int z)862 static __maybe_unused int auto_calibration_instant_mtp(signed int x, signed int y, signed int z)
863 {
864 	unsigned char readbuf[3]={0};
865 	unsigned char buffer[6] = {0};
866 
867 	signed int xoutp,youtp,zoutp;
868 	unsigned char xfinalf,yfinalf,zfinalf;
869 	int reg_13 = 0;
870 
871 	xoutp=youtp=zoutp=0;
872 	xfinalf=yfinalf=zfinalf=0;
873 	if (auto_calibration_instant(x,y,z) == 0)
874          {
875 		printk("auto_calibration_instant ==0 \n");
876 		sensor_write_reg(sc7a30_client, 0x1e,0x05);
877 		mdelay(100);
878 		sensor_write_reg(sc7a30_client, 0x13,0x01);
879 
880 		sensor_write_reg(sc7a30_client, 0x1e,0x15);
881 		mdelay(300);
882 		return 0;
883 	}
884 
885 	//msleep(20);
886 	tilt_3axis_mtp(x,y,z);
887 	Read_Output_3axis(buffer);
888 	xoutp=(signed int)((signed char)buffer[1])-x;
889 	youtp=(signed int)((signed char)buffer[3])-y;
890 	zoutp=(signed int)((signed char)buffer[5])-z;
891 
892 	if(abs(xoutp) < 2){xfinalf=1;}
893 	if(abs(youtp) < 2){yfinalf=1;}
894 	if(abs(zoutp) < 2){zfinalf=1;}
895 
896 	//*tbuffer = 0x10;
897 	//sensor_rx_data(sc7a30_client, tbuffer,1);
898 	readbuf[0]= Read_Reg(0x10);
899 	//*tbuffer = 0x40;
900 	//sensor_rx_data(sc7a30_client, tbuffer,1);
901 	readbuf[1]= Read_Reg(0x40);
902 	//*tbuffer = 0x47;
903 	//sensor_rx_data(sc7a30_client, tbuffer,1);
904 	readbuf[2]= Read_Reg(0x47);
905 	printk("L%4d:xtilt=%4d,xmis=%4d,xoff=%4d\n\r",__LINE__,
906 			(unsigned int)readbuf[0],
907 			(unsigned int)readbuf[1],
908 			(unsigned int)readbuf[2]
909 			);
910 
911 	readbuf[0]= Read_Reg(0x11);
912 	readbuf[1]= Read_Reg(0x41);
913 	readbuf[2]= Read_Reg(0x48);
914 	printk("L%4d:ytilt=%4d,ymis=%4d,yoff=%4d\n\r",__LINE__,
915 			(unsigned int)readbuf[0],
916 			(unsigned int)readbuf[1],
917 			(unsigned int)readbuf[2]
918 			);
919 	readbuf[0]= Read_Reg(0x12);
920 	readbuf[1]= Read_Reg(0x42);
921 	readbuf[2]= Read_Reg(0x49);
922 	printk("L%4d:ztilt=%4d,zmis=%4d,zoff=%4d\n\r",__LINE__,
923 			(unsigned int)readbuf[0],
924 			(unsigned int)readbuf[1],
925 			(unsigned int)readbuf[2]
926 			);
927 
928 	if(xfinalf && yfinalf && zfinalf)
929 	{
930 		sensor_write_reg(sc7a30_client,0x13,0x01);
931 		reg_13 = sensor_read_reg(sc7a30_client,0x13);
932 		printk("line %d  reg_13 = %x\n",__LINE__,reg_13);
933 		Write_Input(0x1e, 0x15);
934 		mdelay(300);
935 		printk(KERN_INFO "run calibration finished\n");
936 
937 		return 1;
938 	} else {
939 		sensor_write_reg(sc7a30_client,0x13,0x01);//allen MTP
940 		reg_13 = sensor_read_reg(sc7a30_client,0x13);
941 		printk("line %d  reg_13 = %x\n",__LINE__,reg_13);
942 		Write_Input(0x1e, 0x15);
943 		mdelay(300);
944 
945 		return 0;
946        }
947 }
948 
949 /****************operate according to sensor chip:start************/
950 
sensor_active(struct i2c_client * client,int enable,int rate)951 static int sensor_active(struct i2c_client *client, int enable, int rate)
952 {
953 	struct sensor_private_data *sensor =
954 	    (struct sensor_private_data *) i2c_get_clientdata(client);
955 	int result = 0;
956 	int status = 0;
957 
958 	sensor->ops->ctrl_data = 0x07;
959 
960 	if (enable)
961 	{
962 		status = SC7A30_ENABLE;	//sc7a30
963 		sensor->ops->ctrl_data |= SC7A30_400HZ;
964 	} else
965 		status = ~SC7A30_ENABLE;	//sc7a30
966 
967 	printk("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
968 	result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
969 
970 	if(result)
971 		printk("%s:fail to active sensor\n",__func__);
972 
973 	return result;
974 }
975 
sensor_init(struct i2c_client * client)976 static int sensor_init(struct i2c_client *client)
977 {
978 	struct sensor_private_data *sensor =
979 	    (struct sensor_private_data *) i2c_get_clientdata(client);
980 	int result = 0;
981 
982 	//mutex_lock(&(sensor->allen_mutex) );//allen
983 
984 	printk("aaaaa %s:line=%d\n",__func__,__LINE__);
985 
986 	result = sensor->ops->active(client,0,0);
987 	if (result)
988 	{
989 		printk("%s:line=%d,error\n",__func__,__LINE__);
990 		return result;
991 	}
992 	calibrated = 0;
993 	sc7a30_client = client;
994 	sensor->status_cur = SENSOR_OFF;
995 	//sensor->time_of_cali =0;//allen
996 	offset.x=offset.y=offset.z=0;
997 	sensor_write_reg(client, SC7A30_BOOT, 0x80);
998 	mdelay(20);
999 	result = sensor_write_reg(client, SC7A30_MODE, 0x07);
1000 
1001 	sensor_write_reg(client, SC7A30_MODE3, 0x88);
1002 //	result = sensor_write_reg(client, SC7A30_MODE, 0x77);
1003 
1004 	//register_test();
1005 	if(result)
1006 	{
1007 		printk("aaaaa %s:line=%d,error\n",__func__,__LINE__);
1008 		return result;
1009 	}
1010 
1011 	if(sensor->pdata->irq_enable)	//open interrupt
1012 	{
1013 		result = sensor_write_reg(client, SC7A30_MODE2, 0x10);
1014 		result = sensor_write_reg(client, 0x25, 0x02);
1015 
1016 		if(result)
1017 		{
1018 			printk("%s:line=%d,error\n",__func__,__LINE__);
1019 			return result;
1020 		}
1021 	}
1022 	memset(&axis_average, 0, sizeof(struct sensor_axis_average));
1023 
1024 	return result;
1025 }
1026 
sensor_convert_data(struct i2c_client * client,char high_byte,char low_byte,s16 off)1027 static int sensor_convert_data(struct i2c_client *client, char high_byte, char low_byte ,s16 off)
1028 {
1029     s64 result;
1030 	result = (((s16)((high_byte << 8) + low_byte)) >>4);
1031 	result -= off;
1032 	result = result* SC7A30_GRAVITY_STEP;
1033 
1034 	return (int)result;
1035 }
1036 
gsensor_report_value(struct i2c_client * client,struct sensor_axis * axis)1037 static int gsensor_report_value(struct i2c_client *client, struct sensor_axis *axis)
1038 {
1039 	struct sensor_private_data *sensor =
1040 	    (struct sensor_private_data *) i2c_get_clientdata(client);
1041 	if (sensor->status_cur == SENSOR_ON) {
1042 		/* Report acceleration sensor information */
1043 		input_report_abs(sensor->input_dev, ABS_X, axis->x);
1044 		input_report_abs(sensor->input_dev, ABS_Y, axis->y);
1045 		input_report_abs(sensor->input_dev, ABS_Z, axis->z);
1046 		input_sync(sensor->input_dev);
1047 		//printk("Gsensor x==%d  y==%d z==%d\n",axis->x,axis->y,axis->z);
1048 	}
1049 	return 0;
1050 }
1051 
1052 #define GSENSOR_MIN  		2
sensor_report_value(struct i2c_client * client)1053 static int sensor_report_value(struct i2c_client *client)
1054 {
1055 
1056 	struct sensor_private_data *sensor =
1057 	(struct sensor_private_data *) i2c_get_clientdata(client);
1058 	struct sensor_platform_data *pdata = sensor->pdata;
1059 	int ret = 0;
1060 	int x,y,z;
1061 	struct sensor_axis axis;
1062 	char value = 0;
1063 	//SC7A30_load_user_calibration(client);
1064 	//printk("---------------in--------------------\n");
1065 #if 0
1066 	memset(buffer1, 0, 3);
1067 	memset(buffer2, 0, 3);
1068 
1069 	*buffer1 = SC7A30_STATUS;
1070 	ret = sensor_rx_data(sc7a30_client, buffer1,1);
1071 	buffer1[0] &= 0x08;
1072 	if(!buffer1[0])
1073 		return ret;
1074 
1075 	*buffer1 = SC7A30_XOUT_L;
1076 	ret = sensor_rx_data(sc7a30_client, buffer1,1);
1077         *buffer2 = SC7A30_XOUT_H;
1078 	ret = sensor_rx_data(client, buffer2,1);
1079 	if (ret < 0)
1080 		return ret;
1081 	x = sensor_convert_data(sensor->client, buffer2[0], buffer1[0],0);	//buffer[1]:high bit
1082 
1083 	*buffer1 = SC7A30_YOUT_L;
1084 	ret = sensor_rx_data(sc7a30_client, buffer1,1);
1085 	*buffer2 = SC7A30_YOUT_H;
1086 	ret = sensor_rx_data(client, buffer2,1);
1087 	if (ret < 0)
1088 		return ret;
1089 	y = sensor_convert_data(sensor->client, buffer2[0], buffer1[0],0);
1090 	*buffer1 = SC7A30_ZOUT_L;
1091 	ret = sensor_rx_data(sc7a30_client, buffer1,1);
1092 	*buffer2 = SC7A30_ZOUT_H;
1093 	ret = sensor_rx_data(client, buffer2,1);
1094 	if (ret < 0)
1095 		return ret;
1096 	z = sensor_convert_data(sensor->client, buffer2[0], buffer1[0],0);
1097 #else
1098 	char buffer[6] = {0};
1099 	memset(buffer, 0, 6);
1100 
1101 	/* Data bytes from hardware xL, xH, yL, yH, zL, zH */
1102 	*buffer = SC7A30_XOUT_L | 0x80;
1103 	ret = sensor_rx_data(sc7a30_client, buffer, 6);
1104 	if (ret < 0) {
1105 		printk("%s, %d, sensor rx data failed\n", __func__, __LINE__);
1106 		return ret;
1107 	}
1108 
1109 	//this gsensor need 6 bytes buffer
1110 	x = sensor_convert_data(sensor->client, buffer[1], buffer[0], 0);  //buffer[1]:high bit
1111 	y = sensor_convert_data(sensor->client, buffer[3], buffer[2], 0);
1112 	z = sensor_convert_data(sensor->client, buffer[5], buffer[4], 0);
1113 #endif
1114 
1115 	axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;
1116 	axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;
1117 	axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;
1118 
1119 #if 0
1120 	axis_average.x_average += axis.x;
1121 	axis_average.y_average += axis.y;
1122 	axis_average.z_average += axis.z;
1123 	axis_average.count++;
1124 
1125 	if(axis_average.count >= SC7A30_COUNT_AVERAGE)
1126 	{
1127 		axis.x = axis_average.x_average / axis_average.count;
1128 		axis.y = axis_average.y_average / axis_average.count;
1129 		axis.z = axis_average.z_average / axis_average.count;
1130 
1131 		printk( "%s: axis = %d  %d  %d \n", __func__, axis.x, axis.y, axis.z);
1132 
1133 		memset(&axis_average, 0, sizeof(struct sensor_axis_average));
1134 
1135 		//Report event only while value is changed to save some power
1136 		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))
1137 		{
1138 			gsensor_report_value(client, &axis);
1139 
1140 			/* \BB\A5\B3\E2\B5ػ\BA\B4\E6\CA\FD\BE\DD. */
1141 			mutex_lock(&(sensor->data_mutex) );
1142 			sensor->axis = axis;
1143 			mutex_unlock(&(sensor->data_mutex) );
1144 		}
1145 	}
1146 #else
1147 	gsensor_report_value(client, &axis);
1148 
1149 	/* \BB\A5\B3\E2\B5ػ\BA\B4\E6\CA\FD\BE\DD. */
1150 	mutex_lock(&(sensor->data_mutex) );
1151 	sensor->axis = axis;
1152 	mutex_unlock(&(sensor->data_mutex) );
1153 #endif
1154 	if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0))	//read sensor intterupt status register
1155 	{
1156 
1157 		value = sensor_read_reg(client, sensor->ops->int_status_reg);
1158 		printk("%s:sensor int status :0x%x\n",__func__,value);
1159 	}
1160 	return ret;
1161 }
1162 
1163 static struct sensor_operate gsensor_sc7a30_ops = {
1164 	.name				= "gs_sc7a30",
1165 	.type				= SENSOR_TYPE_ACCEL,			//sensor type and it should be correct
1166 	.id_i2c				= ACCEL_ID_SC7A30,			//i2c id number
1167 	.read_reg			= SC7A30_XOUT_H,			//read data
1168 	.read_len			= 1,					//data length
1169 	.id_reg				= SENSOR_UNKNOW_DATA,			//read device id from this register
1170 	.id_data 			= SENSOR_UNKNOW_DATA,			//device id
1171 	.precision			= SC7A30_PRECISION,			//12 bit
1172 	.ctrl_reg 			= SC7A30_MODE,			        //enable or disable SC7A30_MODE
1173 	.int_status_reg 		= SENSOR_UNKNOW_DATA,			//intterupt status register
1174 	.range				= {-SC7A30_RANGE,SC7A30_RANGE},	//range
1175 	.trig				= IRQF_TRIGGER_HIGH|IRQF_ONESHOT,
1176 	.active				= sensor_active,
1177 	.init				= sensor_init,
1178 	.report 			= sensor_report_value,
1179 };
1180 
1181 /****************operate according to sensor chip:end************/
gsensor_sc7a30_probe(struct i2c_client * client,const struct i2c_device_id * devid)1182 static int gsensor_sc7a30_probe(struct i2c_client *client,
1183 				const struct i2c_device_id *devid)
1184 {
1185 	return sensor_register_device(client, NULL, devid, &gsensor_sc7a30_ops);
1186 }
1187 
gsensor_sc7a30_remove(struct i2c_client * client)1188 static int gsensor_sc7a30_remove(struct i2c_client *client)
1189 {
1190 	return sensor_unregister_device(client, NULL, &gsensor_sc7a30_ops);
1191 }
1192 
1193 static const struct i2c_device_id gsensor_sc7a30_id[] = {
1194 	{"gs_sc7a30", ACCEL_ID_SC7A30},
1195 	{}
1196 };
1197 
1198 static struct i2c_driver gsensor_sc7a30_driver = {
1199 	.probe = gsensor_sc7a30_probe,
1200 	.remove = gsensor_sc7a30_remove,
1201 	.shutdown = sensor_shutdown,
1202 	.id_table = gsensor_sc7a30_id,
1203 	.driver = {
1204 		.name = "gsensor_sc7a30",
1205 	#ifdef CONFIG_PM
1206 		.pm = &sensor_pm_ops,
1207 	#endif
1208 	},
1209 };
1210 
1211 module_i2c_driver(gsensor_sc7a30_driver);
1212 
1213 MODULE_AUTHOR("luowei <lw@rock-chips.com>");
1214 MODULE_DESCRIPTION("sc7a30 3-Axis accelerometer driver");
1215 MODULE_LICENSE("GPL");
1216