static void detection_work(struct work_struct *work) { int cable_in1; H2W_DBG(""); if (gpio_get_value(hi->gpio_detect) == 1) { /* Headset not plugged in */ if (switch_get_state(&hi->sdev) == LGE_HEADSET || switch_get_state(&hi->sdev) == LGE_NO_MIC_HEADSET ) remove_headset(); H2W_DBG("detection_work-remove_headset \n"); wake_unlock(&hi->wake_lock); return; } cable_in1 = gpio_get_value(hi->gpio_detect); if (cable_in1 == 0) { if (switch_get_state(&hi->sdev) == NO_DEVICE) { H2W_DBG("detection_work-insert_headset \n"); insert_headset(); } } wake_unlock(&hi->wake_lock); }
static int h2w_writec_cmd(H2W_ADDR address, unsigned char data) { int ret = -1; int retry_times = 0; write_resend: if (retry_times == MAX_HOST_RESEND_TIMES) goto err_write; h2w_reset(); h2w_start(); /* Write address */ one_clock_write(address & 0x1000); one_clock_write(address & 0x0800); one_clock_write(address & 0x0400); one_clock_write(address & 0x0200); one_clock_write(address & 0x0100); one_clock_write(address & 0x0080); one_clock_write(address & 0x0040); one_clock_write(address & 0x0020); one_clock_write(address & 0x0010); one_clock_write(address & 0x0008); one_clock_write(address & 0x0004); one_clock_write(address & 0x0002); one_clock_write(address & 0x0001); one_clock_write_RWbit(0); if (h2w_ack() < 0) { H2W_DBG("Addr NO ACK(%d).\n", retry_times); retry_times++; hi->set_clk(0); mdelay(RESEND_DELAY); goto write_resend; } /* Write data */ hi->set_dat_dir(1); one_clock_write(data & 0x0080); one_clock_write(data & 0x0040); one_clock_write(data & 0x0020); one_clock_write(data & 0x0010); one_clock_write(data & 0x0008); one_clock_write(data & 0x0004); one_clock_write(data & 0x0002); one_clock_write_RWbit(data & 0x0001); if (h2w_ack() < 0) { H2W_DBG("Data NO ACK(%d).\n", retry_times); retry_times++; hi->set_clk(0); mdelay(RESEND_DELAY); goto write_resend; } ret = 0; err_write: if (ret < 0) H2WE("NO ACK.\n"); return ret; }
static void detection_work(struct work_struct *work) { int cable_in; H2W_DBG(""); H2W_DBG("%d %d", gpio_get_value(hi->cable_in1), HS_PLUG_IN); /* FIH-SW2-MM-AY-TAP_headset_00 */ if (gpio_get_value(hi->cable_in1) != HS_PLUG_IN) { /* FIH-SW2-MM-AY-TAP_headset_00 */ /* Headset plugged out */ if ( (switch_get_state(&hi->sdev) == HEADSET) || (switch_get_state(&hi->sdev) == NOMIC_HEADSET) || (switch_get_state(&hi->sdev) == NOT_SUPPORT) || (switch_get_state(&hi->sdev) == UNKNOWN_DEVICE)) { /* FIH-SW2-MM-AY-hsed_type-02 */ H2W_DBG("Headset is plugged out.\n"); remove_headset(); } return; } /* Something plugged in, lets make sure its a headset */ cable_in = gpio_get_value(hi->cable_in1); /* FIH-SW2-MM-AY-TAP_headset_00 */ if (cable_in == HS_PLUG_IN ) { if (switch_get_state(&hi->sdev) == NO_DEVICE) { H2W_DBG("Headset is plugged in.\n"); insert_headset(); } } else { H2W_DBG("WARN: AUD_PIN_HEADSET_DET be triggered, but not a headset "); } }
static irqreturn_t detect_irq_handler(int irq, void *dev_id) { int value1, value2; int retry_limit = 10; H2W_DBG(""); aud_hs_print_gpio(); /* debunce */ do { value1 = gpio_get_value(hi->cable_in1); /* FIH-SW2-MM-AY-TAP_headset_00 */ irq_set_irq_type(hi->irq, value1 ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH); value2 = gpio_get_value(hi->cable_in1); /* FIH-SW2-MM-AY-TAP_headset_00 */ } while (value1 != value2 && retry_limit-- > 0); H2W_DBG("value2 = %d (%d retries)", value2, (10-retry_limit)); /* * If the sdev is NO_DEVICE, and we detect the headset has been plugged, * then we can do headset_insertion check. */ if ( (switch_get_state(&hi->sdev) == NO_DEVICE) ^ (value2^HS_PLUG_IN)) { if (switch_get_state(&hi->sdev) == HEADSET) hi->ignore_btn = 1; /* Do the rest of the work in timer context */ hrtimer_start(&hi->timer, hi->debounce_time, HRTIMER_MODE_REL); } return IRQ_HANDLED; }
static int h2w_readc_cmd(H2W_ADDR address) { int ret = -1, retry_times = 0; unsigned char read_data; read_resend: if (retry_times == MAX_HOST_RESEND_TIMES) goto err_read; h2w_reset(); h2w_start(); /* Write address */ one_clock_write(address & 0x1000); one_clock_write(address & 0x0800); one_clock_write(address & 0x0400); one_clock_write(address & 0x0200); one_clock_write(address & 0x0100); one_clock_write(address & 0x0080); one_clock_write(address & 0x0040); one_clock_write(address & 0x0020); one_clock_write(address & 0x0010); one_clock_write(address & 0x0008); one_clock_write(address & 0x0004); one_clock_write(address & 0x0002); one_clock_write(address & 0x0001); one_clock_write_RWbit(1); if (h2w_ack() < 0) { H2W_DBG("Addr NO ACK(%d).\n", retry_times); retry_times++; hi->set_clk(0); mdelay(RESEND_DELAY); goto read_resend; } read_data = h2w_readc(); if (h2w_ack() < 0) { H2W_DBG("Data NO ACK(%d).\n", retry_times); retry_times++; hi->set_clk(0); mdelay(RESEND_DELAY); goto read_resend; } ret = (int)read_data; err_read: if (ret < 0) H2WE("NO ACK.\n"); return ret; }
static void detection_work(struct work_struct *work) { unsigned long irq_flags; int clk, cable_in1; H2W_DBG(""); if (gpio_get_value(SAPPHIRE_GPIO_CABLE_IN1) != 0) { /* */ if (switch_get_state(&hi->sdev) == HTC_HEADSET) remove_headset(); return; } /* */ /* */ configure_cpld(GPIO); /* */ local_irq_save(irq_flags); disable_irq(hi->irq); local_irq_restore(irq_flags); /* */ gpio_direction_output(SAPPHIRE_GPIO_CABLE_IN1, 1); /* */ msleep(10); /* */ clk = gpio_get_value(SAPPHIRE_GPIO_H2W_CLK_GPI); /* */ gpio_direction_input(SAPPHIRE_GPIO_CABLE_IN1); /* */ local_irq_save(irq_flags); enable_irq(hi->irq); local_irq_restore(irq_flags); cable_in1 = gpio_get_value(SAPPHIRE_GPIO_CABLE_IN1); if (cable_in1 == 0 && clk == 0) { if (switch_get_state(&hi->sdev) == NO_DEVICE) insert_headset(); } else { configure_cpld(UART3); H2W_DBG("CABLE_IN1 was low, but not a headset " "(recent cable_in1 = %d, clk = %d)", cable_in1, clk); } }
static void remove_headset(void) { #ifdef FEATURE_AUD_HOOK_BTN unsigned long irq_flags; #endif H2W_DBG(""); hi->ignore_btn = 1; /* FIH-SW2-MM-AY-TAP_Tapioca-00746_00 */ pmic_hsed_enable(PM_HSED_CONTROLLER_0, PM_HSED_ENABLE_OFF); /* FIH-SW2-MM-AY-TAP-ControlHSED_BIAS1-01 */ switch_set_state(&hi->sdev, NO_DEVICE); input_sync(hi->hs_input); #ifdef FEATURE_AUD_HOOK_BTN mHeadphone = false; if (bn_irq_enable) { local_irq_save(irq_flags); disable_irq(hi->irq_btn); local_irq_restore(irq_flags); bn_irq_enable=0; irq_set_irq_wake(hi->irq_btn, 0); } if (atomic_read(&hi->btn_state)) button_released(); #endif }
static irqreturn_t detect_irq_handler(int irq, void *dev_id) { int value1, value2; int retry_limit = 10; int state = BIT_HEADSET | BIT_HEADSET_NO_MIC; H2W_DBG(""); set_irq_type(hi->irq_btn, IRQF_TRIGGER_LOW); do { value1 = gpio_get_value(hi->cable_in1); set_irq_type(hi->irq, value1 ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH); value2 = gpio_get_value(hi->cable_in1); } while (value1 != value2 && retry_limit-- > 0); H2WI("value2 = %d (%d retries), device=%d", value2, (10-retry_limit), switch_get_state(&hi->sdev)); if ((hi->h2w_dev_type == 0) ^ value2) { if ((switch_get_state(&hi->sdev) & state) && !hi->is_ext_insert) hi->ignore_btn = 1; if (hi->is_wake_lock_ready) wake_lock_timeout(&hi->headset_wake_lock, 2.5*HZ); queue_delayed_work(detect_wq, &detect_h2w_work, H2W_DETECT_DELAY); } return IRQ_HANDLED; }
static void button_pressed(void) { H2W_DBG("button_pressed \n"); atomic_set(&hi->btn_state, 1); input_report_key(hi->input, KEY_MEDIA, 1); input_sync(hi->input); }
static void remove_35mm_do_work(struct work_struct *work) { wake_lock_timeout(&hi->headset_wake_lock, 2.5*HZ); H2W_DBG(""); /*To solve the insert, remove, insert headset problem*/ if (time_before_eq(jiffies, hi->insert_jiffies)) msleep(800); if (hi->is_ext_insert) { H2WI("Skip 3.5mm headset plug out!!!"); if (hi->is_hpin_stable) *(hi->is_hpin_stable) = 1; return; } pr_info("3.5mm_headset plug out\n"); if (pd->key_event_disable != NULL) pd->key_event_disable(); if (hi->mic_bias_state) { turn_mic_bias_on(0); hi->mic_bias_state = 0; } hi->ext_35mm_status = 0; if (hi->is_hpin_stable) *(hi->is_hpin_stable) = 0; /* Notify framework via switch class */ mutex_lock(&hi->mutex_lock); switch_set_state(&hi->hs_change, hi->ext_35mm_status); mutex_unlock(&hi->mutex_lock); }
void button_released(int pkey) { bool need_release = bn_hook_state|bn_volup_state|bn_voldown_state|bn_live_state;/*SW-MM-RC-Mesona-03434-01+*/ if ((switch_get_state(&hi->sdev) == HEADSET)&& need_release) { /*SW-MM-RC-Mesona-03434-01**/ H2W_DBG("key = %d", pkey); atomic_set(&hi->btn_state, 0); input_report_key(hi->input, pkey, 0); input_sync(hi->input); /* FIH-SW2-MM-AY-issue_hook_key_event */ bn_state = 0; /*SW-MM-RC-Mesona-03434[+*/ switch(pkey) { case KEY_MEDIA: bn_hook_state=0; break; case KEY_VOLUMEUP: bn_volup_state=0; break; case KEY_VOLUMEDOWN: bn_voldown_state=0; break; case BTN_3: bn_live_state=0; break; default: bn_hook_state=0; break; } /*SW-MM-RC-Mesona-03434]+*/ } }
static void remove_headset(void) { unsigned long irq_flags; H2W_DBG(""); /*Report Headset State*/ input_report_switch(hi->input, SW_HEADPHONE_INSERT, 0); switch_set_state(&hi->sdev, BIT_NO_DEVICE); input_sync(hi->input); /* Disable button */ if(hi->enable_btn_irq) { local_irq_save(irq_flags); disable_irq_nosync(hi->irq_btn); irq_set_irq_wake(hi->irq_btn, 0); hi->enable_btn_irq = 0; local_irq_restore(irq_flags); } /*Check Button State*/ if (atomic_read(&hi->btn_state)) button_released(); //bc gpio_set_value(hi->gpio_mic_mode, 0); /* LGE_CHANGE_S: 2012-04-03, [email protected] Description: 500ms -> 250ms */ hi->debounce_time = ktime_set(0, 250000000); /* 500ms */ /* LGE_CHANGE_E: 500ms -> 250ms */ }
/* MM-RC-HEADSET-MULTIBUTTON-DETECT[* */ void button_pressed(int pkey) { if (switch_get_state(&hi->sdev) == HEADSET) { H2W_DBG("key = %d", pkey); atomic_set(&hi->btn_state, 1); input_report_key(hi->input, pkey, 1); input_sync(hi->input); /* FIH-SW2-MM-AY-issue_hook_key_event */ bn_state = 1; /*SW-MM-RC-Mesona-03434[+*/ switch(pkey) { case KEY_MEDIA: bn_hook_state=1; break; case KEY_VOLUMEUP: bn_volup_state=1; break; case KEY_VOLUMEDOWN: bn_voldown_state=1; break; case BTN_3: bn_live_state=1; break; default: bn_hook_state=1; break; } /*SW-MM-RC-Mesona-03434]+*/ } }
static void insert_headset(void) { unsigned long irq_flags; H2W_DBG(""); switch_set_state(&hi->sdev, HTC_HEADSET); configure_cpld(GPIO); #ifdef CONFIG_MSM_SERIAL_DEBUGGER msm_serial_debug_enable(false); #endif /* */ hi->ignore_btn = !gpio_get_value(SAPPHIRE_GPIO_CABLE_IN2); /* */ local_irq_save(irq_flags); enable_irq(hi->irq_btn); local_irq_restore(irq_flags); hi->debounce_time = ktime_set(0, 20000000); /* */ }
static void button_released(void) { H2W_DBG(""); atomic_set(&hi->btn_state, 0); input_report_key(hi->input, KEY_MEDIA, 0); input_sync(hi->input); }
static enum hrtimer_restart detect_event_timer_func(struct hrtimer *data) { H2W_DBG(""); queue_work(g_detection_work_queue, &g_detection_work); return HRTIMER_NORESTART; }
static enum hrtimer_restart button_event_timer_func(struct hrtimer *data) { H2W_DBG(""); if (switch_get_state(&hi->sdev) == HEADSET) { if (gpio_get_value(hi->cable_in2) == BTN_STATE_RELEASED) { /* FIH-SW2-MM-AY-TAP_headset_00 */ if (hi->ignore_btn) hi->ignore_btn = 0; else { if (bn_state) button_released(); else { if (!hi->ignore_btn) { /* FIH-SW2-MM-AY-TAP_headset_01 */ button_pressed(); button_released(); } /* FIH-SW2-MM-AY-TAP_headset_01 */ } } } else { if (!hi->ignore_btn) button_pressed(); } } return HRTIMER_NORESTART; }
static irqreturn_t detect_irq_handler(int irq, void *dev_id) { int value1, value2; int retry_limit = 10; H2W_DBG(""); set_irq_type(hi->irq_btn, IRQF_TRIGGER_HIGH); do { value1 = gpio_get_value(hi->gpio_detect); H2W_DBG("eklee -------------- gpio_get_value value1= %d ", value1); set_irq_type(hi->irq, value1 ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH); value2 = gpio_get_value(hi->gpio_detect); } while (value1 != value2 && retry_limit-- > 0); H2W_DBG("value2 = %d (%d retries)", value2, (10-retry_limit)); wake_lock(&hi->wake_lock); if (switch_get_state(&hi->sdev) == NO_DEVICE) { if (switch_get_state(&hi->sdev) == LGE_HEADSET || switch_get_state(&hi->sdev) == LGE_NO_MIC_HEADSET ) hi->ignore_btn = 1; /* Do the rest of the work in timer context */ //hrtimer_start(&hi->timer, hi->debounce_time, HRTIMER_MODE_REL); hrtimer_start(&hi->timer, hi->debounce_time, HRTIMER_MODE_ABS); H2W_DBG("detect_irq_handler-no_device \n"); } else if(switch_get_state(&hi->sdev) == LGE_HEADSET || switch_get_state(&hi->sdev) == LGE_NO_MIC_HEADSET ){ /* Do the rest of the work in timer context */ //hrtimer_start(&hi->timer, hi->debounce_time, HRTIMER_MODE_REL); #ifdef CONFIG_LGE_AUDIO_HEADSET_PROTECT gpio_set_value(hi->gpio_mic_bias_en, 0); #endif // hrtimer_start(&hi->timer, hi->unplug_debounce_time, HRTIMER_MODE_REL); hrtimer_start(&hi->timer, hi->unplug_debounce_time, HRTIMER_MODE_ABS); H2W_DBG("detect_irq_handler_headset_no_mic \n"); } return IRQ_HANDLED; }
static void remove_35mm_do_work(struct work_struct *work) { int state; if (hi->is_wake_lock_ready) wake_lock_timeout(&hi->headset_wake_lock, 2.5*HZ); H2W_DBG(""); /*To solve the insert, remove, insert headset problem*/ if (time_before_eq(jiffies, hi->insert_jiffies)) msleep(800); if (hi->is_ext_insert) { H2WI("Skip 3.5mm headset plug out!!!"); return; } printk(KERN_INFO "3.5mm_headset plug out\n"); mutex_lock(&hi->mutex_lock); state = switch_get_state(&hi->sdev); if (hi->mic_bias_state) { turn_mic_bias_on(0); hi->mic_bias_state = 0; } /* For HW Metrico lab test */ if (hi->metrico_status) enable_metrico_headset(0); microp_notify_unplug_mic(); if (atomic_read(&hi->btn_state)) button_released(atomic_read(&hi->btn_state)); hi->ext_35mm_status = HTC_35MM_UNPLUG; if (hi->key_int_shutdown_gpio) gpio_set_value(hi->key_int_shutdown_gpio, 0); if (hi->ext_mic_sel) gpio_direction_output(hi->ext_mic_sel, 0); if (hi->h2w_dev_type == H2W_TVOUT) { state &= ~(BIT_HEADSET | BIT_35MM_HEADSET); state |= BIT_HEADSET_NO_MIC; switch_set_state(&hi->sdev, state); } else if (hi->cable_in1 && !gpio_get_value(hi->cable_in1)) { state &= ~BIT_35MM_HEADSET; switch_set_state(&hi->sdev, state); queue_delayed_work(detect_wq, &detect_h2w_work, H2W_NO_DELAY); } else { state &= ~(BIT_HEADSET | BIT_HEADSET_NO_MIC | BIT_35MM_HEADSET); switch_set_state(&hi->sdev, state); } mutex_unlock(&hi->mutex_lock); }
static irqreturn_t button_irq_handler(int irq, void *dev_id) { int value1, value2; int retry_limit = 10; H2W_DBG(""); do { value1 = gpio_get_value(SAPPHIRE_GPIO_CABLE_IN2); set_irq_type(hi->irq_btn, value1 ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH); value2 = gpio_get_value(SAPPHIRE_GPIO_CABLE_IN2); } while (value1 != value2 && retry_limit-- > 0); H2W_DBG("value2 = %d (%d retries)", value2, (10-retry_limit)); hrtimer_start(&hi->btn_timer, hi->btn_debounce_time, HRTIMER_MODE_REL); return IRQ_HANDLED; }
static void insert_headset(void) { unsigned long irq_flags; int jpole; H2W_DBG(""); #ifdef CONFIG_LGE_AUDIO_HEADSET_PROTECT gpio_set_value(hi->gpio_mic_bias_en, 1); msleep(100); #endif jpole = gpio_get_value(hi->gpio_jpole); if(jpole) // 3pole { hi->ignore_btn = 1; H2W_DBG("insert_headset_no-mic-headset \n"); switch_set_state(&hi->sdev, LGE_NO_MIC_HEADSET); //kiwone, 2009.12.24 , to fix bug //no mic headset insert->no mic headset eject->4pole headset insert->button key do not work. /* Enable button irq */ local_irq_save(irq_flags); enable_irq(hi->irq_btn); set_irq_wake(hi->irq_btn, 1); local_irq_restore(irq_flags); hi->debounce_time = ktime_set(0, 20000000); /* 20 ms */ hi->unplug_debounce_time = ktime_set(0, 100000000); // add eklee gpio_set_value(hi->gpio_mic_bias_en, 0); } else { // 4pole hi->ignore_btn =0; H2W_DBG("insert_headset_headset \n"); switch_set_state(&hi->sdev, LGE_HEADSET); /* Enable button irq */ local_irq_save(irq_flags); enable_irq(hi->irq_btn); set_irq_wake(hi->irq_btn, 1); local_irq_restore(irq_flags); hi->debounce_time = ktime_set(0, 20000000); /* 20 ms */ hi->unplug_debounce_time = ktime_set(0, 100000000); // add eklee } }
void button_released(int pkey) { if (switch_get_state(&hi->sdev) == HEADSET) { H2W_DBG("key = %d", pkey); atomic_set(&hi->btn_state, 0); input_report_key(hi->input, pkey, 0); input_sync(hi->input); /* FIH-SW2-MM-AY-issue_hook_key_event */ bn_state = 0; } }
static int htc_35mm_remove(struct platform_device *pdev) { H2W_DBG(""); switch_dev_unregister(&hi->hs_change); kzfree(hi); #if 0 /* Add keys later */ input_unregister_device(hi->input); #endif return 0; }
static int __init sapphire_h2w_init(void) { if (!machine_is_sapphire()) return 0; int ret; H2W_DBG(""); ret = platform_driver_register(&sapphire_h2w_driver); if (ret) return ret; return platform_device_register(&sapphire_h2w_device); }
static void button_pressed(void) { H2W_DBG(" "); atomic_set(&hi->btn_state, 1); input_report_key(hi->input, KEY_MEDIA, 1); input_sync(hi->input); #if 0 //def CONFIG_LGE_DIAGTEST if(if_condition_is_on_key_buffering == 1) lgf_factor_key_test_rsp((u8)KEY_MEDIA); #endif }
static irqreturn_t button_irq_handler(int irq, void *dev_id) { int value1, value2; int retry_limit = 10; H2W_DBG("button_irq_handler\n"); #if 0 //inverted do { value1 = gpio_get_value(hi->gpio_button_detect); H2W_DBG("button_irq_handler : value1 = %d\n", value1); set_irq_type(hi->irq_btn, value1 ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH); value2 = gpio_get_value(hi->gpio_button_detect); H2W_DBG("button_irq_handler : value2 = %d\n", value2); } while (value1 != value2 && retry_limit-- > 0); #else do { value1 = gpio_get_value(hi->gpio_button_detect); H2W_DBG("button_irq_handler : value1 = %d\n", value1); irq_set_irq_type(hi->irq_btn, value1 ?IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH); value2 = gpio_get_value(hi->gpio_button_detect); H2W_DBG("button_irq_handler : value2 = %d\n", value2); } while (value1 != value2 && retry_limit-- > 0); #endif H2W_DBG("value2 = %d (%d retries) setBTNtimer 10ms", value2, (10-retry_limit)); hrtimer_start(&hi->btn_timer, hi->btn_debounce_time, HRTIMER_MODE_REL); return IRQ_HANDLED; }
static irqreturn_t detect_irq_handler(int irq, void *dev_id) { int value1, value2; int retry_limit = 10; H2W_DBG(""); irq_set_irq_type(hi->irq_btn, IRQF_TRIGGER_LOW); do { value1 = gpio_get_value(hi->gpio_detect); irq_set_irq_type(hi->irq, value1 ?IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH); value2 = gpio_get_value(hi->gpio_detect); H2W_DBG("value 1 [%d], value2 [%d]retry[%d]",value1,value2,retry_limit); } while (value1 != value2 && retry_limit-- > 0); H2W_DBG("value2 = %d (%d retries)", value2, (10-retry_limit)); wake_lock_timeout(&hi->wake_lock, 2*HZ); // 2 second /*Attached*/ if (switch_get_state(&hi->sdev) == BIT_NO_DEVICE) { hrtimer_start(&hi->timer, hi->debounce_time, HRTIMER_MODE_REL); H2W_DBG("Plug in timer set \n"); } /*Detached*/ else if(switch_get_state(&hi->sdev) == BIT_HEADSET || switch_get_state(&hi->sdev) == BIT_HEADSET_SPEAKER_ONLY ){ //test gpio_set_value(hi->gpio_mic_mode, 0); hrtimer_start(&hi->timer, hi->unplug_debounce_time, HRTIMER_MODE_REL); H2W_DBG("Unplug timer set \n"); } return IRQ_HANDLED; }
static void configure_cpld(int route) { H2W_DBG(" route = %s", route == UART3 ? "UART3" : "GPIO"); switch (route) { case UART3: gpio_set_value(SAPPHIRE_GPIO_H2W_SEL0, 0); gpio_set_value(SAPPHIRE_GPIO_H2W_SEL1, 1); break; case GPIO: gpio_set_value(SAPPHIRE_GPIO_H2W_SEL0, 0); gpio_set_value(SAPPHIRE_GPIO_H2W_SEL1, 0); break; } }
static irqreturn_t button_irq_handler(int irq, void *dev_id) { int value1, value2; int retry_limit = 10; H2W_DBG(""); aud_hs_print_gpio(); do { value1 = gpio_get_value(hi->cable_in2); /* FIH-SW2-MM-AY-TAP_headset_00 */ irq_set_irq_type(hi->irq_btn, value1 ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH); value2 = gpio_get_value(hi->cable_in2); /* FIH-SW2-MM-AY-TAP_headset_00 */ } while (value1 != value2 && retry_limit-- > 0); H2W_DBG("Hook BTN :value2 = %d (%d retries)", value2, (10-retry_limit)); hrtimer_start(&hi->btn_timer, hi->btn_debounce_time, HRTIMER_MODE_REL); return IRQ_HANDLED; }
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; }