예제 #1
0
int wacom_i2c_fw_update_UMS(struct wacom_i2c *wac_i2c)
{
	int ret = 0;
	u8 *ums_data = NULL;

	printk(KERN_ERR "epen:Start firmware flashing (UMS).\n");

	/*read firmware data*/
	ret = wacom_i2c_get_ums_data(wac_i2c, &ums_data);
	if (ret < 0) {
		printk(KERN_DEBUG"epen:file op is failed\n");
		return 0;
	}

	/*start firm update*/
	wacom_i2c_set_firm_data(ums_data);

	ret = wacom_i2c_flash(wac_i2c);
	if (ret < 0) {
		printk(KERN_ERR
			"epen:failed to write firmware(%d)\n", ret);
		kfree(ums_data);
		wacom_i2c_set_firm_data(NULL);
		return ret;
	}

	wacom_i2c_set_firm_data(NULL);
	kfree(ums_data);

	return 0;
}
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;
}
예제 #3
0
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 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;
}
예제 #5
0
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;
}
예제 #6
0
int wacom_i2c_load_fw(struct i2c_client *client)
{
	struct file *fp;
	mm_segment_t old_fs;
	long fsize, nread;
	int ret;
	struct wacom_i2c *wac_i2c = i2c_get_clientdata(client);
	unsigned char *Binary_UMS = NULL;

#if defined(CONFIG_MACH_P4NOTE)
	Binary_UMS = kmalloc(MAX_ADDR_514 + 1, GFP_KERNEL);
#else
	Binary_UMS = kmalloc(WACOM_FW_SIZE, GFP_KERNEL);
#endif

	if (Binary_UMS == NULL) {
		printk(KERN_DEBUG "[E-PEN] %s, kmalloc failed\n", __func__);
		return -ENOENT;
	}

	wacom_i2c_set_firm_data(Binary_UMS);

	old_fs = get_fs();
	set_fs(KERNEL_DS);

	fp = filp_open(WACOM_FW_PATH, O_RDONLY, S_IRUSR);

	if (IS_ERR(fp)) {
		printk(KERN_ERR "[E-PEN] failed to open %s.\n", WACOM_FW_PATH);
		goto open_err;
	}

	fsize = fp->f_path.dentry->d_inode->i_size;
	printk(KERN_NOTICE "[E-PEN] start, file path %s, size %ld Bytes\n",
	       WACOM_FW_PATH, fsize);

	nread = vfs_read(fp, (char __user *)Binary, fsize, &fp->f_pos);
	printk(KERN_ERR "[E-PEN] nread %ld Bytes\n", nread);
	if (nread != fsize) {
		printk(KERN_ERR
		       "[E-PEN] failed to read firmware file, nread %ld Bytes\n",
		       nread);
		goto read_err;
	}

	ret = wacom_i2c_flash(wac_i2c);
	if (ret < 0) {
		printk(KERN_ERR "[E-PEN] failed to write firmware(%d)\n", ret);
		goto fw_write_err;
	}

	wacom_i2c_set_firm_data(NULL);

	kfree(Binary_UMS);

	filp_close(fp, current->files);
	set_fs(old_fs);

	return 0;

 open_err:
	kfree(Binary_UMS);
	set_fs(old_fs);
	return -ENOENT;

 read_err:
	kfree(Binary_UMS);
	filp_close(fp, current->files);
	set_fs(old_fs);
	return -EIO;

 fw_write_err:
	kfree(Binary_UMS);
	filp_close(fp, current->files);
	set_fs(old_fs);
	return -1;
}