/* * TI DA830/OMAP L137 EVM board * * Author: Mark A. Greer * Derived from: arch/arm/mach-davinci/board-dm644x-evm.c * * 2007, 2009 (c) MontaVista Software, Inc. This file is licensed under * the terms of the GNU General Public License version 2. This program * is licensed "as is" without any warranty of any kind, whether express * or implied. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define DA830_EVM_PHY_ID "" /* * USB1 VBUS is controlled by GPIO1[15], over-current is reported on GPIO2[4]. */ #define ON_BD_USB_DRV GPIO_TO_PIN(1, 15) #define ON_BD_USB_OVC GPIO_TO_PIN(2, 4) static const short da830_evm_usb11_pins[] = { DA830_GPIO1_15, DA830_GPIO2_4, -1 }; static da8xx_ocic_handler_t da830_evm_usb_ocic_handler; static int da830_evm_usb_set_power(unsigned port, int on) { gpio_set_value(ON_BD_USB_DRV, on); return 0; } static int da830_evm_usb_get_power(unsigned port) { return gpio_get_value(ON_BD_USB_DRV); } static int da830_evm_usb_get_oci(unsigned port) { return !gpio_get_value(ON_BD_USB_OVC); } static irqreturn_t da830_evm_usb_ocic_irq(int, void *); static int da830_evm_usb_ocic_notify(da8xx_ocic_handler_t handler) { int irq = gpio_to_irq(ON_BD_USB_OVC); int error = 0; if (handler != NULL) { da830_evm_usb_ocic_handler = handler; error = request_irq(irq, da830_evm_usb_ocic_irq, IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "OHCI over-current indicator", NULL); if (error) printk(KERN_ERR "%s: could not request IRQ to watch " "over-current indicator changes\n", __func__); } else free_irq(irq, NULL); return error; } static struct da8xx_ohci_root_hub da830_evm_usb11_pdata = { .set_power = da830_evm_usb_set_power, .get_power = da830_evm_usb_get_power, .get_oci = da830_evm_usb_get_oci, .ocic_notify = da830_evm_usb_ocic_notify, /* TPS2065 switch @ 5V */ .potpgt = (3 + 1) / 2, /* 3 ms max */ }; static irqreturn_t da830_evm_usb_ocic_irq(int irq, void *dev_id) { da830_evm_usb_ocic_handler(&da830_evm_usb11_pdata, 1); return IRQ_HANDLED; } static __init void da830_evm_usb_init(void) { u32 cfgchip2; int ret; /* * Set up USB clock/mode in the CFGCHIP2 register. * FYI: CFGCHIP2 is 0x0000ef00 initially. */ cfgchip2 = __raw_readl(DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); /* USB2.0 PHY reference clock is 24 MHz */ cfgchip2 &= ~CFGCHIP2_REFFREQ; cfgchip2 |= CFGCHIP2_REFFREQ_24MHZ; /* * Select internal reference clock for USB 2.0 PHY * and use it as a clock source for USB 1.1 PHY * (this is the default setting anyway). */ cfgchip2 &= ~CFGCHIP2_USB1PHYCLKMUX; cfgchip2 |= CFGCHIP2_USB2PHYCLKMUX; /* * We have to override VBUS/ID signals when MUSB is configured into the * host-only mode -- ID pin will float if no cable is connected, so the * controller won't be able to drive VBUS thinking that it's a B-device. * Otherwise, we want to use the OTG mode and enable VBUS comparators. */ cfgchip2 &= ~CFGCHIP2_OTGMODE; #ifdef CONFIG_USB_MUSB_HOST cfgchip2 |= CFGCHIP2_FORCE_HOST; #else cfgchip2 |= CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN; #endif __raw_writel(cfgchip2, DA8XX_SYSCFG0_VIRT(DA8XX_CFGCHIP2_REG)); /* USB_REFCLKIN is not used. */ ret = davinci_cfg_reg(DA830_USB0_DRVVBUS); if (ret) pr_warning("%s: USB 2.0 PinMux setup failed: %d\n", __func__, ret); else { /* * TPS2065 switch @ 5V supplies 1 A (sustains 1.5 A), * with the power on to power good time of 3 ms. */ ret = da8xx_register_usb20(1000, 3); if (ret)