1 /* 2 * arch/arm/plat-omap/usb.c -- platform level USB initialization 3 * 4 * Copyright (C) 2004 Texas Instruments, Inc. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 21#undef DEBUG 22 23#include <linux/module.h> 24#include <linux/kernel.h> 25#include <linux/init.h> 26#include <linux/platform_device.h> 27#include <linux/io.h> 28 29#include <plat/usb.h> 30#include <plat/board.h> 31 32#include <mach/hardware.h> 33 34#include "../mach-omap2/common.h" 35 36#ifdef CONFIG_ARCH_OMAP_OTG 37 38void __init 39omap_otg_init(struct omap_usb_config *config) 40{ 41 u32 syscon; 42 int status; 43 int alt_pingroup = 0; 44 45 /* NOTE: no bus or clock setup (yet?) */ 46 47 syscon = omap_readl(OTG_SYSCON_1) & 0xffff; 48 if (!(syscon & OTG_RESET_DONE)) 49 pr_debug("USB resets not complete?\n"); 50 51 //omap_writew(0, OTG_IRQ_EN); 52 53 /* pin muxing and transceiver pinouts */ 54 if (config->pins[0] > 2) /* alt pingroup 2 */ 55 alt_pingroup = 1; 56 syscon |= config->usb0_init(config->pins[0], is_usb0_device(config)); 57 syscon |= config->usb1_init(config->pins[1]); 58 syscon |= config->usb2_init(config->pins[2], alt_pingroup); 59 pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); 60 omap_writel(syscon, OTG_SYSCON_1); 61 62 syscon = config->hmc_mode; 63 syscon |= USBX_SYNCHRO | (4 << 16) /* B_ASE0_BRST */; 64#ifdef CONFIG_USB_OTG 65 if (config->otg) 66 syscon |= OTG_EN; 67#endif 68 if (cpu_class_is_omap1()) 69 pr_debug("USB_TRANSCEIVER_CTRL = %03x\n", 70 omap_readl(USB_TRANSCEIVER_CTRL)); 71 pr_debug("OTG_SYSCON_2 = %08x\n", omap_readl(OTG_SYSCON_2)); 72 omap_writel(syscon, OTG_SYSCON_2); 73 74 printk("USB: hmc %d", config->hmc_mode); 75 if (!alt_pingroup) 76 printk(", usb2 alt %d wires", config->pins[2]); 77 else if (config->pins[0]) 78 printk(", usb0 %d wires%s", config->pins[0], 79 is_usb0_device(config) ? " (dev)" : ""); 80 if (config->pins[1]) 81 printk(", usb1 %d wires", config->pins[1]); 82 if (!alt_pingroup && config->pins[2]) 83 printk(", usb2 %d wires", config->pins[2]); 84 if (config->otg) 85 printk(", Mini-AB on usb%d", config->otg - 1); 86 printk("\n"); 87 88 if (cpu_class_is_omap1()) { 89 u16 w; 90 91 /* leave USB clocks/controllers off until needed */ 92 w = omap_readw(ULPD_SOFT_REQ); 93 w &= ~SOFT_USB_CLK_REQ; 94 omap_writew(w, ULPD_SOFT_REQ); 95 96 w = omap_readw(ULPD_CLOCK_CTRL); 97 w &= ~USB_MCLK_EN; 98 w |= DIS_USB_PVCI_CLK; 99 omap_writew(w, ULPD_CLOCK_CTRL); 100 } 101 syscon = omap_readl(OTG_SYSCON_1); 102 syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN; 103 104#ifdef CONFIG_USB_GADGET_OMAP 105 if (config->otg || config->register_dev) { 106 struct platform_device *udc_device = config->udc_device; 107 108 syscon &= ~DEV_IDLE_EN; 109 udc_device->dev.platform_data = config; 110 status = platform_device_register(udc_device); 111 if (status) 112 pr_debug("can't register UDC device, %d\n", status); 113 } 114#endif 115 116#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) 117 if (config->otg || config->register_host) { 118 struct platform_device *ohci_device = config->ohci_device; 119 120 syscon &= ~HST_IDLE_EN; 121 ohci_device->dev.platform_data = config; 122 status = platform_device_register(ohci_device); 123 if (status) 124 pr_debug("can't register OHCI device, %d\n", status); 125 } 126#endif 127 128#ifdef CONFIG_USB_OTG 129 if (config->otg) { 130 struct platform_device *otg_device = config->otg_device; 131 132 syscon &= ~OTG_IDLE_EN; 133 otg_device->dev.platform_data = config; 134 status = platform_device_register(otg_device); 135 if (status) 136 pr_debug("can't register OTG device, %d\n", status); 137 } 138#endif 139 pr_debug("OTG_SYSCON_1 = %08x\n", omap_readl(OTG_SYSCON_1)); 140 omap_writel(syscon, OTG_SYSCON_1); 141 142 status = 0; 143} 144 145#else 146void omap_otg_init(struct omap_usb_config *config) {} 147#endif 148