⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iic_mdd.cpp

📁 Samsung公司S3C6400芯片的BSP源码包
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************************
* 
*	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 + -