📄 hdq.c
字号:
{
Sleep(10);
if( INREG32(&pDevice->pHDQRegs->ulHDQ_SYSSTATUS) & HDQ_SYSSTATUS_RESETDONE)
break;
};
if(i>=50)
DEBUGMSG(ZONE_HDQ_1WIRE, (L"\tHDQ_Init: "
L"Reset of OMAP HDQ module failed !!\r\n"
));
else
DEBUGMSG(ZONE_HDQ_1WIRE, (L"\tHDQ_Init: "
L"Reset of OMAP HDQ module done. Dur=%ld\r\n", i*10
));
*/
// set the HDQ mode of operation - it is the default for OMAP HDQ, but must be sure
CLRREG32(&pDevice->pHDQRegs->ulHDQ_CTRL_STATUS,HDQ_CTRL_STATUS_1_WIRE_SINGLE_BIT);
// Enable the clock and set the mode
SETREG32(&pDevice->pHDQRegs->ulHDQ_CTRL_STATUS, HDQ_CTRL_STATUS_CLOCKENABLE);
CLRREG32(&pDevice->pHDQRegs->ulHDQ_CTRL_STATUS, HDQ_CTRL_STATUS_MODE);
pDevice->mode=HDQ_MODE_HDQ8;
// Clear and enable interrupts
INREG32(&pDevice->pHDQRegs->ulHDQ_INT_STATUS);
SETREG32(&pDevice->pHDQRegs->ulHDQ_CTRL_STATUS, HDQ_CTRL_STATUS_INTERRUPTMASK);
// Set hardware to power-off
SetDevicePowerState(pDevice->hParentBus, D4, NULL);
// Return non-null value - hdq init completed successfully
rc=(DWORD)pDevice;
// sr dump hdq registers
bDumpOmapHdqRegs(pDevice);
cleanUp:
if(rc==0)
{
HDQ_Deinit((DWORD)pDevice);
};
DEBUGMSG(ZONE_HDQ_1WIRE | ZONE_FUNCTION, (L"---HDQ_Init(rc=0x%x) and HDQ power is OFF now.\r\n", rc));
return rc;
}
BOOL bDumpOmapHdqRegs(HDQ_DEVICE* const pDevice)
{
DWORD dwReg=0;
DEBUGMSG(ZONE_INFO, (L"+++bDumpOmapHdqRegs()\r\n- - - - - - Hdq Registers - - - - - - - -\r\n"));
dwReg=INREG32(&pDevice->pHDQRegs->ulHDQ_REVISION);
DEBUGMSG(ZONE_INFO, (L"\tHDQ_REVISION=%08lXh\r\n",dwReg));
dwReg=INREG32(&pDevice->pHDQRegs->ulHDQ_TX_DATA);
DEBUGMSG(ZONE_INFO, (L"\tHDQ_TX_DATA=%08lXh\r\n",dwReg));
dwReg=INREG32(&pDevice->pHDQRegs->ulHDQ_RX_DATA);
DEBUGMSG(ZONE_INFO, (L"\tHDQ_RX_DATA=%08lXh\r\n",dwReg));
dwReg=INREG32(&pDevice->pHDQRegs->ulHDQ_CTRL_STATUS);
DEBUGMSG(ZONE_INFO, (L"\tHDQ_CTRL_STATUS=%08lXh\r\n",dwReg));
dwReg=INREG32(&pDevice->pHDQRegs->ulHDQ_INT_STATUS);
DEBUGMSG(ZONE_INFO, (L"\tHDQ_INT_STATUS=%08lXh\r\n",dwReg));
dwReg=INREG32(&pDevice->pHDQRegs->ulHDQ_SYSCONFIG);
DEBUGMSG(ZONE_INFO, (L"\tHDQ_SYSCONFIG=%08lXh\r\n",dwReg));
dwReg=INREG32(&pDevice->pHDQRegs->ulHDQ_SYSSTATUS);
DEBUGMSG(ZONE_INFO, (L"\tHDQ_SYSSTATUS=%08lXh\r\n",dwReg));
DEBUGMSG(ZONE_INFO, (L"---bDumpOmapHdqRegs()\r\n"));
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: HDQ_Deinit
//
// Called by device manager to uninitialize device.
//
BOOL HDQ_Deinit(DWORD context)
{
BOOL rc=FALSE;
HDQ_DEVICE* pDevice=(HDQ_DEVICE*)context;
DEBUGMSG(ZONE_HDQ_1WIRE | ZONE_FUNCTION, (L"+HDQ_Deinit(0x%08x)\r\n", context));
// Check if we get correct context
if(pDevice == NULL || pDevice->cookie != HDQ_DEVICE_COOKIE)
{
DEBUGMSG(ZONE_ERROR, (L"ERROR: HDQ_Deinit: "
L"Incorrect context paramer\r\n"));
goto cleanUp;
};
// Disable and clear the interrupt
CLRREG32(&pDevice->pHDQRegs->ulHDQ_CTRL_STATUS, HDQ_CTRL_STATUS_INTERRUPTMASK);
INREG32(&pDevice->pHDQRegs->ulHDQ_INT_STATUS);
// Set hardware to D4 and close parent bus driver
if(pDevice->hParentBus!=NULL)
{
SetDevicePowerState(pDevice->hParentBus, D4, NULL);
CloseBusAccessHandle(pDevice->hParentBus);
};
// Delete critical section
DeleteCriticalSection(&pDevice->cs);
// Unmap PRCM controller registers
if(pDevice->pPRCMRegs!=NULL)
{
MmUnmapIoSpace((VOID*)pDevice->pPRCMRegs, sizeof(OMAP2420_PRCM_REGS));
};
// Unmap HDQ_1Wire controller registers
if(pDevice->pHDQRegs != NULL)
{
MmUnmapIoSpace((VOID*)pDevice->pHDQRegs, pDevice->memLen);
};
// Release HDQ_1Wire controller interrupt
if(pDevice->sysIntr != 0)
{
InterruptDisable(pDevice->sysIntr);
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &pDevice->sysIntr,sizeof(pDevice->sysIntr), NULL, 0, NULL);
};
// Close interrupt handler
if(pDevice->hIntrEvent!=NULL)
{
CloseHandle(pDevice->hIntrEvent);
};
// Free device structure
LocalFree(pDevice);
// Done
rc=TRUE;
cleanUp:
DEBUGMSG(ZONE_HDQ_1WIRE | ZONE_FUNCTION, (L"---HDQ_Deinit(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
//
// Function: HDQ_Open
//
// Called by device manager to open a device for reading and/or writing.
//
DWORD HDQ_Open(DWORD context, DWORD accessCode, DWORD shareMode)
{
DWORD rc=(DWORD)-1;
HDQ_DEVICE* pDevice=(HDQ_DEVICE*)context;
DEBUGMSG(ZONE_HDQ_1WIRE | ZONE_FUNCTION, (L"+++HDQ_Open(0x%08x, 0x%08x, 0x%08x\r\n", context, accessCode, shareMode));
// Check if we get correct context
if(pDevice==NULL || pDevice->cookie!=HDQ_DEVICE_COOKIE)
{
DEBUGMSG(ZONE_ERROR, (L"ERROR: HDQ_Open: "
L"Incorrect context paramer\r\n"));
goto cleanUp;
};
// Return device context
rc=context;
cleanUp:
DEBUGMSG(ZONE_HDQ_1WIRE | ZONE_FUNCTION, (L"---HDQ_Open()\r\n"));
return context;
}
//------------------------------------------------------------------------------
//
// Function: HDQ_Close
//
// This function closes the device context.
//
BOOL HDQ_Close(DWORD context)
{
BOOL rc=FALSE;
HDQ_DEVICE* pDevice=(HDQ_DEVICE*)context;
DEBUGMSG(ZONE_HDQ_1WIRE | ZONE_FUNCTION, (L"+++HDQ_Close(0x%08x)\r\n", context));
// Check if we get correct context
if(pDevice==NULL || pDevice->cookie!=HDQ_DEVICE_COOKIE)
{
DEBUGMSG(ZONE_ERROR, (L"ERROR: HDQ_Close: "
L"Incorrect context paramer\r\n"));
goto cleanUp;
};
// Done
rc=TRUE;
cleanUp:
DEBUGMSG(ZONE_HDQ_1WIRE | ZONE_FUNCTION, (L"---HDQ_Close(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
//
// Function: HDQ_IOControl
//
// This function sends a command to a device.
//
BOOL HDQ_IOControl(DWORD context, DWORD code, BYTE *pInBuffer, DWORD inSize, BYTE *pOutBuffer, DWORD outSize, DWORD *pOutSize)
{
BOOL rc=FALSE;
HDQ_DEVICE* pDevice=(HDQ_DEVICE*)context;
DEVICE_IFC_HDQ ifc;
DEBUGMSG(ZONE_HDQ_1WIRE | ZONE_FUNCTION, (L"+++HDQ_IOControl(0x%08x, 0x%08x, 0x%08x, %d, 0x%08x, %d, 0x%08x)\r\n",
context, code, pInBuffer, inSize, pOutBuffer, outSize, pOutSize));
// Check if we get correct context
if(pDevice==NULL || pDevice->cookie!=HDQ_DEVICE_COOKIE)
{
DEBUGMSG(ZONE_ERROR, (L"ERROR: HDQ_IOControl: "
L"Incorrect context paramer\r\n"));
goto cleanUp;
};
switch (code)
{
case IOCTL_DDK_GET_DRIVER_IFC:
// We can give interface only to our peer in device process
if(GetCurrentProcessId()!=(DWORD)GetCallerProcess())
{
DEBUGMSG(ZONE_ERROR, (L"ERROR: HDQ_IOControl: IOCTL_DDK_GET_DRIVER_IFC can be called only from "
L"device process (caller process id 0x%08x)\r\n", GetCallerProcess()));
SetLastError(ERROR_ACCESS_DENIED);
break;
}
if(pInBuffer==NULL || inSize < sizeof(GUID))
{
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
if(IsEqualGUID(pInBuffer, &DEVICE_IFC_HDQ_GUID))
{
if(pOutSize!=NULL)
{
*pOutSize=sizeof(DEVICE_IFC_HDQ);
}
if(pOutBuffer==NULL || outSize < sizeof(DEVICE_IFC_HDQ))
{
SetLastError(ERROR_INVALID_PARAMETER);
break;
}
ifc.context=context;
ifc.pfnWrite=HDQ_Write;
ifc.pfnRead=HDQ_Read;
ifc.pfnSetMode=HDQ_SetMode;
if(!CeSafeCopyMemory(pOutBuffer, &ifc, sizeof(DEVICE_IFC_HDQ)))
{
SetLastError(ERROR_INVALID_PARAMETER);
break;
}
rc=TRUE;
break;
};
SetLastError(ERROR_INVALID_PARAMETER);
break;
default:
DEBUGMSG(ZONE_WARN, (L"WARN: HDQ_IOControl: "
L"Unsupported code 0x%08x\r\n", code));
SetLastError(ERROR_INVALID_PARAMETER);
break;
};
cleanUp:
DEBUGMSG(ZONE_HDQ_1WIRE | ZONE_FUNCTION, (L"---HDQ_IOControl(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
//
// Function: HDQ_PowerUp
//
// This function restores power to a device.
//
VOID HDQ_PowerUp(DWORD context)
{
HDQ_DEVICE* pDevice=(HDQ_DEVICE*)context;
DWORD dwRegValue=0;
DWORD cbRet=0;
// enable the HDQ clocks
#if 0
SETREG32(&pDevice->pPRCMRegs->ulCM_FCLKEN1_CORE, PRCM_FCLKEN1_CORE_EN_HDQ);
SETREG32(&pDevice->pPRCMRegs->ulCM_ICLKEN1_CORE, PRCM_ICLKEN1_CORE_EN_HDQ);
#else
// Enable the 1WIRE functional and interface clocks.
dwRegValue=PRCM_FCLKEN1_CORE_EN_HDQ;
KernelIoControl(IOCTL_FCLK1_ENB, (VOID*)&dwRegValue, sizeof(DWORD), NULL, 0, &cbRet);
dwRegValue=PRCM_ICLKEN1_CORE_EN_HDQ;
KernelIoControl(IOCTL_ICLK1_ENB, (VOID*)&dwRegValue, sizeof(DWORD), NULL, 0, &cbRet);
#endif
// enable the HDQ
SETREG32(&pDevice->pHDQRegs->ulHDQ_CTRL_STATUS, HDQ_CTRL_STATUS_CLOCKENABLE);
// clear and enable interrupts
INREG32(&pDevice->pHDQRegs->ulHDQ_INT_STATUS);
SETREG32(&pDevice->pHDQRegs->ulHDQ_CTRL_STATUS, HDQ_CTRL_STATUS_INTERRUPTMASK);
}
//------------------------------------------------------------------------------
//
// Function: HDQ_PowerDown
//
// This function suspends power to the device.
//
void HDQ_PowerDown(DWORD context)
{
HDQ_DEVICE* pDevice=(HDQ_DEVICE*)context;
DWORD dwRegValue=0;
DWORD cbRet=0;
// disable and clear interrupts
CLRREG32(&pDevice->pHDQRegs->ulHDQ_CTRL_STATUS, HDQ_CTRL_STATUS_INTERRUPTMASK);
INREG32(&pDevice->pHDQRegs->ulHDQ_INT_STATUS);
// disable the HDQ
CLRREG32(&pDevice->pHDQRegs->ulHDQ_CTRL_STATUS, HDQ_CTRL_STATUS_CLOCKENABLE);
// disable the HDQ clocks
#if 0
CLRREG32(&pDevice->pPRCMRegs->ulCM_FCLKEN1_CORE, PRCM_FCLKEN1_CORE_EN_HDQ);
CLRREG32(&pDevice->pPRCMRegs->ulCM_ICLKEN1_CORE, PRCM_ICLKEN1_CORE_EN_HDQ);
#else
// Disable the 1WIRE functional and interface clocks.
dwRegValue=PRCM_FCLKEN1_CORE_EN_HDQ;
KernelIoControl(IOCTL_FCLK1_DIS, (VOID*)&dwRegValue, sizeof(DWORD), NULL, 0, &cbRet);
dwRegValue=PRCM_ICLKEN1_CORE_EN_HDQ;
KernelIoControl(IOCTL_ICLK1_DIS, (VOID*)&dwRegValue, sizeof(DWORD), NULL, 0, &cbRet);
#endif
return;
}
//------------------------------------------------------------------------------
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -