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; }
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; }