mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-27 23:22:37 +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
48
ch347_spi.c
48
ch347_spi.c
@ -36,8 +36,8 @@
|
|||||||
#define WRITE_EP 0x06
|
#define WRITE_EP 0x06
|
||||||
#define READ_EP 0x86
|
#define READ_EP 0x86
|
||||||
|
|
||||||
#define MODE_1_IFACE 2
|
#define CH347T_IFACE 2
|
||||||
#define MODE_2_IFACE 1
|
#define CH347F_IFACE 4
|
||||||
|
|
||||||
/* The USB descriptor says the max transfer size is 512 bytes, but the
|
/* 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,
|
* vendor driver only seems to transfer a maximum of 510 bytes at once,
|
||||||
@ -48,25 +48,29 @@
|
|||||||
|
|
||||||
struct ch347_spi_data {
|
struct ch347_spi_data {
|
||||||
struct libusb_device_handle *handle;
|
struct libusb_device_handle *handle;
|
||||||
|
int interface;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* TODO: Add support for HID mode */
|
/* TODO: Add support for HID mode */
|
||||||
static const struct dev_entry devs_ch347_spi[] = {
|
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}
|
{0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int ch347_interface[] = {
|
||||||
|
CH347T_IFACE,
|
||||||
|
CH347F_IFACE,
|
||||||
|
};
|
||||||
|
|
||||||
static int ch347_spi_shutdown(void *data)
|
static int ch347_spi_shutdown(void *data)
|
||||||
{
|
{
|
||||||
struct ch347_spi_data *ch347_data = data;
|
struct ch347_spi_data *ch347_data = data;
|
||||||
|
int spi_interface = ch347_data->interface;
|
||||||
/* TODO: Set this depending on the mode */
|
|
||||||
int spi_interface = MODE_1_IFACE;
|
|
||||||
libusb_release_interface(ch347_data->handle, spi_interface);
|
libusb_release_interface(ch347_data->handle, spi_interface);
|
||||||
libusb_attach_kernel_driver(ch347_data->handle, spi_interface);
|
libusb_attach_kernel_driver(ch347_data->handle, spi_interface);
|
||||||
libusb_close(ch347_data->handle);
|
libusb_close(ch347_data->handle);
|
||||||
libusb_exit(NULL);
|
libusb_exit(NULL);
|
||||||
|
|
||||||
free(data);
|
free(data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -262,6 +266,9 @@ static const struct spi_master spi_master_ch347_spi = {
|
|||||||
/* Largely copied from ch341a_spi.c */
|
/* Largely copied from ch341a_spi.c */
|
||||||
static int ch347_spi_init(const struct programmer_cfg *cfg)
|
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));
|
struct ch347_spi_data *ch347_data = calloc(1, sizeof(*ch347_data));
|
||||||
if (!ch347_data) {
|
if (!ch347_data) {
|
||||||
msg_perr("Could not allocate space for SPI data\n");
|
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);
|
free(ch347_data);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Enable information, warning, and error messages (only). */
|
/* Enable information, warning, and error messages (only). */
|
||||||
#if LIBUSB_API_VERSION < 0x01000106
|
#if LIBUSB_API_VERSION < 0x01000106
|
||||||
libusb_set_debug(NULL, 3);
|
libusb_set_debug(NULL, 3);
|
||||||
#else
|
#else
|
||||||
libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);
|
libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);
|
||||||
#endif
|
#endif
|
||||||
|
while (devs_ch347_spi[index].vendor_id != 0) {
|
||||||
uint16_t vid = devs_ch347_spi[0].vendor_id;
|
vid = devs_ch347_spi[index].vendor_id;
|
||||||
uint16_t pid = devs_ch347_spi[0].device_id;
|
pid = devs_ch347_spi[index].device_id;
|
||||||
ch347_data->handle = libusb_open_device_with_vid_pid(NULL, vid, pid);
|
ch347_data->handle = libusb_open_device_with_vid_pid(NULL, vid, pid);
|
||||||
if (ch347_data->handle == NULL) {
|
if (ch347_data->handle) {
|
||||||
msg_perr("Couldn't open device %04x:%04x.\n", vid, pid);
|
ch347_data->interface = ch347_interface[index];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
if (!ch347_data->handle) {
|
||||||
|
msg_perr("Couldn't find CH347.\n");
|
||||||
free(ch347_data);
|
free(ch347_data);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: set based on mode */
|
ret = libusb_detach_kernel_driver(ch347_data->handle, ch347_data->interface);
|
||||||
/* 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);
|
|
||||||
if (ret != 0 && ret != LIBUSB_ERROR_NOT_FOUND)
|
if (ret != 0 && ret != LIBUSB_ERROR_NOT_FOUND)
|
||||||
msg_pwarn("Cannot detach the existing USB driver. Claiming the interface may fail. %s\n",
|
msg_pwarn("Cannot detach the existing USB driver. Claiming the interface may fail. %s\n",
|
||||||
libusb_error_name(ret));
|
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) {
|
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;
|
goto error_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user