2008-07-03 12:24:43 +03:00
/*
2005-07-10 19:58:15 +01:00
* 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>
2005-10-29 19:07:23 +01:00
# include <linux/platform_device.h>
2008-09-06 12:10:45 +01:00
# include <linux/io.h>
2005-07-10 19:58:15 +01:00
2009-10-20 09:40:47 -07:00
# include <plat/usb.h>
# include <plat/board.h>
2005-07-10 19:58:15 +01:00
2012-02-24 10:34:35 -08:00
# include <mach/hardware.h>
2005-07-10 19:58:15 +01:00
# ifdef CONFIG_ARCH_OMAP_OTG
void __init
omap_otg_init ( struct omap_usb_config * config )
{
2008-07-03 12:24:43 +03:00
u32 syscon ;
2005-07-10 19:58:15 +01:00
int alt_pingroup = 0 ;
/* NOTE: no bus or clock setup (yet?) */
2008-07-03 12:24:43 +03:00
syscon = omap_readl ( OTG_SYSCON_1 ) & 0xffff ;
2005-07-10 19:58:15 +01:00
if ( ! ( syscon & OTG_RESET_DONE ) )
pr_debug ( " USB resets not complete? \n " ) ;
2008-07-03 12:24:43 +03:00
//omap_writew(0, OTG_IRQ_EN);
2005-07-10 19:58:15 +01:00
/* pin muxing and transceiver pinouts */
if ( config - > pins [ 0 ] > 2 ) /* alt pingroup 2 */
alt_pingroup = 1 ;
2010-07-05 16:31:29 +03:00
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 ) ;
2008-07-03 12:24:43 +03:00
pr_debug ( " OTG_SYSCON_1 = %08x \n " , omap_readl ( OTG_SYSCON_1 ) ) ;
omap_writel ( syscon , OTG_SYSCON_1 ) ;
2005-07-10 19:58:15 +01:00
syscon = config - > hmc_mode ;
syscon | = USBX_SYNCHRO | ( 4 < < 16 ) /* B_ASE0_BRST */ ;
# ifdef CONFIG_USB_OTG
if ( config - > otg )
syscon | = OTG_EN ;
# endif
2006-12-07 13:58:10 -08:00
if ( cpu_class_is_omap1 ( ) )
2008-07-03 12:24:43 +03:00
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 ) ;
2005-07-10 19:58:15 +01:00
printk ( " USB: hmc %d " , config - > hmc_mode ) ;
2006-12-07 13:58:10 -08:00
if ( ! alt_pingroup )
2005-07-10 19:58:15 +01:00
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 " ) ;
2006-12-07 13:58:10 -08:00
if ( cpu_class_is_omap1 ( ) ) {
2008-07-03 12:24:43 +03:00
u16 w ;
2006-12-07 13:58:10 -08:00
/* leave USB clocks/controllers off until needed */
2008-07-03 12:24:43 +03:00
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 ) ;
2006-12-07 13:58:10 -08:00
}
2008-07-03 12:24:43 +03:00
syscon = omap_readl ( OTG_SYSCON_1 ) ;
2005-07-10 19:58:15 +01:00
syscon | = HST_IDLE_EN | DEV_IDLE_EN | OTG_IDLE_EN ;
# ifdef CONFIG_USB_GADGET_OMAP
if ( config - > otg | | config - > register_dev ) {
2010-07-05 16:31:29 +03:00
struct platform_device * udc_device = config - > udc_device ;
2012-05-09 16:38:02 -06:00
int status ;
2010-07-05 16:31:29 +03:00
2005-07-10 19:58:15 +01:00
syscon & = ~ DEV_IDLE_EN ;
2010-07-05 16:31:29 +03:00
udc_device - > dev . platform_data = config ;
status = platform_device_register ( udc_device ) ;
2005-07-10 19:58:15 +01:00
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 ) {
2010-07-05 16:31:29 +03:00
struct platform_device * ohci_device = config - > ohci_device ;
2012-05-09 16:38:02 -06:00
int status ;
2010-07-05 16:31:29 +03:00
2005-07-10 19:58:15 +01:00
syscon & = ~ HST_IDLE_EN ;
2010-07-05 16:31:29 +03:00
ohci_device - > dev . platform_data = config ;
status = platform_device_register ( ohci_device ) ;
2005-07-10 19:58:15 +01:00
if ( status )
pr_debug ( " can't register OHCI device, %d \n " , status ) ;
}
# endif
# ifdef CONFIG_USB_OTG
if ( config - > otg ) {
2010-07-05 16:31:29 +03:00
struct platform_device * otg_device = config - > otg_device ;
2012-05-09 16:38:02 -06:00
int status ;
2010-07-05 16:31:29 +03:00
2005-07-10 19:58:15 +01:00
syscon & = ~ OTG_IDLE_EN ;
2010-07-05 16:31:29 +03:00
otg_device - > dev . platform_data = config ;
status = platform_device_register ( otg_device ) ;
2005-07-10 19:58:15 +01:00
if ( status )
pr_debug ( " can't register OTG device, %d \n " , status ) ;
}
# endif
2008-07-03 12:24:43 +03:00
pr_debug ( " OTG_SYSCON_1 = %08x \n " , omap_readl ( OTG_SYSCON_1 ) ) ;
omap_writel ( syscon , OTG_SYSCON_1 ) ;
2005-07-10 19:58:15 +01:00
}
# else
2010-07-05 16:31:29 +03:00
void omap_otg_init ( struct omap_usb_config * config ) { }
2005-07-10 19:58:15 +01:00
# endif