c8f5562efda5f0f1197543ed0ac1d1ca2bb0be34
[firefly-linux-kernel-4.4.55.git] / drivers / input / sensors / accel / mma8452.c
1 /* drivers/input/sensors/access/mma8452.c
2  *
3  * Copyright (C) 2012-2015 ROCKCHIP.
4  * Author: luowei <lw@rock-chips.com>
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  */
16 #include <linux/interrupt.h>
17 #include <linux/i2c.h>
18 #include <linux/slab.h>
19 #include <linux/irq.h>
20 #include <linux/miscdevice.h>
21 #include <linux/gpio.h>
22 #include <asm/uaccess.h>
23 #include <asm/atomic.h>
24 #include <linux/delay.h>
25 #include <linux/input.h>
26 #include <linux/workqueue.h>
27 #include <linux/freezer.h>
28 #include <mach/gpio.h>
29 #include <mach/board.h> 
30 #ifdef CONFIG_HAS_EARLYSUSPEND
31 #include <linux/earlysuspend.h>
32 #endif
33 #include <linux/sensor-dev.h>
34
35 /* Default register settings */
36 #define RBUFF_SIZE              12      /* Rx buffer size */
37
38 #define MMA8452_REG_STATUS              0x0 //RO
39 #define MMA8452_REG_X_OUT_MSB           0x1 //RO
40 #define MMA8452_REG_X_OUT_LSB           0x2 //RO
41 #define MMA8452_REG_Y_OUT_MSB           0x3 //RO
42 #define MMA8452_REG_Y_OUT_LSB           0x4 //RO
43 #define MMA8452_REG_Z_OUT_MSB           0x5 //RO
44 #define MMA8452_REG_Z_OUT_LSB           0x6 //RO
45 #define MMA8452_REG_F_SETUP                     0x9 //RW
46
47 #define MMA8452_REG_SYSMOD                              0xB //RO
48 #define MMA8452_REG_INTSRC                      0xC //RO
49 #define MMA8452_REG_WHO_AM_I                    0xD //RO
50 #define MMA8452_REG_XYZ_DATA_CFG                0xE //RW
51 #define MMA8452_REG_HP_FILTER_CUTOFF    0xF //RW
52 #define MMA8452_REG_PL_STATUS                   0x10 //RO
53 #define MMA8452_REG_PL_CFG                              0x11 //RW
54 #define MMA8452_REG_PL_COUNT                    0x12 //RW
55 #define MMA8452_REG_PL_BF_ZCOMP                 0x13 //RW
56 #define MMA8452_REG_P_L_THS_REG                 0x14 //RW
57 #define MMA8452_REG_FF_MT_CFG                   0x15 //RW
58 #define MMA8452_REG_FF_MT_SRC                   0x16 //RO
59 #define MMA8452_REG_FF_MT_THS                   0x17 //RW
60 #define MMA8452_REG_FF_MT_COUNT                 0x18 //RW
61 #define MMA8452_REG_TRANSIENT_CFG               0x1D //RW
62 #define MMA8452_REG_TRANSIENT_SRC               0x1E //RO
63 #define MMA8452_REG_TRANSIENT_THS               0x1F //RW
64 #define MMA8452_REG_TRANSIENT_COUNT             0x20 //RW
65 #define MMA8452_REG_PULSE_CFG                   0x21 //RW
66 #define MMA8452_REG_PULSE_SRC                   0x22 //RO
67 #define MMA8452_REG_PULSE_THSX                  0x23 //RW
68 #define MMA8452_REG_PULSE_THSY                  0x24 //RW
69 #define MMA8452_REG_PULSE_THSZ                  0x25 //RW
70 #define MMA8452_REG_PULSE_TMLT                  0x26 //RW
71 #define MMA8452_REG_PULSE_LTCY                  0x27 //RW
72 #define MMA8452_REG_PULSE_WIND                  0x28 //RW
73 #define MMA8452_REG_ASLP_COUNT                  0x29 //RW
74 #define MMA8452_REG_CTRL_REG1                   0x2A //RW
75 #define MMA8452_REG_CTRL_REG2                   0x2B //RW
76 #define MMA8452_REG_CTRL_REG3                   0x2C //RW
77 #define MMA8452_REG_CTRL_REG4                   0x2D //RW
78 #define MMA8452_REG_CTRL_REG5                   0x2E //RW
79 #define MMA8452_REG_OFF_X                               0x2F //RW
80 #define MMA8452_REG_OFF_Y                               0x30 //RW
81 #define MMA8452_REG_OFF_Z                               0x31 //RW
82
83 /*rate*/
84 #define MMA8452_RATE_800          0
85 #define MMA8452_RATE_400          1
86 #define MMA8452_RATE_200          2
87 #define MMA8452_RATE_100          3
88 #define MMA8452_RATE_50           4
89 #define MMA8452_RATE_12P5         5
90 #define MMA8452_RATE_6P25         6
91 #define MMA8452_RATE_1P56         7
92 #define MMA8452_RATE_SHIFT                3
93
94
95 #define MMA8452_ASLP_RATE_50          0
96 #define MMA8452_ASLP_RATE_12P5        1
97 #define MMA8452_ASLP_RATE_6P25        2
98 #define MMA8452_ASLP_RATE_1P56        3
99 #define MMA8452_ASLP_RATE_SHIFT           6
100
101 /*Auto-adapt mma845x series*/
102 /*Modified by Yick @ROCKCHIP 
103   xieyi@rockchips.com*/
104 /*
105   Range: unit(ug 1g=1 000 000 ug)
106                  option(2g,4g,8g)
107                  G would be defined on android HAL
108   Precision: bit wide of valid data
109   Boundary: Max positive count
110   Gravity_step: gravity value indicated by per count
111  */
112 #define FREAD_MASK                              0 /* enabled(1<<1) only if reading MSB 8bits*/
113 #define MMA845X_RANGE                   2000000
114 /* mma8451 */
115 #define MMA8451_PRECISION       14
116 #define MMA8451_BOUNDARY        (0x1 << (MMA8451_PRECISION - 1))
117 #define MMA8451_GRAVITY_STEP    MMA845X_RANGE / MMA8451_BOUNDARY
118
119 /* mma8452 */
120 #define MMA8452_PRECISION       12
121 #define MMA8452_BOUNDARY        (0x1 << (MMA8452_PRECISION - 1))
122 #define MMA8452_GRAVITY_STEP    MMA845X_RANGE / MMA8452_BOUNDARY
123
124 /* mma8453 */
125 #define MMA8453_PRECISION       10
126 #define MMA8453_BOUNDARY        (0x1 << (MMA8453_PRECISION - 1))
127 #define MMA8453_GRAVITY_STEP    MMA845X_RANGE / MMA8453_BOUNDARY
128
129 /* mma8653 */
130 #define MMA8653_PRECISION       10
131 #define MMA8653_BOUNDARY        (0x1 << (MMA8653_PRECISION - 1))
132 #define MMA8653_GRAVITY_STEP    MMA845X_RANGE / MMA8653_BOUNDARY
133
134
135 #define MMA8451_DEVID           0x1a
136 #define MMA8452_DEVID           0x2a
137 #define MMA8453_DEVID           0x3a
138 #define MMA8653_DEVID           0x5a
139
140
141 #define MMA8452_ENABLE          1
142
143
144 /****************operate according to sensor chip:start************/
145
146 static int sensor_active(struct i2c_client *client, int enable, int rate)
147 {
148         struct sensor_private_data *sensor =
149             (struct sensor_private_data *) i2c_get_clientdata(client);  
150         int result = 0;
151         int status = 0;
152                 
153         sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
154         
155         //register setting according to chip datasheet          
156         if(enable)
157         {       
158                 status = MMA8452_ENABLE;        //mma8452
159                 sensor->ops->ctrl_data |= status;       
160         }
161         else
162         {
163                 status = ~MMA8452_ENABLE;       //mma8452
164                 sensor->ops->ctrl_data &= status;
165         }
166
167         DBG("%s:reg=0x%x,reg_ctrl=0x%x,enable=%d\n",__func__,sensor->ops->ctrl_reg, sensor->ops->ctrl_data, enable);
168         result = sensor_write_reg(client, sensor->ops->ctrl_reg, sensor->ops->ctrl_data);
169         if(result)
170                 printk("%s:fail to active sensor\n",__func__);
171         
172         return result;
173
174 }
175
176 static int sensor_init(struct i2c_client *client)
177 {
178         int tmp;
179         int ret = 0; 
180         int i = 0;      
181         unsigned char id_reg = MMA8452_REG_WHO_AM_I;
182         unsigned char id_data = 0;
183         struct sensor_private_data *sensor =
184             (struct sensor_private_data *) i2c_get_clientdata(client);  
185         
186         ret = sensor->ops->active(client,0,0);
187         if(ret)
188         {
189                 printk("%s:line=%d,error\n",__func__,__LINE__);
190                 return ret;
191         }
192         
193         sensor->status_cur = SENSOR_OFF;
194
195         for(i=0; i<3; i++)
196         {
197                 ret = sensor_rx_data(client, &id_reg, 1);
198                 id_data = id_reg;
199                 if(!ret)
200                 break;
201         }
202
203         if(ret)
204         {
205                 printk("%s:fail to read id,ret=%d\n",__func__, ret);
206                 return ret;
207         }
208
209         sensor->devid = id_data;
210
211         /* disable FIFO  FMODE = 0*/
212         ret = sensor_write_reg(client,MMA8452_REG_F_SETUP,0);
213         DBG("%s: MMA8452_REG_F_SETUP:%x\n",__func__, sensor_read_reg(client,MMA8452_REG_F_SETUP));
214
215         /* set full scale range to 2g */
216         ret = sensor_write_reg(client,MMA8452_REG_XYZ_DATA_CFG,0);
217         DBG("%s: MMA8452_REG_XYZ_DATA_CFG:%x\n",__func__, sensor_read_reg(client,MMA8452_REG_XYZ_DATA_CFG));
218
219         /* set bus 8bit/14bit(FREAD = 1,FMODE = 0) ,data rate*/
220         tmp = (MMA8452_RATE_12P5<< MMA8452_RATE_SHIFT) | FREAD_MASK;
221         ret = sensor_write_reg(client,MMA8452_REG_CTRL_REG1,tmp);
222
223         sensor->ops->ctrl_data = tmp;
224         
225         DBG("mma8452 MMA8452_REG_CTRL_REG1:%x\n",sensor_read_reg(client,MMA8452_REG_CTRL_REG1));
226         
227         DBG("mma8452 MMA8452_REG_SYSMOD:%x\n",sensor_read_reg(client,MMA8452_REG_SYSMOD));
228
229         ret = sensor_write_reg(client,MMA8452_REG_CTRL_REG3,5);
230         DBG("mma8452 MMA8452_REG_CTRL_REG3:%x\n",sensor_read_reg(client,MMA8452_REG_CTRL_REG3));
231         
232         ret = sensor_write_reg(client,MMA8452_REG_CTRL_REG4,1);
233         DBG("mma8452 MMA8452_REG_CTRL_REG4:%x\n",sensor_read_reg(client,MMA8452_REG_CTRL_REG4));
234
235         ret = sensor_write_reg(client,MMA8452_REG_CTRL_REG5,1);
236         DBG("mma8452 MMA8452_REG_CTRL_REG5:%x\n",sensor_read_reg(client,MMA8452_REG_CTRL_REG5));        
237
238         DBG("mma8452 MMA8452_REG_SYSMOD:%x\n",sensor_read_reg(client,MMA8452_REG_SYSMOD));
239
240         return ret;
241 }
242
243 static int sensor_convert_data(struct i2c_client *client, char high_byte, char low_byte)
244 {
245     s64 result;
246         struct sensor_private_data *sensor =
247             (struct sensor_private_data *) i2c_get_clientdata(client);  
248         //int precision = sensor->ops->precision;
249         switch (sensor->devid) {
250                 case MMA8451_DEVID:     
251                         swap(high_byte,low_byte);
252                         result = ((int)high_byte << (MMA8451_PRECISION-8)) 
253                                         | ((int)low_byte >> (16-MMA8451_PRECISION));
254                         if (result < MMA8451_BOUNDARY)
255                                 result = result* MMA8451_GRAVITY_STEP;
256                         else
257                                 result = ~( ((~result & (0x7fff>>(16-MMA8451_PRECISION)) ) + 1) 
258                                                 * MMA8451_GRAVITY_STEP) + 1;
259                         break;
260
261                 case MMA8452_DEVID:                     
262                         swap(high_byte,low_byte);
263                         result = ((int)high_byte << (MMA8452_PRECISION-8)) 
264                                         | ((int)low_byte >> (16-MMA8452_PRECISION));
265                         if (result < MMA8452_BOUNDARY)
266                                 result = result* MMA8452_GRAVITY_STEP;
267                         else
268                                 result = ~( ((~result & (0x7fff>>(16-MMA8452_PRECISION)) ) + 1) 
269                                                 * MMA8452_GRAVITY_STEP) + 1;
270                         break;
271                         
272                 case MMA8453_DEVID:
273                         swap(high_byte,low_byte);
274                         result = ((int)high_byte << (MMA8453_PRECISION-8)) 
275                                         | ((int)low_byte >> (16-MMA8453_PRECISION));
276                         if (result < MMA8453_BOUNDARY)
277                                 result = result* MMA8453_GRAVITY_STEP;
278                         else
279                                 result = ~( ((~result & (0x7fff>>(16-MMA8453_PRECISION)) ) + 1) 
280                                                 * MMA8453_GRAVITY_STEP) + 1;
281                         break;
282
283                 case MMA8653_DEVID:
284                         swap(high_byte,low_byte);
285                         result = ((int)high_byte << (MMA8653_PRECISION-8)) 
286                                         | ((int)low_byte >> (16-MMA8653_PRECISION));
287                         if (result < MMA8653_BOUNDARY)
288                                 result = result* MMA8653_GRAVITY_STEP;
289                         else
290                                 result = ~( ((~result & (0x7fff>>(16-MMA8653_PRECISION)) ) + 1) 
291                                                 * MMA8653_GRAVITY_STEP) + 1;
292                         break;
293
294                 default:
295                         printk(KERN_ERR "%s: devid wasn't set correctly\n",__func__);
296                         return -EFAULT;
297     }
298
299     return (int)result;
300 }
301
302 static int gsensor_report_value(struct i2c_client *client, struct sensor_axis *axis)
303 {
304         struct sensor_private_data *sensor =
305             (struct sensor_private_data *) i2c_get_clientdata(client);  
306
307         /* Report acceleration sensor information */
308         input_report_abs(sensor->input_dev, ABS_X, axis->x);
309         input_report_abs(sensor->input_dev, ABS_Y, axis->y);
310         input_report_abs(sensor->input_dev, ABS_Z, axis->z);
311         input_sync(sensor->input_dev);
312         DBG("Gsensor x==%d  y==%d z==%d\n",axis->x,axis->y,axis->z);
313
314         return 0;
315 }
316
317 #define GSENSOR_MIN             10
318 static int sensor_report_value(struct i2c_client *client)
319 {
320         struct sensor_private_data *sensor =
321                 (struct sensor_private_data *) i2c_get_clientdata(client);      
322         struct sensor_platform_data *pdata = sensor->pdata;
323         int ret = 0;
324         int x,y,z;
325         struct sensor_axis axis;
326         char buffer[6] = {0};   
327         char value = 0;
328         
329         if(sensor->ops->read_len < 6)   //sensor->ops->read_len = 6
330         {
331                 printk("%s:lenth is error,len=%d\n",__func__,sensor->ops->read_len);
332                 return -1;
333         }
334         
335         memset(buffer, 0, 6);
336         
337         /* Data bytes from hardware xL, xH, yL, yH, zL, zH */   
338         do {
339                 *buffer = sensor->ops->read_reg;
340                 ret = sensor_rx_data(client, buffer, sensor->ops->read_len);
341                 if (ret < 0)
342                 return ret;
343         } while (0);
344
345
346         //this gsensor need 6 bytes buffer
347         x = sensor_convert_data(sensor->client, buffer[1], buffer[0]);  //buffer[1]:high bit 
348         y = sensor_convert_data(sensor->client, buffer[3], buffer[2]);
349         z = sensor_convert_data(sensor->client, buffer[5], buffer[4]);          
350
351         axis.x = (pdata->orientation[0])*x + (pdata->orientation[1])*y + (pdata->orientation[2])*z;
352         axis.y = (pdata->orientation[3])*x + (pdata->orientation[4])*y + (pdata->orientation[5])*z; 
353         axis.z = (pdata->orientation[6])*x + (pdata->orientation[7])*y + (pdata->orientation[8])*z;
354
355         DBG( "%s: axis = %d  %d  %d \n", __func__, axis.x, axis.y, axis.z);
356
357         //Report event only while value is changed to save some power
358         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))
359         {
360                 gsensor_report_value(client, &axis);
361
362                 /* »¥³âµØ»º´æÊý¾Ý. */
363                 mutex_lock(&(sensor->data_mutex) );
364                 sensor->axis = axis;
365                 mutex_unlock(&(sensor->data_mutex) );
366         }
367
368         if((sensor->pdata->irq_enable)&& (sensor->ops->int_status_reg >= 0))    //read sensor intterupt status register
369         {
370                 
371                 value = sensor_read_reg(client, sensor->ops->int_status_reg);
372                 DBG("%s:sensor int status :0x%x\n",__func__,value);
373         }
374         
375         return ret;
376 }
377
378
379 struct sensor_operate gsensor_mma8452_ops = {
380         .name                           = "mma8452",
381         .type                           = SENSOR_TYPE_ACCEL,                    //sensor type and it should be correct
382         .id_i2c                         = ACCEL_ID_MMA845X,                             //i2c id number
383         .read_reg                       = MMA8452_REG_X_OUT_MSB,                //read data
384         .read_len                       = 6,                                                    //data length
385         .id_reg                         = SENSOR_UNKNOW_DATA,                   //read device id from this register
386         .id_data                        = SENSOR_UNKNOW_DATA,                   //device id
387         .precision                      = MMA8452_PRECISION,                    //12 bit
388         .ctrl_reg                       = MMA8452_REG_CTRL_REG1,                //enable or disable     
389         .int_status_reg                 = MMA8452_REG_INTSRC,                   //intterupt status register
390         .range                          = {-MMA845X_RANGE,MMA845X_RANGE},       //range
391         .trig                           = IRQF_TRIGGER_LOW|IRQF_ONESHOT,                
392         .active                         = sensor_active,        
393         .init                           = sensor_init,
394         .report                         = sensor_report_value,
395 };
396
397 /****************operate according to sensor chip:end************/
398
399 //function name should not be changed
400 static struct sensor_operate *gsensor_get_ops(void)
401 {
402         return &gsensor_mma8452_ops;
403 }
404
405
406 static int __init gsensor_mma8452_init(void)
407 {
408         struct sensor_operate *ops = gsensor_get_ops();
409         int result = 0;
410         int type = ops->type;
411         result = sensor_register_slave(type, NULL, NULL, gsensor_get_ops);      
412         return result;
413 }
414
415 static void __exit gsensor_mma8452_exit(void)
416 {
417         struct sensor_operate *ops = gsensor_get_ops();
418         int type = ops->type;
419         sensor_unregister_slave(type, NULL, NULL, gsensor_get_ops);
420 }
421
422
423 module_init(gsensor_mma8452_init);
424 module_exit(gsensor_mma8452_exit);
425
426
427