📄 hdq.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//------------------------------------------------------------------------------
//
// The file implements HDQ device driver.
//
#include <windows.h>
#include <winuser.h>
#include <winuserm.h>
#include <ceddk.h>
#include <ceddkex.h>
#include <omap2420.h>
#include <CEDDKEX.H>
#include <buses.h>
#include <hdq.h>
/*
#undef DEBUGMSG
#define DEBUGMSG(x, y) RETAILMSG(1,y)
#ifdef RETAIL_DEBUG
#pragma optimize("", off) // debug
#endif
*/
//------------------------------------------------------------------------------
// Global Variables
const GUID DEVICE_IFC_HDQ_GUID;
const long int cliDelay1=100; // 250 first hdq op dealy in msec
const long int cliDelay2=100; // msec
const long int cliDelay2A=100; // msec
const long int cliDelay3=100; // msec
#ifdef DEBUG
DBGPARAM dpCurSettings = {
L"System Buses", {
L"Errors", L"Warnings", L"Function", L"Init",
L"Info", L"IST", L"Power", L"Undefined",
L"Undefined", L"Undefined", L"Undefined", L"Undefined",
L"HDQ", L"I2C", L"GPIO", L"BUS"
},
0x0003
};
#endif
//------------------------------------------------------------------------------
// Local Definitions
#define HDQ_DEVICE_COOKIE 'hdqD'
typedef struct {
DWORD cookie;
DWORD memBase;
DWORD memLen;
DWORD irq;
DWORD breakTimeout;
DWORD txTimeout;
DWORD rxTimeout;
OMAP2420_PRCM_REGS* pPRCMRegs;
OMAP2420_HDQ_REGS* pHDQRegs; // uses OMAP2420_HDQ_1WIRE_REGS_PA
HANDLE hParentBus;
LONG instances;
CRITICAL_SECTION cs;
DWORD sysIntr;
HANDLE hIntrEvent;
DWORD mode;
CEDEVICE_POWER_STATE powerState;
} HDQ_DEVICE;
BOOL bDumpOmapHdqRegs(HDQ_DEVICE* const pDevice);
//------------------------------------------------------------------------------
// Device registry parameters
static const DEVICE_REGISTRY_PARAM g_deviceRegParams[] = {
{
L"MemBase", PARAM_DWORD, TRUE, offset(HDQ_DEVICE, memBase),
fieldsize(HDQ_DEVICE, memBase), NULL // (VOID*)0x480B2000
}, {
L"MemLen", PARAM_DWORD, TRUE, offset(HDQ_DEVICE, memLen),
fieldsize(HDQ_DEVICE, memLen), NULL // (VOID*)0x00001000
}, {
L"Irq", PARAM_DWORD, TRUE, offset(HDQ_DEVICE, irq),
fieldsize(HDQ_DEVICE, irq), NULL // (VOID*)0x3A
}, {
L"BreakTimeout", PARAM_DWORD, FALSE, offset(HDQ_DEVICE, breakTimeout),
fieldsize(HDQ_DEVICE, breakTimeout), (VOID*)1 // msec
}, {
L"TxTimeout", PARAM_DWORD, FALSE, offset(HDQ_DEVICE, txTimeout),
fieldsize(HDQ_DEVICE, txTimeout), (VOID*)5 // in msec, > 8*190 microsec in spec
}, {
L"RxTimeout", PARAM_DWORD, FALSE, offset(HDQ_DEVICE, rxTimeout),
fieldsize(HDQ_DEVICE, rxTimeout), (VOID*)5 // in ms, > 20+8*190=1840 microsec
}
};
//------------------------------------------------------------------------------
// Local Functions
BOOL HDQ_Deinit(DWORD context);
BOOL HDQ_Write(DWORD context, UCHAR address, USHORT data);
BOOL HDQ_Read(DWORD context, UCHAR address, USHORT *pData);
BOOL HDQ_SetMode(DWORD context, DWORD mode);
/* VOID* HdqOpen(void)
* {
* HANDLE hDevice;
* DEVICE_CONTEXT_HDQ* pContext = NULL;
*
* hDevice=CreateFile(HDQ_DEVICE_NAME, 0, 0, NULL, 0, 0, NULL);
* if(hDevice==INVALID_HANDLE_VALUE) goto clean;
*
* // Allocate memory for our handler...
* if((pContext = (DEVICE_CONTEXT_HDQ *)LocalAlloc(
* LPTR, sizeof(DEVICE_CONTEXT_HDQ) )) == NULL)
* {
* CloseHandle(hDevice);
* goto clean;
* };
*
* // Get function pointers, fail when IOCTL isn't supported...
* if (DeviceIoControl(
* hDevice, IOCTL_DDK_GET_DRIVER_IFC, (VOID*)&DEVICE_IFC_HDQ_GUID,
* sizeof(DEVICE_IFC_HDQ_GUID), &pContext->ifc, sizeof(DEVICE_IFC_HDQ),
* NULL, NULL)==0)
* {
* CloseHandle(hDevice);
* LocalFree(pContext);
* pContext = NULL;
* goto clean;
* };
*
* // Save device handle
* pContext->hDevice=hDevice;
*
* clean:
* return pContext;
* }
*
* VOID HdqClose(HANDLE hContext)
* {
* DEVICE_CONTEXT_HDQ* pContext=(DEVICE_CONTEXT_HDQ*)hContext;
* CloseHandle(pContext->hDevice);
* LocalFree(pContext);
* }
*
* BOOL HdqWrite8(HANDLE hContext, UCHAR address, UCHAR data)
* {
* DEVICE_CONTEXT_HDQ *pContext=(DEVICE_CONTEXT_HDQ*)hContext;
* return pContext->ifc.pfnWrite(
* pContext->ifc.context, address, (USHORT)data);
* }
*
* BOOL HdqRead8(HANDLE hContext, UCHAR address, UCHAR* pData)
* {
* DEVICE_CONTEXT_HDQ* pContext=(DEVICE_CONTEXT_HDQ*)hContext;
* BOOL rc;
* USHORT data;
*
* if((rc=pContext->ifc.pfnRead(
* pContext->ifc.context, address, &data)))
* *pData=(UCHAR)data;
* return rc;
* }
*
* BOOL HdqWrite16(HANDLE hContext, UCHAR address, USHORT data)
* {
* DEVICE_CONTEXT_HDQ* pContext = (DEVICE_CONTEXT_HDQ *)hContext;
* return pContext->ifc.pfnWrite(
* pContext->ifc.context, address, data);
* }
*
* BOOL HdqRead16(HANDLE hContext, UCHAR address, USHORT *pData)
* {
* DEVICE_CONTEXT_HDQ *pContext = (DEVICE_CONTEXT_HDQ*)hContext;
*
* return pContext->ifc.pfnRead(pContext->ifc.context, address, pData);
* }
*
* VOID HdqSetMode(HANDLE hContext, DWORD mode)
* {
* DEVICE_CONTEXT_HDQ *pContext = (DEVICE_CONTEXT_HDQ*)hContext;
* pContext->ifc.pfnSetMode(pContext->ifc.context, mode);
* }
*/
//------------------------------------------------------------------------------
//
// Function: DllMain
//
// Standard Windows DLL entry point.
//
BOOL __stdcall DllMain(HANDLE hDLL, DWORD reason, VOID *pReserved)
{
switch (reason) {
case DLL_PROCESS_ATTACH:
DEBUGREGISTER(hDLL);
DisableThreadLibraryCalls((HMODULE)hDLL);
break;
}
return TRUE;
}
//------------------------------------------------------------------------------
//
// Function: HDQ_Init
//
// Called by device manager to initialize device.
//
DWORD HDQ_Init(LPCTSTR szContext, LPCVOID pBusContext)
{
DWORD rc=(DWORD)NULL;
HDQ_DEVICE* pDevice=NULL;
PHYSICAL_ADDRESS pa;
int i=0;
DEBUGMSG(ZONE_HDQ_1WIRE | ZONE_FUNCTION, (L"+HDQ_Init(%s, 0x%08x)\r\n", szContext, pBusContext));
// Create device structure
pDevice=(HDQ_DEVICE*)LocalAlloc(LPTR, sizeof(HDQ_DEVICE));
if(pDevice==NULL)
{
DWORD dwEr=GetLastError();
DEBUGMSG(ZONE_ERROR, (L"ERROR %lu: HDQ_Init: "
L"Failed allocate HDQ controller structure\r\n",dwEr
));
goto cleanUp;
};
// Set cookie
pDevice->cookie=HDQ_DEVICE_COOKIE;
// Initalize critical section
InitializeCriticalSection(&pDevice->cs);
// Read device parameters
if(GetDeviceRegistryParams(szContext, pDevice,
dimof(g_deviceRegParams), g_deviceRegParams) != ERROR_SUCCESS)
{
DEBUGMSG(ZONE_ERROR, (L"ERROR: HDQ_Init: "
L"Failed read HDQ driver registry parameters\r\n"
));
goto cleanUp;
};
// Open parent bus
pDevice->hParentBus=CreateBusAccessHandle(szContext);
if(pDevice->hParentBus==NULL)
{
DEBUGMSG(ZONE_ERROR, (L"ERROR: HDQ_Init: "
L"Failed open parent bus driver\r\n"
));
goto cleanUp;
};
// Set hardware to full power
SetDevicePowerState(pDevice->hParentBus, D0, NULL);
// Map the PRCM registers
pa.LowPart=OMAP2420_PRCM_REGS_PA;
pDevice->pPRCMRegs=(OMAP2420_PRCM_REGS*)MmMapIoSpace(pa,
sizeof(OMAP2420_PRCM_REGS), FALSE);
if(pDevice->pPRCMRegs==NULL)
{
DEBUGMSG(ZONE_ERROR, (L"ERROR: HDQ_Init: "
L"Failed to map PRCM registers\n"
));
goto cleanUp;
};
// Map the HDQ registers
pa.QuadPart=pDevice->memBase;
pDevice->pHDQRegs=(OMAP2420_HDQ_REGS*)MmMapIoSpace(pa,
sizeof(OMAP2420_HDQ_REGS), FALSE);
if(pDevice->pHDQRegs==NULL)
{
DEBUGMSG(ZONE_ERROR, (L"ERROR: HDQ_Init: "
L"Failed map HDQ controller registers\r\n"
));
goto cleanUp;
};
// Map HDQ_1WIRE interrupt
if(KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &pDevice->irq,
sizeof(pDevice->irq), &pDevice->sysIntr,
sizeof(pDevice->sysIntr), NULL)==0)
{
DEBUGMSG(ZONE_ERROR, (L"ERROR: HDQ_Init: "
L"Failed map HDQ/1WIRE controller interrupt\r\n"
));
goto cleanUp;
};
// Create interrupt event
pDevice->hIntrEvent=CreateEvent(NULL, FALSE, FALSE, NULL);
if(pDevice->hIntrEvent==NULL)
{
DEBUGMSG(ZONE_ERROR, (L"ERROR: HDQ_Init: "
L"Failed create interrupt event\r\n"
));
goto cleanUp;
};
// Initialize interrupt
if(InterruptInitialize(pDevice->sysIntr,
pDevice->hIntrEvent, NULL, 0)==0)
{
DEBUGMSG (ZONE_ERROR, (L"ERROR: HDQ_Init: "
L"InterruptInitialize failed\r\n"
));
goto cleanUp;
};
DEBUGMSG(ZONE_ERROR, (L"\tHDQ_Init: "
L"Resetting OMAP HDQ module...\r\n"
));
// reset the hdq device
/* SETREG32(&pDevice->pHDQRegs->ulHDQ_SYSCONFIG,HDQ_SYSCONFIG_SOFTRESET);
// wait for the reset to be completed
for(; i<50; i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -