summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--flashrom.88
-rw-r--r--ft2232_spi.c99
-rw-r--r--print.c9
-rw-r--r--programmer.h13
4 files changed, 106 insertions, 23 deletions
diff --git a/flashrom.8 b/flashrom.8
index 2ee22b5..aab2d02 100644
--- a/flashrom.8
+++ b/flashrom.8
@@ -177,11 +177,11 @@ Specify the programmer device. Currently supported are:
.sp
.BR "* atahpt" " (for flash ROMs on Highpoint ATA/RAID controllers)"
.sp
-.BR "* it87spi" " (for flash ROMs behind an ITE IT87xx Super I/O LPC/SPI\
+.BR "* it87spi" " (for flash ROMs behind an ITE IT87xx Super I/O LPC/SPI \
translation unit)"
.sp
-.BR "* ft2232_spi" " (for SPI flash ROMs attached to a FT2232H/FT4232H based\
-USB SPI programmer)"
+.BR "* ft2232_spi" " (for SPI flash ROMs attached to a FT2232H/FT4232H/JTAGkey \
+based USB SPI programmer)"
.sp
.BR "* serprog" " (for flash ROMs attached to a programmer speaking serprog)"
.sp
@@ -351,7 +351,7 @@ type and interface/port it should support. For that you have to use the
syntax where
.B model
can be any of
-.BR 2232H ", or " 4232H
+.BR 2232H ", "JTAGkey ", or " 4232H
and
.B interface
can be any of
diff --git a/ft2232_spi.c b/ft2232_spi.c
index 25006fb..320725d 100644
--- a/ft2232_spi.c
+++ b/ft2232_spi.c
@@ -31,6 +31,19 @@
#include "spi.h"
#include <ftdi.h>
+
+#define FTDI_VID 0x0403
+#define FTDI_FT2232H_PID 0x6010
+#define FTDI_FT4232H_PID 0x6011
+#define AMONTEC_JTAGKEY_PID 0xCFF8
+
+const struct usbdev_status devs_ft2232spi[] = {
+ {FTDI_VID, FTDI_FT2232H_PID, OK, "FTDI", "FT2232H"},
+ {FTDI_VID, FTDI_FT4232H_PID, OK, "FTDI", "FT4232H"},
+ {FTDI_VID, AMONTEC_JTAGKEY_PID, OK, "Amontec", "JTAGkey"},
+ {},
+};
+
/*
* The 'H' chips can run internally at either 12MHz or 60MHz.
* The non-H chips can only run at 12MHz.
@@ -46,8 +59,43 @@
#define BITMODE_BITBANG_NORMAL 1
#define BITMODE_BITBANG_SPI 2
+/* Set data bits low-byte command:
+ * value: 0x08 CS=high, DI=low, DO=low, SK=low
+ * dir: 0x0b CS=output, DI=input, DO=output, SK=output
+ *
+ * JTAGkey(2) needs to enable its output via Bit4 / GPIOL0
+ * value: 0x18 OE=high, CS=high, DI=low, DO=low, SK=low
+ * dir: 0x1b OE=output, CS=output, DI=input, DO=output, SK=output
+ *
+ */
+static unsigned char cs_bits = 0x08;
+static unsigned char pindir = 0x0b;
static struct ftdi_context ftdic_context;
+static const char *get_ft2232_devicename(int ft2232_vid, int ft2232_type)
+{
+ int i;
+ for (i=0; devs_ft2232spi[i].vendor_name != NULL; i ++) {
+ if ((devs_ft2232spi[i].device_id == ft2232_type)
+ && (devs_ft2232spi[i].vendor_id == ft2232_vid))
+ return devs_ft2232spi[i].device_name;
+ }
+ return "unknown device";
+}
+
+static const char *get_ft2232_vendorname(int ft2232_vid, int ft2232_type)
+{
+ int i;
+ for (i=0; devs_ft2232spi[i].vendor_name != NULL; i ++) {
+ if ((devs_ft2232spi[i].device_id == ft2232_type)
+ && (devs_ft2232spi[i].vendor_id == ft2232_vid))
+ return devs_ft2232spi[i].vendor_name;
+ }
+ return "unknown vendor";
+}
+
+
+
static int send_buf(struct ftdi_context *ftdic, const unsigned char *buf, int size)
{
int r;
@@ -77,16 +125,23 @@ int ft2232_spi_init(void)
int f;
struct ftdi_context *ftdic = &ftdic_context;
unsigned char buf[512];
- int ft2232_type = FTDI_FT4232H;
+ int ft2232_vid = FTDI_VID;
+ int ft2232_type = FTDI_FT4232H_PID;
enum ftdi_interface ft2232_interface = INTERFACE_B;
char *arg;
arg = extract_programmer_param("type");
if (arg) {
if (!strcasecmp(arg, "2232H"))
- ft2232_type = FTDI_FT2232H;
+ ft2232_type = FTDI_FT2232H_PID;
else if (!strcasecmp(arg, "4232H"))
- ft2232_type = FTDI_FT4232H;
+ ft2232_type = FTDI_FT4232H_PID;
+ else if (!strcasecmp(arg, "jtagkey")) {
+ ft2232_type = AMONTEC_JTAGKEY_PID;
+ ft2232_interface = INTERFACE_A;
+ cs_bits = 0x18;
+ pindir = 0x1b;
+ }
else {
msg_perr("Error: Invalid device type specified.\n");
free(arg);
@@ -110,8 +165,9 @@ int ft2232_spi_init(void)
}
}
free(arg);
- msg_pdbg("Using device type %s ",
- (ft2232_type == FTDI_FT2232H) ? "2232H" : "4232H");
+ msg_pdbg("Using device type %s %s ",
+ get_ft2232_vendorname(ft2232_vid,ft2232_type),
+ get_ft2232_devicename(ft2232_vid,ft2232_type));
msg_pdbg("interface %s\n",
(ft2232_interface == INTERFACE_A) ? "A" : "B");
@@ -120,7 +176,7 @@ int ft2232_spi_init(void)
return EXIT_FAILURE; // TODO
}
- f = ftdi_usb_open(ftdic, 0x0403, ft2232_type);
+ f = ftdi_usb_open(ftdic, FTDI_VID, ft2232_type);
if (f < 0 && f != -5) {
msg_perr("Unable to open FTDI device: %d (%s)\n", f,
@@ -179,14 +235,9 @@ int ft2232_spi_init(void)
return -1;
msg_pdbg("Set data bits\n");
- /* Set data bits low-byte command:
- * value: 0x08 CS=high, DI=low, DO=low, SK=low
- * dir: 0x0b CS=output, DI=input, DO=output, SK=output
- */
-#define CS_BIT 0x08
buf[0] = SET_BITS_LOW;
- buf[1] = CS_BIT;
- buf[2] = 0x0b;
+ buf[1] = cs_bits;
+ buf[2] = pindir;
if (send_buf(ftdic, buf, 3))
return -1;
@@ -231,8 +282,8 @@ int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt,
*/
msg_pspew("Assert CS#\n");
buf[i++] = SET_BITS_LOW;
- buf[i++] = 0 & ~CS_BIT; /* assertive */
- buf[i++] = 0x0b;
+ buf[i++] = 0 & ~cs_bits; /* assertive */
+ buf[i++] = pindir;
if (writecnt) {
buf[i++] = 0x11;
@@ -273,8 +324,8 @@ int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt,
msg_pspew("De-assert CS#\n");
buf[i++] = SET_BITS_LOW;
- buf[i++] = CS_BIT;
- buf[i++] = 0x0b;
+ buf[i++] = cs_bits;
+ buf[i++] = pindir;
ret = send_buf(ftdic, buf, i);
failed |= ret;
if (ret)
@@ -294,4 +345,18 @@ int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int l
return spi_write_chunked(flash, buf, start, len, 256);
}
+void print_supported_usbdevs(const struct usbdev_status *devs)
+{
+ int i;
+
+ for (i = 0; devs[i].vendor_name != NULL; i++) {
+ msg_pinfo("%s %s [%02x:%02x]%s\n", devs[i].vendor_name,
+ devs[i].device_name, devs[i].vendor_id,
+ devs[i].device_id,
+ (devs[i].status == NT) ? " (untested)" : "");
+ }
+}
+
+
+
#endif
diff --git a/print.c b/print.c
index 14aa489..5504880 100644
--- a/print.c
+++ b/print.c
@@ -255,6 +255,15 @@ void print_supported(void)
#if CONFIG_ATAHPT == 1
print_supported_pcidevs(ata_hpt);
#endif
+
+#if CONFIG_FT2232_SPI+CONFIG_DEDIPROG >= 1
+ printf("\nSupported USB devices flashrom can use "
+ "as programmer:\n\n");
+#endif
+
+#if CONFIG_FT2232_SPI == 1
+ print_supported_usbdevs(devs_ft2232spi);
+#endif
}
#if CONFIG_INTERNAL == 1
diff --git a/programmer.h b/programmer.h
index 226db04..b8b7d04 100644
--- a/programmer.h
+++ b/programmer.h
@@ -397,12 +397,21 @@ extern const struct pcidev_status ata_hpt[];
#endif
/* ft2232_spi.c */
-#define FTDI_FT2232H 0x6010
-#define FTDI_FT4232H 0x6011
+#if CONFIG_FT2232_SPI == 1
+struct usbdev_status {
+uint16_t vendor_id;
+ uint16_t device_id;
+ int status;
+ const char *vendor_name;
+ const char *device_name;
+};
int ft2232_spi_init(void);
int ft2232_spi_send_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr);
int ft2232_spi_read(struct flashchip *flash, uint8_t *buf, int start, int len);
int ft2232_spi_write_256(struct flashchip *flash, uint8_t *buf, int start, int len);
+extern const struct usbdev_status devs_ft2232spi[];
+void print_supported_usbdevs(const struct usbdev_status *devs);
+#endif
/* rayer_spi.c */
#if CONFIG_RAYER_SPI == 1
OpenPOWER on IntegriCloud