diff options
Diffstat (limited to 'arch/arm/mach-omap1/usb.c')
| -rw-r--r-- | arch/arm/mach-omap1/usb.c | 116 | 
1 files changed, 115 insertions, 1 deletions
diff --git a/arch/arm/mach-omap1/usb.c b/arch/arm/mach-omap1/usb.c index e61afd92276..65f88176fba 100644 --- a/arch/arm/mach-omap1/usb.c +++ b/arch/arm/mach-omap1/usb.c @@ -27,7 +27,8 @@  #include <asm/irq.h>  #include <plat/mux.h> -#include <plat/usb.h> + +#include <mach/usb.h>  #include "common.h" @@ -55,6 +56,119 @@  #define INT_USB_IRQ_HGEN	INT_USB_HHC_1  #define INT_USB_IRQ_OTG		IH2_BASE + 8 +#ifdef	CONFIG_ARCH_OMAP_OTG + +void __init +omap_otg_init(struct omap_usb_config *config) +{ +	u32		syscon; +	int		alt_pingroup = 0; + +	/* NOTE:  no bus or clock setup (yet?) */ + +	syscon = omap_readl(OTG_SYSCON_1) & 0xffff; +	if (!(syscon & OTG_RESET_DONE)) +		pr_debug("USB resets not complete?\n"); + +	//omap_writew(0, OTG_IRQ_EN); + +	/* pin muxing and transceiver pinouts */ +	if (config->pins[0] > 2)	/* alt pingroup 2 */ +		alt_pingroup = 1; +	syscon |= config->usb0_init(config->pins[0], is_usb0_device(config)); +	syscon |= config->usb1_init(config->pins[1]); +	syscon |= config->usb2_init(config->pins[2], alt_pingroup); +	pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); +	omap_writel(syscon, OTG_SYSCON_1); + +	syscon = config->hmc_mode; +	syscon |= USBX_SYNCHRO | (4 << 16) /* B_ASE0_BRST */; +#ifdef	CONFIG_USB_OTG +	if (config->otg) +		syscon |= OTG_EN; +#endif +	if (cpu_class_is_omap1()) +		pr_debug("USB_TRANSCEIVER_CTRL = %03x\n", +			 omap_readl(USB_TRANSCEIVER_CTRL)); +	pr_debug("OTG_SYSCON_2 = %08x\n", omap_readl(OTG_SYSCON_2)); +	omap_writel(syscon, OTG_SYSCON_2); + +	printk("USB: hmc %d", config->hmc_mode); +	if (!alt_pingroup) +		printk(", usb2 alt %d wires", config->pins[2]); +	else if (config->pins[0]) +		printk(", usb0 %d wires%s", config->pins[0], +			is_usb0_device(config) ? " (dev)" : ""); +	if (config->pins[1]) +		printk(", usb1 %d wires", config->pins[1]); +	if (!alt_pingroup && config->pins[2]) +		printk(", usb2 %d wires", config->pins[2]); +	if (config->otg) +		printk(", Mini-AB on usb%d", config->otg - 1); +	printk("\n"); + +	if (cpu_class_is_omap1()) { +		u16 w; + +		/* leave USB clocks/controllers off until needed */ +		w = omap_readw(ULPD_SOFT_REQ); +		w &= ~SOFT_USB_CLK_REQ; +		omap_writew(w, ULPD_SOFT_REQ); + +		w = omap_readw(ULPD_CLOCK_CTRL); +		w &= ~USB_MCLK_EN; +		w |= DIS_USB_PVCI_CLK; +		omap_writew(w, ULPD_CLOCK_CTRL); +	} +	syscon = omap_readl(OTG_SYSCON_1); +	syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN; + +#ifdef	CONFIG_USB_GADGET_OMAP +	if (config->otg || config->register_dev) { +		struct platform_device *udc_device = config->udc_device; +		int status; + +		syscon &= ~DEV_IDLE_EN; +		udc_device->dev.platform_data = config; +		status = platform_device_register(udc_device); +		if (status) +			pr_debug("can't register UDC device, %d\n", status); +	} +#endif + +#if	defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) +	if (config->otg || config->register_host) { +		struct platform_device *ohci_device = config->ohci_device; +		int status; + +		syscon &= ~HST_IDLE_EN; +		ohci_device->dev.platform_data = config; +		status = platform_device_register(ohci_device); +		if (status) +			pr_debug("can't register OHCI device, %d\n", status); +	} +#endif + +#ifdef	CONFIG_USB_OTG +	if (config->otg) { +		struct platform_device *otg_device = config->otg_device; +		int status; + +		syscon &= ~OTG_IDLE_EN; +		otg_device->dev.platform_data = config; +		status = platform_device_register(otg_device); +		if (status) +			pr_debug("can't register OTG device, %d\n", status); +	} +#endif +	pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); +	omap_writel(syscon, OTG_SYSCON_1); +} + +#else +void omap_otg_init(struct omap_usb_config *config) {} +#endif +  #ifdef	CONFIG_USB_GADGET_OMAP  static struct resource udc_resources[] = {  |