一、GPIO驱动研究
boot_images/QcomPkg/QcomTestPkg/TLMMApp/TLMMApp.c分析
EFI_STATUS
EFIAPI
TLMMAppMain (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
DALResult result = DAL_ERROR;
EFI_STATUS status;
TEST_START("TLMM");
/* Create a DAL-formatted GPIO configuration for testing. */
DALGpioSignalType config =
(DALGpioSignalType)DAL_GPIO_CFG(1, 0, DAL_GPIO_OUTPUT, DAL_GPIO_NO_PULL, DAL_GPIO_2MA);
/* Initialize DALSYS and attach to the DAL TLMM driver. */
DALSYS_InitMod(NULL);
result = DAL_DeviceAttach(DALDEVICEID_TLMM, &tlmm_handle);
if((DAL_ERROR == result) || (tlmm_handle == NULL))
{
ASSERT(0);
}
/* Access the TLMM protocol. */
status = gBS->LocateProtocol( &gEfiTLMMProtocolGuid, NULL, (void**)&TLMMProtocol);
ASSERT_EFI_ERROR(status);
/* Test the DAL TLMM driver interface. This application does not have a way to
verify that the HW has been affected. The purpose is to test the interface
mechanism. Only probing the physical device or examining the contents of
HW registers can the actual functionality be fully verified. */
/* Configure the GPIO. */
result = DalTlmm_ConfigGpio(tlmm_handle, config, DAL_TLMM_GPIO_ENABLE);
if(DAL_SUCCESS == result)
{
/* Drive the GPIO HIGH. */
result = DalTlmm_GpioOut(tlmm_handle, config, DAL_GPIO_HIGH_VALUE);
if(result == DAL_SUCCESS)
{
/* Drive the GPIO LOW */
result = DalTlmm_GpioOut(tlmm_handle, config, DAL_GPIO_LOW_VALUE);
}
if(result != DAL_SUCCESS)
{
ASSERT(0);
}
}
/* Test EFI wrapper interface. */
if(TLMMProtocol)
{
TLMMProtocol->ConfigGpio(
(UINT32)EFI_GPIO_CFG(1, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA),
TLMM_GPIO_ENABLE);
TLMMProtocol->GpioOut(
(UINT32)EFI_GPIO_CFG(1, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA),
GPIO_HIGH_VALUE);
TLMMProtocol->GpioOut(
(UINT32)EFI_GPIO_CFG(1, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA),
GPIO_LOW_VALUE);
}
TestStatus("TLMM",EFI_SUCCESS);
TEST_STOP("TLMM");
return EFI_SUCCESS;
}
这里有两种方式来配置gpio,一种调用库来配置,另一种使用驱动提供的协议来配置!
(1)库调用顺序 DALModEnvLib->DALCommonLib->DALFwkLib
DAL_DeviceAttach->DALSYS_DeviceAttachFnc->DAL_DeviceAttach(QcomPkg/Library/DALCommonLib/DALDevice.c)->DalDevice_Init->_h->pVtbl->DalDevice.Init(_h)->接着是下面这个table
static void TLMM_InitInterface(TLMMClientCtxt* pclientCtxt)
{
static const DalTlmm vtbl = {
{
TLMM_DalTlmm_Attach,
TLMM_DalTlmm_Detach,
TLMM_DalTlmm_Init,
TLMM_DalTlmm_DeInit,
TLMM_DalTlmm_Open,
TLMM_DalTlmm_Close,
TLMM_DalTlmm_Info,
TLMM_DalTlmm_PowerEvent,
TLMM_DalTlmm_SysRequest
} ,
TLMM_DalTlmm_ConfigGpio,
TLMM_DalTlmm_ConfigGpioGroup,
TLMM_DalTlmm_GpioIn,
TLMM_DalTlmm_GpioOut,
TLMM_DalTlmm_GpioOutGroup,
TLMM_DalTlmm_SetPort,
TLMM_DalTlmm_GetCurrentConfig,
TLMM_DalTlmm_SetInactiveConfig,
TLMM_DalTlmm_GetInactiveConfig,
TLMM_DalTlmm_GetGpioNumber,
TLMM_DalTlmm_GetGpioStatus,
TLMM_DalTlmm_GetOutput,
TLMM_DalTlmm_PostInit
};
/*--------------------------------------------------------------------------
Depending upon client type setup the vtables (entry points)
--------------------------------------------------------------------------*/
pclientCtxt->DalTlmmHandle.dwDalHandleId = DALDEVICE_INTERFACE_HANDLE_ID;
pclientCtxt->DalTlmmHandle.pVtbl = &vtbl;
pclientCtxt->DalTlmmHandle.pClientCtxt = pclientCtxt;
}
-------> TLMM_DeviceInit