static int htc_headset_1wire_probe(struct platform_device *pdev)
{
	struct htc_headset_1wire_platform_data *pdata = pdev->dev.platform_data;
	HS_LOG("1-wire probe starts");

	hi = kzalloc(sizeof(struct htc_35mm_1wire_info), GFP_KERNEL);
	if (!hi)
		return -ENOMEM;

	hi->pdata.tx_level_shift_en = pdata->tx_level_shift_en;
	hi->pdata.uart_sw = pdata->uart_sw;
	if (pdata->one_wire_remote[5])
		memcpy(hi->pdata.one_wire_remote, pdata->one_wire_remote,
		       sizeof(hi->pdata.one_wire_remote));
	hi->pdata.uart_tx = pdata->uart_tx;
	hi->pdata.uart_rx = pdata->uart_rx;
	hi->pdata.remote_press = pdata->remote_press;
	strncpy(hi->pdata.onewire_tty_dev, pdata->onewire_tty_dev, 15);
	HS_LOG("1wire tty device %s", hi->pdata.onewire_tty_dev);
	hs_1wire_register();
	hs_notify_driver_ready(DRIVER_NAME);

	HS_LOG("--------------------");

	return 0;
}
static int htc_headset_1wire_probe(struct platform_device *pdev)
{
	struct htc_headset_1wire_platform_data *pdata = pdev->dev.platform_data;
	HS_LOG("1-wire probe starts");

	hi = kzalloc(sizeof(struct htc_35mm_1wire_info), GFP_KERNEL);
	if (!hi)
		return -ENOMEM;

	hi->pdata.tx_level_shift_en = pdata->tx_level_shift_en;
	hi->pdata.uart_sw = pdata->uart_sw;
	if (pdata->one_wire_remote[5])
		memcpy(hi->pdata.one_wire_remote, pdata->one_wire_remote,
		       sizeof(hi->pdata.one_wire_remote));
	hi->pdata.uart_tx = pdata->uart_tx;
	hi->pdata.uart_rx = pdata->uart_rx;
	hi->pdata.remote_press = pdata->remote_press;
	fp_count = 0;
	strncpy(hi->pdata.onewire_tty_dev, pdata->onewire_tty_dev, 15);
	HS_LOG("1wire tty device %s", hi->pdata.onewire_tty_dev);
	onewire_wq = create_workqueue("ONEWIRE_WQ");
	if (onewire_wq  == NULL) {
		HS_ERR("Failed to create onewire workqueue");
		return 0;
	}
	mutex_init(&hi->mutex_lock);
	hs_1wire_register();
	queue_delayed_work(onewire_wq, &onewire_init_work, msecs_to_jiffies(3000));
	hs_notify_driver_ready(DRIVER_NAME);

	HS_LOG("--------------------");

	return 0;
}
static int htc_headset_misc_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct htc_headset_misc_platform_data *pdata = pdev->dev.platform_data;

	HS_LOG("++++++++++++++++++++");

	hi = kzalloc(sizeof(struct htc_headset_misc_info), GFP_KERNEL);
	if (!hi) {
		HS_ERR("Failed to allocate memory for headset info");
		return -ENOMEM;
	}

	hi->pdata.driver_flag = pdata->driver_flag;
	hi->pdata.ext_hpin_gpio = pdata->ext_hpin_gpio;
	hi->pdata.ext_accessory_type = pdata->ext_accessory_type;

	hi->pdata.indicator_power_gpio = pdata->indicator_power_gpio;

	hi->ext_hpin_irq_type = IRQF_TRIGGER_LOW;
	hi->ext_hpin_debounce = HS_JIFFIES_INSERT;
	hi->ext_hpin_enable = 0;

	switch (hi->pdata.ext_accessory_type) {
	case USB_AUDIO_OUT:
		hi->accessory_detect = hs_misc_usb_audio_out_detect;
		break;
	default:
		if (hi->pdata.driver_flag & DRIVER_HS_MISC_EXT_HP_DET) {
			ret = -EINVAL;
			HS_ERR("Unknown accessory type");
			goto err_ext_hpin_accessory_type;
		}
	}

	wake_lock_init(&hi->hs_wake_lock, WAKE_LOCK_SUSPEND, DRIVER_NAME);

	detect_wq = create_workqueue("HS_MISC_DETECT");
	if (detect_wq == NULL) {
		ret = -ENOMEM;
		HS_ERR("Failed to create detect workqueue");
		goto err_create_detect_work_queue;
	}

	hs_misc_register();
	hs_notify_driver_ready(DRIVER_NAME);

	HS_LOG("--------------------");

	return 0;

err_create_detect_work_queue:
err_ext_hpin_accessory_type:
	kfree(hi);

	HS_ERR("Failed to register %s driver", DRIVER_NAME);

	return ret;
}
static int htc_headset_1wire_probe(struct platform_device *pdev)
{
	struct htc_hs_1wire_data *dtinfo;
	struct htc_headset_1wire_platform_data *pdata;
	HS_LOG("++++++++++++++++++++");

	wake_lock_init(&onewire_open_wake_lock, WAKE_LOCK_SUSPEND, "one_wire_headset");
	hi = kzalloc(sizeof(struct htc_35mm_1wire_info), GFP_KERNEL);
	if (!hi)
		return -ENOMEM;

	dtinfo = kzalloc(sizeof(*dtinfo), GFP_KERNEL);
	if (!dtinfo)
		return -ENOMEM;

	if (pdev->dev.of_node) {
		pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
		if (pdata == NULL)
			return -ENOMEM;

		dtinfo->dev = &pdev->dev;
		dtinfo->pdata = pdata;
		hs_1wire_dtwq(dtinfo);

		HS_LOG("==DT parser %s==", dtinfo->parser ? "OK": "FAILED");
	} else {
		HS_LOG("old style\n");
		pdata = pdev->dev.platform_data;
	}

	hi->pdata.tx_level_shift_en = pdata->tx_level_shift_en;
	hi->pdata.uart_sw = pdata->uart_sw;
	if (pdata->one_wire_remote[5])
		memcpy(hi->pdata.one_wire_remote, pdata->one_wire_remote,
		       sizeof(hi->pdata.one_wire_remote));
	hi->pdata.uart_tx = pdata->uart_tx;
	hi->pdata.uart_rx = pdata->uart_rx;
	hi->pdata.remote_press = pdata->remote_press;
	fp = NULL;
	fp_count = 0;
	strncpy(hi->pdata.onewire_tty_dev, pdata->onewire_tty_dev, 15);
	HS_LOG("1wire tty device %s", hi->pdata.onewire_tty_dev);
	onewire_wq = create_workqueue("ONEWIRE_WQ");
	if (onewire_wq  == NULL) {
		HS_ERR("Failed to create onewire workqueue");
		return 0;
	}
	mutex_init(&hi->mutex_lock);
	hs_1wire_register();
	queue_delayed_work(onewire_wq, &onewire_init_work, msecs_to_jiffies(3000));
#ifndef CONFIG_OF
	hs_notify_driver_ready(DRIVER_NAME);
#endif
	HS_LOG("--------------------");

	return 0;
}
static int htc_headset_8x60_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct htc_headset_8x60_platform_data *pdata = pdev->dev.platform_data;

	HS_LOG("++++++++++++++++++++");

	hi = kzalloc(sizeof(struct htc_headset_8x60_info), GFP_KERNEL);
	if (!hi) {
		HS_ERR("Failed to allocate memory for headset info");
		return -ENOMEM;
	}

	hi->pdata.adc_mpp = pdata->adc_mpp;
	hi->pdata.adc_amux = pdata->adc_amux;

	if (pdata->adc_mic_bias[0] && pdata->adc_mic_bias[1]) {
		memcpy(hi->pdata.adc_mic_bias, pdata->adc_mic_bias,
		       sizeof(hi->pdata.adc_mic_bias));
	} else {
		hi->pdata.adc_mic_bias[0] = HS_DEF_MIC_ADC_15_BIT_MIN;
		hi->pdata.adc_mic_bias[1] = HS_DEF_MIC_ADC_15_BIT_MAX;
	}

	if (pdata->adc_remote[5])
		memcpy(hi->pdata.adc_remote, pdata->adc_remote,
		       sizeof(hi->pdata.adc_remote));

	wake_lock_init(&hi->hs_wake_lock, WAKE_LOCK_SUSPEND, DRIVER_NAME);

	// faux123, no need to have a multi-thread/multi-cpu bound work queue!
	//button_wq = create_workqueue("HS_8X60_BUTTON");
	button_wq = create_singlethread_workqueue("HS_8X60_BUTTON");
	if (button_wq == NULL) {
		ret = -ENOMEM;
		HS_ERR("Failed to create button workqueue");
		goto err_create_button_work_queue;
	}

	hs_8x60_register();
	hs_notify_driver_ready(DRIVER_NAME);

	HS_LOG("--------------------");

	return 0;

err_create_button_work_queue:
	kfree(hi);

	HS_ERR("Failed to register %s driver", DRIVER_NAME);

	return ret;
}
static int htc_headset_mgr_probe(struct platform_device *pdev)
{
	int ret;

	struct htc_headset_mgr_platform_data *pdata = pdev->dev.platform_data;

	HS_LOG("++++++++++++++++++++");

	hi = kzalloc(sizeof(struct htc_headset_mgr_info), GFP_KERNEL);
	if (!hi)
		return -ENOMEM;

	hi->pdata.driver_flag = pdata->driver_flag;
	hi->pdata.headset_devices_num = pdata->headset_devices_num;
	hi->pdata.headset_devices = pdata->headset_devices;
	hi->pdata.headset_config_num = pdata->headset_config_num;
	hi->pdata.headset_config = pdata->headset_config;

	hi->pdata.hptv_det_hp_gpio = pdata->hptv_det_hp_gpio;
	hi->pdata.hptv_det_tv_gpio = pdata->hptv_det_tv_gpio;
	hi->pdata.hptv_sel_gpio = pdata->hptv_sel_gpio;

	hi->pdata.headset_init = pdata->headset_init;
	hi->pdata.headset_power = pdata->headset_power;

	if (hi->pdata.headset_init)
		hi->pdata.headset_init();

	hi->driver_init_seq = 0;

	hi->early_suspend.suspend = htc_headset_mgr_early_suspend;
	hi->early_suspend.resume = htc_headset_mgr_late_resume;
	register_early_suspend(&hi->early_suspend);

	wake_lock_init(&hi->hs_wake_lock, WAKE_LOCK_SUSPEND, DRIVER_NAME);

	hi->hpin_jiffies = jiffies;
	hi->usb_headset.type = USB_NO_HEADSET;
	hi->usb_headset.status = STATUS_DISCONNECTED;

	hi->hs_35mm_type = HEADSET_UNPLUG;
	hi->h2w_35mm_type = HEADSET_UNPLUG;
	hi->is_ext_insert = 0;
	hi->mic_bias_state = 0;
	hi->mic_detect_counter = 0;
	hi->key_level_flag = -1;
	hi->quick_boot_status = 0;

	atomic_set(&hi->btn_state, 0);

	hi->tty_enable_flag = 0;
	hi->fm_flag = 0;
	hi->debug_flag = 0;

	mutex_init(&hi->mutex_lock);

	hi->sdev_h2w.name = "h2w";
	hi->sdev_h2w.print_name = h2w_print_name;

	ret = switch_dev_register(&hi->sdev_h2w);
	if (ret < 0)
		goto err_h2w_switch_dev_register;

	hi->sdev_usb_audio.name = "usb_audio";
	hi->sdev_usb_audio.print_name = usb_audio_print_name;

	ret = switch_dev_register(&hi->sdev_usb_audio);
	if (ret < 0)
		goto err_usb_audio_switch_dev_register;

	detect_wq = create_workqueue("detect");
	if (detect_wq == NULL) {
		ret = -ENOMEM;
		HS_ERR("Failed to create detect workqueue");
		goto err_create_detect_work_queue;
	}

	button_wq = create_workqueue("button");
	if (button_wq  == NULL) {
		ret = -ENOMEM;
		HS_ERR("Failed to create button workqueue");
		goto err_create_button_work_queue;
	}

	hi->input = input_allocate_device();
	if (!hi->input) {
		ret = -ENOMEM;
		goto err_request_input_dev;
	}

	hi->input->name = "h2w headset";
	set_bit(EV_SYN, hi->input->evbit);
	set_bit(EV_KEY, hi->input->evbit);
	set_bit(KEY_END, hi->input->keybit);
	set_bit(KEY_MUTE, hi->input->keybit);
	set_bit(KEY_VOLUMEDOWN, hi->input->keybit);
	set_bit(KEY_VOLUMEUP, hi->input->keybit);
	set_bit(KEY_NEXTSONG, hi->input->keybit);
	set_bit(KEY_PLAYPAUSE, hi->input->keybit);
	set_bit(KEY_PREVIOUSSONG, hi->input->keybit);
	set_bit(KEY_MEDIA, hi->input->keybit);
	set_bit(KEY_SEND, hi->input->keybit);

	ret = input_register_device(hi->input);
	if (ret < 0)
	goto err_register_input_dev;

	ret = register_attributes();
	if (ret)
		goto err_register_attributes;

#ifdef HTC_HEADSET_CONFIG_MSM_RPC
	if (hi->pdata.driver_flag & DRIVER_HS_MGR_RPC_SERVER) {
		/* Create RPC server */
		ret = msm_rpc_create_server(&hs_rpc_server);
		if (ret < 0) {
			HS_ERR("Failed to create RPC server");
			goto err_create_rpc_server;
		}
		HS_LOG("Create RPC server successfully");
	}
#else
	HS_DBG("NOT support RPC (%du, %du)", hs_rpc_server.prog,
	       hs_rpc_server.vers);
#endif

	headset_mgr_init();
	hs_notify_driver_ready(DRIVER_NAME);

	HS_LOG("--------------------");

	return 0;

#ifdef HTC_HEADSET_CONFIG_MSM_RPC
err_create_rpc_server:
#endif

err_register_attributes:
	input_unregister_device(hi->input);

err_register_input_dev:
	input_free_device(hi->input);

err_request_input_dev:
	destroy_workqueue(button_wq);

err_create_button_work_queue:
	destroy_workqueue(detect_wq);

err_create_detect_work_queue:
	switch_dev_unregister(&hi->sdev_usb_audio);

err_usb_audio_switch_dev_register:
	switch_dev_unregister(&hi->sdev_h2w);

err_h2w_switch_dev_register:
	mutex_destroy(&hi->mutex_lock);
	wake_lock_destroy(&hi->hs_wake_lock);
	kfree(hi);

	HS_ERR("Failed to register %s driver", DRIVER_NAME);

	return ret;
}
static int htc_headset_pmic_probe(struct platform_device *pdev)
{
	int ret = 0;
	uint32_t vers = 0;
	struct htc_headset_pmic_platform_data *pdata = pdev->dev.platform_data;

	HS_LOG("++++++++++++++++++++");

	hi = kzalloc(sizeof(struct htc_35mm_pmic_info), GFP_KERNEL);
	if (!hi)
		return -ENOMEM;

	hi->pdata.driver_flag = pdata->driver_flag;
	hi->pdata.hpin_gpio = pdata->hpin_gpio;
	hi->pdata.hpin_irq = pdata->hpin_irq;
	hi->pdata.key_gpio = pdata->key_gpio;
	hi->pdata.key_irq = pdata->key_irq;
	hi->pdata.key_enable_gpio = pdata->key_enable_gpio;
	hi->pdata.hs_controller = pdata->hs_controller;
	hi->pdata.hs_switch = pdata->hs_switch;
	hi->pdata.adc_mic = pdata->adc_mic;

	if (!hi->pdata.adc_mic)
		hi->pdata.adc_mic = HS_DEF_MIC_ADC_16_BIT_MIN;

	if (pdata->adc_mic_bias[0] && pdata->adc_mic_bias[1]) {
		memcpy(hi->pdata.adc_mic_bias, pdata->adc_mic_bias,
		       sizeof(hi->pdata.adc_mic_bias));
		hi->pdata.adc_mic = hi->pdata.adc_mic_bias[0];
	} else {
		hi->pdata.adc_mic_bias[0] = hi->pdata.adc_mic;
		hi->pdata.adc_mic_bias[1] = HS_DEF_MIC_ADC_16_BIT_MAX;
	}

	if (pdata->adc_remote[5])
		memcpy(hi->pdata.adc_remote, pdata->adc_remote,
		       sizeof(hi->pdata.adc_remote));

	if (pdata->adc_metrico[0] && pdata->adc_metrico[1])
		memcpy(hi->pdata.adc_metrico, pdata->adc_metrico,
		       sizeof(hi->pdata.adc_metrico));

	hi->hpin_irq_type = IRQF_TRIGGER_LOW;
	hi->hpin_debounce = HS_JIFFIES_ZERO;
	hi->key_irq_type = IRQF_TRIGGER_LOW;

	wake_lock_init(&hi->hs_wake_lock, WAKE_LOCK_SUSPEND, DRIVER_NAME);

	detect_wq = create_workqueue("HS_PMIC_DETECT");
	if (detect_wq  == NULL) {
		ret = -ENOMEM;
		HS_ERR("Failed to create detect workqueue");
		goto err_create_detect_work_queue;
	}

	button_wq = create_workqueue("HS_PMIC_BUTTON");
	if (button_wq == NULL) {
		ret = -ENOMEM;
		HS_ERR("Failed to create button workqueue");
		goto err_create_button_work_queue;
	}

	if (hi->pdata.hpin_gpio) {
		ret = hs_pmic_request_irq(hi->pdata.hpin_gpio,
				&hi->pdata.hpin_irq, detect_irq_handler,
				hi->hpin_irq_type, "HS_PMIC_DETECT", 1);
		if (ret < 0) {
			HS_ERR("Failed to request PMIC HPIN IRQ (0x%X)", ret);
			goto err_request_detect_irq;
		}
	}

	if (hi->pdata.key_gpio) {
		ret = hs_pmic_request_irq(hi->pdata.key_gpio,
				&hi->pdata.key_irq, button_irq_handler,
				hi->key_irq_type, "HS_PMIC_BUTTON", 1);
		if (ret < 0) {
			HS_ERR("Failed to request PMIC button IRQ (0x%X)", ret);
			goto err_request_button_irq;
		}
	}

	if (hi->pdata.driver_flag & DRIVER_HS_PMIC_RPC_KEY) {
		/* Register ADC RPC client */
		endpoint_adc = msm_rpc_connect(HS_RPC_CLIENT_PROG,
					       HS_RPC_CLIENT_VERS, 0);
		if (IS_ERR(endpoint_adc)) {
			hi->pdata.driver_flag &= ~DRIVER_HS_PMIC_RPC_KEY;
			HS_LOG("Failed to register ADC RPC client");
		} else
			HS_LOG("Register ADC RPC client successfully");
	}

	if (hi->pdata.driver_flag & DRIVER_HS_PMIC_DYNAMIC_THRESHOLD) {
		/* Register threshold RPC client */
		vers = HS_PMIC_RPC_CLIENT_VERS_3_1;
		endpoint_current = msm_rpc_connect_compatible(
				   HS_PMIC_RPC_CLIENT_PROG, vers, 0);
		if (!endpoint_current) {
			vers = HS_PMIC_RPC_CLIENT_VERS_2_1;
			endpoint_current = msm_rpc_connect(
					   HS_PMIC_RPC_CLIENT_PROG, vers, 0);
		}
		if (!endpoint_current) {
			vers = HS_PMIC_RPC_CLIENT_VERS_1_1;
			endpoint_current = msm_rpc_connect(
					   HS_PMIC_RPC_CLIENT_PROG, vers, 0);
		}
		if (!endpoint_current) {
			vers = HS_PMIC_RPC_CLIENT_VERS;
			endpoint_current = msm_rpc_connect(
					   HS_PMIC_RPC_CLIENT_PROG, vers, 0);
		}
		if (IS_ERR(endpoint_current)) {
			hi->pdata.driver_flag &=
				~DRIVER_HS_PMIC_DYNAMIC_THRESHOLD;
			HS_LOG("Failed to register threshold RPC client");
		} else
			HS_LOG("Register threshold RPC client successfully"
			       " (0x%X)", vers);
	}

	hs_pmic_register();
	hs_notify_driver_ready(DRIVER_NAME);

	HS_LOG("--------------------");

	return 0;

err_request_button_irq:
	if (hi->pdata.hpin_gpio) {
		free_irq(hi->pdata.hpin_irq, 0);
		gpio_free(hi->pdata.hpin_gpio);
	}

err_request_detect_irq:
	destroy_workqueue(button_wq);

err_create_button_work_queue:
	destroy_workqueue(detect_wq);

err_create_detect_work_queue:
	wake_lock_destroy(&hi->hs_wake_lock);
	kfree(hi);

	HS_ERR("Failed to register %s driver", DRIVER_NAME);

	return ret;
}
static int htc_headset_mgr_probe(struct platform_device *pdev)
{
	int ret,i;

	struct htc_headset_mgr_platform_data *pdata = pdev->dev.platform_data;

	HS_LOG("++++++++++++++++++++");

	hi = kzalloc(sizeof(struct htc_headset_mgr_info), GFP_KERNEL);
	if (!hi)
		return -ENOMEM;

	hi->pdata.eng_cfg = pdata->eng_cfg;
	hi->pdata.driver_flag = pdata->driver_flag;
	hi->pdata.headset_devices_num = pdata->headset_devices_num;
	hi->pdata.headset_devices = pdata->headset_devices;
	hi->pdata.headset_config_num = pdata->headset_config_num;
	hi->pdata.headset_config = pdata->headset_config;
	hi->pdata.headset_config_1wire_num = pdata->headset_config_1wire_num;
	hi->pdata.headset_config_1wire = pdata->headset_config_1wire;
	hi->pdata.tx_1wire_gpio = pdata->tx_1wire_gpio;
	hi->pdata.rx_1wire_gpio = pdata->rx_1wire_gpio;
	hi->pdata.level_1wire_gpio = pdata->level_1wire_gpio;
	hi->pdata.enable_1wire = pdata->enable_1wire;
	strncpy(hi->pdata.dev_1wire, pdata->dev_1wire, UART_DEV_NAME_LEN);

	hi->pdata.hptv_det_hp_gpio = pdata->hptv_det_hp_gpio;
	hi->pdata.hptv_det_tv_gpio = pdata->hptv_det_tv_gpio;
	hi->pdata.hptv_sel_gpio = pdata->hptv_sel_gpio;

	hi->pdata.headset_init = pdata->headset_init;
	hi->pdata.headset_power = pdata->headset_power;

	if (hi->pdata.headset_init)
		hi->pdata.headset_init();

	hi->driver_init_seq = 0;

	hi->early_suspend.suspend = htc_headset_mgr_early_suspend;
	hi->early_suspend.resume = htc_headset_mgr_late_resume;
	register_early_suspend(&hi->early_suspend);

	wake_lock_init(&hi->hs_wake_lock, WAKE_LOCK_SUSPEND, DRIVER_NAME);

	hi->hpin_jiffies = jiffies;
	hi->usb_headset.type = USB_NO_HEADSET;
	hi->usb_headset.status = STATUS_DISCONNECTED;

	hi->detect_type = HEADSET_ADC;
	hi->hs_35mm_type = HEADSET_UNPLUG;
	hi->h2w_35mm_type = HEADSET_UNPLUG;
	hi->is_ext_insert = 0;
	hi->mic_bias_state = 0;
	hi->mic_detect_counter = 0;
	hi->key_level_flag = -1;
	hi->quick_boot_status = 0;

	atomic_set(&hi->btn_state, 0);

	hi->tty_enable_flag = 0;
	hi->fm_flag = 0;
	hi->debug_flag = 0;

	mutex_init(&hi->mutex_lock);

	hi->sdev.name = "h2w";
	hi->sdev.print_name = h2w_print_name;

	for (i=0;i<HS_BUTTON_EVENT_QUEUE;i++){
		key_event[i] = kzalloc(sizeof(struct button_work), GFP_KERNEL);
		if (!key_event[i]) {
			HS_ERR("Failed to allocate button memory");
			return -ENOMEM;
		}
	}
	key_event_flag = -1;

	ret = switch_dev_register(&hi->sdev);
	if (ret < 0)
		goto err_switch_dev_register;

	detect_wq = create_workqueue("detect");
	if (detect_wq == NULL) {
		ret = -ENOMEM;
		HS_ERR("Failed to create detect workqueue");
		goto err_create_detect_work_queue;
	}

	button_wq = create_workqueue("button");
	if (button_wq  == NULL) {
		ret = -ENOMEM;
		HS_ERR("Failed to create button workqueue");
		goto err_create_button_work_queue;
	}

	hi->input = input_allocate_device();
	if (!hi->input) {
		ret = -ENOMEM;
		goto err_request_input_dev;
	}

	hi->input->name = "h2w headset";
	set_bit(EV_SYN, hi->input->evbit);
	set_bit(EV_KEY, hi->input->evbit);
	set_bit(KEY_END, hi->input->keybit);
	set_bit(KEY_MUTE, hi->input->keybit);
	set_bit(KEY_VOLUMEDOWN, hi->input->keybit);
	set_bit(KEY_VOLUMEUP, hi->input->keybit);
	set_bit(KEY_NEXTSONG, hi->input->keybit);
	set_bit(KEY_PLAYPAUSE, hi->input->keybit);
	set_bit(KEY_PREVIOUSSONG, hi->input->keybit);
	set_bit(KEY_MEDIA, hi->input->keybit);
	set_bit(KEY_SEND, hi->input->keybit);

	ret = input_register_device(hi->input);
	if (ret < 0)
	goto err_register_input_dev;

	ret = register_attributes();
	if (ret)
		goto err_register_attributes;

	if (hi->pdata.driver_flag & DRIVER_HS_MGR_RPC_SERVER) {
		/* Create RPC server */
		/* FIXME */
		/* ret = msm_rpc_create_server(&hs_rpc_server); */
		ret = -1;
		if (ret < 0) {
			HS_ERR("Failed to create RPC server");
			goto err_create_rpc_server;
		}
		HS_LOG("Create RPC server successfully");
	}

	headset_mgr_init();
	hs_notify_driver_ready(DRIVER_NAME);

	HS_LOG("--------------------");

	return 0;

err_create_rpc_server:

err_register_attributes:
	input_unregister_device(hi->input);

err_register_input_dev:
	input_free_device(hi->input);

err_request_input_dev:
	destroy_workqueue(button_wq);

err_create_button_work_queue:
	destroy_workqueue(detect_wq);

err_create_detect_work_queue:
	switch_dev_unregister(&hi->sdev);

err_switch_dev_register:
	mutex_destroy(&hi->mutex_lock);
	wake_lock_destroy(&hi->hs_wake_lock);
	kfree(hi);

	HS_ERR("Failed to register %s driver", DRIVER_NAME);

	return ret;
}
static int htc_headset_gpio_probe(struct platform_device *pdev)
{
	int ret;
	struct htc_headset_gpio_platform_data *pdata = pdev->dev.platform_data;

	HS_LOG("++++++++++++++++++++");

	hi = kzalloc(sizeof(struct htc_headset_gpio_info), GFP_KERNEL);
	if (!hi) {
		HS_ERR("Failed to allocate memory for headset info");
		return -ENOMEM;
	}

	if (pdata->config_headset_gpio)
		pdata->config_headset_gpio();

	hi->pdata.eng_cfg = pdata->eng_cfg;
	hi->pdata.hpin_gpio = pdata->hpin_gpio;
	hi->pdata.key_gpio = pdata->key_gpio;
	hi->pdata.key_enable_gpio = pdata->key_enable_gpio;
	hi->pdata.mic_select_gpio = pdata->mic_select_gpio;

	hi->hpin_debounce = HS_JIFFIES_ZERO;
	hi->key_irq_type = IRQF_TRIGGER_LOW;
	hi->headset_state = 0;

	if ((hi->pdata.eng_cfg == HS_QUO_F_U))
	{
		/* HW power connet cable issue */
		/* EVT XB WORKAROUND Only */
		if (PROJECT_PHASE_XB == htc_get_pcbid_info()) {
			HS_ERR("=====FORCED RETURN!!!!!=====");
			return -ENOMEM;
		}
	}

	detect_wq = create_workqueue("HS_GPIO_DETECT");
	if (detect_wq == NULL) {
		ret = -ENOMEM;
		HS_ERR("Failed to create detect workqueue");
		goto err_create_detect_work_queue;
	}

	button_wq = create_workqueue("HS_GPIO_BUTTON");
	if (button_wq == NULL){
		ret = -ENOMEM;
		HS_ERR("Failed to create button workqueue");
		goto err_create_button_work_queue;
	}

	wake_lock_init(&hi->hs_wake_lock, WAKE_LOCK_SUSPEND, DRIVER_NAME);

	if (hi->pdata.hpin_gpio) {
		ret = hs_gpio_request_irq(hi->pdata.hpin_gpio,
				&hi->hpin_irq, detect_irq_handler,
				IRQF_TRIGGER_LOW, "HS_GPIO_DETECT", 1);
		if (ret < 0) {
			HS_ERR("Failed to request GPIO HPIN IRQ (0x%X)", ret);
			goto err_request_detect_irq;
		}
	}

	if (hi->pdata.key_gpio) {
		ret = hs_gpio_request(hi->pdata.key_gpio, "HS_GPIO_BUTTON");
		if (ret < 0)
			HS_ERR("Failed to request GPIO HPIN IRQ (0x%X)", ret);
	}

	hs_gpio_register();
	hs_notify_driver_ready(DRIVER_NAME);

	HS_LOG("--------------------");

	return 0;

err_request_detect_irq:
	wake_lock_destroy(&hi->hs_wake_lock);
	destroy_workqueue(button_wq);

err_create_button_work_queue:
	destroy_workqueue(detect_wq);

err_create_detect_work_queue:
	kfree(hi);

	HS_ERR("Failed to register %s driver", DRIVER_NAME);

	return ret;
}
static int htc_headset_gpio_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct htc_headset_gpio_platform_data *pdata;

	HS_LOG("++++++++++++++++++++");

	hi = kzalloc(sizeof(struct htc_headset_gpio_info), GFP_KERNEL);
	if (!hi) {
		HS_ERR("Failed to allocate memory for headset info");
		return -ENOMEM;
	}

	if (pdev->dev.of_node) {
		pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
		if (pdata == NULL)
			ret = -ENOMEM;
		ret = htc_headset_gpio_parse_dt(&pdev->dev, pdata);
	} else {
		HS_LOG("old style\n");
		pdata = pdev->dev.platform_data;
	}

	if (pdata->config_headset_gpio)
		pdata->config_headset_gpio();

	hi->pdata.uart_gpio       = pdata->uart_gpio;
	hi->pdata.hpin_gpio       = pdata->hpin_gpio;
	hi->pdata.key_gpio        = pdata->key_gpio;
	hi->pdata.key_enable_gpio = pdata->key_enable_gpio;
	hi->pdata.mic_select_gpio = pdata->mic_select_gpio;

	hi->hpin_debounce         = HS_JIFFIES_ZERO;
	hi->key_irq_type          = IRQF_TRIGGER_NONE;
	hi->headset_state         = 0;

	detect_wq = create_workqueue("HS_GPIO_DETECT");
	if (detect_wq == NULL) {
		ret = -ENOMEM;
		HS_ERR("Failed to create detect workqueue");
		goto err_create_detect_work_queue;
	}

	button_wq = create_workqueue("HS_GPIO_BUTTON");
	if (button_wq == NULL) {
		ret = -ENOMEM;
		HS_ERR("Failed to create button workqueue");
		goto err_create_button_work_queue;
	}

	wake_lock_init(&hi->hs_wake_lock, WAKE_LOCK_SUSPEND, DRIVER_NAME);

	if (hi->pdata.uart_gpio) {
			ret = hs_gpio_request_output(hi->pdata.uart_gpio, "HS_GPIO_UART", 0);

		if (ret < 0) {
			HS_ERR("Fail to request GPIO UART(0x%x)", ret);
		}
	}

	if (hi->pdata.hpin_gpio) {
		ret = hs_gpio_request_irq(hi->pdata.hpin_gpio,
				&hi->hpin_irq, detect_irq_handler,
				IRQF_TRIGGER_NONE, "HS_GPIO_DETECT", 1);
		if (ret < 0) {
			HS_ERR("Failed to request GPIO HPIN IRQ (0x%X)", ret);
			goto err_request_detect_irq;
		}
		disable_irq(hi->hpin_irq);
	}

	if (hi->pdata.key_gpio) {
		ret = hs_gpio_request_irq(hi->pdata.key_gpio,
				&hi->key_irq, button_irq_handler,
				hi->key_irq_type, "HS_GPIO_BUTTON", 1);
		if (ret < 0) {
			HS_ERR("Failed to request GPIO button IRQ (0x%X)", ret);
			goto err_request_button_irq;
		}
		disable_irq(hi->key_irq);
	}

	queue_delayed_work(detect_wq, &irq_init_work, HS_JIFFIES_IRQ_INIT);

	hs_gpio_register();
#ifndef CONFIG_OF
	hs_notify_driver_ready(DRIVER_NAME);
#endif
	HS_LOG("--------------------");

	return 0;

err_request_button_irq:
	if (hi->pdata.hpin_gpio) {
		free_irq(hi->hpin_irq, 0);
		gpio_free(hi->pdata.hpin_gpio);
	}

err_request_detect_irq:
	wake_lock_destroy(&hi->hs_wake_lock);
	destroy_workqueue(button_wq);

err_create_button_work_queue:
	destroy_workqueue(detect_wq);

err_create_detect_work_queue:
	kfree(hi);

	HS_ERR("Failed to register %s driver", DRIVER_NAME);

	return ret;
}
static int htc_headset_gpio_probe(struct platform_device *pdev)
{
	int ret;
	struct htc_headset_gpio_platform_data *pdata = pdev->dev.platform_data;

	HS_LOG("++++++++++++++++++++");

	hi = kzalloc(sizeof(struct htc_headset_gpio_info), GFP_KERNEL);
	if (!hi) {
		HS_ERR("Failed to allocate memory for headset info");
		return -ENOMEM;
	}

	if (pdata->config_headset_gpio)
		pdata->config_headset_gpio();

	hi->pdata.hpin_gpio = pdata->hpin_gpio;
	hi->pdata.key_gpio = pdata->key_gpio;
	hi->pdata.key_enable_gpio = pdata->key_enable_gpio;
	hi->pdata.mic_select_gpio = pdata->mic_select_gpio;

	hi->hpin_debounce = HS_JIFFIES_ZERO;
	hi->key_irq_type = IRQF_TRIGGER_LOW;
	hi->headset_state = 0;

	detect_wq = create_workqueue("HS_GPIO_DETECT");
	if (detect_wq == NULL) {
		ret = -ENOMEM;
		HS_ERR("Failed to create detect workqueue");
		goto err_create_detect_work_queue;
	}

	button_wq = create_workqueue("HS_GPIO_BUTTON");
	if (button_wq == NULL) {
		ret = -ENOMEM;
		HS_ERR("Failed to create button workqueue");
		goto err_create_button_work_queue;
	}

	wake_lock_init(&hi->hs_wake_lock, WAKE_LOCK_SUSPEND, DRIVER_NAME);

	if (hi->pdata.hpin_gpio) {
		ret = hs_gpio_request_irq(hi->pdata.hpin_gpio,
				&hi->hpin_irq, detect_irq_handler,
				IRQF_TRIGGER_LOW, "HS_GPIO_DETECT", 1);
		if (ret < 0) {
			HS_ERR("Failed to request GPIO HPIN IRQ (0x%X)", ret);
			goto err_request_detect_irq;
		}
	}

	if (hi->pdata.key_gpio) {
		ret = hs_gpio_request_irq(hi->pdata.key_gpio,
				&hi->key_irq, button_irq_handler,
				hi->key_irq_type, "HS_GPIO_BUTTON", 1);
		if (ret < 0) {
			HS_ERR("Failed to request GPIO button IRQ (0x%X)", ret);
			goto err_request_button_irq;
		}
	}

	hs_gpio_register();
	hs_notify_driver_ready(DRIVER_NAME);

	HS_LOG("--------------------");

	return 0;

err_request_button_irq:
	if (hi->pdata.hpin_gpio) {
		free_irq(hi->hpin_irq, 0);
		gpio_free(hi->pdata.hpin_gpio);
	}

err_request_detect_irq:
	wake_lock_destroy(&hi->hs_wake_lock);
	destroy_workqueue(button_wq);

err_create_button_work_queue:
	destroy_workqueue(detect_wq);

err_create_detect_work_queue:
	kfree(hi);

	HS_ERR("Failed to register %s driver", DRIVER_NAME);

	return ret;
}
static int htc_headset_gpio_probe(struct platform_device *pdev)
{
	int ret;
	struct htc_headset_gpio_platform_data *pdata = pdev->dev.platform_data;

	HS_LOG("++++++++++++++++++++");

	hi = kzalloc(sizeof(struct htc_headset_gpio_info), GFP_KERNEL);
	if (!hi) {
		HS_LOG("Failed to allocate memory for headset info");
		return -ENOMEM;
	}

	hi->pdata.hpin_gpio = pdata->hpin_gpio;
	hi->pdata.key_enable_gpio = pdata->key_enable_gpio;
	hi->pdata.mic_select_gpio = pdata->mic_select_gpio;

	hi->hpin_debounce = HS_JIFFIES_INSERT;
	hi->headset_state = 0;

	detect_wq = create_workqueue("detect");
	if (detect_wq == NULL) {
		ret = -ENOMEM;
		HS_LOG("Failed to create detect workqueue");
		goto err_create_detect_work_queue;
	}

	wake_lock_init(&hi->hs_wake_lock, WAKE_LOCK_SUSPEND, DRIVER_NAME);

	if (hi->pdata.hpin_gpio) {
		ret = gpio_request(hi->pdata.hpin_gpio, "HS_GPIO_DETECT");
		if (ret < 0)
			goto err_gpio_request;

		ret = gpio_direction_input(hi->pdata.hpin_gpio);
		if (ret < 0)
			goto err_set_detect_gpio;

		ret = gpio_to_irq(hi->pdata.hpin_gpio);
		if (ret < 0)
			goto err_gpio_to_irq;
		else
			hi->hpin_irq = (unsigned int) ret;

		ret = request_irq(hi->hpin_irq, detect_irq_handler,
				  IRQF_TRIGGER_LOW, "HS_GPIO_DETECT", NULL);
		if (ret < 0)
			goto err_request_irq;

		ret = set_irq_wake(hi->hpin_irq, 1);
		if (ret < 0)
			goto err_set_irq_wake;
	}

	hs_gpio_register();
	hs_notify_driver_ready(DRIVER_NAME);

	HS_LOG("--------------------");

	return 0;

err_set_irq_wake:
	if (hi->pdata.hpin_gpio)
		free_irq(hi->hpin_irq, 0);

err_request_irq:
err_gpio_to_irq:
err_set_detect_gpio:
	if (hi->pdata.hpin_gpio)
		gpio_free(hi->pdata.hpin_gpio);

err_gpio_request:
	wake_lock_destroy(&hi->hs_wake_lock);
	destroy_workqueue(detect_wq);

err_create_detect_work_queue:
	kfree(hi);

	HS_LOG("Failed to register %s driver", DRIVER_NAME);

	return ret;
}
static int htc_headset_pmic_probe(struct platform_device *pdev)
{
	int ret = 0;
	uint32_t vers = 0;
	struct htc_headset_pmic_platform_data *pdata = pdev->dev.platform_data;

	HS_LOG("++++++++++++++++++++");

	pmic_info = kzalloc(sizeof(struct htc_35mm_pmic_info), GFP_KERNEL);
	if (!pmic_info)
		return -ENOMEM;

	pmic_info->pdata.driver_flag = pdata->driver_flag;
	pmic_info->pdata.hpin_gpio = pdata->hpin_gpio;
	pmic_info->pdata.hpin_irq = pdata->hpin_irq;
	pmic_info->pdata.key_enable_gpio = pdata->key_enable_gpio;
	pmic_info->pdata.hs_controller = pdata->hs_controller;
	pmic_info->pdata.hs_switch = pdata->hs_switch;
	pmic_info->pdata.adc_mic = pdata->adc_mic;

	if (!pmic_info->pdata.adc_mic)
		pmic_info->pdata.adc_mic = HS_DEF_MIC_ADC_16_BIT;

	if (pdata->adc_remote[5])
		memcpy(pmic_info->pdata.adc_remote, pdata->adc_remote,
		       sizeof(pmic_info->pdata.adc_remote));

	if (pdata->adc_metrico[0] && pdata->adc_metrico[1])
		memcpy(pmic_info->pdata.adc_metrico, pdata->adc_metrico,
		       sizeof(pmic_info->pdata.adc_metrico));

	pmic_info->hpin_irq_type = IRQF_TRIGGER_LOW;
	pmic_info->hpin_debounce = HS_JIFFIES_INSERT;

	wake_lock_init(&pmic_info->hs_wake_lock, WAKE_LOCK_SUSPEND,
		       DRIVER_NAME);

	detect_wq = create_workqueue("detection");
	if (detect_wq  == NULL) {
		ret = -ENOMEM;
		goto err_create_detect_work_queue;
	}

	if (pmic_info->pdata.hpin_irq) {
		ret = request_irq(pmic_info->pdata.hpin_irq, htc_35mm_pmic_irq,
				  pmic_info->hpin_irq_type, "HS_PMIC_DETECT",
				  NULL);
		if (ret < 0) {
			HS_LOG("Failed to request PMIC HPIN IRQ (0x%X)", ret);
			goto err_request_detect_irq;
		}

		ret = set_irq_wake(pmic_info->pdata.hpin_irq, 1);
		if (ret < 0)
			HS_LOG("Failed to set PMIC HPIN IRQ wake");
	}

	if (pmic_info->pdata.driver_flag & DRIVER_HS_PMIC_RPC_KEY) {
		/* Register ADC RPC client */
		endpoint_adc = msm_rpc_connect(HS_RPC_CLIENT_PROG,
					       HS_RPC_CLIENT_VERS, 0);
		if (IS_ERR(endpoint_adc)) {
			pmic_info->pdata.driver_flag &= ~DRIVER_HS_PMIC_RPC_KEY;
			HS_LOG("Failed to register ADC RPC client");
		} else
			HS_LOG("Register ADC RPC client successfully");
	}

	if (pmic_info->pdata.driver_flag & DRIVER_HS_PMIC_DYNAMIC_THRESHOLD) {
		/* Register threshold RPC client */
		vers = HS_PMIC_RPC_CLIENT_VERS_3_1;
		endpoint_current = msm_rpc_connect_compatible(
				   HS_PMIC_RPC_CLIENT_PROG, vers, 0);
		if (!endpoint_current) {
			vers = HS_PMIC_RPC_CLIENT_VERS_2_1;
			endpoint_current = msm_rpc_connect(
					   HS_PMIC_RPC_CLIENT_PROG, vers, 0);
		}
		if (!endpoint_current) {
			vers = HS_PMIC_RPC_CLIENT_VERS_1_1;
			endpoint_current = msm_rpc_connect(
					   HS_PMIC_RPC_CLIENT_PROG, vers, 0);
		}
		if (!endpoint_current) {
			vers = HS_PMIC_RPC_CLIENT_VERS;
			endpoint_current = msm_rpc_connect(
					   HS_PMIC_RPC_CLIENT_PROG, vers, 0);
		}
		if (IS_ERR(endpoint_current)) {
			pmic_info->pdata.driver_flag &=
				~DRIVER_HS_PMIC_DYNAMIC_THRESHOLD;
			HS_LOG("Failed to register threshold RPC client");
		} else
			HS_LOG("Register threshold RPC client successfully"
			       " (0x%X)", vers);
	}

	hs_pmic_register();
	hs_notify_driver_ready(DRIVER_NAME);

	HS_LOG("--------------------");

	return 0;

err_request_detect_irq:
	destroy_workqueue(detect_wq);

err_create_detect_work_queue:
	wake_lock_destroy(&pmic_info->hs_wake_lock);
	kfree(pmic_info);

	HS_LOG("Failed to register %s driver", DRIVER_NAME);

	return ret;
}
Exemple #14
0
static int htc_headset_mgr_probe(struct platform_device *pdev)
{
    int ret;

    struct htc_headset_mgr_platform_data *pdata = pdev->dev.platform_data;

    HS_LOG("++++++++++++++++++++");

    hi = kzalloc(sizeof(struct htc_headset_mgr_info), GFP_KERNEL);
    if (!hi)
        return -ENOMEM;

    hi->pdata.driver_flag = pdata->driver_flag;
    hi->pdata.headset_devices_num = pdata->headset_devices_num;
    hi->pdata.headset_devices = pdata->headset_devices;

    hi->driver_init_seq = 0;

    wake_lock_init(&hi->hs_wake_lock, WAKE_LOCK_SUSPEND, DRIVER_NAME);

    hi->hpin_jiffies = jiffies;
    hi->usb_headset.type = USB_NO_HEADSET;
    hi->usb_headset.status = STATUS_DISCONNECTED;

    hi->ext_35mm_status = HTC_35MM_UNPLUG;
    hi->h2w_35mm_status = HTC_35MM_UNPLUG;
    hi->is_ext_insert = 0;
    hi->mic_bias_state = 0;
    hi->mic_detect_counter = 0;
    hi->key_level_flag = -1;

    atomic_set(&hi->btn_state, 0);

    hi->tty_enable_flag = 0;
    hi->fm_flag = 0;
    hi->debug_flag = 0;

    mutex_init(&hi->mutex_lock);

    hi->sdev.name = "h2w";
    hi->sdev.print_name = h2w_print_name;

    ret = switch_dev_register(&hi->sdev);
    if (ret < 0)
        goto err_switch_dev_register;

    detect_wq = create_workqueue("detect");
    if (detect_wq == NULL) {
        ret = -ENOMEM;
        HS_ERR("Failed to create detect workqueue");
        goto err_create_detect_work_queue;
    }

    button_wq = create_workqueue("button");
    if (button_wq  == NULL) {
        ret = -ENOMEM;
        HS_ERR("Failed to create button workqueue");
        goto err_create_button_work_queue;
    }

    hi->input = input_allocate_device();
    if (!hi->input) {
        ret = -ENOMEM;
        goto err_request_input_dev;
    }

    hi->input->name = "h2w headset";
    set_bit(EV_SYN, hi->input->evbit);
    set_bit(EV_KEY, hi->input->evbit);
    set_bit(KEY_END, hi->input->keybit);
    set_bit(KEY_MUTE, hi->input->keybit);
    set_bit(KEY_VOLUMEDOWN, hi->input->keybit);
    set_bit(KEY_VOLUMEUP, hi->input->keybit);
    set_bit(KEY_NEXTSONG, hi->input->keybit);
    set_bit(KEY_PLAYPAUSE, hi->input->keybit);
    set_bit(KEY_PREVIOUSSONG, hi->input->keybit);
    set_bit(KEY_MEDIA, hi->input->keybit);
    set_bit(KEY_SEND, hi->input->keybit);

    ret = input_register_device(hi->input);
    if (ret < 0)
        goto err_register_input_dev;

    ret = register_attributes();
    if (ret)
        goto err_register_attributes;

    if (hi->pdata.driver_flag & DRIVER_HS_MGR_RPC_SERVER) {
        /* Create RPC server */
        ret = msm_rpc_create_server(&hs_rpc_server);
        if (ret < 0) {
            HS_ERR("Failed to create RPC server");
            goto err_create_rpc_server;
        }
        HS_LOG("Create RPC server successfully");
    }

    hs_notify_driver_ready(DRIVER_NAME);

    HS_LOG("--------------------");

    return 0;

err_create_rpc_server:

err_register_attributes:
    input_unregister_device(hi->input);

err_register_input_dev:
    input_free_device(hi->input);

err_request_input_dev:
    destroy_workqueue(button_wq);

err_create_button_work_queue:
    destroy_workqueue(detect_wq);

err_create_detect_work_queue:
    switch_dev_unregister(&hi->sdev);

err_switch_dev_register:
    mutex_destroy(&hi->mutex_lock);
    wake_lock_destroy(&hi->hs_wake_lock);
    kfree(hi);

    HS_ERR("Failed to register %s driver", DRIVER_NAME);

    return ret;
}