📄 pmicpdk.cpp
字号:
//-----------------------------------------------------------------------------
//
// Copyright (C) 2004-2005, Motorola Inc. All Rights Reserved
//
//-----------------------------------------------------------------------------
//
// Copyright (C) 2006, Freescale Semiconductor, Inc. All Rights Reserved
// THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
// BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
// FREESCALE SEMICONDUCTOR, INC.
//
//-----------------------------------------------------------------------------
//
// File: pmicpdk.cpp
//
// This file contains the PMIC chip specific functions that provide control
// over the Power Management IC.
//
//-----------------------------------------------------------------------------
#include <windows.h>
#include <nkintr.h>
#include <cmnintrin.h>
#include <Devload.h>
#include <ceddk.h>
#include "cspiutil.h"
#include "pmic_ioctl.h"
#include "pmic_lla.h"
#include "pmic_adc.h"
#include "regs_adc.h"
#include "regs.h"
#include "regs_battery.h"
#include "regs_connectivity.h"
#include "pmic_connectivity.h"
#include "pmic_convity_priv.h"
#include "pmic_lla.h"
//-----------------------------------------------------------------------------
// External Functions
extern "C" int BSPPmicGetSpiPort(void);
extern "C" UINT32 BSPPmicGetSpiFreqOut();
extern "C" DWORD BSPPmicGetIrq(void);
extern "C" BOOL BSPPmicInit(HANDLE *phIntrHdlr);
extern "C" BOOL BSPPmicDeinit(void);
extern "C" BOOL BSPPmicClearIrq(void);
extern "C" BOOL BSPPmicGetIrqStatus(UINT32 *status);
extern "C" VOID BSPPmicPowerNotifySuspend(void);
extern "C" VOID BSPPmicPowerNotifyResume(void);
extern "C" VOID BSPPmicReadIntrStatus(void);
extern "C" VOID BSPPmicSignalOALRTC(void);
//-----------------------------------------------------------------------------
// External Variables
extern "C" BOOL g_bPmicUseCspiPolling;
//-----------------------------------------------------------------------------
// Defines
#define PMIC_INTS0_TO_AP 0xFFFFFF // all interrupts to AP.
#define PMIC_INTS1_TO_AP 0xFFFFFF
#define PMIC_ALL_BITS 0xFFFFFF
#define MC13783_ADC_DEFAULT_ATO_SETTING 0x01
#define MC13783_ADC_REGISTER_MASK_ALL 0xFFFFFF
#define ADC_OPERATION_TIMEOUT 5000
#ifdef DEBUG
// Debug zone bit positions
#define ZONEID_ERROR 0
#define ZONEID_WARN 1
#define ZONEID_INIT 2
#define ZONEID_FUNC 3
#define ZONEID_INFO 4
// Debug zone masks
#define ZONEMASK_ERROR (1 << ZONEID_ERROR)
#define ZONEMASK_WARN (1 << ZONEID_WARN)
#define ZONEMASK_INIT (1 << ZONEID_INIT)
#define ZONEMASK_FUNC (1 << ZONEID_FUNC)
#define ZONEMASK_INFO (1 << ZONEID_INFO)
// Debug zone args to DEBUGMSG
#define ZONE_ERROR DEBUGZONE(ZONEID_ERROR)
#define ZONE_WARN DEBUGZONE(ZONEID_WARN)
#define ZONE_INIT DEBUGZONE(ZONEID_INIT)
#define ZONE_FUNC DEBUGZONE(ZONEID_FUNC)
#define ZONE_INFO DEBUGZONE(ZONEID_INFO)
DBGPARAM dpCurSettings = {
_T("PMICPDK"),
{
TEXT("Errors"), TEXT("Warnings"), TEXT("Init"), TEXT("Func"),
TEXT("Info"), TEXT(""), TEXT(""), TEXT(""),
TEXT(""),TEXT(""),TEXT(""),TEXT(""),
TEXT(""),TEXT(""),TEXT(""),TEXT("")
},
ZONEMASK_ERROR | ZONEMASK_WARN //| ZONEMASK_INIT | ZONEMASK_FUNC | ZONEMASK_INFO // ulZoneMask
};
#endif // DEBUG
//-----------------------------------------------------------------------------
// Types
//-----------------------------------------------------------------------------
// Global Variables
//-----------------------------------------------------------------------------
// Local Variables
static CRITICAL_SECTION pmicCs;
static CRITICAL_SECTION adcCs;
static CRITICAL_SECTION intRegCs;
static HANDLE hIntrEventPmic;
static HANDLE hPmicISTThread;
static DWORD dwSysIntrPmic;
static BOOL bISTTerminate;
static HANDLE phIntrHdlr[PMIC_INT_MAX_ID];
static volatile BOOL g_bAdcPolled = FALSE;
static CEDEVICE_POWER_STATE g_dxCurrent = D0;
//-----------------------------------------------------------------------------
// Local Functions
static BOOL InitializePMIC();
static VOID CleanupPMIC();
static PMIC_STATUS PmicADCGetSettings(UINT16 channel, UINT32 *group,
UINT32 *chann, UINT32 *ena);
static PMIC_STATUS PmicADCConvert();
static VOID PmicADCDisable();
static VOID PmicReadEightValues(UINT16* pReturnVal);
static BOOL CheckIntIdValid(UINT32 IntID);
extern "C" BOOL PMICIoctlIntEnable(UINT32 IntID, BOOL EnableFlag);
static BOOL PMICAdcSetMode(PMIC_TOUCH_MODE mode);
extern "C" VOID SetRegister(UINT32 addr, UINT32 data, UINT32 mask);
extern "C" VOID GetRegister(UINT32 addr, UINT32* content);
static BOOL PmicIsrThreadProc();
static DWORD WINAPI PmicPowerNotificationThread(LPVOID lpParam);
//-----------------------------------------------------------------------------
//
// Function: DllEntry
//
// This is the entry and exit point for the PMIC control module. This
// function is called when processed and threads attach and detach from this
// module.
//
// Parameters:
// hInstDll
// [in] The handle to this module.
//
// dwReason
// [in] Specifies a flag indicating why the DLL entry-point function
// is being called.
//
// lpvReserved
// [in] Specifies further aspects of DLL initialization and cleanup.
//
// Returns:
// TRUE if the PMIC is initialized; FALSE if an error occurred during
// initialization.
//
//-----------------------------------------------------------------------------
BOOL WINAPI
DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{
switch (dwReason) {
case DLL_PROCESS_ATTACH:
DEBUGREGISTER((HMODULE)hInstDll);
DisableThreadLibraryCalls((HMODULE) hInstDll);
DEBUGMSG(ZONE_INIT,
(_T("***** DLL PROCESS ATTACH TO PMIC *****\r\n")));
break;
case DLL_PROCESS_DETACH:
break;
}
// Return TRUE for success
return TRUE;
}
//-----------------------------------------------------------------------------
//
// Function: InitializePMIC
//
// Initializes the PMIC module.
//
// Parameters:
// None.
//
// Returns:
// TRUE if the PMIC is initialized or FALSE if an error occurred during
// initialization. The reason for the failure can be retrieved by the
// GetLastError().
//
//-----------------------------------------------------------------------------
static BOOL
InitializePMIC()
{
BOOL initializedPMIC = FALSE;
DWORD irq;
int i;
UINT32 isr, temp_data;
DEBUGMSG(ZONE_INIT || ZONE_FUNC, (TEXT("+%s()\r\n"), __WFUNCTION__));
// Create critical sections
InitializeCriticalSection(&pmicCs);
InitializeCriticalSection(&adcCs);
InitializeCriticalSection(&intRegCs);
// Initialize CSPI
initializedPMIC = cspiInitialize(BSPPmicGetSpiPort(),
BSPPmicGetSpiFreqOut());
if (!initializedPMIC)
goto Error;
GetRegister(MC13783_REV_ADDR, &temp_data);
if (( temp_data && 0x1f) == NULL)
goto Error;
// Reset Interrupt registration table
for (i = PMIC_INT_MAX_ID - 1; i>=0; i--)
{
phIntrHdlr[i] = NULL;
}
// Initialize interrupt on PMIC.
// Mask all interrupts
SetRegister(MC13783_INT_MSK0_ADDR, PMIC_ALL_BITS, PMIC_ALL_BITS);
SetRegister(MC13783_INT_MSK1_ADDR, PMIC_ALL_BITS, PMIC_ALL_BITS);
// Clear all interrupts
GetRegister(MC13783_INT_STAT0_ADDR, &isr);
SetRegister(MC13783_INT_STAT0_ADDR, (isr & PMIC_INTS0_TO_AP), PMIC_ALL_BITS);
GetRegister(MC13783_INT_STAT1_ADDR, &isr);
SetRegister(MC13783_INT_STAT1_ADDR, (isr & PMIC_INTS1_TO_AP), PMIC_ALL_BITS);
// Initialize platform-specific configuration
BSPPmicInit(phIntrHdlr);
// create event for PMIC interrupt signaling
// pEventAttributes = NULL (must be NULL)
// bManualReset = FALSE => resets automatically to nonsignaled
// state after waiting thread released
// bInitialState = FALSE => initial state is non-signaled
// lpName = NULL => object created without a name
hIntrEventPmic = CreateEvent(NULL, FALSE, FALSE, NULL);
// Check if CreateEvent failed
if (hIntrEventPmic == NULL)
{
DEBUGMSG(ZONE_ERROR, (TEXT("%s(): CreateEvent failed!\r\n"),
__WFUNCTION__));
goto Error;
}
irq = BSPPmicGetIrq();
// Call the OAL to translate the IRQ into a SysIntr value.
if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &irq, sizeof(DWORD),
&dwSysIntrPmic, sizeof(DWORD), NULL))
{
DEBUGMSG(ZONE_ERROR, (TEXT
("ERROR: Failed to obtain sysintr value for PMIC interrupt.\r\n")));
goto Error;
}
// Register PMIC interrupt
if (!InterruptInitialize(dwSysIntrPmic, hIntrEventPmic, NULL, 0))
{
DEBUGMSG(ZONE_ERROR, (TEXT("%s(): InterruptInitialize failed!\r\n")
__WFUNCTION__));
goto Error;
}
// Ask the OAL to enable our interrupt to wake the system from suspend
KernelIoControl(IOCTL_HAL_ENABLE_WAKE, &dwSysIntrPmic,
sizeof(dwSysIntrPmic), NULL, 0, NULL);
bISTTerminate = FALSE;
hPmicISTThread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)PmicIsrThreadProc,
0, 0, NULL);
if (!hPmicISTThread)
{
DEBUGMSG(ZONE_ERROR,
(TEXT("PmicIsrThreadStart: CreateThread failed\r\n")));
goto Error;
}
// Create event for blocking on ADC conversions to complete
phIntrHdlr[PMIC_MC13783_INT_ADCDONEI] =
CreateEvent(NULL, FALSE, FALSE, _T("EVENT_ADCDONE"));
// Check if CreateEvent failed
if (phIntrHdlr[PMIC_MC13783_INT_ADCDONEI] == NULL)
{
DEBUGMSG(ZONE_ERROR, (TEXT("%s(): CreateEvent failed!\r\n"),
__WFUNCTION__));
goto Error;
}
// Unmask ADC complete interrupt
SetRegister(MC13783_INT_MSK0_ADDR, PMIC_ALL_BITS, PMIC_ALL_BITS);
SetRegister(MC13783_INT_MSK0_ADDR, 0, (1 << PMIC_MC13783_INT_ADCDONEI));
// Unmask TOD interrupts
SetRegister(MC13783_INT_MSK1_ADDR, 0, MC13783_TODAM_MASK);
DEBUGMSG(ZONE_INIT || ZONE_FUNC, (TEXT("-%s returning %d\r\n"),
__WFUNCTION__, initializedPMIC));
return initializedPMIC;
Error:
CleanupPMIC();
return FALSE;
}
//-----------------------------------------------------------------------------
//
// Function: CleanupPMIC
//
// This function unmaps the registry space for the PMIC registers.
//
// Parameters:
// None.
//
// Returns:
// None.
//
//-----------------------------------------------------------------------------
static VOID
CleanupPMIC()
{
DEBUGMSG(ZONE_FUNC, (TEXT("+%s\r\n"), __WFUNCTION__));
cspiRelease(BSPPmicGetSpiPort());
// Release SYSINTR
KernelIoControl(IOCTL_HAL_RELEASE_SYSINTR, &dwSysIntrPmic, sizeof(DWORD),
NULL, 0, NULL);
dwSysIntrPmic = SYSINTR_UNDEFINED;
// If PMIC no longer needs service
// Clear the gpio interrupt flag(w1c)
// Deinitialize platform-specific configuration
BSPPmicDeinit();
// kill the IST thread
if (hPmicISTThread)
{
bISTTerminate = TRUE;
CloseHandle(hPmicISTThread);
hPmicISTThread = NULL;
}
// Close interrupt event handle
if (hIntrEventPmic)
{
CloseHandle(hIntrEventPmic);
hIntrEventPmic = NULL;
}
// Delete critical sections
DeleteCriticalSection(&pmicCs);
DeleteCriticalSection(&adcCs);
DeleteCriticalSection(&intRegCs);
DEBUGMSG(ZONE_FUNC, (TEXT("-%s\r\n"), __WFUNCTION__));
}
static BOOL PmicIoctlConvityOpHandler(PMIC_PARAM_CONVITY_OP *inParam, PMIC_STATUS *result)
{
UINT32 addr0 = MC13783_USB0_ADDR, data0 = 0, mask0 = 0;
UINT32 addr1 = MC13783_CHG_USB1_ADDR, data1 = 0, mask1 = 0;
BOOL rc = FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -