phonepad: update the headset driver from huawei project, make some code in
[firefly-linux-kernel-4.4.55.git] / drivers / headset_observe / rk_headset_irq_hook_adc.c
1 /* arch/arm/mach-rockchip/rk28_headset.c
2  *
3  * Copyright (C) 2009 Rockchip Corporation.
4  *
5  * This software is licensed under the terms of the GNU General Public
6  * License version 2, as published by the Free Software Foundation, and
7  * may be copied, distributed, and modified under those terms.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  */
15
16 #include <linux/module.h>
17 #include <linux/sysdev.h>
18 #include <linux/device.h>
19 #include <linux/fs.h>
20 #include <linux/interrupt.h>
21 #include <linux/workqueue.h>
22 #include <linux/irq.h>
23 #include <linux/delay.h>
24 #include <linux/types.h>
25 #include <linux/input.h>
26 #include <linux/platform_device.h>
27 #include <linux/mutex.h>
28 #include <linux/errno.h>
29 #include <linux/err.h>
30 #include <linux/hrtimer.h>
31 #include <linux/switch.h>
32 #include <linux/input.h>
33 #include <linux/debugfs.h>
34 #include <linux/wakelock.h>
35 #include <asm/gpio.h>
36 #include <asm/atomic.h>
37 #include <asm/mach-types.h>
38 #include "rk_headset.h"
39 #include <linux/earlysuspend.h>
40 #include <linux/gpio.h>
41 #include <mach/board.h>
42 #include <linux/slab.h>
43 #include <linux/adc.h>
44
45 /* Debug */
46 #if 0
47 #define DBG(x...) printk(x)
48 #else
49 #define DBG(x...) do { } while (0)
50 #endif
51
52 #define HOOK_ADC_SAMPLE_TIME    100
53 #define HOOK_LEVEL_HIGH                 600             //1V*1024/2.5
54 #define HOOK_LEVEL_LOW                  204             //0.5V*1024/2.5
55 #define HOOK_DEFAULT_VAL                1024    
56
57 #define BIT_HEADSET             (1 << 0)
58 #define BIT_HEADSET_NO_MIC      (1 << 1)
59
60 #define HEADSET 0
61 #define HOOK 1
62
63 #define HEADSET_IN 1
64 #define HEADSET_OUT 0
65 #define HOOK_DOWN 1
66 #define HOOK_UP 0
67 #define enable 1
68 #define disable 0
69
70 #define HEADSET_TIMER 1
71 #define HOOK_TIMER 2
72
73 #define WAIT 2
74 #define BUSY 1
75 #define IDLE 0
76
77 #ifdef CONFIG_SND_SOC_WM8994
78 extern int wm8994_headset_mic_detect(bool headset_status);
79 #endif
80
81 #ifdef CONFIG_SND_SOC_RT3261
82 extern int rt3261_headset_mic_detect(int jack_insert);
83 #endif
84
85 /* headset private data */
86 struct headset_priv {
87         struct input_dev *input_dev;
88         struct rk_headset_pdata *pdata;
89         unsigned int headset_status:1;
90         unsigned int hook_status:1;
91         int isMic;
92         unsigned int heatset_irq_working;// headset interrupt working will not check hook key   
93         int cur_headset_status; 
94         
95         unsigned int irq[2];
96         unsigned int irq_type[2];
97         struct delayed_work h_delayed_work[2];
98         struct switch_dev sdev;
99         struct mutex mutex_lock[2];     
100         struct timer_list headset_timer;
101         unsigned char *keycodes;
102         struct adc_client *client;
103         struct timer_list hook_timer;
104         unsigned int hook_time;//ms
105 };
106 static struct headset_priv *headset_info;
107
108 int Headset_isMic(void)
109 {
110         return headset_info->isMic;
111 }
112 EXPORT_SYMBOL_GPL(Headset_isMic);
113
114 //1
115 static irqreturn_t headset_interrupt(int irq, void *dev_id)
116 {
117         struct rk_headset_pdata *pdata = headset_info->pdata;
118         static unsigned int old_status = 0;
119         int i,level = 0;        
120         int adc_value = 0;
121         if(headset_info->heatset_irq_working == BUSY || headset_info->heatset_irq_working == WAIT)
122                 return IRQ_HANDLED;
123         DBG("In the headset_interrupt for read headset level\n");               
124         headset_info->heatset_irq_working = BUSY;
125         for(i=0; i<3; i++)
126         {
127                 level = gpio_get_value(pdata->Headset_gpio);
128                 if(level < 0)
129                 {
130                         printk("%s:get pin level again,pin=%d,i=%d\n",__FUNCTION__,pdata->Headset_gpio,i);
131                         msleep(1);
132                         continue;
133                 }
134                 else
135                 break;
136         }
137         if(level < 0)
138         {
139                 printk("%s:get pin level  err!\n",__FUNCTION__);
140                 goto out;
141         }
142
143         old_status = headset_info->headset_status;
144         switch(pdata->headset_in_type)
145         {
146         case HEADSET_IN_HIGH:
147                 if(level > 0)
148                         headset_info->headset_status = HEADSET_IN;
149                 else if(level == 0)
150                         headset_info->headset_status = HEADSET_OUT;     
151                 break;
152         case HEADSET_IN_LOW:
153                 if(level == 0)
154                         headset_info->headset_status = HEADSET_IN;
155                 else if(level > 0)
156                         headset_info->headset_status = HEADSET_OUT;             
157                 break;                  
158         default:
159                 DBG("---- ERROR: on headset headset_in_type error -----\n");
160                 break;                  
161         }
162         if(old_status == headset_info->headset_status)
163         {
164                 DBG("Read Headset IO level old status == now status\n");
165                 goto out;
166         }
167
168         DBG("(headset in is %s)headset status is %s\n",
169                 pdata->headset_in_type?"high level":"low level",
170                 headset_info->headset_status?"in":"out");
171         if(headset_info->headset_status == HEADSET_IN)
172         {
173                 #if 0
174                 while(1)
175                 {
176                         if(adc_sync_read(headset_info->client) > HOOK_DEFAULT_VAL
177                          || adc_sync_read(headset_info->client) < 0)
178                         {
179                                 printk("headset is showly inside\n");
180                         }
181                         else
182                                 break;
183                         msleep(50);
184                         
185                         if(pdata->headset_in_type == HEADSET_IN_HIGH)
186                                 old_status = headset_info->headset_status = gpio_get_value(pdata->Headset_gpio)?HEADSET_IN:HEADSET_OUT;
187                         else
188                                 old_status = headset_info->headset_status = gpio_get_value(pdata->Headset_gpio)?HEADSET_OUT:HEADSET_IN;
189                         if(headset_info->headset_status == HEADSET_OUT)
190                                 goto out1;
191                         msleep(5);      
192                 }
193                 #endif
194                 if(pdata->Hook_adc_chn>=0 && 3>=pdata->Hook_adc_chn)
195                 {
196                 // wait for find Hook key
197                         //#ifdef CONFIG_SND_SOC_RT5625
198                         CHECK_AGAIN:
199                         //headset_info->isMic = rt5625_headset_mic_detect(true);
200                         #ifdef CONFIG_SND_SOC_WM8994
201                         wm8994_headset_mic_detect(true);
202                         #endif
203                         #ifdef CONFIG_SND_SOC_RT3261
204                         rt3261_headset_mic_detect(true);
205                         #endif
206                         //mdelay(400);
207                         adc_value = adc_sync_read(headset_info->client);
208                         if(adc_value >= 0 && adc_value < HOOK_LEVEL_LOW)
209                         {
210                                 headset_info->isMic= 0;//No microphone
211                                 #ifdef CONFIG_SND_SOC_WM8994
212                                 wm8994_headset_mic_detect(false);
213                                 #endif
214                                 #ifdef CONFIG_SND_SOC_RT3261
215                                 rt3261_headset_mic_detect(false);
216                                 #endif
217                                 printk("headset->isMic = %d\n",headset_info->isMic);            
218                         }       
219                         else if(adc_value >= HOOK_LEVEL_HIGH)   
220                         {       
221                                 headset_info->isMic = 1;//have mic
222                                 printk("headset->isMic = %d\n",headset_info->isMic);            
223                         }
224                         if(headset_info->isMic < 0)     
225                         {
226                                 printk("codec is error\n");
227                                 headset_info->heatset_irq_working = WAIT;
228                                 if(pdata->headset_in_type == HEADSET_IN_HIGH)
229                                         irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_LOW|IRQF_ONESHOT);
230                                 else
231                                         irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_HIGH|IRQF_ONESHOT);
232                                 schedule_delayed_work(&headset_info->h_delayed_work[HEADSET], msecs_to_jiffies(0));     
233                                 return IRQ_HANDLED;
234                         }
235                         //adc_value = adc_sync_read(headset_info->client);
236                         printk("headset adc value = %d\n",adc_value);
237                         if(headset_info->isMic) {
238                                 if(adc_value > HOOK_DEFAULT_VAL || adc_value < HOOK_LEVEL_HIGH)
239                                         goto CHECK_AGAIN;
240                                 mod_timer(&headset_info->hook_timer, jiffies + msecs_to_jiffies(1000));
241                         }       
242                         //#endif                
243                         headset_info->cur_headset_status = headset_info->isMic ? BIT_HEADSET:BIT_HEADSET_NO_MIC;
244                 }
245                 else
246                 {
247                         headset_info->isMic= 0;//No microphone
248                         headset_info->cur_headset_status = BIT_HEADSET_NO_MIC;
249                 }
250                 printk("headset->isMic = %d\n",headset_info->isMic);            
251                 if(pdata->headset_in_type == HEADSET_IN_HIGH)
252                         irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_FALLING);
253                 else
254                         irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_RISING);
255         }
256         else if(headset_info->headset_status == HEADSET_OUT)
257         {
258                 headset_info->cur_headset_status = ~(BIT_HEADSET|BIT_HEADSET_NO_MIC);
259                 del_timer(&headset_info->hook_timer);
260                 if(headset_info->isMic)
261                 {
262                         headset_info->hook_status = HOOK_UP;
263                         #ifdef CONFIG_SND_SOC_WM8994
264                         //rt5625_headset_mic_detect(false);
265                         wm8994_headset_mic_detect(false);
266                         #endif
267                         #ifdef CONFIG_SND_SOC_RT3261
268                         rt3261_headset_mic_detect(false);
269                         #endif
270                 }       
271                 if(pdata->headset_in_type == HEADSET_IN_HIGH)
272                         irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_RISING);
273                 else
274                         irq_set_irq_type(headset_info->irq[HEADSET],IRQF_TRIGGER_FALLING);                      
275         }       
276
277         rk28_send_wakeup_key();                 
278         switch_set_state(&headset_info->sdev, headset_info->cur_headset_status);        
279         DBG("headset notice android headset status = %d\n",headset_info->cur_headset_status);   
280
281 //      schedule_delayed_work(&headset_info->h_delayed_work[HEADSET], msecs_to_jiffies(0));
282 out:
283         headset_info->heatset_irq_working = IDLE;
284         return IRQ_HANDLED;
285 }
286
287 static int headset_change_irqtype(int type,unsigned int irq_type)
288 {
289         int ret = 0;
290         free_irq(headset_info->irq[type],NULL);
291
292         DBG("%s: type is %s irqtype is %s\n",__FUNCTION__,      type?"hook":"headset",(irq_type == IRQF_TRIGGER_RISING)?"RISING":"FALLING");
293 //      DBG("%s: type is %s irqtype is %s\n",__FUNCTION__,      type?"hook":"headset",(irq_type == IRQF_TRIGGER_LOW)?"LOW":"HIGH");
294         switch(type)
295         {
296         case HEADSET:
297                 ret = request_threaded_irq(headset_info->irq[type],NULL, headset_interrupt, irq_type, "headset_input", NULL);
298                 if (ret<0) 
299                         DBG("headset_change_irqtype: request irq failed\n");            
300                 break;
301         default:
302                 ret = -1;
303                 break;
304         }
305         return ret;
306 }
307 //2
308 static void headsetobserve_work(struct work_struct *work)
309 {
310         struct rk_headset_pdata *pdata = headset_info->pdata;
311         DBG("In the headsetobserve_work headset_status is %s\n",headset_info->headset_status?"in":"out");
312
313         if(headset_info->heatset_irq_working == WAIT && headset_info->headset_status == HEADSET_IN)
314         {
315                 printk("wait for codec\n");
316                 headset_info->heatset_irq_working = IDLE;
317                 headset_info->headset_status = HEADSET_OUT;     
318                 
319                 free_irq(headset_info->irq[HEADSET],NULL);      
320                 msleep(100);
321                 if(pdata->headset_in_type == HEADSET_IN_HIGH)
322                         headset_info->irq_type[HEADSET] = IRQF_TRIGGER_HIGH|IRQF_ONESHOT;
323                 else
324                         headset_info->irq_type[HEADSET] = IRQF_TRIGGER_LOW|IRQF_ONESHOT;
325                 if(request_threaded_irq(headset_info->irq[HEADSET], NULL,headset_interrupt, headset_info->irq_type[HEADSET], "headset_input", NULL) < 0)
326                         printk("headset request_threaded_irq error\n");
327                 return; 
328         }
329 /*      
330         if(pdata->headset_in_type == HEADSET_IN_HIGH && headset_info->headset_status == HEADSET_IN)
331                 headset_change_irqtype(HEADSET,IRQF_TRIGGER_FALLING);
332         else if(pdata->headset_in_type == HEADSET_IN_LOW && headset_info->headset_status == HEADSET_IN)
333                 headset_change_irqtype(HEADSET,IRQF_TRIGGER_RISING);
334
335         if(pdata->headset_in_type == HEADSET_IN_HIGH && headset_info->headset_status == HEADSET_OUT)
336                 headset_change_irqtype(HEADSET,IRQF_TRIGGER_RISING);
337         else if(pdata->headset_in_type == HEADSET_IN_LOW && headset_info->headset_status == HEADSET_OUT)
338                 headset_change_irqtype(HEADSET,IRQF_TRIGGER_FALLING);
339 */              
340 }
341 //4
342 static void hook_adc_callback(struct adc_client *client, void *client_param, int result)
343 {
344         int level = result;
345         struct headset_priv *headset = (struct headset_priv *)client_param;
346         struct rk_headset_pdata *pdata = headset->pdata;
347         static unsigned int old_status = HOOK_UP;
348
349         DBG("hook_adc_callback read adc value: %d\n",level);
350
351         if(level < 0)
352         {
353                 printk("%s:get adc level err = %d!\n",__FUNCTION__,level);
354                 return;
355         }
356
357         if(headset->headset_status == HEADSET_OUT
358                 || headset->heatset_irq_working == BUSY
359                 || headset->heatset_irq_working == WAIT
360                 || pdata->headset_in_type?gpio_get_value(pdata->Headset_gpio) == 0:gpio_get_value(pdata->Headset_gpio) > 0)
361         {
362                 DBG("Headset is out or waiting for headset is in or out,after same time check HOOK key\n");
363                 return;
364         }       
365         
366         old_status = headset->hook_status;
367         if(level < HOOK_LEVEL_LOW && level >= 0)        
368                 headset->hook_status = HOOK_DOWN;
369         else if(level > HOOK_LEVEL_HIGH && level < HOOK_DEFAULT_VAL)
370                 headset->hook_status = HOOK_UP;
371         else{
372                 DBG("hook_adc_callback read adc value.........outside showly....: %d\n",level);
373                 del_timer(&headset->hook_timer);
374                 mod_timer(&headset->hook_timer, jiffies + msecs_to_jiffies(500));
375                 return;
376         }
377         
378         if(old_status == headset->hook_status)
379         {
380         //      DBG("Hook adc read old_status == headset->hook_status hook_time = %d\n",headset->hook_time);
381                 return;
382         }       
383         
384         DBG("HOOK status is %s , adc value = %d hook_time = %d\n",headset->hook_status?"down":"up",level,headset->hook_time);   
385         if(headset->headset_status == HEADSET_OUT
386                 || headset->heatset_irq_working == BUSY
387                 || headset->heatset_irq_working == WAIT
388                 || (pdata->headset_in_type?gpio_get_value(pdata->Headset_gpio) == 0:gpio_get_value(pdata->Headset_gpio) > 0))
389                 DBG("headset is out,HOOK status must discard\n");
390         else
391         {
392                 if(headset->hook_status==HOOK_DOWN)
393                 DBG("hook_adc_callback read adc ------------HOOK_DOWN\n");
394                 else
395                 DBG("hook_adc_callback read adc ------------HOOK_UP\n");
396                 input_report_key(headset->input_dev,pdata->hook_key_code,headset->hook_status);
397                 input_sync(headset->input_dev);
398         }       
399 }
400 //3
401 static void hook_timer_callback(unsigned long arg)
402 {
403         struct headset_priv *headset = (struct headset_priv *)(arg);
404 //      DBG("hook_timer_callback\n");
405         if(headset->headset_status == HEADSET_OUT
406                 || headset->heatset_irq_working == BUSY
407                 || headset->heatset_irq_working == WAIT)
408                 return;
409         adc_async_read(headset->client);
410         mod_timer(&headset->hook_timer, jiffies + msecs_to_jiffies(headset->hook_time));
411 }
412
413 static ssize_t h2w_print_name(struct switch_dev *sdev, char *buf)
414 {
415         return sprintf(buf, "Headset\n");
416 }
417
418 #ifdef CONFIG_HAS_EARLYSUSPEND
419 static void headset_early_resume(struct early_suspend *h)
420 {
421         schedule_delayed_work(&headset_info->h_delayed_work[HEADSET], msecs_to_jiffies(10));
422         //DBG(">>>>>headset_early_resume\n");
423 }
424
425 static struct early_suspend hs_early_suspend;
426 #endif
427
428 static int rk_Hskey_open(struct input_dev *dev)
429 {
430         //struct rk28_adckey *adckey = input_get_drvdata(dev);
431 //      DBG("===========rk_Hskey_open===========\n");
432         return 0;
433 }
434
435 static void rk_Hskey_close(struct input_dev *dev)
436 {
437 //      DBG("===========rk_Hskey_close===========\n");
438 //      struct rk28_adckey *adckey = input_get_drvdata(dev);
439
440 }
441
442 static int rockchip_headsetobserve_probe(struct platform_device *pdev)
443 {
444         int ret;
445         struct headset_priv *headset;
446         struct rk_headset_pdata *pdata;
447
448         headset = kzalloc(sizeof(struct headset_priv), GFP_KERNEL);
449         if (headset == NULL) {
450                 dev_err(&pdev->dev, "failed to allocate driver data\n");
451                 return -ENOMEM;
452         }
453         headset_info = headset;
454         headset->pdata = pdev->dev.platform_data;
455         pdata = headset->pdata;
456         headset->headset_status = HEADSET_OUT;
457         headset->heatset_irq_working = IDLE;
458         headset->hook_status = HOOK_UP;
459         headset->hook_time = HOOK_ADC_SAMPLE_TIME;
460         headset->cur_headset_status = 0;
461         headset->sdev.name = "h2w";
462         headset->sdev.print_name = h2w_print_name;
463         ret = switch_dev_register(&headset->sdev);
464         if (ret < 0)
465                 goto failed_free;
466         
467 //      mutex_init(&headset->mutex_lock[HEADSET]);
468 //      mutex_init(&headset->mutex_lock[HOOK]);
469         
470         INIT_DELAYED_WORK(&headset->h_delayed_work[HEADSET], headsetobserve_work);
471
472         headset->isMic = 0;
473 //------------------------------------------------------------------            
474         // Create and register the input driver. 
475         headset->input_dev = input_allocate_device();
476         if (!headset->input_dev) {
477                 dev_err(&pdev->dev, "failed to allocate input device\n");
478                 ret = -ENOMEM;
479                 goto failed_free;
480         }       
481         headset->input_dev->name = pdev->name;
482         headset->input_dev->open = rk_Hskey_open;
483         headset->input_dev->close = rk_Hskey_close;
484         headset->input_dev->dev.parent = &pdev->dev;
485         //input_dev->phys = KEY_PHYS_NAME;
486         headset->input_dev->id.vendor = 0x0001;
487         headset->input_dev->id.product = 0x0001;
488         headset->input_dev->id.version = 0x0100;
489         // Register the input device 
490         ret = input_register_device(headset->input_dev);
491         if (ret) {
492                 dev_err(&pdev->dev, "failed to register input device\n");
493                 goto failed_free_dev;
494         }
495
496         input_set_capability(headset->input_dev, EV_KEY, pdata->hook_key_code);
497 //------------------------------------------------------------------
498         if (pdata->Headset_gpio) {
499                 ret = pdata->headset_io_init(pdata->Headset_gpio, pdata->headset_gpio_info.iomux_name, pdata->headset_gpio_info.iomux_mode);
500                 if (ret) 
501                         goto failed_free;
502
503                 headset->irq[HEADSET] = gpio_to_irq(pdata->Headset_gpio);
504
505                 if(pdata->headset_in_type == HEADSET_IN_HIGH)
506                         headset->irq_type[HEADSET] = IRQF_TRIGGER_HIGH|IRQF_ONESHOT;
507                 else
508                         headset->irq_type[HEADSET] = IRQF_TRIGGER_LOW|IRQF_ONESHOT;
509                 ret = request_threaded_irq(headset->irq[HEADSET], NULL,headset_interrupt, headset->irq_type[HEADSET], "headset_input", NULL);
510                 if (ret) 
511                         goto failed_free;
512                 enable_irq_wake(headset->irq[HEADSET]);
513         }
514         else
515                 goto failed_free;
516 //------------------------------------------------------------------
517         if(pdata->Hook_adc_chn>=0 && 3>=pdata->Hook_adc_chn)
518         {
519                 headset->client = adc_register(pdata->Hook_adc_chn, hook_adc_callback, (void *)headset);
520                 if(!headset->client) {
521                         printk("hook adc register error\n");
522                         ret = -EINVAL;
523                         goto failed_free;
524                 }
525                 setup_timer(&headset->hook_timer,hook_timer_callback, (unsigned long)headset);  
526                 printk("headset adc default value = %d\n",adc_sync_read(headset->client));
527         }
528         
529 #ifdef CONFIG_HAS_EARLYSUSPEND
530         hs_early_suspend.suspend = NULL;
531         hs_early_suspend.resume = headset_early_resume;
532         hs_early_suspend.level = ~0x0;
533         register_early_suspend(&hs_early_suspend);
534 #endif
535
536         return 0;       
537         
538 failed_free_dev:
539         platform_set_drvdata(pdev, NULL);
540         input_free_device(headset->input_dev);
541 failed_free:
542         dev_err(&pdev->dev, "failed to headset probe\n");
543         kfree(headset);
544         return ret;
545 }
546
547 static int rockchip_headsetobserve_suspend(struct platform_device *pdev, pm_message_t state)
548 {
549         DBG("%s----%d\n",__FUNCTION__,__LINE__);
550 //      disable_irq(headset_info->irq[HEADSET]);
551         del_timer(&headset_info->hook_timer);
552         return 0;
553 }
554
555 static int rockchip_headsetobserve_resume(struct platform_device *pdev)
556 {
557         DBG("%s----%d\n",__FUNCTION__,__LINE__);        
558 //      enable_irq(headset_info->irq[HEADSET]);
559         if(headset_info->isMic)
560                 mod_timer(&headset_info->hook_timer, jiffies + msecs_to_jiffies(1500)); 
561         return 0;
562 }
563
564 static struct platform_driver rockchip_headsetobserve_driver = {
565         .probe  = rockchip_headsetobserve_probe,
566         .resume =       rockchip_headsetobserve_resume, 
567         .suspend =      rockchip_headsetobserve_suspend,        
568         .driver = {
569                 .name   = "rk_headsetdet",
570                 .owner  = THIS_MODULE,
571         },
572 };
573
574 static int __init rockchip_headsetobserve_init(void)
575 {
576         platform_driver_register(&rockchip_headsetobserve_driver);
577         return 0;
578 }
579 late_initcall(rockchip_headsetobserve_init);
580 MODULE_DESCRIPTION("Rockchip Headset Driver");
581 MODULE_LICENSE("GPL");
582