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; }
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; }
/* 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; }