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

📄 sidewindertunerprop.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. 
*
\******************************************************************* ---*/ 

// SidewinderTunerProp.cpp: implementation of the CSidewinderTunerProp class.
//
//////////////////////////////////////////////////////////////////////

#include "SidewinderTunerProp.h"
#include "device.h"
#include "debug.h"
#include "registryAccess.h"

#include "GenSiTuner.h"
#include "tunerinfo.h"
#include "miscfuncs.h"
#include "IVideoDecoder.h"
#include "Merlin.h"
#include "colibri.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////
//CSidewinderTunerProp::CSidewinderTunerProp
//
// Initialize member variables to some default values for the tuner
//
CSidewinderTunerProp::CSidewinderTunerProp(Device* p_device, I2cIF* p_i2c):
ITunerProperties(p_device, p_i2c)
{
    PDEVICE_OBJECT pdo = p_device->getPdo();

    RegistryAccess registry_access(pdo);

    _tuner_type = SIDEWINDER;
    
    RtlZeroMemory(&_sidewinder_private,sizeof(_sidewinder_private));
    
    p_device->acquireTunerMutex();
    _p_tuner1 = allocateTuner(p_device, _tuner_type, p_i2c);
    p_device->releaseTunerMutex();

    // Todo Remove this logic for second tuner.
    if(registry_access.readDword("Tuner2Type", &_tuner_type) == STATUS_SUCCESS)
    {
        p_device->acquireTunerMutex();
        _p_tuner2 = allocateTuner(p_device, _tuner_type, p_i2c);
        p_device->releaseTunerMutex();
    }

    registerFilter(pdo, p_device->getMediumId());

    registry_access.readDword("TunerCountryCode", &_country_code);

    DWORD use_pll_tune = 0;
    registry_access.readDword("TunerUsePllTuningStrategy", &use_pll_tune);
    _use_pll_tune = (BOOLEAN)use_pll_tune;    
}

CSidewinderTunerProp::~CSidewinderTunerProp()
{
}

/////////////////////////////////////////////////////////////////////////////////////////
//CSidewinderTunerProp::powerUp
//
// Power up the device.  We just need to set the tuner to it's current frequency.
//
VOID CSidewinderTunerProp::powerUp()
{
    setCountry(_country_code);
  
    // reset all settings of Sidewinder tuner
    if(_p_tuner1)
    {
        _p_device->acquireTunerMutex();

        // Reinitialize the tuner
        BOOLEAN bRetVal = _p_tuner1->Initialize();

        _p_device->releaseTunerMutex();

        ASSERT(bRetVal == TRUE);

        if (bRetVal == TRUE)
        {
            _p_device->setTunerMode(TUNER_MODE_ANALOG);           
            DWORD old_frequency = _frequency;   
            _frequency = 0; // force set frequency
            setFrequency(old_frequency, _country_code, KS_TUNER_TUNING_EXACT);
        }
    }
}

/////////////////////////////////////////////////////////////////////////////////////////
//CSidewinderTunerProp::powerDown
//
// Performs tuner powerdown 
// Note: Implementation required only for Xceive tuner which requires FW.
//

VOID CSidewinderTunerProp::powerDown()
{
    DbgLogInfo(("CSidewinderTunerProp::powerDown()"));
}

/////////////////////////////////////////////////////////////////////////////////////////
//CSidewinderTunerProp::allocateTuner
//
// Creates the GenSiTunerObject and instantiates the pointers for the object.
//
ITuner* CSidewinderTunerProp::allocateTuner(Device* p_device, DWORD tuner_type, I2cIF* p_i2c)
{

    ITuner *p_tuner=NULL;

    //Get the I2C address
    DWORD i2c_address = 0xC6;
    RegistryAccess registry_access(p_device->getPdo());
    registry_access.readDword("TunerI2CAddress", &i2c_address);

    //Get tuner crystal freqency
    DWORD tuner_freq=0;
    registry_access.readDword("AnalogTunerXTALFreq",&tuner_freq);
    
    //Get Saw filter type,currently for Polaris, Saw filter frequency can be indicated by the saw filter type
    //But to keep backward compability and possible future design, we still keep the Saw_freq filed in sidewinder private struct
    DWORD saw_filter_type=SIDEWINDER_TEMEX_SAW;
    registry_access.readDword("SawFilterType",&saw_filter_type);    
    
    // Send country code to tuner library for Sidwinder Tuner
    DWORD country_code = 0xFFFFFFFF;
    registry_access.readDword("TunerCountryCode", &country_code);
    if(country_code == 0xFFFFFFFF)
    {
        // defaults to USA mode as standard
        country_code = 1;
    }
    

    // Sidewinder tuner doesn't have a GPIO reset object requirement, but we have to pass in
    // the IF frequency callback to setup DIF
    // Setup the sidewinder private callback struct
    _sidewinder_private.p_context               = (void *) p_device->getColibri();
    _sidewinder_private.p_callback              = &(Colibri::static_setColibriForLowIF);
    //Polaris need to have a interrupt driven AGC reset instead of the callback
    _sidewinder_private.p_gen_si_tuner_callback = &(DirectIF::static_Gen_Si_Tuner_Callback);
    _sidewinder_private.saw_freq                = g_saw_freq_and_offsets[saw_filter_type].saw_frequency;
    _sidewinder_private.saw_type                = saw_filter_type;
    _sidewinder_private.xtal_freq               = tuner_freq*1000000;
  
    p_tuner = new GenSiTuner(p_i2c, NULL, country_code, (BYTE)i2c_address, (void *) &_sidewinder_private);

    if (p_tuner)
    {
        // Initialize the tuner
        BOOLEAN bRetVal = p_tuner->Initialize();

        if (!bRetVal)
        {
            DbgLogError(("CSidewinderTunerProp::allocateTuner : GenSituner created but failed to initialised\n"));
        }
    }
    else
    {
        DbgLogError(("CSidewinderTunerProp::allocateTuner : GenSituner created Failed !!!\n"));
    }
    return p_tuner;
}

/////////////////////////////////////////////////////////////////////////////////////////
//CSidewinderTunerProp::setCountry
//
// Sets the country code in register and tuners library after making sure that
// that the standard is supported for this country. Implementation of this function
// is same for Xceive and Sidewinder.
//
VOID CSidewinderTunerProp::setCountry(ULONG country)
{
    KS_AnalogVideoStandard video_standard;
    
    AUDIO_STANDARD audio_standard;    

    if(country == 0xFFFFFFFF)
    {
        return; //Invalid country
    }

    if(!getVideoAndAudioStandardsForCountry(country, &video_standard, &audio_standard))
    {
        return;
    }

    //Check if the video standard is valid for the TV tuner
    ITuner* p_tuner = getTuner(KSPROPERTY_TUNER_MODE_TV);
    if(!p_tuner)
    {
        //No TV tuner
        return;
    }
    
    _p_device->setTunerMode(TUNER_MODE_ANALOG);

    _p_device->acquireTunerMutex();

    //inform the tuner library about the country code
    p_tuner->setCountry(country);

    //Get the video and audio standards for the country.
    DWORD supported_standards = 
        p_tuner->getSupportedStandards(KSPROPERTY_TUNER_MODE_TV);

    _p_device->releaseTunerMutex();

    //If video standard is not supported
    if(!(video_standard & supported_standards))
    {
        //Country code is invalid for this tuner
        return;
    }

    DbgLogInfo(("setting country code(%d) Standard (%x)\n", country, video_standard));

    //The country code is ok.  Set the audio and video stanards
    _p_device->getAudDec()->setAudioStandard(audio_standard);

    _p_device->setVideoStandard(video_standard);    

    _p_device->acquireTunerMutex();

    // notes: we must call setCountry before call setStandard for xceive support
    p_tuner->setCountry(country);

    p_tuner->setStandard(video_standard);

    _p_device->releaseTunerMutex();     

    //Write the country code out to the registry to use the next time the driver loads
    PDEVICE_OBJECT pdo = _p_device->getPdo();

    RegistryAccess registry_access(pdo);

    registry_access.writeDword("TunerCountryCode", country);

    _country_code = country;
}

/////////////////////////////////////////////////////////////////////////////////////////
//CSidewinderTunerProp::setFrequency
//
// Helper function to set the frequency.
//
// Calls the child class to set the frequency and sets the frequency member variable to
// reflect the new frequency.
//
// Starts the channel change thread to keep track of when the channel change is complete
// since it can consist of multiple setFrequency calls.
//
NTSTATUS CSidewinderTunerProp::setFrequency(ULONG frequency, ULONG country, DWORD tuning_flags)
{
    _p_device->setTunerMode(TUNER_MODE_ANALOG);

    // call the base class handler.
    return ITunerProperties::setFrequency(frequency, country, tuning_flags);
}

////////////////////////////////////////////////////////////////////////////////////////
//CSidewinderTunerProp::setMode
//
// Sets the tuner mode. (To TV, FM, or ATSC)
//
//Virtual function in case any child class needs to do anything extra to set up a mode.
//
NTSTATUS CSidewinderTunerProp::setMode(ULONG mode)
{
    ITuner* p_tuner = getTuner(mode);
    if(!p_tuner)
    {
        return STATUS_INVALID_PARAMETER;
    }   
    
    _p_device->setTunerMode(TUNER_MODE_ANALOG);

    if(mode != _mode)
    {
        // We are switching to TV, so call setAudioInput. this will make sure
        // that we don't get a burst of static while loading the TV firmware
        // if we were previously in FM mode.
        _p_device->setMode(mode);
    }

    _p_device->acquireTunerMutex();

    //Set mode in SideWinder
    ((GenSiTuner *)p_tuner)->setMode(mode);
    
    _p_device->releaseTunerMutex();       

    _p_device->setMode(mode);    

    return STATUS_SUCCESS;
}

/////////////////////////////////////////////////////////////////////////////////////////
//CSidewinderTunerProp::resetTunerTVMode
//
// Performs tuner resetTunerTVMode 
// Note: only applied to Xceive tuner
//

VOID CSidewinderTunerProp::resetTunerTVMode()
{
    DbgLogInfo(("CSidewinderTunerProp::resetTunerTVMode()"));

    ITuner* p_AnalogTuner = getTuner();

    _p_device->acquireTunerMutex();

    if (p_AnalogTuner)
        ((GenSiTuner *)p_AnalogTuner)->resetCurrentTVmode();

    _frequency = 0;

    _p_device->releaseTunerMutex();
}

⌨️ 快捷键说明

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