瀏覽代碼

Merge branch 'master' of git://git.denx.de/u-boot-usb

Tom Rini 12 年之前
父節點
當前提交
ba6d4b64b3

+ 77 - 0
board/cm_t35/cm_t35.c

@@ -32,6 +32,7 @@
 #include <netdev.h>
 #include <net.h>
 #include <i2c.h>
+#include <usb.h>
 #include <twl4030.h>
 #include <linux/compiler.h>
 
@@ -41,6 +42,8 @@
 #include <asm/arch/mmc_host_def.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/mach-types.h>
+#include <asm/ehci-omap.h>
+#include <asm/gpio.h>
 
 #include "eeprom.h"
 
@@ -260,6 +263,36 @@ static void cm_t3x_set_common_muxconf(void)
 	MUX_VAL(CP(HSUSB0_DATA6),	(IEN  | PTD | DIS | M0)); /*HSUSB0_DATA6*/
 	MUX_VAL(CP(HSUSB0_DATA7),	(IEN  | PTD | DIS | M0)); /*HSUSB0_DATA7*/
 
+	/* USB EHCI */
+	MUX_VAL(CP(ETK_D0_ES2),		(IEN  | PTD | EN  | M3)); /*HSUSB1_DT0*/
+	MUX_VAL(CP(ETK_D1_ES2),		(IEN  | PTD | EN  | M3)); /*HSUSB1_DT1*/
+	MUX_VAL(CP(ETK_D2_ES2),		(IEN  | PTD | EN  | M3)); /*HSUSB1_DT2*/
+	MUX_VAL(CP(ETK_D7_ES2),		(IEN  | PTD | EN  | M3)); /*HSUSB1_DT3*/
+	MUX_VAL(CP(ETK_D4_ES2),		(IEN  | PTD | EN  | M3)); /*HSUSB1_DT4*/
+	MUX_VAL(CP(ETK_D5_ES2),		(IEN  | PTD | EN  | M3)); /*HSUSB1_DT5*/
+	MUX_VAL(CP(ETK_D6_ES2),		(IEN  | PTD | EN  | M3)); /*HSUSB1_DT6*/
+	MUX_VAL(CP(ETK_D3_ES2),		(IEN  | PTD | EN  | M3)); /*HSUSB1_DT7*/
+	MUX_VAL(CP(ETK_D8_ES2),		(IEN  | PTD | EN  | M3)); /*HSUSB1_DIR*/
+	MUX_VAL(CP(ETK_D9_ES2),		(IEN  | PTD | EN  | M3)); /*HSUSB1_NXT*/
+	MUX_VAL(CP(ETK_CTL_ES2),	(IDIS | PTD | DIS | M3)); /*HSUSB1_CLK*/
+	MUX_VAL(CP(ETK_CLK_ES2),	(IDIS | PTU | DIS | M3)); /*HSUSB1_STP*/
+
+	MUX_VAL(CP(ETK_D14_ES2),	(IEN  | PTD | EN  | M3)); /*HSUSB2_DT0*/
+	MUX_VAL(CP(ETK_D15_ES2),	(IEN  | PTD | EN  | M3)); /*HSUSB2_DT1*/
+	MUX_VAL(CP(MCSPI1_CS3),		(IEN  | PTD | EN  | M3)); /*HSUSB2_DT2*/
+	MUX_VAL(CP(MCSPI2_CS1),		(IEN  | PTD | EN  | M3)); /*HSUSB2_DT3*/
+	MUX_VAL(CP(MCSPI2_SIMO),	(IEN  | PTD | EN  | M3)); /*HSUSB2_DT4*/
+	MUX_VAL(CP(MCSPI2_SOMI),	(IEN  | PTD | EN  | M3)); /*HSUSB2_DT5*/
+	MUX_VAL(CP(MCSPI2_CS0),		(IEN  | PTD | EN  | M3)); /*HSUSB2_DT6*/
+	MUX_VAL(CP(MCSPI2_CLK),		(IEN  | PTD | EN  | M3)); /*HSUSB2_DT7*/
+	MUX_VAL(CP(ETK_D12_ES2),	(IEN  | PTD | EN  | M3)); /*HSUSB2_DIR*/
+	MUX_VAL(CP(ETK_D13_ES2),	(IEN  | PTD | EN  | M3)); /*HSUSB2_NXT*/
+	MUX_VAL(CP(ETK_D10_ES2),	(IDIS | PTD | DIS | M3)); /*HSUSB2_CLK*/
+	MUX_VAL(CP(ETK_D11_ES2),	(IDIS | PTU | DIS | M3)); /*HSUSB2_STP*/
+
+	/* SB_T35_USB_HUB_RESET_GPIO */
+	MUX_VAL(CP(CAM_WEN),		(IDIS | PTD | DIS | M4)); /*GPIO_167*/
+
 	/* I2C1 */
 	MUX_VAL(CP(I2C1_SCL),		(IEN  | PTU | EN  | M0)); /*I2C1_SCL*/
 	MUX_VAL(CP(I2C1_SDA),		(IEN  | PTU | EN  | M0)); /*I2C1_SDA*/
@@ -461,3 +494,47 @@ void __weak get_board_serial(struct tag_serialnr *serialnr)
 	serialnr->low = 0;
 	serialnr->high = 0;
 };
+
+#ifdef CONFIG_USB_EHCI_OMAP
+struct omap_usbhs_board_data usbhs_bdata = {
+	.port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
+	.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
+	.port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
+};
+
+#define SB_T35_USB_HUB_RESET_GPIO	167
+int ehci_hcd_init(int index, struct ehci_hccr **hccr, struct ehci_hcor **hcor)
+{
+	u8 val;
+	int offset;
+
+	if (gpio_request(SB_T35_USB_HUB_RESET_GPIO, "SB-T35 usb hub reset")) {
+		printf("Error: can't obtain GPIO %d for SB-T35 usb hub reset",
+				SB_T35_USB_HUB_RESET_GPIO);
+		return -1;
+	}
+
+	gpio_direction_output(SB_T35_USB_HUB_RESET_GPIO, 0);
+	udelay(10);
+	gpio_set_value(SB_T35_USB_HUB_RESET_GPIO, 1);
+	udelay(1000);
+
+	offset = TWL4030_BASEADD_GPIO + TWL4030_GPIO_GPIODATADIR1;
+	twl4030_i2c_read_u8(TWL4030_CHIP_GPIO, &val, offset);
+	/* Set GPIO6 and GPIO7 of TPS65930 as output */
+	val |= 0xC0;
+	twl4030_i2c_write_u8(TWL4030_CHIP_GPIO, val, offset);
+	offset = TWL4030_BASEADD_GPIO + TWL4030_GPIO_SETGPIODATAOUT1;
+	/* Take both PHYs out of reset */
+	twl4030_i2c_write_u8(TWL4030_CHIP_GPIO, 0xC0, offset);
+	udelay(1);
+
+	return omap_ehci_hcd_init(&usbhs_bdata, hccr, hcor);
+}
+
+int ehci_hcd_stop(void)
+{
+	return omap_ehci_hcd_stop();
+}
+
+#endif /* CONFIG_USB_EHCI_OMAP */

+ 11 - 0
board/h2200/h2200.c

@@ -22,9 +22,16 @@
 #include <asm/arch/pxa.h>
 #include <asm/arch/pxa-regs.h>
 #include <asm/io.h>
+#include <usb.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+int board_eth_init(bd_t *bis)
+{
+	usb_eth_initialize(bis);
+	return 0;
+}
+
 int board_init(void)
 {
 	/* We have RAM, disable cache */
@@ -36,6 +43,10 @@ int board_init(void)
 	/* adress of boot parameters */
 	gd->bd->bi_boot_params = 0xa0000100;
 
+	/* Let host see that device is disconnected */
+	udc_disconnect();
+	mdelay(500);
+
 	return 0;
 }
 

+ 12 - 0
common/usb.c

@@ -805,6 +805,18 @@ struct usb_device *usb_alloc_new_device(void *controller)
 	return &usb_dev[dev_index - 1];
 }
 
+/*
+ * Free the newly created device node.
+ * Called in error cases where configuring a newly attached
+ * device fails for some reason.
+ */
+void usb_free_device(void)
+{
+	dev_index--;
+	USB_PRINTF("Freeing device node: %d\n", dev_index);
+	memset(&usb_dev[dev_index], 0, sizeof(struct usb_device));
+	usb_dev[dev_index].devnum = -1;
+}
 
 /*
  * By the time we get here, the device has gotten a new device ID

+ 30 - 5
common/usb_hub.c

@@ -259,6 +259,8 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
 	/* Run it through the hoops (find a driver, etc) */
 	if (usb_new_device(usb)) {
 		/* Woops, disable the port */
+		usb_free_device();
+		dev->children[port] = NULL;
 		USB_HUB_PRINTF("hub: disabling port %d\n", port + 1);
 		usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE);
 	}
@@ -396,14 +398,37 @@ static int usb_hub_configure(struct usb_device *dev)
 	for (i = 0; i < dev->maxchild; i++) {
 		ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
 		unsigned short portstatus, portchange;
+		int ret;
+		ulong start = get_timer(0);
+
+		/*
+		 * Wait for (whichever finishes first)
+		 *  - A maximum of 10 seconds
+		 *    This is a purely observational value driven by connecting
+		 *    a few broken pen drives and taking the max * 1.5 approach
+		 *  - connection_change and connection state to report same
+		 *    state
+		 */
+		do {
+			ret = usb_get_port_status(dev, i + 1, portsts);
+			if (ret < 0) {
+				USB_HUB_PRINTF("get_port_status failed\n");
+				break;
+			}
+
+			portstatus = le16_to_cpu(portsts->wPortStatus);
+			portchange = le16_to_cpu(portsts->wPortChange);
+
+			if ((portchange & USB_PORT_STAT_C_CONNECTION) ==
+				(portstatus & USB_PORT_STAT_CONNECTION))
+				break;
+
+			mdelay(100);
+		} while (get_timer(start) < CONFIG_SYS_HZ * 10);
 
-		if (usb_get_port_status(dev, i + 1, portsts) < 0) {
-			USB_HUB_PRINTF("get_port_status failed\n");
+		if (ret < 0)
 			continue;
-		}
 
-		portstatus = le16_to_cpu(portsts->wPortStatus);
-		portchange = le16_to_cpu(portsts->wPortChange);
 		USB_HUB_PRINTF("Port %d Status %X Change %X\n",
 				i + 1, portstatus, portchange);
 

+ 10 - 0
common/usb_storage.c

@@ -970,6 +970,16 @@ static int usb_test_unit_ready(ccb *srb, struct us_data *ss)
 			return 0;
 		}
 		usb_request_sense(srb, ss);
+		/*
+		 * Check the Key Code Qualifier, if it matches
+		 * "Not Ready - medium not present"
+		 * (the sense Key equals 0x2 and the ASC is 0x3a)
+		 * return immediately as the medium being absent won't change
+		 * unless there is a user action.
+		 */
+		if ((srb->sense_buf[2] == 0x02) &&
+		    (srb->sense_buf[12] == 0x3a))
+			return -1;
 		mdelay(100);
 	} while (retries--);
 

+ 1 - 1
doc/README.usb

@@ -63,7 +63,7 @@ Common USB Commands:
 Storage USB Commands:
 - usb scan:	    scans the USB for storage devices.The USB must be
 		    running for this command (usb start)
-- usb device [dev]: show or set current USB staorage device
+- usb device [dev]: show or set current USB storage device
 - usb part [dev]:   print partition table of one or all USB storage
 		    devices
 - usb read addr blk# cnt:

+ 11 - 1
drivers/usb/gadget/g_dnl.c

@@ -69,6 +69,7 @@ static struct usb_device_descriptor device_desc = {
 static struct usb_string g_dnl_string_defs[] = {
 	{ 0, manufacturer, },
 	{ 1, product, },
+	{  }		/* end of list */
 };
 
 static struct usb_gadget_strings g_dnl_string_tab = {
@@ -83,7 +84,12 @@ static struct usb_gadget_strings *g_dnl_composite_strings[] = {
 
 static int g_dnl_unbind(struct usb_composite_dev *cdev)
 {
-	debug("%s\n", __func__);
+	struct usb_gadget *gadget = cdev->gadget;
+
+	debug("%s: calling usb_gadget_disconnect for "
+			"controller '%s'\n", shortname, gadget->name);
+	usb_gadget_disconnect(gadget);
+
 	return 0;
 }
 
@@ -153,6 +159,10 @@ static int g_dnl_bind(struct usb_composite_dev *cdev)
 		device_desc.bcdDevice = __constant_cpu_to_le16(0x9999);
 	}
 
+	debug("%s: calling usb_gadget_connect for "
+			"controller '%s'\n", shortname, gadget->name);
+	usb_gadget_connect(gadget);
+
 	return 0;
 
  error:

+ 0 - 1
drivers/usb/gadget/pxa25x_udc.c

@@ -40,7 +40,6 @@
 #include <asm/io.h>
 #include <asm/arch/pxa.h>
 
-#include <usbdescriptors.h>
 #include <linux/usb/ch9.h>
 #include <linux/usb/gadget.h>
 #include <usb/lin_gadget_compat.h>

+ 7 - 1
include/configs/cm_t35.h

@@ -114,9 +114,15 @@
 #define CONFIG_DOS_PARTITION
 
 /* USB */
-#define CONFIG_MUSB_UDC
 #define CONFIG_USB_OMAP3
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_OMAP
+#define CONFIG_USB_ULPI
+#define CONFIG_USB_ULPI_VIEWPORT_OMAP
+#define CONFIG_USB_STORAGE
+#define CONFIG_MUSB_UDC
 #define CONFIG_TWL4030_USB
+#define CONFIG_CMD_USB
 
 /* USB device configuration */
 #define CONFIG_USB_DEVICE

+ 25 - 0
include/configs/h2200.h

@@ -154,4 +154,29 @@
 
 #define CONFIG_BOOTARGS "root=/dev/ram0 ro console=ttyS0,115200n8"
 
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV
+#define CONFIG_USB_DEV_PULLUP_GPIO	33
+/* USB VBUS GPIO 3 */
+
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_PING
+
+#define CONFIG_BOOTDELAY		2
+#define CONFIG_BOOTCOMMAND		\
+	"setenv downloaded 0 ; while test $downloaded -eq 0 ; do " \
+	"if bootp ; then setenv downloaded 1 ; fi ; done ; " \
+	"source :script ; " \
+	"bootm ; "
+
+#define CONFIG_USB_GADGET_PXA2XX
+#define CONFIG_USB_ETHER
+#define CONFIG_USB_ETH_SUBSET
+
+#define CONFIG_USBNET_DEV_ADDR		"de:ad:be:ef:00:01"
+#define CONFIG_USBNET_HOST_ADDR	"de:ad:be:ef:00:02"
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"stdin=serial\0" \
+	"stdout=serial\0" \
+	"stderr=serial\0"
+
 #endif /* __CONFIG_H */

+ 44 - 0
include/twl4030.h

@@ -580,6 +580,50 @@
 #define TWL4030_USB_PHY_CLK_CTRL			0xFE
 #define TWL4030_USB_PHY_CLK_CTRL_STS			0xFF
 
+/* GPIO */
+#define TWL4030_GPIO_GPIODATAIN1			0x00
+#define TWL4030_GPIO_GPIODATAIN2			0x01
+#define TWL4030_GPIO_GPIODATAIN3			0x02
+#define TWL4030_GPIO_GPIODATADIR1			0x03
+#define TWL4030_GPIO_GPIODATADIR2			0x04
+#define TWL4030_GPIO_GPIODATADIR3			0x05
+#define TWL4030_GPIO_GPIODATAOUT1			0x06
+#define TWL4030_GPIO_GPIODATAOUT2			0x07
+#define TWL4030_GPIO_GPIODATAOUT3			0x08
+#define TWL4030_GPIO_CLEARGPIODATAOUT1			0x09
+#define TWL4030_GPIO_CLEARGPIODATAOUT2			0x0A
+#define TWL4030_GPIO_CLEARGPIODATAOUT3			0x0B
+#define TWL4030_GPIO_SETGPIODATAOUT1			0x0C
+#define TWL4030_GPIO_SETGPIODATAOUT2			0x0D
+#define TWL4030_GPIO_SETGPIODATAOUT3			0x0E
+#define TWL4030_GPIO_GPIO_DEBEN1			0x0F
+#define TWL4030_GPIO_GPIO_DEBEN2			0x10
+#define TWL4030_GPIO_GPIO_DEBEN3			0x11
+#define TWL4030_GPIO_GPIO_CTRL				0x12
+#define TWL4030_GPIO_GPIOPUPDCTR1			0x13
+#define TWL4030_GPIO_GPIOPUPDCTR2			0x14
+#define TWL4030_GPIO_GPIOPUPDCTR3			0x15
+#define TWL4030_GPIO_GPIOPUPDCTR4			0x16
+#define TWL4030_GPIO_GPIOPUPDCTR5			0x17
+#define TWL4030_GPIO_GPIO_ISR1A				0x19
+#define TWL4030_GPIO_GPIO_ISR2A				0x1A
+#define TWL4030_GPIO_GPIO_ISR3A				0x1B
+#define TWL4030_GPIO_GPIO_IMR1A				0x1C
+#define TWL4030_GPIO_GPIO_IMR2A				0x1D
+#define TWL4030_GPIO_GPIO_IMR3A				0x1E
+#define TWL4030_GPIO_GPIO_ISR1B				0x1F
+#define TWL4030_GPIO_GPIO_ISR2B				0x20
+#define TWL4030_GPIO_GPIO_ISR3B				0x21
+#define TWL4030_GPIO_GPIO_IMR1B				0x22
+#define TWL4030_GPIO_GPIO_IMR2B				0x23
+#define TWL4030_GPIO_GPIO_IMR3B				0x24
+#define TWL4030_GPIO_GPIO_EDR1				0x28
+#define TWL4030_GPIO_GPIO_EDR2				0x29
+#define TWL4030_GPIO_GPIO_EDR3				0x2A
+#define TWL4030_GPIO_GPIO_EDR4				0x2B
+#define TWL4030_GPIO_GPIO_EDR5				0x2C
+#define TWL4030_GPIO_GPIO_SIH_CTRL			0x2D
+
 /*
  * Convience functions to read and write from TWL4030
  *

+ 1 - 0
include/usb.h

@@ -392,5 +392,6 @@ int hub_port_reset(struct usb_device *dev, int port,
 struct usb_device *usb_alloc_new_device(void *controller);
 
 int usb_new_device(struct usb_device *dev);
+void usb_free_device(void);
 
 #endif /*_USB_H_ */