Merge tag 'v3.10.23' into develop-3.10
[firefly-linux-kernel-4.4.55.git] / drivers / input / sensors / accel / lsm303d.c
1 /* drivers/input/sensors/access/kxtik.c\r
2  *\r
3  * Copyright (C) 2012-2015 ROCKCHIP.\r
4  * Author: Bruins <xwj@rock-chips.com>\r
5  *\r
6  * This software is licensed under the terms of the GNU General Public\r
7  * License version 2, as published by the Free Software Foundation, and\r
8  * may be copied, distributed, and modified under those terms.\r
9  *\r
10  * This program is distributed in the hope that it will be useful,\r
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13  * GNU General Public License for more details.\r
14  *\r
15  */\r
16 \r
17 #include <linux/interrupt.h>\r
18 #include <linux/i2c.h>\r
19 #include <linux/slab.h>\r
20 #include <linux/irq.h>\r
21 #include <linux/miscdevice.h>\r
22 #include <linux/gpio.h>\r
23 #include <asm/uaccess.h>\r
24 #include <asm/atomic.h>\r
25 #include <linux/delay.h>\r
26 #include <linux/input.h>\r
27 #include <linux/workqueue.h>\r
28 #include <linux/freezer.h>\r
29 #include <mach/gpio.h>\r
30 #include <mach/board.h> \r
31 #ifdef CONFIG_HAS_EARLYSUSPEND\r
32 #include <linux/earlysuspend.h>\r
33 #endif\r
34 #include <linux/sensor-dev.h>\r
35 \r
36 \r
37 #define LSM303D_WHO_AM_I                (0x0F)\r
38 \r
39 /* full scale setting - register & mask */\r
40 #define LSM303D_CTRL_REG0               (0x1F)\r
41 #define LSM303D_CTRL_REG1               (0x20)\r
42 #define LSM303D_CTRL_REG2               (0x21)\r
43 #define LSM303D_CTRL_REG3               (0x22)\r
44 #define LSM303D_CTRL_REG4               (0x23)\r
45 #define LSM303D_CTRL_REG5               (0x24)\r
46 #define LSM303D_CTRL_REG6               (0x25)\r
47 #define LSM303D_CTRL_REG7               (0x26)\r
48 #define LSM303D_STATUS_REG              (0x27)\r
49 #define LSM303D_OUT_X_L                 (0x28)\r
50 #define LSM303D_OUT_X_H                 (0x29)\r
51 #define LSM303D_OUT_Y_L                 (0x2a)\r
52 #define LSM303D_OUT_Y_H                 (0x2b)\r
53 #define LSM303D_OUT_Z_L                 (0x2c)\r
54 #define LSM303D_OUT_Z_H                 (0x2d)\r
55 #define LSM303D_FIFO_CTRL_REG           (0x2E)\r
56 #define LSM303D_FIFO_SRC_REG            (0X2F)\r
57 \r
58 #define LSM303D_IG_CFG1                 (0x30)\r
59 #define LSM303D_IG_SRC1                 (0x31)\r
60 #define LSM303D_IG_THS1                 (0x32)\r
61 #define LSM303D_IG_DURATION1            (0x33)\r
62 \r
63 #define LSM303D_IG_CFG2                 (0x34)\r
64 #define LSM303D_IG_SRC2                 (0x35)\r
65 #define LSM303D_IG_THS2                 (0x36)\r
66 #define LSM303D_IG_DURATION2            (0x37)\r
67 \r
68 \r
69 #define LSM303D_DEVID                   (0x49)  //chip id\r
70 #define LSM303D_ACC_DISABLE             (0x08)\r
71 \r
72 #define LSM303D_RANGE                   2000000\r
73 \r
74 /* LSM303D */\r
75 #define LSM303D_PRECISION               16\r
76 #define LSM303D_BOUNDARY                        (0x1 << (LSM303D_PRECISION - 1))\r
77 #define LSM303D_GRAVITY_STEP            (LSM303D_RANGE / LSM303D_BOUNDARY)\r
78 \r
79 #define ODR3P25                         0x10  /* 3.25Hz output data rate */\r
80 #define ODR6P25                         0x20  /* 6.25Hz output data rate */\r
81 #define ODR12P5                         0x30  /* 12.5Hz output data rate */\r
82 #define ODR25                           0x40  /* 25Hz output data rate */\r
83 #define ODR50                           0x50  /* 50Hz output data rate */\r
84 #define ODR100                          0x60  /* 100Hz output data rate */\r
85 #define ODR200                          0x70  /* 200Hz output data rate */\r
86 #define ODR400                          0x80  /* 400Hz output data rate */\r
87 #define ODR800                          0x90  /* 800Hz output data rate */\r
88 #define ODR1600                         0xA0  /* 1600Hz output data rate */\r
89 \r
90 \r
91 struct sensor_reg_data {\r
92         char reg;\r
93         char data;\r
94 };\r
95 \r
96 /****************operate according to sensor chip:start************/\r
97 static int sensor_active(struct i2c_client *client, int enable, int rate)\r
98 {\r
99         struct sensor_private_data *sensor =\r
100             (struct sensor_private_data *) i2c_get_clientdata(client);  \r
101         int result = 0;\r
102         int status = 0;\r
103                 \r
104         sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);\r
105 \r
106         sensor->ops->ctrl_data |= ODR100;       //100HZ,if 0 then power down\r
107         \r
108         //register setting according to chip datasheet          \r
109         if(!enable)\r
110         {       \r
111                 status = LSM303D_ACC_DISABLE;   //lis3dh        \r
112                 sensor->ops->ctrl_data |= status;       \r
113         }\r
114         else\r
115         {\r
116                 status = ~LSM303D_ACC_DISABLE;  //lis3dh\r
117                 sensor->ops->ctrl_data &= status;\r
118         }\r
119 \r
120         DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);\r
121         result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);\r
122         if(result)\r
123                 printk("%s:fail to active sensor\n",__func__);\r
124         \r
125         return result;\r
126 \r
127 }\r
128 \r
129 \r
130 static int sensor_init(struct i2c_client *client)\r
131 {       \r
132         struct sensor_private_data *sensor =\r
133             (struct sensor_private_data *) i2c_get_clientdata(client);  \r
134         int result = 0;\r
135         int i;\r
136 \r
137         struct sensor_reg_data reg_data[] = \r
138         {\r
139                 {LSM303D_CTRL_REG0,0x00},\r
140                 {LSM303D_CTRL_REG1,0x07},\r
141                 {LSM303D_CTRL_REG2,0x00},\r
142                 {LSM303D_CTRL_REG3,0x00},\r
143                 {LSM303D_CTRL_REG4,0x00},\r
144                 {LSM303D_CTRL_REG5,0x78},               //High resolution output mode:11,\r
145                 {LSM303D_CTRL_REG6,0x20},\r
146                 {LSM303D_CTRL_REG7,0x00},\r
147                 {LSM303D_FIFO_CTRL_REG,0x00},\r
148                 {LSM303D_IG_CFG1,0xFF},         //6 direction position recognition      \r
149                 {LSM303D_IG_THS1,0x7F},         //Interrupt 1 threshold \r
150                 {LSM303D_IG_DURATION1,0x7F},    //Duration value 0x00->ox7f\r
151                         \r
152         /*\r
153                 {LSM303D_CTRL_REG7,0x00},               \r
154                 {LSM303D_CTRL_REG4,0x08},               //High resolution output mode: 1, Normal mode   \r
155                 {LSM303D_CTRL_REG6,0x40},       \r
156                 \r
157                 {LSM303D_FIFO_CTRL_REG,0x00},   //      \r
158                 {LSM303D_IG_CFG1,0xFF},                 //6 direction position recognition      \r
159                 {LSM303D_IG_THS1,0x7F},                 //Interrupt 1 threshold \r
160                 {LSM303D_IG_DURATION1,0x7F},    //Duration value 0x00->ox7f\r
161                 */\r
162         };  \r
163         \r
164         result = sensor->ops->active(client,0,0);\r
165         if(result)\r
166         {\r
167                 printk("%s:line=%d,error\n",__func__,__LINE__);\r
168                 return result;\r
169         }\r
170 \r
171         sensor->status_cur = SENSOR_OFF;\r
172         \r
173         for(i=0;i<(sizeof(reg_data)/sizeof(struct sensor_reg_data));i++)\r
174         {\r
175                 result = sensor_write_reg(client, reg_data[i].reg, reg_data[i].data);\r
176                 if(result)\r
177                 {\r
178                         printk("%s:line=%d,i=%d,error\n",__func__,__LINE__,i);\r
179                         return result;\r
180                 }\r
181         }\r
182 \r
183         \r
184         if(sensor->pdata->irq_enable)\r
185         {\r
186 \r
187                 result = sensor_write_reg(client, LSM303D_CTRL_REG3, 0x20);     \r
188                 if(result)\r
189                 {\r
190                         printk("%s:line=%d,error\n",__func__,__LINE__);\r
191                         return result;\r
192                 }\r
193 \r
194                 i = sensor_read_reg(client,LSM303D_CTRL_REG5);\r
195                 \r
196                 result = sensor_write_reg(client, LSM303D_CTRL_REG5, (i|0x01));\r
197                 if(result)\r
198                 {\r
199                         printk("%s:line=%d,error\n",__func__,__LINE__);\r
200                         return result;\r
201                 }\r
202 \r
203         }\r
204         \r
205         return result;\r
206 }\r
207 \r
208 \r
209 static int sensor_convert_data(struct i2c_client *client, char high_byte, char low_byte)\r
210 {\r
211         s64 result;\r
212         struct sensor_private_data *sensor =\r
213             (struct sensor_private_data *) i2c_get_clientdata(client);  \r
214         \r
215         switch (sensor->devid) {        \r
216                 case LSM303D_DEVID:             \r
217                         result = ((int)high_byte << 8) | (int)low_byte;\r
218                         if (result < LSM303D_BOUNDARY)\r
219                         result = result* LSM303D_GRAVITY_STEP;\r
220                 else\r
221                         result = ~( ((~result & (0x7fff>>(16-LSM303D_PRECISION)) ) + 1) \r
222                                                 * LSM303D_GRAVITY_STEP) + 1;\r
223                         break;\r
224 \r
225                 default:\r
226                         printk(KERN_ERR "%s: devid wasn't set correctly\n",__func__);\r
227                         return -EFAULT;\r
228     }\r
229 \r
230     return (int)result;\r
231 }\r
232 \r
233 static int gsensor_report_value(struct i2c_client *client, struct sensor_axis *axis)\r
234 {\r
235         struct sensor_private_data *sensor =\r
236                 (struct sensor_private_data *) i2c_get_clientdata(client);      \r
237 \r
238         /* Report acceleration sensor information */\r
239         input_report_abs(sensor->input_dev, ABS_X, axis->x);\r
240         input_report_abs(sensor->input_dev, ABS_Y, axis->y);\r
241         input_report_abs(sensor->input_dev, ABS_Z, axis->z);\r
242         input_sync(sensor->input_dev);\r
243         DBG("Gsensor x==%d  y==%d z==%d\n",axis->x,axis->y,axis->z);\r
244 \r
245         return 0;\r
246 }\r
247 \r
248 #define GSENSOR_MIN  10\r
249 static int sensor_report_value(struct i2c_client *client)\r
250 {\r
251         struct sensor_private_data *sensor =\r
252                         (struct sensor_private_data *) i2c_get_clientdata(client);      \r
253         struct sensor_platform_data *pdata = sensor->pdata;\r
254         int ret = 0;\r
255         int x,y,z;\r
256         struct sensor_axis axis;        \r
257         char buffer[6] = {0};   \r
258         char value = 0;\r
259         \r
260         if(sensor->ops->read_len < 6)   //sensor->ops->read_len = 6\r
261         {\r
262                 printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);\r
263                 return -1;\r
264         }\r
265         \r
266         memset(buffer, 0, 6);\r
267 \r
268         value = sensor_read_reg(client, LSM303D_STATUS_REG);\r
269         if((value & 0x0f) == 0)\r
270         {\r
271                 printk("%s:line=%d,value=0x%x,data is not ready\n",__func__,__LINE__,value);\r
272                 return -1;\r
273         }\r
274                 \r
275         \r
276         /* Data bytes from hardware xL, xH, yL, yH, zL, zH */   \r
277         do {\r
278                 *buffer = sensor->ops->read_reg;\r
279                 ret = sensor_rx_data(client, buffer, sensor->ops->read_len);\r
280                 if (ret < 0)\r
281                 return ret;\r
282         } while (0);\r
283 \r
284         //this gsensor need 6 bytes buffer\r
285         x = sensor_convert_data(sensor->client, buffer[1], buffer[0]);  //buffer[1]:high bit \r
286         y = sensor_convert_data(sensor->client, buffer[3], buffer[2]);\r
287         z = sensor_convert_data(sensor->client, buffer[5], buffer[4]);          \r
288 \r
289         axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;\r
290         axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z;     \r
291         axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;\r
292 \r
293         DBG( "%s: axis = %d  %d  %d \n", __func__, axis.x, axis.y, axis.z);\r
294         //printk( "%s: axis = %d  %d  %d \n", __func__, axis.x, axis.y, axis.z);\r
295 \r
296         //Report event  only while value is changed to save some power\r
297         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))\r
298         {\r
299                 gsensor_report_value(client, &axis);\r
300 \r
301                 /* »¥³âµØ»º´æÊý¾Ý. */\r
302                 mutex_lock(&(sensor->data_mutex) );\r
303                 sensor->axis = axis;\r
304                 mutex_unlock(&(sensor->data_mutex) );\r
305         }\r
306 \r
307         if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0))    //read sensor intterupt status register\r
308         {\r
309                 \r
310                 value = sensor_read_reg(client, sensor->ops->int_status_reg);\r
311                 DBG("%s:sensor int status :0x%x\n",__func__,value);\r
312         }\r
313         \r
314         return ret;\r
315 }\r
316 \r
317 struct sensor_operate gsensor_lsm303d_ops = {\r
318         .name                           = "lsm303d",\r
319         .type                           = SENSOR_TYPE_ACCEL,            //sensor type and it should be correct\r
320         .id_i2c                         = ACCEL_ID_LSM303D,             //i2c id number\r
321         .read_reg                       = (LSM303D_OUT_X_L | 0x80),     //read data\r
322         .read_len                       = 6,                            //data length\r
323         .id_reg                         = LSM303D_WHO_AM_I,             //read device id from this register\r
324         .id_data                        = LSM303D_DEVID,                        //device id\r
325         .precision                      = LSM303D_PRECISION,            //16 bits\r
326         .ctrl_reg                       = LSM303D_CTRL_REG1,            //enable or disable \r
327         .int_status_reg                 = LSM303D_IG_SRC1,              //intterupt status register\r
328         .range                          = {-LSM303D_RANGE,LSM303D_RANGE},       //range\r
329         .trig                           = (IRQF_TRIGGER_LOW|IRQF_ONESHOT),              \r
330         .active                         = sensor_active,        \r
331         .init                           = sensor_init,\r
332         .report                         = sensor_report_value,\r
333 };\r
334 \r
335 \r
336 /****************operate according to sensor chip:end************/\r
337 \r
338 //function name should not be changed\r
339 static struct sensor_operate *gsensor_get_ops(void)\r
340 {\r
341         return &gsensor_lsm303d_ops;\r
342 }\r
343 \r
344 \r
345 static int __init gsensor_lis3dh_init(void)\r
346 {\r
347         struct sensor_operate *ops = gsensor_get_ops();\r
348         int result = 0;\r
349         int type = ops->type;\r
350         result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);\r
351         return result;\r
352 }\r
353 \r
354 static void __exit gsensor_lis3dh_exit(void)\r
355 {\r
356         struct sensor_operate *ops = gsensor_get_ops();\r
357         int type = ops->type;\r
358         sensor_unregister_slave(type, NULL, NULL, gsensor_get_ops);\r
359 }\r
360 \r
361 \r
362 module_init(gsensor_lis3dh_init);\r
363 module_exit(gsensor_lis3dh_exit);\r
364 \r
365 \r
366 \r
367 \r