Anastasia Klimchuk has submitted this change. ( https://review.coreboot.org/c/flashrom/+/82193?usp=email )
Change subject: ch347_spi: Add driver support for CH347F packaging ......................................................................
ch347_spi: Add driver support for CH347F packaging
CH347F can work simultaneously with SPI, I2C and other signals. CH347 introduce is available at the following URL: https://www.wch-ic.com/products/CH347.html
Change-Id: I693baf1a0d9dc20757f56fba626b5f5ad20f71dd Signed-off-by: ZhiYuanNJ Liu 871238103@qq.com Reviewed-on: https://review.coreboot.org/c/flashrom/+/82193 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Anastasia Klimchuk aklm@chromium.org Reviewed-by: Nicholas Chin nic.c3.14@gmail.com --- M ch347_spi.c 1 file changed, 29 insertions(+), 21 deletions(-)
Approvals: build bot (Jenkins): Verified Anastasia Klimchuk: Looks good to me, approved Nicholas Chin: Looks good to me, approved
diff --git a/ch347_spi.c b/ch347_spi.c index 570e25b..21dcabb 100644 --- a/ch347_spi.c +++ b/ch347_spi.c @@ -36,8 +36,8 @@ #define WRITE_EP 0x06 #define READ_EP 0x86
-#define MODE_1_IFACE 2 -#define MODE_2_IFACE 1 +#define CH347T_IFACE 2 +#define CH347F_IFACE 4
/* The USB descriptor says the max transfer size is 512 bytes, but the * vendor driver only seems to transfer a maximum of 510 bytes at once, @@ -48,25 +48,29 @@
struct ch347_spi_data { struct libusb_device_handle *handle; + int interface; };
/* TODO: Add support for HID mode */ static const struct dev_entry devs_ch347_spi[] = { - {0x1A86, 0x55DB, OK, "QinHeng Electronics", "USB To UART+SPI+I2C"}, + {0x1A86, 0x55DB, OK, "QinHeng Electronics", "USB To UART+SPI+I2C"}, /* CH347T */ + {0x1A86, 0x55DE, OK, "QinHeng Electronics", "USB To UART+SPI+I2C"}, /* CH347F */ {0} };
+static int ch347_interface[] = { + CH347T_IFACE, + CH347F_IFACE, +}; + static int ch347_spi_shutdown(void *data) { struct ch347_spi_data *ch347_data = data; - - /* TODO: Set this depending on the mode */ - int spi_interface = MODE_1_IFACE; + int spi_interface = ch347_data->interface; libusb_release_interface(ch347_data->handle, spi_interface); libusb_attach_kernel_driver(ch347_data->handle, spi_interface); libusb_close(ch347_data->handle); libusb_exit(NULL); - free(data); return 0; } @@ -262,6 +266,9 @@ /* Largely copied from ch341a_spi.c */ static int ch347_spi_init(const struct programmer_cfg *cfg) { + uint16_t vid = devs_ch347_spi[0].vendor_id; + uint16_t pid = 0; + int index = 0; struct ch347_spi_data *ch347_data = calloc(1, sizeof(*ch347_data)); if (!ch347_data) { msg_perr("Could not allocate space for SPI data\n"); @@ -274,35 +281,36 @@ free(ch347_data); return 1; } - /* Enable information, warning, and error messages (only). */ #if LIBUSB_API_VERSION < 0x01000106 libusb_set_debug(NULL, 3); #else libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO); #endif - - uint16_t vid = devs_ch347_spi[0].vendor_id; - uint16_t pid = devs_ch347_spi[0].device_id; - ch347_data->handle = libusb_open_device_with_vid_pid(NULL, vid, pid); - if (ch347_data->handle == NULL) { - msg_perr("Couldn't open device %04x:%04x.\n", vid, pid); + while (devs_ch347_spi[index].vendor_id != 0) { + vid = devs_ch347_spi[index].vendor_id; + pid = devs_ch347_spi[index].device_id; + ch347_data->handle = libusb_open_device_with_vid_pid(NULL, vid, pid); + if (ch347_data->handle) { + ch347_data->interface = ch347_interface[index]; + break; + } + index++; + } + if (!ch347_data->handle) { + msg_perr("Couldn't find CH347.\n"); free(ch347_data); return 1; }
- /* TODO: set based on mode */ - /* Mode 1 uses interface 2 for the SPI interface */ - int spi_interface = MODE_1_IFACE; - - ret = libusb_detach_kernel_driver(ch347_data->handle, spi_interface); + ret = libusb_detach_kernel_driver(ch347_data->handle, ch347_data->interface); if (ret != 0 && ret != LIBUSB_ERROR_NOT_FOUND) msg_pwarn("Cannot detach the existing USB driver. Claiming the interface may fail. %s\n", libusb_error_name(ret));
- ret = libusb_claim_interface(ch347_data->handle, spi_interface); + ret = libusb_claim_interface(ch347_data->handle, ch347_data->interface); if (ret != 0) { - msg_perr("Failed to claim interface 2: '%s'\n", libusb_error_name(ret)); + msg_perr("Failed to claim interface %d: '%s'\n", ch347_data->interface, libusb_error_name(ret)); goto error_exit; }