![Tony Lindgren](/assets/img/avatar_default.png)
This is needed to minimize io.h so the SoC specific io.h for ARMs can removed. Note that minimal driver changes for DSS and RNG are needed to include cpu.h for SoC detection macros. Cc: Tomi Valkeinen <tomi.valkeinen@ti.com> Cc: Matt Mackall <mpm@selenic.com> Cc: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Tony Lindgren <tony@atomide.com>
148 lines
4.1 KiB
C
148 lines
4.1 KiB
C
/*
|
|
* arch/arm/plat-omap/usb.c -- platform level USB initialization
|
|
*
|
|
* Copyright (C) 2004 Texas Instruments, Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#undef DEBUG
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/init.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/io.h>
|
|
|
|
#include <plat/usb.h>
|
|
#include <plat/board.h>
|
|
|
|
#include <mach/hardware.h>
|
|
|
|
#include "../mach-omap2/common.h"
|
|
|
|
#ifdef CONFIG_ARCH_OMAP_OTG
|
|
|
|
void __init
|
|
omap_otg_init(struct omap_usb_config *config)
|
|
{
|
|
u32 syscon;
|
|
int status;
|
|
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;
|
|
|
|
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;
|
|
|
|
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;
|
|
|
|
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);
|
|
|
|
status = 0;
|
|
}
|
|
|
|
#else
|
|
void omap_otg_init(struct omap_usb_config *config) {}
|
|
#endif
|