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;
}
示例#2
0
void check_fwbl(struct ssp_data *data)
{
	int iRet;

	data->client->addr = BOOTLOADER_SLAVE_ADDR;
	iRet = check_bootloader(data->client, BL_WAITING_BOOTLOAD_CMD);

	if (iRet >= 0) {
		pr_info("[SSP] ssp_load_fw_bootmode\n");
		load_fw_bootmode(data->client, BL_FW_NAME);
		msleep(SSP_SW_RESET_TIME);
	} else {
		data->client->addr = APP_SLAVE_ADDR;
		data->uCurFirmRev = get_firmware_rev(data);
		if (data->uCurFirmRev != SSP_FIRMWARE_REVISION) {
			pr_info("[SSP] MPU Firm Rev. : Old = %8u, New = %8u\n",
				data->uCurFirmRev, SSP_FIRMWARE_REVISION);
			update_mcu_bin(data);
		}
	}

	data->client->addr = APP_SLAVE_ADDR;
	data->uCurFirmRev = get_firmware_rev(data);
	pr_info("[SSP] MPU Firm Rev. : Old = %8u, New = %8u\n",
		data->uCurFirmRev, SSP_FIRMWARE_REVISION);
}
int check_fwbl(struct ssp_data *data)
{
	int iRet;
	unsigned int fw_revision;

	fw_revision = get_module_rev(data);
	data->uCurFirmRev = get_firmware_rev(data);

	if ((data->uCurFirmRev == SSP_INVALID_REVISION) \
		|| (data->uCurFirmRev == SSP_INVALID_REVISION2)) {
		iRet = check_bootloader(data, BL_WAITING_BOOTLOAD_CMD);

		if (iRet >= 0)
			pr_info("[SSP] ssp_load_fw_bootmode\n");
		else {
			pr_warn("[SSP] Firm Rev is invalid(%8u). Retry.\n",
				data->uCurFirmRev);
			data->uCurFirmRev = get_firmware_rev(data);
		}
		data->uCurFirmRev = SSP_INVALID_REVISION;
		pr_err("[SSP] SSP_INVALID_REVISION\n");
		return FW_DL_STATE_NEED_TO_SCHEDULE;
	} else {
		if (data->uCurFirmRev != fw_revision) {
			pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
				data->uCurFirmRev, fw_revision);

			return FW_DL_STATE_NEED_TO_SCHEDULE;
		}
		pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
			data->uCurFirmRev, fw_revision);
	}

	return FW_DL_STATE_NONE;
}
int check_fwbl(struct ssp_data *data)
{
	int iRet;
	unsigned int fw_revision;

	pr_info("[SSP] change_rev = %d\n", data->ssp_changes);

	if (data->ssp_changes == SSP_MCU_L0)
		fw_revision = SSP_FIRMWARE_REVISION;
	else
		fw_revision = SSP_FIRMWARE_REVISION_03;

	data->client->addr = APP_SLAVE_ADDR;
	data->uCurFirmRev = check_firmware_rev(data);

	if (data->uCurFirmRev == SSP_INVALID_REVISION) {
		toggle_mcu_reset(data);
		msleep(SSP_SW_RESET_TIME);
	}

	if ((data->uCurFirmRev == SSP_INVALID_REVISION) \
		|| (data->uCurFirmRev == SSP_INVALID_REVISION2)) {
		data->client->addr = BOOTLOADER_SLAVE_ADDR;
		iRet = check_bootloader(data->client, BL_WAITING_BOOTLOAD_CMD);

		if (iRet >= 0) {
			pr_info("[SSP] ssp_load_fw_bootmode\n");

			return FW_DL_STATE_NEED_TO_SCHEDULE;
		} else {
			pr_warn("[SSP] Firm Rev is invalid(%8u). Retry.\n",
				data->uCurFirmRev);
			data->client->addr = APP_SLAVE_ADDR;
			data->uCurFirmRev = get_firmware_rev(data);
			if (data->uCurFirmRev == SSP_INVALID_REVISION ||\
				data->uCurFirmRev == ERROR) {
				pr_err("[SSP] MCU is not working, FW download failed\n");
				return FW_DL_STATE_FAIL;
			} else if (data->uCurFirmRev != fw_revision) {
				pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
					data->uCurFirmRev, fw_revision);

				return FW_DL_STATE_NEED_TO_SCHEDULE;
			}
			pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
				data->uCurFirmRev, fw_revision);
		}
	} else {
		if (data->uCurFirmRev != fw_revision) {
			pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
				data->uCurFirmRev, fw_revision);

			return FW_DL_STATE_NEED_TO_SCHEDULE;
		}
		pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
			data->uCurFirmRev, fw_revision);
	}

	return FW_DL_STATE_NONE;
}
示例#5
0
int main(void)
{
    _buttonusr_isr = (void *)&buttonisr_usr;
    _timerusr_isr = (void *)&timerisr_usr;
    _mmhusr_isr = (void *)&mmhisr;

    /* Drop privileges */
    drop_privs();

    /* Init board */
    kk_board_init();

    /* Program the model into OTP, if we're not in screen-test mode, and it's
     * not already there
     */
    (void)flash_programModel();

    /* Init for safeguard against stack overflow (-fstack-protector-all) */
    __stack_chk_guard = (uintptr_t)random32();

    /* Bootloader Verification */
    check_bootloader();

    led_func(SET_RED_LED);
    dbg_print("Application Version %d.%d.%d\n\r", MAJOR_VERSION, MINOR_VERSION,
              PATCH_VERSION);

    /* Init storage */
    storage_init();

    /* Init protcol buffer message map and usb msg callback */
    fsm_init();

    led_func(SET_GREEN_LED);

    usbInit();
    u2fInit();
    led_func(CLR_RED_LED);

    reset_idle_time();

    if (is_mfg_mode())
        layout_screen_test();
    else if (!storage_isInitialized())
        layout_standard_notification("Welcome", "keepkey.com/get-started",
                                     NOTIFICATION_LOGO);
    else
        layoutHomeForced();

    while (1) {
        delay_ms_with_callback(ONE_SEC, &exec, 1);
        increment_idle_time(ONE_SEC);
        toggle_screensaver();
    }

    return 0;
}
int check_fwbl(struct ssp_data *data)
{

	unsigned int fw_revision;

	pr_info("[SSP] change_rev = %d\n", data->ssp_changes);
#if defined(CONFIG_SEC_KSPORTS_PROJECT)
	fw_revision = SSP_FIRMWARE_REVISION_TASMAN;
#elif defined(CONFIG_SENSORS_SSP_STM_HESTIA)
	fw_revision = SSP_FIRMWARE_REVISION_HESTIA;
#else
	fw_revision = SSP_FIRMWARE_REVISION_STM;
#endif

	data->uCurFirmRev = get_firmware_rev(data);

	if ((data->uCurFirmRev == SSP_INVALID_REVISION)
			|| (data->uCurFirmRev == SSP_INVALID_REVISION2)) {
#if STM_SHOULD_BE_IMPLEMENT
		data->client->addr = BOOTLOADER_SLAVE_ADDR;
		iRet = check_bootloader(data->client, BL_WAITING_BOOTLOAD_CMD);

		if (iRet >= 0)
			pr_info("[SSP] ssp_load_fw_bootmode\n");
		else {
			pr_warn("[SSP] Firm Rev is invalid(%8u). Retry.\n",
					data->uCurFirmRev);
			data->client->addr = APP_SLAVE_ADDR;
			data->uCurFirmRev = get_firmware_rev(data);
			if (data->uCurFirmRev == SSP_INVALID_REVISION
					|| data->uCurFirmRev == ERROR) {
				pr_err("[SSP] MCU is not working, FW download failed\n");
				return FW_DL_STATE_FAIL;
			}
		}
#endif
		data->uCurFirmRev = SSP_INVALID_REVISION;
		pr_err("[SSP] SSP_INVALID_REVISION\n");
		return FW_DL_STATE_NEED_TO_SCHEDULE;
	} else {
		if (data->uCurFirmRev != fw_revision) {
			pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
				data->uCurFirmRev, fw_revision);

			return FW_DL_STATE_NEED_TO_SCHEDULE;
		}
		pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
			data->uCurFirmRev, fw_revision);
	}

	return FW_DL_STATE_NONE;
}
int check_fwbl(struct ssp_data *data)
{
	int iRet;

	data->client->addr = APP_SLAVE_ADDR;
	data->uCurFirmRev = get_firmware_rev(data);

	if (data->uCurFirmRev == SSP_INVALID_REVISION) {
		toggle_mcu_reset(data);
		msleep(SSP_SW_RESET_TIME);

		data->client->addr = BOOTLOADER_SLAVE_ADDR;
		iRet = check_bootloader(data->client, BL_WAITING_BOOTLOAD_CMD);

		if (iRet >= 0) {
			pr_info("[SSP] ssp_load_fw_bootmode\n");

			return FW_DL_STATE_NEED_TO_SCHEDULE;
		} else {
			pr_warn("[SSP] Firm Rev is invalid. Retry.\n");
			data->client->addr = APP_SLAVE_ADDR;
			data->uCurFirmRev = get_firmware_rev(data);

			if (data->uCurFirmRev == SSP_INVALID_REVISION ||\
				data->uCurFirmRev == ERROR) {
				pr_err("[SSP] MCU is not working\n");
				return FW_DL_STATE_FAIL;
			} else if (data->uCurFirmRev != SSP_FIRMWARE_REVISION) {
				pr_info("[SSP] MCU Firm Rev : Old = %8u, New = "
					"%8u\n", data->uCurFirmRev,
					SSP_FIRMWARE_REVISION);
				return FW_DL_STATE_NEED_TO_SCHEDULE;
			}
			pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
				data->uCurFirmRev, SSP_FIRMWARE_REVISION);
		}
	} else {
		if (data->uCurFirmRev != SSP_FIRMWARE_REVISION) {
			pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
				data->uCurFirmRev, SSP_FIRMWARE_REVISION);

			return FW_DL_STATE_NEED_TO_SCHEDULE;
		}
		pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
			data->uCurFirmRev, SSP_FIRMWARE_REVISION);
	}

	return FW_DL_STATE_NONE;
}
示例#8
0
int check_fwbl(struct ssp_data *data)
{
	int iRet;
	unsigned int fw_revision;

#if defined(CONFIG_SENSORS_MPU6500_BMI058_DUAL)
	if (data->ap_rev < MPU6500_REV)
		fw_revision = SSP_BMI_FIRMWARE_REVISION;
	else
		fw_revision = SSP_FIRMWARE_REVISION;
#else
	fw_revision = SSP_FIRMWARE_REVISION;
#endif
	data->uCurFirmRev = get_firmware_rev(data);

	if ((data->uCurFirmRev == SSP_INVALID_REVISION) \
		|| (data->uCurFirmRev == SSP_INVALID_REVISION2)) {
		iRet = check_bootloader(data, BL_WAITING_BOOTLOAD_CMD);

		if (iRet >= 0)
			pr_info("[SSP] ssp_load_fw_bootmode\n");
		else {
			pr_warn("[SSP] Firm Rev is invalid(%8u). Retry.\n",
				data->uCurFirmRev);
			data->uCurFirmRev = get_firmware_rev(data);
		}
		data->uCurFirmRev = SSP_INVALID_REVISION;
		pr_err("[SSP] SSP_INVALID_REVISION\n");
		return FW_DL_STATE_NEED_TO_SCHEDULE;
	} else {
		if (data->uCurFirmRev != fw_revision) {
			pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
				data->uCurFirmRev, fw_revision);

			return FW_DL_STATE_NEED_TO_SCHEDULE;
		}
		pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
			data->uCurFirmRev, fw_revision);
	}

	return FW_DL_STATE_NONE;
}
示例#9
0
int
main(void)
{
	int i, j, k, l;
	unsigned button[3];
	unsigned steps[3];
	unsigned hz;

	/*-------------------------------------------------------------
	 * First things first:  Start the watchdog
	 */

	fido_setup(0x1000);

	/*-------------------------------------------------------------
	 * Setup GPIO
	 */

	LPC_SYSCON->SYSAHBCLKCTRL |=  (1 << 6);			// GPIO
	LPC_SYSCON->PRESETCTRL    &= ~(1 << 10);		// GPIO reset
	LPC_SYSCON->PRESETCTRL    |= (1 << 10);

	LPC_IOCON->PIO0_0 = 0
		| (1 << 3)					// Pull down
		| (1 << 5)					// Hysteresis
		;

	LPC_IOCON->PIO0_1 = 0
		| (2 << 3)					// Pull up
		| (1 << 5)					// Hysteresis
		;

	LPC_IOCON->PIO0_2 = 0
		| (2 << 3)					// Pull up
		| (1 << 5)					// Hysteresis
		;

	LPC_IOCON->PIO0_3 = 0
		| (2 << 3)					// Pull up
		| (1 << 5)					// Hysteresis
		;

	LPC_IOCON->PIO0_5 = 0
		| (2 << 3)					// Pull up
		| (1 << 5)					// Hysteresis
		;

	/*-------------------------------------------------------------
	 * Provide a chance to enter the boot-loader
	 */

	check_bootloader();

	/*-------------------------------------------------------------
	 * Enable UART for startup-debugging
	 */

	uart0Init(115200);
	uart_enable();

	/*-------------------------------------------------------------
	 * Start timer
	 */

	mrtInit(__SYSTEM_CLOCK/1000);

	/*-------------------------------------------------------------
	 * Enable reset pin
	 */

	LPC_SWM->PINENABLE0 = ~(1 << 6);		// PIO0_5 RESET_EN

	/*-------------------------------------------------------------
	 * Hello World
	 */

	welcome();

	/*-------------------------------------------------------------
	 * Detect pin-configuration by counting edges on the two possible
	 * possible clock inputs.
 	 *
	 * If neither is active the watch-dog will trigger.
	 */

	do {
		/* Measure input frequency on PIO0_1 and PIO0_2 */
		for (i = 1; i < 3; i++) {
			sct_setup(i);
			k = LPC_SCT->COUNT_U;
			mrtDelay(100);
			l = LPC_SCT->COUNT_U;
			hz = 10 * (l-k);
			printf("Rate PIO0_%d = %u\r\n", i, hz);
			if (hz > 1000)
				break;
		}
	} while (hz < 1000);

	/*-------------------------------------------------------------
 	 * Configure counter
	 */

	mrtDelay(100);
	printf("Using PIO0_%d\r\n", i);
	mrtDelay(100);
	uart_disable();

	button[0] = 1<<(3-i);	steps[0] = 1;
	button[1] = 1<<3;	steps[1] = 60;
	button[2] = 1<<5;	steps[2] = 3600;
	if (i == 1) {

		LPC_SWM->PINENABLE0 &= ~(1 << 7);       // Enable CLKIN

		LPC_SYSCON->MAINCLKSEL = 0x1;		// PLL input
		LPC_SYSCON->MAINCLKUEN = 0x0;
		LPC_SYSCON->MAINCLKUEN = 0x1;

		LPC_SYSCON->SYSPLLCLKSEL = 0x3;		// CLKIN
		LPC_SYSCON->SYSPLLCLKUEN = 0x0;
		LPC_SYSCON->SYSPLLCLKUEN = 0x1;

		LPC_SYSCON->SYSAHBCLKDIV = 1;

		sct_setup(0xff);
		mrtInit(FREQ/1000);

		/* Calibrated to look like 0x00 at 115200 bps */
		pulse_lo = 29;
		pulse_hi = 10;
	} else {
		sct_setup(2);
	}

	sct_output(4);

	/*-------------------------------------------------------------
	 * Until the clock is set, have it run 11 times too fast
	 */
	while (1) {
		fido_pat();
		if (!(LPC_GPIO_PORT->PIN0 & button[0]))
			break;
		if (!(LPC_GPIO_PORT->PIN0 & button[1]))
			break;
		if (!(LPC_GPIO_PORT->PIN0 & button[2]))
			break;
		mrtDelay(100);
		run_pulse();
	}

	LPC_SWM->PINENABLE0 |= (1 << 6);		// Disable RESET

	j = 0;
	while(1) {
		if (j == 0 && LPC_SCT->COUNT_U < 10000) {
			fido_pat();
			j = 1;
		}
		if (j == 1 && LPC_SCT->COUNT_U > 10000) {
			j = 0;
		}

		for (i = 0; i < 3; i++) {
			if (LPC_GPIO_PORT->PIN0 & button[i])
				continue;

			fido_pat();

			for(k = 0; k < steps[i]; k++)
				run_pulse();

			if (i > 0) {
				/*
				 * Min/Hour button release
				 * If you hold them for 10+ seconds
				 * The watch-dog bites
				 */
				for(k = 0; k < 1000; k++) {
					if (LPC_GPIO_PORT->PIN0 & button[i])
						continue;
					k = 0;
				}
				continue;
			}

			/* Check if the Sec button is held for >1s */

			mrt_counter = 0;
			for(k = 0; k < 1000; k++) {
				if (LPC_GPIO_PORT->PIN0 & button[i])
					break;
				if (mrt_counter > 1000)
					break;
				k = 0;
			}
			if (k == 1000)
				continue;

			/* Stop counter */
			sct_stop();

			/*
			 * Restart counter on button release
			 * or sync input
			 */
			for(k = 0; k < 1000; k++) {
				if (LPC_GPIO_PORT->PIN0 & button[i])
					break;
				l = LPC_GPIO_PORT->PIN0 & (1<<0);
				if (l)
					k = 0;
			}

			l = (1 << 0) | button[i];
			while (!(LPC_GPIO_PORT->PIN0 & l))
				continue;

			/*
			 * Calibrated for falling edge = PPI rising edge
			 * PPSO comes 164ns after PPS1
			 */
			LPC_SCT->COUNT_U = FREQ - 366;
			LPC_SCT->CTRL_L &= ~(1 << 2);		// Start

			for(k = 0; k < 1000; k++) {
				if (LPC_GPIO_PORT->PIN0 & button[i])
					continue;
				k = 0;
			}
		}
	}
}
示例#10
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;
}
示例#11
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;
}
示例#12
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;
}
示例#13
0
int check_fwbl(struct ssp_data *data)
{

	unsigned int fw_revision;

	pr_info("[SSP] change_rev = %d\n", data->ssp_changes);
#if defined (CONFIG_MACH_VIKALCU)
	fw_revision = SSP_FIRMWARE_REVISION_STM;
#elif defined (CONFIG_MACH_HLTEVZW) || defined (CONFIG_MACH_HLTESPR) \
	|| defined (CONFIG_MACH_HLTEUSC)
		if (data->ap_rev > 3)
			fw_revision = SSP_FIRMWARE_REVISION_STM;
		else if (data->ap_rev > 2)
			fw_revision = SSP_FIRMWARE_REVISION_STM_88921;
		else
			fw_revision = SSP_FIRMWARE_REVISION_STM_RVS;
#else
	if (data->ap_rev > 3)
		fw_revision = SSP_FIRMWARE_REVISION_STM;
	else
		fw_revision = SSP_FIRMWARE_REVISION_STM_88921;
#endif

	data->uCurFirmRev = get_firmware_rev(data);

	if ((data->uCurFirmRev == SSP_INVALID_REVISION) \
		|| (data->uCurFirmRev == SSP_INVALID_REVISION2)) {
#if STM_SHOULD_BE_IMPLEMENT
		data->client->addr = BOOTLOADER_SLAVE_ADDR;
		iRet = check_bootloader(data->client, BL_WAITING_BOOTLOAD_CMD);

		if (iRet >= 0) {
			pr_info("[SSP] ssp_load_fw_bootmode\n");

			return FW_DL_STATE_NEED_TO_SCHEDULE;
		} else {
			pr_warn("[SSP] Firm Rev is invalid(%8u). Retry.\n",
				data->uCurFirmRev);
			data->client->addr = APP_SLAVE_ADDR;
			data->uCurFirmRev = get_firmware_rev(data);
			if (data->uCurFirmRev == SSP_INVALID_REVISION ||\
				data->uCurFirmRev == ERROR) {
				pr_err("[SSP] MCU is not working, FW download failed\n");
				return FW_DL_STATE_FAIL;
			} else if (data->uCurFirmRev != fw_revision) {
				pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
					data->uCurFirmRev, fw_revision);

				return FW_DL_STATE_NEED_TO_SCHEDULE;
			}
			pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
				data->uCurFirmRev, fw_revision);
		}
#endif
		pr_err("[SSP] SSP_INVALID_REVISION\n");
		return FW_DL_STATE_NEED_TO_SCHEDULE;
	} else {
		if (data->uCurFirmRev != fw_revision) {
			pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
				data->uCurFirmRev, fw_revision);

			return FW_DL_STATE_NEED_TO_SCHEDULE;
		}
		pr_info("[SSP] MCU Firm Rev : Old = %8u, New = %8u\n",
			data->uCurFirmRev, fw_revision);
	}

	return FW_DL_STATE_NONE;
}