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