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

📄 bdatunerfilter.cpp

📁 完整的基于Conxant平台的USB电视棒的WIN驱动程序。
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*+++ *******************************************************************\ 
* 
*  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. 
*
\******************************************************************* ---*/ 

#include "bdaTunerFilter.h"
#include "Bda_Descriptors.h"
#include "device.h"
#include "miscfuncs.h"
#include "debug.h"
#include "IBdaTuner.h"
#include "RegistryAccess.h"
#include "CrossbarProp.h"
#include "cusbintf.h"
#include "Polaris_GPIOPin.h"
#include "GenSiTuner.h"
#include "ITunerProperties.h"

/////////////////////////////////////////////////////////////////////////////////////////
BdaTunerFilter::BdaTunerFilter(Device* p_device) :
_bda_change_state(BDA_CHANGES_COMPLETE),
_tuner_is_initialized(FALSE),
_freq_initialized(FALSE),
_p_device(p_device)
{
    //Initialize the current and pending frequency settings.
    _current_freq.frequency = 0;
    _current_freq.frequency_multiplier = 1;
    _current_freq.channel_bandwidth = 0;

    _pending_freq.frequency = 0;
    _pending_freq.frequency_multiplier = 1;
    _pending_freq.channel_bandwidth = 0;

    _p_tuner = _p_device->getBdaTuner();

    if(!_p_device->isRunning())
    {
        InitBdaDevices();
    }
   
}

/////////////////////////////////////////////////////////////////////////////////////////
BdaTunerFilter::~BdaTunerFilter()
{
    DbgLogTrace((__FUNCTION__));

    if(_p_tuner && !_p_device->isRunning())
    {
        _p_tuner->bdaTuner_powerDown(); 
    }    
    
}


VOID  BdaTunerFilter::InitBdaDevices()
{
    if(_p_device==NULL)
        return;

    USHORT revID=_p_device->getRevID();
    
    if(revID == POLARIS_REVID_T0)
    {
        _p_device->setUSBConfiguration(VIDEO_INPUT_BDA);
    }
    else if(revID>=POLARIS_REVID_A0 )
    {   
        //For A0        
        if((_p_device->getUSBType() == USB_BUS_POWER)) //bus power
        {
            _p_device->setPowerMode(POLARIS_AVMODE_DIGITAL);
        }
    }
    
    // AGC mux for Demod/Analog
    // 0 - Demod,  1 - Analog 
    PolarisGPIOPin* pGPIOpin = _p_device->getGPIOPin();    
    if(pGPIOpin)
    {   
        // Switch to Demod
        pGPIOpin->SetGpioPinLogicValue(pGPIOpin->getAGCAnalogDigitalMuxSelectGPIOBit(), 0);
    }
    
    //Tuner must be re-initialized to accompany with demodulator
    //Otherwise, tuner will not able to lock channel once again for next TS BDA filter graph
    //This solutions is the workaround way. It will be replaced by makeing _p_device->resetAnalogTuner() really 
    //taken effect for Sidewinder initialization in Altair lib.
    if(revID>=POLARIS_REVID_A0)
    {
        if(_p_device->getUSBType()==USB_BUS_POWER)
        {
            ITunerProperties * p_tuner_prop=_p_device->getTunerProperties();
            if(p_tuner_prop)
            {
                ITuner *p_analog_tuner=p_tuner_prop->getTuner();
                if(p_analog_tuner)
                {
                    p_analog_tuner->Initialize();
                }
            }
        }
    }
    
    
    if(_p_tuner)
    {           
        _p_tuner->bdaTuner_powerUp();
        _p_device->setBdaTunerPowerUpState(FALSE);        
    }
}

/////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS BdaTunerFilter::static_Create(PKSFILTER  p_ks_filter, 
                                       PIRP       p_irp)
{
    Device* p_device = getDevice(p_irp);

    p_ks_filter->Context = new BdaTunerFilter(p_device);

    if( !p_ks_filter->Context )
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    NTSTATUS Status = BdaInitFilter(p_ks_filter,(BDA_FILTER_TEMPLATE *)p_device->getFilterTemplate());
    if( !NT_SUCCESS(Status) )
    {
        DbgLogError(("BdaTunerFilter: static_Create : BdaInitFilter failed\n"));
        return STATUS_UNSUCCESSFUL;
    }

    return STATUS_SUCCESS;

}

/////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS BdaTunerFilter::static_Close(PKSFILTER  p_ks_filter, 
                                      PIRP       p_irp)
{
    delete reinterpret_cast<BdaTunerFilter*>( p_ks_filter->Context );
    p_ks_filter->Context = NULL;
    return STATUS_SUCCESS;
}


/////////////////////////////////////////////////////////////////////////////////////////
NTSTATUS BdaTunerFilter::static_RegisterFilter(KSDEVICE* p_ks_device, DWORD medium_id)
{
    KSPIN_MEDIUM antenna_pin_medium = {0, 0, 0};
    const ULONG pin_count = 2;

    //Create an array of mediums
    KSPIN_MEDIUM mediums[pin_count];
    
    mediums[BDA_PIN_ANTENNA] = antenna_pin_medium;
    mediums[BDA_PIN_TRANSPORT] = g_bda_transport_pin_medium; 
    mediums[BDA_PIN_TRANSPORT].Id = medium_id;
    
    //Create an array of pin directions
    const BOOL INPUT_PIN  = FALSE;
    const BOOL OUTPUT_PIN = TRUE;
    
    BOOL pin_directions[pin_count] =
    {
        INPUT_PIN,
        OUTPUT_PIN
    };

    return KsRegisterFilterWithNoKSPins(
        p_ks_device->PhysicalDeviceObject,
        &KSCATEGORY_BDA_NETWORK_TUNER,
        pin_count,
        pin_directions,
        mediums,
        NULL);
}

//////////////////////////////////////////////////////////////////////////////
NTSTATUS BdaTunerFilter::AllocateFilterDescriptorForMediums
(
    IN KSFILTER_DESCRIPTOR FilterDescriptor,
    IN KSOBJECT_BAG ObjectBag,
    IN DWORD medium_id,
    OUT PKSFILTER_DESCRIPTOR *ppFilterDescriptor
    )
{
    NTSTATUS ntStatus = STATUS_SUCCESS;    

    // Dynamically allocate filter descriptor. 
    *ppFilterDescriptor = (PKSFILTER_DESCRIPTOR) 
        ExAllocatePoolWithTag(NonPagedPool, sizeof(KSFILTER_DESCRIPTOR), 'txnC');
    if (!*ppFilterDescriptor)
    {
        DbgLogError(("BdaTunerFilter:AllocateFilterDescriptorForMediums: Insufficient memory\n"));
        ntStatus = STATUS_NO_MEMORY;
        return ntStatus;
    }
    ntStatus = KsAddItemToObjectBag(ObjectBag, *ppFilterDescriptor, NULL);
    if (!NT_SUCCESS(ntStatus))
    {
        DbgLogError(("BdaTunerFilter:AllocateFilterDescriptorForMediums: Failed to add filter descriptor to object bag\n"));
        ExFreePool(*ppFilterDescriptor);
        return ntStatus;
    }
    // Use the values from the original descriptor by default (even if they are static)
    // Only those fields will be reallocated that need to have updated values - in this
    // case the pin descriptors and the mediums
    **ppFilterDescriptor = FilterDescriptor;

    if (FilterDescriptor.PinDescriptorsCount == 0)
    {
        return STATUS_SUCCESS;
    }

    // Allocate the pin descriptor list dynamically
    KSPIN_DESCRIPTOR_EX* pPinDescriptorsEx = 
        (KSPIN_DESCRIPTOR_EX *) ExAllocatePoolWithTag(NonPagedPool, 
                                  FilterDescriptor.PinDescriptorSize * FilterDescriptor.PinDescriptorsCount,
                                  'txnC');
    if (!pPinDescriptorsEx)
    {
        DbgLogError(("BdaTunerFilter:AllocateFilterDescriptorForMediums: Insufficient memory for pin descriptors\n"));
        ntStatus = STATUS_NO_MEMORY;
        return ntStatus;
    }
    ntStatus = KsAddItemToObjectBag(ObjectBag, pPinDescriptorsEx, NULL);
    if (!NT_SUCCESS(ntStatus))
    {
        DbgLogError(("BdaTunerFilter:AllocateFilterDescriptorForMediums: Failed to add pin descriptors to object bag\n"));
        ExFreePool(pPinDescriptorsEx);
        return ntStatus;
    }

    // Copy default values over even if the default pointers are static. Update/reallocate
    // only required fields - namely the mediums
    RtlCopyMemory(pPinDescriptorsEx, FilterDescriptor.PinDescriptors, 
        FilterDescriptor.PinDescriptorSize * FilterDescriptor.PinDescriptorsCount);


    // Update/reallocate the relevant fields - the mediums
    for (unsigned int i = 0; i < FilterDescriptor.PinDescriptorsCount; i++)
    {

        // The size of the pin descriptors is specified in the filter descriptor
        KSPIN_DESCRIPTOR_EX* pCurrentPinDescriptorEx = 
            (KSPIN_DESCRIPTOR_EX *) (((BYTE *)pPinDescriptorsEx) + i * FilterDescriptor.PinDescriptorSize);
        KSPIN_DESCRIPTOR* pPinDescriptor = &pCurrentPinDescriptorEx->PinDescriptor;
        KSPIN_MEDIUM *pPinMediums = NULL;

        // If this pin has no mediums continue
        if (pPinDescriptor->MediumsCount == 0) {
            continue;
        }

        // Allocate memory for the pin mediums
        pPinMediums = (KSPIN_MEDIUM *)ExAllocatePoolWithTag(NonPagedPool, 
                                        sizeof(KSPIN_MEDIUM) * pPinDescriptor->MediumsCount, 
                                        'txnC');
        if (!pPinMediums)
        {
            DbgLogError(("BdaTunerFilter:AllocateFilterDescriptorForMediums: Insufficient memory for pin mediums\n"));
            ntStatus = STATUS_NO_MEMORY;
            return ntStatus;
        }
        ntStatus = KsAddItemToObjectBag(ObjectBag, pPinMediums, NULL);
        if (!NT_SUCCESS(ntStatus))
        {
            DbgLogError(("BdaTunerFilter:AllocateFilterDescriptorForMediums: Failed to add pin mediums to object bag\n"));
            ExFreePool(pPinMediums);
            return ntStatus;
        }

        // Copy over all the mediums. The Medium.Set guid is the same across all instances.
        RtlCopyMemory(pPinMediums, pPinDescriptor->Mediums, 
            sizeof(KSPIN_MEDIUM) * pPinDescriptor->MediumsCount);

        for (unsigned int j = 0; j < pPinDescriptor->MediumsCount; j++)
        {
            // The core of this function. Update the Medium.Id

            // This allows multiple instances to be uniquely identified and
            // connected.  The value used in .Id is not important, only that
            // it is unique for each hardware connection. For example, one could
            // use serial numbers to generate such a unique Id.

            ((KSPIN_MEDIUM *)pPinMediums)[j].Id = medium_id;

⌨️ 快捷键说明

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