Index: u-boot/drivers/usbtty.c =================================================================== --- u-boot.orig/drivers/usbtty.c +++ u-boot/drivers/usbtty.c @@ -66,7 +66,7 @@ /* * Defines */ -#define NUM_CONFIGS 1 +#define NUM_CONFIGS 2 #define MAX_INTERFACES 2 #define NUM_ENDPOINTS 3 #define ACM_TX_ENDPOINT 3 @@ -192,8 +192,7 @@ #endif .bConfigurationValue = 1, .iConfiguration = STR_CONFIG, - .bmAttributes = - BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED, + .bmAttributes = BMATTRIBUTE_RESERVED, .bMaxPower = USBTTY_MAXPOWER }, /* Interface 1 */ @@ -294,6 +293,120 @@ .func_dfu = DFU_FUNC_DESC, #endif }, + { + .configuration_desc ={ + .bLength = + sizeof(struct usb_configuration_descriptor), + .bDescriptorType = USB_DT_CONFIG, + .wTotalLength = + cpu_to_le16(sizeof(struct acm_config_desc) +#ifdef CONFIG_USBD_DFU + - sizeof(struct usb_interface_descriptor) + - sizeof(struct usb_dfu_func_descriptor) +#endif + ), + .bNumInterfaces = NUM_ACM_INTERFACES, + .bConfigurationValue = 2, + .iConfiguration = STR_CONFIG, + .bmAttributes = BMATTRIBUTE_RESERVED, + .bMaxPower = 50, /* 100mA */ + }, + /* Interface 1 */ + .interface_desc = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 0x01, + .bInterfaceClass = + COMMUNICATIONS_INTERFACE_CLASS_CONTROL, + .bInterfaceSubClass = COMMUNICATIONS_ACM_SUBCLASS, + .bInterfaceProtocol = COMMUNICATIONS_V25TER_PROTOCOL, + .iInterface = STR_CTRL_INTERFACE, + }, + .usb_class_header = { + .bFunctionLength = + sizeof(struct usb_class_header_function_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_ST_HEADER, + .bcdCDC = cpu_to_le16(110), + }, + .usb_class_call_mgt = { + .bFunctionLength = + sizeof(struct usb_class_call_management_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_ST_CMF, + .bmCapabilities = 0x00, + .bDataInterface = 0x01, + }, + .usb_class_acm = { + .bFunctionLength = + sizeof(struct usb_class_abstract_control_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_ST_ACMF, + .bmCapabilities = 0x00, + }, + .usb_class_union = { + .bFunctionLength = + sizeof(struct usb_class_union_function_descriptor), + .bDescriptorType = CS_INTERFACE, + .bDescriptorSubtype = USB_ST_UF, + .bMasterInterface = 0x00, + .bSlaveInterface0 = 0x01, + }, + .notification_endpoint = { + .bLength = + sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x01 | USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_INT, + .wMaxPacketSize + = cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE), + .bInterval = 0xFF, + }, + + /* Interface 2 */ + .data_class_interface = { + .bLength = + sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0x01, + .bAlternateSetting = 0x00, + .bNumEndpoints = 0x02, + .bInterfaceClass = + COMMUNICATIONS_INTERFACE_CLASS_DATA, + .bInterfaceSubClass = DATA_INTERFACE_SUBCLASS_NONE, + .bInterfaceProtocol = DATA_INTERFACE_PROTOCOL_NONE, + .iInterface = STR_DATA_INTERFACE, + }, + .data_endpoints = { + { + .bLength = + sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x02 | USB_DIR_OUT, + .bmAttributes = + USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = + cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE), + .bInterval = 0xFF, + }, + { + .bLength = + sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x03 | USB_DIR_IN, + .bmAttributes = + USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = + cpu_to_le16(CONFIG_USBD_SERIAL_BULK_PKTSIZE), + .bInterval = 0xFF, + }, + }, + /* We don't add the DFU functional descriptor here since we only + * want to do DFU in the high-current charging mode for safety reasons */ + }, + }; static struct rs232_emu rs232_desc={ @@ -330,8 +443,7 @@ .bNumInterfaces = NUM_GSERIAL_INTERFACES, .bConfigurationValue = 1, .iConfiguration = STR_CONFIG, - .bmAttributes = - BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED, + .bmAttributes = BMATTRIBUTE_RESERVED, .bMaxPower = USBTTY_MAXPOWER }, .interface_desc = { @@ -384,6 +496,68 @@ }, }, }, + { + .configuration_desc ={ + .bLength = sizeof(struct usb_configuration_descriptor), + .bDescriptorType = USB_DT_CONFIG, + .wTotalLength = + cpu_to_le16(sizeof(struct gserial_config_desc)), + .bNumInterfaces = NUM_GSERIAL_INTERFACES, + .bConfigurationValue = 1, + .iConfiguration = STR_CONFIG, + .bmAttributes = BMATTRIBUTE_RESERVED, + .bMaxPower = 50 + }, + .interface_desc = { + { + .bLength = + sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DT_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = NUM_ENDPOINTS, + .bInterfaceClass = + COMMUNICATIONS_INTERFACE_CLASS_VENDOR, + .bInterfaceSubClass = + COMMUNICATIONS_NO_SUBCLASS, + .bInterfaceProtocol = + COMMUNICATIONS_NO_PROTOCOL, + .iInterface = STR_DATA_INTERFACE + }, + }, + .data_endpoints = { + { + .bLength = + sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x01 | USB_DIR_OUT, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = + cpu_to_le16(CONFIG_USBD_SERIAL_OUT_PKTSIZE), + .bInterval= 0xFF, + }, + { + .bLength = + sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x02 | USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_BULK, + .wMaxPacketSize = + cpu_to_le16(CONFIG_USBD_SERIAL_IN_PKTSIZE), + .bInterval = 0xFF, + }, + { + .bLength = + sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DT_ENDPOINT, + .bEndpointAddress = 0x03 | USB_DIR_IN, + .bmAttributes = USB_ENDPOINT_XFER_INT, + .wMaxPacketSize = + cpu_to_le16(CONFIG_USBD_SERIAL_INT_PKTSIZE), + .bInterval = 0xFF, + }, + }, + }, }; /* @@ -679,12 +853,14 @@ bus_instance->maxpacketsize = 64; bus_instance->serial_number_str = serial_number; - /* configuration instance */ - memset (config_instance, 0, - sizeof (struct usb_configuration_instance)); - config_instance->interfaces = interface_count; - config_instance->configuration_descriptor = configuration_descriptor; - config_instance->interface_instance_array = interface_instance; + /* configuration instances */ + for (i = 0; i < NUM_CONFIGS; i++) { + memset(&config_instance[i], 0, sizeof(config_instance)); + config_instance[i].interfaces = interface_count; + /* FIXME: this breaks for the non-ACM case */ + config_instance[i].configuration_descriptor = &acm_configuration_descriptors[i]; + config_instance[i].interface_instance_array = interface_instance; + } /* interface instance */ memset (interface_instance, 0, @@ -1043,9 +1219,17 @@ usbtty_configured_flag = 0; break; case DEVICE_CONFIGURED: + printf("DEVICE_CONFIGURED: %u\n", device->configuration); + if (device->configuration == 1) + udc_ctrl(UDC_CTRL_500mA_ENABLE, 1); + else + udc_ctrl(UDC_CTRL_500mA_ENABLE, 0); usbtty_configured_flag = 1; break; - + case DEVICE_DE_CONFIGURED: + printf("DEVICE_DE_CONFIGURED\n"); + udc_ctrl(UDC_CTRL_500mA_ENABLE, 0); + break; case DEVICE_ADDRESS_ASSIGNED: usbtty_init_endpoints (); Index: u-boot/drivers/usbtty.h =================================================================== --- u-boot.orig/drivers/usbtty.h +++ u-boot/drivers/usbtty.h @@ -60,7 +60,7 @@ #define USBTTY_DEVICE_CLASS COMMUNICATIONS_DEVICE_CLASS #define USBTTY_BCD_DEVICE 0x00 -#define USBTTY_MAXPOWER 0x00 +#define USBTTY_MAXPOWER 250 /* 500mA */ #define STR_LANG 0x00 #define STR_MANUFACTURER 0x01 Index: u-boot/board/neo1973/common/udc.c =================================================================== --- u-boot.orig/board/neo1973/common/udc.c +++ u-boot/board/neo1973/common/udc.c @@ -2,6 +2,7 @@ #include #include #include +#include void udc_ctrl(enum usbd_event event, int param) { @@ -17,6 +18,13 @@ gpio->GPBDAT &= ~(1 << 9); #endif break; + case UDC_CTRL_500mA_ENABLE: +#if defined(CONFIG_ARCH_GTA01_v3) || defined(CONFIG_ARCH_GTA01_v4) || \ + defined(CONFIG_ARCH_GTA01B_v2) || defined(CONFIG_ARCH_GTA01B_v3) || \ + defined(CONFIG_ARCH_GTA01B_v4) + pcf50606_charge_autofast(param); +#endif + break; default: break; } Index: u-boot/include/usbdcore.h =================================================================== --- u-boot.orig/include/usbdcore.h +++ u-boot/include/usbdcore.h @@ -686,8 +686,8 @@ enum usbd_event { UDC_CTRL_PULLUP_ENABLE, + UDC_CTRL_500mA_ENABLE, }; void udc_ctrl(enum usbd_event event, int param); #endif -#endif