📄 polarisusbinterface.cpp
字号:
/*+++ *******************************************************************\
*
* Copyright and Disclaimer:
*
* ---------------------------------------------------------------
* This software is provided "AS IS" without warranty of any kind,
* either expressed or implied, including but not limited to the
* implied warranties of noninfringement, merchantability and/or
* fitness for a particular purpose.
* ---------------------------------------------------------------
*
* Copyright (c) 2008 Conexant Systems, Inc.
* All rights reserved.
*
\******************************************************************* ---*/
extern "C"
{
#include <wdm.h>
}
#include <windef.h>
#include "PolarisUsbInterface.h"
#include "cusbintf.h"
#include "debug.h"
#include "device.h"
////////////////////////////////////////////////////////////////////////////////////////
PolarisUsbInterface::PolarisUsbInterface(CUsbInterface *pUsbInterface) :
_p_usb(pUsbInterface),
_i2c_period(I2C_SPEED_400K),
_is_initialized(FALSE)
{
KeInitializeMutex(&_mutex, 0);
_i2c_nostop=0x0;
_i2c_reserve=0x0;
}
/////////////////////////////////////////////////////////////////////////////////////////
PolarisUsbInterface::~PolarisUsbInterface()
{
Release();
}
/////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS PolarisUsbInterface::selectInterface(UCHAR usb_interface, UCHAR alternate_setting)
{
//Synchronize with any commands being sent
KeWaitForSingleObject(&_mutex, Executive, KernelMode, FALSE, NULL);
//Change the interface
NTSTATUS status = _p_usb->UsbInterfaceSelect(usb_interface, alternate_setting);
KeReleaseMutex(&_mutex, FALSE);
return status;
}
/////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS PolarisUsbInterface::InitDevice()
{
NTSTATUS ntStatus;
if(_is_initialized)
{
DbgLogInfo(("PolarisUsbInterface::InitDevice() Already Initialized. Skipping..."));
return (STATUS_SUCCESS);
}
// power management
//
powerUp();
_is_initialized = TRUE;
return (STATUS_SUCCESS);
}
/////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS PolarisUsbInterface::Release(VOID)
{
_is_initialized = FALSE;
return (STATUS_SUCCESS);
}
NTSTATUS PolarisUsbInterface::powerUp()
{
return (STATUS_SUCCESS);
}
/////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS PolarisUsbInterface::powerDown()
{
return (STATUS_SUCCESS);
}
/////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS PolarisUsbInterface::setGpio(DWORD gpio_bit, BYTE* p_gpio_value, BYTE len, BYTE request)
{
NTSTATUS status = STATUS_SUCCESS;
VENDOR_REQUEST_IN VendorReq;
BYTE req_type;
KeWaitForSingleObject(&_mutex, Executive, KernelMode, FALSE, NULL);
if(request == 0)
req_type = VRT_SET_GPIO; //0x8 gpio
else
req_type = VRT_SET_GPIE; //0xa gpie
VendorReq.bRequest = req_type;
VendorReq.wValue = (WORD)(gpio_bit>>16 & 0xffff); //[31:16]
VendorReq.wIndex = (WORD)(gpio_bit & 0xffff); //[15:0]
VendorReq.wLength = len;
VendorReq.bData = 0;
VendorReq.direction = USBD_TRANSFER_DIRECTION_OUT;
VendorReq.pBuff = new BYTE[VendorReq.wLength];
if (NULL != VendorReq.pBuff)
{
RtlZeroMemory(VendorReq.pBuff, VendorReq.wLength);
RtlCopyMemory(VendorReq.pBuff, p_gpio_value, VendorReq.wLength);
}
status = _p_usb->Ezusb_VendorRequest(&VendorReq);
if (!NT_SUCCESS(status))
{
DbgLogError(("PolarisUsbInterface::setGpio, output buffer failed with status %x\n", status));
}
delete [] VendorReq.pBuff;
KeReleaseMutex(&_mutex, FALSE);
return status;
}
/////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS PolarisUsbInterface::getGpio(DWORD gpio_bit, PBYTE p_gpio_value ,BYTE len, BYTE request)
{
NTSTATUS status = STATUS_SUCCESS;
VENDOR_REQUEST_IN VendorReq;
BYTE req_type;
KeWaitForSingleObject(&_mutex, Executive, KernelMode, FALSE, NULL);
if(request == 0)
req_type = VRT_GET_GPIO; // 0x9 gpio
else
req_type = VRT_GET_GPIE; //0xb gpie
VendorReq.bRequest = req_type; //channel number
VendorReq.wValue =(WORD)(gpio_bit>>16 & 0xff); //[31:16]
VendorReq.wIndex = (WORD)(gpio_bit & 0xff); //[15:0]
VendorReq.wLength = len;
VendorReq.bData = 0;
VendorReq.direction = USBD_TRANSFER_DIRECTION_IN;
VendorReq.pBuff = p_gpio_value;
status = _p_usb->Ezusb_VendorRequest(&VendorReq);
if (!NT_SUCCESS(status))
{
DbgLogError(("PolarisUsbInterface::getGpio, output buffer failed with status %x\n", status));
}
KeReleaseMutex(&_mutex, FALSE);
return status;
}
NTSTATUS PolarisUsbInterface::getPolarisRegister(WORD address, PBYTE buffer ,BYTE len)
{
NTSTATUS status = STATUS_SUCCESS;
VENDOR_REQUEST_IN VendorReq;
BYTE req_type;
BYTE tmp_wValue;
KeWaitForSingleObject(&_mutex, Executive, KernelMode, FALSE, NULL);
req_type = VRT_GET_REGISTER; //0xd get
switch(len)
{
case 1:
tmp_wValue = ENABLE_ONE_BYTE;
break;
case 2:
tmp_wValue = ENABLE_TWE_BYTE;
break;
case 3:
tmp_wValue = ENABLE_THREE_BYTE;
break;
case 4:
tmp_wValue = ENABLE_FOUR_BYTE;
break;
default:
KeReleaseMutex(&_mutex, FALSE);
return STATUS_INVALID_PARAMETER;
}
VendorReq.bRequest = req_type; //channel number
VendorReq.wValue = tmp_wValue; // 4 bytes is ok
VendorReq.wIndex = address; //[15:0]
VendorReq.wLength = len;
VendorReq.bData = 0;
VendorReq.direction = USBD_TRANSFER_DIRECTION_IN; //read
VendorReq.pBuff = buffer;
status = _p_usb->Ezusb_VendorRequest(&VendorReq);
if (!NT_SUCCESS(status))
{
DbgLogError(("PolarisUsbInterface::getPolarisRegister, output buffer failed with status %x\n", status));
}
KeReleaseMutex(&_mutex, FALSE);
return status;
}
NTSTATUS PolarisUsbInterface::setPolarisRegister(WORD address, PBYTE buffer ,BYTE len)
{
DbgLog(("PolarisUsbInterface::setPolarisRegister : 0x%x, 0x%x,0x%x,0x%x,0x%x, %d\n", address, *buffer,*(buffer+1),*(buffer+2),*(buffer+3), len));
NTSTATUS status = STATUS_SUCCESS;
VENDOR_REQUEST_IN VendorReq;
BYTE req_type;
BYTE tmp_wValue;
KeWaitForSingleObject(&_mutex, Executive, KernelMode, FALSE, NULL);
req_type = VRT_SET_REGISTER; //0xc set
switch(len)
{
case 1:
tmp_wValue = ENABLE_ONE_BYTE;
break;
case 2:
tmp_wValue = ENABLE_TWE_BYTE;
break;
case 3:
tmp_wValue = ENABLE_THREE_BYTE;
break;
case 4:
tmp_wValue = ENABLE_FOUR_BYTE;
break;
default:
KeReleaseMutex(&_mutex, FALSE);
return STATUS_INVALID_PARAMETER;
}
VendorReq.bRequest = req_type; //channel number
VendorReq.wValue = tmp_wValue; // 4 bytes is ok
VendorReq.wIndex = address; //[15:0]
VendorReq.wLength = len;
VendorReq.bData = 0;
VendorReq.direction = USBD_TRANSFER_DIRECTION_OUT; //write
VendorReq.pBuff = new BYTE[VendorReq.wLength];
if (NULL != VendorReq.pBuff)
{
RtlZeroMemory(VendorReq.pBuff, VendorReq.wLength);
RtlCopyMemory(VendorReq.pBuff, buffer, VendorReq.wLength);
}
status = _p_usb->Ezusb_VendorRequest(&VendorReq);
if (!NT_SUCCESS(status))
{
DbgLogError(("PolarisUsbInterface::setPolarisRegister, output buffer failed with status %x\n", status));
}
delete [] VendorReq.pBuff;
KeReleaseMutex(&_mutex, FALSE);
return status;
}
/////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS PolarisUsbInterface::sendCommand(PBYTE p_out_buffer, //data sent to the device
DWORD out_buffer_size,
PBYTE p_in_buffer, //data received from the device
DWORD in_buffer_size)
{
NTSTATUS status = STATUS_SUCCESS;
BYTE tmp =0;
VENDOR_REQUEST_IN VendorReq;
KeWaitForSingleObject(&_mutex, Executive, KernelMode, FALSE, NULL);
POLARIS_REV_ID rev_id = (POLARIS_REV_ID)_p_usb->getRevID();
BYTE saddr_len = 0;
if(out_buffer_size)
{
saddr_len = p_out_buffer[2];
if(rev_id >=POLARIS_REVID_A0)
{
if(saddr_len == 1) // TODO, need check saddr_len == 0
VendorReq.wValue = p_out_buffer[1]<<9|_i2c_period<<4|saddr_len<<2|_i2c_nostop<<1|I2C_SYNC|_i2c_reserve<<6;
else
VendorReq.wValue = p_out_buffer[1]<<9|_i2c_period<<4|saddr_len<<2|_i2c_nostop<<1|I2C_SYNC|_i2c_reserve<<6;
}
else
{
if(saddr_len == 1) // TODO, need check saddr_len == 0
VendorReq.wValue = p_out_buffer[1]<<9|_i2c_period<<4|saddr_len<<2|I2C_STOP<<1|I2C_SYNC;
else
VendorReq.wValue = p_out_buffer[1]<<9|_i2c_period<<4|saddr_len<<2|I2C_NOSTOP<<1|I2C_SYNC;
}
VendorReq.bRequest = p_out_buffer[0]; //channel number
switch(saddr_len)
{
case 0:
VendorReq.wIndex = 0; //need check
tmp = 3;
break;
case 1:
VendorReq.wIndex = p_out_buffer[3];
tmp = 4;
break;
case 2:
VendorReq.wIndex = p_out_buffer[4]<<8|p_out_buffer[3];
tmp = 5;
break;
}
VendorReq.wLength = p_out_buffer[tmp];
VendorReq.bData = 0;
VendorReq.direction = USBD_TRANSFER_DIRECTION_OUT;
VendorReq.pBuff = new BYTE[VendorReq.wLength];
if (NULL != VendorReq.pBuff)
{
RtlZeroMemory(VendorReq.pBuff, VendorReq.wLength);
RtlCopyMemory(VendorReq.pBuff, &p_out_buffer[tmp+1], VendorReq.wLength);
}
#if 0
DbgLogInfo(("VendorReq.bRequest = %x\n", VendorReq.bRequest));
DbgLogInfo(("VendorReq.wValue = %x\n", VendorReq.wValue));
DbgLogInfo(("VendorReq.wIndex = %x\n",VendorReq.wIndex));
DbgLogInfo(("VendorReq.wLength = %x\n",VendorReq.wLength));
for(int i =0; i<VendorReq.wLength;i++)
DbgLogInfo(("VendorReq.pBuff[i] = %x\n", VendorReq.pBuff[i]));
#endif
status = _p_usb->Ezusb_VendorRequest(&VendorReq);
if (!NT_SUCCESS(status))
{
DbgLogError(("PolarisUsbInterface::sendCommand, output buffer failed with status %x\n", status));
}
delete [] VendorReq.pBuff;
}
if(in_buffer_size) // read
{
saddr_len = p_in_buffer[2];
if(rev_id >=POLARIS_REVID_A0)
{
VendorReq.wValue = p_in_buffer[1]<<9|_i2c_period<<4|saddr_len<<2|I2C_SYNC;
}
else
{
VendorReq.wValue = p_in_buffer[1]<<9|_i2c_period<<4|saddr_len<<2|I2C_NOSTOP<<1|I2C_SYNC;
}
VendorReq.bRequest = p_in_buffer[0]+4; //channel number, for read, spec required channel_num +4
switch(saddr_len)
{
case 0:
VendorReq.wIndex =0;
tmp = 3;
break;
case 1:
VendorReq.wIndex = p_in_buffer[3];
tmp =4;
break;
case 2:
VendorReq.wIndex = p_in_buffer[4]<<8|p_in_buffer[3];
tmp = 5;
break;
}
VendorReq.wLength = (WORD)p_in_buffer[tmp];
VendorReq.bData = 0;
VendorReq.direction = USBD_TRANSFER_DIRECTION_IN; // read
VendorReq.pBuff = &p_in_buffer[tmp+1];
#if 0
DbgLogInfo(("VendorReq.bRequest = %x\n", VendorReq.bRequest));
DbgLogInfo(("VendorReq.wValue = %x\n", VendorReq.wValue));
DbgLogInfo(("VendorReq.wIndex = %x\n",VendorReq.wIndex));
DbgLogInfo(("VendorReq.wLength = %x\n",VendorReq.wLength));
for(int j =0; j<VendorReq.wLength;j++)
DbgLogInfo(("VendorReq.pBuff[j] = %x\n", VendorReq.pBuff[j]));
#endif
status = _p_usb->Ezusb_VendorRequest(&VendorReq);
if(!NT_SUCCESS(status))
{
DbgLogError(("PolarisUsbInterface::sendCommand, input buffer failed with status %x\n", status));
}
}
KeReleaseMutex(&_mutex, FALSE);
return status;
}
////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS PolarisUsbInterface::getI2CSpeed(PBYTE pbuffer)
{
*pbuffer = _i2c_period;
return STATUS_SUCCESS;
}
NTSTATUS PolarisUsbInterface::setI2CSpeed(UCHAR i2c_period)
{
_i2c_period = i2c_period;
return STATUS_SUCCESS;
}
////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS PolarisUsbInterface::setCommandFormat(BOOLEAN first,BOOLEAN last)
{
if((first == TRUE) && (last == FALSE))
{
_i2c_nostop = 0x1;
_i2c_reserve = 0x0;
}
else if((first == FALSE) && (last == FALSE))
{
_i2c_nostop = 0x1;
_i2c_reserve = 0x1;
}
else if((first == FALSE) && (last == TRUE))
{
_i2c_nostop = 0x0;
_i2c_reserve = 0x1;
}
else
{
_i2c_nostop = 0x0;
_i2c_reserve = 0x0;
}
return STATUS_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -