📄 sdbusdriver.cpp
字号:
ReleaseLock();
return slotCount;
}
///////////////////////////////////////////////////////////////////////////////
// GetFunctionPowerState - Get the power state of a SDIO function
// Input: pDevice - the device
//
// Output: pPowerState - structure describing the power state of the device
// Return: SD_API_STATUS code
//
// Notes:
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDBusDriver::GetFunctionPowerState(PSDCARD_DEVICE_CONTEXT pDevice,
PFUNCTION_POWER_STATE pPowerState)
{
SD_API_STATUS status; // intermediate status
DWORD FBROffset; // calculated FBR offset
UCHAR regValue; // register value
if (NULL == pDevice->pParentDevice) {
return SD_API_STATUS_INVALID_PARAMETER;
}
pPowerState->fPowerControlSupport = pDevice->pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->fCardSupportsPowerControl;
pPowerState->fPowerControlEnabled = pDevice->pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->fPowerControlEnabled;
pPowerState->fFunctionEnabled = (pDevice->pParentDevice->SDCardInfo.SDIOInformation.pCommonInformation->CCCRShadowIOEnable
& (1 << pDevice->SDCardInfo.SDIOInformation.Function)) ? TRUE : FALSE;
FBROffset = SD_IO_FBR_1_OFFSET + (pDevice->SDCardInfo.SDIOInformation.Function - 1) * SD_IO_FBR_LENGTH;
status = SDReadWriteRegistersDirect__X((SD_DEVICE_HANDLE)pDevice,
SD_IO_READ,
0, // all from function 0
FBROffset + SD_IO_FBR_POWER_SELECT,
FALSE,
®Value,
1);
if (!SD_API_SUCCESS(status))
{
return status;
}
pPowerState->fSupportsPowerSelect = (regValue & SD_IO_FUNCTION_POWER_SELECT_SUPPORT) ? TRUE : FALSE;
if(pPowerState->fSupportsPowerSelect)
{
pPowerState->fLowPower = regValue & SD_IO_FUNCTION_POWER_SELECT_STATE ? TRUE : FALSE;
}
else
{
pPowerState->fLowPower = 0;
}
pPowerState->OperatingVoltage = pDevice->OperatingVoltage;
//calculate the current draw
if(pPowerState->fPowerControlSupport)
{
if(pPowerState->fFunctionEnabled)
{
//
// in future when more power tuples are added select the proper tuple here
// currently only the 3.3V tuple is supported
//
if((pPowerState->fPowerControlEnabled) &&
(pPowerState->fSupportsPowerSelect))
{
if(pPowerState->fLowPower)
{
//function enabled at low power
pPowerState->CurrentDrawNow = pDevice->SDCardInfo.SDIOInformation.PowerDrawData.LpMaxPower33;
pPowerState->EnableDelta = ((INT)pDevice->SDCardInfo.SDIOInformation.PowerDrawData.LpMaxPower33) * -1;
pPowerState->SelectDelta = ((INT)pDevice->SDCardInfo.SDIOInformation.PowerDrawData.HpMaxPower33)
- ((INT)pDevice->SDCardInfo.SDIOInformation.PowerDrawData.LpMaxPower33);
}
else
{
//function enabled at high power
pPowerState->CurrentDrawNow = pDevice->SDCardInfo.SDIOInformation.PowerDrawData.HpMaxPower33;
pPowerState->EnableDelta = ((INT)pDevice->SDCardInfo.SDIOInformation.PowerDrawData.HpMaxPower33) * -1;
pPowerState->SelectDelta = ((INT)pDevice->SDCardInfo.SDIOInformation.PowerDrawData.LpMaxPower33)
- ((INT)pDevice->SDCardInfo.SDIOInformation.PowerDrawData.HpMaxPower33);
}
}
else
{
//function enabled at no power select
pPowerState->CurrentDrawNow = pDevice->SDCardInfo.SDIOInformation.PowerDrawData.SpMaxPower33;
pPowerState->EnableDelta = ((INT)pDevice->SDCardInfo.SDIOInformation.PowerDrawData.SpMaxPower33) * -1;
pPowerState->SelectDelta = 0;
}
}
else
{
if((pPowerState->fPowerControlEnabled) &&
(pPowerState->fSupportsPowerSelect))
{
if(pPowerState->fLowPower)
{
//function disabled power select set to low
pPowerState->CurrentDrawNow = 0;
pPowerState->EnableDelta = pDevice->SDCardInfo.SDIOInformation.PowerDrawData.LpMaxPower33;
pPowerState->SelectDelta = 0;
}
else
{
//function disabled power select set to low
pPowerState->CurrentDrawNow = 0;
pPowerState->EnableDelta = pDevice->SDCardInfo.SDIOInformation.PowerDrawData.HpMaxPower33;
pPowerState->SelectDelta = 0;
}
}
else
{
//function disabled, no power select
pPowerState->CurrentDrawNow = 0;
pPowerState->EnableDelta = pDevice->SDCardInfo.SDIOInformation.PowerDrawData.SpMaxPower33;
}
}
}
else
{
USHORT TempMaxPower;
//the current draw must never be greater than 200mA for a non Power Control enabled card
if((0 == pDevice->SDCardInfo.SDIOInformation.PowerDrawData.OpMaxPower) ||
(200 < pDevice->SDCardInfo.SDIOInformation.PowerDrawData.OpMaxPower))
{
TempMaxPower = 200;
}
else
{
TempMaxPower = pDevice->SDCardInfo.SDIOInformation.PowerDrawData.OpMaxPower;
}
if(pPowerState->fFunctionEnabled)
{
//function enabled, no power control
pPowerState->CurrentDrawNow = TempMaxPower;
pPowerState->EnableDelta = ((INT)TempMaxPower) * -1;
pPowerState->SelectDelta = 0;
}
else
{
//function disabled, no power control
pPowerState->CurrentDrawNow = 0;
pPowerState->EnableDelta = (INT)TempMaxPower;
pPowerState->SelectDelta = 0;
}
}
return SD_API_STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////
// GetSlotContext - get slot context based on an index value
// Input: slotIndexWanted - index of slot
//
// Output:
// Notes:
// returns a pointer to the slot context
// NULL is returned if slot is not found
///////////////////////////////////////////////////////////////////////////////
PSDBUS_HC_SLOT_CONTEXT CSDBusDriver::GetSlotContext(DWORD slotIndexWanted)
{
LIST_ENTRY *pListEntry; // list entry
PSDBUS_HC_CONTEXT pHCContext; // host controller context
PSDBUS_HC_SLOT_CONTEXT pSlot; // slot context
ULONG slotIndex; // slot index
ULONG slotCount; // running slot count
// get the head
pListEntry = m_HostControllerListHead.Flink;
// reset slot count
slotCount = 0;
// acquire the lock to protect the list
AcquireLock();
// loop through the host controllers and get the slot count
while (pListEntry != &m_HostControllerListHead) {
// get the context
pHCContext = CONTAINING_RECORD(pListEntry, SDBUS_HC_CONTEXT, ListEntry);
// increment the slot count
slotCount += pHCContext->NumberOfSlots;
if(slotIndexWanted <= slotCount)
{
slotIndex = pHCContext->NumberOfSlots - (slotCount - slotIndexWanted);
break;
}
// move to the next one
pListEntry = pListEntry->Flink;
}
if(slotIndexWanted > slotCount)
{
DbgPrintZo(SDCARD_ZONE_ERROR, (TEXT("SDBusDriver: GetSlotContext: Slot %d Could not be found \n"),
slotIndexWanted));
pSlot = NULL;
}
else
{
pSlot = SDHCGetSlotContext(pHCContext, slotIndex);
}
ReleaseLock();
return pSlot;
}
///////////////////////////////////////////////////////////////////////////////
// GetSlotPowerControlInfo - get slot power control information
// Input: slotIndexWanted - index of slot
//
// Output: pPCdata - data about power control at the slot
// Notes:
// returns SD Api Error
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDBusDriver::GetSlotPowerControlInfo(DWORD slotIndexWanted,
PSLOT_POWER_DATA pPCdata)
{
PSDBUS_HC_SLOT_CONTEXT pSlot; // slot context
PSDCARD_DEVICE_CONTEXT pCurrentDevice; // the device in the slot
SD_API_STATUS status; // intermediate SD status
UCHAR NumOfFunctions; // Number of functions for the device
pSlot = GetSlotContext(slotIndexWanted);
if(NULL == pSlot)
{
return SD_API_STATUS_NO_SUCH_DEVICE;
}
memset(pPCdata, 0, sizeof(SLOT_POWER_DATA));
status = CheckSlotReady(pSlot);
if(!SD_API_SUCCESS(status)) {
return status;
}
// Start from parent device
pCurrentDevice = SDDCGetClientDeviceFromHandle(pSlot->hDevice);
if ( NULL ==pCurrentDevice ) {
return SD_API_STATUS_UNSUCCESSFUL;
}
// ensure the device when through the SDGetSDIOPnpInformation process
if ( NULL == pCurrentDevice->SDCardInfo.SDIOInformation.pCommonInformation) {
DbgPrintZo(SDCARD_ZONE_ERROR,(TEXT("SDBusDriver: GetSlotPowerControlInfo: Card's common infomation was not initalized.\r\n")));
return SD_API_STATUS_UNSUCCESSFUL;
}
pPCdata->fCardSupportsPowerControl = pCurrentDevice->SDCardInfo.SDIOInformation.pCommonInformation->fCardSupportsPowerControl;
pPCdata->fPowerControlEnabled = pCurrentDevice->SDCardInfo.SDIOInformation.pCommonInformation->fPowerControlEnabled;
pPCdata->CurrentDrawOfSlot = SDHCDGetSlotPower(pSlot->pHostController, slotIndexWanted);
pPCdata->OperatingVoltage = pCurrentDevice->OperatingVoltage;
pPCdata->CurrentTupleVoltageRange = SD_MASK_FOR_33V_POWER_CONTROL_TUPLE;
pPCdata->NumberOfHighPowerTuples = 1; // For SDIO 1.1 this is 1
pPCdata->SizeOfFunctionRecord = sizeof(FUNCTION_POWER_DATA);
// count the number of functions in the device
NumOfFunctions = 0;
while (pCurrentDevice != NULL) {
NumOfFunctions++;
pCurrentDevice = pCurrentDevice->pNext;
}
pPCdata->Functions = NumOfFunctions;
return SD_API_STATUS_SUCCESS;
}
///////////////////////////////////////////////////////////////////////////////
// GetFunctionPowerControlInfo - get function power control information
// Input: slotIndexWanted - index of slot
// - index of slot
//
// Output: pFPCdata - data about power control at the function
// Notes:
// returns SD Api Error
///////////////////////////////////////////////////////////////////////////////
SD_API_STATUS CSDBusDriver::GetFunctionPowerControlInfo(DWORD slotIndexWanted,
DWORD FunctionIndexWanted,
PFUNCTION_POWER_DATA pFPCdata)
{
PSDBUS_HC_SLOT_CONTEXT pSlot; // slot context
PSDCARD_DEVICE_CONTEXT pCurrentDevice; // the device in the slot
SD_API_STATUS status; // intermediate SD status
pSlot = GetSlotContext(slotIndexWanted);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -