Пример #1
0
int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit)
{
	int	response;
	dbg("%s - %d", __FUNCTION__, reset_bit);
	response = ezusb_writememory (serial, CPUCS_REG, &reset_bit, 1, 0xa0);
	if (response < 0) {
		err("%s- %d failed", __FUNCTION__, reset_bit);
	}
	return response;
}
Пример #2
0
int ezusb_set_reset(struct usb_serial *serial, unsigned char reset_bit)
{
	int response;

	response = ezusb_writememory(serial, CPUCS_REG, &reset_bit, 1, 0xa0);
	if (response < 0)
		dev_err(&serial->dev->dev, "%s- %d failed\n",
						__func__, reset_bit);
	return response;
}
Пример #3
0
/* steps to download the firmware to the WhiteHEAT device:
 - hold the reset (by writing to the reset bit of the CPUCS register)
 - download the VEND_AX.HEX file to the chip using VENDOR_REQUEST-ANCHOR_LOAD
 - release the reset (by writing to the CPUCS register)
 - download the WH.HEX file for all addresses greater than 0x1b3f using
   VENDOR_REQUEST-ANCHOR_EXTERNAL_RAM_LOAD
 - hold the reset
 - download the WH.HEX file for all addresses less than 0x1b40 using
   VENDOR_REQUEST_ANCHOR_LOAD
 - release the reset
 - device renumerated itself and comes up as new device id with all
   firmware download completed.
*/
static int whiteheat_firmware_download(struct usb_serial *serial,
					const struct usb_device_id *id)
{
	int response, ret = -ENOENT;
	const struct firmware *loader_fw = NULL, *firmware_fw = NULL;
	const struct ihex_binrec *record;

	if (request_ihex_firmware(&firmware_fw, "whiteheat.fw",
				  &serial->dev->dev)) {
		dev_err(&serial->dev->dev,
			"%s - request \"whiteheat.fw\" failed\n", __func__);
		goto out;
	}
	if (request_ihex_firmware(&loader_fw, "whiteheat_loader.fw",
			     &serial->dev->dev)) {
		dev_err(&serial->dev->dev,
			"%s - request \"whiteheat_loader.fw\" failed\n",
			__func__);
		goto out;
	}
	ret = 0;
	response = ezusb_set_reset (serial, 1);

	record = (const struct ihex_binrec *)loader_fw->data;
	while (record) {
		response = ezusb_writememory (serial, be32_to_cpu(record->addr),
					      (unsigned char *)record->data,
					      be16_to_cpu(record->len), 0xa0);
		if (response < 0) {
			dev_err(&serial->dev->dev, "%s - ezusb_writememory "
				"failed for loader (%d %04X %p %d)\n",
				__func__, response, be32_to_cpu(record->addr),
				record->data, be16_to_cpu(record->len));
			break;
		}
		record = ihex_next_binrec(record);
	}

	response = ezusb_set_reset(serial, 0);

	record = (const struct ihex_binrec *)firmware_fw->data;
	while (record && be32_to_cpu(record->addr) < 0x1b40)
		record = ihex_next_binrec(record);
	while (record) {
		response = ezusb_writememory (serial, be32_to_cpu(record->addr),
					      (unsigned char *)record->data,
					      be16_to_cpu(record->len), 0xa3);
		if (response < 0) {
			dev_err(&serial->dev->dev, "%s - ezusb_writememory "
				"failed for first firmware step "
				"(%d %04X %p %d)\n", __func__, response,
				be32_to_cpu(record->addr), record->data,
				be16_to_cpu(record->len));
			break;
		}
		++record;
	}

	response = ezusb_set_reset(serial, 1);

	record = (const struct ihex_binrec *)firmware_fw->data;
	while (record && be32_to_cpu(record->addr) < 0x1b40) {
		response = ezusb_writememory (serial, be32_to_cpu(record->addr),
					      (unsigned char *)record->data,
					      be16_to_cpu(record->len), 0xa0);
		if (response < 0) {
			dev_err(&serial->dev->dev, "%s - ezusb_writememory "
				"failed for second firmware step "
				"(%d %04X %p %d)\n", __func__, response,
				be32_to_cpu(record->addr), record->data,
				be16_to_cpu(record->len));
			break;
		}
		++record;
	}
	ret = 0;
	response = ezusb_set_reset (serial, 0);
 out:
	release_firmware(loader_fw);
	release_firmware(firmware_fw);
	return ret;
}