/*---------------------------------------------------------------------------
* Copyright (C) 2005-2007, Freescale Semiconductor, Inc. All Rights Reserved.
* THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
* AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT 
*--------------------------------------------------------------------------*/


/*
 *  File:     hwinit.c
 *  Purpose:  Platform-specific host driver initialisation and configuration
 *            Pin muxing
 *            CPLD configuration
 *            transceiver, wakeup, Vbus configuration
 *
 *  Functions:  BSPUsbhCheckConfigPower  - verify power available for devices
 *              BSPUsbSetWakeUp          - setup wakeup sources for host port
 *              InitializeTransceiver    - any setup required for attached transceiver   
 *              SetPHYPowerMgmt          - suspend or resume the transceiver
 */

#pragma warning(push)
#pragma warning(disable: 4115 4201 4204 4214)
#include <windows.h>
#include <Winbase.h>
#include <ceddk.h>
#pragma warning(pop)

#include "bsp.h"
#include "MX31_usb.h"
#include "MX31_usbname.h"
#include "MX31_usbcommon.h"
#define HIGH_SPEED      1
#define FULL_SPEED      2

#define ULPI_CHIP_1504                  0
#define ULPI_CHIP_3317                  1

PCSP_USB_REGS gRegs; 
WORD gSel;
static WORD gwChipSel=ULPI_CHIP_1504;
void SetULPIHostMode1504(PCSP_USB_REGS pRegs, WORD pSel, BOOL fSuspend);
void SetULPIHostMode3317(PCSP_USB_REGS pRegs, WORD pSel, BOOL fSuspend);

volatile UINT32 *gQueueHead;
#define QUEUE_HEAD_SIZE 0x200

// Really needs this
TCHAR gszOTGGroup[30];
DWORD gdwOTGSupport;
BOOL BSPUsbCheckWakeUp(void);

#ifdef DEBUG
#define ZONE_FUNCTION DEBUGZONE(6)
#define ZONE_INIT     DEBUGZONE(1)
#endif
//-----------------------------------------------------------------------------
//
//  Function: SetPHYPowerMgmt
//
//  This function is to configure the ULPI to suspend or resume mode.
//
//  Parameters:
//     fSuspend - TRUE : Suspend request, FALSE : Resume request
//     
//  Returns:
//     NULL
//
//-----------------------------------------------------------------------------
void SetPHYPowerMgmt(BOOL fSuspend)
{
   // 2 is OTG while 0 is H2
   if ((gSel != 2) && (gSel != 0))
      return;
   
#if 0
    if (gSel == 2)
    {
        //otg 1504
        SetULPIHostMode1504(gRegs, gSel, fSuspend);
    }
    else
    {
        //hs 3317
        SetULPIHostMode3317(gRegs, gSel, fSuspend);
    }
#else
   switch (gwChipSel) {
      case ULPI_CHIP_1504:
         SetULPIHostMode1504(gRegs, gSel, fSuspend);
         break;
         
      case ULPI_CHIP_3317:
         SetULPIHostMode3317(gRegs, gSel, fSuspend);
         break;
         
      default:
         break;
   }
#endif
   return;
}

//-----------------------------------------------------------------------------
//
//  Function: InitializeOTGMux
//
//  This function is to configure the IOMUX for USB OTG Core
//
//  Parameters:
//     NULL
//     
//  Returns:
//     NULL
//
//-----------------------------------------------------------------------------
static void InitializeOTGMux()
{

//    DEBUGMSG (1, (TEXT("Configure OTG Host\r\n")));
    //usb_otg_iomux_connection();
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA7, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA6, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA5, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA4, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA3, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA2, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA1, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DATA0, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_NXT, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_STP, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_DIR, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBOTG_CLK, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
#if 0 /*ERIC0420*/
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USB_PWR, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
#endif    

    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_DATA0, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_NONE);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_DATA1, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_NONE);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_DATA2, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_NONE);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_DATA3, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_NONE);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_DATA4, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_NONE);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_DATA5, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_NONE);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_DATA6, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_NONE);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_DATA7, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_NONE);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_STP, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_NONE);
// Not sure for last 3
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_NXT, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_NONE);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_DIR, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_NONE);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBOTG_CLK, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_NONE);

   // Config USBOTG_nCS pin as GPIO Output0
   GPIO_DDKIomuxSetPinMux(USBOTG_nCS);
   GPIO_DDKIomuxSetPadConfig(USBOTG_nCS);
   GPIO_DDKGpioWriteDataPinLow(USBOTG_nCS);
   GPIO_DDKGpioSetConfigIntNone(USBOTG_nCS, DIR_OUT);
   
    return;
}

//-----------------------------------------------------------------------------
//
//  Function: InitializeHost1Mux
//
//  This function is to configure the IOMUX for USB H1 Core
//
//  Parameters:
//     NULL
//     
//  Returns:
//     NULL
//
//-----------------------------------------------------------------------------
static void InitializeHost1Mux()
{
     
     DDKIomuxSetPinMux(DDK_IOMUX_PIN_CSPI1_SS0, DDK_IOMUX_OUT_ALT1, DDK_IOMUX_IN_ALT1);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_CSPI1_SS1, DDK_IOMUX_OUT_ALT1, DDK_IOMUX_IN_ALT1);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_CSPI1_SCLK, DDK_IOMUX_OUT_ALT1, DDK_IOMUX_IN_ALT1);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_CSPI1_SS2, DDK_IOMUX_OUT_ALT1, DDK_IOMUX_IN_ALT1);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_CSPI1_MOSI, DDK_IOMUX_OUT_ALT1, DDK_IOMUX_IN_ALT1);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_CSPI1_MISO, DDK_IOMUX_OUT_ALT1, DDK_IOMUX_IN_ALT1);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_CSPI1_SPI_RDY, DDK_IOMUX_OUT_ALT1, DDK_IOMUX_IN_ALT1);
    
     DDKIomuxSetGprBit(DDK_IOMUX_GPR_USB_SUSPEND, 1);

    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_CSPI1_SS1, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_HIGH, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_CSPI1_SS0, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_HIGH, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_CSPI1_SCLK, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_HIGH,DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_CSPI1_SS2, DDK_IOMUX_PAD_SLEW_FAST,DDK_IOMUX_PAD_DRIVE_HIGH, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_CSPI1_MOSI, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_HIGH, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_CSPI1_MISO, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_HIGH, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_CSPI1_SPI_RDY, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_HIGH, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
}


//-----------------------------------------------------------------------------
//
//  Function: InitializeHost2Mux
//
//  This function is to configure the IOMUX for USB H2 Core
//
//  Parameters:
//     NULL
//     
//  Returns:
//     NULL
//
//-----------------------------------------------------------------------------
static void InitializeHost2Mux()
{
#if 0
    DDK_IOMUX_OUT OutMux;
    DDK_IOMUX_IN  InMux;
#endif

    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBH2_CLK, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBH2_DIR, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBH2_NXT, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBH2_STP, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBH2_DATA0, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USBH2_DATA1, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);

#if 0
    // daisy_chain_ipp_ind_uh2_data_2_via_PCVS2
    //DDKIomuxGetPinMux(DDK_IOMUX_PIN_PC_VS2, &OutMux, &InMux);   
    //DDKIomuxSetPinMux(DDK_IOMUX_PIN_PC_VS2, OutMux, DDK_IOMUX_IN_NONE);
    //DDKIomuxGetPinMux(DDK_IOMUX_PIN_NFWE_B, &OutMux, &InMux);   
    //DDKIomuxSetPinMux(DDK_IOMUX_PIN_NFWE_B, OutMux, DDK_IOMUX_IN_NONE);
    //DDKIomuxSetGprBit(DDK_IOMUX_GPR_UH2, 1);
    DDKIomuxGetPinMux(DDK_IOMUX_PIN_NFWE_B, &OutMux, &InMux);   
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_NFWE_B, OutMux, DDK_IOMUX_IN_NONE);
    DDKIomuxSetGprBit(DDK_IOMUX_GPR_UH2, 0);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_PC_VS2, DDK_IOMUX_OUT_ALT1, DDK_IOMUX_IN_ALT1);


    // daisy_chain_ipp_ind_uh2_data_3_via_SRXD3
    //DDKIomuxGetPinMux(DDK_IOMUX_PIN_PC_BVD1, &OutMux, &InMux);  
    //DDKIomuxSetPinMux(DDK_IOMUX_PIN_PC_BVD1, OutMux, DDK_IOMUX_IN_NONE);
    //DDKIomuxGetPinMux(DDK_IOMUX_PIN_NFRE_B, &OutMux, &InMux);   
    //DDKIomuxSetPinMux(DDK_IOMUX_PIN_NFRE_B, OutMux, DDK_IOMUX_IN_NONE);
    //DDKIomuxSetGprBit(DDK_IOMUX_GPR_UH2, 1);
    DDKIomuxGetPinMux(DDK_IOMUX_PIN_NFRE_B, &OutMux, &InMux);   
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_NFRE_B, OutMux, DDK_IOMUX_IN_NONE);
    DDKIomuxSetGprBit(DDK_IOMUX_GPR_UH2, 0);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_PC_BVD1, DDK_IOMUX_OUT_ALT1, DDK_IOMUX_IN_ALT1);

    // daisy_chain_ipp_ind_uh2_data_4_via_SCK3
    //DDKIomuxGetPinMux(DDK_IOMUX_PIN_PC_BVD2, &OutMux, &InMux);  
    //DDKIomuxSetPinMux(DDK_IOMUX_PIN_PC_BVD2, OutMux, DDK_IOMUX_IN_NONE);
    //DDKIomuxGetPinMux(DDK_IOMUX_PIN_NFALE, &OutMux, &InMux);    
    //DDKIomuxSetPinMux(DDK_IOMUX_PIN_NFALE, OutMux, DDK_IOMUX_IN_NONE);
    //DDKIomuxSetGprBit(DDK_IOMUX_GPR_UH2, 1);
    DDKIomuxGetPinMux(DDK_IOMUX_PIN_NFALE, &OutMux, &InMux);    
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_NFALE, OutMux, DDK_IOMUX_IN_NONE);
    DDKIomuxSetGprBit(DDK_IOMUX_GPR_UH2, 0);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_PC_BVD2, DDK_IOMUX_OUT_ALT1, DDK_IOMUX_IN_ALT1);

    // daisy_chain_ipp_ind_uh2_data_5_via_SFS3
    //DDKIomuxGetPinMux(DDK_IOMUX_PIN_PC_RST, &OutMux, &InMux);   
    //DDKIomuxSetPinMux(DDK_IOMUX_PIN_PC_RST, OutMux, DDK_IOMUX_IN_NONE);
    //DDKIomuxGetPinMux(DDK_IOMUX_PIN_NFCLE, &OutMux, &InMux);    
    //DDKIomuxSetPinMux(DDK_IOMUX_PIN_NFCLE, OutMux, DDK_IOMUX_IN_NONE);
    //DDKIomuxSetGprBit(DDK_IOMUX_GPR_UH2, 1);
    DDKIomuxGetPinMux(DDK_IOMUX_PIN_NFCLE, &OutMux, &InMux);    
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_NFCLE, OutMux, DDK_IOMUX_IN_NONE);
    DDKIomuxSetGprBit(DDK_IOMUX_GPR_UH2, 0);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_PC_RST, DDK_IOMUX_OUT_ALT1, DDK_IOMUX_IN_ALT1);

    // daisy_chain_ipp_ind_uh2_data_6_via_STXD6
    //DDKIomuxGetPinMux(DDK_IOMUX_PIN_IOIS16, &OutMux, &InMux);   
    //DDKIomuxSetPinMux(DDK_IOMUX_PIN_IOIS16, OutMux, DDK_IOMUX_IN_NONE);
    //DDKIomuxGetPinMux(DDK_IOMUX_PIN_NFWP_B, &OutMux, &InMux);   
    //DDKIomuxSetPinMux(DDK_IOMUX_PIN_NFWP_B, OutMux, DDK_IOMUX_IN_NONE);
    //DDKIomuxSetGprBit(DDK_IOMUX_GPR_UH2, 1);
    DDKIomuxGetPinMux(DDK_IOMUX_PIN_NFWP_B, &OutMux, &InMux);   
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_NFWP_B, OutMux, DDK_IOMUX_IN_NONE);
    DDKIomuxSetGprBit(DDK_IOMUX_GPR_UH2, 0);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_IOIS16, DDK_IOMUX_OUT_ALT1, DDK_IOMUX_IN_ALT1);

    // daisy_chain_ipp_ind_uh2_data_7_via_SRXD6
    //DDKIomuxGetPinMux(DDK_IOMUX_PIN_PC_RW_B, &OutMux, &InMux);  
    //DDKIomuxSetPinMux(DDK_IOMUX_PIN_PC_RW_B, OutMux, DDK_IOMUX_IN_NONE);
    //DDKIomuxGetPinMux(DDK_IOMUX_PIN_NFCE_B, &OutMux, &InMux);   
    //DDKIomuxSetPinMux(DDK_IOMUX_PIN_NFCE_B, OutMux, DDK_IOMUX_IN_NONE);
    //DDKIomuxSetGprBit(DDK_IOMUX_GPR_UH2, 1);
    DDKIomuxGetPinMux(DDK_IOMUX_PIN_NFCE_B, &OutMux, &InMux);   
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_NFCE_B, OutMux, DDK_IOMUX_IN_NONE);
    DDKIomuxSetGprBit(DDK_IOMUX_GPR_UH2, 0);
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_PC_RW_B, DDK_IOMUX_OUT_ALT1, DDK_IOMUX_IN_ALT1);

    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBH2_CLK, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBH2_DIR, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBH2_NXT, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBH2_STP, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    //DDKIomuxSetPadConfig(DDK_IOMUX_PAD_SRXD6, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    //DDKIomuxSetPadConfig(DDK_IOMUX_PAD_STXD6, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    //DDKIomuxSetPadConfig(DDK_IOMUX_PAD_SFS3, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    //DDKIomuxSetPadConfig(DDK_IOMUX_PAD_SCK3, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    //DDKIomuxSetPadConfig(DDK_IOMUX_PAD_SRXD3, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    //DDKIomuxSetPadConfig(DDK_IOMUX_PAD_STXD3, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_PC_VS2, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_PC_BVD1, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_PC_BVD2, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_PC_RST, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_IOIS16, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_PC_RW_B, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBH2_DATA0, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
    DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBH2_DATA1, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
#else
   DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBH2_CLK, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
   DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBH2_DIR, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
   DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBH2_NXT, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
   DDKIomuxSetPadConfig(DDK_IOMUX_PAD_USBH2_STP, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
   
   // Enable USBH2 signals on AudioPort 3 and AudioPort6
   // Config uP_USB_HSH_D2(R1)
   DDKIomuxSetPinMux(DDK_IOMUX_PIN_STXD3, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
   DDKIomuxSetPadConfig(DDK_IOMUX_PAD_STXD3, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
   // Config uP_USB_HSH_D3(R3)
   DDKIomuxSetPinMux(DDK_IOMUX_PIN_SRXD3, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
   DDKIomuxSetPadConfig(DDK_IOMUX_PAD_SRXD3, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
   // Config uP_USB_HSH_D4(R2)
   DDKIomuxSetPinMux(DDK_IOMUX_PIN_SCK3, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
   DDKIomuxSetPadConfig(DDK_IOMUX_PAD_SCK3, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
   // Config uP_USB_HSH_D5(R6)
   DDKIomuxSetPinMux(DDK_IOMUX_PIN_SFS3, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
   DDKIomuxSetPadConfig(DDK_IOMUX_PAD_SFS3, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
   // Config uP_USB_HSH_D6(T1)
   DDKIomuxSetPinMux(DDK_IOMUX_PIN_STXD6, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
   DDKIomuxSetPadConfig(DDK_IOMUX_PAD_STXD6, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
   // Config uP_USB_HSH_D7(R7)
   DDKIomuxSetPinMux(DDK_IOMUX_PIN_SRXD6, DDK_IOMUX_OUT_FUNC, DDK_IOMUX_IN_FUNC);
   DDKIomuxSetPadConfig(DDK_IOMUX_PAD_SRXD6, DDK_IOMUX_PAD_SLEW_FAST, DDK_IOMUX_PAD_DRIVE_MAX, DDK_IOMUX_PAD_MODE_CMOS, DDK_IOMUX_PAD_TRIG_CMOS, DDK_IOMUX_PAD_PULL_UP_100K);
   
   DDKIomuxSetGprBit(DDK_IOMUX_GPR_UH2, 1);
   
   // Config USBHSH_nCS pin as GPIO Output0
   GPIO_DDKIomuxSetPinMux(USBHSH_nCS);
   GPIO_DDKIomuxSetPadConfig(USBHSH_nCS);
   GPIO_DDKGpioWriteDataPinLow(USBHSH_nCS);
   GPIO_DDKGpioSetConfigIntNone(USBHSH_nCS, DIR_OUT);
#endif
    
#if 0 /*ERIC0611*/
    // reset pin
    DDKIomuxSetPinMux(DDK_IOMUX_PIN_USB_BYP, DDK_IOMUX_OUT_GPIO, DDK_IOMUX_IN_GPIO);
    DDKGpioSetConfig(DDK_GPIO_PORT1, 31, DDK_GPIO_DIR_OUT, DDK_GPIO_INTR_NONE);
    DDKGpioWriteDataPin(DDK_GPIO_PORT1, 31, 1);
#endif
}
    
//-----------------------------------------------------------------------------
//
//  Function: InitializeMux
//
//  This function is to configure the IOMUX for USB Host Cores
//
//  Parameters:
//     speed - FULL_SPEED, HIGH_SPEED
//     sel - Selection of the USB cores (0 - H2, 1 - H1, 2- OTG)
//     
//  Returns:
//     offset of the USB core register to be configured.
//
//-----------------------------------------------------------------------------
static DWORD InitializeMux(int speed, int sel)
{
   DWORD off=offset(CSP_USB_REGS, H2)+offset(CSP_USB_REG, CAPLENGTH);
   
   DEBUGMSG(ZONE_INIT, (__WFUNCTION__ TEXT("(%d, %d)+\r\n"), speed, sel));
   
   if (sel==2) {   // OTG
      InitializeOTGMux();
      off=offset(CSP_USB_REG, CAPLENGTH);
   }
   else if (speed==FULL_SPEED) {
      if (sel==0) {       // Host 2
         off=offset(CSP_USB_REGS, H2)+offset(CSP_USB_REG, CAPLENGTH);
         InitializeHost2Mux();
      
      }   
      else {          // Host 1
         off=offset(CSP_USB_REGS, H1)+offset(CSP_USB_REG, CAPLENGTH);
         InitializeHost1Mux();
      }
   }
   else {
      off = offset(CSP_USB_REGS, H2) + offset(CSP_USB_REG, CAPLENGTH);
      InitializeHost2Mux();
   }
   
   DEBUGMSG(ZONE_INIT, (__WFUNCTION__ TEXT("(%d)-\r\n"), off));
   
   return off;
}

//-----------------------------------------------------------------------------
//
//  Function: dumpCPLD
//
//  This function is to dump the CPLD information
//
//  Parameters:
//     cpld - Pointer to Mapped CPLD Register
//
//  Returns:
//      None
//
//-----------------------------------------------------------------------------
#ifdef DEBUG
void dumpCPLD(PCSP_PBC_REGS cpld)
{
    // Remove-W4: Warning C4100 workaround
    UNREFERENCED_PARAMETER(cpld);

    DEBUGMSG (1,(L"Dump PBC registers:\r\n"));
    DEBUGMSG (1,(L"\tVERSION=%x\r\n", INREG16(&cpld->VERSION)));
    DEBUGMSG (1,(L"\tBSTAT2=%x\r\n", INREG16(&cpld->BSTAT2)));
    DEBUGMSG (1,(L"\tBCTRL1_SET=%x\r\n", INREG16(&cpld->BCTRL1_SET)));
    DEBUGMSG (1,(L"\tBCTRL1_CLEAR=%x\r\n", INREG16(&cpld->BCTRL1_CLEAR)));
    DEBUGMSG (1,(L"\tBCTRL2_SET=%x\r\n", INREG16(&cpld->BCTRL2_SET)));
    DEBUGMSG (1,(L"\tBCTRL2_CLEAR=%x\r\n", INREG16(&cpld->BCTRL2_CLEAR)));
    DEBUGMSG (1,(L"\tBCTRL3_SET=%x\r\n", INREG16(&cpld->BCTRL3_SET)));
    DEBUGMSG (1,(L"\tBCTRL3_CLEAR=%x\r\n", INREG16(&cpld->BCTRL3_CLEAR)));
    DEBUGMSG (1,(L"\tBCTRL4_SET=%x\r\n", INREG16(&cpld->BCTRL4_SET)));
    DEBUGMSG (1,(L"\tBCTRL4_CLEAR=%x\r\n", INREG16(&cpld->BCTRL4_CLEAR)));
    DEBUGMSG (1,(L"\tBSTAT1=%x\r\n", INREG16(&cpld->BSTAT1)));
    DEBUGMSG (1,(L"\tINT_STATUS=%x\r\n", INREG16(&cpld->INT_STATUS)));
    DEBUGMSG (1,(L"\tINT_CUR_STATUS=%x\r\n", INREG16(&cpld->INT_CUR_STATUS)));
    DEBUGMSG (1,(L"\tINT_MASK_SET=%x\r\n", INREG16(&cpld->INT_MASK_SET)));
    DEBUGMSG (1,(L"\tINT_MASK_CLEAR=%x\r\n", INREG16(&cpld->INT_MASK_CLEAR)));
}
#endif

//-----------------------------------------------------------------------------
//
//  Function: InitializeCPLD
//
//  This function is to configure the CPLD to corresponding USB core
//
//  Parameters:
//     sel - the value in which USB core to configure. 
//     
//  Returns:
//     Speed of the USB core - HIGH_SPEED or FULL_SPEED
//
//-----------------------------------------------------------------------------
// sel = 0 => Host 2
// sel = 1 => Host 1
// sel =2 => OTG
static int InitializeCPLD(WORD * sel)
{
    int r;
#if (USB_HOST_MODE==0)||(USB_HOST_MODE==1)
    // OTG port, be sure to turn off the USB function driver.   
    *sel=2;
    #if (USB_HOST_MODE==0)  //OTG Full Speed - not implemented here
        //Set this to OTG_FS on base board
        //Clear this to OTG_FS on ATLAS board
        r=FULL_SPEED;
    #else                   //OTG High Speed - ISP1504
        r=HIGH_SPEED;
        DEBUGMSG(ZONE_INIT, (L"High Speed USB OTG Host\r\n"));
    #endif
#else 
     #if (USB_HOST_MODE!=4)
    {
        DEBUGMSG(ZONE_INIT, (L"Full speed USB host\r\n"));
        
        #if (USB_HOST_MODE==2)
            *sel=1;
        #else
            *sel=0;  
        #endif

        r=FULL_SPEED;
    }
#else
    {
        *sel = 0;
        DEBUGMSG(ZONE_INIT, (L"High speed USB host\r\n"));
         
        r=HIGH_SPEED;
    }
#endif
#endif  
    return r;
}

static int TransceiverPowerOn(void)
{
#if 0 /*PMIC register write will cause problem, leave it for OAL*/
    UINT32 reg_mask, reg_value;

    PmicRegisterRead(MC13783_PWR_MISC_ADDR, &reg_value);
    RETAILMSG(1, (L"regvalue is %x\r\n", reg_value));

    reg_value = 1<<10 ; //GPO3
    reg_mask  = 1<<10;
    
	//Enable GPO3
    if (PMIC_SUCCESS != PmicRegisterWrite(MC13783_PWR_MISC_ADDR, reg_value, reg_mask))
    {
        ERRORMSG(1, (TEXT("%s: Enable GPO3 (PmicRegisterWrite) failed\r\n"), __WFUNCTION__)); 
        return FALSE;
    }
    
    //Enable GPO1, GPO3
    reg_value = (1<<6) | (1<<10);
    reg_mask = (1<<6) | (1<<10);
    if (PMIC_SUCCESS != PmicRegisterWrite(MC13783_PWR_MISC_ADDR, reg_value, reg_mask))
    {
        ERRORMSG(1, (TEXT("%s: Enable GPO1,2,3 (PmicRegisterWrite) failed\r\n"), __WFUNCTION__)); 
        return FALSE;
    }
#endif

    return TRUE;
}
extern BOOL Initialize1504(CSP_USB_REGS * regs, WORD sel);
extern BOOL Initialize3317(CSP_USB_REGS * regs, WORD sel);
extern void DumpULPIRegs(PCSP_USB_REGS pRegs, WORD sel);

//-----------------------------------------------------------------------------
//
//  Function: DumpDeviceState
//
//  This function is to dump the device status
//
//  Parameters:
//     state - pointer to PORTSC register
//     
//  Returns:
//     NULL
//
//-----------------------------------------------------------------------------
#ifdef DEBUG
static void DumpDeviceState( USB_PORTSC_T * state)  
{ 
    if (state->CCS)
        DEBUGMSG(1, (L"\t\tCurrent Connect Status: Attached\r\n"));
    if (state->CSC)
        DEBUGMSG (1, (L"\t\tConnect Status Change: Changed\r\n"));
    if (state->PE)
        DEBUGMSG (1, (L"\t\tPort Enabled\r\n"));
    if (state->PEC)
        DEBUGMSG (1, (L"\t\tPort Enable/Disable Change\r\n"));
    if (state->OCA)
        DEBUGMSG (1, (L"\t\tOver-current Active\r\n"));
    if (state->OCC)
        DEBUGMSG (1, (L"\t\tOver-current Change\r\n"));
    if (state->FPR)
        DEBUGMSG (1, (L"\t\tForce Port Resume\r\n"));
    if (state->SUSP)
        DEBUGMSG (1, (L"\t\tSuspend\r\n"));
    if (state->PR)
        DEBUGMSG (1, (L"\t\tPort Reset\r\n"));
    if (state->HSP)
        DEBUGMSG (1, (L"\t\tHigh-Speed Port \r\n"));
    
    DEBUGMSG (1, (L"\t\tLine Status: %x", state->LS));
    switch (state->LS) 
	{
        case 0:
            DEBUGMSG (1, (L"\t\t\tSE0\r\n"));
            break;
        case 1:
            DEBUGMSG (1, (L"\t\t\tJ-state\r\n"));
            break;
        case 2:
            DEBUGMSG (1, (L"\t\t\tK-state\r\n"));
            break;
        default:
            DEBUGMSG (1, (L"\t\t\tUndefined\r\n"));
            break;
    }

    if (state->PP)
        DEBUGMSG (1, (L"\t\t??? Should be 0 for device\r\n"));
    if (state->PO)
        DEBUGMSG (1, (L"\t\tPort Owner\r\n"));
    if (state->PIC) {
        DEBUGMSG (1, (L"\t\tPort Indicator Control"));
        switch (state->PIC) {
            case 1:
                DEBUGMSG (1, (L"\t\t\tAmber\r\n"));
                break;
            case 2:
                DEBUGMSG (1, (L"\t\t\tGreen\r\n"));
                break;
          
            default:
                DEBUGMSG (1, (L"\t\t\tUndefined\r\n"));
                break;
        }
    }   
    if (state->PTC) 
        DEBUGMSG (1, (L"\t\tPort Test Control: %x\r\n", state->PTC));
        
    if (state->WKCN) 
        DEBUGMSG (1, (L"\t\tWake on Connect Enable (WKCNNT_E)\r\n"));
                        
    if (state->WKDC) 
        DEBUGMSG (1, (L"\t\tWake on Disconnect Enable (WKDSCNNT_E) \r\n"));

    if (state->WKOC) 
        DEBUGMSG (1, (L"\t\tWake on Over-current Enable (WKOC_E) \r\n"));
    
    if (state->PHCD) 
        DEBUGMSG (1, (L"\t\tPHY Low Power Suspend - Clock Disable (PLPSCD) \r\n"));

    if (state->PFSC) 
        DEBUGMSG (1, (L"\t\tPort Force Full Speed Connect \r\n"));

    DEBUGMSG (1, (L"\t\tPort Speed: %x->", state->PSPD));
    switch (state->PSPD) 
	{
        case 0:
            DEBUGMSG (1, (L"\t\t\tFull Speed\r\n"));
            break;
        case 1:
            DEBUGMSG (1, (L"\t\t\tLow Speed\r\n"));
            break;
        case 2:
            DEBUGMSG (1, (L"\t\t\tHigh Speed\r\n"));
            break;
        
        default:
            DEBUGMSG (1, (L"\t\t\tUndefined\r\n"));
            break;
    }
    DEBUGMSG (1, (L"\t\tParallel Transceiver Width:%x->", state->PTW));
    if (state->PTW) 
        DEBUGMSG (1, (L"\t\t\t16 bits\r\n"));
    else
        DEBUGMSG (1, (L"\t\t\t8 bits\r\n"));
    if (state->STS) 
        DEBUGMSG (1, (L"\t\tSerial Transceiver Select \r\n"));
    
    DEBUGMSG (1, (L"\t\tParallel Transceiver Select:%x->", state->PTS));
    switch (state->PTS) {
        case 0:
            DEBUGMSG (1, (L"\t\t\tUTMI/UTMI+\r\n"));
            break;
        case 1:
            DEBUGMSG (1, (L"\t\t\tPhilips Classic\r\n"));
            break;
        case 2:
            DEBUGMSG (1, (L"\t\t\tULPI\r\n"));
            break;
        case 3:
            DEBUGMSG (1, (L"\t\t\tSerial/1.1 PHY (FS Only)\r\n"));
            break;
        default:
            DEBUGMSG (1, (L"\t\t\tUndefined\r\n"));
            break;
    }                   
}

//-----------------------------------------------------------------------------
//
//  Function: DumpUSBRegs
//
//  This function is to dump the USB Register detail
//
//  Parameters:
//     regs - Pointer to 3 USB Core Register
//     sel - 0: H2, 1: H1, 2: OTG
//     
//  Returns:
//     NULL
//
//-----------------------------------------------------------------------------
static void DumpUSBRegs(PCSP_USB_REGS regs, WORD sel)
{    
    CSP_USB_REG *pReg;
    
    if (sel == 2)
        DEBUGMSG (1, (L"Dump OTG Regs\r\n"));
    else
        DEBUGMSG (1,(L"Dump H%s USB Regs\r\n", ((sel == 0)? "2": "1")));
    
    if (sel == 0)
        pReg = (PCSP_USB_REG)(&(regs->H2));
    else if (sel==1)
        pReg = (PCSP_USB_REG)(&(regs->H1));
    else
        pReg=(PCSP_USB_REG)(&(regs->OTG));

    DEBUGMSG (1,(L"\tID(%xh)=%x\r\n",offset(CSP_USB_REG,ID), INREG32(&pReg->ID)));
    DEBUGMSG (1,(L"\tHWGENERAL(%xh)=%x\r\n",offset(CSP_USB_REG,HWGENERAL),INREG32(&pReg->HWGENERAL)));
    DEBUGMSG (1,(L"\tHWHOST(%xh)=%x\r\n",offset(CSP_USB_REG,HWHOST),INREG32(&pReg->HWHOST)));
    DEBUGMSG (1,(L"\tHWDEVICE(%xh)=%x\r\n",offset(CSP_USB_REG,HWDEVICE),INREG32(&pReg->HWDEVICE)));
    DEBUGMSG (1,(L"\tHWTXBUF(%xh)=%x\r\n",offset(CSP_USB_REG,HWTXBUF),INREG32(&pReg->HWTXBUF)));
    DEBUGMSG (1,(L"\tHWRXBUF(%xh)=%x\r\n",offset(CSP_USB_REG,HWRXBUF),INREG32(&pReg->HWRXBUF)));
    DEBUGMSG (1,(L"\tCAPLENGTH(%xh)=%x\r\n",offset(CSP_USB_REG,CAPLENGTH),INREG8(&pReg->CAPLENGTH)));
    DEBUGMSG (1,(L"\tHCIVERSION(%xh)=%x\r\n",offset(CSP_USB_REG,HCIVERSION),INREG16(&pReg->HCIVERSION)));
    DEBUGMSG (1,(L"\tHCSPARAMS(%xh)=%x\r\n",offset(CSP_USB_REG,HCSPARAMS),INREG32(&pReg->HCSPARAMS)));
    DEBUGMSG (1,(L"\tHCCPARAMS(%xh)=%x\r\n",offset(CSP_USB_REG,HCCPARAMS),INREG32(&pReg->HCCPARAMS)));
    DEBUGMSG (1,(L"\tDCIVERSION(%xh)=%x\r\n",offset(CSP_USB_REG,DCIVERSION),INREG16(&pReg->DCIVERSION)));
    DEBUGMSG (1,(L"\tDCCPARAMS(%xh)=%x\r\n",offset(CSP_USB_REG,DCCPARAMS),INREG32(&pReg->DCCPARAMS)));
    DEBUGMSG (1,(L"\tUSBCMD(%xh)=%x\r\n",offset(CSP_USB_REG,USBCMD),INREG32(&pReg->USBCMD)));
    DEBUGMSG (1,(L"\tUSBSTS(%xh)=%x\r\n",offset(CSP_USB_REG,USBSTS),INREG32(&pReg->USBSTS)));
    DEBUGMSG (1,(L"\tUSBINTR(%xh)=%x\r\n",offset(CSP_USB_REG,USBINTR),INREG32(&pReg->USBINTR)));
    DEBUGMSG (1,(L"\tPORTSC(%xh)[0]=%x\r\n",offset(CSP_USB_REG,PORTSC[0]),INREG32(&pReg->PORTSC[0])));
    {
        USB_PORTSC_T state;
        DWORD * temp=(DWORD*)&state;
        *temp=INREG32(&pReg->PORTSC[0]);
        DumpDeviceState( & state);
    }
    DEBUGMSG (1,(L"\tOTGSC(%xh)=%x\r\n",offset(CSP_USB_REG,OTGSC),INREG32(&pReg->OTGSC)));
    DEBUGMSG (1,(L"\tUSBMODE(%xh)=%x\r\n",offset(CSP_USB_REG,USBMODE),INREG32(&pReg->USBMODE)));
    DEBUGMSG (1,(L"\tULPI_VIEWPORT(%xh)=%x\r\n",offset(CSP_USB_REG,ULPI_VIEWPORT),INREG32(&pReg->ULPI_VIEWPORT)));

    DEBUGMSG (1,(L"\t*********************\r\n"));
    DEBUGMSG (1,(L"\tAddress of ASYNCLISTADDR at 0x%x\r\n", &pReg->T_158H.ASYNCLISTADDR));
    DEBUGMSG (1,(L"\tASYNCLISTADDR(%xh)=%x\r\n",offset(CSP_USB_REG,T_158H),INREG32(&pReg->T_158H.ASYNCLISTADDR)));
    DEBUGMSG (1,(L"\tENDPTSETUPSTAT(%xh)=%x\r\n",offset(CSP_USB_REG,ENDPTSETUPSTAT),INREG32(&pReg->ENDPTSETUPSTAT)));
    DEBUGMSG (1,(L"\tENDPTPRIME(%xh)=%x\r\n",offset(CSP_USB_REG,ENDPTPRIME),INREG32(&pReg->ENDPTPRIME)));
    DEBUGMSG (1,(L"\tENDPTFLUSH(%xh)=%x\r\n",offset(CSP_USB_REG,ENDPTFLUSH),INREG32(&pReg->ENDPTFLUSH)));
    DEBUGMSG (1,(L"\tENDPTSTATUS(%xh)=%x\r\n",offset(CSP_USB_REG,ENDPTSTATUS),INREG32(&pReg->ENDPTSTATUS)));
    DEBUGMSG (1,(L"\tENDPTCOMPLETE(%xh)=%x\r\n",offset(CSP_USB_REG,ENDPTCOMPLETE),INREG32(&pReg->ENDPTCOMPLETE)));
    DEBUGMSG (1,(L"\tENDPTCTRL0(%xh)=%x\r\n",offset(CSP_USB_REG,ENDPTCTRL0),INREG32(&pReg->ENDPTCTRL0)));
    DEBUGMSG (1,(L"\t*********************\r\n"));
    
    DEBUGMSG (1,(L"\tUSB_CTRL(%xh)=%x\r\n",offset(CSP_USB_REGS,USB_CTRL),INREG32(&regs->USB_CTRL)));
    DEBUGMSG (1,(L"\tUSB_OTG_MIRROR(%xh)=%x\r\n",offset(CSP_USB_REGS,USB_OTG_MIRROR),INREG32(&regs->USB_OTG_MIRROR)));
}

#endif

//-----------------------------------------------------------------------------
//
//  Function: ConfigH1
//
//  This function is to configure the USB H1 Core.
//
//  Parameters:
//     pRegs - Pointer to 3 USB Core Registers
//     
//  Returns:
//     NULL
//
//-----------------------------------------------------------------------------
static void ConfigH1(CSP_USB_REGS *pRegs)
{
    USB_PORTSC_T portsc;
    USB_CTRL_T ctrl;
    USB_USBCMD_T  cmd;
    USB_USBMODE_T mode;
    DWORD *temp;

     temp =  (DWORD *)&ctrl;
    *temp = INREG32(&pRegs->USB_CTRL);
    ctrl.H1SIC = 0x2;
    OUTREG32(&pRegs->USB_CTRL, *temp);

     temp = (DWORD *)&ctrl;
    *temp = INREG32(&pRegs->USB_CTRL);
    ctrl.H1WIE = 0x1;
    OUTREG32(&pRegs->USB_CTRL, *temp);

     temp = (DWORD *)&ctrl;
    *temp = INREG32(&pRegs->USB_CTRL);
    ctrl.H1PM = 0x1;
    OUTREG32(&pRegs->USB_CTRL, *temp);

     temp = (DWORD *)&ctrl;
    *temp = INREG32(&pRegs->USB_CTRL);
    ctrl.H1DT = 0x1;
    OUTREG32(&pRegs->USB_CTRL, *temp);

     temp = (DWORD *)&ctrl;
    *temp = INREG32(&pRegs->USB_CTRL);
    ctrl.BPE = 0x1;
    OUTREG32(&pRegs->USB_CTRL, *temp);
    
     temp = (DWORD *)&cmd;
    *temp = INREG32(&pRegs->H1.USBCMD);
    cmd.RST = 1;
    OUTREG32(&pRegs->H1.USBCMD, *temp);

    while (INREG32(&pRegs->H1.USBCMD)& (0x1 << 1));

    temp = (DWORD *)&mode;
    *temp = INREG32(&pRegs->H1.USBMODE);
    mode.CM = 0x3;
    OUTREG32(&pRegs->H1.USBMODE, *temp);

    Sleep(10);
    if ((INREG32(&pRegs->H1.USBMODE)& 0x3) != 0x3)
    {
//        DEBUGMSG (1, (TEXT("USBMode setting failure\r\n")));
        return;
    }

     if (INREG32(&pRegs->H1.HCSPARAMS) &(0x1 << 4))
    {
        temp = (DWORD *)&portsc;
        *temp = INREG32(&pRegs->H1.PORTSC);
        portsc.PP = 1;
        OUTREG32(&pRegs->H1.PORTSC, *temp);
    }

     temp=(DWORD *)&cmd; 
    *temp=0;
    cmd.RST=1;  
    CLRREG32(&pRegs->H1.USBCMD, *temp);
    *temp = INREG32(&pRegs->H1.USBCMD);
    cmd.RST=1;
    OUTREG32(&pRegs->H1.USBCMD, *temp);
    while (INREG32(&pRegs->H1.USBCMD) & (0x1 << 1));

    temp = (DWORD *)&mode;
    *temp = INREG32(&pRegs->H1.USBMODE);
    mode.CM = 0x3;
    OUTREG32(&pRegs->H1.USBMODE, *temp);

    Sleep(10);
    while ((INREG32(&pRegs->H1.USBMODE)& 0x3) != 0x3);

    
     return;
}
//-----------------------------------------------------------------------------
//
//  Function: ConfigH2
//
//  This function is to configure the USB H2 Core.
//
//  Parameters:
//     pRegs - Pointer to 3 USB Core Registers
//     
//  Returns:
//     NULL
//
//-----------------------------------------------------------------------------
static void ConfigH2(CSP_USB_REGS *pRegs)
{
    USB_PORTSC_T portsc;
    USB_CTRL_T   ctrl;
    USB_USBMODE_T mode;
    USB_USBCMD_T cmd;
    DWORD *temp;
            

    //usb_hs2_ulpi_interface_configure
    temp  = (DWORD *)&portsc;
    *temp = INREG32(&pRegs->H2.PORTSC);
    portsc.LS  = 0x2;
    portsc.PTS = 0x2;

	// Keep this comment as to configure for the Full Speed Testing
    // Configure this to Full Speed for testing purpose
     OUTREG32(&pRegs->H2.PORTSC, *temp);

    //usb_h2_interrupt_enable
    temp =  (DWORD *)&ctrl;
    *temp = INREG32(&pRegs->USB_CTRL);
    ctrl.H2WIE = 1;
    OUTREG32(&pRegs->USB_CTRL, *temp);

    //usb_h2_power_mask_enable
    temp =  (DWORD *)&ctrl;
    *temp = INREG32(&pRegs->USB_CTRL);
    ctrl.H2PM = 1;
    OUTREG32(&pRegs->USB_CTRL, *temp);

    // usb_h2_tll_disable
    temp =  (DWORD *)&ctrl;
    *temp = INREG32(&pRegs->USB_CTRL);
    ctrl.H2DT = 1;
    OUTREG32(&pRegs->USB_CTRL, *temp);

    // usb_bypass_inactive
    temp=(DWORD *)&ctrl;    
    *temp=0;
    ctrl.BPE=1;     //  Bypass Enable bit, clear it
    CLRREG32(&pRegs->USB_CTRL, *temp);

    //uh2_setmode
    temp = (DWORD *)&cmd;
    *temp = INREG32(&pRegs->H2.USBCMD);
    cmd.RST = 1;
    OUTREG32(&pRegs->H2.USBCMD, *temp);

    while (INREG32(&pRegs->H2.USBCMD)& (0x1 << 1));

    temp = (DWORD *)&mode;
    *temp = INREG32(&pRegs->H2.USBMODE);
    mode.CM = 0x3;
    OUTREG32(&pRegs->H2.USBMODE, *temp);

    Sleep(10);
    if ((INREG32(&pRegs->H2.USBMODE)& 0x3) != 0x3)
    {
//        DEBUGMSG (1, (TEXT("USBMode setting failure\r\n")));
        return;
    }

    //uh2_power_on_port1
    if (INREG32(&pRegs->H2.HCSPARAMS) &(0x1 << 4))
    {
        temp = (DWORD *)&portsc;
        *temp = INREG32(&pRegs->H2.PORTSC);
        portsc.PP = 1;
        OUTREG32(&pRegs->H2.PORTSC, *temp);
    }

    //uh2_controller_reset
    temp=(DWORD *)&cmd; 
    *temp=0;
    cmd.RST=1;  
    CLRREG32(&pRegs->H2.USBCMD, *temp);
    *temp = INREG32(&pRegs->H2.USBCMD);
    cmd.RST=1;
    OUTREG32(&pRegs->H2.USBCMD, *temp);
    while (INREG32(&pRegs->H2.USBCMD) & (0x1 << 1));

    temp = (DWORD *)&mode;
    *temp = INREG32(&pRegs->H2.USBMODE);
    mode.CM = 0x3;
    OUTREG32(&pRegs->H2.USBMODE, *temp);

    Sleep(10);
    while ((INREG32(&pRegs->H2.USBMODE)& 0x3) != 0x3);

 #ifdef H2_TEST_MODE
     // Disable async and periodic schedule
    // Disable async and periodic schedule
    temp = (DWORD *)&cmd;
    *temp = 0;
    *temp = INREG32(&pRegs->H2.USBCMD);
    *temp = *temp & ~0x30;
    OUTREG32(&pRegs->H2.USBCMD, *temp);

 
    // Go to suspend mode, please
    temp  = (DWORD *)&portsc;
    *temp = 0;
    *temp = INREG32(&pRegs->H2.PORTSC);
    *temp  |= 0x00000080;
    OUTREG32(&pRegs->H2.PORTSC, *temp);

    // Set to TEST_MODE, please
    temp  = (DWORD *)&portsc;
    *temp = 0;
    *temp = INREG32(&pRegs->H2.PORTSC);
    portsc.PTC = 0x4; // PTC = 4 -> test pattern
    OUTREG32(&pRegs->H2.PORTSC, *temp);

 
    // Set run/stop bit now
    temp = (DWORD *)&cmd;
    *temp = 0;
    *temp = INREG32(&pRegs->H2.USBCMD);
    cmd.RS = 1;
    OUTREG32(&pRegs->H2.USBCMD, *temp);

      while(1);
#endif

    return;
}

//-----------------------------------------------------------------------------
//
//  Function: ConfigOTG
//
//  This function is to configure the USB OTG Core.
//
//  Parameters:
//     pRegs - Pointer to 3 USB Core Registers
//     
//  Returns:
//     NULL
//
//-----------------------------------------------------------------------------
static void ConfigOTG(CSP_USB_REGS *pRegs, int speed)
{
   USB_PORTSC_T portsc;
   USB_CTRL_T   ctrl;
   USB_USBMODE_T mode;
   USB_USBCMD_T cmd;
   DWORD *temp;
   
   DEBUGMSG(ZONE_INIT, (__WFUNCTION__ TEXT("(0x%08X, %d)+\r\n"), pRegs, speed));
   
   // Stop the controller first
   {
      temp = (DWORD *)&cmd;
      *temp = INREG32(&pRegs->OTG.USBCMD);
      cmd.RS = 0;
      OUTREG32(&pRegs->OTG.USBCMD, *temp);
      while ((INREG32(&pRegs->OTG.USBCMD) & 0x1) == 0x1) {
         Sleep(100);
      }
   }
   
   // Do a reset first no matter what
   {
      temp = (DWORD *)&cmd;
      *temp = INREG32(&pRegs->OTG.USBCMD);
      cmd.RST = 1;
      OUTREG32(&pRegs->OTG.USBCMD, *temp);
      while ((INREG32(&pRegs->OTG.USBCMD) & (0x1<<1)) == (0x1<<1)) {
         Sleep(100);
      }
   }
   
   temp  = (DWORD *)&portsc;
   *temp = INREG32(&pRegs->OTG.PORTSC);
   if (speed == FULL_SPEED) {
      portsc.PTS = 0x3;
   }
   else {
      portsc.LS  = 0x2;
      portsc.PTS = 0x2;
   }
   OUTREG32(&pRegs->OTG.PORTSC, *temp);
   
   // usb_ulpi_interrupt_enable
   temp  = (DWORD *)&ctrl;
   *temp = INREG32(&pRegs->USB_CTRL);
   if (speed == FULL_SPEED)
      ctrl.OUIE = 0;
   else
      ctrl.OUIE = 1;
   OUTREG32(&pRegs->USB_CTRL, *temp);
   
   // usb_otg_interrupt_enable
   temp = (DWORD *)&ctrl;
   *temp = INREG32(&pRegs->USB_CTRL);
   ctrl.OWIE = 1;
   OUTREG32(&pRegs->USB_CTRL, *temp);
   
   // usb_otg_power_mask_enable
   temp = (DWORD *)&ctrl;
   *temp = INREG32(&pRegs->USB_CTRL);
   ctrl.OPM = 1;
   OUTREG32(&pRegs->USB_CTRL, *temp);
   
   // usb_otg_tll_disable
   temp = (DWORD *)&ctrl;
   *temp = INREG32(&pRegs->USB_CTRL);
   ctrl.H1DT = 1;
   OUTREG32(&pRegs->USB_CTRL, *temp);
   
   // usb_bypass_inactive
   temp = (DWORD *)&ctrl;
   *temp=0;
   ctrl.BPE=1;     //  Bypass Enable bit, clear it
   CLRREG32(&pRegs->USB_CTRL, *temp);
   
    // otg_setmode
   temp = (DWORD *)&cmd;
   *temp = INREG32(&pRegs->OTG.USBCMD);
   cmd.RST = 1;
   OUTREG32(&pRegs->OTG.USBCMD, *temp);
   
   while (INREG32(&pRegs->OTG.USBCMD)& (0x1 << 1));
   
   temp = (DWORD *)&mode;
   *temp = INREG32(&pRegs->OTG.USBMODE);
   mode.CM = 0x3;
   OUTREG32(&pRegs->OTG.USBMODE, *temp);
   
   Sleep(10);
   if ((INREG32(&pRegs->OTG.USBMODE)& 0x3) != 0x3) {
//      DEBUGMSG (1, (TEXT("USBMode setting failure\r\n")));
      return;
   }
   
   // otg_power_on_port1
   if (INREG32(&pRegs->OTG.HCSPARAMS) & (0x1 << 4)) {
      DWORD mask = (0x1<<1) + (0x1<<3) + (0x1<<5);
      CLRREG32(&pRegs->OTG.PORTSC, mask);
      temp = (DWORD *)&portsc;
      *temp = INREG32(&pRegs->OTG.PORTSC);
      portsc.PP = 1;
      OUTREG32(&pRegs->OTG.PORTSC, *temp);
   }
   else {
      DEBUGMSG (1, (TEXT("Host does not control power\r\n")));
   }
   
#ifdef OTG_TEST_MODE 
   //otg_controller_reset
   temp=(DWORD *)&cmd;
   *temp=0;
   cmd.RST=1;
   CLRREG32(&pRegs->OTG.USBCMD, *temp);
   *temp = INREG32(&pRegs->OTG.USBCMD);
   cmd.RST=1;
   OUTREG32(&pRegs->OTG.USBCMD, *temp);
   while (INREG32(&pRegs->OTG.USBCMD) & (0x1 << 1));
   
   temp = (DWORD *)&mode;
   *temp = INREG32(&pRegs->OTG.USBMODE);
   mode.CM = 0x3;
   OUTREG32(&pRegs->OTG.USBMODE, *temp);
   
   
   Sleep(10);
   while ((INREG32(&pRegs->OTG.USBMODE)& 0x3) != 0x3);
   
    // Disable async and periodic schedule
   // Disable async and periodic schedule
   temp = (DWORD *)&cmd;
   *temp = 0;
   *temp = INREG32(&pRegs->OTG.USBCMD);
   *temp = *temp & ~0x30;
   OUTREG32(&pRegs->OTG.USBCMD, *temp);
   
   
   // Go to suspend mode, please
   temp  = (DWORD *)&portsc;
   *temp = 0;
   *temp = INREG32(&pRegs->OTG.PORTSC);
   *temp  |= 0x00000080;
   OUTREG32(&pRegs->OTG.PORTSC, *temp);
   
   // Set to TEST_MODE, please
   temp  = (DWORD *)&portsc;
   *temp = 0;
   *temp = INREG32(&pRegs->OTG.PORTSC);
   portsc.PTC = 0x4; // PTC = 4 -> test pattern
   OUTREG32(&pRegs->OTG.PORTSC, *temp);
   
   // Set run/stop bit now
   temp = (DWORD *)&cmd;
   *temp = 0;
   *temp = INREG32(&pRegs->OTG.USBCMD);
   cmd.RS = 1;
   OUTREG32(&pRegs->OTG.USBCMD, *temp);
   
   while(1);
#else
   temp = (DWORD *)&cmd;
   *temp = INREG32(&pRegs->OTG.USBCMD);
   cmd.RS=0;
   OUTREG32(&pRegs->OTG.USBCMD, *temp);
   
   // Handshake to wait for Halted
   while ((INREG32(&pRegs->OTG.USBSTS) & 0x1000) != 0x1000);
#endif
   
   // Enable interrupts
   OUTREG32(&pRegs->OTG.USBINTR, 0x5ff);
   
   DEBUGMSG(ZONE_INIT, (__WFUNCTION__ TEXT("-\r\n")));
}

//-----------------------------------------------------------------------------
//
//  Function: gfnGetOTGGroup
//
//  This function is to return the OTG Group 
//
//  Parameters:
//     NULL
//     
//  Returns:
//     the OTG Group Name, that is used for creating the mode switching event semaphore
//     the value is reading from registry
//
//-----------------------------------------------------------------------------
TCHAR *gfnGetOTGGroup(void)
{
    return (gszOTGGroup);
}

//-----------------------------------------------------------------------------
//
//  Function: gfnIsOTGSupport
//
//  This function is whether to have OTG support
//
//  Parameters:
//     NULL
//     
//  Returns:
//     0 - Not OTG Support, 1 - OTG Support
//
//-----------------------------------------------------------------------------
DWORD gfnIsOTGSupport(void)
{
    return gdwOTGSupport;
}

//-----------------------------------------------------------------------------
//
//  Function: InitializeTransceiver
//
//  This function is to configure the USB Transceiver, register the interrupt
//
//  Parameters:
//     NULL
//     
//  Returns:
//     TRUE - success, FALSE - failure
//
//-----------------------------------------------------------------------------
BOOL InitializeTransceiver(PCSP_USB_REGS* regs, DWORD * phyregs, 
                           DWORD * sysintr, DWORD dwOTGSupport, TCHAR *pOTGGroup)
{
    DWORD dwRet=TRUE, speed, temp;
    int off, irq;
    WORD sel = 0;
    WORD StringSize = 0;

    StringSize = sizeof(gszOTGGroup) / sizeof(TCHAR);
    StringCchCopy(gszOTGGroup,StringSize,pOTGGroup);
    gdwOTGSupport = dwOTGSupport;

    dwRet =InitializeCPLD(&sel);
    speed=dwRet;
    gSel = sel;
   switch (gSel) {
      case 0:
         // Host 2
         gwChipSel = ULPI_CHIP_1504;
         break;
      case 2:
         // OTG
         gwChipSel = ULPI_CHIP_1504;
         break;
      case 1:
      default:
         // Host 1 or others
         gwChipSel = ULPI_CHIP_1504;
         break;
   }
    
    off=InitializeMux(dwRet, sel);  
    USBClockInit();
    
    if (speed==FULL_SPEED && sel==1) {
        ConfigH1(*regs);
        irq=IRQ_USB_HOST1;
    }
    else if (sel<2) {
        TransceiverPowerOn();
        ConfigH2(*regs);
        irq = IRQ_USB_HOST2;
    }
    else {
        ConfigOTG(*regs, speed);
        irq = IRQ_USB_OTG;      
    }


     if (irq == IRQ_USB_OTG)
        *sysintr = SYSINTR_USBOTG;
    else
        KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irq, sizeof(DWORD), sysintr, sizeof(DWORD), NULL);      
//    DEBUGMSG(1, (TEXT("InitializeTransceiver: IRQ=%d, sysIntr=%d\r\n"), irq, *sysintr));
        
    {    
        USB_CTRL_T ctrl;
        DWORD * ptemp=(DWORD *)&ctrl;
        
        *ptemp=0;
        ctrl.BPE=1;     //  Bypass Enable bit, clear it
        CLRREG32(&(*regs)->USB_CTRL, *ptemp);
    }
       
    {
        USB_USBMODE_T mode;
        DWORD * ptemp=(DWORD *)&mode;
        
        // Set USB Mode 
        *ptemp=0;
        mode.CM=3;      // Host 

 
        if (sel == 1)
            OUTREG32(&(*regs)->H1.USBMODE, *ptemp);
        else if (sel == 0)
            OUTREG32(&(*regs)->H2.USBMODE, *ptemp);
        else
            OUTREG32(&(*regs)->OTG.USBMODE, *ptemp);

	}


    // power on port
    {
        if (sel == 0)
        {
            DWORD *ptemp;
            USB_HCSPARAMS_T hcs;
            ptemp=(DWORD *)&hcs;
            *ptemp=INREG32(&(*regs)->H2.HCSPARAMS);

            if (hcs.PPC) 
            {
                USB_PORTSC_T portsc;
                DWORD * temp2= (DWORD *)&portsc;

                *temp2 = INREG32(&(*regs)->H2.PORTSC);
                portsc.PP = 1;
                SETREG32(&(*regs)->H2.PORTSC, *temp2);
            }   
        }
        else if (sel == 2)
        {
            DWORD *ptemp;
            USB_HCSPARAMS_T hcs;
            ptemp=(DWORD *)&hcs;
            *ptemp=INREG32(&(*regs)->OTG.HCSPARAMS);

            if (hcs.PPC) 
            {
                USB_PORTSC_T portsc;
                DWORD * temp2= (DWORD *)&portsc;

                *temp2 = INREG32(&(*regs)->OTG.PORTSC);
                portsc.PP = 1;
                SETREG32(&(*regs)->OTG.PORTSC, *temp2);
            }   
        }
        else if (speed==FULL_SPEED && sel==1)
        {
            DWORD *ptemp;
            USB_HCSPARAMS_T hcs;
            ptemp=(DWORD *)&hcs;
            *ptemp=INREG32(&(*regs)->H1.HCSPARAMS);

            if (hcs.PPC) 
            {
                USB_PORTSC_T portsc;
                DWORD * temp2= (DWORD *)&portsc;

                *temp2 = INREG32(&(*regs)->H1.PORTSC);
                portsc.PP = 1;
                SETREG32(&(*regs)->H1.PORTSC, *temp2);
            }   
        }

    }
    
    gRegs = (PCSP_USB_REGS)(*regs);
    gSel = sel;
        
#if 0
    if (sel==2 && speed==FULL_SPEED)
    {
        RETAILMSG(1, (L"Full Speed Transciever not implemented in this design\r\n"));
        DEBUGCHK(FALSE);
    }
    else
    {
        if (speed==FULL_SPEED)
        {
            RETAILMSG(1, (L"Full Speed Transciever not implemented in this design\r\n"));
            DEBUGCHK(FALSE);
        }
        else if (sel == 0)
        {
            DEBUGMSG(ZONE_FUNCTION, (TEXT("Initialize3317 H2 HighSpeed\r\n")));
            dwRet=Initialize3317(*regs, sel);
        }
        else
        {
            DEBUGMSG(ZONE_FUNCTION, (TEXT("Initialize1504 OTG HighSpeed\r\n")));
            dwRet=Initialize1504(*regs,sel);
        }
    }
#else
   switch (gwChipSel) {
      case ULPI_CHIP_1504:
         DEBUGMSG(ZONE_FUNCTION, (TEXT("Initialize1504 HighSpeed\r\n")));
         dwRet = Initialize1504(*regs, sel);
         break;
         
      case ULPI_CHIP_3317:
         DEBUGMSG(ZONE_FUNCTION, (TEXT("Initialize3317 HighSpeed\r\n")));
         dwRet = Initialize3317(*regs, sel);
         break;
         
      default:
         break;
   }
#endif

    temp=*(DWORD*)regs;
    temp+=off;
    *(DWORD*)regs=temp;
    *phyregs+=off;
    return dwRet;
}

//-----------------------------------------------------------------------------
//
//  Function:  BSPUsbCheckConfigPower
//
//  Check power required by specific device configuration and return whether it
//  can be supported on this platform.  For CEPC, this is trivial, just limit
//  to the 500mA requirement of USB.  For battery powered devices, this could
//  be more sophisticated, taking into account current battery status or other 
//  info.
//
// Parameters:
//      bPort
//          [in] Port number
//
//      dwCfgPower
//          [in] Power required by configuration in mA.
//
//      dwTotalPower
//          [in] Total power currently in use on port in mA.
//
// Returns:
//      Return TRUE if configuration can be supported, FALSE if not.
//
//-----------------------------------------------------------------------------
BOOL BSPUsbhCheckConfigPower(UCHAR bPort, DWORD dwCfgPower, DWORD dwTotalPower)
{
    // Remove-W4: Warning C4100 workaround
    UNREFERENCED_PARAMETER(bPort);

    return ((dwCfgPower + dwTotalPower) > 100) ? FALSE : TRUE;
}

#ifdef DISABLE_DETACH_WAKEUP
#undef DISABLE_DETACH_WAKEUP
#endif
 //-----------------------------------------------------------------------------
//
//  Function: BSPUsbSetWakeUp
//
//  This function is to enable/disable the wakeup interrupt bit in USBCONTROL
//
//  Parameters:
//     bEnable - TRUE : Enable, FALSE : Disable
//     
//  Returns:
//     NULL
//
//-----------------------------------------------------------------------------
void BSPUsbSetWakeUp(BOOL bEnable)
{
    // Access the USB Control Register
    volatile DWORD  *temp;
    USB_CTRL_T ctrl;
    USB_PORTSC_T portsc;
    CSP_USB_REG *pReg; 

    // still need to check it first before proceed
    BSPUsbCheckWakeUp();
        
    switch (gSel) 
	{
    case 0:
        pReg = (PCSP_USB_REG)(&(gRegs->H2));
        break;
    case 1:
        pReg = (PCSP_USB_REG)(&(gRegs->H1));
        break;
    
    default:
        pReg = (PCSP_USB_REG)(&(gRegs->OTG));
        break;
    }
    temp = (DWORD *)&portsc;
    *temp = INREG32(&pReg->PORTSC[0]);
    // If Current Connect Status = 1, we should not set WKCN or it would 
    // wake up right away.  With this we can enable wake up on attach
    if ((bEnable) && (portsc.CCS == 0))
    {
        portsc.WKCN = 1;
        portsc.WKOC = 1;
        portsc.WKDC = 0;        
    }
    else
    {
        portsc.WKOC = 0;
        portsc.WKDC = 0;
        portsc.WKCN = 0;
    }
    OUTREG32(&pReg->PORTSC[0], *temp);
    
    temp = (DWORD *)&ctrl;
#ifdef DISABLE_DETACH_WAKEUP
    if (bEnable)
#else
    if ((bEnable) && (portsc.CCS == 0))
#endif
        *temp = INREG32(&gRegs->USB_CTRL);
    else
        *temp = 0;

    switch (gSel)
	{
    case 0:     
        ctrl.H2WIE = 1;
        ctrl.H2UIE = 1;
        break;
    case 1:
        ctrl.H1WIE = 1;     
        break;
    case 2:
        ctrl.OWIE = 1;
        ctrl.OUIE = 1;
        break;
    default:
        break;
    }

#ifdef DISABLE_DETACH_WAKEUP
    if (bEnable)
#else
    if ((bEnable) && (portsc.CCS == 0))
#endif
        SETREG32(&gRegs->USB_CTRL, *temp);
    else
        CLRREG32(&gRegs->USB_CTRL, *temp);

     return;
}

//-----------------------------------------------------------------------------
//
//  Function: BSPUsbCheckWakeUp
//
//  This function is called by CSP to clear the wakeup interrupt bit in USBCONTROL. According to
//  MX31 specification, disable the wake-up enable bit also clear the interrupt request bit.
//  This wake-up interrupt enable should be disable after receiving a wakeup request.
//
//  Parameters:
//     NULL
//     
//  Returns:
//     TRUE - there is a wakeup.  FALSE - no wakeup is set.
//
//-----------------------------------------------------------------------------

BOOL BSPUsbCheckWakeUp(void)
{
    // Access the USB Control Register
    volatile DWORD  *temp;
    USB_CTRL_T ctrl;
    BOOL fWakeUp = FALSE;

    temp = (DWORD *)&ctrl;
    *temp = INREG32(&gRegs->USB_CTRL);

 
    switch (gSel) {
    case 0:
        if (ctrl.H2WIR == 1)
        {
            *temp = 0;
            fWakeUp = TRUE;
            ctrl.H2WIE = 1;
        }
        break;
    case 1:
        if (ctrl.H1WIR == 1)
        {
            *temp = 0;
            fWakeUp = TRUE;
            ctrl.H1WIE = 1;
        }
        break;
    case 2:
        if (ctrl.OWIR == 1)
        {
            *temp = 0;
            fWakeUp = TRUE;
            ctrl.OWIE = 1;
        }
        break;
    default:
        break;
    }

    if (fWakeUp)
        CLRREG32(&gRegs->USB_CTRL, *temp);  

     return fWakeUp;
}


