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

📄 polarisusbinterface.cpp

📁 完整的基于Conxant平台的USB电视棒的WIN驱动程序。
💻 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 + -