diff options
| -rw-r--r-- | board/cm_t35/cm_t35.c | 77 | ||||
| -rw-r--r-- | board/h2200/h2200.c | 11 | ||||
| -rw-r--r-- | common/usb.c | 12 | ||||
| -rw-r--r-- | common/usb_hub.c | 35 | ||||
| -rw-r--r-- | common/usb_storage.c | 10 | ||||
| -rw-r--r-- | doc/README.usb | 2 | ||||
| -rw-r--r-- | drivers/usb/gadget/g_dnl.c | 12 | ||||
| -rw-r--r-- | drivers/usb/gadget/pxa25x_udc.c | 1 | ||||
| -rw-r--r-- | include/configs/cm_t35.h | 8 | ||||
| -rw-r--r-- | include/configs/h2200.h | 25 | ||||
| -rw-r--r-- | include/twl4030.h | 44 | ||||
| -rw-r--r-- | include/usb.h | 1 | 
12 files changed, 229 insertions, 9 deletions
diff --git a/board/cm_t35/cm_t35.c b/board/cm_t35/cm_t35.c index 6c2e95b1d..edbb94198 100644 --- a/board/cm_t35/cm_t35.c +++ b/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 */ diff --git a/board/h2200/h2200.c b/board/h2200/h2200.c index 30763061c..720b06e4c 100644 --- a/board/h2200/h2200.c +++ b/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;  } diff --git a/common/usb.c b/common/usb.c index ac9b4ca8d..6fc0fc1c0 100644 --- a/common/usb.c +++ b/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 diff --git a/common/usb_hub.c b/common/usb_hub.c index e4a120120..b5eeb62fb 100644 --- a/common/usb_hub.c +++ b/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); -		if (usb_get_port_status(dev, i + 1, portsts) < 0) { -			USB_HUB_PRINTF("get_port_status failed\n"); +		/* +		 * 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 (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); diff --git a/common/usb_storage.c b/common/usb_storage.c index 2d92ee1bb..fb322b401 100644 --- a/common/usb_storage.c +++ b/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--); diff --git a/doc/README.usb b/doc/README.usb index ef1d6ba36..b4c3ef522 100644 --- a/doc/README.usb +++ b/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: diff --git a/drivers/usb/gadget/g_dnl.c b/drivers/usb/gadget/g_dnl.c index 7d87050df..a5a4c1fe6 100644 --- a/drivers/usb/gadget/g_dnl.c +++ b/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: diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index dd741439a..9ce98f076 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/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> diff --git a/include/configs/cm_t35.h b/include/configs/cm_t35.h index 568ae8e09..8db3a6194 100644 --- a/include/configs/cm_t35.h +++ b/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 diff --git a/include/configs/h2200.h b/include/configs/h2200.h index ef14dd38c..516a26e9f 100644 --- a/include/configs/h2200.h +++ b/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 */ diff --git a/include/twl4030.h b/include/twl4030.h index 0c17f5929..5aa184183 100644 --- a/include/twl4030.h +++ b/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   * diff --git a/include/usb.h b/include/usb.h index 8d8a2c9b9..d79c86588 100644 --- a/include/usb.h +++ b/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_ */  |