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