Example #1
0
int wacom_i2c_flash(struct wacom_i2c *wac_i2c)
{
    unsigned long max_address = 0;
    unsigned long start_address = 0x4000;
    int eraseBlock[32], eraseBlockNum;
    bool bRet;
    int iChecksum;
    int iBLVer, iMpuType, iStatus;
    bool bBootFlash = false;
    bool bMarking;
    int iRet;
    unsigned long ulMaxRange;

    pr_info("wacom: %s\n", __func__);
    pr_info(
        "wacom: start getting the boot loader version\n");
    /*Obtain boot loader version*/
    iRet = GetBLVersion(wac_i2c, &iBLVer);
    if (iRet != EXIT_OK) {
        pr_err(
            "wacom: %s failed to get Boot Loader version\n",
            __func__);
        return EXIT_FAIL_GET_BOOT_LOADER_VERSION;
    }

    pr_info(
        "wacom: start getting the MPU version\n");
    /*Obtain MPU type: this can be manually done in user space*/
    iRet = GetMpuType(wac_i2c, &iMpuType);
    if (iRet != EXIT_OK) {
        pr_err(
            "wacom: %s failed to get MPU type\n",
            __func__);
        return EXIT_FAIL_GET_MPU_TYPE;
    }

    /*Set start and end address and block numbers*/
    eraseBlockNum = 0;
    start_address = 0x4000;
    max_address = 0x12FFF;
    eraseBlock[eraseBlockNum++] = 2;
    eraseBlock[eraseBlockNum++] = 1;
    eraseBlock[eraseBlockNum++] = 0;
    eraseBlock[eraseBlockNum++] = 3;

    /*If MPU is in Boot mode, do below*/
    if (bBootFlash)
        eraseBlock[eraseBlockNum++] = 4;

    pr_info(
        "wacom: obtaining the checksum\n");
    /*Calculate checksum*/
    iChecksum = wacom_i2c_flash_chksum(wac_i2c,
                                       wac_i2c->fw_bin, &max_address);
    pr_info(
        "wacom: Checksum is :%d\n",
        iChecksum);

    bRet = true;

    pr_info(
        "wacom: setting the security unlock\n");
    /*Unlock security*/
    iRet = SetSecurityUnlock(wac_i2c, &iStatus);
    if (iRet != EXIT_OK) {
        pr_err(
            "wacom: %s failed to set security unlock\n",
            __func__);
        return iRet;
    }

    /*Set adress range*/
    ulMaxRange = max_address;
    ulMaxRange -= start_address;
    ulMaxRange >>= 6;
    if (max_address > (ulMaxRange<<6))
        ulMaxRange++;

    pr_info(
        "wacom: connecting to Wacom Digitizer\n");
    pr_info(
        "wacom: erasing the current firmware\n");
    /*Erase the old program*/
    bRet = flash_erase(wac_i2c, true, eraseBlock,  eraseBlockNum);
    if (!bRet) {
        pr_err(
            "wacom: %s failed to erase the user program\n",
            __func__);
        return EXIT_FAIL_ERASE;
    }
    pr_info(
        "wacom: erasing done\n");

    max_address = 0x11FC0;

    pr_info(
        "wacom: writing new firmware\n");
    /*Write the new program*/
    bRet = flash_write(wac_i2c, wac_i2c->fw_bin, start_address,
                       &max_address, iMpuType);
    if (!bRet) {
        pr_err(
            "wacom: %s failed to write firmware\n",
            __func__);
        return EXIT_FAIL_WRITE_FIRMWARE;
    }

    pr_info(
        "wacom: start marking\n");

    /*Set mark in writing process*/
    bRet = flash_marking(wac_i2c, true, iMpuType);
    if (!bRet) {
        pr_err(
            "wacom: %s failed to mark firmware\n",
            __func__);
        return EXIT_FAIL_WRITE_FIRMWARE;
    }

    /*Set the address for verify*/
    start_address = 0x4000;
    max_address = 0x11FBF;

    pr_info(
        "wacom: start the verification\n");
    /*Verify the written program*/
    bRet = flash_verify(wac_i2c, wac_i2c->fw_bin, start_address,
                        &max_address, iMpuType);
    if (!bRet) {
        pr_err(
            "wacom: failed to verify the firmware\n");
        return EXIT_FAIL_VERIFY_FIRMWARE;
    }


    pr_info(
        "wacom: checking the mark\n");
    /*Set mark*/
    bRet = is_flash_marking(wac_i2c, &bMarking, iMpuType);
    if (!bRet) {
        pr_err(
            "wacom: %s marking firmwrae failed\n",
            __func__);
        return EXIT_FAIL_WRITING_MARK_NOT_SET;
    }

    /*Enable */
    pr_info(
        "wacom: closing the boot mode\n");

    bRet = flash_end(wac_i2c);
    if (!bRet) {
        pr_err(
            "wacom: %s closing boot mode failed\n",
            __func__);
        return EXIT_FAIL_WRITING_MARK_NOT_SET;
    }

    pr_info(
        "wacom: write and verify completed\n");
    return EXIT_OK;
}
int wacom_i2c_flash(struct wacom_i2c *wac_i2c)
{
	unsigned long max_address = 0;
	unsigned long start_address = START_ADDR;
	int i;
	int eraseBlock[150], eraseBlockNum;
	bool bRet;
	int iBLVer, iMpuType;
	int iRet;
	unsigned long ulMaxRange;
#ifdef CONFIG_EPEN_WACOM_G9PL
	int iChecksum;
	int iStatus;
	bool bBootFlash = false;
	bool bMarking;
#endif

	if (fw_data == NULL) {
		printk(KERN_ERR"epen:Data is NULL. Exit.\n");
		return -1;
	}

	wac_i2c->pdata->compulsory_flash_mode(true);
	/*Reset */
	wac_i2c->pdata->reset_platform_hw();
	msleep(200);

	printk(KERN_DEBUG "epen:start getting the boot loader version\n");
	/*Obtain boot loader version */
	iRet = GetBLVersion(wac_i2c, &iBLVer);
	if (iRet != EXIT_OK) {
		printk(KERN_DEBUG "epen:failed to get Boot Loader version\n");
		goto fw_update_error;
	}

	printk(KERN_DEBUG"epen:BL version: %x \n", iBLVer);
	printk(KERN_DEBUG "epen:start getting the MPU version\n");
	/*Obtain MPU type: this can be manually done in user space */
	iRet = GetMpuType(wac_i2c, &iMpuType);
	if (iRet != EXIT_OK) {
		printk(KERN_DEBUG "epen:failed to get MPU type\n");
		goto fw_update_error;
	}

#ifdef CONFIG_EPEN_WACOM_G9PLL
	if (iMpuType != MPU_W9007) {
		printk(KERN_DEBUG"epen:MPU is not for W9007 : %x \n", iMpuType);
		return EXIT_FAIL_GET_MPU_TYPE;
	}
#endif

	printk(KERN_DEBUG"epen:MPU type: %x \n", iMpuType);

	/*Set start and end address and block numbers*/
	eraseBlockNum = 0;
	start_address = START_ADDR;
	max_address = MAX_ADDR;

#ifdef CONFIG_EPEN_WACOM_G9PL
	eraseBlock[eraseBlockNum++] = 2;
	eraseBlock[eraseBlockNum++] = 1;
	eraseBlock[eraseBlockNum++] = 0;
	eraseBlock[eraseBlockNum++] = 3;
#else
	for (i = BLOCK_NUM; i >= 8; i--) {
		eraseBlock[eraseBlockNum] = i;
		eraseBlockNum++;
	}
#endif

#ifdef CONFIG_EPEN_WACOM_G9PL
	/*If MPU is in Boot mode, do below */
	if (bBootFlash)
		eraseBlock[eraseBlockNum++] = 4;

	printk(KERN_DEBUG "epen:obtaining the checksum\n");
	/*Calculate checksum */
	iChecksum = wacom_i2c_flash_chksum(wac_i2c, fw_data, &max_address);
	printk(KERN_DEBUG "epen:Checksum is :%d\n", iChecksum);

	printk(KERN_DEBUG "epen:setting the security unlock\n");
	/*Unlock security */
	iRet = SetSecurityUnlock(wac_i2c, &iStatus);
	if (iRet != EXIT_OK) {
		printk(KERN_DEBUG "epen:failed to set security unlock\n");
		goto fw_update_error;
	}
#endif

	bRet = true;

	/*Set adress range */
	ulMaxRange = max_address;
	ulMaxRange -= start_address;
	ulMaxRange >>= 6;
	if (max_address > (ulMaxRange << 6))
		ulMaxRange++;

	printk(KERN_DEBUG "epen:connecting to Wacom Digitizer\n");
	printk(KERN_DEBUG "epen:erasing the current firmware\n");
	/*Erase the old program */
	bRet = flash_erase(wac_i2c, eraseBlock, eraseBlockNum);
	if (!bRet) {
		printk(KERN_DEBUG "epen:failed to erase the user program\n");
		iRet = EXIT_FAIL_ERASE;
		goto fw_update_error;
	}
	printk(KERN_DEBUG "epen:erasing done\n");

#ifdef CONFIG_EPEN_WACOM_G9PL
	max_address = 0x11FC0;
#endif

	printk(KERN_DEBUG "epen:writing new firmware\n");
	/*Write the new program */
	bRet =
	    flash_write(wac_i2c, fw_data, DATA_SIZE, start_address, &max_address,
			iMpuType);
	if (!bRet) {
		printk(KERN_DEBUG "epen:failed to write firmware\n");
		iRet = EXIT_FAIL_WRITE_FIRMWARE;
		goto fw_update_error;
	}

#ifdef CONFIG_EPEN_WACOM_G9PL
	printk(KERN_DEBUG "epen:start marking\n");
	/*Set mark in writing process */
	bRet = flash_marking(wac_i2c, DATA_SIZE, true, iMpuType);
	if (!bRet) {
		printk(KERN_DEBUG "epen:failed to mark firmware\n");
		iRet = EXIT_FAIL_WRITE_FIRMWARE;
		goto fw_update_error;
	}

	/*Set the address for verify */
	start_address = 0x4000;
	max_address = 0x11FBF;

	printk(KERN_DEBUG "epen:start the verification\n");
	/*Verify the written program */
	bRet =
	    flash_verify(wac_i2c, fw_data, DATA_SIZE, start_address,
			 &max_address, iMpuType);
	if (!bRet) {
		printk(KERN_DEBUG "epen:failed to verify the firmware\n");
		iRet = EXIT_FAIL_VERIFY_FIRMWARE;
		goto fw_update_error;
	}

	printk(KERN_DEBUG "epen:checking the mark\n");
	/*Set mark */
	bRet = is_flash_marking(wac_i2c, DATA_SIZE, &bMarking, iMpuType);
	if (!bRet) {
		printk(KERN_DEBUG "epen:marking firmwrae failed\n");
		iRet = EXIT_FAIL_WRITING_MARK_NOT_SET;
		goto fw_update_error;
	}
#endif

	/*Enable */
	printk(KERN_DEBUG "epen:closing the boot mode\n");
	bRet = flash_end(wac_i2c);
	if (!bRet) {
		printk(KERN_DEBUG "epen:closing boot mode failed\n");
		iRet = EXIT_FAIL_WRITING_MARK_NOT_SET;
		goto fw_update_error;
	}
	iRet = EXIT_OK;
	printk(KERN_DEBUG "epen:write and verify completed\n");

fw_update_error:
	wac_i2c->pdata->compulsory_flash_mode(false);
	/*Reset */
	wac_i2c->pdata->reset_platform_hw();
	msleep(200);

	return iRet;
}
int wacom_i2c_flash_w9012(struct wacom_i2c *wac_i2c, unsigned char *fw_data)
{
	bool bRet = false;
	int result, i;
	int eraseBlock[200], eraseBlockNum;
	int iBLVer, iMpuType;
	unsigned long max_address = 0;	/* Max.address of Load data */
	unsigned long start_address = 0x2000;	/* Start.address of Load data */

	/*Obtain boot loader version */
	if (!flash_blver(wac_i2c, &iBLVer)) {
		printk(KERN_DEBUG"epen:%s failed to get Boot Loader version \n", __func__);
		return -EXIT_FAIL_GET_BOOT_LOADER_VERSION;
	}
	printk(KERN_DEBUG"epen:BL version: %x \n", iBLVer);

	/*Obtain MPU type: this can be manually done in user space */
	if (!flash_mputype(wac_i2c, &iMpuType)) {
		printk(KERN_DEBUG"epen:%s failed to get MPU type \n", __func__);
		return -EXIT_FAIL_GET_MPU_TYPE;
	}
	if (iMpuType != MPU_W9012) {
		printk(KERN_DEBUG"epen:MPU is not for W9012 : %x \n", iMpuType);
		return -EXIT_FAIL_GET_MPU_TYPE;
	}
	printk(KERN_DEBUG"epen:MPU type: %x \n", iMpuType);

	/*-----------------------------------*/
	/*Flashing operation starts from here */

	/*Set start and end address and block numbers */
	eraseBlockNum = 0;
	start_address = W9012_START_ADDR;
	max_address = W9012_END_ADDR;
	for (i = BLOCK_NUM; i >= 8; i--) {
		eraseBlock[eraseBlockNum] = i;
		eraseBlockNum++;
	}

	msleep(300);

	/*Erase the old program */
	printk(KERN_DEBUG"epen:%s erasing the current firmware \n", __func__);
	bRet = flash_erase(wac_i2c, eraseBlock, eraseBlockNum);
	if (!bRet) {
		printk(KERN_DEBUG"epen:%s failed to erase the user program \n", __func__);
		result = -EXIT_FAIL_ERASE;
		goto fail;
	}

	/*Write the new program */
	printk(KERN_DEBUG"epen:%s writing new firmware \n", __func__);
	bRet = flash_write(wac_i2c, fw_data, start_address, &max_address);
	if (!bRet) {
		printk(KERN_DEBUG"epen:%s failed to write firmware \n", __func__);
		result = -EXIT_FAIL_WRITE_FIRMWARE;
		goto fail;
	}

	/*Return to the user mode */
	printk(KERN_DEBUG"epen:%s closing the boot mode \n", __func__);
	bRet = flash_end(wac_i2c);
	if (!bRet) {
		printk(KERN_DEBUG"epen:%s closing boot mode failed  \n", __func__);
		result = -EXIT_FAIL_WRITING_MARK_NOT_SET;
		goto fail;
	}

	printk(KERN_DEBUG"epen:%s write and verify completed \n", __func__);
	result = EXIT_OK;

 fail:
	return result;
}