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;
}
Exemple #3
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);
}
Exemple #4
0
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;
}
Exemple #5
0
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) );
}
Exemple #6
0
/**********************************************************
**  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);
}
Exemple #8
0
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;
}
Exemple #11
0
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;
}
Exemple #13
0
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;
}
Exemple #15
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);
}
Exemple #23
0
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
}
Exemple #25
0
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;
}