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

📄 drv.c

📁 三星ARM9系列CPU S3C2440A的WINCE 5.0下的BSP
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//

/*++

THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
PARTICULAR PURPOSE.

Module Name:

    drv.c   I2C (logical) MDD

Abstract:

   Streams interface driver

Functions:

Notes:

--*/

#include <windows.h>
#include <nkintr.h>

#include <winreg.h>
#include <winioctl.h>
#include <ceddk.h>
#include <devload.h>

#include "drv.h"

#ifdef DEBUG
DBGPARAM dpCurSettings = {
    TEXT("I2C"), {
    TEXT("Error"), TEXT("Warn"),  TEXT("Init"),  TEXT("Open"),
    TEXT("Read"),  TEXT("Write"), TEXT("IOCTL"), TEXT("IST"),
    TEXT("Power"), TEXT("9"),     TEXT("10"),    TEXT("11"), 
    TEXT("12"),    TEXT("13"),    TEXT("14"),    TEXT("Trace"),
    },
    0x0003 // ZONE_WRN|ZONE_ERR
};
#endif  // DEBUG


BOOL
I2C_PowerUp(
   PVOID Context
   );

BOOL
I2C_PowerDown(
   PVOID Context
   );

BOOL
DllEntry(
    HINSTANCE   hinstDll,             /*@parm Instance pointer. */
    DWORD   dwReason,                 /*@parm Reason routine is called. */
    LPVOID  lpReserved                /*@parm system parameter. */
    )
{
    if ( dwReason == DLL_PROCESS_ATTACH ) {
        DEBUGREGISTER(hinstDll);
        DEBUGMSG (ZONE_INIT, (TEXT("I2C: Process Attach\r\n")));
    }

    if ( dwReason == DLL_PROCESS_DETACH ) {
        DEBUGMSG (ZONE_INIT, (TEXT("I2C: Process Detach\r\n")));
    }

    return(TRUE);
}


BOOL
GetRegistryData(PI2C_CONTEXT pI2C, LPCTSTR regKeyPath)
{
    LONG    regError;
    HKEY    hKey;
    DWORD   dwDataSize;

    DEBUGMSG(ZONE_INIT, (TEXT("Try to open %s\r\n"), regKeyPath));

    // We've been handed the name of a key in the registry that was generated
    // on the fly by device.exe.  We're going to open that key and pull from it
    // a value that is the name of this drivers's real key.  That key
    // will have the DeviceArrayIndex that we're trying to find.  
    hKey = OpenDeviceKey(regKeyPath);
    if ( hKey == NULL ) {
        DEBUGMSG(ZONE_INIT | ZONE_ERR,(TEXT("Failed to open device key\r\n")));
        return ( FALSE );        
    }

    dwDataSize = REG_MODE_VAL_LEN;
    regError = RegQueryValueEx(
                hKey, 
                REG_MODE_VAL_NAME, 
                NULL, 
                NULL,
                (LPBYTE)(&pI2C->Mode),
                &dwDataSize);

    if (regError)
        goto _done;


    dwDataSize = REG_SLAVEADDR_VAL_LEN;
    regError = RegQueryValueEx(
                hKey, 
                REG_SLAVEADDR_VAL_NAME,
                NULL, 
                NULL,
                (LPBYTE)(&pI2C->SlaveAddress),
                &dwDataSize);

    if (regError)
        goto _done;


_done:
    RegCloseKey (hKey);

    if ( regError != ERROR_SUCCESS ) {
        DEBUGMSG(ZONE_ERR, (TEXT("Failed to get registry values, Error 0x%X\r\n"),regError));
        return ( FALSE );
    }

    DEBUGMSG (ZONE_INIT,(TEXT("I2C_Init - Mode: %s\r\n"),
        pI2C->Mode == POLLING ? L"POLLING" : L"INTERRUPT"));

    return ( TRUE ); 
}

#ifdef UTLDRV
static
DWORD
InternalMapRegisters(
    PI2C_CONTEXT pI2C
    )
{
    HANDLE       hUtil;
    UTL_FASTCALL utlFc = {0};
    DWORD dwErr = ERROR_SUCCESS, bytes;

    // Open the util driver so we can map in our registers VA
    hUtil = CreateFile( TEXT("UTL0:"), GENERIC_READ|GENERIC_WRITE,
                        FILE_SHARE_READ|FILE_SHARE_WRITE,
                        NULL, OPEN_EXISTING, 0, 0);
    
    if (INVALID_HANDLE_VALUE == hUtil) {
        dwErr = GetLastError();
        DEBUGMSG(ZONE_ERR, (TEXT("CreateFile ERROR: %d\n"), dwErr));
        goto _error_exit;
    }

    //  get it's FAST CALL function pointers.
    if( !DeviceIoControl(hUtil, 
                         IOCTL_UTL_GET_FASTCALL,
                         NULL, 0, 
                         &utlFc, sizeof(utlFc),
                         &bytes, NULL)) {
        dwErr = GetLastError();
        DEBUGMSG(ZONE_ERR, (TEXT("DeviceIoControl ERROR: %d\n"), dwErr));
        goto _error_exit;
    }

    // map in I2C registers
    dwErr = utlFc.GetRegisterVA(utlFc.pContext, 
                                IIC_BASE,
                                sizeof(IICreg),
                                FALSE, 
                                (DWORD *)&pI2C->pI2CReg);
    if ( dwErr ) {
        DEBUGMSG(ZONE_ERR, (TEXT("GetRegisterVA(IIC_BASE) ERROR: %d\n"), dwErr));
        goto _error_exit;
    }

    // map in GPIO
    dwErr = utlFc.GetRegisterVA(utlFc.pContext, 
                                IOP_BASE, 
                                sizeof(IOPreg),
                                FALSE, 
                                (DWORD *)&pI2C->pIOPReg);
    if ( dwErr ) {
        DEBUGMSG(ZONE_ERR, (TEXT("GetRegisterVA(IOP_BASE) ERROR: %d\n"), dwErr));
        goto _error_exit;
    }

    // map in CLK/PWR registers
    dwErr = utlFc.GetRegisterVA(utlFc.pContext, 
                                CLKPWR_BASE, 
                                sizeof(CLKPWRreg),
                                FALSE, 
                                (DWORD *)&pI2C->pCLKPWRReg);
    if ( dwErr ) {
        DEBUGMSG(ZONE_ERR, (TEXT("GetRegisterVA(CLKPWR_BASE) ERROR: %d\n"), dwErr));
        goto _error_exit;
    }

_error_exit:
    // We only mapped in registers, which remain in utildrv forever.
    // If we mapped in memory we would need to keep the handle and FreeMemVA later.
    if (INVALID_HANDLE_VALUE != hUtil)
        CloseHandle(hUtil);
        
    return dwErr;
}


#else

static
DWORD
InternalMapRegisters(
    PI2C_CONTEXT pI2C
    )
{
    PUCHAR  pVMem;
    BOOL    bMapReturn;
    DWORD   err = ERROR_SUCCESS;
  
    // reserve enough space for our registers
    pVMem = (PUCHAR)VirtualAlloc(0, PAGE_SIZE*3, MEM_RESERVE, PAGE_NOACCESS);
    
    if (pVMem) {
        // map in I2C registers
        bMapReturn = VirtualCopy( pVMem,
                                  (LPVOID)(S3C2440A_BASE_REG_PA_IICBUS>>8),
                                  PAGE_SIZE,
                                  PAGE_READWRITE | PAGE_NOCACHE |PAGE_PHYSICAL);
        if (!bMapReturn) {
            err = GetLastError();
            DEBUGMSG(ZONE_ERR, (TEXT("Virtual Copy ERROR for IICBUS regs: %d\r\n"), err));
            return err;
        }
        pI2C->pI2CReg = (volatile S3C2440A_IICBUS_REG*)(pVMem);

        // map in GPIO registers
        pVMem += PAGE_SIZE;
        bMapReturn = VirtualCopy(pVMem,
                                 (LPVOID)(S3C2440A_BASE_REG_PA_IOPORT>>8),
                                 PAGE_SIZE,
                                 PAGE_READWRITE | PAGE_NOCACHE |PAGE_PHYSICAL);
        if (!bMapReturn) {
            err = GetLastError();
            DEBUGMSG(ZONE_ERR, (TEXT("Virtual Copy ERROR for IOP regs: %d\r\n"), err));
            return err;
        }
        pI2C->pIOPReg = (volatile S3C2440A_IOPORT_REG*)(pVMem);
        
        // map in CLK/PWR  registers 
        pVMem += PAGE_SIZE;
        bMapReturn = VirtualCopy(pVMem,
                                 (LPVOID)(S3C2440A_BASE_REG_PA_CLOCK_POWER>>8),
                                 PAGE_SIZE,
                                 PAGE_READWRITE | PAGE_NOCACHE |PAGE_PHYSICAL);
        if (!bMapReturn) {
            err = GetLastError();
            DEBUGMSG(ZONE_ERR, (TEXT("Virtual Copy ERROR for CLK power regs: %d\r\n"), err));
            return err;
        }
        pI2C->pCLKPWRReg = (volatile S3C2440A_CLKPWR_REG*)(pVMem);

    } else {
        err = GetLastError();
        DEBUGMSG(ZONE_ERR, (TEXT("Virtual Alloc ERROR: %d\r\n"), err));
    }
  
    return err;
}

#endif


BOOL
I2C_Deinit(
   PI2C_CONTEXT pI2C
   )
{
   DEBUGMSG(ZONE_INIT, (TEXT(">I2C_Deinit\n")));

    if (!pI2C)
        return FALSE;
        
    HW_Deinit(pI2C);
    
#ifndef UTLDRV
    if (pI2C->pI2CReg)
        VirtualFree((PVOID)pI2C->pI2CReg, 0, MEM_RELEASE);

    if (pI2C->pIOPReg)
        VirtualFree((PVOID)pI2C->pIOPReg, 0, MEM_RELEASE);

    if (pI2C->pCLKPWRReg)
        VirtualFree((PVOID)pI2C->pCLKPWRReg, 0, MEM_RELEASE);
#endif

	LocalFree(pI2C);

	DEBUGMSG(ZONE_INIT, (TEXT("<I2C_Deinit\n")));

	return TRUE;
}


/*++

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -