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