📄 iic_mdd.cpp
字号:
/**************************************************************************************
*
* Project Name : IIC Driver
*
* Copyright 2006 by Samsung Electronics, Inc.
* All rights reserved.
*
* Project Description :
* This software is MDD layer for IIC Samsung driver.
*
*--------------------------------------------------------------------------------------
*
* File Name : iic_mdd.cpp
*
* File Description : This file implements MDD layer functions which is stream driver.
*
* Author : JeGeon.Jung
* Dept. : AP Development Team
* Created Date : 2007/06/11
* Version : 0.1
*
* History
* - Created(JeGeon.Jung 2007/06/11)
* - Add Power Management (JeGeon.Jung 2007/06/25)
*
* Todo
*
*
* Note
*
**************************************************************************************/
#include <windows.h>
#include <types.h>
#include <linklist.h>
#include <nkintr.h>
#include <devload.h>
#include <pm.h>
#include <pmplatform.h>
#include <iic_mdd.h>
#include <iic_pdd.h>
#define DEFAULT_CE_THREAD_PRIORITY 103
#define MSG_ERROR 1
#define MSG_FUNCTION 0
#define MSG_INFO 0
#define MSG_WARN 0
CEDEVICE_POWER_STATE g_Dx;
// Define some internally used functions
BOOL IIC_Close(PHW_OPEN_INFO pOpenContext);
BOOL IIC_Deinit(PHW_INIT_INFO pInitContext);
//////////
// Function Name : DllEntry
// Function Description : Process attach/detach api.
// Input : HINSTANCE hinstDll, DWORD dwReason, LPVOID lpReserved
// Output : The return is a BOOL, representing success (TRUE) or failure (FALSE).
// Version : v1.0
BOOL
DllEntry(
HINSTANCE hinstDll, /*Instance pointer. */
DWORD dwReason, /*Reason routine is called. */
LPVOID lpReserved /*system parameter. */
)
{
if ( dwReason == DLL_PROCESS_ATTACH ) {
DEBUGREGISTER(hinstDll);
DEBUGMSG (ZONE_INIT, (TEXT("serial port process attach\r\n")));
DisableThreadLibraryCalls((HMODULE) hinstDll);
}
if ( dwReason == DLL_PROCESS_DETACH ) {
DEBUGMSG (ZONE_INIT, (TEXT("process detach called\r\n")));
}
return(TRUE);
}
//////////
// Function Name : IIC_Init
// Function Description : IIC device initialization.
// Input : LPCTSTR pContext
// Output : Returns a pointer to the serial head which is passed into
// the IIC_OPEN and IIC_DEINIT entry points as a device handle.
// Version : v0.5
HANDLE
IIC_Init(
LPCTSTR pContext /* Pointer to a string containing the registry path.*/
)
{
PHW_INIT_INFO pInitContext = NULL;
HKEY hKey;
ULONG datasize = sizeof(ULONG);
ULONG kvaluetype;
RETAILMSG(MSG_FUNCTION,(TEXT("+IIC_Init\r\n")));
// Allocate our control structure.
pInitContext = (PHW_INIT_INFO)LocalAlloc(LPTR, sizeof(HW_INIT_INFO));
// Check that LocalAlloc did stuff ok too.
if ( !pInitContext ) {
RETAILMSG(MSG_ERROR,
(TEXT("Error allocating memory for pInitContext, IIC_Init failed\n\r")));
return(NULL);
}
//memset(pInitContext,0,sizeof(HW_INIT_INFO));
// Initially, open list is empty.
InitializeListHead( &pInitContext->OpenList );
InitializeCriticalSection(&(pInitContext->OpenCS));
/* Initialize the critical sections that will guard the parts of
* the receive and transmit action.
*/
InitializeCriticalSection(&(pInitContext->CritSec));
pInitContext->pAccessOwner = NULL;
/* Want to use the Identifier to do RegOpenKey and RegQueryValue (?)
* to get the index to be passed to GetHWObj.
* The HWObj will also have a flag denoting whether to start the
* listening thread or provide the callback.
*/
RETAILMSG(MSG_INFO, (TEXT("Try to open %s\r\n"), pContext));
hKey = OpenDeviceKey(pContext);
if ( !hKey ) {
RETAILMSG (MSG_ERROR,
(TEXT("Failed to open devkeypath, IIC_Init failed\r\n")));
IIC_Deinit(pInitContext);
return(NULL);
}
datasize = sizeof(DWORD);
if ( RegQueryValueEx(hKey, L"Priority256", NULL, &kvaluetype,
(LPBYTE)&pInitContext->Priority256, &datasize) ) {
pInitContext->Priority256 = DEFAULT_CE_THREAD_PRIORITY;
RETAILMSG (MSG_WARN,
(TEXT("Failed to get Priority256 value, defaulting to %d\r\n"), pInitContext->Priority256));
}
if ( RegQueryValueEx(hKey, L"SlaveAddress", NULL, &kvaluetype,
(LPBYTE)&pInitContext->PDDCommonVal.SlaveAddress, &datasize) ) {
pInitContext->PDDCommonVal.SlaveAddress = DEFAULT_SLAVE_ADDRESS;
RETAILMSG (MSG_WARN,
(TEXT("Failed to get SlaveAddress value, defaulting to %d\r\n"), pInitContext->PDDCommonVal.SlaveAddress));
}
if ( RegQueryValueEx(hKey, L"Mode", NULL, &kvaluetype,
(LPBYTE)&pInitContext->PDDCommonVal.InterruptEnable, &datasize) ) {
pInitContext->PDDCommonVal.InterruptEnable = DEFAULT_INTERRUPT_ENABLE;
RETAILMSG (MSG_WARN,
(TEXT("Failed to get InterruptEnable value, defaulting to %d\r\n"), pInitContext->PDDCommonVal.InterruptEnable));
}
RegCloseKey (hKey);
pInitContext->State = IIC_RUN;
/* Check that HW_Init did stuff ok. From here on out, call Deinit function
* when things fail.
*/
if ( !HW_Init(pInitContext) ) {
RETAILMSG (MSG_ERROR,
(TEXT("Hardware doesn't init correctly, IIC_Init failed\r\n")));
IIC_Deinit(pInitContext);
return(NULL);
}
g_Dx = D0;
RETAILMSG(MSG_FUNCTION, (TEXT("-IIC_Init\r\n")));
return(pInitContext);
}
//////////
// Function Name : IIC_Deinit
// Function Description : IIC device De-initialization.
// Input : PHW_INIT_INFO pInitContext
// Output : The return is a BOOL, representing success (TRUE) or failure (FALSE).
// Version : v0.5
BOOL
IIC_Deinit(
PHW_INIT_INFO pInitContext /* Context pointer returned from IIC_Init*/
)
{
RETAILMSG(MSG_FUNCTION, (TEXT("+IIC_Deinit\r\n")));
if ( !pInitContext ) {
/* Can't do much without this */
RETAILMSG (MSG_ERROR,
(TEXT("IIC_Deinit can't find pInitContext\r\n")));
SetLastError(ERROR_INVALID_HANDLE);
return(FALSE);
}
/*
** Call close, if we have a user. Note that this call will ensure that
** all users are out of the serial routines before it returns, so we can
** go ahead and free our internal memory.
*/
EnterCriticalSection(&(pInitContext->OpenCS));
if ( pInitContext->OpenCnt ) {
PLIST_ENTRY pEntry;
PHW_OPEN_INFO pOpenContext;
pEntry = pInitContext->OpenList.Flink;
while ( pEntry != &pInitContext->OpenList ) {
pOpenContext = CONTAINING_RECORD( pEntry, HW_OPEN_INFO, llist);
pEntry = pEntry->Flink; // advance to next
RETAILMSG (MSG_INFO, (TEXT(" Deinit - Closing Handle 0x%X\r\n"),
pOpenContext ));
IIC_Close(pOpenContext);
}
}
LeaveCriticalSection(&(pInitContext->OpenCS));
/* Free our resources */
DeleteCriticalSection(&(pInitContext->CritSec));
DeleteCriticalSection(&(pInitContext->OpenCS));
pInitContext->State = IIC_FINISH;
/* Now, call HW specific deinit function */
HW_Deinit(pInitContext);
LocalFree(pInitContext);
RETAILMSG(MSG_FUNCTION, (TEXT("-IIC_Deinit\r\n")));
return(TRUE);
}
//////////
// Function Name : IIC_Open
// Function Description : IIC device initialization.
/* This routine must be called by the user to open the
* IIC device. The HANDLE returned must be used by the application in
* all subsequent calls to the IIC driver.
* Exported to users.
*/
// Input : HANDLE pHead, DWORD AccessCode, DWORD ShareMode
// Output : This routine returns a HANDLE representing the device.
// Version : v0.1
HANDLE
IIC_Open(
HANDLE pHead, // Handle returned by IIC_Init.
DWORD AccessCode, // access code.
DWORD ShareMode // share mode - Not used in this driver.
)
{
PHW_INIT_INFO pInitContext = (PHW_INIT_INFO)pHead;
PHW_OPEN_INFO pOpenContext;
RETAILMSG (MSG_FUNCTION, (TEXT("+IIC_Open handle x%X, access x%X, share x%X\r\n"),
pHead, AccessCode, ShareMode));
// Return NULL if pInitContext failed.
if ( !pInitContext ) {
RETAILMSG (MSG_ERROR,
(TEXT("Open attempted on uninited device!\r\n")));
SetLastError(ERROR_INVALID_HANDLE);
return(NULL);
}
if (AccessCode & DEVACCESS_BUSNAMESPACE ) {
AccessCode &=~(GENERIC_READ |GENERIC_WRITE|GENERIC_EXECUTE|GENERIC_ALL);
}
// This driver has no access permission.
/*
// Return NULL if opening with access & someone else already has
if ( (AccessCode & (GENERIC_READ | GENERIC_WRITE)) &&
pInitContext->pAccessOwner ) {
RETAILMSG (MSG_ERROR,
(TEXT("Open requested access %x, handle x%X already has x%X!\r\n"),
AccessCode, pInitContext->pAccessOwner,
pInitContext->pAccessOwner->AccessCode));
SetLastError(ERROR_INVALID_ACCESS);
return(NULL);
} */
// OK, lets allocate an open structure
pOpenContext = (PHW_OPEN_INFO)LocalAlloc(LPTR, sizeof(HW_OPEN_INFO));
if ( !pOpenContext ) {
RETAILMSG (MSG_ERROR,
(TEXT("Error allocating memory for pOpenContext, IIC_Open failed\n\r")));
return(NULL);
}
// Init the structure
pOpenContext->pInitContext = pInitContext; // pointer back to our parent
pOpenContext->StructUsers = 0;
pOpenContext->AccessCode = AccessCode;
pOpenContext->ShareMode = ShareMode;
// if we have access permissions, note it in pInitContext
if ( AccessCode & (GENERIC_READ | GENERIC_WRITE) ) {
RETAILMSG(MSG_INFO,
(TEXT("IIC_Open: Access permission handle granted x%X\n\r"),
pOpenContext));
pInitContext->pAccessOwner = pOpenContext;
}
// add this open entry to list of open entries.
// Note that we hold the open CS for the duration of the routine since
// all of our state info is in flux during this time. In particular,
// without the CS is would be possible for an open & close to be going on
// simultaneously and have bad things happen like spinning a new event
// thread before the old one was gone, etc.
EnterCriticalSection(&(pInitContext->OpenCS));
InsertHeadList(&pInitContext->OpenList,
&pOpenContext->llist);
// We do special for Power Manger and Device Manager.
if (pOpenContext->AccessCode & DEVACCESS_BUSNAMESPACE ) {
// OK, We do not need initialize pSerailHead and start any thread. return the handle now.
LeaveCriticalSection(&(pInitContext->OpenCS));
RETAILMSG(MSG_FUNCTION, (TEXT("-IIC_Open handle x%X, x%X, Ref x%X\r\n"),
pOpenContext, pOpenContext->pInitContext, pInitContext->OpenCnt));
return(pOpenContext);
}
if ( ! pInitContext->OpenCnt ) {
RETAILMSG(MSG_INFO,
(TEXT("IIC_Open: First open : Do Init x%X\n\r"),
pOpenContext));
if ( !HW_OpenFirst(pOpenContext) ) {
RETAILMSG (MSG_ERROR, (TEXT("HW Open First failed.\r\n")));
goto OpenFail;
}
HW_PowerUp(pInitContext);
}
if ( !HW_Open(pOpenContext) ) {
RETAILMSG (MSG_ERROR, (TEXT("HW Open failed.\r\n")));
goto OpenFail;
}
++(pInitContext->OpenCnt);
// OK, we are finally back in a stable state. Release the CS.
LeaveCriticalSection(&(pInitContext->OpenCS));
RETAILMSG(MSG_FUNCTION, (TEXT("-IIC_Open handle x%X, x%X, Ref x%X\r\n"),
pOpenContext, pOpenContext->pInitContext, pInitContext->OpenCnt));
return(pOpenContext);
OpenFail :
RETAILMSG(MSG_FUNCTION, (TEXT("-IIC_Open handle x%X, x%X, Ref x%X\r\n"),
NULL, pOpenContext->pInitContext, pInitContext->OpenCnt));
SetLastError(ERROR_OPEN_FAILED);
// If this was the handle with access permission, remove pointer
if ( pOpenContext == pInitContext->pAccessOwner )
pInitContext->pAccessOwner = NULL;
// Remove the Open entry from the linked list
RemoveEntryList(&pOpenContext->llist);
// OK, everything is stable so release the critical section
LeaveCriticalSection(&(pInitContext->OpenCS));
// Free all data allocated in open
LocalFree( pOpenContext );
return(NULL);
}
//////////
// Function Name : IIC_Close
// Function Description : close the IIC device.
// Input : PHW_OPEN_INFO pOpenContext
// Output : TRUE if success; FALSE if failure.
// Note : This routine is called by the device manager to close the device.
// Version : v0.5
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -