e902fc8cd884bf073077781ebcdd6dd571a0d12d
[firefly-linux-kernel-4.4.55.git] / drivers / input / sensors / lsensor / ls_ap321xx.c
1 /* drivers/input/sensors/access/kxtik.c\r
2  *\r
3  * Copyright (C) 2012-2015 ROCKCHIP.\r
4  * Author: luowei <lw@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 #include <linux/interrupt.h>\r
17 #include <linux/i2c.h>\r
18 #include <linux/slab.h>\r
19 #include <linux/irq.h>\r
20 #include <linux/miscdevice.h>\r
21 #include <linux/gpio.h>\r
22 #include <asm/uaccess.h>\r
23 #include <asm/atomic.h>\r
24 #include <linux/delay.h>\r
25 #include <linux/input.h>\r
26 #include <linux/workqueue.h>\r
27 #include <linux/freezer.h>\r
28 #include <mach/gpio.h>\r
29 #include <mach/board.h> \r
30 #ifdef CONFIG_HAS_EARLYSUSPEND\r
31 #include <linux/earlysuspend.h>\r
32 #endif\r
33 #include <linux/sensor-dev.h>\r
34 \r
35 \r
36 #define AP3212B_NUM_CACHABLE_REGS       23
37 #define AP3216C_NUM_CACHABLE_REGS       26\r
38 \r
39 #define AP3212B_RAN_COMMAND     0x10
40 #define AP3212B_RAN_MASK                0x30
41 #define AP3212B_RAN_SHIFT       (4)
42
43 #define AP3212B_MODE_COMMAND    0x00
44 #define AP3212B_MODE_SHIFT      (0)
45 #define AP3212B_MODE_MASK       0x07\r
46 \r
47 #define AP3212B_INT_COMMAND     0x01
48 #define AP3212B_INT_SHIFT       (0)
49 #define AP3212B_INT_MASK                0x03
50 #define AP3212B_INT_PMASK               0x02
51 #define AP3212B_INT_AMASK               0x01
52 \r
53 #define AL3212_ADC_LSB          0x0c
54 #define AL3212_ADC_MSB          0x0d
55 \r
56 #define AP3212B_ALS_LTHL                        0x1a
57 #define AP3212B_ALS_LTHL_SHIFT  (0)
58 #define AP3212B_ALS_LTHL_MASK   0xff
59
60 #define AP3212B_ALS_LTHH                        0x1b
61 #define AP3212B_ALS_LTHH_SHIFT  (0)
62 #define AP3212B_ALS_LTHH_MASK   0xff
63
64 #define AP3212B_ALS_HTHL                        0x1c
65 #define AP3212B_ALS_HTHL_SHIFT  (0)
66 #define AP3212B_ALS_HTHL_MASK   0xff
67
68 #define AP3212B_ALS_HTHH                        0x1d
69 #define AP3212B_ALS_HTHH_SHIFT  (0)
70 #define AP3212B_ALS_HTHH_MASK   0xff
71 \r
72 static u16 ap321xx_threshole[8] = {28,444,625,888,1778,3555,7222,0xffff};\r
73 \r
74 /*
75  * register access helpers
76  */
77
78 static int __ap321xx_read_reg(struct i2c_client *client,
79                                u32 reg, u8 mask, u8 shift)
80 {
81         u8 val;\r
82 \r
83         val = i2c_smbus_read_byte_data(client, reg);\r
84         return (val & mask) >> shift;\r
85 }
86
87 static int __ap321xx_write_reg(struct i2c_client *client,
88                                 u32 reg, u8 mask, u8 shift, u8 val)
89 {
90         int ret = 0;\r
91         u8 tmp;
92 \r
93         tmp = i2c_smbus_read_byte_data(client, reg);\r
94         tmp &= ~mask;
95         tmp |= val << shift;
96
97         ret = i2c_smbus_write_byte_data(client, reg, tmp);\r
98         \r
99         return ret;\r
100 }
101 \r
102 \r
103 /*
104  * internally used functions
105  */\r
106 /* range */
107 static int ap321xx_set_range(struct i2c_client *client, int range)\r
108 {
109         return __ap321xx_write_reg(client, AP3212B_RAN_COMMAND,
110                 AP3212B_RAN_MASK, AP3212B_RAN_SHIFT, range);;
111 }
112
113
114 /* mode */
115 static int ap321xx_get_mode(struct i2c_client *client)
116 {
117         struct sensor_private_data *sensor =\r
118             (struct sensor_private_data *) i2c_get_clientdata(client);  \r
119         int ret;
120
121         ret = __ap321xx_read_reg(client, sensor->ops->ctrl_reg,\r
122                         AP3212B_MODE_MASK, AP3212B_MODE_SHIFT);
123         return ret;
124 }
125 static int ap321xx_set_mode(struct i2c_client *client, int mode)\r
126 {
127         struct sensor_private_data *sensor =\r
128             (struct sensor_private_data *) i2c_get_clientdata(client);  \r
129         int ret;\r
130
131         ret = __ap321xx_write_reg(client, sensor->ops->ctrl_reg,\r
132                                 AP3212B_MODE_MASK, AP3212B_MODE_SHIFT, mode);
133         return ret;
134 }\r
135 \r
136 static int ap321xx_get_adc_value(struct i2c_client *client)
137 {
138         unsigned int lsb, msb, val;
139         unsigned char index=0;\r
140
141         lsb = i2c_smbus_read_byte_data(client, AL3212_ADC_LSB);\r
142         if (lsb < 0) {
143                 return lsb;
144         }
145
146         msb = i2c_smbus_read_byte_data(client, AL3212_ADC_MSB);\r
147         if (msb < 0)
148                 return msb;
149
150         val = msb << 8 | lsb;\r
151         for(index = 0; index < 7 && val > ap321xx_threshole[index];index++)
152                 ;
153
154         return index;
155 }\r
156 \r
157 /* ALS low threshold */\r
158 static int ap321xx_set_althres(struct i2c_client *client, int val)
159 {
160         int lsb, msb, err;
161         
162         msb = val >> 8;
163         lsb = val & AP3212B_ALS_LTHL_MASK;
164
165         err = __ap321xx_write_reg(client, AP3212B_ALS_LTHL,
166                 AP3212B_ALS_LTHL_MASK, AP3212B_ALS_LTHL_SHIFT, lsb);
167         if (err)
168                 return err;
169
170         err = __ap321xx_write_reg(client, AP3212B_ALS_LTHH,
171                 AP3212B_ALS_LTHH_MASK, AP3212B_ALS_LTHH_SHIFT, msb);
172
173         return err;
174 }
175
176 /* ALS high threshold */\r
177 static int ap321xx_set_ahthres(struct i2c_client *client, int val)
178 {
179         int lsb, msb, err;
180         
181         msb = val >> 8;
182         lsb = val & AP3212B_ALS_HTHL_MASK;
183         
184         err = __ap321xx_write_reg(client, AP3212B_ALS_HTHL,
185                 AP3212B_ALS_HTHL_MASK, AP3212B_ALS_HTHL_SHIFT, lsb);
186         if (err)
187                 return err;
188
189         err = __ap321xx_write_reg(client, AP3212B_ALS_HTHH,
190                 AP3212B_ALS_HTHH_MASK, AP3212B_ALS_HTHH_SHIFT, msb);
191
192         return err;
193 }\r
194 \r
195 static int ap321xx_get_intstat(struct i2c_client *client)
196 {
197         struct sensor_private_data *sensor =\r
198             (struct sensor_private_data *) i2c_get_clientdata(client);  \r
199         int val;
200         
201         val = i2c_smbus_read_byte_data(client, sensor->ops->int_status_reg);\r
202         val &= AP3212B_INT_MASK;
203
204         return val >> AP3212B_INT_SHIFT;
205 }\r
206 \r
207 static int ap321xx_product_detect(struct i2c_client *client)\r
208 {
209         int mid = i2c_smbus_read_byte_data(client, 0x03);
210         int pid = i2c_smbus_read_byte_data(client, 0x04);
211         int rid = i2c_smbus_read_byte_data(client, 0x05);
212
213         if ( mid == 0x01 && pid == 0x01 && 
214             (rid == 0x03 || rid == 0x04) )
215         {
216                 //printk("RevID [%d], ==> DA3212 v1.5~1.8 ...... AP3212B detected\n", rid);\r
217         }\r
218         else if ( (mid == 0x01 && pid == 0x02 && rid == 0x00) || 
219                       (mid == 0x02 && pid == 0x02 && rid == 0x01))
220         {
221                 //printk("RevID [%d], ==> DA3212 v2.0 ...... AP3212C/AP3216C detected\n", rid);\r
222         }\r
223         else
224         {
225                 //printk("MakeID[%d] ProductID[%d] RevID[%d] .... can't detect ... bad reversion!!!\n", mid, pid, rid);\r
226                 return -EIO;
227         }
228 \r
229         return 0;
230 }\r
231 \r
232 static int ap321xx_init_client(struct i2c_client *client)
233 {
234         /* set defaults */\r
235         ap321xx_set_range(client, 0);
236         ap321xx_set_mode(client, 0);
237
238         return 0;
239 }\r
240 \r
241 static int ap321xx_lsensor_enable(struct i2c_client *client)
242 {
243         int ret = 0,mode;
244         
245         mode = ap321xx_get_mode(client);
246         if((mode & 0x01) == 0){
247                 mode |= 0x01;
248                 ret = ap321xx_set_mode(client,mode);
249         }
250         
251         return ret;
252 }
253
254 static int ap321xx_lsensor_disable(struct i2c_client *client)
255 {
256         int ret = 0,mode;
257         
258         mode = ap321xx_get_mode(client);
259         if(mode & 0x01){
260                 mode &= ~0x01;
261                 if(mode == 0x04)
262                         mode = 0;
263                 ret = ap321xx_set_mode(client,mode);
264         }
265         
266         return ret;
267 }\r
268 \r
269 static void ap321xx_change_ls_threshold(struct i2c_client *client)
270 {
271         struct sensor_private_data *sensor =\r
272             (struct sensor_private_data *) i2c_get_clientdata(client);  \r
273         int value;
274
275         value = ap321xx_get_adc_value(client);
276         DBG("ALS lux index: %u\n", value);\r
277         if(value > 0){
278                 ap321xx_set_althres(client,ap321xx_threshole[value-1]);
279                 ap321xx_set_ahthres(client,ap321xx_threshole[value]);
280         }
281         else{
282                 ap321xx_set_althres(client,0);
283                 ap321xx_set_ahthres(client,ap321xx_threshole[value]);
284         }
285         
286         input_report_abs(sensor->input_dev, ABS_MISC, value);\r
287         input_sync(sensor->input_dev);\r
288 }\r
289 \r
290 \r
291 /****************operate according to sensor chip:start************/\r
292 \r
293 static int sensor_active(struct i2c_client *client, int enable, int rate)\r
294 {\r
295         int result = 0;\r
296         \r
297         //register setting according to chip datasheet          \r
298         if (enable){\r
299                 result = ap321xx_lsensor_enable(client);\r
300                 if(!result){\r
301                         msleep(200);\r
302                         ap321xx_change_ls_threshold(client);\r
303                 }\r
304         }\r
305         else\r
306                 result = ap321xx_lsensor_disable(client);\r
307 \r
308         if(result)\r
309                 printk("%s:fail to active sensor\n",__func__);\r
310 \r
311         return result;\r
312 \r
313 }\r
314 \r
315 \r
316 static int sensor_init(struct i2c_client *client)\r
317 {       \r
318         struct sensor_private_data *sensor =\r
319             (struct sensor_private_data *) i2c_get_clientdata(client);  \r
320         int result = 0;\r
321 \r
322         result = ap321xx_product_detect(client);\r
323         if (result)\r
324         {
325                 dev_err(&client->dev, "ret: %d, product version detect failed.\n",result);\r
326                 return result;\r
327         }\r
328 \r
329         /* initialize the AP3212B chip */
330         result = ap321xx_init_client(client);\r
331         if (result)\r
332                 return result;\r
333         \r
334         result = sensor->ops->active(client,0,0);\r
335         if(result)\r
336         {\r
337                 printk("%s:line=%d,error\n",__func__,__LINE__);\r
338                 return result;\r
339         }\r
340         \r
341         sensor->status_cur = SENSOR_OFF;\r
342                 \r
343         return result;\r
344 }\r
345 \r
346 static int sensor_report_value(struct i2c_client *client)\r
347 {\r
348         int result = 0;\r
349         u8 int_stat;\r
350         \r
351         int_stat = ap321xx_get_intstat(client);\r
352         // ALS int
353         if (int_stat & AP3212B_INT_AMASK)\r
354         {
355                 ap321xx_change_ls_threshold(client);\r
356         }
357         \r
358         return result;\r
359 }\r
360 \r
361 struct sensor_operate light_ap321xx_ops = {\r
362         .name                           = "ls_ap321xx",\r
363         .type                           = SENSOR_TYPE_LIGHT,    //sensor type and it should be correct\r
364         .id_i2c                         = LIGHT_ID_AP321XX,     //i2c id number\r
365         .read_reg                       = SENSOR_UNKNOW_DATA,   //read data             //there are two regs, we fix them in code.\r
366         .read_len                       = 1,                    //data length\r
367         .id_reg                         = SENSOR_UNKNOW_DATA,   //read device id from this register   //there are 3 regs, we fix them in code.\r
368         .id_data                        = SENSOR_UNKNOW_DATA,   //device id\r
369         .precision                      = 16,                   //8 bits\r
370         .ctrl_reg                       = AP3212B_MODE_COMMAND,         //enable or disable \r
371         .int_status_reg                 = AP3212B_INT_COMMAND,  //intterupt status register\r
372         .range                          = {100,65535},          //range\r
373         .brightness                                        ={10,255},                          // brightness\r
374         .trig                           = IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED,            \r
375         .active                         = sensor_active,        \r
376         .init                           = sensor_init,\r
377         .report                         = sensor_report_value,\r
378 };\r
379 \r
380 /****************operate according to sensor chip:end************/\r
381 \r
382 //function name should not be changed\r
383 static struct sensor_operate *light_get_ops(void)\r
384 {\r
385         return &light_ap321xx_ops;\r
386 }\r
387 \r
388 \r
389 static int __init light_ap321xx_init(void)\r
390 {\r
391         struct sensor_operate *ops = light_get_ops();\r
392         int result = 0;\r
393         int type = ops->type;\r
394         result = sensor_register_slave(type, NULL, NULL, light_get_ops);\r
395         return result;\r
396 }\r
397 \r
398 static void __exit light_ap321xx_exit(void)\r
399 {\r
400         struct sensor_operate *ops = light_get_ops();\r
401         int type = ops->type;\r
402         sensor_unregister_slave(type, NULL, NULL, light_get_ops);\r
403 }\r
404 \r
405 \r
406 module_init(light_ap321xx_init);\r
407 module_exit(light_ap321xx_exit);\r
408 \r
409 \r