📄 sidewindertunerprop.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 + -