1 /* arch/arm/mach-rockchip/rk28_headset.c
3 * Copyright (C) 2009 Rockchip Corporation.
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.
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.
16 #include <linux/module.h>
17 #include <linux/sysdev.h>
18 #include <linux/device.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>
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>
47 #define DBG(x...) printk(x)
49 #define DBG(x...) do { } while (0)
52 #define HOOK_ADC_SAMPLE_TIME 700
53 #define HOOK_LEVEL_HIGH 409 //1V*1024/2.5
54 #define HOOK_LEVEL_LOW 204 //0.5V*1024/2.5
56 #define BIT_HEADSET (1 << 0)
57 #define BIT_HEADSET_NO_MIC (1 << 1)
69 #define HEADSET_TIMER 1
72 #ifdef CONFIG_SND_SOC_WM8994
73 extern int wm8994_set_status(void);
76 /* headset private data */
78 struct input_dev *input_dev;
79 struct rk_headset_pdata *pdata;
80 unsigned int headset_status:1;
81 unsigned int hook_status:1;
83 unsigned int isHook_irq:1;
84 int cur_headset_status;
87 unsigned int irq_type[2];
88 struct delayed_work h_delayed_work[2];
89 struct switch_dev sdev;
90 struct mutex mutex_lock[2];
91 struct timer_list headset_timer;
92 unsigned char *keycodes;
93 struct adc_client *client;
94 struct timer_list hook_timer;
95 int adc_callback_status;
97 static struct headset_priv *headset_info;
99 int Headset_isMic(void)
101 return headset_info->isMic;
103 EXPORT_SYMBOL_GPL(Headset_isMic);
105 static irqreturn_t headset_interrupt(int irq, void *dev_id)
107 DBG("---headset_interrupt---\n");
108 schedule_delayed_work(&headset_info->h_delayed_work[HEADSET], msecs_to_jiffies(50));
112 static int headset_change_irqtype(int type,unsigned int irq_type)
115 DBG("--------%s----------\n",__FUNCTION__);
116 free_irq(headset_info->irq[type],NULL);
121 ret = request_irq(headset_info->irq[type], headset_interrupt, irq_type, "headset_hook", NULL);
130 DBG("headset_change_irqtype: request irq failed\n");
136 static void headsetobserve_work(struct work_struct *work)
139 struct rk_headset_pdata *pdata = headset_info->pdata;
140 static unsigned int old_status = 0;
141 DBG("---headsetobserve_work---\n");
142 mutex_lock(&headset_info->mutex_lock[HEADSET]);
146 level = gpio_get_value(pdata->Headset_gpio);
149 printk("%s:get pin level again,pin=%d,i=%d\n",__FUNCTION__,pdata->Headset_gpio,i);
158 printk("%s:get pin level err!\n",__FUNCTION__);
162 old_status = headset_info->headset_status;
163 switch(pdata->headset_in_type)
165 case HEADSET_IN_HIGH:
167 headset_info->headset_status = HEADSET_IN;
169 headset_info->headset_status = HEADSET_OUT;
173 headset_info->headset_status = HEADSET_IN;
175 headset_info->headset_status = HEADSET_OUT;
178 DBG("---- ERROR: on headset headset_in_type error -----\n");
181 if(old_status == headset_info->headset_status)
183 DBG("old_status == headset_info->headset_status\n");
187 switch(pdata->headset_in_type)
189 case HEADSET_IN_HIGH:
192 DBG("--- HEADSET_IN_HIGH headset in HIGH---\n");
193 headset_info->cur_headset_status = BIT_HEADSET_NO_MIC;
194 headset_change_irqtype(HEADSET,IRQF_TRIGGER_FALLING);//
196 del_timer(&headset_info->headset_timer);//Start the timer, wait for switch to the headphone channel
197 // headset_info->headset_timer.expires = jiffies + 500;
198 headset_info->headset_timer.expires = jiffies + 10;
199 add_timer(&headset_info->headset_timer);
203 DBG("---HEADSET_IN_HIGH headset out HIGH---\n");
205 del_timer(&headset_info->hook_timer);
206 headset_info->cur_headset_status = ~(BIT_HEADSET|BIT_HEADSET_NO_MIC);
207 headset_change_irqtype(HEADSET,IRQF_TRIGGER_RISING);//
208 rk28_send_wakeup_key();
209 switch_set_state(&headset_info->sdev, headset_info->cur_headset_status);
210 DBG("headset_info->cur_headset_status = %d\n",headset_info->cur_headset_status);
216 DBG("---HEADSET_IN_LOW headset in LOW ---\n");
217 headset_info->cur_headset_status = BIT_HEADSET_NO_MIC;
218 headset_change_irqtype(HEADSET,IRQF_TRIGGER_RISING);//
220 del_timer(&headset_info->headset_timer);//Start the timer, wait for switch to the headphone channel
221 // headset_info->headset_timer.expires = jiffies + 500;
222 headset_info->headset_timer.expires = jiffies + 10;
223 add_timer(&headset_info->headset_timer);
227 DBG("---HEADSET_IN_LOW headset out LOW ---\n");
229 del_timer(&headset_info->hook_timer);
230 headset_info->cur_headset_status = ~(BIT_HEADSET|BIT_HEADSET_NO_MIC);
231 headset_change_irqtype(HEADSET,IRQF_TRIGGER_FALLING);//
232 rk28_send_wakeup_key();
233 switch_set_state(&headset_info->sdev, headset_info->cur_headset_status);
234 DBG("headset_info->cur_headset_status = %d\n",headset_info->cur_headset_status);
238 DBG("---- ERROR: on headset headset_in_type error -----\n");
244 mutex_unlock(&headset_info->mutex_lock[HEADSET]);
247 static void hook_adc_callback(struct adc_client *client, void *client_param, int result)
250 struct headset_priv *headset = (struct headset_priv *)client_param;
251 struct rk_headset_pdata *pdata = headset_info->pdata;
252 static unsigned int old_status = HOOK_UP;
254 DBG("---hook_adc_callback---, result = %d, flag = %d\n", result, headset->adc_callback_status);
260 printk("%s:get adc level err!\n",__FUNCTION__);
264 switch(headset->adc_callback_status)
269 if(level >= 0 && level < HOOK_LEVEL_LOW)
271 headset->isMic= 0;//No microphone
272 headset_info->cur_headset_status = BIT_HEADSET_NO_MIC;
273 printk("headset->isMic = %d\n",headset->isMic);
275 else if(level >= HOOK_LEVEL_HIGH)
277 headset->isMic = 1;//have mic
278 DBG("enable headset_hook irq\n");
279 headset_info->cur_headset_status = BIT_HEADSET;
280 mod_timer(&headset_info->hook_timer, jiffies + msecs_to_jiffies(HOOK_ADC_SAMPLE_TIME));
281 printk("headset->isMic = %d\n",headset->isMic);
284 rk28_send_wakeup_key();
285 switch_set_state(&headset_info->sdev, headset_info->cur_headset_status);
286 DBG("headset_info->cur_headset_status = %d\n",headset_info->cur_headset_status);
290 mutex_lock(&headset_info->mutex_lock[HOOK]);
291 if(headset_info->headset_status == HEADSET_OUT)
293 DBG("Headset is out\n");
296 #ifdef CONFIG_SND_SOC_WM8994
297 if(wm8994_set_status() != 0)
299 DBG("wm8994 is not set on heatset channel or suspend\n");
304 old_status = headset_info->hook_status;
305 if(level >= HOOK_LEVEL_HIGH)
306 headset_info->hook_status = HOOK_UP;
307 else if(level < HOOK_LEVEL_LOW && level >= 0)
308 headset_info->hook_status = HOOK_DOWN;
309 if(old_status == headset_info->hook_status)
311 DBG("old_status == headset_info->hook_status\n");
315 if(level < HOOK_LEVEL_LOW && level >= 0)
317 DBG("---HOOK Down ---\n");
318 //headset_change_irqtype(HOOK,IRQF_TRIGGER_RISING);//
319 input_report_key(headset_info->input_dev,pdata->hook_key_code,headset_info->hook_status);
320 input_sync(headset_info->input_dev);
322 else if(level >= HOOK_LEVEL_HIGH)
324 DBG("---HOOK Up ---\n");
325 //headset_change_irqtype(HOOK,IRQF_TRIGGER_FALLING);//
326 input_report_key(headset_info->input_dev,pdata->hook_key_code,headset_info->hook_status);
327 input_sync(headset_info->input_dev);
329 mutex_unlock(&headset_info->mutex_lock[HOOK]);
332 printk("adc callback flag status error!!! default case\n");
338 mutex_unlock(&headset_info->mutex_lock[HOOK]);
341 static void hook_timer_callback(unsigned long arg)
343 struct headset_priv *headset = (struct headset_priv *)(arg);
344 DBG("hook_timer_callback\n");
345 adc_async_read(headset->client);
346 headset->adc_callback_status = HOOK_TIMER;
347 mod_timer(&headset->hook_timer, jiffies + msecs_to_jiffies(HOOK_ADC_SAMPLE_TIME));
350 static void headset_timer_callback(unsigned long arg)
352 struct headset_priv *headset = (struct headset_priv *)(arg);
353 //struct rk_headset_pdata *pdata = headset->pdata;
356 DBG("headset_timer_callback,headset->headset_status=%d\n",headset->headset_status);
358 if(headset->headset_status == HEADSET_OUT)
360 printk("Headset is out\n");
363 #ifdef CONFIG_SND_SOC_WM8994
364 if(wm8994_set_status() != 0)
366 // printk("wait wm8994 set the MICB2\n");
367 // headset_info->headset_timer.expires = jiffies + 500;
368 headset_info->headset_timer.expires = jiffies + 10;
369 add_timer(&headset_info->headset_timer);
374 adc_async_read(headset->client);
375 headset->adc_callback_status = HEADSET_TIMER;
380 static ssize_t h2w_print_name(struct switch_dev *sdev, char *buf)
382 return sprintf(buf, "Headset\n");
385 #ifdef CONFIG_HAS_EARLYSUSPEND
386 static void headset_early_resume(struct early_suspend *h)
388 schedule_delayed_work(&headset_info->h_delayed_work[HEADSET], msecs_to_jiffies(10));
389 //DBG(">>>>>headset_early_resume\n");
392 static struct early_suspend hs_early_suspend;
395 static int rk_Hskey_open(struct input_dev *dev)
397 //struct rk28_adckey *adckey = input_get_drvdata(dev);
398 // DBG("===========rk_Hskey_open===========\n");
402 static void rk_Hskey_close(struct input_dev *dev)
404 // DBG("===========rk_Hskey_close===========\n");
405 // struct rk28_adckey *adckey = input_get_drvdata(dev);
409 static int rockchip_headsetobserve_probe(struct platform_device *pdev)
412 struct headset_priv *headset;
413 struct rk_headset_pdata *pdata;
415 headset = kzalloc(sizeof(struct headset_priv), GFP_KERNEL);
416 if (headset == NULL) {
417 dev_err(&pdev->dev, "failed to allocate driver data\n");
420 headset->pdata = pdev->dev.platform_data;
421 pdata = headset->pdata;
422 headset->headset_status = HEADSET_OUT;
423 headset->hook_status = HOOK_UP;
424 headset->adc_callback_status = HEADSET_TIMER;
425 headset->cur_headset_status = 0;
426 headset->sdev.name = "h2w";
427 headset->sdev.print_name = h2w_print_name;
428 ret = switch_dev_register(&headset->sdev);
432 mutex_init(&headset->mutex_lock[HEADSET]);
433 mutex_init(&headset->mutex_lock[HOOK]);
435 INIT_DELAYED_WORK(&headset->h_delayed_work[HEADSET], headsetobserve_work);
438 setup_timer(&headset->headset_timer, headset_timer_callback, (unsigned long)headset);
440 //------------------------------------------------------------------
441 if (pdata->Headset_gpio) {
443 ret = pdata->headset_io_init(pdata->Headset_gpio, pdata->headset_gpio_info.iomux_name, pdata->headset_gpio_info.iomux_mode);
447 headset->irq[HEADSET] = gpio_to_irq(pdata->Headset_gpio);
449 if(pdata->headset_in_type == HEADSET_IN_HIGH)
450 headset->irq_type[HEADSET] = IRQF_TRIGGER_RISING;
452 headset->irq_type[HEADSET] = IRQF_TRIGGER_FALLING;
453 ret = request_irq(headset->irq[HEADSET], headset_interrupt, headset->irq_type[HEADSET], "headset_input", NULL);
456 enable_irq_wake(headset->irq[HEADSET]);
460 //------------------------------------------------------------------
462 if(pdata->Hook_adc_chn>=0 && 2>=pdata->Hook_adc_chn)
464 printk("hook adc register\n");
465 headset->client = adc_register(pdata->Hook_adc_chn, hook_adc_callback, (void *)headset);
466 if(!headset->client) {
467 printk("hook adc register error\n");
471 setup_timer(&headset->hook_timer,
472 hook_timer_callback, (unsigned long)headset);
475 //------------------------------------------------------------------
476 // Create and register the input driver.
477 headset->input_dev = input_allocate_device();
478 if (!headset->input_dev) {
479 dev_err(&pdev->dev, "failed to allocate input device\n");
483 headset->input_dev->name = pdev->name;
484 headset->input_dev->open = rk_Hskey_open;
485 headset->input_dev->close = rk_Hskey_close;
486 headset->input_dev->dev.parent = &pdev->dev;
487 //input_dev->phys = KEY_PHYS_NAME;
488 headset->input_dev->id.vendor = 0x0001;
489 headset->input_dev->id.product = 0x0001;
490 headset->input_dev->id.version = 0x0100;
491 // Register the input device
492 ret = input_register_device(headset->input_dev);
494 dev_err(&pdev->dev, "failed to register input device\n");
495 goto failed_free_dev;
499 // headset->input_dev->keycode = headset->keycodes;
500 // headset->input_dev->keycodesize = sizeof(unsigned char);
501 // headset->input_dev->keycodemax = 2;
503 // set_bit(KEY_MEDIA, headset->input_dev->keybit);
504 // clear_bit(0, headset->input_dev->keybit);
505 input_set_capability(headset->input_dev, EV_KEY, pdata->hook_key_code);
506 // input_set_capability(headset->input_dev, EV_SW, SW_HEADPHONE_INSERT);
507 // input_set_capability(headset->input_dev, EV_KEY, KEY_END);
509 // headset->input_dev->evbit[0] = BIT_MASK(EV_KEY);
511 headset_info = headset;
512 schedule_delayed_work(&headset->h_delayed_work[HEADSET], msecs_to_jiffies(500));
514 #ifdef CONFIG_HAS_EARLYSUSPEND
515 hs_early_suspend.suspend = NULL;
516 hs_early_suspend.resume = headset_early_resume;
517 hs_early_suspend.level = ~0x0;
518 register_early_suspend(&hs_early_suspend);
524 platform_set_drvdata(pdev, NULL);
525 input_free_device(headset->input_dev);
527 dev_err(&pdev->dev, "failed to headset probe\n");
532 static int rockchip_headsetobserve_suspend(struct platform_device *pdev, pm_message_t state)
534 DBG("%s----%d\n",__FUNCTION__,__LINE__);
535 disable_irq(headset_info->irq[HEADSET]);
539 static int rockchip_headsetobserve_resume(struct platform_device *pdev)
541 DBG("%s----%d\n",__FUNCTION__,__LINE__);
542 enable_irq(headset_info->irq[HEADSET]);
546 static struct platform_driver rockchip_headsetobserve_driver = {
547 .probe = rockchip_headsetobserve_probe,
548 // .resume = rockchip_headsetobserve_resume,
549 // .suspend = rockchip_headsetobserve_suspend,
551 .name = "rk_headsetdet",
552 .owner = THIS_MODULE,
556 static int __init rockchip_headsetobserve_init(void)
558 platform_driver_register(&rockchip_headsetobserve_driver);
561 module_init(rockchip_headsetobserve_init);
562 MODULE_DESCRIPTION("Rockchip Headset Driver");
563 MODULE_LICENSE("GPL");