int switch_send_event(unsigned int bit, int on) { unsigned long state; HS_DBG(); mutex_lock(&hi->mutex_lock); state = switch_get_state(&hi->sdev_h2w); state &= ~(bit); if (on) state |= bit; switch_set_state(&hi->sdev_h2w, state); mutex_unlock(&hi->mutex_lock); return 0; }
static int hds_remove(struct platform_device *pdev) { HDSI("Removing 3.5mm headset driver\n"); if (switch_get_state(&hi->sdev)) remove_headset(); input_unregister_device(hi->input); if (hi->gpio_detect) gpio_free(hi->gpio_detect); if (hi->gpio_headset_mic) { gpio_free(hi->gpio_headset_mic); free_irq(hi->irq_btn_35mm, 0); } destroy_workqueue(g_detection_work_queue); switch_dev_unregister(&hi->sdev); return 0; }
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_detect)){ if (gpio_get_value_cansleep(hi->gpio_detect) && (switch_get_state(&hi->sdev)== LGE_HEADSET)){ HSD_ERR("button_released but ear jack is plugged out already! just ignore the event.\n"); return; } HSD_DBG("button_released \n"); atomic_set(&hi->btn_state, 0); input_report_key(hi->input, hi->key_code, 0); input_sync(hi->input); }
static ssize_t lge_hsd_print_name(struct switch_dev *sdev, char *buf) { switch (switch_get_state(sdev)) { case NO_DEVICE: return sprintf(buf, "No Device"); case LGE_HEADSET: return sprintf(buf, "Headset"); case LGE_HEADSET_NO_MIC: return sprintf(buf, "Headset"); /* return sprintf(buf, "Headset_no_mic\n"); */ } return -EINVAL; }
static void lid_switch_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) { if (type == EV_SW && code == SW_TABLET_MODE ) { printk(KERN_DEBUG "%s(%s): Event. Type: %d, Code: %d, Value: %d KEYPAD : %s \n",__FILE__, __FUNCTION__, type, code, value , value ? "UNLOCKED":"LOCKED"); adp5588_data.update_config = value+1; schedule_work(&adp5588_data.lock_work); } if (type == EV_SW && ((code == SW_TABLET_MODE) || (code == SW_LID))) switch_set_state(&adp5588_data.sw_lid_dev, (switch_get_state(&adp5588_data.sw_lid_dev) & ~(1<<code)) | ( value << code) ); }
/********************************************************** ** Function: Headset jack-in detection interrupt handler ** Parameter: dedicated irq ** Return value: if sucess, then returns IRQ_HANDLED ** ************************************************************/ static irqreturn_t detect_irq_handler(int irq, void *dev_id) { int value1, value2; int retry_limit = 10; do { value1 = gpio_get_value(JACK_GPIO); set_irq_type(hs_data->irq, value1 ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING); value2 = gpio_get_value(JACK_GPIO); } while (value1 != value2 && retry_limit-- > 0); if ((switch_get_state(&hs_data->sdev) == NO_DEVICE) ^ value2) hrtimer_start(&hs_data->timer, hs_data->debouncing_time, HRTIMER_MODE_REL); return IRQ_HANDLED; }
static void usb_headset_detect(int type) { int state_h2w = 0; int state_usb = 0; HS_DBG(); mutex_lock(&hi->mutex_lock); state_h2w = switch_get_state(&hi->sdev_h2w); switch (type) { case USB_NO_HEADSET: hi->usb_headset.type = USB_NO_HEADSET; hi->usb_headset.status = STATUS_DISCONNECTED; state_h2w &= ~MASK_USB_HEADSET; state_usb = GOOGLE_USB_AUDIO_UNPLUG; HS_LOG_TIME("Remove USB_HEADSET (state %d, %d)", state_h2w, state_usb); break; case USB_AUDIO_OUT: hi->usb_headset.type = USB_AUDIO_OUT; hi->usb_headset.status = STATUS_CONNECTED_ENABLED; state_h2w |= BIT_USB_AUDIO_OUT; state_usb = GOOGLE_USB_AUDIO_ANLG; HS_LOG_TIME("Insert USB_AUDIO_OUT (state %d, %d)", state_h2w, state_usb); break; #ifdef CONFIG_SUPPORT_USB_SPEAKER case USB_AUDIO_OUT_DGTL: hi->usb_headset.type = USB_AUDIO_OUT; hi->usb_headset.status = STATUS_CONNECTED_ENABLED; state_h2w |= BIT_USB_AUDIO_OUT; state_usb = GOOGLE_USB_AUDIO_DGTL; HS_LOG_TIME("Insert USB_AUDIO_OUT DGTL (state %d, %d)", state_h2w, state_usb); break; #endif default: HS_LOG("Unknown headset type"); } switch_set_state(&hi->sdev_h2w, state_h2w); switch_set_state(&hi->sdev_usb_audio, state_usb); mutex_unlock(&hi->mutex_lock); }
static int bu52014hfv_update(struct bu52014hfv_info *info, int gpio, int dock) { if (bu52014hfv_disable) { if (switch_get_state(&info->sdev) != NO_DOCK) { switch_set_state(&info->sdev, NO_DOCK); } return 0; } int state = !gpio_get_value(gpio); if (state) switch_set_state(&info->sdev, dock); else switch_set_state(&info->sdev, NO_DOCK); return state; }
static int htc_headset_mgr_remove(struct platform_device *pdev) { #if 0 if ((switch_get_state(&hi->sdev) & MASK_HEADSET) != 0) remove_headset(); #endif unregister_attributes(); input_unregister_device(hi->input); destroy_workqueue(button_wq); destroy_workqueue(detect_wq); switch_dev_unregister(&hi->sdev); mutex_destroy(&hi->mutex_lock); wake_lock_destroy(&hi->hs_wake_lock); kfree(hi); return 0; }
static ssize_t msm_flip_chatt_print_name(struct switch_dev *sdev, char *buf) { switch (switch_get_state(&hs->sdev_flip_chatt)) { case MSM_OPEN: return sprintf(buf, "OPEN\n"); case MSM_CLOSE: return sprintf(buf, "CLOSE\n"); #ifdef SWIVEL_USE case MSM_SWIVEL_CLOSE: return sprintf(buf, "SWIVEL_CLOSE\n"); #endif case MSM_OPEN_CHATT: return sprintf(buf, "OPEN_CHATT\n"); case MSM_CLOSE_CHATT: return sprintf(buf, "CLOSE_CHATT\n"); } return -EINVAL; }
static int simple_remote_remove(struct platform_device *pdev) { struct simple_remote_driver *jack = platform_get_drvdata(pdev); if (switch_get_state(&jack->swdev)) { jack->interface->unregister_hssd_button_interrupt(jack); jack->interface->enable_mic_bias(0); switch_set_state(&jack->swdev, NO_DEVICE); } jack->interface->unregister_plug_detect_interrupt(jack); remove_sysfs_interfaces(&pdev->dev); input_unregister_device(jack->indev_appkey); input_unregister_device(jack->indev); switch_dev_unregister(&jack->swdev); kzfree(jack); return 0; }
static enum hrtimer_restart button_event_timer_func(struct hrtimer *data) { H2W_DBG(""); if (switch_get_state(&hi->sdev) == HTC_HEADSET) { if (gpio_get_value(SAPPHIRE_GPIO_CABLE_IN2)) { if (hi->ignore_btn) hi->ignore_btn = 0; else if (atomic_read(&hi->btn_state)) button_released(); } else { if (!hi->ignore_btn && !atomic_read(&hi->btn_state)) button_pressed(); } } return HRTIMER_NORESTART; }
static void htc_headset_mgr_late_resume(struct early_suspend *h) { int state = 0; HS_DBG(); if (hi->quick_boot_status) { mutex_lock(&hi->mutex_lock); state = switch_get_state(&hi->sdev); HS_LOG_TIME("Resend quick boot U-Event (state = %d)", state | BIT_UNDEFINED); switch_set_state(&hi->sdev, state | BIT_UNDEFINED); HS_LOG_TIME("Resend quick boot U-Event (state = %d)", state); switch_set_state(&hi->sdev, state); hi->quick_boot_status = 0; mutex_unlock(&hi->mutex_lock); } }
static ssize_t othc_headset_print_name(struct switch_dev *sdev, char *buf) { #if 0 switch (switch_get_state(sdev)) { case OTHC_NO_DEVICE: return sprintf(buf, "No Device\n"); case OTHC_HEADSET: case OTHC_HEADPHONE: case OTHC_MICROPHONE: case OTHC_ANC_HEADSET: case OTHC_ANC_HEADPHONE: case OTHC_ANC_MICROPHONE: return sprintf(buf, "Headset\n"); } return -EINVAL; #endif return 0; }
static ssize_t headset_name_show(struct switch_dev *sdev, char *buf) { switch (switch_get_state(&hs_data->sdev)){ case NO_DEVICE: { return sprintf(buf, "%s\n", "No Device"); } case HEADSET_WITH_MIC: { return sprintf(buf, "%s\n", "HEADSET"); } case HEADSET_WITHOUT_MIC: { return sprintf(buf, "%s\n", "HEADPHONE"); } } return -EINVAL; }
static irqreturn_t detect_irq_handler(int irq, void *dev_id) { int value1, value2; int retry_limit = 10; do { value1 = gpio_get_value(JACK_GPIO); irq_set_irq_type(hs_data->hp_det_irq, value1 ? IRQF_TRIGGER_FALLING : IRQF_TRIGGER_RISING); value2 = gpio_get_value(JACK_GPIO); }while (value1 != value2 && retry_limit-- > 0); if ((switch_get_state(&hs_data->sdev) == NO_DEVICE) != (value2 == 1)) { hs_data->btn_ignore = true; queue_delayed_work(g_detection_work_queue, &g_detection_work, msecs_to_jiffies(100)); } return IRQ_HANDLED; }
static ssize_t msm_headset_print_name(struct switch_dev *sdev, char *buf) { switch (switch_get_state(&hs->sdev)) { #if 0 case NO_DEVICE: return sprintf(buf, "No Device\n"); case MSM_HEADSET: return sprintf(buf, "Headset\n"); #else case NO_DEVICE: return sprintf(buf, "NoDevice\n"); case MSM_HEADSET_MONO: return sprintf(buf, "MonoHeadset\n"); case MSM_HEADSET_OTHER: case MSM_HEADSET_STE: return sprintf(buf, "StereoHeadset\n"); #endif } return -EINVAL; }
static void remove_headset(void) { HDS_DBG(""); mutex_lock(&hi->mutex_lock); switch_set_state(&hi->sdev, switch_get_state(&hi->sdev) & ~(BIT_HEADSET | BIT_HEADSET_NO_MIC)); mutex_unlock(&hi->mutex_lock); if (hi->btn_11pin_35mm_flag) { disable_irq(hi->irq_btn_35mm); //turn_mic_bias_on(0); hi->btn_11pin_35mm_flag = 0; if (atomic_read(&hi->btn_state)) button_released(); } HDS_DBG("removed 3.5mm headset\n"); hi->debounce_time = ktime_set(0, 100000000); /* 100 ms */ }
static irqreturn_t gpio_irq_handler(int irq, void *dev_id) { int value1, value2; int retry_limit = 10; value1 = gpio_get_value(hi->gpio); do { value2 = gpio_get_value(hi->gpio); } while(retry_limit-- < 0); if (value1 ^ value2) return IRQ_HANDLED; HSD_DBG("value2 = %d\n", value2); if ((switch_get_state(&hi->sdev) ^ value2)) { queue_work(hs_detect_work_queue, &hs_detect_work); } return IRQ_HANDLED; }
static int trout_h2w_remove(struct platform_device *pdev) { H2W_DBG(""); if (switch_get_state(&hi->sdev)) remove_headset(); #ifdef FEATURE_AUD_HOOK_BTN input_unregister_device(hi->input); gpio_free(hi->cable_in2); /* FIH-SW2-MM-AY-TAP_headset_00 */ free_irq(hi->irq_btn, 0); #endif gpio_free(hi->cable_in1); /* FIH-SW2-MM-AY-TAP_headset_00 */ free_irq(hi->irq, 0); destroy_workqueue(g_detection_work_queue); switch_dev_unregister(&hi->sdev); return 0; }
static enum hrtimer_restart button_event_timer_func(struct hrtimer *data) { H2W_DBG(""); if (switch_get_state(&hi->sdev) == LGE_HEADSET //kiwone, 2009.12.24, to fix bug // 4 pole headset eject->button key is detected && (0 == gpio_get_value(hi->gpio_detect)) ) { if (!gpio_get_value(hi->gpio_button_detect)) { if (hi->ignore_btn) hi->ignore_btn = 0; else if (atomic_read(&hi->btn_state)) button_released(); } else { if (!hi->ignore_btn && !atomic_read(&hi->btn_state)) button_pressed(); } } return HRTIMER_NORESTART; }
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); #ifdef CONFIG_LGE_HEADSET_MIC_NOISE_WA taiko_dec5_vol_mute(); #endif } input_sync(hi->input); 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 ssize_t switch_headset_print_state(struct switch_dev *sdev, char *buf) { struct gpio_switch_data *switch_data = container_of(sdev, struct gpio_switch_data, sdev); const char *state; int stateValue = 0; /* if (switch_get_state(sdev)) state = switch_data->state_on; else state = switch_data->state_off; if (state) return sprintf(buf, "%s\n", state); */ stateValue = switch_get_state(sdev); return sprintf(buf, "%d\n", stateValue); return -1; }
static void htc_headset_mgr_late_resume(struct early_suspend *h) { #ifdef HTC_HEADSET_CONFIG_QUICK_BOOT int state = 0; HS_DBG(); if (hi->quick_boot_status) { mutex_lock(&hi->mutex_lock); state = switch_get_state(&hi->sdev_h2w); HS_LOG_TIME("Resend quick boot U-Event (state = %d)", state | BIT_UNDEFINED); switch_set_state(&hi->sdev_h2w, state | BIT_UNDEFINED); HS_LOG_TIME("Resend quick boot U-Event (state = %d)", state); switch_set_state(&hi->sdev_h2w, state); hi->quick_boot_status = 0; mutex_unlock(&hi->mutex_lock); } #else HS_DBG(); #endif }
static irqreturn_t gpio_irq_handler(int irq, void *dev_id) { struct hsd_info *hi = (struct hsd_info *) dev_id; #if 0 int value = gpio_get_value_cansleep(hi->gpio_detect); #endif wake_lock_timeout(&ear_hook_wake_lock, 2 * HZ); HSD_DBG("gpio_irq_handler"); #if 0 if ((switch_get_state(&hi->sdev) ^ !value)) { /* the detection status is inverted */ schedule_work(&(hi->work)); } #else #ifdef CONFIG_FSA8008_USE_LOCAL_WORK_QUEUE #if 1 //def CONFIG_MACH_LGE_I_BOARD_DCM queue_delayed_work(local_fsa8008_workqueue, &(hi->work), HZ/2 /* 500ms */); #else queue_delayed_work(local_fsa8008_workqueue, &(hi->work), 0); #endif #else #if 1 //def CONFIG_MACH_LGE_I_BOARD_DCM schedule_delayed_work(&(hi->work), HZ/2 /* 500ms */); #else schedule_delayed_work(&(hi->work), 0); #endif #endif #endif return IRQ_HANDLED; }
static void hdmi_hpd_changed(struct hdmi_device *hdev, int state) { int ret; #ifdef CONFIG_SEC_MHL_SUPPORT u32 audio_info = 0; #endif if (state == switch_get_state(&hdev->hpd_switch)) return; if (state) { ret = edid_update(hdev); if (ret == -ENODEV) { dev_err(hdev->dev, "failed to update edid\n"); return; } hdev->dvi_mode = !edid_supports_hdmi(hdev); hdev->cur_timings = edid_preferred_preset(hdev); hdev->cur_conf = hdmi_timing2conf(&hdev->cur_timings); } switch_set_state(&hdev->hpd_switch, state); dev_info(hdev->dev, "%s\n", state ? "plugged" : "unplugged"); #ifdef CONFIG_SEC_MHL_SUPPORT if (state) { /*Audio CH event*/ audio_info = edid_audio_informs(hdev); pr_err("[HDMI] send audio_info :: %x\n", audio_info); switch_set_state(&hdev->audio_ch_switch, (int)audio_info); } else { switch_set_state(&hdev->audio_ch_switch, -1); } #endif }
static int htc_35mm_remove(struct platform_device *pdev) { H2W_DBG(""); if ((switch_get_state(&hi->sdev) & (BIT_HEADSET | BIT_HEADSET_NO_MIC)) != 0) remove_headset(); unregister_common_headset(hi); input_unregister_device(hi->input); if (hi->h2w_data) { gpio_free(hi->h2w_data); free_irq(hi->irq_btn, 0); } if (hi->cable_in1) { gpio_free(hi->cable_in1); free_irq(hi->irq, 0); } destroy_workqueue(detect_wq); destroy_workqueue(button_wq); switch_dev_unregister(&hi->sdev); return 0; }
static void hdmi_hpd_changed(struct hdmi_device *hdev, int state) { int ret; if (state == switch_get_state(&hdev->hpd_switch)) return; if (state) { ret = edid_update(hdev); if (ret == -ENODEV) { dev_err(hdev->dev, "failed to update edid\n"); return; } hdev->dvi_mode = !edid_supports_hdmi(hdev); hdev->cur_timings = edid_preferred_preset(hdev); hdev->cur_conf = hdmi_timing2conf(&hdev->cur_timings); } switch_set_state(&hdev->hpd_switch, state); dev_info(hdev->dev, "%s\n", state ? "plugged" : "unplugged"); }
static enum hrtimer_restart button_event_timer_func(struct hrtimer *data) { int headset_in =0; int btn_down =0; H2W_DBG(""); /* Low Detect, Fast Check*/ /* "button timer < headset detach timer" makes abnormal operation*/ headset_in = gpio_get_value(hi->gpio_detect)?0: 1; /*Headset button - High Detect*/ //btn_down = gpio_get_value(hi->gpio_button_detect)?1 :0; /*Headset button - LOW Detect*/ btn_down = gpio_get_value(hi->gpio_button_detect)?0 :1; if(hi->ignore_btn){ H2W_DBG("ignore_btn"); return HRTIMER_NORESTART; } if ((switch_get_state(&hi->sdev) == BIT_HEADSET) && headset_in){ H2W_DBG(" headset in %d btn down %d",headset_in,btn_down); if (btn_down){ if (!atomic_read(&hi->btn_state)) button_pressed(); } else { if (atomic_read(&hi->btn_state)) button_released(); } } H2W_DBG(" No button event"); return HRTIMER_NORESTART; }
static ssize_t fm_flag_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int state; HS_DBG(); mutex_lock(&hi->mutex_lock); state = switch_get_state(&hi->sdev_h2w); state &= ~(BIT_FM_HEADSET | BIT_FM_SPEAKER); if (count == (strlen("fm_headset") + 1) && strncmp(buf, "fm_headset", strlen("fm_headset")) == 0) { hi->fm_flag = 1; state |= BIT_FM_HEADSET; HS_LOG("Enable FM HEADSET"); } else if (count == (strlen("fm_speaker") + 1) && strncmp(buf, "fm_speaker", strlen("fm_speaker")) == 0) { hi->fm_flag = 2; state |= BIT_FM_SPEAKER; HS_LOG("Enable FM SPEAKER"); } else if (count == (strlen("disable") + 1) && strncmp(buf, "disable", strlen("disable")) == 0) { hi->fm_flag = 0 ; HS_LOG("Disable FM"); } else { mutex_unlock(&hi->mutex_lock); HS_LOG("Invalid FM argument"); return -EINVAL; } switch_set_state(&hi->sdev_h2w, state); mutex_unlock(&hi->mutex_lock); return count; }