static irqreturn_t gpio_irq_handler(int irq, void *dev_id) { struct hsd_info *hi = (struct hsd_info *) dev_id; int state = gpio_get_value_cansleep(hi->gpio_detect); wake_lock_timeout(&ear_hook_wake_lock, 2 * HZ); HSD_DBG("gpio_irq_handler [%d]", state); if (state == EARJACK_REMOVED) { if (switch_get_state(&hi->sdev) != NO_DEVICE #ifdef HEADSET_REMOVE_ERROR || insert_state_check #endif ){ HSD_DBG("==== LGE headset removing\n"); cancel_delayed_work_sync(&(hi->work_for_insert)); queue_delayed_work(local_fsa8008_workqueue, &(hi->work_for_remove), FSA8008_DETECT_DELAY_MS ); } else { HSD_DBG("err_invalid_state state = %d\n", state); } } else { if (switch_get_state(&hi->sdev) == NO_DEVICE) { HSD_DBG("==== LGE headset inserting\n"); queue_delayed_work(local_fsa8008_workqueue, &(hi->work_for_insert), FSA8008_DETECT_DELAY_MS ); } else { HSD_DBG("err_invalid_state state = %d\n", state); } } return IRQ_HANDLED; }
static void detect_work(struct work_struct *work) { int state; struct hsd_info *hi = container_of(work, struct hsd_info, work); HSD_DBG("detect_work\n"); state = hi->gpio_get_value_func(hi->gpio_detect); if (state == 1) { if (switch_get_state(&hi->sdev) != NO_DEVICE) { HSD_DBG("LGE headset removing\n"); remove_headset(hi); } else { HSD_DBG("err_invalid_state remove state = %d\n", state); } } else { if (switch_get_state(&hi->sdev) == NO_DEVICE) { HSD_DBG("LGE headset inserting\n"); insert_headset(hi); } else { HSD_DBG("err_invalid_state insert state = %d\n", state); } } }
static irqreturn_t button_irq_handler(int irq, void *dev_id) { struct hsd_info *hi = (struct hsd_info *) dev_id; int value; wake_lock_timeout(&ear_hook_wake_lock, 2 * HZ); HSD_DBG("button_irq_handler"); // low:pressed, high:released if( gpio_cansleep(hi->gpio_swd) ) value = gpio_get_value_cansleep(hi->gpio_swd); else value = gpio_get_value(hi->gpio_swd); HSD_DBG("======= hi->gpio_swd : %d =======", value); if (value) queue_delayed_work(local_max1462x_workqueue, &(hi->work_for_key_released), hi->latency_for_key ); else queue_delayed_work(local_max1462x_workqueue, &(hi->work_for_key_pressed), hi->latency_for_key ); return IRQ_HANDLED; }
static void detect_work(struct work_struct *work) { int state; unsigned long irq_flags; local_irq_save(irq_flags); disable_irq(hi->irq); local_irq_restore(irq_flags); state = gpio_get_value(hi->gpio); HSD_DBG("hs:%d\n", state); local_irq_save(irq_flags); enable_irq(hi->irq); local_irq_restore(irq_flags); if (state != 1) { if (switch_get_state(&hi->sdev) == LGE_HEADSET) { HSD_DBG("==== LGE headset removing\n"); remove_headset(); } return; } if (state == 1) { if (switch_get_state(&hi->sdev) == NO_DEVICE) { HSD_DBG("==== LGE headset inserting\n"); insert_headset(); } } else { HSD_ERR("Invalid state\n"); } }
static irqreturn_t gpio_irq_handler(int irq, void *dev_id) { struct hsd_info *hi = (struct hsd_info *) dev_id; int state = gpio_get_value_cansleep(hi->gpio_detect); wake_lock_timeout(&ear_hook_wake_lock, 2 * HZ); HSD_DBG("gpio_irq_handler [%d]", state); if (state == EARJACK_REMOVED) { /* 2012-12-04 Hoseong Kang([email protected]) do not check headset status before setting work queue [START] */ #if 1 HSD_DBG("==== LGE headset removing\n"); cancel_delayed_work_sync(&(hi->work_for_insert)); queue_delayed_work(local_fsa8008_workqueue, &(hi->work_for_remove), FSA8008_DETECT_DELAY_MS ); } else { HSD_DBG("==== LGE headset inserting\n"); queue_delayed_work(local_fsa8008_workqueue, &(hi->work_for_insert), FSA8008_DETECT_DELAY_MS ); #else // origin if (switch_get_state(&hi->sdev) != NO_DEVICE) { HSD_DBG("==== LGE headset removing\n"); cancel_delayed_work_sync(&(hi->work_for_insert)); queue_delayed_work(local_fsa8008_workqueue, &(hi->work_for_remove), FSA8008_DETECT_DELAY_MS ); } else { HSD_DBG("err_invalid_state state = %d\n", state); } } else { if (switch_get_state(&hi->sdev) == NO_DEVICE) {
static void __exit lge_hsd_exit(void) { HSD_DBG("lge_hsd_exit"); #ifdef CONFIG_MAX1462X_USE_LOCAL_WORK_QUEUE if(local_max1462x_workqueue) destroy_workqueue(local_max1462x_workqueue); local_max1462x_workqueue = NULL; #endif platform_driver_unregister(&lge_hsd_driver); HSD_DBG("lge_hsd_exit : wake_lock_destroy"); wake_lock_destroy(&ear_hook_wake_lock); }
static void button_pressed(struct work_struct *work) { struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct hsd_info *hi = container_of(dwork, struct hsd_info, work_for_key_pressed); if (gpio_get_value_cansleep(hi->gpio_key) != BUTTON_PRESSED) { HSD_ERR("button_pressed but actually Fake pressed state!!\n"); return; } if (gpio_get_value_cansleep(hi->gpio_detect) == EARJACK_REMOVED || (switch_get_state(&hi->sdev) != LGE_HEADSET)) { HSD_ERR("button_pressed but ear jack is plugged out already! just ignore the event.\n"); return; } if(atomic_read(&hi->btn_state)) { HSD_ERR("button_pressed but already pressed state!!\n"); return; } hi->gpio_key_cnt += 1; if(hi->gpio_key_cnt < FSA8008_KEY_PRESS_TH_CNT) { queue_delayed_work(local_fsa8008_workqueue, &(hi->work_for_key_pressed), hi->latency_for_key ); return; } HSD_DBG("button_pressed [%d] \n", hi->gpio_key_cnt); atomic_set(&hi->btn_state, 1); input_report_key(hi->input, hi->key_code, 1); input_sync(hi->input); }
static void remove_headset(struct hsd_info *hi) { HSD_DBG("remove_headset\n"); if(atomic_read(&hi->is_3_pole_or_not) == 1) spmi_write(0x80); if(atomic_read(&hi->is_3_pole_or_not) == 0) gpio_direction_output(hi->gpio_mic_en, 0); atomic_set(&hi->is_3_pole_or_not, 1); mutex_lock(&hi->mutex_lock); switch_set_state(&hi->sdev, NO_DEVICE); mutex_unlock(&hi->mutex_lock); if (atomic_read(&hi->irq_key_enabled)) { atomic_set(&hi->irq_key_enabled, FALSE); } if (atomic_read(&hi->btn_state)) #ifdef CONFIG_MAX1462X_USE_LOCAL_WORK_QUEUE queue_delayed_work(local_max1462x_workqueue, &(hi->work_for_key_released), hi->latency_for_key ); #else schedule_delayed_work(&(hi->work_for_key_released), hi->latency_for_key ); #endif atomic_set(&hi->isdetect,FALSE); }
static void remove_headset(struct hsd_info *hi) { HSD_DBG("remove_headset"); gpio_set_value_cansleep(hi->gpio_mic_en, 0); if (hi->set_headset_mic_bias) hi->set_headset_mic_bias(FALSE); atomic_set(&hi->is_3_pole_or_not, 1); mutex_lock(&hi->mutex_lock); switch_set_state(&hi->sdev, NO_DEVICE); mutex_unlock(&hi->mutex_lock); if (atomic_read(&hi->irq_key_enabled)) { unsigned long irq_flags; local_irq_save(irq_flags); disable_irq(hi->irq_key); local_irq_restore(irq_flags); atomic_set(&hi->irq_key_enabled, FALSE); } if (atomic_read(&hi->btn_state)) button_released(hi); }
static void button_released(struct work_struct *work) { struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct hsd_info *hi = container_of(dwork, struct hsd_info, work_for_key_released); if (gpio_get_value_cansleep(hi->gpio_key) != BUTTON_RELEASED) { HSD_ERR("button_released but actually Fake released state!!\n"); return; } if (gpio_get_value_cansleep(hi->gpio_detect) == EARJACK_REMOVED || (switch_get_state(&hi->sdev) != LGE_HEADSET)) { HSD_ERR("button_released but ear jack is plugged out already! just ignore the event.\n"); return; } if(!atomic_read(&hi->btn_state)) { HSD_ERR("button_released but already released state!!\n"); return; } HSD_DBG("button_released \n"); atomic_set(&hi->btn_state, 0); hi->gpio_key_cnt = 0; input_report_key(hi->input, hi->key_code, 0); input_sync(hi->input); }
static int lge_hsd_remove(struct platform_device *pdev) { struct hsd_info *hi = (struct hsd_info *)platform_get_drvdata(pdev); HSD_DBG("lge_hsd_remove"); if (switch_get_state(&hi->sdev)) remove_headset(hi); input_unregister_device(hi->input); switch_dev_unregister(&hi->sdev); free_irq(hi->irq_key, 0); free_irq(hi->irq_detect, 0); gpio_free(hi->gpio_mic_en); gpio_free(hi->gpio_key); gpio_free(hi->gpio_jpole); gpio_free(hi->gpio_detect); mutex_destroy(&hi->mutex_lock); kfree(hi); return 0; }
static void remove_headset(struct hsd_info *hi) { HSD_DBG("remove_headset"); gpio_set_value_cansleep(hi->gpio_mic_en, 0); if (hi->set_headset_mic_bias) hi->set_headset_mic_bias(FALSE); atomic_set(&hi->is_3_pole_or_not, 1); mutex_lock(&hi->mutex_lock); switch_set_state(&hi->sdev, NO_DEVICE); mutex_unlock(&hi->mutex_lock); if (atomic_read(&hi->irq_key_enabled)) { unsigned long irq_flags; local_irq_save(irq_flags); disable_irq(hi->irq_key); local_irq_restore(irq_flags); atomic_set(&hi->irq_key_enabled, FALSE); } if (atomic_read(&hi->btn_state)) #ifdef CONFIG_FSA8008_USE_LOCAL_WORK_QUEUE queue_delayed_work(local_fsa8008_workqueue, &(hi->work_for_key_released), hi->latency_for_key ); #else schedule_delayed_work(&(hi->work_for_key_released), hi->latency_for_key ); #endif }
static void button_pressed(struct work_struct *work) { struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct hsd_info *hi = container_of(dwork, struct hsd_info, work_for_key_pressed); // msleep(1); //if (gpio_get_value_cansleep(hi->gpio_detect)){ if (gpio_get_value_cansleep(hi->gpio_detect) && (switch_get_state(&hi->sdev)== LGE_HEADSET)){ HSD_ERR("button_pressed but ear jack is plugged out already! just ignore the event.\n"); return; } HSD_DBG("button_pressed \n"); atomic_set(&hi->btn_state, 1); input_report_key(hi->input, hi->key_code, 1); #ifdef AT_TEST_GPKD if(start_keylog == '1') hook_keycode = 'H'; #endif input_sync(hi->input); }
static void remove_headset(struct hsd_info *hi) { int has_mic = switch_get_state(&hi->sdev); HSD_DBG("remove_headset\n"); if(atomic_read(&hi->is_3_pole_or_not) == 1) spmi_write(0x80); if(atomic_read(&hi->is_3_pole_or_not) == 0) gpio_direction_output(hi->gpio_mic_en, 0); atomic_set(&hi->is_3_pole_or_not, 1); mutex_lock(&hi->mutex_lock); switch_set_state(&hi->sdev, NO_DEVICE); mutex_unlock(&hi->mutex_lock); input_report_switch(hi->input, SW_HEADPHONE_INSERT, 0); if (has_mic == LGE_HEADSET) input_report_switch(hi->input, SW_MICROPHONE_INSERT, 0); input_sync(hi->input); if (atomic_read(&hi->irq_key_enabled)) { atomic_set(&hi->irq_key_enabled, FALSE); } if (atomic_read(&hi->btn_state)) schedule_delayed_work(&(hi->work_for_key_released_remove), hi->latency_for_key ); atomic_set(&hi->isdetect,FALSE); }
static int lge_hsd_remove(struct platform_device *pdev) { struct hsd_info *hi = (struct hsd_info *)platform_get_drvdata(pdev); HSD_DBG("lge_hsd_remove"); if (switch_get_state(&hi->sdev)) #ifdef CONFIG_LGE_AUDIO_FSA8008_MODIFY queue_delayed_work(local_fsa8008_workqueue, &(hi->work_for_remove), 0 ); #else remove_headset(hi); #endif input_unregister_device(hi->input); switch_dev_unregister(&hi->sdev); free_irq(hi->irq_key, 0); free_irq(hi->irq_detect, 0); gpio_free(hi->gpio_mic_en); gpio_free(hi->gpio_key); gpio_free(hi->gpio_jpole); gpio_free(hi->gpio_detect); mutex_destroy(&hi->mutex_lock); kfree(hi); return 0; }
static irqreturn_t button_irq_handler(int irq, void *dev_id) { struct hsd_info *hi = (struct hsd_info *) dev_id; int value; wake_lock_timeout(&ear_hook_wake_lock, 2 * HZ); HSD_DBG("button_irq_handler"); /* if(gpio_get_value_cansleep(hi->gpio_mic_en) == 0) { HSD_DBG("button press returned"); gpio_set_value_cansleep(hi->gpio_mic_en, 1); return IRQ_HANDLED; } */ value = gpio_get_value_cansleep(hi->gpio_key); #ifdef CONFIG_FSA8008_USE_LOCAL_WORK_QUEUE if (value) queue_delayed_work(local_fsa8008_workqueue, &(hi->work_for_key_pressed), hi->latency_for_key ); else queue_delayed_work(local_fsa8008_workqueue, &(hi->work_for_key_released), hi->latency_for_key ); #else if (value) schedule_delayed_work(&(hi->work_for_key_pressed), hi->latency_for_key ); else schedule_delayed_work(&(hi->work_for_key_released), hi->latency_for_key ); #endif return IRQ_HANDLED; }
static int lge_hsd_remove(struct platform_device *pdev) { struct hsd_info *hi = (struct hsd_info *)platform_get_drvdata(pdev); HSD_DBG("lge_hsd_remove"); if (switch_get_state(&hi->sdev)) remove_headset(hi); input_unregister_device(hi->input); switch_dev_unregister(&hi->sdev); free_irq(hi->irq_key, 0); free_irq(hi->irq_detect, 0); gpio_free(hi->gpio_det); gpio_free(hi->gpio_swd); gpio_free(hi->gpio_mode); //LGE_CHANGE_S 20130710 ilda.jung[Audio] Disable not using GPIO #if !defined(CONFIG_MACH_APQ8064_AWIFI) if( hi->external_ldo_mic_bias > 0 ) gpio_free(hi->external_ldo_mic_bias); #endif //LGE_CHANGE_E 20130710 ilda.jung[Audio] Disable not using GPIO mutex_destroy(&hi->mutex_lock); kfree(hi); return 0; }
static void button_pressed(struct work_struct *work) { struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct hsd_info *hi = container_of(dwork, struct hsd_info, work_for_key_pressed); struct qpnp_vadc_result result; int acc_read_value = 0; int i, rc; struct ear_3button_info_table *table; int table_size = ARRAY_SIZE(max1462x_ear_3button_type_data); if (hi->gpio_get_value_func(hi->gpio_detect) || (atomic_read(&hi->is_3_pole_or_not))) { HSD_ERR("button_pressed but 4 pole ear jack is plugged out already! just ignore the event.\n"); return; } rc = qpnp_vadc_read(switch_vadc, P_MUX6_1_1, &result); if (rc < 0) { if (rc == -ETIMEDOUT) { pr_err("[DEBUG] button_pressed : adc read timeout \n"); } else { pr_err("button_pressed: adc read error - %d\n", rc); } } acc_read_value = (int)result.physical; pr_info("%s: acc_read_value - %d\n", __func__, acc_read_value); for (i = 0; i < table_size; i++) { table = &max1462x_ear_3button_type_data[i]; /* */ if ((acc_read_value <= table->PERMISS_REANGE_MAX) && (acc_read_value >= table->PERMISS_REANGE_MIN)) { HSD_DBG("button_pressed \n"); atomic_set(&hi->btn_state, 1); switch (table->ADC_HEADSET_BUTTON) { case KEY_MEDIA: input_report_key(hi->input, KEY_MEDIA, 1); pr_info("%s: KEY_MEDIA \n", __func__); break; case KEY_VOLUMEUP: input_report_key(hi->input, KEY_VOLUMEUP, 1); pr_info("%s: KEY_VOLUMEUP \n", __func__); break; case KEY_VOLUMEDOWN: input_report_key(hi->input, KEY_VOLUMEDOWN, 1); pr_info("%s: KEY_VOLUMDOWN \n", __func__); break; default: break; } table->PRESS_OR_NOT = 1; input_sync(hi->input); break; } } return; }
static void insert_headset(struct hsd_info *hi) { int earjack_type; HSD_DBG("insert_headset"); if (hi->set_headset_mic_bias) hi->set_headset_mic_bias(TRUE); gpio_set_value_cansleep(hi->gpio_mic_en, 1); msleep(hi->latency_for_detection); earjack_type = gpio_get_value_cansleep(hi->gpio_jpole); if (earjack_type == 1) { HSD_DBG("3 polarity earjack"); atomic_set(&hi->is_3_pole_or_not, 1); mutex_lock(&hi->mutex_lock); switch_set_state(&hi->sdev, LGE_HEADSET_NO_MIC); mutex_unlock(&hi->mutex_lock); gpio_set_value_cansleep(hi->gpio_mic_en, 0); if (hi->set_headset_mic_bias) hi->set_headset_mic_bias(FALSE); } else { HSD_DBG("4 polarity earjack"); atomic_set(&hi->is_3_pole_or_not, 0); mutex_lock(&hi->mutex_lock); switch_set_state(&hi->sdev, LGE_HEADSET); mutex_unlock(&hi->mutex_lock); if (!atomic_read(&hi->irq_key_enabled)) { unsigned long irq_flags; local_irq_save(irq_flags); enable_irq(hi->irq_key); local_irq_restore(irq_flags); atomic_set(&hi->irq_key_enabled, TRUE); } } }
static void detect_work(struct work_struct *work) { int state; #if 0 unsigned long irq_flags; #endif struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct hsd_info *hi = container_of(dwork, struct hsd_info, work); HSD_DBG("detect_work"); #if 0 local_irq_save(irq_flags); disable_irq(hi->irq_detect); local_irq_restore(irq_flags); #endif printk(KERN_INFO " dev=0x%x\n",(unsigned int)hi); state = gpio_get_value_cansleep(hi->gpio_detect); if (state == 1) { if (switch_get_state(&hi->sdev) != NO_DEVICE) { HSD_DBG("==== LGE headset removing\n"); remove_headset(hi); } else { HSD_DBG("err_invalid_state state = %d\n", state); } } else { if (switch_get_state(&hi->sdev) == NO_DEVICE) { HSD_DBG("==== LGE headset inserting\n"); insert_headset(hi); } else { HSD_DBG("err_invalid_state state = %d\n", state); } } #if 0 local_irq_save(irq_flags); enable_irq(hi->irq_detect); local_irq_restore(irq_flags); #endif }
static void insert_headset(struct hsd_info *hi) { int earjack_type; HSD_DBG("insert_headset\n"); if(atomic_read(&hi->isdetect)) { HSD_DBG("duplicate irq\n"); return; } atomic_set(&hi->isdetect,TRUE); irq_set_irq_wake(hi->irq_key, 1); gpio_direction_output(hi->gpio_mic_en, 1); #ifdef CONFIG_SWITCH_MAX1462X_WA msleep(500); HSD_DBG("insert delay 500\n"); #else msleep(40); HSD_DBG("insert delay 40\n"); #endif /* check if 3-pole or 4-pole 1. read gpio_key 2. check if 3-pole or 4-pole 3-1. NOT regiter irq with gpio_key if 3-pole. complete. 3-2. regiter irq with gpio_key if 4-pole 4. read MPP6 and decide a pressed key when interrupt occurs */ earjack_type = hi->gpio_get_value_func(hi->gpio_key); if ( earjack_type == 1 ) { HSD_DBG("4 polarity earjack\n"); atomic_set(&hi->is_3_pole_or_not, 0); mutex_lock(&hi->mutex_lock); switch_set_state(&hi->sdev, LGE_HEADSET); mutex_unlock(&hi->mutex_lock); if (!atomic_read(&hi->irq_key_enabled)) { HSD_DBG("irq_key_enabled = FALSE\n"); atomic_set(&hi->irq_key_enabled, TRUE); } } else { gpio_direction_output(hi->gpio_mic_en, 0); spmi_write(0x00); HSD_DBG("3 polarity earjack\n"); atomic_set(&hi->is_3_pole_or_not, 1); mutex_lock(&hi->mutex_lock); switch_set_state(&hi->sdev, LGE_HEADSET_NO_MIC); mutex_unlock(&hi->mutex_lock); irq_set_irq_wake(hi->irq_key, 0); } }
static irqreturn_t button_irq_handler(int irq, void *dev_id) { struct hsd_info *hi = (struct hsd_info *) dev_id; int value = 0; int fp = read_file(EARJACK_FILENAME); if(fp < 0) { HSD_DBG("button_irq_handler"); value = gpio_get_value_cansleep(hi->gpio_key); if (value) button_pressed(hi); else button_released(hi); return IRQ_HANDLED; } else { if(fp) { HSD_DBG("button_irq_handler"); value = gpio_get_value_cansleep(hi->gpio_key); if (value) button_pressed(hi); else button_released(hi); return IRQ_HANDLED; } else { return IRQ_NONE; } } return IRQ_NONE; }
static irqreturn_t button_irq_handler(int irq, void *dev_id) { struct hsd_info *hi = (struct hsd_info *) dev_id; int value; wake_lock_timeout(&ear_hook_wake_lock, 2 * HZ); HSD_DBG("button_irq_handler\n"); value = hi->gpio_get_value_func(hi->gpio_key); HSD_DBG("hi->gpio_get_value_func(hi->gpio_key) : %d\n", value); #ifdef CONFIG_SWITCH_MAX1462X_WA HSD_DBG("hi->gpio_get_value_func(hi->gpio_key) %d hi->hook_disable : %d\n", value, hook_disable); #endif if(atomic_read(&hi->is_3_pole_or_not) == 0) { #ifdef CONFIG_SWITCH_MAX1462X_WA if (hook_disable) return IRQ_HANDLED; #endif if (value) queue_delayed_work(local_max1462x_workqueue, &(hi->work_for_key_released), hi->latency_for_key ); else queue_delayed_work(local_max1462x_workqueue, &(hi->work_for_key_pressed), hi->latency_for_key ); } #ifdef CONFIG_SWITCH_MAX1462X_WA else { msleep(10); HSD_DBG("3 pole wrong detection -> 4 pole"); if (value && hi->gpio_get_value_func(hi->gpio_detect) == 0) { remove_headset(hi); insert_headset(hi); } } #endif return IRQ_HANDLED; }
static int __init lge_hsd_init(void) { int ret; HSD_DBG("lge_hsd_init"); ret = platform_driver_register(&lge_hsd_driver); if (ret) { HSD_ERR("Fail to register platform driver\n"); } return ret; }
static int __init lge_hsd_init(void) { int ret; HSD_DBG("lge_hsd_init"); #ifdef CONFIG_MAX1462X_USE_LOCAL_WORK_QUEUE local_max1462x_workqueue = create_workqueue("max1462x"); if(!local_max1462x_workqueue) return -ENOMEM; #endif HSD_DBG("lge_hsd_init : wake_lock_init"); wake_lock_init(&ear_hook_wake_lock, WAKE_LOCK_SUSPEND, "ear_hook"); ret = platform_driver_register(&lge_hsd_driver); if (ret) { HSD_ERR("Fail to register platform driver\n"); } return ret; }
static void insert_headset(struct hsd_info *hi) { int earjack_type; HSD_DBG("insert_headset\n"); if (atomic_read(&hi->isdetect)) { HSD_DBG("duplicate irq\n"); return; } atomic_set(&hi->isdetect, TRUE); irq_set_irq_wake(hi->irq_key, 1); gpio_direction_output(hi->gpio_mic_en, 1); msleep(40); HSD_DBG("insert delay 40\n"); /* */ earjack_type = hi->gpio_get_value_func(hi->gpio_key); if (earjack_type == 1) { HSD_DBG("4 polarity earjack\n"); atomic_set(&hi->is_3_pole_or_not, 0); mutex_lock(&hi->mutex_lock); switch_set_state(&hi->sdev, LGE_HEADSET); mutex_unlock(&hi->mutex_lock); if (!atomic_read(&hi->irq_key_enabled)) { HSD_DBG("irq_key_enabled = FALSE\n"); atomic_set(&hi->irq_key_enabled, TRUE); } input_report_switch(hi->input, SW_HEADPHONE_INSERT, 1); input_report_switch(hi->input, SW_MICROPHONE_INSERT, 1); input_sync(hi->input); } else { gpio_direction_output(hi->gpio_mic_en, 0); spmi_write(0x00); HSD_DBG("3 polarity earjack\n"); atomic_set(&hi->is_3_pole_or_not, 1); mutex_lock(&hi->mutex_lock); switch_set_state(&hi->sdev, LGE_HEADSET_NO_MIC); mutex_unlock(&hi->mutex_lock); irq_set_irq_wake(hi->irq_key, 0); input_report_switch(hi->input, SW_HEADPHONE_INSERT, 1); input_sync(hi->input); } }
static irqreturn_t button_irq_handler(int irq, void *dev_id) { struct hsd_info *hi = (struct hsd_info *) dev_id; int value; wake_lock_timeout(&ear_hook_wake_lock, 2 * HZ); HSD_DBG("button_irq_handler\n"); value = hi->gpio_get_value_func(hi->gpio_key); HSD_DBG("hi->gpio_get_value_func(hi->gpio_key) : %d\n", value); if(atomic_read(&hi->is_3_pole_or_not) == 0) { if (value) queue_delayed_work(local_max1462x_workqueue, &(hi->work_for_key_released), hi->latency_for_key ); else queue_delayed_work(local_max1462x_workqueue, &(hi->work_for_key_pressed), hi->latency_for_key ); } return IRQ_HANDLED; }
static void detect_work(struct work_struct *work) { int state = 0; struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct hsd_info *hi = container_of(dwork, struct hsd_info, work); HSD_DBG("detect_work"); if( gpio_cansleep(hi->gpio_det) ) state = gpio_get_value_cansleep(hi->gpio_det); else state = gpio_get_value(hi->gpio_det); if( state == 1 ) { // gpio_det high - jack out if( switch_get_state(&hi->sdev) != HEADSET_NO_DEVICE ) { HSD_DBG("======= LGE headset removing ======="); remove_headset(hi); #ifdef CONFIG_LGE_BROADCAST_ONESEG isdbt_hw_antenna_switch(0); ear_state = 0; #endif } else { HSD_DBG("err_invalid_state state = %d\n", state); } } else { // gpio_det low - jack in if( switch_get_state(&hi->sdev) == HEADSET_NO_DEVICE ) { HSD_DBG("********** LGE headset inserting **********"); insert_headset(hi); #ifdef CONFIG_LGE_BROADCAST_ONESEG isdbt_hw_antenna_switch(1); ear_state = 1; #endif } else { HSD_DBG("err_invalid_state state = %d\n", state); } } }
static void button_pressed(struct hsd_info *hi) { HSD_DBG("button_pressed \n"); atomic_set(&hi->btn_state, 1); input_report_key(hi->input, hi->key_code, 1); #ifdef AT_TEST_GPKD if(start_keylog == '1') hook_keycode = 'H'; #endif input_sync(hi->input); }
static irqreturn_t gpio_irq_handler(int irq, void *dev_id) { struct hsd_info *hi = (struct hsd_info *) dev_id; int value = gpio_get_value_cansleep(hi->gpio_detect); HSD_DBG("gpio_irq_handler"); if ((switch_get_state(&hi->sdev) ^ !value)) { /* the detection status is inverted */ schedule_work(&(hi->work)); } return IRQ_HANDLED; }