static void update_work_func(struct work_struct *work) { int ret; int retry = 2; struct wacom_i2c *wac_i2c = container_of(work, struct wacom_i2c, update_work); printk(KERN_DEBUG "[E-PEN] %s\n", __func__); disable_irq(wac_i2c->irq); while (retry--) { printk(KERN_DEBUG "[E-PEN] INIT_FIRMWARE_FLASH is enabled.\n"); ret = wacom_i2c_flash(wac_i2c); if (ret == 0) break; printk(KERN_DEBUG "[E-PEN] update failed. retry %d, ret %d\n", retry, ret); /* Reset IC */ wacom_i2c_reset_hw(wac_i2c->wac_pdata); } msleep(800); printk(KERN_DEBUG "[E-PEN] flashed.(%d)\n", ret); wacom_i2c_query(wac_i2c); enable_irq(wac_i2c->irq); }
static ssize_t epen_reset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct wacom_i2c *wac_i2c = dev_get_drvdata(dev); int ret; int val; sscanf(buf, "%d", &val); if( val == 1 ) { disable_irq(wac_i2c->client->irq); /* reset IC */ gpio_set_value(GPIO_PEN_RESET, 0); msleep(200); gpio_set_value(GPIO_PEN_RESET, 1); msleep(200); /* I2C Test */ ret = wacom_i2c_query(wac_i2c); enable_irq(wac_i2c->client->irq); if( ret < 0 ) epen_reset_result = false; else epen_reset_result = true; printk(KERN_DEBUG "[E-PEN] %s, result %d\n", __func__, epen_reset_result); } return count; }
static void update_work_func(struct work_struct *work) { int ret; int retry = 2; struct wacom_i2c *wac_i2c = container_of(work, struct wacom_i2c, update_work); printk("[E-PEN] %s\n", __func__); disable_irq(wac_i2c->irq); while( retry-- ) { printk(KERN_DEBUG "[E-PEN]: INIT_FIRMWARE_FLASH is enabled.\n"); ret = wacom_i2c_flash(wac_i2c); if( ret == 0 ) break; printk(KERN_DEBUG "[E-PEN] update failed. retry %d\n", retry); /* Reset IC */ gpio_set_value(GPIO_PEN_RESET, 0); msleep(200); gpio_set_value(GPIO_PEN_RESET, 1); msleep(200); } msleep(800); printk(KERN_DEBUG "[E-PEN]: flashed.(%d)\n", ret); wacom_i2c_query(wac_i2c); enable_irq(wac_i2c->irq); }
static ssize_t epen_reset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct wacom_i2c *wac_i2c = dev_get_drvdata(dev); int ret; int val; sscanf(buf, "%d", &val); if (val == 1) { wacom_i2c_enable_irq(wac_i2c, false); /* Reset IC */ wacom_i2c_reset_hw(wac_i2c->wac_pdata); /* I2C Test */ ret = wacom_i2c_query(wac_i2c); wacom_i2c_enable_irq(wac_i2c, true); if (ret < 0) epen_reset_result = false; else epen_reset_result = true; printk(KERN_DEBUG "[E-PEN] %s, result %d\n", __func__, epen_reset_result); } return count; }
static ssize_t epen_reset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct wacom_i2c *wac_i2c = dev_get_drvdata(dev); int val; sscanf(buf, "%d", &val); if (val == 1) { wacom_enable_irq(wac_i2c, false); /* Reset IC */ wacom_reset_hw(wac_i2c); /* I2C Test */ wacom_i2c_query(wac_i2c); wacom_enable_irq(wac_i2c, true); dev_info(&wac_i2c->client->dev, "%s, result %d\n", __func__, wac_i2c->query_status); } return count; }
static ssize_t epen_firmware_update_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct wacom_i2c *wac_i2c = dev_get_drvdata(dev); u8 *data; u8 buf_if; int ret; buf_if = COM_QUERY; data = wac_i2c->wac_feature->data; printk(KERN_DEBUG "[E-PEN]:%s:\n", __func__); disable_irq(wac_i2c->irq); wac_i2c->wac_feature->firm_update_status = 1; if (*buf == 'F') { printk(KERN_ERR "[E-PEN]: Start firmware flashing (UMS).\n"); ret = wacom_i2c_load_fw(wac_i2c->client); if (ret < 0) { printk(KERN_ERR "[E-PEN]: failed to flash firmware.\n"); goto failure; } } else if (*buf == 'B') { printk(KERN_ERR "[E-PEN]: Start firmware flashing (kernel image).\n"); ret = wacom_i2c_flash(wac_i2c); if (ret < 0) { printk(KERN_ERR "[E-PEN]: failed to flash firmware.\n"); goto failure; } } else { printk(KERN_ERR "[E-PEN]: wrong parameter.\n"); goto param_err; } printk(KERN_ERR "[E-PEN]: Finish firmware flashing.\n"); msleep(800); wacom_i2c_query(wac_i2c); wac_i2c->wac_feature->firm_update_status = 2; enable_irq(wac_i2c->irq); return count; param_err: failure: wac_i2c->wac_feature->firm_update_status = -1; enable_irq(wac_i2c->irq); return -1; }
static int wacom_firmware_update(struct wacom_i2c *wac_i2c) { int ret = 0; ret = wacom_load_fw_from_req_fw(wac_i2c); if (ret) goto failure; if (wac_i2c->wac_feature->fw_ic_version < wac_i2c->wac_feature->fw_version) { /*start firm update*/ dev_info(&wac_i2c->client->dev, "%s: Start firmware flashing (kernel image).\n", __func__); mutex_lock(&wac_i2c->lock); wacom_enable_irq(wac_i2c, false); wac_i2c->wac_feature->firm_update_status = 1; ret = wacom_i2c_firm_update(wac_i2c); if (ret) goto update_err; wacom_i2c_set_firm_data(NULL); wacom_i2c_query(wac_i2c); wac_i2c->wac_feature->firm_update_status = 2; wacom_enable_irq(wac_i2c, true); mutex_unlock(&wac_i2c->lock); } else { dev_info(&wac_i2c->client->dev, "%s: firmware update does not need.\n", __func__); } return ret; update_err: wacom_i2c_set_firm_data(NULL); wac_i2c->wac_feature->firm_update_status = -1; wacom_enable_irq(wac_i2c, true); mutex_unlock(&wac_i2c->lock); failure: return ret; }
static int wacom_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct wacom_g5_platform_data *pdata; struct wacom_i2c *wac_i2c; struct input_dev *input; int ret = 0; int error; int fw_ver; /*Check I2C functionality */ ret = i2c_check_functionality(client->adapter, I2C_FUNC_I2C); if (!ret) { printk(KERN_ERR "%s: No I2C functionality found\n", __func__); ret = -ENODEV; goto err_i2c_fail; } /*Obtain kernel memory space for wacom i2c */ if (client->dev.of_node) { pdata = devm_kzalloc(&client->dev, sizeof(struct wacom_g5_platform_data), GFP_KERNEL); if (!pdata) { dev_err(&client->dev, "%s: Failed to allocate memory\n", __func__); return -ENOMEM; } error = wacom_parse_dt(&client->dev, pdata); if (error) return error; } else { pdata = client->dev.platform_data; if (pdata == NULL) { dev_err(&client->dev, "%s: no pdata\n", __func__); ret = -ENODEV; goto err_i2c_fail; } } wacom_connect_platform_data(pdata); wacom_request_gpio(pdata); wac_i2c = kzalloc(sizeof(struct wacom_i2c), GFP_KERNEL); if (NULL == wac_i2c) { dev_err(&client->dev, "%s: failed to allocate wac_i2c.\n", __func__); ret = -ENOMEM; goto err_i2c_fail; } 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) { dev_err(&client->dev, "%s: failed to allocate input device.\n", __func__); ret = -ENOMEM; goto err_freemem; } 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; client->irq = gpio_to_irq(pdata->gpio_int); printk(KERN_ERR "%s: wacom : gpio_to_irq : %d\n", __func__, client->irq); wac_i2c->irq = client->irq; /*Set client data */ i2c_set_clientdata(client, wac_i2c); i2c_set_clientdata(wac_i2c->client_boot, wac_i2c); #ifdef WACOM_PDCT_WORK_AROUND wac_i2c->irq_pdct = gpio_to_irq(pdata->gpio_pen_pdct); wac_i2c->pen_pdct = PDCT_NOSIGNAL; #endif #ifdef WACOM_PEN_DETECT wac_i2c->gpio_pen_insert = pdata->gpio_pen_insert; wac_i2c->irq_pen_insert = gpio_to_irq(wac_i2c->gpio_pen_insert); #endif #ifdef WACOM_IMPORT_FW_ALGO wac_i2c->use_offset_table = true; wac_i2c->use_aveTransition = false; #endif #ifdef USE_WACOM_CALLBACK /*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); #endif #ifdef CONFIG_SEC_VIENNA_PROJECT if (system_rev >= WACOM_BOOT_REVISION) { wac_i2c->wac_pdata->ic_mpu_ver = MPU_W9007; wac_i2c->boot_ver = 0x92; } #endif #ifdef CONFIG_SEC_LT03_PROJECT wac_i2c->boot_ver = 0x92; #endif if (wac_i2c->wac_pdata->ic_mpu_ver > 0) { wac_i2c->ic_mpu_ver = wac_i2c->wac_pdata->ic_mpu_ver; wac_i2c->wac_pdata->compulsory_flash_mode(wac_i2c, false); wac_i2c->wac_pdata->wacom_start(wac_i2c); msleep(200); } else { wac_i2c->wac_pdata->compulsory_flash_mode(wac_i2c, true); /*Reset */ wac_i2c->wac_pdata->wacom_start(wac_i2c); msleep(200); ret = wacom_check_mpu_version(wac_i2c); if (ret == -ETIMEDOUT) #if defined(CONFIG_SEC_H_PROJECT) || defined(CONFIG_SEC_FRESCO_PROJECT) goto err_wacom_i2c_send_timeout; #else pr_err("[E-PEN] wacom_i2c_send failed.\n"); #endif wac_i2c->ic_mpu_ver = wacom_check_flash_mode(wac_i2c, BOOT_MPU); dev_info(&wac_i2c->client->dev, "%s: mpu version: %x\n", __func__, ret); if (wac_i2c->ic_mpu_ver == MPU_W9001) wac_i2c->client_boot = i2c_new_dummy(client->adapter, WACOM_I2C_9001_BOOT); else if (wac_i2c->ic_mpu_ver == MPU_W9007) { ret = wacom_enter_bootloader(wac_i2c); if (ret < 0) { dev_info(&wac_i2c->client->dev, "%s: failed to get BootLoader version, %d\n", __func__, ret); goto err_wacom_i2c_bootloader_ver; } else { dev_info(&wac_i2c->client->dev, "%s: BootLoader version: %x\n", __func__, ret); } } wac_i2c->wac_pdata->compulsory_flash_mode(wac_i2c, false); wac_i2c->wac_pdata->reset_platform_hw(wac_i2c); wac_i2c->power_enable = true; } /* Firmware Feature */ wacom_i2c_init_firm_data(); pr_err("%s: wacon ic turn on\n", __func__); fw_ver = wacom_i2c_query(wac_i2c); wacom_init_abs_params(wac_i2c); input_set_drvdata(input, wac_i2c); /*Initializing for semaphor */ mutex_init(&wac_i2c->lock); #if defined(CONFIG_SEC_LT03_PROJECT) || defined(CONFIG_SEC_VIENNA_PROJECT) mutex_init(&wac_i2c->irq_lock); #endif #ifdef WACOM_BOOSTER wacom_init_dvfs(wac_i2c); #endif INIT_DELAYED_WORK(&wac_i2c->resume_work, wacom_i2c_resume_work); #ifdef USE_WACOM_BLOCK_KEYEVENT INIT_DELAYED_WORK(&wac_i2c->touch_pressed_work, wacom_i2c_touch_pressed_work); wac_i2c->key_delay_time = 100; #endif #ifdef USE_WACOM_LCD_WORKAROUND wac_i2c->wait_done = true; wac_i2c->delay_time = 5; INIT_DELAYED_WORK(&wac_i2c->read_vsync_work, wacom_i2c_read_vsync_work); wac_i2c->boot_done = false; INIT_DELAYED_WORK(&wac_i2c->boot_done_work, wacom_i2c_boot_done_work); #endif #ifdef WACOM_PEN_DETECT INIT_DELAYED_WORK(&wac_i2c->pen_insert_dwork, pen_insert_work); #endif #ifdef WACOM_RESETPIN_DELAY INIT_DELAYED_WORK(&wac_i2c->work_wacom_reset, wacom_reset); #endif /*Before registering input device, data in each input_dev must be set */ ret = input_register_device(input); if (ret) { pr_err("[E-PEN] failed to register input device.\n"); goto err_input_allocate_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)) { dev_err(&wac_i2c->client->dev, "%s: Failed to create device(wac_i2c->dev)!\n", __func__); goto err_sysfs_create_group; } dev_set_drvdata(wac_i2c->dev, wac_i2c); ret = sysfs_create_group(&wac_i2c->dev->kobj, &epen_attr_group); if (ret) { dev_err(&wac_i2c->client->dev, "%s: failed to create sysfs group\n", __func__); goto err_sysfs_create_group; } ret = wacom_firmware_update(wac_i2c); if (ret) { dev_err(&wac_i2c->client->dev, "%s: firmware update failed.\n", __func__); if (fw_ver > 0 && wac_i2c->ic_mpu_ver < 0) dev_err(&wac_i2c->client->dev, "%s: read query but not enter boot mode[%x,%x]\n", __func__, fw_ver, wac_i2c->ic_mpu_ver); else goto err_fw_update; } /*Request IRQ */ if (pdata->irq_flags) { ret = request_threaded_irq(wac_i2c->irq, NULL, wacom_interrupt, IRQF_DISABLED | pdata->irq_flags | IRQF_ONESHOT, wac_i2c->name, wac_i2c); if (ret < 0) { dev_err(&wac_i2c->client->dev, "%s: failed to request irq(%d) - %d\n", __func__, wac_i2c->irq, ret); goto err_fw_update; } #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, wac_i2c->name, wac_i2c); if (ret < 0) { dev_err(&wac_i2c->client->dev, "%s: failed to request irq(%d) - %d\n", __func__, wac_i2c->irq_pdct, ret); goto err_request_irq_pdct; } #endif #ifdef WACOM_PEN_DETECT ret = request_threaded_irq( wac_i2c->irq_pen_insert, NULL, wacom_pen_detect, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, "pen_insert", wac_i2c); if (ret < 0) { dev_err(&wac_i2c->client->dev, "%s: failed to request irq(%d) - %d\n", __func__, wac_i2c->irq_pen_insert, ret); goto err_request_irq_pen_inster; } enable_irq_wake(wac_i2c->irq_pen_insert); /* update the current status */ schedule_delayed_work(&wac_i2c->pen_insert_dwork, HZ / 2); #endif } #ifdef USE_WACOM_LCD_WORKAROUND schedule_delayed_work(&wac_i2c->boot_done_work, msecs_to_jiffies(20 * 1000)); #endif #ifdef WACOM_RESETPIN_DELAY schedule_delayed_work(&wac_i2c->work_wacom_reset, msecs_to_jiffies(5000)); #endif return 0; err_request_irq_pen_inster: #ifdef WACOM_PDCT_WORK_AROUND free_irq(wac_i2c->irq_pdct, wac_i2c); err_request_irq_pdct: #endif free_irq(wac_i2c->irq, wac_i2c); err_fw_update: sysfs_remove_group(&wac_i2c->dev->kobj, &epen_attr_group); err_sysfs_create_group: wac_i2c->init_fail = true; input_unregister_device(input); err_input_allocate_device: cancel_delayed_work_sync(&wac_i2c->resume_work); cancel_delayed_work_sync(&wac_i2c->touch_pressed_work); #ifdef USE_WACOM_LCD_WORKAROUND cancel_delayed_work_sync(&wac_i2c->read_vsync_work); cancel_delayed_work_sync(&wac_i2c->boot_done_work); #endif cancel_delayed_work_sync(&wac_i2c->pen_insert_dwork); #ifdef WACOM_RESETPIN_DELAY cancel_delayed_work_sync(&wac_i2c->work_wacom_reset); #endif #ifdef WACOM_BOOSTER cancel_delayed_work_sync(&wac_i2c->work_dvfs_off); cancel_delayed_work_sync(&wac_i2c->work_dvfs_chg); mutex_destroy(&wac_i2c->dvfs_lock); #endif wac_i2c->wac_pdata->wacom_stop(wac_i2c); mutex_destroy(&wac_i2c->lock); err_wacom_i2c_bootloader_ver: #if defined(CONFIG_SEC_H_PROJECT) || defined(CONFIG_SEC_FRESCO_PROJECT) err_wacom_i2c_send_timeout: #endif input_free_device(input); err_freemem: kfree(wac_i2c); err_i2c_fail: return ret; }
static void wacom_i2c_update_work(struct work_struct *work) { struct wacom_i2c *wac_i2c = container_of(work, struct wacom_i2c, update_work); u32 fw_ver_ic = wac_i2c->wac_feature->fw_version; int ret; int retry = 3; mutex_lock(&wac_i2c->update_lock); wacom_enable_irq(wac_i2c, false); printk(KERN_DEBUG"epen:%s\n", __func__); if (!wac_i2c->update_info.forced) { #if defined(CONFIG_SAMSUNG_PRODUCT_SHIP) if (fw_ver_ic == fw_ver_file) { #else if (fw_ver_ic >= fw_ver_file) { #endif printk(KERN_DEBUG"epen:pass fw update, ic ver %#x, img ver %#x\n", fw_ver_ic, fw_ver_file); goto err_update_load_fw; } } wac_i2c->wac_feature->firm_update_status = 1; ret = wacom_i2c_load_fw(wac_i2c); if (ret < 0) { printk(KERN_DEBUG"epen:failed to load fw(%d)\n", ret); goto err_update_load_fw; } while (retry--) { ret = wacom_i2c_flash(wac_i2c); if (ret) { printk(KERN_DEBUG"epen:failed to flash fw(%d)\n", ret); continue; } break; } if (ret) goto err_update_fw; ret = wacom_i2c_query(wac_i2c); if (ret < 0) { printk(KERN_DEBUG"epen:failed to query to IC(%d)\n", ret); goto err_update_fw; } err_update_fw: wacom_i2c_unload_fw(wac_i2c); err_update_load_fw: wac_i2c->wac_feature->firm_update_status = 2; wacom_enable_irq(wac_i2c, true); mutex_unlock(&wac_i2c->update_lock); } static ssize_t epen_reset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct wacom_i2c *wac_i2c = dev_get_drvdata(dev); int val; sscanf(buf, "%d", &val); if (val == 1) { wacom_enable_irq(wac_i2c, false); /* Reset IC */ wacom_i2c_reset_hw(wac_i2c->wac_pdata); /* I2C Test */ wacom_i2c_query(wac_i2c); wacom_enable_irq(wac_i2c, true); printk(KERN_DEBUG "epen:%s, result %d\n", __func__, wac_i2c->query_status); } return count; } static ssize_t epen_reset_result_show(struct device *dev, struct device_attribute *attr, char *buf) { struct wacom_i2c *wac_i2c = dev_get_drvdata(dev); if (wac_i2c->query_status) { printk(KERN_DEBUG "epen:%s, PASS\n", __func__); return sprintf(buf, "PASS\n"); } else { printk(KERN_DEBUG "epen:%s, FAIL\n", __func__); return sprintf(buf, "FAIL\n"); } } #ifdef WACOM_USE_AVE_TRANSITION static ssize_t epen_ave_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int v1, v2, v3, v4, v5; int height; sscanf(buf, "%d%d%d%d%d%d", &height, &v1, &v2, &v3, &v4, &v5); if (height < 0 || height > 2) { printk(KERN_DEBUG"epen:Height err %d\n", height); return count; } g_aveLevel_C[height] = v1; g_aveLevel_X[height] = v2; g_aveLevel_Y[height] = v3; g_aveLevel_Trs[height] = v4; g_aveLevel_Cor[height] = v5; printk(KERN_DEBUG "epen:%s, v1 %d v2 %d v3 %d v4 %d\n", __func__, v1, v2, v3, v4); return count; }
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; }
static ssize_t epen_firmware_update_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct wacom_i2c *wac_i2c = dev_get_drvdata(dev); int ret = 1; u32 fw_ic_ver = wac_i2c->wac_feature->fw_version; bool need_update = false; printk(KERN_DEBUG "epen:%s\n", __func__); need_update = check_update_condition(wac_i2c, *buf); if (need_update == false) { printk(KERN_DEBUG"epen:Pass Update." "Cmd %c, IC ver %04x, Ker ver %04x\n", *buf, fw_ic_ver, Firmware_version_of_file); return count; } /*start firm update*/ mutex_lock(&wac_i2c->lock); wacom_enable_irq(wac_i2c, false); wac_i2c->wac_feature->firm_update_status = 1; switch (*buf) { /*ums*/ case 'I': ret = wacom_i2c_fw_update_UMS(wac_i2c); break; /*kernel*/ #ifdef CONFIG_MACH_P4NOTE case 'K': printk(KERN_ERR "epen:Start firmware flashing (kernel image).\n"); ret = wacom_i2c_flash(wac_i2c); break; case 'R': update_fw_p4(wac_i2c); break; #else case 'K': printk(KERN_ERR "epen:Start firmware flashing (kernel image).\n"); case 'R': ret = wacom_i2c_firm_update(wac_i2c); break; #endif default: /*There's no default case*/ break; } if (ret < 0) { printk(KERN_ERR "epen:failed to flash firmware.\n"); goto failure; } printk(KERN_ERR "epen:Finish firmware flashing.\n"); wacom_i2c_query(wac_i2c); wac_i2c->wac_feature->firm_update_status = 2; wacom_enable_irq(wac_i2c, true); mutex_unlock(&wac_i2c->lock); return count; failure: wac_i2c->wac_feature->firm_update_status = -1; wacom_enable_irq(wac_i2c, true); mutex_unlock(&wac_i2c->lock); return -1; }
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_freemem; } 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_input_allocate_device; } 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_HAVE_FWE_PIN wac_i2c->have_fwe_pin = true; #ifdef CONFIG_MACH_T0 if (system_rev < WACOM_FWE1_HWID) wac_i2c->have_fwe_pin = false; #endif #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 */ #if defined(CONFIG_MACH_Q1_BD) wacom_i2c_reset_hw(wac_i2c->wac_pdata); #else wac_i2c->wac_pdata->resume_platform_hw(); msleep(200); #endif 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); wake_lock_init(&wac_i2c->wakelock, WAKE_LOCK_SUSPEND, "wacom"); INIT_DELAYED_WORK(&wac_i2c->resume_work, wacom_i2c_resume_work); #if defined(WACOM_IRQ_WORK_AROUND) INIT_DELAYED_WORK(&wac_i2c->pendct_dwork, wacom_i2c_pendct_work); #endif #ifdef WACOM_STATE_CHECK INIT_DELAYED_WORK(&wac_i2c->wac_statecheck_work, wac_statecheck_work); #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"); goto err_sysfs_create_group; } 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, Firmware_version_of_file); #ifdef CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK INIT_DELAYED_WORK(&wac_i2c->dvfs_work, free_dvfs_lock); if (exynos_cpufreq_get_level(WACOM_DVFS_LOCK_FREQ, &wac_i2c->cpufreq_level)) printk(KERN_ERR "epen:exynos_cpufreq_get_level Error\n"); #ifdef SEC_BUS_LOCK wac_i2c->dvfs_lock_status = false; #if defined(CONFIG_MACH_P4NOTE) || defined(CONFIG_MACH_KONA) wac_i2c->bus_dev = dev_get("exynos-busfreq"); #endif /* CONFIG_MACH_P4NOTE */ #endif /* SEC_BUS_LOCK */ #endif /* CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK */ /*Request IRQ */ if (wac_i2c->irq_flag) { ret = request_threaded_irq(wac_i2c->irq, NULL, wacom_interrupt, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_ONESHOT, wac_i2c->name, 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, wac_i2c->name, 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_DEBOUNCEINT_BY_ESD /*Invert gpio value for first irq. schedule_delayed_work in wacom_i2c_input_open*/ pen_insert_state = gpio_get_value(wac_i2c->gpio_pen_insert); wac_i2c->pen_insert = pen_insert_state; #if defined(CONFIG_MACH_T0) if (wac_i2c->invert_pen_insert) { wac_i2c->pen_insert = !wac_i2c->pen_insert; pen_insert_state = wac_i2c->pen_insert; } #endif #endif /*complete_all(&wac_i2c->init_done);*/ return 0; err_request_irq: err_sysfs_create_group: err_register_device: input_unregister_device(input); err_input_allocate_device: input_free_device(input); err_freemem: kfree(wac_i2c); err_i2c_fail: return ret; }
static int wacom_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct wacom_g5_platform_data *wac_pdata = client->dev.platform_data; struct wacom_i2c *wac_i2c; struct input_dev *input; struct device *sec_epen; int ret = 0; /*Check I2C functionality*/ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { pr_err("[E-PEN]: No I2C functionality found\n"); ret = -ENODEV; goto fail; } /*Obtain kernel memory space for wacom i2c*/ wac_i2c = kzalloc(sizeof(struct wacom_i2c), GFP_KERNEL); if (NULL == wac_i2c) { pr_err("[E-PEN]: failed to allocate wac_i2c.\n"); ret = -ENOMEM; goto err_freemem; } input = input_allocate_device(); if (NULL == input) { pr_err("[E-PEN]: failed to allocate input device.\n"); ret = -ENOMEM; goto err_input_allocate_device; } wac_i2c->wac_feature = &wacom_feature_EMR; wac_i2c->wac_pdata = wac_pdata; wac_i2c->input_dev = input; wac_i2c->client = client; wac_i2c->irq = client->irq; /*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); wacom_i2c_query(wac_i2c); #if defined(INIT_FIRMWARE_FLASH) if (0 == wac_i2c->wac_feature->fw_version) wacom_i2c_flash(wac_i2c); #endif wacom_i2c_set_input_values(client, wac_i2c, input); if (wac_i2c->wac_pdata->xy_switch) { input_set_abs_params(input, ABS_X, 0, wac_i2c->wac_feature->y_max, 4, 0); input_set_abs_params(input, ABS_Y, 0, wac_i2c->wac_feature->x_max, 4, 0); } else { input_set_abs_params(input, ABS_X, 0, wac_i2c->wac_feature->x_max, 4, 0); input_set_abs_params(input, ABS_Y, 0, wac_i2c->wac_feature->y_max, 4, 0); } input_set_abs_params(input, ABS_PRESSURE, 0, wac_i2c->wac_feature->pressure_max, 0, 0); input_set_drvdata(input, wac_i2c); /*Before registering input device, data in each input_dev must be set*/ ret = input_register_device(input); if (ret) { pr_err("[E-PEN]: failed to register input device.\n"); goto err_register_device; } i2c_set_clientdata(client, wac_i2c); /* if(wac_i2c->irq_flag) */ /* disable_irq(wac_i2c->irq); */ /*Initializing for semaphor*/ mutex_init(&wac_i2c->lock); /*Request IRQ*/ if (wac_i2c->irq_flag) { ret = request_threaded_irq(wac_i2c->irq, NULL, wacom_interrupt, IRQF_TRIGGER_RISING | IRQF_ONESHOT, wac_i2c->name, wac_i2c); if (ret < 0) { pr_err("[E-PEN]: failed to request irq!\n"); goto err_irq; } } g_client = client; #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 sec_epen = device_create(sec_class, NULL, 0, wac_i2c, "sec_epen"); if (IS_ERR(sec_epen)) { pr_err("[E-PEN]: failed to create device(sec_epen)!\n"); goto err_sysfs_create_group; } ret = sysfs_create_group(&sec_epen->kobj, &epen_attr_group); if (ret) { pr_err("[E-PEN]: failed to create sysfs group\n"); goto err_sysfs_create_group; } return 0; err_sysfs_create_group: free_irq(wac_i2c->irq, wac_i2c); err_irq: err_register_device: input_unregister_device(input); input = NULL; err_input_allocate_device: input_free_device(input); err_freemem: kfree(wac_i2c); fail: pr_err("[E-PEN]: fail occured\n"); 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 */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { printk(KERN_ERR "[E-PEN] 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 "[E-PEN] failed to allocate wac_i2c.\n"); ret = -ENOMEM; goto err_freemem; } input = input_allocate_device(); if (NULL == input) { printk(KERN_ERR "[E-PEN] failed to allocate input device.\n"); ret = -ENOMEM; goto err_input_allocate_device; } else 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; #ifdef WACOM_PDCT_WORK_AROUND wac_i2c->irq_pdct = gpio_to_irq(pdata->gpio_pendct); #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(); #if defined(CONFIG_MACH_Q1_BD) /* Change Origin offset by rev */ if (system_rev < 6) { origin_offset[0] = origin_offset_48[0]; origin_offset[1] = origin_offset_48[1]; } /* Reset IC */ wacom_i2c_reset_hw(wac_i2c->wac_pdata); #endif #if defined(CONFIG_MACH_Q1_BD) || defined(CONFIG_MACH_P4NOTE) wac_i2c->wac_pdata->resume_platform_hw(); msleep(200); #endif ret = wacom_i2c_query(wac_i2c); if (ret < 0) epen_reset_result = false; else epen_reset_result = true; INIT_WORK(&wac_i2c->update_work, update_work_func); #if defined(CONFIG_MACH_P4NOTE) if (pdata->xy_switch) { input_set_abs_params(input, ABS_X, WACOM_POSY_OFFSET, wac_i2c->wac_feature->y_max, 4, 0); input_set_abs_params(input, ABS_Y, WACOM_POSX_OFFSET, wac_i2c->wac_feature->x_max, 4, 0); } else { input_set_abs_params(input, ABS_X, WACOM_POSX_OFFSET, wac_i2c->wac_feature->x_max, 4, 0); input_set_abs_params(input, ABS_Y, WACOM_POSY_OFFSET, wac_i2c->wac_feature->y_max, 4, 0); } input_set_abs_params(input, ABS_PRESSURE, 0, wac_i2c->wac_feature->pressure_max, 0, 0); #else input_set_abs_params(wac_i2c->input_dev, ABS_X, pdata->min_x, pdata->max_x, 4, 0); input_set_abs_params(wac_i2c->input_dev, ABS_Y, pdata->min_y, pdata->max_y, 4, 0); input_set_abs_params(wac_i2c->input_dev, ABS_PRESSURE, pdata->min_pressure, pdata->max_pressure, 0, 0); #endif input_set_drvdata(input, wac_i2c); /*Before registering input device, data in each input_dev must be set */ ret = input_register_device(input); if (ret) { pr_err("[E-PEN] failed to register input device.\n"); goto err_register_device; } /*Change below if irq is needed */ wac_i2c->irq_flag = 1; /*Set client data */ i2c_set_clientdata(client, wac_i2c); /*Initializing for semaphor */ mutex_init(&wac_i2c->lock); wake_lock_init(&wac_i2c->wakelock, WAKE_LOCK_SUSPEND, "wacom"); INIT_DELAYED_WORK(&wac_i2c->resume_work, wacom_i2c_resume_work); #if defined(WACOM_IRQ_WORK_AROUND) INIT_DELAYED_WORK(&wac_i2c->pendct_dwork, wacom_i2c_pendct_work); #endif /*Request IRQ */ if (wac_i2c->irq_flag) { ret = request_threaded_irq(wac_i2c->irq, NULL, wacom_interrupt, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_ONESHOT, wac_i2c->name, wac_i2c); if (ret < 0) { printk(KERN_ERR "[E-PEN]: 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, wac_i2c->name, wac_i2c); if (ret < 0) { printk(KERN_ERR "[E-PEN]: failed to request irq(%d) - %d\n", wac_i2c->irq_pdct, ret); goto err_request_irq; } #endif } #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"); else { dev_set_drvdata(wac_i2c->dev, wac_i2c); ret = sysfs_create_group(&wac_i2c->dev->kobj, &epen_attr_group); if (ret) { printk(KERN_ERR "[E-PEN]: failed to create sysfs group\n"); goto err_sysfs_create_group; } } /* firmware info */ printk(KERN_NOTICE "[E-PEN] wacom fw ver : 0x%x, new fw ver : 0x%x\n", wac_i2c->wac_feature->fw_version, Firmware_version_of_file); #ifdef CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK INIT_DELAYED_WORK(&wac_i2c->dvfs_work, free_dvfs_lock); if (exynos_cpufreq_get_level(500000, &wac_i2c->cpufreq_level)) printk(KERN_ERR "[E-PEN] exynos_cpufreq_get_level Error\n"); #ifdef SEC_BUS_LOCK wac_i2c->dvfs_lock_status = false; #if defined(CONFIG_MACH_P4NOTE) wac_i2c->bus_dev = dev_get("exynos-busfreq"); #endif /* CONFIG_MACH_P4NOTE */ #endif /* SEC_BUS_LOCK */ #endif /* CONFIG_SEC_TOUCHSCREEN_DVFS_LOCK */ return 0; err_sysfs_create_group: free_irq(wac_i2c->irq, wac_i2c); #ifdef WACOM_PDCT_WORK_AROUND free_irq(wac_i2c->irq_pdct, wac_i2c); #endif err_request_irq: err_register_device: input_unregister_device(input); input = NULL; err_input_allocate_device: input_free_device(input); err_freemem: kfree(wac_i2c); err_i2c_fail: return ret; }
static ssize_t epen_firmware_update_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct wacom_i2c *wac_i2c = dev_get_drvdata(dev); int ret = 1; disable_irq(wac_i2c->irq); #ifdef WACOM_PDCT_WORK_AROUND disable_irq(wac_i2c->irq_pdct); #endif wac_i2c->wac_feature->firm_update_status = 1; printk(KERN_DEBUG "[E-PEN] %s\n", __func__); /* F and B are used by Factory app, and R is used when boot */ switch (*buf) { #ifdef WACOM_UMS_UPDATE /* Block UMS update for MR */ case 'F': printk(KERN_ERR "[E-PEN] Start firmware flashing (UMS).\n"); ret = wacom_i2c_load_fw(wac_i2c->client); break; #endif case 'B': printk(KERN_ERR "[E-PEN] Start firmware flashing (kernel image).\n"); #ifdef CONFIG_MACH_Q1_BD ret = wacom_i2c_firm_update(wac_i2c); #else ret = wacom_i2c_flash(wac_i2c); #endif break; #ifdef CONFIG_MACH_Q1_BD case 'R': /* Q1 board rev 0.3 */ if (system_rev >= 6) { if (wac_i2c->wac_feature->fw_version < Firmware_version_of_file) ret = wacom_i2c_firm_update(wac_i2c); } else { if (wac_i2c->wac_feature->fw_version != Firmware_version_of_file) ret = wacom_i2c_firm_update(wac_i2c); } if (ret > 0) { enable_irq(wac_i2c->irq); #ifdef WACOM_PDCT_WORK_AROUND enable_irq(wac_i2c->irq_pdct); #endif return count; } break; #endif #if defined(CONFIG_MACH_P4NOTE) case 'W': if (Firmware_version_of_file != wac_i2c->wac_feature->fw_version) schedule_work(&wac_i2c->update_work); break; #endif default: printk(KERN_ERR "[E-PEN] wrong parameter.\n"); goto param_err; break; } if (ret < 0) { printk(KERN_ERR "[E-PEN] failed to flash firmware.\n"); goto failure; } printk(KERN_ERR "[E-PEN] Finish firmware flashing.\n"); msleep(800); wacom_i2c_query(wac_i2c); wac_i2c->wac_feature->firm_update_status = 2; enable_irq(wac_i2c->irq); #ifdef WACOM_PDCT_WORK_AROUND enable_irq(wac_i2c->irq_pdct); #endif return count; param_err: failure: wac_i2c->wac_feature->firm_update_status = -1; enable_irq(wac_i2c->irq); #ifdef WACOM_PDCT_WORK_AROUND enable_irq(wac_i2c->irq_pdct); #endif return -1; }
static ssize_t epen_firmware_update_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct wacom_i2c *wac_i2c = dev_get_drvdata(dev); int ret = 1; u32 fw_ic_ver = wac_i2c->wac_feature->fw_ic_version; bool need_update = false; need_update = check_update_condition(wac_i2c, *buf); if (need_update == false) { dev_info(&wac_i2c->client->dev, "%s:Pass Update. Cmd %c, IC ver %04x, Ker ver %04x\n", __func__, *buf, fw_ic_ver, wac_i2c->wac_feature->fw_version); return count; } else { dev_info(&wac_i2c->client->dev, "%s:Update Start. IC fw ver : 0x%x, new fw ver : 0x%x\n", __func__, wac_i2c->wac_feature->fw_ic_version, wac_i2c->wac_feature->fw_version); } switch (*buf) { /*ums*/ case 'I': ret = wacom_fw_load_from_UMS(wac_i2c); if (ret) goto failure; dev_info(&wac_i2c->client->dev, "%s: Start firmware flashing (UMS image).\n", __func__); ums_binary = true; break; /*kernel*/ case 'K': ret = wacom_load_fw_from_req_fw(wac_i2c); if (ret) goto failure; break; /*booting*/ case 'R': ret = wacom_load_fw_from_req_fw(wac_i2c); if (ret) goto failure; dev_info(&wac_i2c->client->dev, "%s: Start firmware flashing (kernel image).\n", __func__); break; default: /*There's no default case*/ break; } /*start firm update*/ mutex_lock(&wac_i2c->lock); wacom_enable_irq(wac_i2c, false); wac_i2c->wac_feature->firm_update_status = 1; ret = wacom_i2c_firm_update(wac_i2c); if (ret) goto update_err; wacom_i2c_set_firm_data(NULL); wacom_i2c_query(wac_i2c); wac_i2c->wac_feature->firm_update_status = 2; wacom_enable_irq(wac_i2c, true); mutex_unlock(&wac_i2c->lock); return count; update_err: wacom_i2c_set_firm_data(NULL); failure: wac_i2c->wac_feature->firm_update_status = -1; wacom_enable_irq(wac_i2c, true); mutex_unlock(&wac_i2c->lock); return -1; }
static int wacom_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct wacom_i2c *wac_i2c; struct wacom_g5_platform_data *pdata = client->dev.platform_data; int i, ret; i = ret = 0; printk(KERN_DEBUG "[E-PEN]:%s:\n", __func__); /*Check I2C functionality*/ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) goto err3; /*Obtain kernel memory space for wacom i2c*/ wac_i2c = kzalloc(sizeof(struct wacom_i2c), GFP_KERNEL); if (wac_i2c == NULL) goto fail; wac_i2c->wac_feature = &wacom_feature_EMR; pdata->init_platform_hw(); /*Initializing for semaphor*/ mutex_init(&wac_i2c->lock); /*Register platform data*/ wac_i2c->wac_pdata = client->dev.platform_data; /*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); /*Register wacom i2c to input device*/ wac_i2c->input_dev = input_allocate_device(); if (wac_i2c == NULL || wac_i2c->input_dev == NULL) goto fail; wacom_i2c_set_input_values(client, wac_i2c, wac_i2c->input_dev); wac_i2c->client = client; wac_i2c->irq = client->irq; /*Change below if irq is needed*/ wac_i2c->irq_flag = 1; #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 /*Init Featreus by hw rev*/ #if defined(CONFIG_USA_MODEL_SGH_I717) if( get_hw_rev() == 0x01 ) { printk("[E-PEN] Wacom driver is working for 4.4mm pitch pad.\n"); /* Firmware Feature */ Firmware_version_of_file = 0x340; Binary = Binary_44; } else if( get_hw_rev() >= HWREV_PEN_PITCH4P4 ) { printk("[E-PEN] Wacom driver is working for 4.4mm pitch pad.\n"); /* Firmware Feature */ Firmware_version_of_file = Firmware_version_of_file_44; Binary = Binary_44; } #else if( get_hw_rev() >= HWREV_PEN_PITCH4P4 ) { printk("[E-PEN] Wacom driver is working for 4.4mm pitch pad.\n"); /* Firmware Feature */ Firmware_version_of_file = Firmware_version_of_file_44; Binary = Binary_44; } else { printk("[E-PEN] Wacom driver is working for 4.8mm pitch pad.\n"); /* Firmware Feature */ Firmware_version_of_file = Firmware_version_of_file_48; Binary = Binary_48; } #endif init_offset_tables(); INIT_WORK(&wac_i2c->update_work, update_work_func); INIT_DELAYED_WORK(&wac_i2c->resume_work, wacom_i2c_resume_work); /* Reset IC */ gpio_set_value(GPIO_PEN_RESET, 0); msleep(200); gpio_set_value(GPIO_PEN_RESET, 1); msleep(200); ret = wacom_i2c_query(wac_i2c); if( ret < 0 ) epen_reset_result = false; else epen_reset_result = true; input_set_abs_params(wac_i2c->input_dev, ABS_X, pdata->min_x, pdata->max_x, 4, 0); input_set_abs_params(wac_i2c->input_dev, ABS_Y, pdata->min_y, pdata->max_y, 4, 0); input_set_abs_params(wac_i2c->input_dev, ABS_PRESSURE, pdata->min_pressure, pdata->max_pressure, 0, 0); input_set_drvdata(wac_i2c->input_dev, wac_i2c); /*Set client data*/ i2c_set_clientdata(client, wac_i2c); /*Before registering input device, data in each input_dev must be set*/ if (input_register_device(wac_i2c->input_dev)) goto err2; g_client = client; /* if(wac_i2c->irq_flag) */ /* disable_irq(wac_i2c->irq); */ sec_epen= device_create(sec_class, NULL, 0, NULL, "sec_epen"); dev_set_drvdata(sec_epen, wac_i2c); if (IS_ERR(sec_epen)) printk(KERN_ERR "Failed to create device(sec_epen)!\n"); if (device_create_file(sec_epen, &dev_attr_epen_firm_update)< 0) printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_firm_update.attr.name); if (device_create_file(sec_epen, &dev_attr_epen_firm_update_status)< 0) printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_firm_update_status.attr.name); if (device_create_file(sec_epen, &dev_attr_epen_firm_version)< 0) printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_firm_version.attr.name); if (device_create_file(sec_epen, &dev_attr_epen_rotation)< 0) printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_rotation.attr.name); if (device_create_file(sec_epen, &dev_attr_epen_hand)< 0) printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_hand.attr.name); if (device_create_file(sec_epen, &dev_attr_epen_reset)< 0) printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_reset.attr.name); if (device_create_file(sec_epen, &dev_attr_epen_reset_result)< 0) printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_reset_result.attr.name); if (device_create_file(sec_epen, &dev_attr_epen_checksum)< 0) printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_checksum.attr.name); if (device_create_file(sec_epen, &dev_attr_epen_checksum_result)< 0) printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_epen_checksum_result.attr.name); if (device_create_file(sec_epen, &dev_attr_set_epen_module_off) < 0) printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_set_epen_module_off.attr.name); if (device_create_file(sec_epen, &dev_attr_set_epen_module_on) < 0) printk(KERN_ERR "Failed to create device file(%s)!\n", dev_attr_set_epen_module_on.attr.name); /*Request IRQ*/ if (wac_i2c->irq_flag) { ret = request_threaded_irq(wac_i2c->irq, NULL, wacom_interrupt, IRQF_DISABLED|IRQF_TRIGGER_RISING|IRQF_ONESHOT, wac_i2c->name, wac_i2c); if (ret < 0) goto err1; } /* firmware update */ printk(KERN_NOTICE "[E-PEN] wacom fw ver : 0x%x, new fw ver : 0x%x\n", wac_i2c->wac_feature->fw_version, Firmware_version_of_file); if( wac_i2c->wac_feature->fw_version < Firmware_version_of_file ) { #if defined(CONFIG_KOR_MODEL_SHV_E160S) || defined(CONFIG_KOR_MODEL_SHV_E160K) || defined(CONFIG_KOR_MODEL_SHV_E160L) || defined(CONFIG_JPN_MODEL_SC_05D) printk("[E-PEN] %s\n", __func__); disable_irq(wac_i2c->irq); printk(KERN_NOTICE "[E-PEN]: INIT_FIRMWARE_FLASH is enabled.\n"); ret = wacom_i2c_flash(wac_i2c); msleep(800); printk(KERN_ERR "[E-PEN]: flashed.(%d)\n", ret); wacom_i2c_query(wac_i2c); enable_irq(wac_i2c->irq); #else schedule_work(&wac_i2c->update_work); #endif } /* To send exact checksum data at sleep state ... Xtopher */ printk(KERN_ERR"[E-PEN]: Verify CHECKSUM.\n"); epen_checksum_read_atBoot(wac_i2c); msleep(20); return 0; err3: printk(KERN_ERR "[E-PEN]: No I2C functionality found\n"); return -ENODEV; err2: printk(KERN_ERR "[E-PEN]: err2 occured\n"); input_free_device(wac_i2c->input_dev); return -EIO; err1: printk(KERN_ERR "[E-PEN]: err1 occured(num:%d)\n", ret); input_free_device(wac_i2c->input_dev); wac_i2c->input_dev = NULL; return -EIO; fail: printk(KERN_ERR "[E-PEN]: fail occured\n"); return -ENOMEM; }
static ssize_t epen_firmware_update_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct wacom_i2c *wac_i2c = dev_get_drvdata(dev); u8 *data; u8 buf_if; int ret; disable_irq(wac_i2c->irq); #ifdef WACOM_PDCT_WORK_AROUND disable_irq(wac_i2c->irq_pdct); #endif buf_if = COM_QUERY; data = wac_i2c->wac_feature->data; wac_i2c->wac_feature->firm_update_status = 1; if (*buf == 'F') { printk(KERN_ERR "[E-PEN]: Start firmware flashing (UMS).\n"); ret = wacom_i2c_load_fw(wac_i2c->client); if (ret < 0) { printk(KERN_ERR "[E-PEN]: failed to flash firmware.\n"); goto failure; } } else if (*buf == 'B') { printk(KERN_ERR "[E-PEN]: Start firmware flashing (kernel image).\n"); #if 0 //#if defined(CONFIG_KOR_MODEL_SHV_E160S) || defined(CONFIG_KOR_MODEL_SHV_E160K) || defined(CONFIG_KOR_MODEL_SHV_E160L) Binary = Binary_44; #endif ret = wacom_i2c_flash(wac_i2c); if (ret < 0) { printk(KERN_ERR "[E-PEN]: failed to flash firmware.\n"); goto failure; } } else { printk(KERN_ERR "[E-PEN]: wrong parameter.\n"); goto param_err; } printk(KERN_ERR "[E-PEN]: Finish firmware flashing.\n"); msleep(800); wacom_i2c_query(wac_i2c); wac_i2c->wac_feature->firm_update_status = 2; enable_irq(wac_i2c->irq); #ifdef WACOM_PDCT_WORK_AROUND enable_irq(wac_i2c->irq_pdct); #endif return count; param_err: failure: wac_i2c->wac_feature->firm_update_status = -1; enable_irq(wac_i2c->irq); #ifdef WACOM_PDCT_WORK_AROUND enable_irq(wac_i2c->irq_pdct); #endif return -1; }