static int __init headset_init(void)
{
	int ret, i;
	struct _headset *ht = &headset;
	ret = switch_dev_register(&ht->sdev);
	if (ret < 0) {
		pr_err("switch_dev_register failed!\n");
		return ret;
	}
	platform_driver_register(&headset_button_driver); 
	ht->input = input_allocate_device();
	if (ht->input == NULL) {
		pr_err("switch_dev_register failed!\n");
		goto _switch_dev_register;
	}
	//jinwon.baek 120808 for earloopback switch checking 
	ret = device_create_file((&ht->sdev)->dev, &dev_attr_estate);
	if (ret < 0) {
		pr_err("eswitch_dev_register failed!\n");
		return ret;
	}
	/* Add for manual adc checking - ffkaka */
	ret = device_create_file((&ht->sdev)->dev, &dev_attr_hs_adc);
	if (ret < 0) {
		pr_err("hs_adc_dev_register failed!\n");
		return ret;
	}
	/* gnd detection checking - ffkaka */
	ret = device_create_file((&ht->sdev)->dev, &dev_attr_gnd_detect);
	if (ret < 0) {
		pr_err("gnd_detect_dev_register failed!\n");
		return ret;
	}	

	ht->input->name = "headset-keyboard";
	ht->input->id.bustype = BUS_HOST;
	ht->input->id.vendor = 0x0001;
	ht->input->id.product = 0x0001;
	ht->input->id.version = 0x0100;

	for(i = 0; headset_key_capability[i].key != KEY_RESERVED; i++) {
		__set_bit(headset_key_capability[i].type, ht->input->evbit);
		input_set_capability(ht->input, headset_key_capability[i].type, headset_key_capability[i].key);
	}

	if (input_register_device(ht->input))
		goto _switch_dev_register;

	headset_gpio_init(ht->detect.gpio, ht->detect.desc);
	headset_gpio_init(ht->button.gpio, ht->button.desc);

	/* control of external mic bias - ffkaka */
	ret = gpio_request(HEADSET_MICBIAS_GPIO, "hs_mic_control");
	if (ret)
	{
		pr_info("[headset] hs mic control gpio get fail!!!\n");
		goto _gpio_request;
	}
	gpio_direction_output(HEADSET_MICBIAS_GPIO, 0);	

	/* com open detect - ffkaka */
	ret = gpio_request(HEADSET_COM_DETECT_GPIO,"hs_com_detect");
	if(ret)
	{
		pr_info("[headset] hs_com_detect gpio get fail!!!\n");
		goto _gpio_request;	
	}
	gpio_direction_input(HEADSET_COM_DETECT_GPIO);

	/* adc path enable/disable control(REV0.3) - ffkaka */
	ret = gpio_request(HEADSET_ADC_EN_GPIO,"hs_adc_enable");
	if(ret)
	{
		pr_info("[headset] hs_adc_enable gpio get fail!!!\n");
		goto _gpio_request;	
	}
	gpio_direction_input(HEADSET_ADC_EN_GPIO);
	
	/* ffkaka */

	headset_gpio_debounce(ht->detect.gpio, ht->detect.debounce * 1000);
	headset_gpio_debounce(ht->button.gpio, ht->button.debounce * 1000);
	pr_info("[headset] init headset detection[GPIO=%d] / button[GPIO=%d] \n", ht->detect.gpio, ht->button.gpio);

	HEADSET_DEBOUNCE_ROUND_UP(ht->button.debounce_sw);
	ht->button.parent = ht;
	ht->button.irq = headset_gpio2irq(ht->button.gpio);
	INIT_WORK(&ht->button.gpio_work,headset_button_gpio_work);
	wake_lock_init(&ht->button.gpio_wakelock,WAKE_LOCK_SUSPEND,"hs_button_wakelock");
	init_timer(&ht->button.gpio_timer);
	ht->button.gpio_timer.function = headset_button_timer;
	ht->button.gpio_timer.data = (unsigned long)&ht->button;	
	ht->button.irq_type_active = ht->button.active_low ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH;
	ht->button.irq_type_inactive = ht->button.active_low ? IRQF_TRIGGER_HIGH : IRQF_TRIGGER_LOW;
	ret = request_irq(ht->button.irq, headset_button_irq_handler,
					ht->button.irq_type_active, ht->button.desc, &ht->button);
	if (ret) {
		pr_err("request_irq gpio %d's irq failed!\n", ht->button.gpio);
		goto _gpio_request;
	}
	headset_gpio_irq_enable(0, &ht->button);

	HEADSET_DEBOUNCE_ROUND_UP(ht->detect.debounce_sw);
	ht->detect.parent = ht;
	ht->detect.irq = headset_gpio2irq(ht->detect.gpio);
	INIT_WORK(&ht->detect.gpio_work,headset_detect_gpio_work);
	wake_lock_init(&ht->detect.gpio_wakelock,WAKE_LOCK_SUSPEND,"hs_detect_wakelock");	
	init_timer(&ht->detect.gpio_timer);
	ht->detect.gpio_timer.function = headset_detect_timer;
	ht->detect.gpio_timer.data = (unsigned long)&ht->detect;
	ht->detect.irq_type_active = ht->detect.active_low ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH;
	ht->detect.irq_type_inactive = ht->detect.active_low ? IRQF_TRIGGER_HIGH : IRQF_TRIGGER_LOW;
	ret = request_irq(ht->detect.irq, headset_detect_irq_handler,
					ht->detect.irq_type_active, ht->detect.desc, &ht->detect);
	if (ret) {
		pr_err("request_irq gpio %d's irq failed!\n", ht->detect.gpio);
		goto _headset_button_gpio_irq_handler;
	}
	return 0;
_headset_button_gpio_irq_handler:
	free_irq(ht->button.irq, &ht->button);
	headset_gpio2irq_free(ht->button.irq, &ht->button);
_gpio_request:
	headset_gpio_free(ht->detect.gpio);
	headset_gpio_free(ht->button.gpio);
	headset_gpio_free(HEADSET_MICBIAS_GPIO); /* add for control of external mic bias - ffkaka */
	headset_gpio_free(HEADSET_COM_DETECT_GPIO); /* com open detect - ffkaka */
	input_free_device(ht->input);
_switch_dev_register:
	platform_driver_unregister(&headset_button_driver);
	switch_dev_unregister(&ht->sdev);
	return ret;
}
예제 #2
0
static int __init headset_init(void)
{
	int ret, i;
	struct _headset *ht = &headset;
	pa_regulator = regulator_get(NULL, REGU_NAME_LCDIO);
	regulator_set_voltage(pa_regulator, 2800000, 2800000);

	ret = switch_dev_register(&ht->sdev);
	if (ret < 0) {
		pr_err("switch_dev_register failed!\n");
		return ret;
	}
	platform_driver_register(&headset_button_driver); 
	ht->input = input_allocate_device();
	if (ht->input == NULL) {
		pr_err("switch_dev_register failed!\n");
		goto _switch_dev_register;
	}
	//jinwon.baek 120808 for earloopback switch checking 
	ret = device_create_file((&ht->sdev)->dev, &dev_attr_estate);
	if (ret < 0) {
		pr_err("eswitch_dev_register failed!\n");
		return ret;
	}

	ht->input->name = "headset-keyboard";
	ht->input->id.bustype = BUS_HOST;
	ht->input->id.vendor = 0x0001;
	ht->input->id.product = 0x0001;
	ht->input->id.version = 0x0100;

	for(i = 0; headset_key_capability[i].key != KEY_RESERVED; i++) {
		__set_bit(headset_key_capability[i].type, ht->input->evbit);
		input_set_capability(ht->input, headset_key_capability[i].type, headset_key_capability[i].key);
	}

	if (input_register_device(ht->input))
		goto _switch_dev_register;

	headset_gpio_init(ht->detect.gpio, ht->detect.desc);
	headset_gpio_init(ht->button.gpio, ht->button.desc);

	headset_gpio_debounce(ht->detect.gpio, ht->detect.debounce * 1000);
	headset_gpio_debounce(ht->button.gpio, ht->button.debounce * 1000);

	hrtimer_init(&ht->button.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	ht->button.timer.function = headset_gpio_timer_func;
	HEADSET_DEBOUNCE_ROUND_UP(ht->button.debounce_sw);
	HEADSET_DEBOUNCE_ROUND_UP(ht->button.timeout_ms);
	ht->button.parent = ht;
	ht->button.irq = headset_gpio2irq(ht->button.gpio);
	ht->button.irq_type_active = ht->button.active_low ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH;
	ht->button.irq_type_inactive = ht->button.active_low ? IRQF_TRIGGER_HIGH : IRQF_TRIGGER_LOW;
	ret = request_irq(ht->button.irq, headset_gpio_irq_handler,
					ht->button.irq_type_active, ht->button.desc, &ht->button);
	if (ret) {
		pr_err("request_irq gpio %d's irq failed!\n", ht->button.gpio);
		goto _gpio_request;
	}
	headset_gpio_irq_enable(0, &ht->button);

	hrtimer_init(&ht->detect.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	ht->detect.timer.function = headset_gpio_timer_func;
	HEADSET_DEBOUNCE_ROUND_UP(ht->detect.debounce_sw);
	ht->detect.parent = ht;
	ht->detect.irq = headset_gpio2irq(ht->detect.gpio);
	ht->detect.irq_type_active = ht->detect.active_low ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH;
	ht->detect.irq_type_inactive = ht->detect.active_low ? IRQF_TRIGGER_HIGH : IRQF_TRIGGER_LOW;
	ret = request_irq(ht->detect.irq, headset_gpio_irq_handler,
					ht->detect.irq_type_active, ht->detect.desc, &ht->detect);
	if (ret) {
		pr_err("request_irq gpio %d's irq failed!\n", ht->detect.gpio);
		goto _headset_button_gpio_irq_handler;
	}
	return 0;
_headset_button_gpio_irq_handler:
	free_irq(ht->button.irq, &ht->button);
	headset_gpio2irq_free(ht->button.irq, &ht->button);
_gpio_request:
	headset_gpio_free(ht->detect.gpio);
	headset_gpio_free(ht->button.gpio);
	input_free_device(ht->input);
_switch_dev_register:
	platform_driver_unregister(&headset_button_driver);
	switch_dev_unregister(&ht->sdev);
	return ret;
}