예제 #1
0
static int headset_switch_probe(struct platform_device *pdev)
{
	struct gpio_switch_platform_data *pdata = pdev->dev.platform_data;
	struct v210_headset_switch_data *switch_data;
	int ret = 0;

	if (!pdata)
		return -EBUSY;

	switch_data = kzalloc(sizeof(struct v210_headset_switch_data), GFP_KERNEL);
	if (!switch_data)
		return -ENOMEM;

	switch_data->sdev.name = pdata->name;
	switch_data->gpio = HP_DETECT_PIN;
	switch_data->ear_jack_gpio = EAR_DETECT_PIN;
	switch_data->name_on = pdata->name_on;
	switch_data->name_off = pdata->name_off;
	switch_data->state_on = pdata->state_on;
	switch_data->state_off = pdata->state_off;
	switch_data->sdev.print_state = headset_switch_print_state;
	switch_data->set_micbias_state=sec_jack_set_micbias_state;
	
    	ret = switch_dev_register(&switch_data->sdev);
	if (ret < 0)
		goto err_switch_dev_register;

	ret = gpio_request(switch_data->gpio, HP_DETEST_IRQ);
	if (ret)
	    printk(KERN_ERR "#### failed to request GPH0-6 ");

	ret = gpio_request(switch_data->ear_jack_gpio, "EAR_DET_GPIO");
	if (ret)
	    printk(KERN_ERR "#### failed to request GPH0-3 ");
#if 0	 //mask 
	gpio_direction_input(switch_data->gpio);
	switch_data->irq = gpio_to_irq(switch_data->gpio);
#else
	#ifndef DOUBLE_IRQ_CHECK	
	 s3c_gpio_cfgpin(switch_data->ear_jack_gpio, S3C_GPIO_INPUT);
	 s3c_gpio_setpull(switch_data->ear_jack_gpio, S3C_GPIO_PULL_UP);
	#else
	s3c_gpio_cfgpin(switch_data->ear_jack_gpio, S3C_GPIO_SPECIAL(0x0f)); //Eint6
	s3c_gpio_setpull(switch_data->ear_jack_gpio, S3C_GPIO_PULL_UP);
	set_irq_type(EAR_ENIT_NUM, IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING);	
	#endif
//	s3c_gpio_cfgpin(switch_data->gpio, S3C_GPIO_INPUT);
	s3c_gpio_cfgpin(switch_data->gpio, S3C_GPIO_SPECIAL(0xf)); //Eint6
	s3c_gpio_setpull(switch_data->gpio, S3C_GPIO_PULL_NONE);
	set_irq_type(ENIT_NUM, IRQF_TRIGGER_RISING |IRQF_TRIGGER_FALLING);

	switch_data->irq = ENIT_NUM;
	switch_data->ear_jack_irq = EAR_ENIT_NUM;
#endif
	gpio_set_debounce(switch_data->gpio, 100);
	gpio_set_debounce(switch_data->ear_jack_gpio, 143);

	SwitchData=switch_data;

	INIT_WORK(&switch_data->work, headset_switch_work);

	init_timer(&earphone_timer);
	earphone_timer.function = earphone_key_scan;
	 earphone_timer.expires = jiffies + EARPHONE_KEY_DETECT_INTERVAL;
	add_timer(&earphone_timer);

	
	INIT_WORK(&earphone_report_work, report_4pole_earphone);
	
		
	INIT_WORK(&delay_open_micbias, delay_micbias_open);


	ret = request_irq(switch_data->irq ,headset_irq_handler, IRQF_SHARED /*| IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING*/, switch_data->sdev.name, switch_data);
	if(ret < 0)
	{
		printk(KERN_ERR "%s(), IRQ%d not available", __func__, switch_data->irq);
		goto err_request_gpio;
	}

	#ifdef DOUBLE_IRQ_CHECK
	ret = request_irq(switch_data->ear_jack_irq ,headset_irq_handler, IRQF_SHARED, switch_data->sdev.name, switch_data);
	if(ret < 0)
	{
		printk(KERN_ERR "%s(), IRQ%d not available", __func__, switch_data->ear_jack_irq);
		goto err_request_gpio;
	}
	//enable_irq_wake(switch_data->irq);
	#endif
	
	/* Perform initial detection */
	headset_switch_work(&switch_data->work);

	return 0;

err_request_gpio:
    switch_dev_unregister(&switch_data->sdev);
err_switch_dev_register:
	kfree(switch_data);

	return ret;
}
예제 #2
0
static int headset_switch_probe(struct platform_device *pdev)
{
	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
	struct pm860x_headset_info *info;
	struct pm860x_platform_data *pm860x_pdata;
	struct gpio_switch_platform_data *pdata_headset = pdev->dev.platform_data;
	struct gpio_switch_platform_data *pdata_hook = pdata_headset + 1;
	struct headset_switch_data *switch_data_headset, *switch_data_hook;
	int irq_headset, irq_hook, ret = 0;

	if (pdev->dev.parent->platform_data) {
		pm860x_pdata = pdev->dev.parent->platform_data;
	} else {
		pr_debug("Invalid pm860x platform data!\n");
		return -EINVAL;
	}

	if (pdata_headset == NULL || pdata_hook == NULL) {
		pr_debug("Invalid gpio switch platform data!\n");
		return -EBUSY;
	}

	irq_headset = platform_get_irq(pdev, 0);
	if (irq_headset < 0) {
		dev_err(&pdev->dev, "No IRQ resource for headset!\n");
		return -EINVAL;
	}
	irq_hook = platform_get_irq(pdev, 1);
	if (irq_hook < 0) {
		dev_err(&pdev->dev, "No IRQ resource for hook!\n");
		return -EINVAL;
	}

	info = kzalloc(sizeof(struct pm860x_headset_info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;
	info->chip = chip;
	info->dev = &pdev->dev;
	info->irq_headset = irq_headset + chip->irq_base;
	info->irq_hook = irq_hook + chip->irq_base;
	info->headset_flag = pm860x_pdata->headset_flag;
	info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;

	switch_data_headset = kzalloc(sizeof(struct headset_switch_data), GFP_KERNEL);
	if (!switch_data_headset)
		return -ENOMEM;
	switch_data_hook = kzalloc(sizeof(struct headset_switch_data), GFP_KERNEL);
	if (!switch_data_hook)
		return -ENOMEM;

	switch_data_headset->sdev.name = pdata_headset->name;
	switch_data_headset->name_on = pdata_headset->name_on;
	switch_data_headset->name_off = pdata_headset->name_off;
	switch_data_headset->state_on = pdata_headset->state_on;
	switch_data_headset->state_off = pdata_headset->state_off;
	switch_data_headset->sdev.print_state = switch_headset_print_state;
	info->psw_data_headset = switch_data_headset;

	switch_data_hook->sdev.name = pdata_hook->name;
	switch_data_hook->name_on = pdata_hook->name_on;
	switch_data_hook->name_off = pdata_hook->name_off;
	switch_data_hook->state_on = pdata_hook->state_on;
	switch_data_hook->state_off = pdata_hook->state_off;
	switch_data_hook->sdev.print_state = switch_headset_print_state;
	info->psw_data_hook = switch_data_hook;

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

	ret = request_threaded_irq(info->irq_headset, NULL, pm860x_headset_handler,
				   IRQF_ONESHOT, "headset", info);
	if (ret < 0) {
		dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
			info->irq_headset, ret);
		goto out_irq_headset;
	}
	ret = request_threaded_irq(info->irq_hook, NULL, pm860x_headset_handler,
				   IRQF_ONESHOT, "hook", info);
	if (ret < 0) {
		dev_err(chip->dev, "Failed to request IRQ: #%d: %d\n",
			info->irq_hook, ret);
		goto out_irq_hook;
	}

	platform_set_drvdata(pdev, info);

	/* set hook detection debounce time to 24ms, it's the best setting we experienced */
	pm860x_set_bits(info->i2c, PM8607_HEADSET_DECTION, PM8607_HEADSET_BTN_DBNC, 0x10);

	//pm860x_set_bits(info->i2c, PM8607_HEADSET_DECTION, PM8607_HEADSET_PERIOD, 0x04);
	
	/* set headset period to continuous detection */
	pm860x_set_bits(info->i2c, PM8607_HEADSET_DECTION, PM8607_HEADSET_PERIOD, 0x06);

	/* set MIC detection parameter: MIC period set to 250msec */
	pm860x_reg_write(info->i2c, PM8607_MIC_DECTION, 0xDC);

	/* mask hook interrupt since we don't want the first false hook press down detection
	when inserting a headset without Mic */
	pm860x_set_bits(info->i2c, PM8607_INT_MASK_3, PM8607_INT_EN_HOOK, 0);

	/* enable headset detection */
	pm860x_set_bits(info->i2c, PM8607_HEADSET_DECTION, PM8607_HEADSET_EN_HS_DET, 1);

	INIT_WORK(&info->work_headset, headset_switch_work);
	INIT_WORK(&info->work_hook, hook_switch_work);

	/* Perform initial detection */
	headset_switch_work(&info->work_headset);
	hook_switch_work(&info->work_hook);

	return 0;

err_switch_dev_register:
	kfree(switch_data_headset);
	kfree(switch_data_hook);

out_irq_hook:
	free_irq(info->irq_headset, info);
out_irq_headset:
	kfree(info);
	return ret;
}