Author: stefanct
Date: Thu Feb 18 22:42:15 2016
New Revision: 1927
URL: http://flashrom.org/trac/flashrom/changeset/1927

Log:
dediprog: add support for SF600.

This patch is based on a number of changes by David Woodhouse and
David Hendricks.

SF600 uses two bulk endpoints, 1 for out and 2 for in unlike the
SF100 that uses only a single one. This patch make endpoint usage
more explicit and sets the in/out endpoint(s) appropriately for
SF100 and SF600.

Also, change all SF100-specific strings in messages and
leave standalone mode on SF600s.

Signed-off-by: David Woodhouse <david.woodho...@intel.com>
Signed-off-by: David Hendricks <dhend...@chromium.org>
Signed-off-by: Stefan Tauner <stefan.tau...@alumni.tuwien.ac.at>
Acked-by: Stefan Tauner <stefan.tau...@alumni.tuwien.ac.at>

Modified:
   trunk/dediprog.c

Modified: trunk/dediprog.c
==============================================================================
--- trunk/dediprog.c    Wed Feb 17 23:25:12 2016        (r1926)
+++ trunk/dediprog.c    Thu Feb 18 22:42:15 2016        (r1927)
@@ -45,7 +45,14 @@
 #define REQTYPE_EP_OUT (USB_ENDPOINT_OUT | USB_TYPE_VENDOR | 
USB_RECIP_ENDPOINT)       /* 0x42 */
 #define REQTYPE_EP_IN (USB_ENDPOINT_IN | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT) 
        /* 0xC2 */
 static usb_dev_handle *dediprog_handle;
-static int dediprog_endpoint;
+static int dediprog_in_endpoint;
+static int dediprog_out_endpoint;
+
+enum dediprog_devtype {
+       DEV_UNKNOWN             = 0,
+       DEV_SF100               = 100,
+       DEV_SF600               = 600,
+};
 
 enum dediprog_leds {
        LED_INVALID             = -1,
@@ -127,16 +134,26 @@
        WRITE_MODE_4B_ADDR_256B_PAGE_PGM_FLAGS  = 12,
 };
 
+enum dediprog_standalone_mode {
+       ENTER_STANDALONE_MODE = 0,
+       LEAVE_STANDALONE_MODE = 1,
+};
+
 
 static int dediprog_firmwareversion = FIRMWARE_VERSION(0, 0, 0);
+enum dediprog_devtype dediprog_devicetype = DEV_UNKNOWN;
 
 /* Returns true if firmware (and thus hardware) supports the "new" protocol */
 static bool is_new_prot(void)
 {
-       /* if (SF100) */
-       return dediprog_firmwareversion >= FIRMWARE_VERSION(5, 5, 0);
-       /* else if (SF600)
-       return dediprog_firmwareversion >= FIRMWARE_VERSION(6, 9, 0); */
+       switch (dediprog_devicetype) {
+       case DEV_SF100:
+               return dediprog_firmwareversion >= FIRMWARE_VERSION(5, 5, 0);
+       case DEV_SF600:
+               return dediprog_firmwareversion >= FIRMWARE_VERSION(6, 9, 0);
+       default:
+               return 0;
+       }
 }
 
 static int dediprog_read(enum dediprog_cmds cmd, unsigned int value, unsigned 
int idx, uint8_t *bytes, size_t size)
@@ -340,7 +357,7 @@
 
        unsigned int i;
        for (i = 0; i < count; i++) {
-               ret = usb_bulk_read(dediprog_handle, 0x80 | dediprog_endpoint,
+               ret = usb_bulk_read(dediprog_handle, 0x80 | 
dediprog_in_endpoint,
                                    (char *)buf + i * chunksize, chunksize,
                                    DEFAULT_TIMEOUT);
                if (ret != chunksize) {
@@ -447,7 +464,7 @@
                char usbbuf[512];
                memcpy(usbbuf, buf + i * chunksize, chunksize);
                memset(usbbuf + chunksize, 0xff, sizeof(usbbuf) - chunksize); 
// fill up with 0xFF
-               ret = usb_bulk_write(dediprog_handle, dediprog_endpoint, 
usbbuf, 512, DEFAULT_TIMEOUT);
+               ret = usb_bulk_write(dediprog_handle, dediprog_out_endpoint, 
usbbuf, 512, DEFAULT_TIMEOUT);
                if (ret != 512) {
                        msg_perr("SPI bulk write failed, expected %i, got %i 
%s!\n", 512, ret, usb_strerror());
                        return 1;
@@ -575,7 +592,6 @@
 static int dediprog_check_devicestring(void)
 {
        int ret;
-       int fw[3];
        char buf[0x11];
 
        /* Command Receive Device String. */
@@ -586,16 +602,24 @@
        }
        buf[0x10] = '\0';
        msg_pdbg("Found a %s\n", buf);
-       if (memcmp(buf, "SF100", 0x5) != 0) {
-               msg_perr("Device not a SF100!\n");
+       if (memcmp(buf, "SF100", 0x5) == 0)
+               dediprog_devicetype = DEV_SF100;
+       else if (memcmp(buf, "SF600", 0x5) == 0)
+               dediprog_devicetype = DEV_SF600;
+       else {
+               msg_perr("Device not a SF100 or SF600!\n");
                return 1;
        }
-       if (sscanf(buf, "SF100 V:%d.%d.%d ", &fw[0], &fw[1], &fw[2]) != 3) {
+
+       int sfnum;
+       int fw[3];
+       if (sscanf(buf, "SF%d V:%d.%d.%d ", &sfnum, &fw[0], &fw[1], &fw[2]) != 
4 ||
+           sfnum != dediprog_devicetype) {
                msg_perr("Unexpected firmware version string '%s'\n", buf);
                return 1;
        }
        /* Only these major versions were tested. */
-       if (fw[0] < 2 || fw[0] > 6) {
+       if (fw[0] < 2 || fw[0] > 7) {
                msg_perr("Unexpected firmware version %d.%d.%d!\n", fw[0], 
fw[1], fw[2]);
                return 1;
        }
@@ -623,6 +647,23 @@
        return 0;
 }
 
+static int dediprog_standalone_mode(void)
+{
+       int ret;
+
+       if (dediprog_devicetype != DEV_SF600)
+               return 0;
+
+       msg_pdbg2("Disabling standalone mode.\n");
+       ret = dediprog_write(CMD_SET_STANDALONE, LEAVE_STANDALONE_MODE, 0, 
NULL, 0);
+       if (ret) {
+               msg_perr("Failed to disable standalone mode: %s\n", 
usb_strerror());
+               return 1;
+       }
+
+       return 0;
+}
+
 #if 0
 /* Something.
  * Present in eng_detect_blink.log with firmware 3.1.8
@@ -737,6 +778,7 @@
 static int dediprog_shutdown(void *data)
 {
        dediprog_firmwareversion = FIRMWARE_VERSION(0, 0, 0);
+       dediprog_devicetype = DEV_UNKNOWN;
 
        /* URB 28. Command Set SPI Voltage to 0. */
        if (dediprog_set_spi_voltage(0x0))
@@ -849,7 +891,7 @@
                 dev->descriptor.idVendor, dev->descriptor.idProduct);
        dediprog_handle = usb_open(dev);
        if (!dediprog_handle) {
-               msg_perr("Could not open USB device: %s\n", usb_strerror());
+               msg_perr("Could not find a Dediprog programmer on USB: %s\n", 
usb_strerror());
                return 1;
        }
        ret = usb_set_configuration(dediprog_handle, 1);
@@ -868,7 +910,6 @@
                        msg_perr("Could not close USB device!\n");
                return 1;
        }
-       dediprog_endpoint = 2;
 
        if (register_shutdown(dediprog_shutdown, NULL))
                return 1;
@@ -879,6 +920,13 @@
        if (dediprog_check_devicestring())
                return 1;
 
+       /* SF100 only has 1 endpoint for in/out, SF600 uses two separate 
endpoints instead. */
+       dediprog_in_endpoint = 2;
+       if (dediprog_devicetype == DEV_SF100)
+               dediprog_out_endpoint = 2;
+       else
+               dediprog_out_endpoint = 1;
+
        /* Set all possible LEDs as soon as possible to indicate activity.
         * Because knowing the firmware version is required to set the LEDs 
correctly we need to this after
         * dediprog_check_devicestring() has queried the device and set 
dediprog_firmwareversion. */
@@ -892,6 +940,9 @@
                return 1;
        }
 
+       if (dediprog_standalone_mode())
+               return 1;
+
        if (register_spi_master(&spi_master_dediprog) || 
dediprog_set_leds(LED_NONE))
                return 1;
 

_______________________________________________
flashrom mailing list
flashrom@flashrom.org
http://www.flashrom.org/mailman/listinfo/flashrom

Reply via email to