mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-26 22:52:34 +02:00
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>
This commit is contained in:
parent
acd6a326cb
commit
e25129d9b6
50
ch347_spi.c
50
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 @@ static const struct spi_master spi_master_ch347_spi = {
|
||||
/* 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 @@ static int ch347_spi_init(const struct programmer_cfg *cfg)
|
||||
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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user