Index: u-boot/drivers/usbtty.c
===================================================================
--- u-boot.orig/drivers/usbtty.c
+++ u-boot/drivers/usbtty.c
@@ -54,7 +54,7 @@
 /*
  * Defines
  */
-#define NUM_CONFIGS    1
+#define NUM_CONFIGS    2
 #define MAX_INTERFACES 2
 #define NUM_ENDPOINTS  3
 #define ACM_TX_ENDPOINT 3
@@ -180,8 +180,7 @@
 #endif
     			.bConfigurationValue = 1,
 			.iConfiguration = STR_CONFIG,
-			.bmAttributes =
-				BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
+			.bmAttributes = BMATTRIBUTE_RESERVED,
 			.bMaxPower = USBTTY_MAXPOWER
 		},
 		/* Interface 1 */
@@ -282,6 +281,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={
@@ -318,8 +431,7 @@
 			.bNumInterfaces = NUM_GSERIAL_INTERFACES,
 			.bConfigurationValue = 1,
 			.iConfiguration = STR_CONFIG,
-			.bmAttributes =
-				BMATTRIBUTE_SELF_POWERED|BMATTRIBUTE_RESERVED,
+			.bmAttributes = BMATTRIBUTE_RESERVED,
 			.bMaxPower = USBTTY_MAXPOWER
 		},
 		.interface_desc = {
@@ -372,6 +484,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,
+			},
+		},
+	},
 };
 
 /*
@@ -675,12 +849,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,
@@ -963,9 +1139,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
@@ -59,7 +59,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 <common.h>
 #include <usbdcore.h>
 #include <s3c2410.h>
+#include <pcf50606.h>
 
 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
