static void update_fw_p4(struct wacom_i2c *wac_i2c) { int ret = 0; int retry = 3; #if !defined(CONFIG_TARGET_LOCALE_USA) /* the firmware should be updated in factory mode durring the boot */ if (!epen_check_factory_mode()) retry = 0; #endif while (retry--) { printk(KERN_DEBUG "epen:INIT_FIRMWARE_FLASH is enabled.\n"); ret = wacom_i2c_flash(wac_i2c); if (ret == 0) break; printk(KERN_DEBUG "epen:update failed. retry %d, ret %d\n", retry, ret); /* Reset IC */ wacom_i2c_reset_hw(wac_i2c->wac_pdata); } printk(KERN_DEBUG "epen:flashed.(%d)\n", ret); }
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_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_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 */ wacom_i2c_reset_hw(wac_i2c->wac_pdata); /* 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(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); }
int wacom_i2c_firm_update(struct wacom_i2c *wac_i2c) { int ret; int retry = 3; const struct firmware *firm_data = NULL; firmware_updating_state = true; while (retry--) { ret = request_firmware(&firm_data, firmware_name, &wac_i2c->client->dev); if (ret < 0) { printk(KERN_ERR "[E-PEN] Unable to open firmware. ret %d retry %d\n", ret, retry); continue; } wacom_i2c_set_firm_data((unsigned char *)firm_data->data); ret = wacom_i2c_flash(wac_i2c); if (ret == 0) { release_firmware(firm_data); break; } printk(KERN_ERR "[E-PEN] failed to write firmware(%d)\n", ret); release_firmware(firm_data); /* Reset IC */ wacom_i2c_reset_hw(wac_i2c->wac_pdata); } firmware_updating_state = false; if (ret < 0) return -1; return 0; }
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_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; }
int wacom_i2c_firm_update(struct wacom_i2c *wac_i2c) { int ret; int retry = 3; const struct firmware *firm_data = NULL; #if defined(CONFIG_MACH_KONA) u8 *flash_data; flash_data = kmalloc(65536*2, GFP_KERNEL); if (IS_ERR(flash_data)) { printk(KERN_ERR "[E-PEN] %s, kmalloc failed\n", __func__); return -1; } memset((void *)flash_data, 0xff, 65536*2); #endif firmware_updating_state = true; while (retry--) { ret = request_firmware(&firm_data, firmware_name, &wac_i2c->client->dev); if (ret < 0) { printk(KERN_ERR "[E-PEN] Unable to open firmware. ret %d retry %d\n", ret, retry); continue; } #if defined(CONFIG_MACH_KONA) memcpy((void *)flash_data, (const void *)firm_data->data, firm_data->size); wacom_i2c_set_firm_data((unsigned char *)flash_data); #else wacom_i2c_set_firm_data((unsigned char *)firm_data->data); #endif ret = wacom_i2c_flash(wac_i2c); if (ret == 0) { release_firmware(firm_data); break; } printk(KERN_ERR "[E-PEN] failed to write firmware(%d)\n", ret); release_firmware(firm_data); /* Reset IC */ wacom_i2c_reset_hw(wac_i2c->wac_pdata); } firmware_updating_state = false; #if defined(CONFIG_MACH_KONA) kfree(flash_data); #endif if (ret < 0) return -1; return 0; }
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; }