static int wacom_i2c_input_open(struct input_dev *dev) { struct wacom_i2c *wac_i2c = input_get_drvdata(dev); int ret = 0; static bool init_insert = true; printk(KERN_DEBUG"epen:%s\n", __func__); #ifdef WACOM_PEN_DETECT if (unlikely(init_insert)) { init_pen_insert(wac_i2c); init_insert = false; } #endif #if 0 ret = wait_for_completion_interruptible_timeout(&wac_i2c->init_done, msecs_to_jiffies(1 * MSEC_PER_SEC)); if (ret < 0) { dev_err(&wac_i2c->client->dev, "error while waiting for device to init (%d)\n", ret); ret = -ENXIO; goto err_open; } if (ret == 0) { dev_err(&wac_i2c->client->dev, "timedout while waiting for device to init\n"); ret = -ENXIO; goto err_open; } #endif wacom_power_on(wac_i2c); err_open: return ret; }
static int wacom_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct wacom_g5_platform_data *pdata = client->dev.platform_data; struct wacom_i2c *wac_i2c; struct input_dev *input; int ret = 0; if (pdata == NULL) { printk(KERN_ERR "%s: no pdata\n", __func__); ret = -ENODEV; goto err_i2c_fail; } /*Check I2C functionality */ ret = i2c_check_functionality(client->adapter, I2C_FUNC_I2C); if (!ret) { printk(KERN_ERR "epen:No I2C functionality found\n"); ret = -ENODEV; goto err_i2c_fail; } /*Obtain kernel memory space for wacom i2c */ wac_i2c = kzalloc(sizeof(struct wacom_i2c), GFP_KERNEL); if (NULL == wac_i2c) { printk(KERN_ERR "epen:failed to allocate wac_i2c.\n"); ret = -ENOMEM; goto err_alloc_mem; } wac_i2c->client_boot = i2c_new_dummy(client->adapter, WACOM_I2C_BOOT); if (!wac_i2c->client_boot) { dev_err(&client->dev, "Fail to register sub client[0x%x]\n", WACOM_I2C_BOOT); } input = input_allocate_device(); if (NULL == input) { printk(KERN_ERR "epen:failed to allocate input device.\n"); ret = -ENOMEM; goto err_alloc_input_dev; } wacom_i2c_set_input_values(client, wac_i2c, input); wac_i2c->wac_feature = &wacom_feature_EMR; wac_i2c->wac_pdata = pdata; wac_i2c->input_dev = input; wac_i2c->client = client; wac_i2c->irq = client->irq; /* init_completion(&wac_i2c->init_done); */ #ifdef WACOM_PDCT_WORK_AROUND wac_i2c->irq_pdct = gpio_to_irq(pdata->gpio_pendct); wac_i2c->pen_pdct = PDCT_NOSIGNAL; #endif #ifdef WACOM_PEN_DETECT wac_i2c->gpio_pen_insert = pdata->gpio_pen_insert; #endif #ifdef WACOM_IMPORT_FW_ALGO wac_i2c->use_offset_table = true; wac_i2c->use_aveTransition = false; wacom_init_fw_algo(wac_i2c); #endif /*Change below if irq is needed */ wac_i2c->irq_flag = 1; /*Register callbacks */ wac_i2c->callbacks.check_prox = wacom_check_emr_prox; if (wac_i2c->wac_pdata->register_cb) wac_i2c->wac_pdata->register_cb(&wac_i2c->callbacks); /* Firmware Feature */ wacom_i2c_init_firm_data(); /* Power on */ wac_i2c->wac_pdata->resume_platform_hw(); msleep(200); wac_i2c->power_enable = true; wacom_i2c_query(wac_i2c); wacom_init_abs_params(wac_i2c); input_set_drvdata(input, wac_i2c); /*Change below if irq is needed */ wac_i2c->irq_flag = 1; /*Set client data */ i2c_set_clientdata(client, wac_i2c); i2c_set_clientdata(wac_i2c->client_boot, wac_i2c); /*Initializing for semaphor */ mutex_init(&wac_i2c->lock); mutex_init(&wac_i2c->update_lock); mutex_init(&wac_i2c->irq_lock); wake_lock_init(&wac_i2c->fw_wakelock, WAKE_LOCK_SUSPEND, "wacom"); INIT_DELAYED_WORK(&wac_i2c->resume_work, wacom_i2c_resume_work); #ifdef LCD_FREQ_SYNC mutex_init(&wac_i2c->freq_write_lock); INIT_WORK(&wac_i2c->lcd_freq_work, wacom_i2c_lcd_freq_work); INIT_DELAYED_WORK(&wac_i2c->lcd_freq_done_work, wacom_i2c_finish_lcd_freq_work); if (likely(system_rev >= LCD_FREQ_SUPPORT_HWID)) wac_i2c->use_lcd_freq_sync = true; #endif #ifdef WACOM_USE_SOFTKEY_BLOCK INIT_DELAYED_WORK(&wac_i2c->softkey_block_work, wacom_i2c_block_softkey_work); wac_i2c->block_softkey = false; #endif INIT_WORK(&wac_i2c->update_work, wacom_i2c_update_work); /*init wacom booster*/ #ifdef WACOM_BOOSTER wacom_init_dvfs(wac_i2c); wac_i2c->boost_level = WACOM_BOOSTER_LEVEL2; #endif /*Before registering input device, data in each input_dev must be set */ ret = input_register_device(input); if (ret) { pr_err("epen:failed to register input device.\n"); goto err_register_device; } #ifdef CONFIG_HAS_EARLYSUSPEND wac_i2c->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; wac_i2c->early_suspend.suspend = wacom_i2c_early_suspend; wac_i2c->early_suspend.resume = wacom_i2c_late_resume; register_early_suspend(&wac_i2c->early_suspend); #endif wac_i2c->dev = device_create(sec_class, NULL, 0, NULL, "sec_epen"); if (IS_ERR(wac_i2c->dev)) { printk(KERN_ERR "Failed to create device(wac_i2c->dev)!\n"); ret = -ENODEV; goto err_create_device; } dev_set_drvdata(wac_i2c->dev, wac_i2c); ret = sysfs_create_group(&wac_i2c->dev->kobj, &epen_attr_group); if (ret) { printk(KERN_ERR "epen:failed to create sysfs group\n"); goto err_sysfs_create_group; } /* firmware info */ printk(KERN_NOTICE "epen:wacom fw ver : 0x%x, new fw ver : 0x%x\n", wac_i2c->wac_feature->fw_version, fw_ver_file); /*Request IRQ */ if (wac_i2c->irq_flag) { ret = request_threaded_irq(wac_i2c->irq, NULL, wacom_interrupt, IRQF_DISABLED | EPEN_IRQF_TRIGGER_TYPE | IRQF_ONESHOT, "sec_epen_irq", wac_i2c); if (ret < 0) { printk(KERN_ERR "epen:failed to request irq(%d) - %d\n", wac_i2c->irq, ret); goto err_request_irq; } #if defined(WACOM_PDCT_WORK_AROUND) ret = request_threaded_irq(wac_i2c->irq_pdct, NULL, wacom_interrupt_pdct, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "sec_epen_pdct", wac_i2c); if (ret < 0) { printk(KERN_ERR "epen:failed to request irq(%d) - %d\n", wac_i2c->irq_pdct, ret); goto err_request_irq; } #endif } #ifdef WACOM_PEN_DETECT init_pen_insert(wac_i2c); #endif wac_i2c->update_info.forced = false; wac_i2c->update_info.fw_path = FW_BUILT_IN; schedule_work(&wac_i2c->update_work); /*complete_all(&wac_i2c->init_done);*/ return 0; err_request_irq: wake_lock_destroy(&wac_i2c->fw_wakelock); sysfs_remove_group(&wac_i2c->dev->kobj, &epen_attr_group); err_sysfs_create_group: device_destroy(sec_class, (dev_t)NULL); err_create_device: input_unregister_device(input); input = NULL; err_register_device: input_free_device(input); err_alloc_input_dev: kfree(wac_i2c); wac_i2c = NULL; err_alloc_mem: err_i2c_fail: return ret; }