static int msm_hsusb_pmic_vbus_notif_init(void (*callback)(int online),
								int init)
{
	unsigned ret = -ENODEV;

	if (!callback)
		return -EINVAL;

	if (init) {
		notify_vbus_state_func_ptr = callback;
		ret = pm8058_mpp_config_digital_in(PMIC_CBLPWR0_N,
			PM8058_MPP_DIG_LEVEL_S3, PM_MPP_DIN_TO_INT);
		if (ret) {
			pr_err("%s: PM8058 MPP%d configuration failed\n",
					__func__, PMIC_CBLPWR0_N + 1);
			return ret;
		}
		INIT_DELAYED_WORK(&pmic_vbus_det, pmic_vbus_detect);
		ret = request_threaded_irq(PMICVBUS_INT, NULL, pmic_vbus_on_irq,
			(IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING),
						"msm_otg_vbus", NULL);
		if (ret) {
			pr_err("%s:pmic_usb_vbus interrupt registration failed",
					__func__);
			return ret;
		}
		semc_fuji_otg_pdata.pmic_vbus_irq = PMICVBUS_INT;
	} else {
		free_irq(PMICVBUS_INT, 0);
		semc_fuji_otg_pdata.pmic_vbus_irq = 0;
		cancel_delayed_work_sync(&pmic_vbus_det);
		notify_vbus_state_func_ptr = NULL;
	}
	return 0;
}
示例#2
0
static void remotekey_detect_func(struct work_struct * test_remotekey_work)
{
	int key_first=0;
	int key_second=0;    
	//	int key_third=0;    

	dbg_func_in();
	// car kit
	if(earjack->car_kit ){
		if(EARJACK_INSERTED){
			dbg("report KEY_MEDIA input from car_kit");
			input_report_key(earjack->ipdev, KEY_MEDIA, earjack->remotekey_pressed);		// car kit button down
			earjack->car_kit = 0; // reset car_kit flag
			if(REMOTEKEY_RELEASED) {
				earjack->remotekey_pressed = 0;
				input_report_key(earjack->ipdev, KEY_MEDIA, earjack->remotekey_pressed);	// car kit button up
			}
		}		
		earjack->car_kit = 0; // reset car_kit flag.
		enable_irq(gpio_to_irq(REMOTEKEY_DET));
		wake_unlock(&remotekey_wake_lock);
		dbg_func_out();
		return ;
	}
	// if current state: key not pressed
	if(!earjack->remotekey_pressed){ 
		dbg("current state: remotekey not pressed, read adc value. \n");
		pm8058_mpp_config_analog_input(XOADC_MPP_3,PM_MPP_AIN_AMUX_CH5, PM_MPP_AOUT_CTL_DISABLE);
		// read adc value twice 
		key_first=adc_value_to_key();
		key_second=adc_value_to_key(); // after 20ms (adc reading delay)
		pm8058_mpp_config_digital_in(XOADC_MPP_3,PM8058_MPP_DIG_LEVEL_S3, PM_MPP_DIN_TO_INT);

		// is valid key && earjack inserted 
		if( (key_first==key_second) && EARJACK_INSERTED){
			earjack->remotekey_index = key_first;
			earjack->remotekey_pressed = 1; 
			if (earjack->remotekey_index != 0 && !earjack->car_kit)
			{
				input_report_key(earjack->ipdev, remotekey_type[earjack->remotekey_index].key_index, earjack->remotekey_pressed);
				dbg("remote key: %s : %d->%d \n", remotekey_type[earjack->remotekey_index].key_name, !earjack->remotekey_pressed, earjack->remotekey_pressed);
			}	
			else if (earjack->car_kit)
			{
				schedule_delayed_work(&remotekey_work, 20);	// for car kit : delayed work after 200ms for __  TODO
				return;
			}
			
			// Defense code :key pressed but released during processing key. 
			if(REMOTEKEY_RELEASED){
				earjack->remotekey_pressed=0;
				if (earjack->remotekey_index != 0) 
					input_report_key(earjack->ipdev, remotekey_type[earjack->remotekey_index].key_index, earjack->remotekey_pressed);
				dbg("remote key: %s : %d->%d \n", remotekey_type[earjack->remotekey_index].key_name, !earjack->remotekey_pressed, earjack->remotekey_pressed);
			}

		}
		// else, ignore key
		else {
			dbg("igrnore key.\n");
			enable_irq(gpio_to_irq(REMOTEKEY_DET));
			wake_unlock(&remotekey_wake_lock);
			dbg_func_out();
			return ;
		}	
	}
	// if current state : key pressed
	else
	{ 
		earjack->remotekey_pressed=0;
		if (earjack->remotekey_index != 0) 
			input_report_key(earjack->ipdev, remotekey_type[earjack->remotekey_index].key_index, earjack->remotekey_pressed);
		dbg("remote key: %s : %d->%d \n", remotekey_type[earjack->remotekey_index].key_name, !earjack->remotekey_pressed, earjack->remotekey_pressed);
	}        
	input_sync(earjack->ipdev);
	enable_irq(gpio_to_irq(REMOTEKEY_DET));
	wake_unlock(&remotekey_wake_lock);
	dbg_func_out();
	return;
}
示例#3
0
static void earjack_detect_func( struct work_struct *test_earjack)         
{
	int err;
	dbg_func_in();
	dbg("currnet earjack->type: ");
	switch(earjack->type){
		case    EARJACK_STATE_OFF : 
			{
				dbg_without_label("EARJACK_STATE_OFF\n");
				if(EARJACK_INSERTED){
					earjack->type = EARJACK_STATE_CHECK;
#if defined(CONFIG_MIC_BIAS_1_8V)
#else
					err=regulator_is_enabled(hs_jack_l8);
					if(err<=0)  err = regulator_enable(hs_jack_l8);
#endif //defined(CONFIG_MACH_MSM8X60_PRESTO)
					pm8058_mpp_config_digital_in(XOADC_MPP_3,PM8058_MPP_DIG_LEVEL_S3, PM_MPP_DIN_TO_INT);
					schedule_delayed_work(&earjack_work, 5); //50ms
					// return without enable IRQ, wake_unlock.
					return;
				}
				break;
			}
		case    EARJACK_STATE_CHECK  :   
			{
				dbg_without_label("EARJACK_STATE_CHECK\n");   
				if(EARJACK_INSERTED)
				{
					// 3pole
					if(!is_4pole_earjack()){
						dbg("3pole headset inserted.\n");
						earjack->type= EARJACK_STATE_ON_3POLE_CHECK;
						earjack->mic_on = 0;
						earjack->hs_on = 1;
						input_report_switch(earjack->ipdev, SW_HEADPHONE_INSERT,earjack->hs_on);
						switch_set_state(&earjack->sdev, switch_state());
						schedule_delayed_work(&earjack_work, 60);   // check if 4pole 600ms
						// return without enable IRQ, wake_unlock.
						return;
					}
					//4pole
					else {
						dbg("4pole headset inserted.\n");
						earjack->type= EARJACK_STATE_ON;
						err=request_threaded_irq(gpio_to_irq(REMOTEKEY_DET),NULL,Remotekey_Det_handler,IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "remote_det-irq", earjack);
						if(err) 
							dbg("request_threaded_irq failed\n");
						earjack->mic_on = 1;
						earjack->hs_on = 1;
						input_report_switch(earjack->ipdev, SW_MICROPHONE_INSERT,earjack->mic_on); //TODO: NO USE?
						input_report_switch(earjack->ipdev, SW_HEADPHONE_INSERT,earjack->hs_on);
						switch_set_state(&earjack->sdev, switch_state());
					}
				}
				else // if EARJACK_RELEASED
				{
					earjack->type = EARJACK_STATE_OFF;                
					dbg("earjack_type: -> EARJACK_STATE_OFF");
				}

				break; // case EARJACK_STATE_CHECK 
			}

		case    EARJACK_STATE_ON_3POLE_CHECK  :   
			{                        
				// CHECKING IF 4POLE EARJACK IS INSERTIND?
				dbg_without_label("EARJACK_STATE_ON_3POLE_CHECK\n");   
				if(EARJACK_INSERTED){
					earjack->type= EARJACK_STATE_ON;                   
					if(!is_4pole_earjack()){
						dbg("3pole earjack insert.\n");
#if defined(CONFIG_MIC_BIAS_1_8V)
#else
            err=regulator_is_enabled(hs_jack_l8);
						dbg("regulator_is_enabled(hs_jack_l8) value => %d\n",err);
						if(err>0) regulator_disable(hs_jack_l8);
#endif //defined(CONFIG_MACH_MSM8X60_PRESTO)
					}
					else {
						dbg("4pole earjack insert.\n");
						earjack->mic_on =1;
						input_report_switch(earjack->ipdev, SW_MICROPHONE_INSERT,earjack->mic_on);
    						switch_set_state(&earjack->sdev, switch_state());
						err=request_threaded_irq(gpio_to_irq(REMOTEKEY_DET),NULL,Remotekey_Det_handler,IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "remote_det-irq", earjack);
						if(err) dbg("request_threaded_irq failed\n");
					}                 
				}
				else{
#if defined(CONFIG_MIC_BIAS_1_8V)
#else          
					err=regulator_is_enabled(hs_jack_l8);
					dbg("regulator_is_enabled(hs_jack_l8) value => %d\n",err);
					if(err>0) regulator_disable(hs_jack_l8);
#endif// defined(CONFIG_MACH_MSM8X60_PRESTO)
					earjack->type = EARJACK_STATE_OFF; 
					earjack->hs_on=0;
					input_report_switch(earjack->ipdev, SW_HEADPHONE_INSERT,earjack->hs_on);
    					switch_set_state(&earjack->sdev, switch_state());
				}
				break;   
			}

		case EARJACK_STATE_ON:   
			{
				dbg_without_label("EARJACK_STATE_ON\n");
				if(EARJACK_RELEASED){
					earjack->type = EARJACK_STATE_OFF;
					// if 4pole
					if (earjack->mic_on) {
						earjack->mic_on = 0;
						input_report_switch(earjack->ipdev, SW_MICROPHONE_INSERT,earjack->mic_on);
						// free remote key irq and turn off mic power.
						free_irq(gpio_to_irq(REMOTEKEY_DET), earjack);
#if defined(CONFIG_MIC_BIAS_1_8V)
#else
            err=regulator_is_enabled(hs_jack_l8);
						dbg("regulator_is_enabled(hs_jack_l8) value => %d\n",err);
						if(err>0){
							regulator_disable(hs_jack_l8);
						}
#endif //defined(CONFIG_MACH_MSM8X60_PRESTO)

						// release remote key if pressed	
						if(earjack->remotekey_pressed){
							earjack->remotekey_pressed = 0;
							if (earjack->remotekey_index != 0) 
								input_report_key(earjack->ipdev, remotekey_type[earjack->remotekey_index].key_index, earjack->remotekey_pressed);
							dbg("remote key: %s : %d->%d \n", remotekey_type[earjack->remotekey_index].key_name, !earjack->remotekey_pressed, earjack->remotekey_pressed);
							input_sync(earjack->ipdev);
						}                            
						dbg("earjack_release \n");

					}
					earjack->hs_on = 0;
					input_report_switch(earjack->ipdev, SW_HEADPHONE_INSERT,earjack->hs_on);
    					switch_set_state(&earjack->sdev, switch_state());
				}

				break;
			}                    
		default :   
			dbg("earjack_detect_func default.\n");
	}
	enable_irq(gpio_to_irq(EARJACK_DET));
	wake_unlock(&earjack_wake_lock);
	dbg_func_out();
	return;
}