📄 bul_ohci.cpp
字号:
)
{
switch(Mode) {
case XLLP_USBOHCI_PPM_NPS:
// set NO Power Switching mode
m_pDCUSBOHCIReg->uhcrhda |= XLLP_USBOHCI_UHCRHDA_NPS;
break;
case XLLP_USBOHCI_PPM_GLOBAL:
// make sure the NO Power Switching mode bit is OFF so Power Switching can occur
// make sure the PSM bit is CLEAR, which allows all ports to be controlled with
// the GLOBAL set and clear power commands
m_pDCUSBOHCIReg->uhcrhda &= ~(XLLP_USBOHCI_UHCRHDA_NPS|XLLP_USBOHCI_UHCRHDA_PSM_PERPORT);
break;
case XLLP_USBOHCI_PPM_PERPORT:
// make sure the NO Power Switching mode bit is OFF so Power Switching can occur
// make sure the PSM bit is SET, which allows all ports to be controlled with
// the PER PORT set and clear power commands
m_pDCUSBOHCIReg->uhcrhda &= ~XLLP_USBOHCI_UHCRHDA_NPS;
m_pDCUSBOHCIReg->uhcrhda |= XLLP_USBOHCI_UHCRHDA_PSM_PERPORT;
// set the power management mode for each individual port to Per Port.
{
int p;
for( p = 0; p < NumPorts; p++ ) {
m_pDCUSBOHCIReg->uhcrhdb |= (unsigned int)( 1u << (p+17) ); // port 1 begins at bit 17
}
}
break;
case XLLP_USBOHCI_PPM_MIXED:
// make sure the NO Power Switching mode bit is OFF so Power Switching can occur
// make sure the PSM bit is SET, which allows all ports to be controlled with
// the PER PORT set and clear power commands
m_pDCUSBOHCIReg->uhcrhda &= ~XLLP_USBOHCI_UHCRHDA_NPS;
m_pDCUSBOHCIReg->uhcrhda |= XLLP_USBOHCI_UHCRHDA_PSM_PERPORT;
// set the power management mode for each individual port to Per Port.
// if the value in the PortMode array is non-zero, set Per Port mode for the port.
// if the value in the PortMode array is zero, set Global mode for the port
{
int p;
for( p = 0; p < NumPorts; p++ ) {
if( PortMode[p] ) {
m_pDCUSBOHCIReg->uhcrhdb |= (unsigned int)( 1u << (p+17) ); // port 1 begins at bit 17
}
else {
m_pDCUSBOHCIReg->uhcrhdb &= ~(unsigned int)( 1u << (p+17) ); // port 1 begins at bit 17
}
}
}
break;
}
}
// Manage WinCE suspend/resume events
DWORD SOhcdPdd::InitiatePowerUp()
{
DEBUGMSG(ZONE_INIT,(TEXT("SOhcdPdd::InitiatePowerUp: m_pDCUSBOHCIReg: %08x.\r\n"), m_pDCUSBOHCIReg));
TurnOnUSBHostClocks(); // make sure the ohci block is running (eg. getting clocked)
// Port 1
SetupUSBHostPWR(1); // this sets up Pwr 1 notification using gpio 88 as input in alternate function 1 mode
SetupUSBHostPEN(1); // this sets up Pwr 1 enable using gpio 89 as output in alternate function 2 mode
// Port 2
SetupUSBHostPWR(2); // this sets up Pwr 2 notification using gpio 88 as input in alternate function 1 mode
SetupUSBHostPEN(2); // this sets up Pwr 2 enable using gpio 89 as output in alternate function 2 mode
//TurnOnUSBHostPorts(); // probably only do this after the rest of the ohci is set up.
//TestUSBHostPEN(0);
SelectUSBHOSTPowerManagementMode( XLLP_USBOHCI_PPM_NPS, 0, 0 );
OHCI_Reset();
return 0;
}
void SOhcdPdd::PowerUp()
{
HcdMdd_PowerUp(m_pobOhcd);
}
void SOhcdPdd::PowerDown()
{
// let the MDD do its processing (including putting the HC into reset)
HcdMdd_PowerDown(m_pobOhcd);
// disable the USB port as described in section 6.1.4.4 of the SA-1111 companion
// chip documentation:
// (1) Reset HC (done by MDD)
// (2) wait 10 us
// (3) clear global power enable bit
// (4) set the standby enable bit
// (5) stop the usb clock
//usWait(10); // must not block or do operations illegal in interrupt context
m_pDCUSBOHCIReg->uhcrhda &= ~ ((1 << 8) | (1 << 9)); // set global power switch mode
m_pDCUSBOHCIReg->uhcrhs |= 0x0001; // clear global power
};
/* HcdPdd_DllMain
*
* DLL Entry point.
*
* Return Value:
*/
extern "C" BOOL HcdPdd_DllMain(HANDLE /*hinstDLL*/, DWORD /*dwReason*/, LPVOID /*lpvReserved*/)
{
return TRUE;
}
// This gets called by the MDD's IST when it detects a power resume.
extern "C" void HcdPdd_InitiatePowerUp (DWORD hDeviceContext)
{
SOhcdPdd * pPddObject = (SOhcdPdd *)hDeviceContext;
if (pPddObject)
pPddObject->InitiatePowerUp();
return;
}
/* HcdPdd_Init
*
* PDD Entry point - called at system init to detect and configure UHCI card.
*
* Return Value:
* Return pointer to PDD specific data structure, or NULL if error.
*/
extern "C" DWORD
HcdPdd_Init(
DWORD dwContext) // IN - Pointer to context value. For device.exe, this is a string
// indicating our active registry key.
{
SOhcdPdd * pPddObject = CreateBulverdeOhci((LPCTSTR)dwContext);
if (pPddObject && pPddObject->Init()) {
DEBUGMSG(ZONE_INIT, (TEXT("HcdPdd_Init: Checking SW18 - controls OHCI loading.\r\n")));
return (DWORD) pPddObject ;
}
if (pPddObject)
delete pPddObject;
return (DWORD)NULL;
}
/* HcdPdd_CheckConfigPower
*
* 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.
*
* Return Value:
* Return TRUE if configuration can be supported, FALSE if not.
*/
extern "C" BOOL HcdPdd_CheckConfigPower(
UCHAR bPort, // IN - Port number
DWORD dwCfgPower, // IN - Power required by configuration
DWORD dwTotalPower) // IN - Total power currently in use on port
{
return ((dwCfgPower + dwTotalPower) > 500) ? FALSE : TRUE;
}
extern "C" void HcdPdd_PowerUp(DWORD hDeviceContext)
{
SOhcdPdd * pPddObject = (SOhcdPdd *)hDeviceContext;
DEBUGMSG(ZONE_INIT, (TEXT("HcdPdd_PowerUp: enter.\n\r")));
if (pPddObject)
pPddObject->PowerUp();
DEBUGMSG(ZONE_INIT, (TEXT("HcdPdd_PowerUp: Need to add Bulverde support.\n\r")));
return;
}
extern "C" void HcdPdd_PowerDown(DWORD hDeviceContext)
{
SOhcdPdd * pPddObject = (SOhcdPdd *)hDeviceContext;
DEBUGMSG(ZONE_INIT, (TEXT("HcdPdd_PowerDown: enter.\n\r")));
if (pPddObject)
pPddObject->PowerDown();
DEBUGMSG(ZONE_INIT, (TEXT("HcdPdd_PowerDown: Need to add Bulverde support.\n\r")));
return;
}
extern "C" BOOL HcdPdd_Deinit(DWORD hDeviceContext)
{
SOhcdPdd * pPddObject = (SOhcdPdd *)hDeviceContext;
if (pPddObject)
delete pPddObject;
return TRUE;
}
extern "C" DWORD HcdPdd_Open(DWORD /*hDeviceContext*/, DWORD /*AccessCode*/,
DWORD /*ShareMode*/)
{
return 1; // we can be opened, but only once!
}
extern "C" BOOL HcdPdd_Close(DWORD /*hOpenContext*/)
{
return TRUE;
}
extern "C" DWORD HcdPdd_Read(DWORD /*hOpenContext*/, LPVOID /*pBuffer*/, DWORD /*Count*/)
{
return (DWORD)-1; // an error occured
}
extern "C" DWORD HcdPdd_Write(DWORD /*hOpenContext*/, LPCVOID /*pSourceBytes*/,
DWORD /*NumberOfBytes*/)
{
return (DWORD)-1;
}
extern "C" DWORD HcdPdd_Seek(DWORD /*hOpenContext*/, LONG /*Amount*/, DWORD /*Type*/)
{
return (DWORD)-1;
}
extern "C" BOOL HcdPdd_IOControl(DWORD /*hOpenContext*/, DWORD /*dwCode*/, PBYTE /*pBufIn*/,
DWORD /*dwLenIn*/, PBYTE /*pBufOut*/, DWORD /*dwLenOut*/, PDWORD /*pdwActualOut*/)
{
return FALSE;
}
#include <COhcd.hpp>
class CBulverdeOhcd : public COhcd {
public:
CBulverdeOhcd ( IN LPVOID pvOhcdPddObject,
IN CPhysMem * pCPhysMem,
IN LPCWSTR szDriverRegistryKey,
IN REGISTER portBase,
IN DWORD dwSysIntr)
: COhcd(pvOhcdPddObject,pCPhysMem,szDriverRegistryKey,portBase,dwSysIntr)
{ ; }
//
// Root Hub Queries
//
virtual UCHAR GetNumberOfDownStreamPort() {
return (COhcd::GetNumberOfDownStreamPort()+1) ;
}
//
// Load "HcdCapability" value from the registry key
//
virtual void LoadHcdCapability( IN LPCWSTR szDriverRegistryKey) {
LONG regError;
DWORD dwDataSize;
HKEY hKey = NULL;
DWORD dwHcdCapability=0;
// Open the driver registry key
regError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,szDriverRegistryKey,0,KEY_ALL_ACCESS,&hKey);
if (regError != ERROR_SUCCESS)
{
DEBUGMSG(ZONE_INIT,(TEXT("CBulverdeOhcd:LoadHcdCapability:: Failed opening HKLM\\%s \r\n"), szDriverRegistryKey));
hKey = NULL;
}
// Get "HcdCapability"
if (hKey)
{
dwDataSize = sizeof(dwHcdCapability);
regError = RegQueryValueEx(hKey,HCD_CAPABILITY_VALNAME,NULL,NULL,(LPBYTE)&dwHcdCapability,&dwDataSize);
if (regError == ERROR_SUCCESS)
{
this->SetCapability(dwHcdCapability);
}
else
{
DEBUGMSG(ZONE_INIT,(TEXT("CBulverdeOhcd:LoadHcdCapability:: Failed opening HKLM\\%s\\%s \r\n"), szDriverRegistryKey,HCD_CAPABILITY_VALNAME));
}
}
RegCloseKey (hKey);
}
};
LPVOID CreateBulverdeHcdObject (LPVOID lpvHcdPddObject,
LPVOID lpvMemoryObject, LPCWSTR szRegKey, PUCHAR ioPortBase,
DWORD dwSysIntr)
{
CHcd * pobHcd = new CBulverdeOhcd (lpvHcdPddObject, (CPhysMem *)lpvMemoryObject,szRegKey,ioPortBase,dwSysIntr) ;
if ( pobHcd != NULL ) {
((CBulverdeOhcd*)pobHcd)->LoadHcdCapability(szRegKey);
if ( !pobHcd->DeviceInitialize( )) {
delete pobHcd;
pobHcd = NULL;
}
}
return pobHcd;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -