drivers/usb/gadget.c: Add support for EHCI debug using the WCH CH347
The WCH CH347 presents a USB CDC serial port on interface 4 while in operating modes 0, 1, and 3. Mode 0 also presents a UART on interface 2 but this is ignored for compatibility with the other modes. Mode 2 uses vendor defined HID usages for communication and is not currently supported. Like the FT232H the data format is hard coded to 8n1. Tested using a CH347 breakout board and a Dell Latitude E6400. Change-Id: Ibd4ad17b7369948003fff7e825b46fe852bc7eb9 Signed-off-by: Nicholas Chin <nic.c3.14@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/68264 Reviewed-by: Angel Pons <th3fanbus@gmail.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
This commit is contained in:
parent
458751c2d5
commit
81827aad3c
|
@ -92,6 +92,14 @@ config USBDEBUG_DONGLE_FTDI_FT232H
|
||||||
Use this with FT232H usb-to-uart. Configuration is hard-coded
|
Use this with FT232H usb-to-uart. Configuration is hard-coded
|
||||||
to use 8n1, no flow control.
|
to use 8n1, no flow control.
|
||||||
|
|
||||||
|
config USBDEBUG_DONGLE_WCH_CH347
|
||||||
|
bool "WCH CH347 UART"
|
||||||
|
help
|
||||||
|
Use this with CH347 usb-to-uart. Configuration is hard-coded
|
||||||
|
to use 8n1, no flow control. For compatibility across modes
|
||||||
|
0, 1, and 3, only UART 1 is supported. The UART in mode 2 is
|
||||||
|
not currently supported.
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
config USBDEBUG_DONGLE_FTDI_FT232H_BAUD
|
config USBDEBUG_DONGLE_FTDI_FT232H_BAUD
|
||||||
|
@ -104,6 +112,16 @@ config USBDEBUG_DONGLE_FTDI_FT232H_BAUD
|
||||||
connection works with it. Multiples of 115,200 seem to be a good
|
connection works with it. Multiples of 115,200 seem to be a good
|
||||||
choice, and EHCI debug usually can't saturate more than 576,000.
|
choice, and EHCI debug usually can't saturate more than 576,000.
|
||||||
|
|
||||||
|
config USBDEBUG_DONGLE_WCH_CH347_BAUD
|
||||||
|
int "WCH CH347 baud rate"
|
||||||
|
default 115200
|
||||||
|
depends on USBDEBUG_DONGLE_WCH_CH347
|
||||||
|
help
|
||||||
|
Select baud rate for CH347 in the range 1200..9,000,000. Make
|
||||||
|
sure that your receiving side supports the same setting and your
|
||||||
|
connection works with it. Multiples of 115,200 seem to be a good
|
||||||
|
choice, and EHCI debug usually can't saturate more than 576,000.
|
||||||
|
|
||||||
config USBDEBUG_OPTIONAL_HUB_PORT
|
config USBDEBUG_OPTIONAL_HUB_PORT
|
||||||
int
|
int
|
||||||
default 2 if USBDEBUG_DONGLE_BEAGLEBONE
|
default 2 if USBDEBUG_DONGLE_BEAGLEBONE
|
||||||
|
|
|
@ -205,6 +205,73 @@ small_write:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Refer to USB CDC PSTN Subclass specification section 6.3 */
|
||||||
|
#define CDC_SET_LINE_CODING_REQUEST 0x20
|
||||||
|
struct cdc_line_coding {
|
||||||
|
u32 baudrate;
|
||||||
|
u8 stop_bits;
|
||||||
|
u8 parity;
|
||||||
|
u8 data_bits;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
static int probe_for_ch347(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u8 devnum = 0;
|
||||||
|
u8 uart_if = 2; /* CH347 UART 1 */
|
||||||
|
|
||||||
|
/* Move the device to 127 if it isn't already there */
|
||||||
|
ret = dbgp_control_msg(ehci_debug, devnum,
|
||||||
|
USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
|
||||||
|
USB_REQ_SET_ADDRESS, USB_DEBUG_DEVNUM, 0, NULL, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
printk(BIOS_INFO, "Could not move attached device to %d.\n",
|
||||||
|
USB_DEBUG_DEVNUM);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
devnum = USB_DEBUG_DEVNUM;
|
||||||
|
printk(BIOS_INFO, "EHCI debug device renamed to %d.\n", devnum);
|
||||||
|
|
||||||
|
/* Send Set Configure request to device. */
|
||||||
|
ret = dbgp_control_msg(ehci_debug, devnum,
|
||||||
|
USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE,
|
||||||
|
USB_REQ_SET_CONFIGURATION, 1, 0, NULL, 0);
|
||||||
|
if (ret < 0) {
|
||||||
|
printk(BIOS_INFO, "CH347 set configuration failed.\n");
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct cdc_line_coding line_coding = {
|
||||||
|
.baudrate = CONFIG_USBDEBUG_DONGLE_WCH_CH347_BAUD,
|
||||||
|
.stop_bits = 0, /* 1 stop bit */
|
||||||
|
.parity = 0, /* No parity */
|
||||||
|
.data_bits = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
ret = dbgp_control_msg(ehci_debug, devnum,
|
||||||
|
USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
|
||||||
|
CDC_SET_LINE_CODING_REQUEST, 0, uart_if, &line_coding, sizeof(line_coding));
|
||||||
|
if (ret < 0) {
|
||||||
|
printk(BIOS_INFO, "CDC SET_LINE_CODING failed.\n");
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Modes 0, 1, and 3 all have UART 1 on endpoint 4 in common */
|
||||||
|
pipe[DBGP_CONSOLE_EPOUT].endpoint = 0x04;
|
||||||
|
pipe[DBGP_CONSOLE_EPIN].endpoint = 0x84;
|
||||||
|
|
||||||
|
ack_set_configuration(pipe, devnum, 1000);
|
||||||
|
|
||||||
|
/* Perform a small write. */
|
||||||
|
ret = dbgp_bulk_write_x(&pipe[DBGP_CONSOLE_EPOUT], "USB\r\n", 5);
|
||||||
|
if (ret < 0) {
|
||||||
|
printk(BIOS_INFO, "dbgp_bulk_write failed: %d\n", ret);
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
printk(BIOS_INFO, "Test write done\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* FTDI FT232H UART programming. */
|
/* FTDI FT232H UART programming. */
|
||||||
#define FTDI_SIO_SET_FLOW_CTRL_REQUEST 0x02
|
#define FTDI_SIO_SET_FLOW_CTRL_REQUEST 0x02
|
||||||
#define FTDI_SIO_SET_BAUDRATE_REQUEST 0x03
|
#define FTDI_SIO_SET_BAUDRATE_REQUEST 0x03
|
||||||
|
@ -329,6 +396,8 @@ int dbgp_probe_gadget(struct ehci_dbg_port *ehci_debug, struct dbgp_pipe *pipe)
|
||||||
|
|
||||||
if (CONFIG(USBDEBUG_DONGLE_FTDI_FT232H)) {
|
if (CONFIG(USBDEBUG_DONGLE_FTDI_FT232H)) {
|
||||||
ret = probe_for_ftdi(ehci_debug, pipe);
|
ret = probe_for_ftdi(ehci_debug, pipe);
|
||||||
|
} else if (CONFIG(USBDEBUG_DONGLE_WCH_CH347)) {
|
||||||
|
ret = probe_for_ch347(ehci_debug, pipe);
|
||||||
} else {
|
} else {
|
||||||
ret = probe_for_debug_descriptor(ehci_debug, pipe);
|
ret = probe_for_debug_descriptor(ehci_debug, pipe);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue