1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * stk8baxx.c - Linux kernel modules for sensortek stk8ba50 / stk8ba50-R /
3*4882a593Smuzhiyun * stk8ba53 accelerometer
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (C) 2012~2016 Lex Hsieh / Sensortek
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or modify
8*4882a593Smuzhiyun * it under the terms of the GNU General Public License as published by
9*4882a593Smuzhiyun * the Free Software Foundation; either version 2 of the License, or
10*4882a593Smuzhiyun * (at your option) any later version.
11*4882a593Smuzhiyun *
12*4882a593Smuzhiyun * This program is distributed in the hope that it will be useful,
13*4882a593Smuzhiyun * but WITHOUT ANY WARRANTY; without even the implied warranty of
14*4882a593Smuzhiyun * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15*4882a593Smuzhiyun * GNU General Public License for more details.
16*4882a593Smuzhiyun */
17*4882a593Smuzhiyun #include <linux/i2c.h>
18*4882a593Smuzhiyun #include <linux/kernel.h>
19*4882a593Smuzhiyun #include <linux/slab.h>
20*4882a593Smuzhiyun #include <linux/input.h>
21*4882a593Smuzhiyun #include <linux/delay.h>
22*4882a593Smuzhiyun #include <linux/interrupt.h>
23*4882a593Smuzhiyun #include <linux/workqueue.h>
24*4882a593Smuzhiyun #include <linux/mutex.h>
25*4882a593Smuzhiyun #include <linux/uaccess.h>
26*4882a593Smuzhiyun #include <linux/fs.h>
27*4882a593Smuzhiyun #include <linux/module.h>
28*4882a593Smuzhiyun #include <linux/math64.h>
29*4882a593Smuzhiyun #include <linux/init.h>
30*4882a593Smuzhiyun #include <linux/sensor-dev.h>
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun #define STK_ACC_DRIVER_VERSION "3.7.1_rk_0425_0428"
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun /*------------------User-defined settings-------------------------*/
35*4882a593Smuzhiyun /* #define CONFIG_SENSORS_STK8BA53 */
36*4882a593Smuzhiyun #define CONFIG_SENSORS_STK8BA50
37*4882a593Smuzhiyun /* #define STK_DEBUG_PRINT */
38*4882a593Smuzhiyun /* #define STK_LOWPASS */
39*4882a593Smuzhiyun #define STK_FIR_LEN 4 /* 1~32 */
40*4882a593Smuzhiyun /* #define STK_TUNE */
41*4882a593Smuzhiyun /* #define STK_ZG_FILTER */
42*4882a593Smuzhiyun #define STK_HOLD_ODR
43*4882a593Smuzhiyun #define STK_DEBUG_CALI
44*4882a593Smuzhiyun #define STK8BAXX_DEF_PLACEMENT 7
45*4882a593Smuzhiyun
46*4882a593Smuzhiyun /*------------------Miscellaneous settings-------------------------*/
47*4882a593Smuzhiyun #define STK8BAXX_I2C_NAME "stk8baxx"
48*4882a593Smuzhiyun #define ACC_IDEVICE_NAME "accelerometer"
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun #define STK8BAXX_INIT_ODR 0xD /* 0xB:125Hz, 0xA:62Hz */
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun #define STK8BAXX_RNG_2G 0x3
53*4882a593Smuzhiyun #define STK8BAXX_RNG_4G 0x5
54*4882a593Smuzhiyun #define STK8BAXX_RNG_8G 0x8
55*4882a593Smuzhiyun #define STK8BAXX_RNG_16G 0xC
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun #ifdef CONFIG_SENSORS_STK8BA53
58*4882a593Smuzhiyun /* Parameters under +-4g dynamic range */
59*4882a593Smuzhiyun #define STK_DEF_DYNAMIC_RANGE STK8BAXX_RNG_4G
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun #if (STK_DEF_DYNAMIC_RANGE == STK8BAXX_RNG_4G)
62*4882a593Smuzhiyun #define STK_LSB_1G 512
63*4882a593Smuzhiyun #define STK_DEF_RANGE 4
64*4882a593Smuzhiyun #elif (STK_DEF_DYNAMIC_RANGE == STK8BAXX_RNG_2G)
65*4882a593Smuzhiyun #define STK_LSB_1G 1024
66*4882a593Smuzhiyun #define STK_DEF_RANGE 2
67*4882a593Smuzhiyun #elif (STK_DEF_DYNAMIC_RANGE == STK8BAXX_RNG_8G)
68*4882a593Smuzhiyun #define STK_LSB_1G 256
69*4882a593Smuzhiyun #define STK_DEF_RANGE 8
70*4882a593Smuzhiyun #elif (STK_DEF_DYNAMIC_RANGE == STK8BAXX_RNG_16G)
71*4882a593Smuzhiyun #define STK_LSB_1G 128
72*4882a593Smuzhiyun #define STK_DEF_RANGE 16
73*4882a593Smuzhiyun #endif
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun #define STK_ZG_COUNT (STK_LSB_1G / 128)
76*4882a593Smuzhiyun #define STK_TUNE_XYOFFSET (STK_LSB_1G * 3 / 10)
77*4882a593Smuzhiyun #define STK_TUNE_ZOFFSET (STK_LSB_1G * 3 / 10) /* (STK_LSB_1G * 3 / 20) */
78*4882a593Smuzhiyun #define STK_TUNE_NOISE (STK_LSB_1G / 10)
79*4882a593Smuzhiyun #else
80*4882a593Smuzhiyun /* Parameters under +-2g dynamic range */
81*4882a593Smuzhiyun #define STK_DEF_DYNAMIC_RANGE STK8BAXX_RNG_2G
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun #if (STK_DEF_DYNAMIC_RANGE == STK8BAXX_RNG_2G)
84*4882a593Smuzhiyun #define STK_LSB_1G 256
85*4882a593Smuzhiyun #define STK_DEF_RANGE 2
86*4882a593Smuzhiyun #elif (STK_DEF_DYNAMIC_RANGE == STK8BAXX_RNG_4G)
87*4882a593Smuzhiyun #define STK_LSB_1G 128
88*4882a593Smuzhiyun #define STK_DEF_RANGE 4
89*4882a593Smuzhiyun #elif (STK_DEF_DYNAMIC_RANGE == STK8BAXX_RNG_8G)
90*4882a593Smuzhiyun #define STK_LSB_1G 64
91*4882a593Smuzhiyun #define STK_DEF_RANGE 8
92*4882a593Smuzhiyun #elif (STK_DEF_DYNAMIC_RANGE == STK8BAXX_RNG_16G)
93*4882a593Smuzhiyun #define STK_LSB_1G 32
94*4882a593Smuzhiyun #define STK_DEF_RANGE 16
95*4882a593Smuzhiyun #endif
96*4882a593Smuzhiyun #define STK_ZG_COUNT (STK_LSB_1G / 128 + 1)
97*4882a593Smuzhiyun #define STK_TUNE_XYOFFSET (STK_LSB_1G * 4 / 10)
98*4882a593Smuzhiyun #define STK_TUNE_ZOFFSET (STK_LSB_1G * 4 / 10) /* (STK_LSB_1G * 3 / 20) */
99*4882a593Smuzhiyun #define STK_TUNE_NOISE (STK_LSB_1G / 10)
100*4882a593Smuzhiyun #endif
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun #define STK8BAXX_RANGE_UG (STK_DEF_RANGE * 16384)
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun /* STK_OFFSET_REG_LSB_1G is fixed for all dynamic range */
105*4882a593Smuzhiyun #define STK_OFFSET_REG_LSB_1G 128
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun #define STK_TUNE_NUM 60
108*4882a593Smuzhiyun #define STK_TUNE_DELAY 30
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun #define STK_EVENT_SINCE_EN_LIMIT_DEF (1)
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun #define STK8BA50_ID 0x09
113*4882a593Smuzhiyun #define STK8BA50R_ID 0x86
114*4882a593Smuzhiyun #define STK8BA53_ID 0x87
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun /*------------------Calibration prameters-------------------------*/
117*4882a593Smuzhiyun #define STK_SAMPLE_NO 10
118*4882a593Smuzhiyun #define STK_ACC_CALI_VER0 0x18
119*4882a593Smuzhiyun #define STK_ACC_CALI_VER1 0x03
120*4882a593Smuzhiyun #define STK_ACC_CALI_END '\0'
121*4882a593Smuzhiyun #define STK_ACC_CALI_FILE "/data/misc/stkacccali.conf"
122*4882a593Smuzhiyun #define STK_ACC_CALI_FILE_SDCARD "/sdcard/.stkacccali.conf"
123*4882a593Smuzhiyun #define STK_ACC_CALI_FILE_SIZE 25
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun #define STK_K_SUCCESS_TUNE 0x04
126*4882a593Smuzhiyun #define STK_K_SUCCESS_FT2 0x03
127*4882a593Smuzhiyun #define STK_K_SUCCESS_FT1 0x02
128*4882a593Smuzhiyun #define STK_K_SUCCESS_FILE 0x01
129*4882a593Smuzhiyun #define STK_K_NO_CALI 0xFF
130*4882a593Smuzhiyun #define STK_K_RUNNING 0xFE
131*4882a593Smuzhiyun #define STK_K_FAIL_LRG_DIFF 0xFD
132*4882a593Smuzhiyun #define STK_K_FAIL_OPEN_FILE 0xFC
133*4882a593Smuzhiyun #define STK_K_FAIL_W_FILE 0xFB
134*4882a593Smuzhiyun #define STK_K_FAIL_R_BACK 0xFA
135*4882a593Smuzhiyun #define STK_K_FAIL_R_BACK_COMP 0xF9
136*4882a593Smuzhiyun #define STK_K_FAIL_I2C 0xF8
137*4882a593Smuzhiyun #define STK_K_FAIL_K_PARA 0xF7
138*4882a593Smuzhiyun #define STK_K_FAIL_OUT_RG 0xF6
139*4882a593Smuzhiyun #define STK_K_FAIL_ENG_I2C 0xF5
140*4882a593Smuzhiyun #define STK_K_FAIL_FT1_USD 0xF4
141*4882a593Smuzhiyun #define STK_K_FAIL_FT2_USD 0xF3
142*4882a593Smuzhiyun #define STK_K_FAIL_WRITE_NOFST 0xF2
143*4882a593Smuzhiyun #define STK_K_FAIL_OTP_5T 0xF1
144*4882a593Smuzhiyun #define STK_K_FAIL_PLACEMENT 0xF0
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun /*------------------stk8baxx registers-------------------------*/
147*4882a593Smuzhiyun #define STK8BAXX_XOUT1 0x02
148*4882a593Smuzhiyun #define STK8BAXX_XOUT2 0x03
149*4882a593Smuzhiyun #define STK8BAXX_YOUT1 0x04
150*4882a593Smuzhiyun #define STK8BAXX_YOUT2 0x05
151*4882a593Smuzhiyun #define STK8BAXX_ZOUT1 0x06
152*4882a593Smuzhiyun #define STK8BAXX_ZOUT2 0x07
153*4882a593Smuzhiyun #define STK8BAXX_INTSTS1 0x09
154*4882a593Smuzhiyun #define STK8BAXX_INTSTS2 0x0A
155*4882a593Smuzhiyun #define STK8BAXX_EVENTINFO1 0x0B
156*4882a593Smuzhiyun #define STK8BAXX_EVENTINFO2 0x0C
157*4882a593Smuzhiyun #define STK8BAXX_RANGESEL 0x0F
158*4882a593Smuzhiyun #define STK8BAXX_BWSEL 0x10
159*4882a593Smuzhiyun #define STK8BAXX_POWMODE 0x11
160*4882a593Smuzhiyun #define STK8BAXX_DATASETUP 0x13
161*4882a593Smuzhiyun #define STK8BAXX_SWRST 0x14
162*4882a593Smuzhiyun #define STK8BAXX_INTEN1 0x16
163*4882a593Smuzhiyun #define STK8BAXX_INTEN2 0x17
164*4882a593Smuzhiyun #define STK8BAXX_INTMAP1 0x19
165*4882a593Smuzhiyun #define STK8BAXX_INTMAP2 0x1A
166*4882a593Smuzhiyun #define STK8BAXX_INTMAP3 0x1B
167*4882a593Smuzhiyun #define STK8BAXX_DATASRC 0x1E
168*4882a593Smuzhiyun #define STK8BAXX_INTCFG1 0x20
169*4882a593Smuzhiyun #define STK8BAXX_INTCFG2 0x21
170*4882a593Smuzhiyun #define STK8BAXX_LGDLY 0x22
171*4882a593Smuzhiyun #define STK8BAXX_LGTHD 0x23
172*4882a593Smuzhiyun #define STK8BAXX_HLGCFG 0x24
173*4882a593Smuzhiyun #define STK8BAXX_HGDLY 0x25
174*4882a593Smuzhiyun #define STK8BAXX_HGTHD 0x26
175*4882a593Smuzhiyun #define STK8BAXX_SLOPEDLY 0x27
176*4882a593Smuzhiyun #define STK8BAXX_SLOPETHD 0x28
177*4882a593Smuzhiyun #define STK8BAXX_TAPTIME 0x2A
178*4882a593Smuzhiyun #define STK8BAXX_TAPCFG 0x2B
179*4882a593Smuzhiyun #define STK8BAXX_ORIENTCFG 0x2C
180*4882a593Smuzhiyun #define STK8BAXX_ORIENTTHETA 0x2D
181*4882a593Smuzhiyun #define STK8BAXX_FLATTHETA 0x2E
182*4882a593Smuzhiyun #define STK8BAXX_FLATHOLD 0x2F
183*4882a593Smuzhiyun #define STK8BAXX_SLFTST 0x32
184*4882a593Smuzhiyun #define STK8BAXX_INTFCFG 0x34
185*4882a593Smuzhiyun #define STK8BAXX_OFSTCOMP1 0x36
186*4882a593Smuzhiyun #define STK8BAXX_OFSTCOMP2 0x37
187*4882a593Smuzhiyun #define STK8BAXX_OFSTFILTX 0x38
188*4882a593Smuzhiyun #define STK8BAXX_OFSTFILTY 0x39
189*4882a593Smuzhiyun #define STK8BAXX_OFSTFILTZ 0x3A
190*4882a593Smuzhiyun #define STK8BAXX_OFSTUNFILTX 0x3B
191*4882a593Smuzhiyun #define STK8BAXX_OFSTUNFILTY 0x3C
192*4882a593Smuzhiyun #define STK8BAXX_OFSTUNFILTZ 0x3D
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun /* ZOUT1 register */
195*4882a593Smuzhiyun #define STK8BAXX_O_NEW 0x01
196*4882a593Smuzhiyun
197*4882a593Smuzhiyun /* SWRST register */
198*4882a593Smuzhiyun #define STK8BAXX_SWRST_VAL 0xB6
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun /* STK8BAXX_POWMODE register */
201*4882a593Smuzhiyun #define STK8BAXX_MD_SUSPEND 0x80
202*4882a593Smuzhiyun #define STK8BAXX_MD_NORMAL 0x00
203*4882a593Smuzhiyun #define STK8BAXX_MD_SLP_MASK 0x1E
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun /* RANGESEL register */
206*4882a593Smuzhiyun #define STK8BAXX_RANGE_MASK 0x0F
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun /* OFSTCOMP1 register */
209*4882a593Smuzhiyun #define STK8BAXX_OF_CAL_DRY_MASK 0x10
210*4882a593Smuzhiyun #define CAL_AXIS_X_EN 0x20
211*4882a593Smuzhiyun #define CAL_AXIS_Y_EN 0x40
212*4882a593Smuzhiyun #define CAL_AXIS_Z_EN 0x60
213*4882a593Smuzhiyun #define CAL_OFST_RST 0x80
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun /* OFSTCOMP2 register */
216*4882a593Smuzhiyun #define CAL_TG_X0_Y0_ZPOS1 0x20
217*4882a593Smuzhiyun #define CAL_TG_X0_Y0_ZNEG1 0x40
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun /*no_create_attr:the initial is 1-->no create attr. if created, change no_create_att to 0.*/
220*4882a593Smuzhiyun static int no_create_att = 1;
221*4882a593Smuzhiyun static int enable_status = -1;
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun /*------------------Data structure-------------------------*/
224*4882a593Smuzhiyun struct stk8baxx_acc {
225*4882a593Smuzhiyun union {
226*4882a593Smuzhiyun struct {
227*4882a593Smuzhiyun s16 x;
228*4882a593Smuzhiyun s16 y;
229*4882a593Smuzhiyun s16 z;
230*4882a593Smuzhiyun };
231*4882a593Smuzhiyun s16 acc[3];
232*4882a593Smuzhiyun };
233*4882a593Smuzhiyun };
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun #if defined(STK_LOWPASS)
236*4882a593Smuzhiyun #define MAX_FIR_LEN 32
237*4882a593Smuzhiyun struct data_filter {
238*4882a593Smuzhiyun s16 raw[MAX_FIR_LEN][3];
239*4882a593Smuzhiyun int sum[3];
240*4882a593Smuzhiyun int num;
241*4882a593Smuzhiyun int idx;
242*4882a593Smuzhiyun };
243*4882a593Smuzhiyun #endif
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun struct stk8baxx_data {
246*4882a593Smuzhiyun struct i2c_client *client;
247*4882a593Smuzhiyun struct input_dev *input_dev;
248*4882a593Smuzhiyun int irq;
249*4882a593Smuzhiyun struct stk8baxx_acc acc_xyz;
250*4882a593Smuzhiyun atomic_t enabled;
251*4882a593Smuzhiyun bool first_enable;
252*4882a593Smuzhiyun struct work_struct stk_work;
253*4882a593Smuzhiyun struct hrtimer acc_timer;
254*4882a593Smuzhiyun struct workqueue_struct *stk_mems_work_queue;
255*4882a593Smuzhiyun unsigned char stk8baxx_placement;
256*4882a593Smuzhiyun atomic_t cali_status;
257*4882a593Smuzhiyun atomic_t recv_reg;
258*4882a593Smuzhiyun bool re_enable;
259*4882a593Smuzhiyun #if defined(STK_LOWPASS)
260*4882a593Smuzhiyun atomic_t firlength;
261*4882a593Smuzhiyun atomic_t fir_en;
262*4882a593Smuzhiyun struct data_filter fir;
263*4882a593Smuzhiyun #endif
264*4882a593Smuzhiyun int event_since_en;
265*4882a593Smuzhiyun int event_since_en_limit;
266*4882a593Smuzhiyun u8 stk_tune_offset_record[3];
267*4882a593Smuzhiyun #ifdef STK_TUNE
268*4882a593Smuzhiyun int stk_tune_offset[3];
269*4882a593Smuzhiyun int stk_tune_sum[3];
270*4882a593Smuzhiyun int stk_tune_max[3];
271*4882a593Smuzhiyun int stk_tune_min[3];
272*4882a593Smuzhiyun int stk_tune_index;
273*4882a593Smuzhiyun int stk_tune_done;
274*4882a593Smuzhiyun s64 stk_tune_square_sum[3];
275*4882a593Smuzhiyun u32 variance[3];
276*4882a593Smuzhiyun #endif
277*4882a593Smuzhiyun };
278*4882a593Smuzhiyun
279*4882a593Smuzhiyun /*------------------Function prototype-------------------------*/
280*4882a593Smuzhiyun static int stk8baxx_set_enable(struct stk8baxx_data *stk, char en);
281*4882a593Smuzhiyun static int stk8baxx_read_sensor_data(struct stk8baxx_data *stk);
282*4882a593Smuzhiyun /*------------------Global variables-------------------------*/
283*4882a593Smuzhiyun static struct stk8baxx_data *stk8baxx_data_ptr;
284*4882a593Smuzhiyun static struct sensor_private_data *sensor_ptr;
285*4882a593Smuzhiyun /*------------------Main functions-------------------------*/
286*4882a593Smuzhiyun
stk8baxx_smbus_write_byte_data(u8 command,u8 value)287*4882a593Smuzhiyun static s32 stk8baxx_smbus_write_byte_data(u8 command, u8 value)
288*4882a593Smuzhiyun {
289*4882a593Smuzhiyun return sensor_write_reg(stk8baxx_data_ptr->client, command, value);
290*4882a593Smuzhiyun }
291*4882a593Smuzhiyun
stk8baxx_smbus_read_byte_data(u8 command)292*4882a593Smuzhiyun static int stk8baxx_smbus_read_byte_data(u8 command)
293*4882a593Smuzhiyun {
294*4882a593Smuzhiyun return sensor_read_reg(stk8baxx_data_ptr->client, command);
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun
stk8baxx_chk_for_addr(struct stk8baxx_data * stk,s32 org_address,unsigned short reset_address)297*4882a593Smuzhiyun static int stk8baxx_chk_for_addr(struct stk8baxx_data *stk, s32 org_address, unsigned short reset_address)
298*4882a593Smuzhiyun {
299*4882a593Smuzhiyun int result;
300*4882a593Smuzhiyun s32 expected_reg0 = 0x86;
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun if ((org_address & 0xFE) == 0x18)
303*4882a593Smuzhiyun expected_reg0 = 0x86;
304*4882a593Smuzhiyun else
305*4882a593Smuzhiyun expected_reg0 = 0x87;
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun stk->client->addr = reset_address;
308*4882a593Smuzhiyun result = stk8baxx_smbus_write_byte_data(STK8BAXX_SWRST, STK8BAXX_SWRST_VAL);
309*4882a593Smuzhiyun printk(KERN_INFO "%s:issue sw reset to 0x%x, result=%d\n", __func__, reset_address, result);
310*4882a593Smuzhiyun usleep_range(2000, 3000);
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun stk->client->addr = org_address;
313*4882a593Smuzhiyun printk(KERN_INFO "%s Revise I2C Address = 0x%x\n", __func__, org_address);
314*4882a593Smuzhiyun result = stk8baxx_smbus_write_byte_data(STK8BAXX_POWMODE, STK8BAXX_MD_NORMAL);
315*4882a593Smuzhiyun result = stk8baxx_smbus_read_byte_data(0x0);
316*4882a593Smuzhiyun if (result < 0) {
317*4882a593Smuzhiyun printk(KERN_INFO "%s: read 0x0, result=%d\n", __func__, result);
318*4882a593Smuzhiyun return result;
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun if (result == expected_reg0) {
321*4882a593Smuzhiyun printk(KERN_INFO "%s:passed, expected_reg0=0x%x\n", __func__, expected_reg0);
322*4882a593Smuzhiyun result = stk8baxx_smbus_write_byte_data(STK8BAXX_SWRST, STK8BAXX_SWRST_VAL);
323*4882a593Smuzhiyun if (result < 0) {
324*4882a593Smuzhiyun printk(KERN_ERR "%s:failed to issue software reset, error=%d\n", __func__, result);
325*4882a593Smuzhiyun return result;
326*4882a593Smuzhiyun }
327*4882a593Smuzhiyun usleep_range(2000, 3000);
328*4882a593Smuzhiyun return 1;
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun return 0;
331*4882a593Smuzhiyun }
332*4882a593Smuzhiyun
stk8baxx_sw_reset(struct stk8baxx_data * stk)333*4882a593Smuzhiyun static int stk8baxx_sw_reset(struct stk8baxx_data *stk)
334*4882a593Smuzhiyun {
335*4882a593Smuzhiyun unsigned short org_addr = 0;
336*4882a593Smuzhiyun int result;
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun org_addr = stk->client->addr;
339*4882a593Smuzhiyun printk(KERN_INFO "%s:org_addr=0x%x\n", __func__, org_addr);
340*4882a593Smuzhiyun
341*4882a593Smuzhiyun if ((org_addr & 0xFE) == 0x18) {
342*4882a593Smuzhiyun result = stk8baxx_chk_for_addr(stk, org_addr, 0x18);
343*4882a593Smuzhiyun if (result == 1)
344*4882a593Smuzhiyun return 0;
345*4882a593Smuzhiyun result = stk8baxx_chk_for_addr(stk, org_addr, 0x19);
346*4882a593Smuzhiyun if (result == 1)
347*4882a593Smuzhiyun return 0;
348*4882a593Smuzhiyun result = stk8baxx_chk_for_addr(stk, org_addr, 0x08);
349*4882a593Smuzhiyun if (result == 1)
350*4882a593Smuzhiyun return 0;
351*4882a593Smuzhiyun result = stk8baxx_chk_for_addr(stk, org_addr, 0x28);
352*4882a593Smuzhiyun if (result == 1)
353*4882a593Smuzhiyun return 0;
354*4882a593Smuzhiyun } else if (org_addr == 0x28) {
355*4882a593Smuzhiyun result = stk8baxx_chk_for_addr(stk, org_addr, 0x28);
356*4882a593Smuzhiyun if (result == 1)
357*4882a593Smuzhiyun return 0;
358*4882a593Smuzhiyun result = stk8baxx_chk_for_addr(stk, org_addr, 0x18);
359*4882a593Smuzhiyun if (result == 1)
360*4882a593Smuzhiyun return 0;
361*4882a593Smuzhiyun result = stk8baxx_chk_for_addr(stk, org_addr, 0x08);
362*4882a593Smuzhiyun if (result == 1)
363*4882a593Smuzhiyun return 0;
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun result = stk8baxx_chk_for_addr(stk, org_addr, 0x0B);
366*4882a593Smuzhiyun return 0;
367*4882a593Smuzhiyun }
368*4882a593Smuzhiyun
stk8baxx_reg_init(struct stk8baxx_data * stk,struct i2c_client * client,struct sensor_private_data * sensor)369*4882a593Smuzhiyun static int stk8baxx_reg_init(struct stk8baxx_data *stk, struct i2c_client *client, struct sensor_private_data *sensor)
370*4882a593Smuzhiyun {
371*4882a593Smuzhiyun int result;
372*4882a593Smuzhiyun int aa;
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun #ifdef CONFIG_SENSORS_STK8BA53
375*4882a593Smuzhiyun printk(KERN_INFO "%s: Initialize stk8ba53\n", __func__);
376*4882a593Smuzhiyun #else
377*4882a593Smuzhiyun printk(KERN_INFO "%s: Initialize stk8ba50/stk8ba50-r\n", __func__);
378*4882a593Smuzhiyun #endif
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun /* sw reset */
381*4882a593Smuzhiyun result = stk8baxx_sw_reset(stk);
382*4882a593Smuzhiyun if (result < 0) {
383*4882a593Smuzhiyun printk(KERN_ERR "%s:failed to stk8baxx_sw_reset, error=%d\n", __func__, result);
384*4882a593Smuzhiyun return result;
385*4882a593Smuzhiyun }
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun result = stk8baxx_smbus_write_byte_data(STK8BAXX_POWMODE, STK8BAXX_MD_NORMAL);
388*4882a593Smuzhiyun if (result < 0) {
389*4882a593Smuzhiyun printk(KERN_ERR "%s:failed to write reg 0x%x, error=%d\n", __func__, STK8BAXX_POWMODE, result);
390*4882a593Smuzhiyun return result;
391*4882a593Smuzhiyun }
392*4882a593Smuzhiyun
393*4882a593Smuzhiyun result = stk8baxx_smbus_read_byte_data(STK8BAXX_LGDLY);
394*4882a593Smuzhiyun if (result < 0) {
395*4882a593Smuzhiyun printk(KERN_ERR "%s: failed to read acc data, error=%d\n", __func__, result);
396*4882a593Smuzhiyun return result;
397*4882a593Smuzhiyun }
398*4882a593Smuzhiyun
399*4882a593Smuzhiyun if (result == STK8BA50_ID) {
400*4882a593Smuzhiyun printk(KERN_INFO "%s: chip is stk8ba50\n", __func__);
401*4882a593Smuzhiyun sensor->devid = STK8BA50_ID;
402*4882a593Smuzhiyun } else {
403*4882a593Smuzhiyun result = stk8baxx_smbus_read_byte_data(0x0);
404*4882a593Smuzhiyun if (result < 0) {
405*4882a593Smuzhiyun printk(KERN_ERR "%s: failed to read acc data, error=%d\n", __func__, result);
406*4882a593Smuzhiyun return result;
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun printk(KERN_INFO "%s: 0x0=0x%x\n", __func__, result);
409*4882a593Smuzhiyun if (result == STK8BA50R_ID) {
410*4882a593Smuzhiyun printk(KERN_INFO "%s: chip is stk8ba50-R\n", __func__);
411*4882a593Smuzhiyun sensor->devid = STK8BA50R_ID;
412*4882a593Smuzhiyun } else {
413*4882a593Smuzhiyun printk(KERN_INFO "%s: chip is stk8ba53\n", __func__);
414*4882a593Smuzhiyun sensor->devid = STK8BA53_ID;
415*4882a593Smuzhiyun }
416*4882a593Smuzhiyun }
417*4882a593Smuzhiyun #ifdef CONFIG_SENSORS_STK8BA53
418*4882a593Smuzhiyun if (sensor->devid != STK8BA53_ID) {
419*4882a593Smuzhiyun printk(KERN_ERR "%s: stk8ba53 is not attached, devid=0x%x\n", __func__, sensor->devid);
420*4882a593Smuzhiyun return -ENODEV;
421*4882a593Smuzhiyun }
422*4882a593Smuzhiyun #else
423*4882a593Smuzhiyun if (sensor->devid == STK8BA53_ID) {
424*4882a593Smuzhiyun printk(KERN_ERR "%s: stk8ba50/stk8ba50-R is not attached, devid=0x%x\n", __func__, sensor->devid);
425*4882a593Smuzhiyun return -ENODEV;
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun #endif
428*4882a593Smuzhiyun if (sensor->pdata->irq_enable) {
429*4882a593Smuzhiyun /* map new data int to int1 */
430*4882a593Smuzhiyun result = stk8baxx_smbus_write_byte_data(STK8BAXX_INTMAP2, 0x01);
431*4882a593Smuzhiyun if (result < 0) {
432*4882a593Smuzhiyun printk(KERN_ERR "%s:failed to write reg 0x%x, error=%d\n", __func__, STK8BAXX_INTMAP2, result);
433*4882a593Smuzhiyun return result;
434*4882a593Smuzhiyun }
435*4882a593Smuzhiyun /* enable new data in */
436*4882a593Smuzhiyun result = stk8baxx_smbus_write_byte_data(STK8BAXX_INTEN2, 0x10);
437*4882a593Smuzhiyun if (result < 0) {
438*4882a593Smuzhiyun printk(KERN_ERR "%s:failed to write reg 0x%x, error=%d\n", __func__, STK8BAXX_INTEN2, result);
439*4882a593Smuzhiyun return result;
440*4882a593Smuzhiyun }
441*4882a593Smuzhiyun /* non-latch int */
442*4882a593Smuzhiyun result = stk8baxx_smbus_write_byte_data(STK8BAXX_INTCFG2, 0x00);
443*4882a593Smuzhiyun if (result < 0) {
444*4882a593Smuzhiyun printk(KERN_ERR "%s:failed to write reg 0x%x, error=%d\n", __func__, STK8BAXX_INTCFG2, result);
445*4882a593Smuzhiyun return result;
446*4882a593Smuzhiyun }
447*4882a593Smuzhiyun /* filtered data source for new data int */
448*4882a593Smuzhiyun result = stk8baxx_smbus_write_byte_data(STK8BAXX_DATASRC, 0x00);
449*4882a593Smuzhiyun if (result < 0) {
450*4882a593Smuzhiyun printk(KERN_ERR "%s:failed to write reg 0x%x, error=%d\n", __func__, STK8BAXX_DATASRC, result);
451*4882a593Smuzhiyun return result;
452*4882a593Smuzhiyun }
453*4882a593Smuzhiyun /* int1, push-pull, active high */
454*4882a593Smuzhiyun result = stk8baxx_smbus_write_byte_data(STK8BAXX_INTCFG1, 0x01);
455*4882a593Smuzhiyun if (result < 0) {
456*4882a593Smuzhiyun printk(KERN_ERR "%s:failed to write reg 0x%x, error=%d\n", __func__, STK8BAXX_INTCFG1, result);
457*4882a593Smuzhiyun return result;
458*4882a593Smuzhiyun }
459*4882a593Smuzhiyun }
460*4882a593Smuzhiyun #ifdef CONFIG_SENSORS_STK8BA53
461*4882a593Smuzhiyun /* +- 4g */
462*4882a593Smuzhiyun result = stk8baxx_smbus_write_byte_data(STK8BAXX_RANGESEL, STK_DEF_DYNAMIC_RANGE);
463*4882a593Smuzhiyun if (result < 0) {
464*4882a593Smuzhiyun printk(KERN_ERR "%s:failed to write reg 0x%x, error=%d\n", __func__, STK8BAXX_RANGESEL, result);
465*4882a593Smuzhiyun return result;
466*4882a593Smuzhiyun }
467*4882a593Smuzhiyun #else
468*4882a593Smuzhiyun /* +- 2g */
469*4882a593Smuzhiyun result = stk8baxx_smbus_write_byte_data(STK8BAXX_RANGESEL, STK_DEF_DYNAMIC_RANGE);
470*4882a593Smuzhiyun if (result < 0) {
471*4882a593Smuzhiyun printk(KERN_ERR "%s:failed to write reg 0x%x, error=%d\n", __func__, STK8BAXX_RANGESEL, result);
472*4882a593Smuzhiyun return result;
473*4882a593Smuzhiyun }
474*4882a593Smuzhiyun #endif
475*4882a593Smuzhiyun /* ODR = 62 Hz */
476*4882a593Smuzhiyun result = stk8baxx_smbus_write_byte_data(STK8BAXX_BWSEL, STK8BAXX_INIT_ODR);
477*4882a593Smuzhiyun if (result < 0) {
478*4882a593Smuzhiyun printk(KERN_ERR "%s:failed to write reg 0x%x, error=%d\n", __func__, STK8BAXX_BWSEL, result);
479*4882a593Smuzhiyun return result;
480*4882a593Smuzhiyun }
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun /* i2c watchdog enable, 1 ms timer perios */
483*4882a593Smuzhiyun result = stk8baxx_smbus_write_byte_data(STK8BAXX_INTFCFG, 0x04);
484*4882a593Smuzhiyun if (result < 0) {
485*4882a593Smuzhiyun printk(KERN_ERR "%s:failed to write reg 0x%x, error=%d\n", __func__, STK8BAXX_INTFCFG, result);
486*4882a593Smuzhiyun return result;
487*4882a593Smuzhiyun }
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun result = stk8baxx_smbus_write_byte_data(STK8BAXX_POWMODE, STK8BAXX_MD_SUSPEND);
490*4882a593Smuzhiyun if (result < 0) {
491*4882a593Smuzhiyun printk(KERN_ERR "%s:failed to write reg 0x%x, error=%d\n", __func__, STK8BAXX_POWMODE, result);
492*4882a593Smuzhiyun return result;
493*4882a593Smuzhiyun }
494*4882a593Smuzhiyun atomic_set(&stk->enabled, 0);
495*4882a593Smuzhiyun stk->first_enable = true;
496*4882a593Smuzhiyun atomic_set(&stk->cali_status, STK_K_NO_CALI);
497*4882a593Smuzhiyun atomic_set(&stk->recv_reg, 0);
498*4882a593Smuzhiyun #ifdef STK_LOWPASS
499*4882a593Smuzhiyun memset(&stk->fir, 0x00, sizeof(stk->fir));
500*4882a593Smuzhiyun atomic_set(&stk->firlength, STK_FIR_LEN);
501*4882a593Smuzhiyun atomic_set(&stk->fir_en, 1);
502*4882a593Smuzhiyun #endif
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun for (aa = 0; aa < 3; aa++)
505*4882a593Smuzhiyun stk->stk_tune_offset_record[aa] = 0;
506*4882a593Smuzhiyun #ifdef STK_TUNE
507*4882a593Smuzhiyun for (aa = 0; aa < 3; aa++) {
508*4882a593Smuzhiyun stk->stk_tune_offset[aa] = 0;
509*4882a593Smuzhiyun stk->stk_tune_sum[aa] = 0;
510*4882a593Smuzhiyun stk->stk_tune_max[aa] = 0;
511*4882a593Smuzhiyun stk->stk_tune_min[aa] = 0;
512*4882a593Smuzhiyun stk->stk_tune_square_sum[aa] = 0LL;
513*4882a593Smuzhiyun stk->variance[aa] = 0;
514*4882a593Smuzhiyun }
515*4882a593Smuzhiyun stk->stk_tune_done = 0;
516*4882a593Smuzhiyun stk->stk_tune_index = 0;
517*4882a593Smuzhiyun #endif
518*4882a593Smuzhiyun stk->event_since_en_limit = STK_EVENT_SINCE_EN_LIMIT_DEF;
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun return 0;
521*4882a593Smuzhiyun }
522*4882a593Smuzhiyun
523*4882a593Smuzhiyun #ifdef STK_LOWPASS
stk8baxx_low_pass(struct stk8baxx_data * stk,struct stk8baxx_acc * acc_lp)524*4882a593Smuzhiyun static void stk8baxx_low_pass(struct stk8baxx_data *stk, struct stk8baxx_acc *acc_lp)
525*4882a593Smuzhiyun {
526*4882a593Smuzhiyun int idx, firlength = atomic_read(&stk->firlength);
527*4882a593Smuzhiyun #ifdef STK_ZG_FILTER
528*4882a593Smuzhiyun s16 zero_fir = 0;
529*4882a593Smuzhiyun #endif
530*4882a593Smuzhiyun
531*4882a593Smuzhiyun if (atomic_read(&stk->fir_en)) {
532*4882a593Smuzhiyun if (stk->fir.num < firlength) {
533*4882a593Smuzhiyun stk->fir.raw[stk->fir.num][0] = acc_lp->x;
534*4882a593Smuzhiyun stk->fir.raw[stk->fir.num][1] = acc_lp->y;
535*4882a593Smuzhiyun stk->fir.raw[stk->fir.num][2] = acc_lp->z;
536*4882a593Smuzhiyun stk->fir.sum[0] += acc_lp->x;
537*4882a593Smuzhiyun stk->fir.sum[1] += acc_lp->y;
538*4882a593Smuzhiyun stk->fir.sum[2] += acc_lp->z;
539*4882a593Smuzhiyun stk->fir.num++;
540*4882a593Smuzhiyun stk->fir.idx++;
541*4882a593Smuzhiyun } else {
542*4882a593Smuzhiyun idx = stk->fir.idx % firlength;
543*4882a593Smuzhiyun stk->fir.sum[0] -= stk->fir.raw[idx][0];
544*4882a593Smuzhiyun stk->fir.sum[1] -= stk->fir.raw[idx][1];
545*4882a593Smuzhiyun stk->fir.sum[2] -= stk->fir.raw[idx][2];
546*4882a593Smuzhiyun stk->fir.raw[idx][0] = acc_lp->x;
547*4882a593Smuzhiyun stk->fir.raw[idx][1] = acc_lp->y;
548*4882a593Smuzhiyun stk->fir.raw[idx][2] = acc_lp->z;
549*4882a593Smuzhiyun stk->fir.sum[0] += acc_lp->x;
550*4882a593Smuzhiyun stk->fir.sum[1] += acc_lp->y;
551*4882a593Smuzhiyun stk->fir.sum[2] += acc_lp->z;
552*4882a593Smuzhiyun stk->fir.idx++;
553*4882a593Smuzhiyun #ifdef STK_ZG_FILTER
554*4882a593Smuzhiyun if (abs(stk->fir.sum[0] / firlength) <= STK_ZG_COUNT)
555*4882a593Smuzhiyun acc_lp->x = (stk->fir.sum[0] * zero_fir) / firlength;
556*4882a593Smuzhiyun else
557*4882a593Smuzhiyun acc_lp->x = stk->fir.sum[0] / firlength;
558*4882a593Smuzhiyun if (abs(stk->fir.sum[1] / firlength) <= STK_ZG_COUNT)
559*4882a593Smuzhiyun acc_lp->y = (stk->fir.sum[1] * zero_fir) / firlength;
560*4882a593Smuzhiyun else
561*4882a593Smuzhiyun acc_lp->y = stk->fir.sum[1] / firlength;
562*4882a593Smuzhiyun if (abs(stk->fir.sum[2] / firlength) <= STK_ZG_COUNT)
563*4882a593Smuzhiyun acc_lp->z = (stk->fir.sum[2] * zero_fir) / firlength;
564*4882a593Smuzhiyun else
565*4882a593Smuzhiyun acc_lp->z = stk->fir.sum[2] / firlength;
566*4882a593Smuzhiyun #else
567*4882a593Smuzhiyun acc_lp->x = stk->fir.sum[0] / firlength;
568*4882a593Smuzhiyun acc_lp->y = stk->fir.sum[1] / firlength;
569*4882a593Smuzhiyun acc_lp->z = stk->fir.sum[2] / firlength;
570*4882a593Smuzhiyun #endif
571*4882a593Smuzhiyun }
572*4882a593Smuzhiyun }
573*4882a593Smuzhiyun }
574*4882a593Smuzhiyun #endif
575*4882a593Smuzhiyun
576*4882a593Smuzhiyun #ifdef STK_TUNE
stk8baxx_reset_para(struct stk8baxx_data * stk)577*4882a593Smuzhiyun static void stk8baxx_reset_para(struct stk8baxx_data *stk)
578*4882a593Smuzhiyun {
579*4882a593Smuzhiyun int ii;
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun for (ii = 0; ii < 3; ii++) {
582*4882a593Smuzhiyun stk->stk_tune_sum[ii] = 0;
583*4882a593Smuzhiyun stk->stk_tune_square_sum[ii] = 0LL;
584*4882a593Smuzhiyun stk->stk_tune_min[ii] = 4096;
585*4882a593Smuzhiyun stk->stk_tune_max[ii] = -4096;
586*4882a593Smuzhiyun stk->variance[ii] = 0;
587*4882a593Smuzhiyun }
588*4882a593Smuzhiyun }
589*4882a593Smuzhiyun
stk8baxx_tune(struct stk8baxx_data * stk,struct stk8baxx_acc * acc_xyz)590*4882a593Smuzhiyun static void stk8baxx_tune(struct stk8baxx_data *stk, struct stk8baxx_acc *acc_xyz)
591*4882a593Smuzhiyun {
592*4882a593Smuzhiyun int ii;
593*4882a593Smuzhiyun u8 offset[3];
594*4882a593Smuzhiyun s16 acc[3];
595*4882a593Smuzhiyun s64 s64_temp;
596*4882a593Smuzhiyun const s64 var_enlarge_scale = 64;
597*4882a593Smuzhiyun
598*4882a593Smuzhiyun if (stk->stk_tune_done != 0)
599*4882a593Smuzhiyun return;
600*4882a593Smuzhiyun
601*4882a593Smuzhiyun acc[0] = acc_xyz->x;
602*4882a593Smuzhiyun acc[1] = acc_xyz->y;
603*4882a593Smuzhiyun acc[2] = acc_xyz->z;
604*4882a593Smuzhiyun
605*4882a593Smuzhiyun if (stk->event_since_en >= STK_TUNE_DELAY) {
606*4882a593Smuzhiyun if ((abs(acc[0]) <= STK_TUNE_XYOFFSET) && (abs(acc[1]) <= STK_TUNE_XYOFFSET) &&
607*4882a593Smuzhiyun (abs(abs(acc[2]) - STK_LSB_1G) <= STK_TUNE_ZOFFSET)) {
608*4882a593Smuzhiyun stk->stk_tune_index++;
609*4882a593Smuzhiyun /* printk("\n-qhy20161108--%s----acc[0]=0x%x,,acc[1]=0x%x,,acc[2]=0x%x\n",__func__,acc[0],acc[1],acc[2]); */
610*4882a593Smuzhiyun } else {
611*4882a593Smuzhiyun stk->stk_tune_index = 0;
612*4882a593Smuzhiyun }
613*4882a593Smuzhiyun
614*4882a593Smuzhiyun if (stk->stk_tune_index == 0) {
615*4882a593Smuzhiyun stk8baxx_reset_para(stk);
616*4882a593Smuzhiyun /* printk("\n--qhy20161108--%s-- %d--\n",__func__,__LINE__); */
617*4882a593Smuzhiyun } else {
618*4882a593Smuzhiyun for (ii = 0; ii < 3; ii++) {
619*4882a593Smuzhiyun stk->stk_tune_sum[ii] += acc[ii];
620*4882a593Smuzhiyun stk->stk_tune_square_sum[ii] += acc[ii] * acc[ii];
621*4882a593Smuzhiyun if (acc[ii] > stk->stk_tune_max[ii])
622*4882a593Smuzhiyun stk->stk_tune_max[ii] = acc[ii];
623*4882a593Smuzhiyun if (acc[ii] < stk->stk_tune_min[ii])
624*4882a593Smuzhiyun stk->stk_tune_min[ii] = acc[ii];
625*4882a593Smuzhiyun }
626*4882a593Smuzhiyun }
627*4882a593Smuzhiyun
628*4882a593Smuzhiyun if (stk->stk_tune_index == STK_TUNE_NUM) {
629*4882a593Smuzhiyun for (ii = 0; ii < 3; ii++) {
630*4882a593Smuzhiyun if ((stk->stk_tune_max[ii] - stk->stk_tune_min[ii]) > STK_TUNE_NOISE) {
631*4882a593Smuzhiyun stk->stk_tune_index = 0;
632*4882a593Smuzhiyun stk8baxx_reset_para(stk);
633*4882a593Smuzhiyun return;
634*4882a593Smuzhiyun }
635*4882a593Smuzhiyun }
636*4882a593Smuzhiyun
637*4882a593Smuzhiyun stk->stk_tune_offset[0] = stk->stk_tune_sum[0] / STK_TUNE_NUM;
638*4882a593Smuzhiyun stk->stk_tune_offset[1] = stk->stk_tune_sum[1] / STK_TUNE_NUM;
639*4882a593Smuzhiyun if (acc[2] > 0)
640*4882a593Smuzhiyun stk->stk_tune_offset[2] = stk->stk_tune_sum[2] / STK_TUNE_NUM - STK_LSB_1G;
641*4882a593Smuzhiyun else
642*4882a593Smuzhiyun stk->stk_tune_offset[2] = stk->stk_tune_sum[2] / STK_TUNE_NUM - (-STK_LSB_1G);
643*4882a593Smuzhiyun
644*4882a593Smuzhiyun offset[0] = (u8)(-stk->stk_tune_offset[0]);
645*4882a593Smuzhiyun offset[1] = (u8)(-stk->stk_tune_offset[1]);
646*4882a593Smuzhiyun offset[2] = (u8)(-stk->stk_tune_offset[2]);
647*4882a593Smuzhiyun stk->stk_tune_offset_record[0] = offset[0];
648*4882a593Smuzhiyun stk->stk_tune_offset_record[1] = offset[1];
649*4882a593Smuzhiyun stk->stk_tune_offset_record[2] = offset[2];
650*4882a593Smuzhiyun
651*4882a593Smuzhiyun stk->stk_tune_done = 1;
652*4882a593Smuzhiyun atomic_set(&stk->cali_status, STK_K_SUCCESS_TUNE);
653*4882a593Smuzhiyun stk->event_since_en = 0;
654*4882a593Smuzhiyun printk(KERN_INFO "%s:TUNE done, %d,%d,%d\n", __func__, offset[0], offset[1], offset[2]);
655*4882a593Smuzhiyun printk(KERN_INFO "%s:TUNE done, var=%u,%u,%u\n", __func__, stk->variance[0], stk->variance[1], stk->variance[2]);
656*4882a593Smuzhiyun }
657*4882a593Smuzhiyun }
658*4882a593Smuzhiyun }
659*4882a593Smuzhiyun #endif
660*4882a593Smuzhiyun
stk8baxx_sign_conv(struct stk8baxx_data * stk,s16 raw_acc_data[],u8 acc_reg_data[])661*4882a593Smuzhiyun static void stk8baxx_sign_conv(struct stk8baxx_data *stk, s16 raw_acc_data[], u8 acc_reg_data[])
662*4882a593Smuzhiyun {
663*4882a593Smuzhiyun #ifdef CONFIG_SENSORS_STK8BA53
664*4882a593Smuzhiyun raw_acc_data[0] = acc_reg_data[1] << 8 | acc_reg_data[0];
665*4882a593Smuzhiyun raw_acc_data[0] >>= 4;
666*4882a593Smuzhiyun raw_acc_data[1] = acc_reg_data[3] << 8 | acc_reg_data[2];
667*4882a593Smuzhiyun raw_acc_data[1] >>= 4;
668*4882a593Smuzhiyun raw_acc_data[2] = acc_reg_data[5] << 8 | acc_reg_data[4];
669*4882a593Smuzhiyun raw_acc_data[2] >>= 4;
670*4882a593Smuzhiyun #else
671*4882a593Smuzhiyun raw_acc_data[0] = acc_reg_data[1] << 8 | acc_reg_data[0];
672*4882a593Smuzhiyun raw_acc_data[0] >>= 6;
673*4882a593Smuzhiyun raw_acc_data[1] = acc_reg_data[3] << 8 | acc_reg_data[2];
674*4882a593Smuzhiyun raw_acc_data[1] >>= 6;
675*4882a593Smuzhiyun raw_acc_data[2] = acc_reg_data[5] << 8 | acc_reg_data[4];
676*4882a593Smuzhiyun raw_acc_data[2] >>= 6;
677*4882a593Smuzhiyun #endif
678*4882a593Smuzhiyun }
679*4882a593Smuzhiyun
stk8baxx_set_enable(struct stk8baxx_data * stk,char en)680*4882a593Smuzhiyun static int stk8baxx_set_enable(struct stk8baxx_data *stk, char en)
681*4882a593Smuzhiyun {
682*4882a593Smuzhiyun s8 result;
683*4882a593Smuzhiyun s8 write_buffer = 0;
684*4882a593Smuzhiyun int new_enabled = (en) ? 1 : 0;
685*4882a593Smuzhiyun
686*4882a593Smuzhiyun /*int k_status = atomic_read(&stk->cali_status);*/
687*4882a593Smuzhiyun #ifdef STK_DEBUG_PRINT
688*4882a593Smuzhiyun printk("%s:+++1+++--k_status=%d,first_enable=%d\n", __func__, k_status, stk->first_enable);
689*4882a593Smuzhiyun if (stk->first_enable && k_status != STK_K_RUNNING) {
690*4882a593Smuzhiyun stk->first_enable = false;
691*4882a593Smuzhiyun printk("%s:+++2+++first_enable=%d\n", __func__, stk->first_enable);
692*4882a593Smuzhiyun stk8baxx_load_cali(stk);
693*4882a593Smuzhiyun }
694*4882a593Smuzhiyun #endif
695*4882a593Smuzhiyun enable_status = new_enabled;
696*4882a593Smuzhiyun if (new_enabled == atomic_read(&stk->enabled))
697*4882a593Smuzhiyun return 0;
698*4882a593Smuzhiyun /* printk(KERN_INFO "%s:%x\n", __func__, en); */
699*4882a593Smuzhiyun
700*4882a593Smuzhiyun if (en)
701*4882a593Smuzhiyun write_buffer = STK8BAXX_MD_NORMAL;
702*4882a593Smuzhiyun else
703*4882a593Smuzhiyun write_buffer = STK8BAXX_MD_SUSPEND;
704*4882a593Smuzhiyun
705*4882a593Smuzhiyun result = stk8baxx_smbus_write_byte_data(STK8BAXX_POWMODE, write_buffer);
706*4882a593Smuzhiyun if (result < 0) {
707*4882a593Smuzhiyun printk(KERN_ERR "%s:failed to write reg 0x%x, error=%d\n", __func__, STK8BAXX_POWMODE, result);
708*4882a593Smuzhiyun goto error_enable;
709*4882a593Smuzhiyun }
710*4882a593Smuzhiyun
711*4882a593Smuzhiyun if (en) {
712*4882a593Smuzhiyun stk->event_since_en = 0;
713*4882a593Smuzhiyun #ifdef STK_TUNE
714*4882a593Smuzhiyun if ((k_status & 0xF0) != 0 && stk->stk_tune_done == 0) {
715*4882a593Smuzhiyun stk->stk_tune_index = 0;
716*4882a593Smuzhiyun stk8baxx_reset_para(stk);
717*4882a593Smuzhiyun }
718*4882a593Smuzhiyun #endif
719*4882a593Smuzhiyun }
720*4882a593Smuzhiyun
721*4882a593Smuzhiyun atomic_set(&stk->enabled, new_enabled);
722*4882a593Smuzhiyun return 0;
723*4882a593Smuzhiyun
724*4882a593Smuzhiyun error_enable:
725*4882a593Smuzhiyun return result;
726*4882a593Smuzhiyun }
727*4882a593Smuzhiyun
gsensor_report_value(struct i2c_client * client,struct sensor_axis * axis)728*4882a593Smuzhiyun static int gsensor_report_value(struct i2c_client *client, struct sensor_axis *axis)
729*4882a593Smuzhiyun {
730*4882a593Smuzhiyun struct sensor_private_data *sensor =
731*4882a593Smuzhiyun (struct sensor_private_data *)i2c_get_clientdata(client);
732*4882a593Smuzhiyun
733*4882a593Smuzhiyun /* Report acceleration sensor information */
734*4882a593Smuzhiyun input_report_abs(sensor->input_dev, ABS_X, axis->x);
735*4882a593Smuzhiyun input_report_abs(sensor->input_dev, ABS_Y, axis->y);
736*4882a593Smuzhiyun input_report_abs(sensor->input_dev, ABS_Z, axis->z);
737*4882a593Smuzhiyun input_sync(sensor->input_dev);
738*4882a593Smuzhiyun #ifdef STK_DEBUG_PRINT
739*4882a593Smuzhiyun printk(KERN_INFO "Gsensor x==%d y==%d z==%d\n", axis->x, axis->y, axis->z);
740*4882a593Smuzhiyun #endif
741*4882a593Smuzhiyun return 0;
742*4882a593Smuzhiyun }
743*4882a593Smuzhiyun
stk8baxx_read_sensor_data(struct stk8baxx_data * stk)744*4882a593Smuzhiyun static int stk8baxx_read_sensor_data(struct stk8baxx_data *stk)
745*4882a593Smuzhiyun {
746*4882a593Smuzhiyun int result;
747*4882a593Smuzhiyun u8 acc_reg[6];
748*4882a593Smuzhiyun int x, y, z;
749*4882a593Smuzhiyun struct stk8baxx_acc acc;
750*4882a593Smuzhiyun struct sensor_private_data *sensor =
751*4882a593Smuzhiyun (struct sensor_private_data *)i2c_get_clientdata(stk->client);
752*4882a593Smuzhiyun struct sensor_platform_data *pdata = sensor->pdata;
753*4882a593Smuzhiyun s16 raw_acc[3];
754*4882a593Smuzhiyun
755*4882a593Smuzhiyun acc.x = 0;
756*4882a593Smuzhiyun acc.y = 0;
757*4882a593Smuzhiyun acc.z = 0;
758*4882a593Smuzhiyun
759*4882a593Smuzhiyun *acc_reg = sensor->ops->read_reg;
760*4882a593Smuzhiyun result = sensor_rx_data(stk->client, (char *)acc_reg, sensor->ops->read_len);
761*4882a593Smuzhiyun if (result < 0) {
762*4882a593Smuzhiyun printk(KERN_ERR "%s: failed to read acc data, error=%d\n", __func__, result);
763*4882a593Smuzhiyun return result;
764*4882a593Smuzhiyun }
765*4882a593Smuzhiyun
766*4882a593Smuzhiyun stk8baxx_sign_conv(stk, raw_acc, acc_reg);
767*4882a593Smuzhiyun #ifdef STK_DEBUG_PRINT
768*4882a593Smuzhiyun printk(KERN_INFO "%s: raw_acc=%4d,%4d,%4d\n", __func__, (int)raw_acc[0], (int)raw_acc[1], (int)raw_acc[2]);
769*4882a593Smuzhiyun #endif
770*4882a593Smuzhiyun acc.x = raw_acc[0];
771*4882a593Smuzhiyun acc.y = raw_acc[1];
772*4882a593Smuzhiyun acc.z = raw_acc[2];
773*4882a593Smuzhiyun #ifdef STK_TUNE
774*4882a593Smuzhiyun if ((k_status & 0xF0) != 0)
775*4882a593Smuzhiyun stk8baxx_tune(stk, &acc);
776*4882a593Smuzhiyun #endif
777*4882a593Smuzhiyun x = acc.x;
778*4882a593Smuzhiyun y = acc.y;
779*4882a593Smuzhiyun z = acc.z;
780*4882a593Smuzhiyun acc.x = (pdata->orientation[0]) * x + (pdata->orientation[1]) * y + (pdata->orientation[2]) * z;
781*4882a593Smuzhiyun acc.y = (pdata->orientation[3]) * x + (pdata->orientation[4]) * y + (pdata->orientation[5]) * z;
782*4882a593Smuzhiyun acc.z = (pdata->orientation[6]) * x + (pdata->orientation[7]) * y + (pdata->orientation[8]) * z;
783*4882a593Smuzhiyun
784*4882a593Smuzhiyun #ifdef STK_LOWPASS
785*4882a593Smuzhiyun stk8baxx_low_pass(stk, &acc);
786*4882a593Smuzhiyun #endif
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun stk->acc_xyz.x = acc.x;
789*4882a593Smuzhiyun stk->acc_xyz.y = acc.y;
790*4882a593Smuzhiyun stk->acc_xyz.z = acc.z;
791*4882a593Smuzhiyun #ifdef STK_DEBUG_PRINT
792*4882a593Smuzhiyun printk(KERN_INFO "stk8baxx acc= %4d, %4d, %4d\n", (int)stk->acc_xyz.x, (int)stk->acc_xyz.y, (int)stk->acc_xyz.z);
793*4882a593Smuzhiyun #endif
794*4882a593Smuzhiyun return 0;
795*4882a593Smuzhiyun }
796*4882a593Smuzhiyun
sensor_report_value(struct i2c_client * client)797*4882a593Smuzhiyun static int sensor_report_value(struct i2c_client *client)
798*4882a593Smuzhiyun {
799*4882a593Smuzhiyun unsigned int xyz_adc_rang = 0;
800*4882a593Smuzhiyun struct sensor_axis axis;
801*4882a593Smuzhiyun struct sensor_private_data *sensor =
802*4882a593Smuzhiyun (struct sensor_private_data *)i2c_get_clientdata(client);
803*4882a593Smuzhiyun static int flag;
804*4882a593Smuzhiyun
805*4882a593Smuzhiyun stk8baxx_read_sensor_data(stk8baxx_data_ptr);
806*4882a593Smuzhiyun
807*4882a593Smuzhiyun xyz_adc_rang = STK_LSB_1G * STK_DEF_RANGE;
808*4882a593Smuzhiyun axis.x = stk8baxx_data_ptr->acc_xyz.x * (STK8BAXX_RANGE_UG / xyz_adc_rang);
809*4882a593Smuzhiyun axis.y = stk8baxx_data_ptr->acc_xyz.y * (STK8BAXX_RANGE_UG / xyz_adc_rang);
810*4882a593Smuzhiyun axis.z = stk8baxx_data_ptr->acc_xyz.z * (STK8BAXX_RANGE_UG / xyz_adc_rang);
811*4882a593Smuzhiyun
812*4882a593Smuzhiyun /*
813*4882a593Smuzhiyun *input dev will ignore report data if data value is the same with last_value,
814*4882a593Smuzhiyun *sample rate will not enough by this way, so just avoid this case
815*4882a593Smuzhiyun */
816*4882a593Smuzhiyun if ((sensor->axis.x == axis.x) && (sensor->axis.y == axis.y) && (sensor->axis.z == axis.z)) {
817*4882a593Smuzhiyun if (flag) {
818*4882a593Smuzhiyun flag = 0;
819*4882a593Smuzhiyun axis.x += 1;
820*4882a593Smuzhiyun axis.y += 1;
821*4882a593Smuzhiyun axis.z += 1;
822*4882a593Smuzhiyun } else {
823*4882a593Smuzhiyun flag = 1;
824*4882a593Smuzhiyun axis.x -= 1;
825*4882a593Smuzhiyun axis.y -= 1;
826*4882a593Smuzhiyun axis.z -= 1;
827*4882a593Smuzhiyun }
828*4882a593Smuzhiyun }
829*4882a593Smuzhiyun
830*4882a593Smuzhiyun gsensor_report_value(client, &axis);
831*4882a593Smuzhiyun
832*4882a593Smuzhiyun mutex_lock(&sensor->data_mutex);
833*4882a593Smuzhiyun sensor->axis = axis;
834*4882a593Smuzhiyun mutex_unlock(&sensor->data_mutex);
835*4882a593Smuzhiyun
836*4882a593Smuzhiyun return 0;
837*4882a593Smuzhiyun }
838*4882a593Smuzhiyun
sensor_active(struct i2c_client * client,int enable,int rate)839*4882a593Smuzhiyun static int sensor_active(struct i2c_client *client, int enable, int rate)
840*4882a593Smuzhiyun {
841*4882a593Smuzhiyun if (enable)
842*4882a593Smuzhiyun stk8baxx_set_enable(stk8baxx_data_ptr, 1);
843*4882a593Smuzhiyun else
844*4882a593Smuzhiyun stk8baxx_set_enable(stk8baxx_data_ptr, 0);
845*4882a593Smuzhiyun
846*4882a593Smuzhiyun return 0;
847*4882a593Smuzhiyun }
848*4882a593Smuzhiyun
sensor_init(struct i2c_client * client)849*4882a593Smuzhiyun static int sensor_init(struct i2c_client *client)
850*4882a593Smuzhiyun {
851*4882a593Smuzhiyun int ret = 0;
852*4882a593Smuzhiyun struct stk8baxx_data *stk;
853*4882a593Smuzhiyun struct sensor_private_data *sensor =
854*4882a593Smuzhiyun (struct sensor_private_data *)i2c_get_clientdata(client);
855*4882a593Smuzhiyun
856*4882a593Smuzhiyun printk(KERN_INFO "driver version:%s\n", STK_ACC_DRIVER_VERSION);
857*4882a593Smuzhiyun if (!enable_status)
858*4882a593Smuzhiyun return 0;
859*4882a593Smuzhiyun stk = kzalloc(sizeof(*stk), GFP_KERNEL);
860*4882a593Smuzhiyun if (!stk) {
861*4882a593Smuzhiyun printk(KERN_ERR "%s:memory allocation error\n", __func__);
862*4882a593Smuzhiyun return -ENOMEM;
863*4882a593Smuzhiyun }
864*4882a593Smuzhiyun stk8baxx_data_ptr = stk;
865*4882a593Smuzhiyun sensor_ptr = sensor;
866*4882a593Smuzhiyun stk->stk8baxx_placement = STK8BAXX_DEF_PLACEMENT;
867*4882a593Smuzhiyun stk->client = client;
868*4882a593Smuzhiyun ret = stk8baxx_reg_init(stk, client, sensor);
869*4882a593Smuzhiyun if (ret) {
870*4882a593Smuzhiyun printk(KERN_ERR "%s:stk8baxx initialization failed\n", __func__);
871*4882a593Smuzhiyun return ret;
872*4882a593Smuzhiyun }
873*4882a593Smuzhiyun stk->re_enable = false;
874*4882a593Smuzhiyun sensor->status_cur = SENSOR_OFF;
875*4882a593Smuzhiyun
876*4882a593Smuzhiyun /* Sys Attribute Register */
877*4882a593Smuzhiyun if (no_create_att) {
878*4882a593Smuzhiyun struct input_dev *p_input_dev = NULL;
879*4882a593Smuzhiyun
880*4882a593Smuzhiyun p_input_dev = input_allocate_device();
881*4882a593Smuzhiyun if (!p_input_dev) {
882*4882a593Smuzhiyun dev_err(&client->dev,
883*4882a593Smuzhiyun "Failed to allocate input device\n");
884*4882a593Smuzhiyun return -ENOMEM;
885*4882a593Smuzhiyun }
886*4882a593Smuzhiyun
887*4882a593Smuzhiyun p_input_dev->name = "stk8baxx_attr";
888*4882a593Smuzhiyun set_bit(EV_ABS, p_input_dev->evbit);
889*4882a593Smuzhiyun dev_set_drvdata(&p_input_dev->dev, stk);
890*4882a593Smuzhiyun ret = input_register_device(p_input_dev);
891*4882a593Smuzhiyun if (ret) {
892*4882a593Smuzhiyun dev_err(&client->dev,
893*4882a593Smuzhiyun "Unable to register input device %s\n", p_input_dev->name);
894*4882a593Smuzhiyun return ret;
895*4882a593Smuzhiyun }
896*4882a593Smuzhiyun
897*4882a593Smuzhiyun DBG("Sys Attribute Register here %s is called for stk8baxx.\n", __func__);
898*4882a593Smuzhiyun no_create_att = 0;
899*4882a593Smuzhiyun }
900*4882a593Smuzhiyun
901*4882a593Smuzhiyun return 0;
902*4882a593Smuzhiyun }
903*4882a593Smuzhiyun
904*4882a593Smuzhiyun static struct sensor_operate gsensor_stk8baxx_ops = {
905*4882a593Smuzhiyun .name = "gs_stk8baxx",
906*4882a593Smuzhiyun .type = SENSOR_TYPE_ACCEL, /*sensor type and it should be correct*/
907*4882a593Smuzhiyun .id_i2c = ACCEL_ID_STK8BAXX, /*i2c id number*/
908*4882a593Smuzhiyun .read_reg = STK8BAXX_XOUT1, /*read data*/
909*4882a593Smuzhiyun .read_len = 6, /*data length*/
910*4882a593Smuzhiyun .id_reg = SENSOR_UNKNOW_DATA, /*read device id from this register*/
911*4882a593Smuzhiyun .id_data = SENSOR_UNKNOW_DATA, /*device id*/
912*4882a593Smuzhiyun .precision = SENSOR_UNKNOW_DATA, /*12 bit*/
913*4882a593Smuzhiyun .ctrl_reg = STK8BAXX_POWMODE, /*enable or disable*/
914*4882a593Smuzhiyun /*intterupt status register*/
915*4882a593Smuzhiyun .int_status_reg = STK8BAXX_INTSTS2,
916*4882a593Smuzhiyun .range = {-STK8BAXX_RANGE_UG, STK8BAXX_RANGE_UG}, /*range*/
917*4882a593Smuzhiyun .trig = IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
918*4882a593Smuzhiyun .active = sensor_active,
919*4882a593Smuzhiyun .init = sensor_init,
920*4882a593Smuzhiyun .report = sensor_report_value,
921*4882a593Smuzhiyun };
922*4882a593Smuzhiyun
gsensor_stk8baxx_probe(struct i2c_client * client,const struct i2c_device_id * devid)923*4882a593Smuzhiyun static int gsensor_stk8baxx_probe(struct i2c_client *client,
924*4882a593Smuzhiyun const struct i2c_device_id *devid)
925*4882a593Smuzhiyun {
926*4882a593Smuzhiyun return sensor_register_device(client, NULL, devid, &gsensor_stk8baxx_ops);
927*4882a593Smuzhiyun }
928*4882a593Smuzhiyun
gsensor_stk8baxx_remove(struct i2c_client * client)929*4882a593Smuzhiyun static int gsensor_stk8baxx_remove(struct i2c_client *client)
930*4882a593Smuzhiyun {
931*4882a593Smuzhiyun return sensor_unregister_device(client, NULL, &gsensor_stk8baxx_ops);
932*4882a593Smuzhiyun }
933*4882a593Smuzhiyun
934*4882a593Smuzhiyun static const struct i2c_device_id gsensor_stk8baxx_id[] = {
935*4882a593Smuzhiyun {"gs_stk8baxx", ACCEL_ID_STK8BAXX},
936*4882a593Smuzhiyun {}
937*4882a593Smuzhiyun };
938*4882a593Smuzhiyun
939*4882a593Smuzhiyun static struct i2c_driver gsensor_stk8baxx_driver = {
940*4882a593Smuzhiyun .probe = gsensor_stk8baxx_probe,
941*4882a593Smuzhiyun .remove = gsensor_stk8baxx_remove,
942*4882a593Smuzhiyun .shutdown = sensor_shutdown,
943*4882a593Smuzhiyun .id_table = gsensor_stk8baxx_id,
944*4882a593Smuzhiyun .driver = {
945*4882a593Smuzhiyun .name = "gsensor_stk8baxx",
946*4882a593Smuzhiyun #ifdef CONFIG_PM
947*4882a593Smuzhiyun .pm = &sensor_pm_ops,
948*4882a593Smuzhiyun #endif
949*4882a593Smuzhiyun },
950*4882a593Smuzhiyun };
951*4882a593Smuzhiyun
952*4882a593Smuzhiyun module_i2c_driver(gsensor_stk8baxx_driver);
953*4882a593Smuzhiyun
954*4882a593Smuzhiyun MODULE_AUTHOR("Lex Hsieh, Sensortek");
955*4882a593Smuzhiyun MODULE_DESCRIPTION("stk8baxx 3-Axis accelerometer driver");
956*4882a593Smuzhiyun MODULE_LICENSE("GPL");
957*4882a593Smuzhiyun MODULE_VERSION(STK_ACC_DRIVER_VERSION);
958