int mxt_load_firmware(struct device *dev, const char *fn)
{
	struct mxt_data *mxt = dev_get_drvdata(dev);

	unsigned int frame_size;
	unsigned int pos = 0;
	unsigned int retry;
	int ret;

#if READ_FW_FROM_HEADER
	struct firmware *fw = NULL;
	fw = kzalloc(sizeof(struct firmware), GFP_KERNEL);

	fw->data = firmware_latest;
	fw->size = sizeof(firmware_latest);

#else
	const struct firmware *fw = NULL;

	ret = request_firmware(&fw, fn, dev);
	if (ret < 0) {
		dev_err(&client->dev, "[TSP] Unable to open firmware %s\n", fn);
		return -ENOMEM;
	}
#endif

	/* set resets into bootloader mode */
	reset_chip(mxt, RESET_TO_BOOTLOADER);
	msleep(250);  /* mdelay(100); */

	/* change to slave address of bootloader */
	if (mxt->client->addr == MXT_I2C_APP_ADDR) {
		pr_info("[TSP] I2C address: 0x%02X --> 0x%02X", MXT_I2C_APP_ADDR, MXT_I2C_BOOTLOADER_ADDR);
		mxt->client->addr = MXT_I2C_BOOTLOADER_ADDR;
	}

	ret = check_bootloader(mxt->client, WAITING_BOOTLOAD_COMMAND);
	if (ret < 0) {
		pr_err("[TSP] ... Waiting bootloader command: Failed");
		goto err_fw;
	}

	/* unlock bootloader */
	unlock_bootloader(mxt->client);
	msleep(200);  /* mdelay(100); */

	/* reading the information of the firmware */
	pr_info("[TSP] Firmware info: version [0x%02X], build [0x%02X]", fw->data[0], fw->data[1]);
	pr_info("Updating progress: ");
	pos += 2;

	while (pos < fw->size) {
		retry = 0;
		ret = check_bootloader(mxt->client, WAITING_FRAME_DATA);
		if (ret < 0) {
			pr_err("... Waiting frame data: Failed");
			goto err_fw;
		}

		frame_size = ((*(fw->data + pos) << 8) | *(fw->data + pos + 1));

		/* We should add 2 at frame size as the the firmware data is not
		* included the CRC bytes.
		*/
		frame_size += 2;

		/* write one frame to device */
try_to_resend_the_last_frame:
		i2c_master_send(mxt->client, (u8 *)(fw->data + pos), frame_size);

		ret = check_bootloader(mxt->client, FRAME_CRC_PASS);
		if (ret < 0) {
			if (++retry < 10) {
				check_bootloader(mxt->client, WAITING_FRAME_DATA);  /* recommendation from ATMEL */
				pr_info("[TSP] We've got a FRAME_CRC_FAIL, so try again up to 10 times (count=%d)", retry);
				goto try_to_resend_the_last_frame;
			}
			pr_err("... CRC on the frame failed after 10 trials!");
			goto err_fw;
		}

		pos += frame_size;

		pr_info("#");
		pr_info("%zd / %zd (bytes) updated...", pos, fw->size);
	}
	pr_info("\n[TSP] Updating firmware completed!\n");
	pr_info("[TSP] note: You may need to reset this target.\n");

err_fw:
	/* change to slave address of application */
	if (mxt->client->addr == MXT_I2C_BOOTLOADER_ADDR) {
		pr_info("[TSP] I2C address: 0x%02X --> 0x%02X", MXT_I2C_BOOTLOADER_ADDR, MXT_I2C_APP_ADDR);
		mxt->client->addr = MXT_I2C_APP_ADDR;
	}

#if READ_FW_FROM_HEADER
	kfree(fw);
#endif

	return ret;
}
Exemplo n.º 2
0
static int load_kernel_fw_bootmode(struct i2c_client *client, const char *pFn)
{
	unsigned int uFrameSize;
	unsigned int uPos = 0;
	int iRet = SUCCESS;
	int iCheckFrameCrcError = 0;
	int iCheckWatingFrameDataError = 0;
	const struct firmware *fw = NULL;

	pr_info("[SSP] ssp_load_fw start!!!\n");

	if (request_firmware(&fw, pFn, &client->dev)) {
		iRet = ERROR;
		pr_err("[SSP]: %s - Unable to open firmware %s\n",
			__func__, pFn);
		return iRet;
	}

	/* Unlock bootloader */
	unlock_bootloader(client);

	while (uPos < fw->size) {
		if (check_bootloader(client, BL_WAITING_FRAME_DATA)) {
			iCheckWatingFrameDataError++;
			if (iCheckWatingFrameDataError > 10) {
				iRet = ERROR;
				pr_err("[SSP]: %s - F/W update fail\n",
					__func__);
				goto out;
			} else {
				pr_err("[SSP]: %s - F/W data_error %d, retry\n",
					__func__, iCheckWatingFrameDataError);
				continue;
			}
		}

		uFrameSize = ((*(fw->data + uPos) << 8) |
			*(fw->data + uPos + 1));

		/* We should add 2 at frame size as the the firmware data is not
		*  included the CRC bytes.
		*/
		uFrameSize += 2;

		/* Write one frame to device */
		fw_write(client, fw->data + uPos, uFrameSize);
		if (check_bootloader(client, BL_FRAME_CRC_PASS)) {
			iCheckFrameCrcError++;
			if (iCheckFrameCrcError > 10) {
				iRet = ERROR;
				pr_err("[SSP]: %s - F/W Update Fail. crc err\n",
					__func__);
				goto out;
			} else {
				pr_err("[SSP]: %s - F/W crc_error %d, retry\n",
					__func__, iCheckFrameCrcError);
				continue;
			}
		}

		uPos += uFrameSize;

		pr_info("[SSP] Updated %d bytes / %zd bytes\n", uPos, fw->size);
		mdelay(1);
	}

out:
	release_firmware(fw);

	return iRet;
}
Exemplo n.º 3
0
static int load_ums_fw_bootmode(struct i2c_client *client, const char *pFn)
{
	const u8 *buff = NULL;
	char fw_path[BL_UMS_FW_PATH+1];
	unsigned int uFrameSize;
	unsigned int uFSize = 0, uNRead = 0;
	unsigned int uPos = 0;
	int iRet = SUCCESS;
	int iCheckFrameCrcError = 0;
	int iCheckWatingFrameDataError = 0;
	struct file *fp = NULL;
	mm_segment_t old_fs = get_fs();

	pr_info("[SSP] ssp_load_ums_fw start!!!\n");

	old_fs = get_fs();
	set_fs(get_ds());

	snprintf(fw_path, BL_UMS_FW_PATH, "/sdcard/ssp/%s", pFn);

	fp = filp_open(fw_path, O_RDONLY, 0);
	if (IS_ERR(fp)) {
		iRet = ERROR;
		pr_err("file %s open error:%d\n", fw_path, (s32)fp);
		goto err_open;
	}

	uFSize = (unsigned int)fp->f_path.dentry->d_inode->i_size;
	pr_info("ssp_load_ums firmware size: %u\n", uFSize);

	buff = kzalloc((size_t)uFSize, GFP_KERNEL);
	if (!buff) {
		iRet = ERROR;
		pr_err("fail to alloc buffer for fw\n");
		goto err_alloc;
	}

	uNRead = (unsigned int)vfs_read(fp, (char __user *)buff,
			(unsigned int)uFSize, &fp->f_pos);
	if (uNRead != uFSize) {
		iRet = ERROR;
		pr_err("fail to read file %s (nread = %u)\n", fw_path, uNRead);
		goto err_fw_size;
	}

	/* Unlock bootloader */
	unlock_bootloader(client);

	while (uPos < uFSize) {
		if (check_bootloader(client, BL_WAITING_FRAME_DATA)) {
			iCheckWatingFrameDataError++;
			if (iCheckWatingFrameDataError > 10) {
				iRet = ERROR;
				pr_err("[SSP]: %s - F/W update fail\n",
					__func__);
				goto out;
			} else {
				pr_err("[SSP]: %s - F/W data_error %d, retry\n",
					__func__, iCheckWatingFrameDataError);
				continue;
			}
		}

		uFrameSize = (unsigned int)((*(buff + uPos) << 8) |
			*(buff + uPos + 1));

		/* We should add 2 at frame size as the the firmware data is not
		*  included the CRC bytes.
		*/
		uFrameSize += 2;

		/* Write one frame to device */
		fw_write(client, buff + uPos, uFrameSize);
		if (check_bootloader(client, BL_FRAME_CRC_PASS)) {
			iCheckFrameCrcError++;
			if (iCheckFrameCrcError > 10) {
				iRet = ERROR;
				pr_err("[SSP]: %s - F/W Update Fail. crc err\n",
					__func__);
				goto out;
			} else {
				pr_err("[SSP]: %s - F/W crc_error %d, retry\n",
					__func__, iCheckFrameCrcError);
				continue;
			}
		}

		uPos += uFrameSize;

		pr_info("[SSP] Updated %u bytes / %u bytes\n", uPos, uFSize);
		mdelay(1);
	}

out:
err_fw_size:
	kfree(buff);
err_alloc:
	filp_close(fp, NULL);
err_open:
	set_fs(old_fs);

	return iRet;
}
Exemplo n.º 4
0
static int load_kernel_fw_bootmode(struct ssp_data *data, const char *pFn)
{
	const struct firmware *fw = NULL;
	unsigned int uFrameSize;
	unsigned int uPos = 0;
	int iRet;
	int iCheckFrameCrcError = 0;
	int iCheckWatingFrameDataError = 0;
	int count = 0;

	pr_info("[SSP] ssp_load_fw start!!!\n");

	iRet = request_firmware(&fw, pFn, &data->spi->dev);
	if (iRet) {
		pr_err("[SSP]: %s - Unable to open firmware %s\n",
			__func__, pFn);
		return iRet;
	}

	/* Unlock bootloader */
	iRet = unlock_bootloader(data);
	if (iRet < 0) {
		pr_err("[SSP] %s - unlock_bootloader failed! %d\n",
			__func__, iRet);
		goto out;
	}

	while (uPos < fw->size) {
		iRet = check_bootloader(data, BL_WAITING_FRAME_DATA);
		if (iRet) {
			iCheckWatingFrameDataError++;
			if (iCheckWatingFrameDataError > 10) {
				pr_err("[SSP]: %s - F/W update fail\n",
					__func__);
				goto out;
			} else {
				pr_err("[SSP]: %s - F/W data_error %d, retry\n",
					__func__, iCheckWatingFrameDataError);
				continue;
			}
		}

		uFrameSize = ((*(fw->data + uPos) << 8) |
			*(fw->data + uPos + 1));

		/* We should add 2 at frame size as the the firmware data is not
		*  included the CRC bytes.
		*/
		uFrameSize += 2;

		/* Write one frame to device */
		fw_write(data, fw->data + uPos, uFrameSize);
		iRet = check_bootloader(data, BL_FRAME_CRC_PASS);
		if (iRet) {
			iCheckFrameCrcError++;
			if (iCheckFrameCrcError > 10) {
				pr_err("[SSP]: %s - F/W Update Fail. crc err\n",
					__func__);
				goto out;
			} else {
				pr_err("[SSP]: %s - F/W crc_error %d, retry\n",
					__func__, iCheckFrameCrcError);
				continue;
			}
		}

		uPos += uFrameSize;
		if (count++ == 100) {
			pr_info("[SSP] Updated %d bytes / %zd bytes\n", uPos,
				fw->size);
			count = 0;
		}
	}
	pr_info("[SSP] Firmware download is success.(%d bytes)\n", uPos);
out:
	release_firmware(fw);
	return iRet;
}