2009-11-22 10:11:01 -08:00
/*
2011-03-01 20:08:15 +05:30
* usb - host . c - OMAP USB Host
2009-11-22 10:11:01 -08:00
*
* This file will contain the board specific details for the
2011-03-01 20:08:15 +05:30
* Synopsys EHCI / OHCI host controller on OMAP3430 and onwards
2009-11-22 10:11:01 -08:00
*
2011-03-01 20:08:15 +05:30
* Copyright ( C ) 2007 - 2011 Texas Instruments
2009-11-22 10:11:01 -08:00
* Author : Vikram Pandita < vikram . pandita @ ti . com >
2011-03-01 20:08:18 +05:30
* Author : Keshava Munegowda < keshava_mgowda @ ti . com >
2009-11-22 10:11:01 -08:00
*
* Generalization by :
2011-03-01 20:08:15 +05:30
* Felipe Balbi < balbi @ ti . com >
2009-11-22 10:11:01 -08:00
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
# include <linux/types.h>
# include <linux/errno.h>
# include <linux/delay.h>
# include <linux/platform_device.h>
2011-03-01 20:08:18 +05:30
# include <linux/slab.h>
2010-06-09 13:53:05 +03:00
# include <linux/dma-mapping.h>
2013-03-20 17:44:41 +02:00
# include <linux/regulator/machine.h>
# include <linux/regulator/fixed.h>
# include <linux/string.h>
# include <linux/io.h>
# include <linux/gpio.h>
# include <linux/usb/phy.h>
2009-11-22 10:11:01 -08:00
2012-10-05 13:25:59 -07:00
# include "soc.h"
2012-10-02 17:25:48 -07:00
# include "omap_device.h"
2009-12-11 16:16:32 -08:00
# include "mux.h"
2012-10-24 14:26:18 -07:00
# include "usb.h"
2009-12-11 16:16:32 -08:00
2011-03-01 20:08:18 +05:30
# ifdef CONFIG_MFD_OMAP_USB_HOST
2009-11-22 10:11:01 -08:00
2011-10-11 13:21:37 +05:30
# define OMAP_USBHS_DEVICE "usbhs_omap"
2012-07-16 19:01:10 +05:30
# define OMAP_USBTLL_DEVICE "usbhs_tll"
2011-10-11 13:21:37 +05:30
# define USBHS_UHH_HWMODNAME "usb_host_hs"
# define USBHS_TLL_HWMODNAME "usb_tll_hs"
2009-11-22 10:11:01 -08:00
/* MUX settings for EHCI pins */
/*
* setup_ehci_io_mux - initialize IO pad mux for USBHOST
*/
2012-03-26 16:51:10 +02:00
static void __init setup_ehci_io_mux ( const enum usbhs_omap_port_mode * port_mode )
2009-11-22 10:11:01 -08:00
{
switch ( port_mode [ 0 ] ) {
2011-03-01 20:08:16 +05:30
case OMAP_EHCI_PORT_MODE_PHY :
2009-12-11 16:16:32 -08:00
omap_mux_init_signal ( " hsusb1_stp " , OMAP_PIN_OUTPUT ) ;
omap_mux_init_signal ( " hsusb1_clk " , OMAP_PIN_OUTPUT ) ;
omap_mux_init_signal ( " hsusb1_dir " , OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_nxt " , OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_data0 " , OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_data1 " , OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_data2 " , OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_data3 " , OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_data4 " , OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_data5 " , OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_data6 " , OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_data7 " , OMAP_PIN_INPUT_PULLDOWN ) ;
2009-11-22 10:11:01 -08:00
break ;
2011-03-01 20:08:16 +05:30
case OMAP_EHCI_PORT_MODE_TLL :
2009-12-11 16:16:32 -08:00
omap_mux_init_signal ( " hsusb1_tll_stp " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " hsusb1_tll_clk " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_tll_dir " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_tll_nxt " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_tll_data0 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_tll_data1 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_tll_data2 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_tll_data3 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_tll_data4 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_tll_data5 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_tll_data6 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb1_tll_data7 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
2009-11-22 10:11:01 -08:00
break ;
2011-03-01 20:08:16 +05:30
case OMAP_USBHS_PORT_MODE_UNUSED :
2009-11-22 10:11:01 -08:00
/* FALLTHROUGH */
default :
break ;
}
switch ( port_mode [ 1 ] ) {
2011-03-01 20:08:16 +05:30
case OMAP_EHCI_PORT_MODE_PHY :
2009-12-11 16:16:32 -08:00
omap_mux_init_signal ( " hsusb2_stp " , OMAP_PIN_OUTPUT ) ;
omap_mux_init_signal ( " hsusb2_clk " , OMAP_PIN_OUTPUT ) ;
omap_mux_init_signal ( " hsusb2_dir " , OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_nxt " , OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_data0 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_data1 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_data2 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_data3 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_data4 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_data5 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_data6 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_data7 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
2009-11-22 10:11:01 -08:00
break ;
2011-03-01 20:08:16 +05:30
case OMAP_EHCI_PORT_MODE_TLL :
2009-12-11 16:16:32 -08:00
omap_mux_init_signal ( " hsusb2_tll_stp " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " hsusb2_tll_clk " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_tll_dir " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_tll_nxt " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_tll_data0 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_tll_data1 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_tll_data2 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_tll_data3 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_tll_data4 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_tll_data5 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_tll_data6 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb2_tll_data7 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
2009-11-22 10:11:01 -08:00
break ;
2011-03-01 20:08:16 +05:30
case OMAP_USBHS_PORT_MODE_UNUSED :
2009-11-22 10:11:01 -08:00
/* FALLTHROUGH */
default :
break ;
}
switch ( port_mode [ 2 ] ) {
2011-03-01 20:08:16 +05:30
case OMAP_EHCI_PORT_MODE_PHY :
2009-11-22 10:11:01 -08:00
printk ( KERN_WARNING " Port3 can't be used in PHY mode \n " ) ;
break ;
2011-03-01 20:08:16 +05:30
case OMAP_EHCI_PORT_MODE_TLL :
2009-12-11 16:16:32 -08:00
omap_mux_init_signal ( " hsusb3_tll_stp " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " hsusb3_tll_clk " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb3_tll_dir " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb3_tll_nxt " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb3_tll_data0 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb3_tll_data1 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb3_tll_data2 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb3_tll_data3 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb3_tll_data4 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb3_tll_data5 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb3_tll_data6 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " hsusb3_tll_data7 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
2009-11-22 10:11:01 -08:00
break ;
2011-03-01 20:08:16 +05:30
case OMAP_USBHS_PORT_MODE_UNUSED :
2009-11-22 10:11:01 -08:00
/* FALLTHROUGH */
default :
break ;
}
return ;
}
2012-03-26 16:51:10 +02:00
static
void __init setup_4430ehci_io_mux ( const enum usbhs_omap_port_mode * port_mode )
2010-11-21 23:23:41 +05:30
{
switch ( port_mode [ 0 ] ) {
2011-03-01 20:08:16 +05:30
case OMAP_EHCI_PORT_MODE_PHY :
2010-11-21 23:23:41 +05:30
omap_mux_init_signal ( " usbb1_ulpiphy_stp " ,
OMAP_PIN_OUTPUT ) ;
omap_mux_init_signal ( " usbb1_ulpiphy_clk " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpiphy_dir " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpiphy_nxt " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpiphy_dat0 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpiphy_dat1 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpiphy_dat2 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpiphy_dat3 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpiphy_dat4 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpiphy_dat5 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpiphy_dat6 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpiphy_dat7 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
break ;
2011-03-01 20:08:16 +05:30
case OMAP_EHCI_PORT_MODE_TLL :
2010-11-21 23:23:41 +05:30
omap_mux_init_signal ( " usbb1_ulpitll_stp " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " usbb1_ulpitll_clk " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpitll_dir " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpitll_nxt " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpitll_dat0 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpitll_dat1 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpitll_dat2 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpitll_dat3 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpitll_dat4 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpitll_dat5 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpitll_dat6 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_ulpitll_dat7 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
break ;
2011-03-01 20:08:16 +05:30
case OMAP_USBHS_PORT_MODE_UNUSED :
2010-11-21 23:23:41 +05:30
default :
break ;
}
switch ( port_mode [ 1 ] ) {
2011-03-01 20:08:16 +05:30
case OMAP_EHCI_PORT_MODE_PHY :
2010-11-21 23:23:41 +05:30
omap_mux_init_signal ( " usbb2_ulpiphy_stp " ,
OMAP_PIN_OUTPUT ) ;
omap_mux_init_signal ( " usbb2_ulpiphy_clk " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpiphy_dir " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpiphy_nxt " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpiphy_dat0 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpiphy_dat1 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpiphy_dat2 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpiphy_dat3 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpiphy_dat4 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpiphy_dat5 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpiphy_dat6 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpiphy_dat7 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
break ;
2011-03-01 20:08:16 +05:30
case OMAP_EHCI_PORT_MODE_TLL :
2010-11-21 23:23:41 +05:30
omap_mux_init_signal ( " usbb2_ulpitll_stp " ,
OMAP_PIN_INPUT_PULLUP ) ;
omap_mux_init_signal ( " usbb2_ulpitll_clk " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpitll_dir " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpitll_nxt " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpitll_dat0 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpitll_dat1 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpitll_dat2 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpitll_dat3 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpitll_dat4 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpitll_dat5 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpitll_dat6 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_ulpitll_dat7 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
break ;
2011-03-01 20:08:16 +05:30
case OMAP_USBHS_PORT_MODE_UNUSED :
2010-11-21 23:23:41 +05:30
default :
break ;
}
}
2012-03-26 16:51:10 +02:00
static void __init setup_ohci_io_mux ( const enum usbhs_omap_port_mode * port_mode )
2010-05-10 21:56:10 +05:30
{
switch ( port_mode [ 0 ] ) {
case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM :
case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM :
omap_mux_init_signal ( " mm1_rxdp " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " mm1_rxdm " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
/* FALLTHROUGH */
case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM :
case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM :
omap_mux_init_signal ( " mm1_rxrcv " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
/* FALLTHROUGH */
case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0 :
omap_mux_init_signal ( " mm1_txen_n " , OMAP_PIN_OUTPUT ) ;
/* FALLTHROUGH */
case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM :
omap_mux_init_signal ( " mm1_txse0 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " mm1_txdat " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
break ;
2011-03-01 20:08:16 +05:30
case OMAP_USBHS_PORT_MODE_UNUSED :
2010-05-10 21:56:10 +05:30
/* FALLTHROUGH */
default :
break ;
}
switch ( port_mode [ 1 ] ) {
case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM :
case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM :
omap_mux_init_signal ( " mm2_rxdp " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " mm2_rxdm " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
/* FALLTHROUGH */
case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM :
case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM :
omap_mux_init_signal ( " mm2_rxrcv " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
/* FALLTHROUGH */
case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0 :
omap_mux_init_signal ( " mm2_txen_n " , OMAP_PIN_OUTPUT ) ;
/* FALLTHROUGH */
case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM :
omap_mux_init_signal ( " mm2_txse0 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " mm2_txdat " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
break ;
2011-03-01 20:08:16 +05:30
case OMAP_USBHS_PORT_MODE_UNUSED :
2010-05-10 21:56:10 +05:30
/* FALLTHROUGH */
default :
break ;
}
switch ( port_mode [ 2 ] ) {
case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM :
case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM :
omap_mux_init_signal ( " mm3_rxdp " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " mm3_rxdm " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
/* FALLTHROUGH */
case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM :
case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM :
omap_mux_init_signal ( " mm3_rxrcv " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
/* FALLTHROUGH */
case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0 :
omap_mux_init_signal ( " mm3_txen_n " , OMAP_PIN_OUTPUT ) ;
/* FALLTHROUGH */
case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM :
omap_mux_init_signal ( " mm3_txse0 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " mm3_txdat " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
break ;
2011-03-01 20:08:16 +05:30
case OMAP_USBHS_PORT_MODE_UNUSED :
2010-05-10 21:56:10 +05:30
/* FALLTHROUGH */
default :
break ;
}
}
2012-03-26 16:51:10 +02:00
static
void __init setup_4430ohci_io_mux ( const enum usbhs_omap_port_mode * port_mode )
2011-03-01 20:08:18 +05:30
{
switch ( port_mode [ 0 ] ) {
case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM :
case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM :
omap_mux_init_signal ( " usbb1_mm_rxdp " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_mm_rxdm " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM :
case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM :
omap_mux_init_signal ( " usbb1_mm_rxrcv " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0 :
omap_mux_init_signal ( " usbb1_mm_txen " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM :
omap_mux_init_signal ( " usbb1_mm_txdat " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb1_mm_txse0 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
break ;
case OMAP_USBHS_PORT_MODE_UNUSED :
default :
break ;
}
switch ( port_mode [ 1 ] ) {
case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM :
case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM :
omap_mux_init_signal ( " usbb2_mm_rxdp " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_mm_rxdm " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM :
case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM :
omap_mux_init_signal ( " usbb2_mm_rxrcv " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0 :
omap_mux_init_signal ( " usbb2_mm_txen " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0 :
case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM :
omap_mux_init_signal ( " usbb2_mm_txdat " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
omap_mux_init_signal ( " usbb2_mm_txse0 " ,
OMAP_PIN_INPUT_PULLDOWN ) ;
break ;
case OMAP_USBHS_PORT_MODE_UNUSED :
default :
break ;
}
}
2013-02-14 10:13:48 +02:00
void __init usbhs_init ( struct usbhs_omap_platform_data * pdata )
2011-03-01 20:08:18 +05:30
{
2012-07-16 19:01:10 +05:30
struct omap_hwmod * uhh_hwm , * tll_hwm ;
2012-02-14 10:54:46 +02:00
struct platform_device * pdev ;
2011-10-11 13:21:37 +05:30
int bus_id = - 1 ;
2011-03-01 20:08:18 +05:30
if ( cpu_is_omap34xx ( ) ) {
setup_ehci_io_mux ( pdata - > port_mode ) ;
setup_ohci_io_mux ( pdata - > port_mode ) ;
2012-12-14 09:09:11 -08:00
if ( omap_rev ( ) < = OMAP3430_REV_ES2_1 )
2013-02-14 10:13:48 +02:00
pdata - > single_ulpi_bypass = true ;
2012-12-14 09:09:11 -08:00
2011-03-01 20:08:18 +05:30
} else if ( cpu_is_omap44xx ( ) ) {
setup_4430ehci_io_mux ( pdata - > port_mode ) ;
setup_4430ohci_io_mux ( pdata - > port_mode ) ;
}
2012-07-16 19:01:10 +05:30
uhh_hwm = omap_hwmod_lookup ( USBHS_UHH_HWMODNAME ) ;
if ( ! uhh_hwm ) {
2011-10-11 13:21:37 +05:30
pr_err ( " Could not look up %s \n " , USBHS_UHH_HWMODNAME ) ;
return ;
2011-03-01 20:08:18 +05:30
}
2012-07-16 19:01:10 +05:30
tll_hwm = omap_hwmod_lookup ( USBHS_TLL_HWMODNAME ) ;
if ( ! tll_hwm ) {
2011-10-11 13:21:37 +05:30
pr_err ( " Could not look up %s \n " , USBHS_TLL_HWMODNAME ) ;
return ;
}
2011-03-01 20:08:18 +05:30
2012-07-16 19:01:10 +05:30
pdev = omap_device_build ( OMAP_USBTLL_DEVICE , bus_id , tll_hwm ,
2013-02-19 20:54:15 +01:00
pdata , sizeof ( * pdata ) ) ;
2012-02-14 10:54:46 +02:00
if ( IS_ERR ( pdev ) ) {
2012-07-16 19:01:10 +05:30
pr_err ( " Could not build hwmod device %s \n " ,
USBHS_TLL_HWMODNAME ) ;
return ;
}
pdev = omap_device_build ( OMAP_USBHS_DEVICE , bus_id , uhh_hwm ,
2013-02-19 20:54:15 +01:00
pdata , sizeof ( * pdata ) ) ;
2012-07-16 19:01:10 +05:30
if ( IS_ERR ( pdev ) ) {
pr_err ( " Could not build hwmod devices %s \n " ,
USBHS_UHH_HWMODNAME ) ;
2011-10-11 13:21:37 +05:30
return ;
}
2011-03-01 20:08:18 +05:30
}
2010-05-10 21:56:10 +05:30
# else
2013-02-14 10:13:48 +02:00
void __init usbhs_init ( struct usbhs_omap_platform_data * pdata )
2011-03-01 20:08:18 +05:30
{
}
# endif
2013-03-20 17:44:41 +02:00
/* Template for PHY regulators */
static struct fixed_voltage_config hsusb_reg_config = {
/* .supply_name filled later */
. microvolts = 3300000 ,
. gpio = - 1 , /* updated later */
. startup_delay = 70000 , /* 70msec */
. enable_high = 1 , /* updated later */
. enabled_at_boot = 0 , /* keep in RESET */
/* .init_data filled later */
} ;
static const char * nop_name = " nop_usb_xceiv " ; /* NOP PHY driver */
static const char * reg_name = " reg-fixed-voltage " ; /* Regulator driver */
/**
* usbhs_add_regulator - Add a gpio based fixed voltage regulator device
* @ name : name for the regulator
* @ dev_id : device id of the device this regulator supplies power to
* @ dev_supply : supply name that the device expects
* @ gpio : GPIO number
* @ polarity : 1 - Active high , 0 - Active low
*/
static int usbhs_add_regulator ( char * name , char * dev_id , char * dev_supply ,
int gpio , int polarity )
{
struct regulator_consumer_supply * supplies ;
struct regulator_init_data * reg_data ;
struct fixed_voltage_config * config ;
struct platform_device * pdev ;
int ret ;
supplies = kzalloc ( sizeof ( * supplies ) , GFP_KERNEL ) ;
if ( ! supplies )
return - ENOMEM ;
supplies - > supply = dev_supply ;
supplies - > dev_name = dev_id ;
reg_data = kzalloc ( sizeof ( * reg_data ) , GFP_KERNEL ) ;
if ( ! reg_data )
return - ENOMEM ;
reg_data - > constraints . valid_ops_mask = REGULATOR_CHANGE_STATUS ;
reg_data - > consumer_supplies = supplies ;
reg_data - > num_consumer_supplies = 1 ;
config = kmemdup ( & hsusb_reg_config , sizeof ( hsusb_reg_config ) ,
GFP_KERNEL ) ;
if ( ! config )
return - ENOMEM ;
config - > supply_name = name ;
config - > gpio = gpio ;
config - > enable_high = polarity ;
config - > init_data = reg_data ;
/* create a regulator device */
pdev = kzalloc ( sizeof ( * pdev ) , GFP_KERNEL ) ;
if ( ! pdev )
return - ENOMEM ;
pdev - > id = PLATFORM_DEVID_AUTO ;
pdev - > name = reg_name ;
pdev - > dev . platform_data = config ;
ret = platform_device_register ( pdev ) ;
if ( ret )
pr_err ( " %s: Failed registering regulator %s for %s \n " ,
__func__ , name , dev_id ) ;
return ret ;
}
int usbhs_init_phys ( struct usbhs_phy_data * phy , int num_phys )
{
char * rail_name ;
int i , len ;
struct platform_device * pdev ;
char * phy_id ;
/* the phy_id will be something like "nop_usb_xceiv.1" */
len = strlen ( nop_name ) + 3 ; /* 3 -> ".1" and NULL terminator */
for ( i = 0 ; i < num_phys ; i + + ) {
if ( ! phy - > port ) {
pr_err ( " %s: Invalid port 0. Must start from 1 \n " ,
__func__ ) ;
continue ;
}
/* do we need a NOP PHY device ? */
if ( ! gpio_is_valid ( phy - > reset_gpio ) & &
! gpio_is_valid ( phy - > vcc_gpio ) )
continue ;
/* create a NOP PHY device */
pdev = kzalloc ( sizeof ( * pdev ) , GFP_KERNEL ) ;
if ( ! pdev )
return - ENOMEM ;
pdev - > id = phy - > port ;
pdev - > name = nop_name ;
pdev - > dev . platform_data = phy - > platform_data ;
phy_id = kmalloc ( len , GFP_KERNEL ) ;
if ( ! phy_id )
return - ENOMEM ;
scnprintf ( phy_id , len , " nop_usb_xceiv.%d \n " ,
pdev - > id ) ;
if ( platform_device_register ( pdev ) ) {
pr_err ( " %s: Failed to register device %s \n " ,
__func__ , phy_id ) ;
continue ;
}
usb_bind_phy ( " ehci-omap.0 " , phy - > port - 1 , phy_id ) ;
/* Do we need RESET regulator ? */
if ( gpio_is_valid ( phy - > reset_gpio ) ) {
rail_name = kmalloc ( 13 , GFP_KERNEL ) ;
if ( ! rail_name )
return - ENOMEM ;
scnprintf ( rail_name , 13 , " hsusb%d_reset " , phy - > port ) ;
usbhs_add_regulator ( rail_name , phy_id , " reset " ,
phy - > reset_gpio , 1 ) ;
}
/* Do we need VCC regulator ? */
if ( gpio_is_valid ( phy - > vcc_gpio ) ) {
rail_name = kmalloc ( 13 , GFP_KERNEL ) ;
if ( ! rail_name )
return - ENOMEM ;
scnprintf ( rail_name , 13 , " hsusb%d_vcc " , phy - > port ) ;
usbhs_add_regulator ( rail_name , phy_id , " vcc " ,
phy - > vcc_gpio , phy - > vcc_polarity ) ;
}
phy + + ;
}
return 0 ;
}