//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
#include <windows.h>
#include <nkintr.h>
#include <ddkreg.h>
#include <S3C6400.h>
#include <DrvLib.h>
#include "s3c6400otgdevice.h"
#include <Bsp.h>
static volatile BSP_ARGS *v_gBspArgs;
static BOOL UsbpulgIn=FALSE;
#define CARD_INSERTED 1
#define CARD_REMOVED 2
#define UDC_REG_PRIORITY_VAL _T("Priority256")
//#define _CHANDOLP
enum EP0_STATE {
EP0_STATE_IDLE = 0,
EP0_STATE_IN_DATA_PHASE,
EP0_STATE_OUT_DATA_PHASE
};
typedef enum
{
USB_HIGH, USB_FULL, USB_LOW
} USB_SPEED;
#define IN_TRANSFER 1
#define OUT_TRANSFER 2
#define EP0_STALL_BITS (EP0_SEND_STALL | EP0_SENT_STALL)
typedef struct EP_STATUS {
DWORD dwEndpointNumber;
DWORD dwDirectionAssigned;
DWORD dwPacketSizeAssigned;
BOOL fInitialized;
DWORD dwEndpointType;
PSTransfer pTransfer;
CRITICAL_SECTION cs;
} *PEP_STATUS;
#define LOCK_ENDPOINT(peps) EnterCriticalSection(&peps->cs)
#define UNLOCK_ENDPOINT(peps) LeaveCriticalSection(&peps->cs)
#define EP_0_PACKET_SIZE 0x40 // USB2.0
#define ENDPOINT_COUNT 16
#define EP_VALID(x) ((x) < ENDPOINT_COUNT)
#define DEFAULT_PRIORITY 120
// GOTGCTL
#define B_SESSION_VALID (0x1<<19)
#define A_SESSION_VALID (0x1<<18)
// GRX STATUS
#define PKTSTS (0xF<<17)
#define GLOBAL_OUT_NAK (0x1<<17)
#define OUT_PKT_RECEIVED (0x2<<17)
#define OUT_TRF_COMPLETED (0x3<<17)
#define SETUP_TRANS_COMPLETED (0x4<<17)
#define SETUP_PKT_RECEIVED (0x6<<17)
#define SETUPPHASEDONE (0x1<<3) //Setup Phase Done Interrupt
#define XFERCOPMPL (0x1<<0) //Transfer Complete Interrupt
// DIEPCTL0/DOEPCTL0 device control IN/OUT endpoint 0 control register
#define DEPCTL_SNAK (0x1<<27)
#define DEPCTL_CNAK (0x1<<26)
//DIEPINT
#define IN_TKN_RECEIVED (0x1<<4)
#define TIMEOUT_CONDITION (0x1<<3)
#define IN_EP 0
#define OUT_EP 1
// DCTL
#define SOFT_DISCONNECT (0x1<<1)
#define CLEAR_GOUTNAK (0x1<<10)
#define SET_GOUTNAK (0x1<<9)
#define CLEAR_GNPINNAK (0x1<<8)
#define SET_GNINNAK (0x1<<7)
extern "C"
{
void RxData512(unsigned char *bufPt, volatile ULONG *FifoPt);
void TxData512(unsigned char *bufPt, volatile ULONG *FifoPt);
}
extern BOOL USBCurrentDriver(PUFN_CLIENT_INFO pDriverList);
typedef struct CTRL_PDD_CONTEXT {
volatile OTG_PHY_REG * pOTGPhyregs;
volatile S3C6400_SYSCON_REG * pSYSCONregs;
PVOID pvMddContext;
DWORD dwSig;
HANDLE hIST;
HANDLE hevInterrupt;
BOOL fRunning;
CRITICAL_SECTION csRegisterAccess;
BOOL fSpeedReported;
BOOL fRestartIST;
BOOL fExitIST;
BOOL attachedState;
BOOL sendDataEnd;
BOOL FirstCall;
BOOL IsFirstReset;
EP0_STATE Ep0State;
// new value in 6400 otg
USB_SPEED eSpeed;
DWORD dwEp0MaxPktSize;
// 6400 flag
BOOL fSetUpPhaseDone;
DWORD CntValue;
DWORD dwDetectedSpeed;
// registry
DWORD dwSysIntr;
DWORD dwIrq;
DWORD dwISTPriority;
USB_DEVICE_REQUEST udr;
EP_STATUS rgEpStatus[ENDPOINT_COUNT];
PFN_UFN_MDD_NOTIFY pfnNotify;
HANDLE hBusAccess;
CEDEVICE_POWER_STATE cpsCurrent;
HANDLE BootCompleteEvent;
DWORD USBClassInfo;
} *PCTRLR_PDD_CONTEXT;
#define SC6400_SIG '6400' // "S3C6400" signature
#define IS_VALID_SC6400_CONTEXT(ptr) \
( (ptr != NULL) && (ptr->dwSig == SC6400_SIG) )
#ifdef DEBUG
#define ZONE_POWER DEBUGZONE(8)
UFN_GENERATE_DPCURSETTINGS(UFN_DEFAULT_DPCURSETTINGS_NAME,
_T("Power"), _T(""), _T(""), _T(""),
DBG_ERROR | DBG_INIT);
// Caution: Turning on more debug zones can cause STALLs due
// to corrupted setup packets.
// Validate the context.
static
VOID
ValidateContext(
PCTRLR_PDD_CONTEXT pContext
)
{
PREFAST_DEBUGCHK(pContext);
DEBUGCHK(pContext->dwSig == SC6400_SIG);
DEBUGCHK(!pContext->hevInterrupt || pContext->hIST);
DEBUGCHK(VALID_DX(pContext->cpsCurrent));
DEBUGCHK(pContext->pfnNotify);
}
#else
#define ValidateContext(ptr)
#endif
volatile BYTE *g_pUDCBase;
#define USB_RNDIS 0
#define USB_Serial 1
#define USB_MSF 2
#define CTRLR_BASE_REG_ADDR(offset) ((volatile ULONG*) ( (g_pUDCBase) + (offset)))
#define DRIVER_USB_KEY TEXT("Drivers\\USB\\FunctionDrivers")
#define DRIVER_USB_VALUE TEXT("DefaultClientDriver")
#define DRIVER_USB_MSF_CARD_KEY TEXT("Drivers\\USB\\FunctionDrivers\\Mass_Storage_Class")
#define DRIVER_USB_MSF_CARD_VALUE TEXT("DeviceName")
#define DRIVER_USB_MSF_MMC_KEY TEXT("Drivers\\SDCARD\\ClientDrivers\\Class\\MMC_Class")
#define DRIVER_USB_MSF_MMC_VALUE TEXT("Index")
#define DRIVER_USB_MSF_SD_KEY TEXT("Drivers\\SDCARD\\ClientDrivers\\Class\\SDMemory_Class")
#define DRIVER_USB_MSF_SD_VALUE TEXT("Index")
#define DRIVER_USB_MSF_SDHC_KEY TEXT("Drivers\\SDCARD\\ClientDrivers\\Class\\SDMemory_Class\\High_Capacity")
#define DRIVER_USB_MSF_SDHC_VALUE TEXT("Index")
#define DRIVER_USB_MSF_FLASH_KEY TEXT("Drivers\\BuiltIn\\NANDFLASH")
#define DRIVER_USB_MSF_FLASH_VALUE TEXT("Index")
HANDLE g_SdCardDetectThread;
BOOL HW_USBClocks(
PCTRLR_PDD_CONTEXT pContext,
CEDEVICE_POWER_STATE cpsNew);
static DWORD SDCARD_DetectIST();
DWORD bSDMMCMSF = FALSE;
#define HIGH 1
#define FULL 0
#define POWER_THREAD_PRIORITY 101
static void Delay(UINT32 count)
{
volatile int i, j = 0;
volatile static int loop = S3C6400_FCLK/100000; // mod by shin.0313
for(;count > 0;count--)
for(i=0;i < loop; i++) { j++; }
}
// Read a register.
inline
DWORD
ReadReg(
PCTRLR_PDD_CONTEXT pContext,
DWORD dwOffset
)
{
DEBUGCHK(IS_VALID_SC6400_CONTEXT(pContext));
volatile ULONG *pbReg = CTRLR_BASE_REG_ADDR(dwOffset);
DWORD bValue = (DWORD) *pbReg;
return bValue;
}
// Write a register.
inline
VOID
WriteReg(
PCTRLR_PDD_CONTEXT pContext,
DWORD dwOffset,
DWORD bValue
)
{
DEBUGCHK(IS_VALID_SC6400_CONTEXT(pContext));
volatile ULONG *pbReg = CTRLR_BASE_REG_ADDR(dwOffset);
*pbReg = (ULONG) bValue;
}
// Calling with dwMask = 0 and SET reads and writes the contents unchanged.
inline
DWORD
SetClearReg(
PCTRLR_PDD_CONTEXT pContext,
DWORD dwOffset,
DWORD dwMask,
BOOL bSet
)
{
DEBUGCHK(IS_VALID_SC6400_CONTEXT(pContext));
volatile ULONG *pbReg = CTRLR_BASE_REG_ADDR(dwOffset);
volatile DWORD bValue = (DWORD) *pbReg;
if (bSet)
{
bValue |= dwMask;
}
else
{
bValue &= ~dwMask;
}
*pbReg = bValue;
return bValue;
}
// Calling with dwMask = 0 and SET reads and writes the contents unchanged.
inline
int
SetClearSpecificReg(
PCTRLR_PDD_CONTEXT pContext,
DWORD dwEndpoint,
DWORD dwOffset,
int dwMask,
BOOL bSet
)
{
DEBUGCHK(IS_VALID_SC6400_CONTEXT(pContext));
int bValue = 0;
EnterCriticalSection(&pContext->csRegisterAccess);
// Write the EP number to the index reg
// Now Write the Register associated
评论0