/*------------------------------------------------------------------------------
 Functions
------------------------------------------------------------------------------*/
sony_result_t sony_tuner_ascot3_Create (sony_tuner_terr_cable_t * pTuner,
                                         uint32_t xtalFreqMHz,                                     
                                         uint8_t i2cAddress,
                                         sony_i2c_t * pI2c,
                                         uint32_t configFlags, 
                                         sony_ascot3_t * pAscot2ETuner)
{
    sony_result_t result = SONY_RESULT_OK;
    SONY_TRACE_ENTER ("sony_tuner_ascot3_Create");

    if ((!pI2c) || (!pAscot2ETuner) || (!pTuner)) {
        SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
    }

    /* Create the underlying Ascot2E reference driver. */
	result = sony_ascot3_Create (pAscot2ETuner, xtalFreqMHz, i2cAddress, pI2c, configFlags);
    if (result != SONY_RESULT_OK) {
        SONY_TRACE_RETURN (result);
    }

    /* Create local copy of instance data. */
    pTuner->Initialize = sony_tuner_ascot2e_Initialize;
    pTuner->Sleep = sony_tuner_ascot2e_Sleep;
    pTuner->Shutdown = sony_tuner_ascot2e_Shutdown;
    pTuner->Tune = sony_tuner_ascot2e_Tune;
    pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
    pTuner->bandwidth = SONY_DEMOD_BW_UNKNOWN;  
    pTuner->frequencyKHz = 0;
    pTuner->i2cAddress = i2cAddress;
    pTuner->pI2c = pI2c;
    pTuner->flags = configFlags;
    pTuner->user = pAscot2ETuner;

    SONY_TRACE_RETURN (result);
}
static sony_result_t X_oscen(sony_ascot2e_t *pTuner)
{
    sony_result_t result = SONY_RESULT_OK;

    SONY_TRACE_ENTER("X_oscen");

    if((!pTuner) || (!pTuner->pI2c)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    /* XOSC_SEL setting (Max) */
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x07, 0x1F);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    SONY_SLEEP(10);

    /* Xtal oscillator current control setting */
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x4C, 0x01);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    /* XOSC_SEL setting */
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x07, 0x04);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    SONY_TRACE_RETURN(SONY_RESULT_OK);
}
sony_result_t sony_ascot2e_SetGPO(sony_ascot2e_t *pTuner, uint8_t id, uint8_t val)
{
    sony_result_t result = SONY_RESULT_OK;

    SONY_TRACE_ENTER("sony_ascot2e_SetGPO");

    if((!pTuner) || (!pTuner->pI2c)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    switch(id){
    case 0:
        result = sony_i2c_SetRegisterBits(pTuner->pI2c, pTuner->i2cAddress, 0x05, (uint8_t)(val ? 0x01 : 0x00), 0x01);
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
        break;
    case 1:
        result = sony_i2c_SetRegisterBits(pTuner->pI2c, pTuner->i2cAddress, 0x05, (uint8_t)(val ? 0x02 : 0x00), 0x02);
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
        break;
    default:
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    SONY_TRACE_RETURN(SONY_RESULT_OK);
}
sony_result_t sony_demod_isdbt_monitor_SyncStat(sony_demod_t* pDemod,
                                                uint8_t*      pDmdLock,
                                                uint8_t*      pTsLock,
                                                uint8_t*      pUnlock)
{
    uint8_t data = 0;
    sony_result_t result;
    SONY_TRACE_ENTER("sony_demod_isdbt_monitor_SyncStat");

    if ((!pDemod) || (!pDmdLock) || (!pTsLock) || (!pUnlock)) {
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    if ((pDemod->state != SONY_DEMOD_STATE_ACTIVE) &&
        (pDemod->state != SONY_DEMOD_STATE_EWS)) {
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
    }

    /* Set SLV-T Bank : 0x60 */
    result = pDemod->pI2c->WriteOneRegister(pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x60);
    if (result != SONY_RESULT_OK) {
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C);
    }

    /* Demodulator Lock Flag : IREG_DMDLOCK
     * TS Lock Flag          : ITSLOCK
     * slave    Bank    Addr    Bit              Name                meaning
     * --------------------------------------------------------------------------------
     * <SLV-T>   60h     10h     [1]          IREG_DMDLOCK        0:UNLOCK, 1:LOCK
     * <SLV-T>   60h     10h     [0]          ITSLOCK             0:UNLOCK, 1:LOCK
     * <SLV-T>   60h     10h     [4]          IEARLY_NOOFDM
     */
    result = pDemod->pI2c->ReadRegister(pDemod->pI2c, pDemod->i2cAddressSLVT, 0x10, &data, 1);
    if (result != SONY_RESULT_OK) {
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C);
    }

    if ((data & 0x02) > 0) {
        *pDmdLock = 1;
    } else {
        *pDmdLock = 0;
    }

    if ((data & 0x01) > 0) {
        *pTsLock = 1;
    } else {
        *pTsLock = 0;
    }

    if ((data & 0x10) > 0) {
        *pUnlock = 1;
    } else {
        *pUnlock = 0;
    }

    SONY_TRACE_RETURN(SONY_RESULT_OK);
}
sony_result_t sony_tuner_ascot2e_SetGPO (sony_tuner_terr_cable_t * pTuner, uint8_t id, uint8_t value)
{
    sony_result_t result = SONY_RESULT_OK;
    SONY_TRACE_ENTER ("sony_tuner_ascot2e_Write_GPIO");

    if (!pTuner || !pTuner->user) {
        SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
    }

    result = sony_ascot2e_SetGPO (((sony_ascot2e_t *) pTuner->user), id, value);

    SONY_TRACE_RETURN (result);
}
sony_result_t sony_tuner_ascot2e_RFFilterConfig (sony_tuner_terr_cable_t * pTuner, uint8_t coeff, uint8_t offset)
{
    sony_result_t result = SONY_RESULT_OK;
    SONY_TRACE_ENTER ("sony_tuner_ascot2e_RFFilterConfig");

    if (!pTuner || !pTuner->user) {
        SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
    }

    result = sony_ascot2e_RFFilterConfig (((sony_ascot2e_t *) pTuner->user), coeff, offset);

    SONY_TRACE_RETURN (result);
}
sony_result_t sony_tuner_ascot2e_ReadGain (sony_tuner_terr_cable_t * pTuner, int32_t * pIFGain, int32_t * pRFGain, uint8_t forceRFAGCRead)
{
    sony_result_t result = SONY_RESULT_OK;
    SONY_TRACE_ENTER ("sony_tuner_ascot2e_ReadGain");

    if (!pTuner || !pTuner->user) {
        SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
    }
//if(TunMode==45)
//	result = sony_ascot3_ReadRssi(((sony_ascot2e_t *) pTuner->user), int32_t *pRssi);
//else
    result = sony_ascot2e_ReadGain (((sony_ascot2e_t *) pTuner->user), pIFGain, pRFGain, forceRFAGCRead);

    SONY_TRACE_RETURN (result);
}
sony_result_t sony_ascot2e_SetRfExtCtrl(sony_ascot2e_t *pTuner, uint8_t enable)
{
    sony_result_t result = SONY_RESULT_OK;

    SONY_TRACE_ENTER("sony_ascot2e_SetRfExtCtrl");

    if((!pTuner) || (!pTuner->pI2c)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x51, (uint8_t)(enable ? 0x01 : 0x00));
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    SONY_TRACE_RETURN(SONY_RESULT_OK);
}
sony_result_t sony_demod_isdbt_monitor_PresetInfo(sony_demod_t*                   pDemod,
                                                  sony_demod_isdbt_preset_info_t* pPresetInfo)
{
    sony_result_t result = SONY_RESULT_OK;
    SONY_TRACE_ENTER("sony_demod_isdbt_monitor_PresetInfo");

    if ((!pDemod) || (!pPresetInfo)) {
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }
    
    if ((pDemod->state != SONY_DEMOD_STATE_ACTIVE) &&
        (pDemod->state != SONY_DEMOD_STATE_EWS)) {
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
    }

    result = SLVT_FreezeReg(pDemod);
    if (result != SONY_RESULT_OK) {
        SONY_TRACE_RETURN(result);
    }

    result = isLock(pDemod);
    if (result != SONY_RESULT_OK) {
        SLVT_UnFreezeReg(pDemod);
        SONY_TRACE_RETURN(result);
    }

    /* Set SLV-T Bank : 0x60 */
    result = pDemod->pI2c->WriteOneRegister(pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x60);
    if (result != SONY_RESULT_OK) {
        SLVT_UnFreezeReg(pDemod);
        SONY_TRACE_RETURN(result);
    }

    /*
     *  slave    Bank    Addr    Bit              Name        
     *  --------------------------------------------------------
     *  <SLV-T>   60h     32h    [7:0]          PIR_TMCC_SET_2
     *  <SLV-T>   60h     33h    [7:0]          PIR_TMCC_SET_3
     *  <SLV-T>   60h     34h    [7:0]          PIR_TMCC_SET_4
     *  <SLV-T>   60h     35h    [7:0]          PIR_TMCC_SET_5
     *  <SLV-T>   60h     36h    [7:0]          PIR_TMCC_SET_6
     *  <SLV-T>   60h     37h    [7:0]          PIR_TMCC_SET_7
     *  <SLV-T>   60h     38h    [7:0]          PIR_TMCC_SET_8
     *  <SLV-T>   60h     39h    [7:0]          PIR_TMCC_SET_9
     *  <SLV-T>   60h     3Ah    [7:0]          PIR_TMCC_SET_10
     *  <SLV-T>   60h     3Bh    [7:0]          PIR_TMCC_SET_11
     *  <SLV-T>   60h     3Ch    [7:0]          PIR_TMCC_SET_12
     *  <SLV-T>   60h     3Dh    [7:0]          PIR_TMCC_SET_13
     *  <SLV-T>   60h     3Eh    [7:0]          PIR_TMCC_SET_14
     */
    result = pDemod->pI2c->ReadRegister(pDemod->pI2c, pDemod->i2cAddressSLVT, 0x32, pPresetInfo->data, 13);
    if (result != SONY_RESULT_OK) {
        SLVT_UnFreezeReg(pDemod);
        SONY_TRACE_RETURN(result);
    }

    SLVT_UnFreezeReg(pDemod);

    SONY_TRACE_RETURN(result);
}
sony_result_t sony_ascot2e_TuneEnd(sony_ascot2e_t *pTuner)
{
    sony_result_t result = SONY_RESULT_OK;

    SONY_TRACE_ENTER("sony_ascot2e_TuneEnd");

    if((!pTuner) || (!pTuner->pI2c)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    if(pTuner->state != SONY_ASCOT2E_STATE_ACTIVE){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
    }

    result = X_tune_end(pTuner);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(result); }

    SONY_TRACE_RETURN(SONY_RESULT_OK);
}
sony_result_t sony_ascot2e_Tune(sony_ascot2e_t *pTuner, uint32_t frequencykHz, sony_ascot2e_tv_system_t tvSystem)
{
    sony_result_t result = SONY_RESULT_OK;

    SONY_TRACE_ENTER("sony_ascot2e_Tune");

    /* Argument check */
    if((!pTuner) || (!pTuner->pI2c)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    if(!SONY_ASCOT2E_IS_ATV(tvSystem) && !SONY_ASCOT2E_IS_DTV(tvSystem)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    /* State check */
    if((pTuner->state != SONY_ASCOT2E_STATE_SLEEP) && (pTuner->state != SONY_ASCOT2E_STATE_ACTIVE)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
    }

    if(pTuner->state == SONY_ASCOT2E_STATE_SLEEP){
        /* Set system to "Unknown". (for safe) */
        pTuner->tvSystem = SONY_ASCOT2E_TV_SYSTEM_UNKNOWN;

        if((pTuner->flags & SONY_ASCOT2E_CONFIG_SLEEP_DISABLEXTAL) && !(pTuner->flags & SONY_ASCOT2E_CONFIG_EXT_REF)){
            /* Enable Xtal */
            result = X_oscen(pTuner);
            if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(result); }
        }
    }

    /* In digital tuning, step size is 25kHz. (+ rounding) */
    if(SONY_ASCOT2E_IS_DTV(tvSystem)){
        frequencykHz = ((frequencykHz + 25/2) / 25) * 25;
    }

    /* Broadcasting system dependent setting */
    result = X_init(pTuner, frequencykHz, tvSystem);
    if(result != SONY_RESULT_OK){
        SONY_TRACE_RETURN(result);
    }

    /* Tuning */
    result = X_tune(pTuner, frequencykHz, tvSystem, 1);
    if(result != SONY_RESULT_OK){
        SONY_TRACE_RETURN(result);
    }

    pTuner->state = SONY_ASCOT2E_STATE_ACTIVE;
    pTuner->frequencykHz = frequencykHz;
    pTuner->tvSystem = tvSystem;

    /* Previous rfagcreg value should not be used for sony_ascot2e_ReadGain calculation. */
    pTuner->rfagcValid = 0;

    SONY_TRACE_RETURN(SONY_RESULT_OK);
}
static sony_result_t X_fin(sony_ascot2e_t *pTuner)
{
    sony_result_t result = SONY_RESULT_OK;

    SONY_TRACE_ENTER("X_fin");

    if((!pTuner) || (!pTuner->pI2c)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    /* Power save setting */
    {
        const uint8_t cdata[2] = {0x00, 0x04};
        result = pTuner->pI2c->WriteRegister(pTuner->pI2c, pTuner->i2cAddress, 0x14, cdata, sizeof(cdata));
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    }
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x50, 0x01);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    SONY_TRACE_RETURN(SONY_RESULT_OK);
}
sony_result_t sony_demod_isdbt_monitor_SpectrumSense(sony_demod_t*                 pDemod,
                                                     sony_demod_spectrum_sense_t * pSense)
{
    sony_result_t result = SONY_RESULT_OK;
    uint8_t data = 0;
    SONY_TRACE_ENTER("sony_demod_isdbt_monitor_SpectrumSense");

    if ((!pDemod) || (!pSense)) {
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    if ((pDemod->state != SONY_DEMOD_STATE_ACTIVE) &&
        (pDemod->state != SONY_DEMOD_STATE_EWS)) {
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
    }

    result = SLVT_FreezeReg(pDemod);
    if (result != SONY_RESULT_OK) {
        SONY_TRACE_RETURN(result);
    }

    result = isLock(pDemod);
    if (result != SONY_RESULT_OK) {
        SLVT_UnFreezeReg(pDemod);
        SONY_TRACE_RETURN(result);
    }

    /* Set SLV-T Bank : 0x60 */
    result = pDemod->pI2c->WriteOneRegister(pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x60);
    if (result != SONY_RESULT_OK) {
        SLVT_UnFreezeReg(pDemod);
        SONY_TRACE_RETURN(result);
    }

    /*
     * slave    Bank    Addr    Bit          Signal name                Meaning
     * ---------------------------------------------------------------------------------
     * <SLV-T>   60h     3Fh     [0]          IREG_COSNE_SINV    0:Not inverted,  1:Inverted
     */
    result = pDemod->pI2c->ReadRegister(pDemod->pI2c, pDemod->i2cAddressSLVT, 0x3F, &data, 1);
    if (result != SONY_RESULT_OK) {
        SLVT_UnFreezeReg(pDemod);
        SONY_TRACE_RETURN(result);
    }

    SLVT_UnFreezeReg(pDemod);

    if (pDemod->confSense == SONY_DEMOD_SPECTRUM_INV) {
        *pSense = (data & 0x01) ? SONY_DEMOD_SPECTRUM_NORMAL : SONY_DEMOD_SPECTRUM_INV;
    } else {
        *pSense = (data & 0x01) ? SONY_DEMOD_SPECTRUM_INV : SONY_DEMOD_SPECTRUM_NORMAL;
    }

    SONY_TRACE_RETURN(result);
}
static sony_result_t sony_tuner_ascot2e_Sleep (sony_tuner_terr_cable_t * pTuner)
{
    sony_result_t result = SONY_RESULT_OK;
    SONY_TRACE_ENTER ("sony_tuner_ascot2e_Sleep");

    if (!pTuner || !pTuner->user) {
        SONY_TRACE_RETURN (SONY_RESULT_ERROR_ARG);
    }

    /* Call into underlying driver. */
	if(TunMode==45)
	result = sony_ascot3_Sleep (((sony_ascot3_t *) pTuner->user));
	else
    result = sony_ascot2e_Sleep (((sony_ascot2e_t *) pTuner->user));

    /* Device is in "Power Save" state. */
    pTuner->system = SONY_DTV_SYSTEM_UNKNOWN;
    pTuner->frequencyKHz = 0;
    pTuner->bandwidth = SONY_DEMOD_BW_UNKNOWN;

    SONY_TRACE_RETURN (result);
}
/*------------------------------------------------------------------------------
  Functions
------------------------------------------------------------------------------*/
sony_result_t sony_demod_isdbt_monitor_IFAGCOut(sony_demod_t* pDemod,
                                                uint32_t*     pIFAGC)
{
    sony_result_t result = SONY_RESULT_OK;
    uint8_t data[2] = {0x00, 0x00};
    SONY_TRACE_ENTER("sony_demod_isdbt_monitor_IFAGCOut");

    if ((!pDemod) || (!pIFAGC)) {
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    if ((pDemod->state != SONY_DEMOD_STATE_ACTIVE) &&
        (pDemod->state != SONY_DEMOD_STATE_EWS)) {
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
    }

    /* Set SLV-T Bank : 0x60 */
    result = pDemod->pI2c->WriteOneRegister(pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x60);
    if (result != SONY_RESULT_OK) {
        SONY_TRACE_RETURN(result);
    }

    /*
     * slave    Bank    Addr    Bit              Name
     * ------------------------------------------------------------
     * <SLV-T>   60h     26h     [3:0]        IIFAGC_OUT[11:8]
     * <SLV-T>   60h     27h     [7:0]        IIFAGC_OUT[7:0]
     */
    
    if (pDemod->pI2c->ReadRegister(pDemod->pI2c, pDemod->i2cAddressSLVT, 0x26, data, 2)
        != SONY_RESULT_OK) {
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C);
    }

    *pIFAGC = data[0] & 0x0F;
    *pIFAGC = (*pIFAGC << 8) + data[1];

    SONY_TRACE_RETURN(result);
}
sony_result_t sony_demod_isdbt_monitor_InternalDigitalAGCOut(sony_demod_t* pDemod,
                                                             uint32_t*     pInternalDigitalAGC)
{
    sony_result_t result = SONY_RESULT_OK;
    uint8_t data[2] = {0x00, 0x00};
    SONY_TRACE_ENTER("sony_demod_isdbt_monitor_InternalDigitalAGCOut");

    if ((!pDemod) || (!pInternalDigitalAGC)) {
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    if ((pDemod->state != SONY_DEMOD_STATE_ACTIVE) &&
        (pDemod->state != SONY_DEMOD_STATE_EWS)) {
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
    }

    /* Set SLV-T Bank : 0x11 */
    result = pDemod->pI2c->WriteOneRegister(pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x11);
    if (result != SONY_RESULT_OK) {
        SONY_TRACE_RETURN(result);
    }

    /*
     * slave    Bank    Addr    Bit              Name
     * ------------------------------------------------------------
     * <SLV-T>   11h     6Dh     [5:0]        ITDA_DAGC_GAIN[13:8]
     * <SLV-T>   11h     6Eh     [7:0]        ITDA_DAGC_GAIN[7:0]
     */

    if (pDemod->pI2c->ReadRegister(pDemod->pI2c, pDemod->i2cAddressSLVT, 0x6D, data, 2)
        != SONY_RESULT_OK) {
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C);
    }

    *pInternalDigitalAGC = data[0] & 0x3F;
    *pInternalDigitalAGC = (*pInternalDigitalAGC << 8) + data[1];

    SONY_TRACE_RETURN(result);
}
sony_result_t sony_ascot2e_Create(sony_ascot2e_t *pTuner, uint32_t xtalFreqMHz,
    uint8_t i2cAddress, sony_i2c_t *pI2c, uint32_t flags)
{
    SONY_TRACE_ENTER("sony_ascot2e_Create");

    if((!pTuner) || (!pI2c)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    /* Supported Xtal check */
    if((xtalFreqMHz != 16) && (xtalFreqMHz != 24) && (xtalFreqMHz != 41)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_NOSUPPORT);
    }

    /* 41MHz is only for external reference input */
    if((xtalFreqMHz == 41) && !(flags & SONY_ASCOT2E_CONFIG_EXT_REF)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_NOSUPPORT);
    }

    /* SONY_ASCOT2E_CONFIG_EXT_REF and SONY_ASCOT2E_CONFIG_SLEEP_DISABLEXTAL cannot be used at the same time. */
    if((flags & SONY_ASCOT2E_CONFIG_EXT_REF) && (flags & SONY_ASCOT2E_CONFIG_SLEEP_DISABLEXTAL)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_NOSUPPORT);
    }

    pTuner->state = SONY_ASCOT2E_STATE_UNKNOWN; /* Chip is not accessed for now */
    pTuner->xtalFreqMHz = xtalFreqMHz;
    pTuner->pI2c = pI2c;
    pTuner->i2cAddress = i2cAddress;
    pTuner->flags = flags;
    pTuner->frequencykHz = 0;
    pTuner->tvSystem = SONY_ASCOT2E_TV_SYSTEM_UNKNOWN;
    pTuner->rfagcreg = 0;
    pTuner->rfagcValid = 0;
    pTuner->pParamTable = g_param_table;
    pTuner->user = NULL;

    SONY_TRACE_RETURN(SONY_RESULT_OK);
}
static sony_result_t X_tune_end(sony_ascot2e_t *pTuner)
{
    sony_result_t result = SONY_RESULT_OK;

    SONY_TRACE_ENTER("X_tune_end");

    if((!pTuner) || (!pTuner->pI2c)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    /* CPU deep sleep */
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x04, 0x00);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    /* Logic sleep */
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x03, 0xC0);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    /* RFAGC normal mode (set bit[5:4] only) */
    result = sony_i2c_SetRegisterBits(pTuner->pI2c, pTuner->i2cAddress, 0x0C, 0x00, 0x30);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    SONY_TRACE_RETURN(SONY_RESULT_OK);
}
sony_result_t sony_ascot2e_ShiftFRF(sony_ascot2e_t *pTuner, uint32_t frequencykHz)
{
    sony_result_t result = SONY_RESULT_OK;

    SONY_TRACE_ENTER("sony_ascot2e_ShiftFRF");

    /* Argument check */
    if((!pTuner) || (!pTuner->pI2c)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    /* State check */
    if(pTuner->state != SONY_ASCOT2E_STATE_ACTIVE){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
    }

    /* In digital tuning, step size is 25kHz. (+ rounding) */
    if(SONY_ASCOT2E_IS_DTV(pTuner->tvSystem)){
        frequencykHz = ((frequencykHz + 25/2) / 25) * 25;
    }

    /* Tune using current system, no VCO calibration */
    result = X_tune(pTuner, frequencykHz, pTuner->tvSystem, 0);
    if(result != SONY_RESULT_OK){
        SONY_TRACE_RETURN(result);
    }

    pTuner->frequencykHz = frequencykHz;

    SONY_SLEEP(10);

    result = X_tune_end(pTuner);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(result); }

    SONY_TRACE_RETURN(SONY_RESULT_OK);
}
sony_result_t sony_ascot2e_Initialize(sony_ascot2e_t *pTuner)
{
    sony_result_t result = SONY_RESULT_OK;

    SONY_TRACE_ENTER("sony_ascot2e_Initialize");

    if((!pTuner) || (!pTuner->pI2c)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    {
        uint8_t data = 0x00;

        /* Confirm connected device is ASCOT2E */
        result = pTuner->pI2c->ReadRegister(pTuner->pI2c, pTuner->i2cAddress, 0x7F, &data, 1);
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
		printk("jay data  0x%x , pTuner->i2cAddress 0x%x \n",data,pTuner->i2cAddress);
        if(((data & 0xF0) != 0x70) && ((data & 0xF0) != 0x60)){
            SONY_TRACE_RETURN(SONY_RESULT_ERROR_NOSUPPORT);
        }
    }

    /* X_pon sequence */
    result = X_pon(pTuner);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(result); }

    if((pTuner->flags & SONY_ASCOT2E_CONFIG_SLEEP_DISABLEXTAL) && !(pTuner->flags & SONY_ASCOT2E_CONFIG_EXT_REF)){
        /* Disable Xtal */
        result = X_oscdis(pTuner);
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(result); }
    }

    pTuner->state = SONY_ASCOT2E_STATE_SLEEP;
    pTuner->frequencykHz = 0;
    pTuner->tvSystem = SONY_ASCOT2E_TV_SYSTEM_UNKNOWN;

    pTuner->rfagcValid = 0;

    SONY_TRACE_RETURN(SONY_RESULT_OK);
}
sony_result_t sony_ascot2e_Sleep(sony_ascot2e_t *pTuner)
{
    sony_result_t result = SONY_RESULT_OK;

    SONY_TRACE_ENTER("sony_ascot2e_Sleep");

    if((!pTuner) || (!pTuner->pI2c)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    /* State check */
    if((pTuner->state != SONY_ASCOT2E_STATE_SLEEP) && (pTuner->state != SONY_ASCOT2E_STATE_ACTIVE)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
    }

    if(pTuner->state == SONY_ASCOT2E_STATE_SLEEP){
        /* Nothing to do */
        SONY_TRACE_RETURN(SONY_RESULT_OK);
    }

    /* To Power Save state */
    result = X_fin(pTuner);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(result); }

    if((pTuner->flags & SONY_ASCOT2E_CONFIG_SLEEP_DISABLEXTAL) && !(pTuner->flags & SONY_ASCOT2E_CONFIG_EXT_REF)){
        /* Disable Xtal */
        result = X_oscdis(pTuner);
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(result); }
    }
    
    pTuner->state = SONY_ASCOT2E_STATE_SLEEP;
    pTuner->frequencykHz = 0;
    pTuner->tvSystem = SONY_ASCOT2E_TV_SYSTEM_UNKNOWN;

    pTuner->rfagcValid = 0;

    SONY_TRACE_RETURN(SONY_RESULT_OK);
}
static sony_result_t X_read_ss(sony_ascot2e_t *pTuner, uint8_t *pAGCReg, uint8_t *pRFAGCReg)
{
    sony_result_t result = SONY_RESULT_OK;

    SONY_TRACE_ENTER("X_read_ss");

    /* pRFAGCReg can be NULL (RFAGC read is skipped) */
    if((!pTuner) || (!pTuner->pI2c) || (!pAGCReg)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    if((pTuner->state != SONY_ASCOT2E_STATE_SLEEP) && (pTuner->state != SONY_ASCOT2E_STATE_ACTIVE)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
    }

    /* Logic wake up, CPU wake up */
    {
        const uint8_t cdata[2] = {0xC4, 0x40};
        result = pTuner->pI2c->WriteRegister(pTuner->pI2c, pTuner->i2cAddress, 0x03, cdata, sizeof(cdata));
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    }

    /* ADC enable */
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x59, 0x05);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    /* Timer reset */
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x18, 0x00);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    SONY_SLEEP(1);

    /* ADC start */
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x04, 0xF0);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x5A, 0x01);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x04, 0x40);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    /* ADC read out */
    result = pTuner->pI2c->ReadRegister(pTuner->pI2c, pTuner->i2cAddress, 0x5B, pAGCReg, 1);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    if(pRFAGCReg){
        /* Connect AGC */
        result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x59, 0x03);
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

        /* Timer reset */
        result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x18, 0x00);
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

        SONY_SLEEP(1);

        /* ADC start */
        result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x04, 0xF0);
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
        result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x5A, 0x01);
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
        result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x04, 0x40);
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

        /* ADC read out */
        result = pTuner->pI2c->ReadRegister(pTuner->pI2c, pTuner->i2cAddress, 0x5B, pRFAGCReg, 1);
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    }

    /* ADC disable */
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x59, 0x04);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    /* CPU deep sleep */
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x04, 0x00);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    /* Logic sleep */
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x03, 0xC0);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    SONY_TRACE_RETURN(SONY_RESULT_OK);
}
static sony_result_t X_tune(sony_ascot2e_t *pTuner, uint32_t frequencykHz, sony_ascot2e_tv_system_t tvSystem, uint8_t vcoCal)
{
    sony_result_t result = SONY_RESULT_OK;

    SONY_TRACE_ENTER("X_tune");

    if((!pTuner) || (!pTuner->pI2c)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    /* RFAGC fast mode / RFAGC auto control enable (set bit[7], bit[5:4] only) */
    {
        uint8_t data = 0;
        if(vcoCal){
            data = 0x90; /* Set MIX_OL_CPU_EN */
        }else{
            data = 0x10;
        }
        result = sony_i2c_SetRegisterBits(pTuner->pI2c, pTuner->i2cAddress, 0x0C, data, 0xB0);
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    }

    /* Logic wake up, CPU wake up */
    {
        const uint8_t cdata[2] = {0xC4, 0x40};
        result = pTuner->pI2c->WriteRegister(pTuner->pI2c, pTuner->i2cAddress, 0x03, cdata, sizeof(cdata));
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    }

    /* 0x10 - 0x14 */
    {
        uint8_t data[5];

        data[0] = (uint8_t)(frequencykHz & 0xFF);         /* 0x10: FRF_L */
        data[1] = (uint8_t)((frequencykHz >> 8) & 0xFF);  /* 0x11: FRF_M */
        data[2] = (uint8_t)((frequencykHz >> 16) & 0x0F); /* 0x12: FRF_H (bit[3:0]) */

        data[2] |= (uint8_t)(pTuner->pParamTable[tvSystem].BW << 4); /* 0x12: BW (bit[5:4]) */

        if(tvSystem == SONY_ASCOT2E_ATV_L_DASH){
            data[2] |= 0x40; /* 0x12: IS_L_DASH (bit[6]) */
        }

        if(SONY_ASCOT2E_IS_ATV(tvSystem)){
            data[2] |= 0x80; /* 0x12: IS_FP (bit[7]) */
        }

        if(vcoCal){
            data[3] = 0xFF; /* 0x13: VCO calibration enable */
        }else{
            data[3] = 0x8F; /* 0x13: VCO calibration disable */
        }

        data[4] = 0xFF; /* 0x14: Analog block enable */
        
        /* Tune (Burst write) */
        result = pTuner->pI2c->WriteRegister(pTuner->pI2c, pTuner->i2cAddress, 0x10, data, sizeof(data));
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    }

    SONY_TRACE_RETURN(SONY_RESULT_OK);
}
static sony_result_t X_init(sony_ascot2e_t *pTuner, uint32_t frequencykHz, sony_ascot2e_tv_system_t tvSystem)
{
    sony_result_t result = SONY_RESULT_OK;

    SONY_TRACE_ENTER("X_init");

    if((!pTuner) || (!pTuner->pI2c)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    /* Disable power save */
    {
        const uint8_t cdata[2] = {0xFB, 0x0F};
        result = pTuner->pI2c->WriteRegister(pTuner->pI2c, pTuner->i2cAddress, 0x14, cdata, sizeof(cdata));
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    }
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x50, 0x00);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    /* IF_OUT_SEL / AGC_SEL setting */
    {
        uint8_t data = 0x00;

        if(pTuner->pParamTable[tvSystem].AGC_SEL == AUTO){
            /* AGC pin setting by config flags */
            if(SONY_ASCOT2E_IS_ATV(tvSystem)){
                /* Analog */
                if(pTuner->flags & SONY_ASCOT2E_CONFIG_AGC2_ATV){
                    data |= 0x08;
                }
            }else{
                /* Digital */
                if(pTuner->flags & SONY_ASCOT2E_CONFIG_AGC2_DTV){
                    data |= 0x08;
                }
            }
        }else{
            /* AGC pin setting from parameter table */
            data |= (uint8_t)((pTuner->pParamTable[tvSystem].AGC_SEL & 0x03) << 3);
        }

        if(pTuner->pParamTable[tvSystem].IF_OUT_SEL == AUTO){
            /* IFOUT pin setting by config flags */
            if(SONY_ASCOT2E_IS_ATV(tvSystem)){
                /* Analog */
                if(pTuner->flags & SONY_ASCOT2E_CONFIG_IF2_ATV){
                    data |= 0x04;
                }
            }else{
                /* Digital */
                if(pTuner->flags & SONY_ASCOT2E_CONFIG_IF2_DTV){
                    data |= 0x04;
                }
            }
        }else{
            /* IFOUT pin setting from parameter table */
            data |= (uint8_t)((pTuner->pParamTable[tvSystem].IF_OUT_SEL & 0x01) << 2);
        }

        /* Set bit[4:2] only */
        result = sony_i2c_SetRegisterBits(pTuner->pI2c, pTuner->i2cAddress, 0x05, data, 0x1C);
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    }

    /* 0x06 - 0x0F */
    {
        uint8_t data[10];

        /* REF_R setting (0x06) */
        if(SONY_ASCOT2E_IS_ATV(tvSystem) || (tvSystem == SONY_ASCOT2E_DTV_DVBC)){
            if(frequencykHz > 500000){
                data[0] = (uint8_t)((pTuner->xtalFreqMHz == 41) ? 40 : (pTuner->xtalFreqMHz));
            }else{
                data[0] = (uint8_t)((pTuner->xtalFreqMHz == 41) ? 82 : (pTuner->xtalFreqMHz * 2));
            }
        }else{
            if(frequencykHz > 500000){
                data[0] = (uint8_t)(pTuner->xtalFreqMHz / 8);
            }else{
                data[0] = (uint8_t)(pTuner->xtalFreqMHz / 4);
            }
        }

        /* XOSC_SEL setting (0x07) */
        if(pTuner->flags & SONY_ASCOT2E_CONFIG_EXT_REF){ /* Use external Xtal */
            /* XOSC_SEL=0(disable) */
            data[1] = 0x00;
        }else{
            /* XOSC_SEL=100uA */
            data[1] = 0x04;
        }

        /* KBW setting (0x08), KC0 setting (0x09), KC1 setting (0x0A) */
        if(SONY_ASCOT2E_IS_ATV(tvSystem) || (tvSystem == SONY_ASCOT2E_DTV_DVBC)){
            data[2] = 18;
            data[3] = 120;
            data[4] = 20;
        }else{
            data[2] = 48;
            data[3] = 10;
            data[4] = 30;
        }

        /* ORDER/R2_RANGE/R2_BANK/C2_BANK setting (0x0B) */
        if(SONY_ASCOT2E_IS_ATV(tvSystem) || (tvSystem == SONY_ASCOT2E_DTV_DVBC)){
            if(frequencykHz > 500000){
                /* ORDER=0(1-1 MASH), R2_RANGE=0, R2_BANK=10, C2_BANK=00(800pF) */
                data[5] = 0x08;
            }else{
                /* ORDER=0(1-1 MASH), R2_RANGE=0, R2_BANK=11, C2_BANK=00(800pF) */
                data[5] = 0x0C;
            }
        }else{
            if(frequencykHz > 500000){
                /* ORDER=1(1-1-1 MASH), R2_RANGE=1, R2_BANK=00, C2_BANK=00(800pF) */
                data[5] = 0x30;
            }else{
                /* ORDER=1(1-1-1 MASH), R2_RANGE=1, R2_BANK=10, C2_BANK=00(800pF) */
                data[5] = 0x38;
            }
        }

        /* Set MIX_OLL (0x0C) value from parameter table */
        data[6] = pTuner->pParamTable[tvSystem].MIX_OLL;

        /* Set RF_GAIN (0x0D) setting from parameter table */
        if(pTuner->pParamTable[tvSystem].RF_GAIN == AUTO){
            /* RF_GAIN auto control enable */
            result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x4E, 0x01);
            if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

            data[7] = 0x00; /* RF_GAIN Default value */
        }else{
            /* RF_GAIN auto control disable */
            result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x4E, 0x00);
            if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

            data[7] = pTuner->pParamTable[tvSystem].RF_GAIN;
        }

        /* Set IF_BPF_GC/FIF_OFFSET (0x0E) value from parameter table */
        data[8] = (uint8_t)((pTuner->pParamTable[tvSystem].FIF_OFFSET << 3) | (pTuner->pParamTable[tvSystem].IF_BPF_GC & 0x07));

        /* Set BW_OFFSET (0x0F) value from parameter table */
        data[9] = pTuner->pParamTable[tvSystem].BW_OFFSET;

        result = pTuner->pI2c->WriteRegister(pTuner->pI2c, pTuner->i2cAddress, 0x06, data, sizeof(data));
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    }

    /* 0x45 - 0x47 */
    {
        /* LNA optimization setting */
        /* RF_LNA_DIST1-5, RF_LNA_CM */
        uint8_t data[3];

        if(SONY_ASCOT2E_IS_ATV(tvSystem) || (tvSystem == SONY_ASCOT2E_DTV_DVBC)){
            data[0] = 0x0F;
            data[1] = 0x00;
            data[2] = 0x01;
        }else{
            data[0] = 0x0F;
            data[1] = 0x00;
            data[2] = 0x03;
        }

        result = pTuner->pI2c->WriteRegister(pTuner->pI2c, pTuner->i2cAddress, 0x45, data, sizeof(data));
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    }

    /* 0x49 - 0x4A */
    {
        uint8_t data[2];

        /* Set RF_OLDET_ENX/RF_OLDET_OLL value from parameter table */
        data[0] = pTuner->pParamTable[tvSystem].RF_OLDET;

        /* Set IF_BPF_F0 value from parameter table */
        data[1] = pTuner->pParamTable[tvSystem].IF_BPF_F0;

        result = pTuner->pI2c->WriteRegister(pTuner->pI2c, pTuner->i2cAddress, 0x49, data, sizeof(data));
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    }

    SONY_TRACE_RETURN(SONY_RESULT_OK);
}
static sony_result_t X_pon(sony_ascot2e_t *pTuner)
{
    sony_result_t result = SONY_RESULT_OK;

    SONY_TRACE_ENTER("X_pon");

    if((!pTuner) || (!pTuner->pI2c)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    /* Xtal==41MHz special setting */
    if(pTuner->xtalFreqMHz == 41){
        result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x44, 0x07);
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    }

    /* 0x01 - 0x04 */
    {
        uint8_t data[4];

        /* Xtal frequency setting */
        data[0] = (uint8_t)(pTuner->xtalFreqMHz);

        /* VCO current setting */
        data[1] = 0x06;

        /* Logic wake up, CPU boot */
        data[2] = 0xC4;
        data[3] = 0x40;

        result = pTuner->pI2c->WriteRegister(pTuner->pI2c, pTuner->i2cAddress, 0x01, data, sizeof(data));
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    }

    /* 0x22 - 0x24 */
    {
        /* RFVGA optimization setting (RF_DIST0 - RF_DIST2) */
        const uint8_t cdata[] = {0x10, 0x3F, 0x25};
        result = pTuner->pI2c->WriteRegister(pTuner->pI2c, pTuner->i2cAddress, 0x22, cdata, sizeof(cdata));
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    }

    /* PLL mode setting */
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x28, 0x1E);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    /* RSSI setting */
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x59, 0x04);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    /* Wait 80ms */
    SONY_SLEEP(80);

    /* Check CPU_STT/CPU_ERR */
    {
        uint8_t rdata[2];

        result = pTuner->pI2c->ReadRegister(pTuner->pI2c, pTuner->i2cAddress, 0x1A, rdata, sizeof(rdata));
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

        if(rdata[0] != 0x00){
            SONY_TRACE_RETURN(SONY_RESULT_ERROR_HW_STATE); /* CPU_STT != 0x00 */
        }

#ifndef SONY_ASCOT2E_IGNORE_NVM_ERROR /* For no NVM tuner evaluation */
        if((rdata[1] & 0x3F) != 0x00){
            SONY_TRACE_RETURN(SONY_RESULT_ERROR_HW_STATE); /* CPU_ERR[5:0] != 0x00 (NVM Error) */
        }
#endif /* SONY_ASCOT2E_IGNORE_NVM_ERROR */
    }

    /* Xtal oscillator current control setting */
    if(!(pTuner->flags & SONY_ASCOT2E_CONFIG_EXT_REF)){
        result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x4C, 0x01);
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    }

    /* XOSC_SEL setting */
    {
        uint8_t data = 0;

        if(pTuner->flags & SONY_ASCOT2E_CONFIG_EXT_REF){ /* Use external Xtal */
            /* XOSC_SEL=0(disable) */
            data = 0x00;
        }else{
            /* XOSC_SEL=100uA */
            data = 0x04;
        }
        result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x07, data);
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    }

    /* CPU deep sleep */
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x04, 0x00);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    /* Logic sleep */
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x03, 0xC0);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    /* Power save setting */
    {
        const uint8_t cdata[2] = {0x00, 0x04};
        result = pTuner->pI2c->WriteRegister(pTuner->pI2c, pTuner->i2cAddress, 0x14, cdata, sizeof(cdata));
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    }

    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x50, 0x01);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    SONY_TRACE_RETURN(SONY_RESULT_OK);
}
sony_result_t sony_ascot2e_RFFilterConfig(sony_ascot2e_t *pTuner, uint8_t coeff, uint8_t offset)
{
    sony_result_t result = SONY_RESULT_OK;

    SONY_TRACE_ENTER("sony_ascot2e_RFFilterConfig");

    if((!pTuner) || (!pTuner->pI2c)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    if((pTuner->state != SONY_ASCOT2E_STATE_SLEEP) && (pTuner->state != SONY_ASCOT2E_STATE_ACTIVE)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
    }

    if(pTuner->state == SONY_ASCOT2E_STATE_SLEEP){
        if((pTuner->flags & SONY_ASCOT2E_CONFIG_SLEEP_DISABLEXTAL) && !(pTuner->flags & SONY_ASCOT2E_CONFIG_EXT_REF)){
            /* Enable Xtal */
            result = X_oscen(pTuner);
            if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(result); }
        }
    }

    /* Logic wake up, CPU wake up */
    {
        const uint8_t cdata[2] = {0xC4, 0x40};
        result = pTuner->pI2c->WriteRegister(pTuner->pI2c, pTuner->i2cAddress, 0x03, cdata, sizeof(cdata));
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }
    }

    {
        uint8_t data[3];

        /* Write VL_TRCKOUT_COEFF */
        data[0] = coeff;
        data[1] = 0x49;
        data[2] = 0x03;
        result = pTuner->pI2c->WriteRegister(pTuner->pI2c, pTuner->i2cAddress, 0x16, data, sizeof(data));
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

        SONY_SLEEP(1);

        /* Write VL_TRCKOUT_OFS */
        data[0] = offset;
        data[1] = 0x4B;
        data[2] = 0x03;
        result = pTuner->pI2c->WriteRegister(pTuner->pI2c, pTuner->i2cAddress, 0x16, data, sizeof(data));
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

        SONY_SLEEP(1);
    }

    /* CPU deep sleep */
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x04, 0x00);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    /* Logic sleep */
    result = pTuner->pI2c->WriteOneRegister(pTuner->pI2c, pTuner->i2cAddress, 0x03, 0xC0);
    if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

    if(pTuner->state == SONY_ASCOT2E_STATE_SLEEP){
        if((pTuner->flags & SONY_ASCOT2E_CONFIG_SLEEP_DISABLEXTAL) && !(pTuner->flags & SONY_ASCOT2E_CONFIG_EXT_REF)){
            /* Disable Xtal */
            result = X_oscdis(pTuner);
            if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(result); }
        }
    }

    SONY_TRACE_RETURN(SONY_RESULT_OK);
}
sony_result_t sony_ascot2e_ReadGain(sony_ascot2e_t *pTuner, int32_t *pIFGain, int32_t *pRFGain, uint8_t forceRFAGCRead)
{
    sony_result_t result = SONY_RESULT_OK;
    uint8_t agcreg = 0;
    uint8_t rfagcreg = 0;

    SONY_TRACE_ENTER("sony_ascot2e_ReadGain");

    if((!pTuner) || (!pTuner->pI2c) || (!pIFGain) || (!pRFGain)){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    if(pTuner->state != SONY_ASCOT2E_STATE_ACTIVE){
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
    }

    if(forceRFAGCRead || !(pTuner->rfagcValid)){
        result = X_read_ss(pTuner, &agcreg, &rfagcreg);
        if(result != SONY_RESULT_OK){
            SONY_TRACE_RETURN(result);
        }
        /* Update stored RFAGC value */
        pTuner->rfagcreg = rfagcreg;
        pTuner->rfagcValid = 1;
    }else{
        /* Avoid RFAGC read */
        result = X_read_ss(pTuner, &agcreg, NULL);
        if(result != SONY_RESULT_OK){
            SONY_TRACE_RETURN(result);
        }
        /* Use previous RFAGC value */
        rfagcreg = pTuner->rfagcreg;
    }

    /*
        IFGAIN = if(AGC > 0.6){
                     6 + IF_BPF_GC 
                 }else{
                     if(AGC > 0.19){
                         6 + IF_BPF_GC + 69 * (0.6 - AGC)
                     }else{
                         6 + IF_BPF_GC + 69 * 0.41
                     }
                 }
        Note that AGC(V) = AGCReg(by X_read_ss) / 128
        So...
        IFGAIN(100xdB) = if(AGCReg * 100 > 7680){
                             (6 + IF_BPF_GC) * 100 
                         }else if(AGCReg * 100 > 2432){
                             (6 + IF_BPF_GC) * 100 + (69 * (7680 - AGCReg * 100))/128
                         }else{
                             (6 + IF_BPF_GC) * 100 + 69 * 41
                         }
    */
    {
        const int8_t if_bpf_gc_table[] = {-2, 0, 2, 4, 6, 8, 12, 20};
        uint8_t data = 0;
        int8_t if_bpf_gc = 0;
        int32_t agcreg_x100 = agcreg * 100;

        result = pTuner->pI2c->ReadRegister(pTuner->pI2c, pTuner->i2cAddress, 0x0E, &data, 1);
        if(result != SONY_RESULT_OK){ SONY_TRACE_RETURN(SONY_RESULT_ERROR_I2C); }

        if_bpf_gc = if_bpf_gc_table[data & 0x07];

        if(agcreg_x100 > 7680){
            *pIFGain = (6 + if_bpf_gc) * 100;
        }else if(agcreg_x100 > 2432){
            *pIFGain = (6 + if_bpf_gc) * 100 + (69 * (7680 - agcreg_x100) + 64) / 128; /* Round */
        }else{
            *pIFGain = (6 + if_bpf_gc) * 100 + 69 * 41;
        }
    }

    /*
        RFGAIN = if(max(AGC,RFAGC) < 0.42){
                     RFGAIN_MAX
                 }else if(max(AGC,RFAGC) < 0.49){
                     RF_GAIN_MAX - 63 * (max(AGC,RFAGC) - 0.42)
                 }else if(max(AGC,RFAGC) < 0.6){
                     RF_GAIN_MAX - 63 * 0.07
                 }else if(max(AGC,RFAGC) < 1.13){
                     RF_GAIN_MAX - 63 * 0.07 - 63 * (max(AGC,RFAGC) - 0.6)
                 }else if(max(AGC,RFAGC) < 1.38){
                     RF_GAIN_MAX - 63 * 0.6 - 45 * (max(AGC,RFAGC) - 1.13)
                 }else{
                     RF_GAIN_MAX - 63 * 0.6 - 45 * 0.25 + RFGRAD * (max(AGC,RFAGC) - 1.38)
                 }

        Note that AGC(V) = AGCReg(by X_read_ss) / 128
                  RFAGC(V) = RFAGCReg(by X_read_ss) / 128
        So...
        RFGAIN(100xdB) = if(maxagcreg * 100 < 5376){
                             RFGAIN_MAX * 100
                         }else if(maxagcreg * 100 < 6272){
                             RFGAIN_MAX * 100 - (63 * (maxagcreg * 100 - 5376))/128
                         }else if(maxagcreg * 100 < 7680){
                             RFGAIN_MAX * 100 - 63 * 7
                         }else if(maxagcreg * 100 < 14464){
                             RFGAIN_MAX * 100 - 63 * 7 - (63 * (maxagcreg * 100 - 7680))/128
                         }else if(maxagcreg * 100 < 17664){
                             RFGAIN_MAX * 100 - 63 * 60 - (45 * (maxagcreg * 100 - 14464))/128
                         }else{
                             RFGAIN_MAX * 100 - 63 * 60 - 45 * 25 + RFGRAD * (maxagcreg * 100 - 17664))/128
                         }
        (NOTE: maxagcreg = max(AGCReg, RFAGCReg))
    */
    {
        int32_t maxagcreg_x100 = 0;
        int32_t rfgainmax_x100 = 0;

        if(agcreg > rfagcreg){
            maxagcreg_x100 = agcreg * 100;
        }else{
            maxagcreg_x100 = rfagcreg * 100;
        }

        if(pTuner->frequencykHz > 900000){
            rfgainmax_x100 = 4320;
        }else if(pTuner->frequencykHz > 700000){
            rfgainmax_x100 = 4420;
        }else if(pTuner->frequencykHz > 600000){
            rfgainmax_x100 = 4330;
        }else if(pTuner->frequencykHz > 504000){
            rfgainmax_x100 = 4160;
        }else if(pTuner->frequencykHz > 400000){
            rfgainmax_x100 = 4550;
        }else if(pTuner->frequencykHz > 320000){
            rfgainmax_x100 = 4400;
        }else if(pTuner->frequencykHz > 270000){
            rfgainmax_x100 = 4520;
        }else if(pTuner->frequencykHz > 235000){
            rfgainmax_x100 = 4370;
        }else if(pTuner->frequencykHz > 192000){
            rfgainmax_x100 = 4190;
        }else if(pTuner->frequencykHz > 130000){
            rfgainmax_x100 = 4550;
        }else if(pTuner->frequencykHz > 86000){
            rfgainmax_x100 = 4630;
        }else if(pTuner->frequencykHz > 50000){
            rfgainmax_x100 = 4350;
        }else{
            rfgainmax_x100 = 4450;
        }

        if(maxagcreg_x100 < 5376){
            *pRFGain = rfgainmax_x100;
        }else if(maxagcreg_x100 < 6272){
            *pRFGain = rfgainmax_x100 - (63 * (maxagcreg_x100 - 5376) + 64) / 128; /* Round */
        }else if(maxagcreg_x100 < 7680){
            *pRFGain = rfgainmax_x100 - 63 * 7;
        }else if(maxagcreg_x100 < 14464){
            *pRFGain = rfgainmax_x100 - 63 * 7 - (63 * (maxagcreg_x100 - 7680) + 64) / 128; /* Round */
        }else if(maxagcreg_x100 < 17664){
            *pRFGain = rfgainmax_x100 - 63 * 60 - (45 * (maxagcreg_x100 - 14464) + 64) / 128; /* Round */
        }else{
            int32_t rfgrad = -95;

            *pRFGain = rfgainmax_x100 - 63 * 60 - 45 * 25 + (rfgrad * (maxagcreg_x100 - 17664) - 64) / 128; /* Round */
        }
    }

    SONY_TRACE_RETURN(SONY_RESULT_OK);
}
sony_result_t sony_demod_isdbt_monitor_PER(sony_demod_t*                pDemod,
                                           sony_isdbt_monitor_target_t  target,
                                           uint32_t*                    pPER)
{
    sony_result_t result = SONY_RESULT_OK;
    uint8_t tmpPacketNum[2] = {0x00, 0x00};
    uint8_t tmpPacketError[2] = {0x00, 0x00};
    uint16_t packetNum = 0x0000;
    uint32_t packetError = 0x00000000;
    SONY_TRACE_ENTER("sony_demod_isdbt_monitor_PER");

    if ((!pDemod) || (!pPER)) {
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
        /* Invalid on EWS mode */
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
    }

    result = SLVT_FreezeReg(pDemod);
    if (result != SONY_RESULT_OK) {
        SONY_TRACE_RETURN(result);
    }

    result = isLock(pDemod);
    if (result != SONY_RESULT_OK) {
        SLVT_UnFreezeReg(pDemod);
        SONY_TRACE_RETURN(result);
    }

    /* Set SLV-T Bank : 0x60 */
    result = pDemod->pI2c->WriteOneRegister(pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x60);
    if (result != SONY_RESULT_OK) {
        SLVT_UnFreezeReg(pDemod);
        SONY_TRACE_RETURN(result);
    }
    
    /*
     *  slave     Bank   Addr    Bit          Name
     * ------------------------------------------------------------
     * <SLV-T>    60h    5Bh     [6:0]    OBER_CDUR_RSA[14:8]
     * <SLV-T>    60h    5Ch     [7:0]    OBER_CDUR_RSA[7:0]
     */
    result = pDemod->pI2c->ReadRegister(pDemod->pI2c,
                                        pDemod->i2cAddressSLVT,
                                        0x5B,
                                        tmpPacketNum,
                                        2);

    if (result != SONY_RESULT_OK) {
        SLVT_UnFreezeReg(pDemod);
        SONY_TRACE_RETURN(result);
    }

    switch (target) {
    case SONY_ISDBT_MONITOR_TARGET_LAYER_A:
        /*
         *  slave     Bank   Addr    Bit          Name
         * ------------------------------------------------------------
         * <SLV-T>    60h    1Fh     [6:0]    IBER_PENUM_RSA[14:8]
         * <SLV-T>    60h    20h     [7:0]    IBER_PENUM_RSA[7:0]
         */
        result = pDemod->pI2c->ReadRegister(pDemod->pI2c, pDemod->i2cAddressSLVT, 0x1F, tmpPacketError, 2);
        break;
    case SONY_ISDBT_MONITOR_TARGET_LAYER_B:
        /*
         *  slave     Bank   Addr    Bit          Name
         * ------------------------------------------------------------
         * <SLV-T>    60h    21h     [6:0]    IBER_PENUM_RSB[14:8]
         * <SLV-T>    60h    22h     [7:0]    IBER_PENUM_RSB[7:0]
         */
        result = pDemod->pI2c->ReadRegister(pDemod->pI2c, pDemod->i2cAddressSLVT, 0x21, tmpPacketError, 2);
        break;
    case SONY_ISDBT_MONITOR_TARGET_LAYER_C:
        /*
         *  slave     Bank   Addr    Bit          Name
         * ------------------------------------------------------------
         * <SLV-T>    60h    23h     [6:0]    IBER_PENUM_RSC[14:8]
         * <SLV-T>    60h    24h     [7:0]    IBER_PENUM_RSC[7:0]
         */
        result = pDemod->pI2c->ReadRegister(pDemod->pI2c, pDemod->i2cAddressSLVT, 0x23, tmpPacketError, 2);
        break;
    default:
        SLVT_UnFreezeReg(pDemod);
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }
    
    if (result != SONY_RESULT_OK) {
        SLVT_UnFreezeReg(pDemod);
        SONY_TRACE_RETURN(result);
    }

    SLVT_UnFreezeReg(pDemod);
    
    packetError = tmpPacketError[0];
    packetError = (packetError << 8) + tmpPacketError[1];
    packetNum = tmpPacketNum[0];
    packetNum = (packetNum << 8) + tmpPacketNum[1];

    if (packetNum == 0) {
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_HW_STATE);
    }
    /*
      PER = packetError * 1000000 / packetNum

      PER = packetError * 1000 * 1000 / packetNum
     */
    {
        uint32_t div = 0;
        uint32_t Q = 0;
        uint32_t R = 0;

        div = packetNum;
        Q = (packetError * 1000) / div;
        R = (packetError * 1000) % div;

        R *= 1000;
        Q = Q * 1000 + R / div;
        R = R % div;

        if ((div != 1) && (R >= (div / 2))) {
            *pPER = Q + 1;
        } else {
            *pPER = Q;
        }
    }
    
    SONY_TRACE_RETURN(result);
}
sony_result_t sony_demod_isdbt_monitor_PacketErrorNumber(sony_demod_t*               pDemod,
                                                         sony_isdbt_monitor_target_t target,
                                                         uint32_t*                   pPacketErrorNum)
{
    sony_result_t result = SONY_RESULT_OK;
    uint8_t data[2];
    SONY_TRACE_ENTER("sony_demod_isdbt_monitor_PacketErrorNumber");

    if ((!pDemod) || (!pPacketErrorNum)) {
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    if (pDemod->state != SONY_DEMOD_STATE_ACTIVE) {
        /* Invalid on EWS mode */
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_SW_STATE);
    }

    result = SLVT_FreezeReg(pDemod);
    if (result != SONY_RESULT_OK) {
        SONY_TRACE_RETURN(result);
    }

    result = isLock(pDemod);
    if (result != SONY_RESULT_OK) {
        SLVT_UnFreezeReg(pDemod);
        SONY_TRACE_RETURN(result);
    }

    /* Set SLV-T Bank : 0x60 */
    result = pDemod->pI2c->WriteOneRegister(pDemod->pI2c, pDemod->i2cAddressSLVT, 0x00, 0x60);
    if (result != SONY_RESULT_OK) {
        SLVT_UnFreezeReg(pDemod);
        SONY_TRACE_RETURN(result);
    }

    switch (target) {
    case SONY_ISDBT_MONITOR_TARGET_LAYER_A:
        /*
         * slave    Bank    Addr    Bit           Name
         * ------------------------------------------------------------
         * <SLV-T>   60h     A2h     [7:0]    ICWRJCTCNT_A[15:8]
         * <SLV-T>   60h     A3h     [7:0]    ICWRJCTCNT_A[7:0]
         */
        result = pDemod->pI2c->ReadRegister(pDemod->pI2c, pDemod->i2cAddressSLVT, 0xA2, data, 2);
        break;
    case SONY_ISDBT_MONITOR_TARGET_LAYER_B:
        /*
         * slave    Bank    Addr    Bit           Name
         * ------------------------------------------------------------
         * <SLV-T>   60h     A4h     [7:0]    ICWRJCTCNT_B[15:8]
         * <SLV-T>   60h     A5h     [7:0]    ICWRJCTCNT_B[7:0]
         */
        result = pDemod->pI2c->ReadRegister(pDemod->pI2c, pDemod->i2cAddressSLVT, 0xA4, data, 2);
        break;
    case SONY_ISDBT_MONITOR_TARGET_LAYER_C:
        /*
         * slave    Bank    Addr    Bit           Name
         * ------------------------------------------------------------
         * <SLV-T>   60h     A6h     [7:0]    ICWRJCTCNT_C[15:8]
         * <SLV-T>   60h     A7h     [7:0]    ICWRJCTCNT_C[7:0]
         */
        result = pDemod->pI2c->ReadRegister(pDemod->pI2c, pDemod->i2cAddressSLVT, 0xA6, data, 2);
        break;
    default:
        SLVT_UnFreezeReg(pDemod);
        SONY_TRACE_RETURN(SONY_RESULT_ERROR_ARG);
    }

    if (result != SONY_RESULT_OK) {
        SLVT_UnFreezeReg(pDemod);
        SONY_TRACE_RETURN(result);
    }
    
    SLVT_UnFreezeReg(pDemod);

    *pPacketErrorNum = 0;
    *pPacketErrorNum = data[0];
    *pPacketErrorNum = (*pPacketErrorNum << 8) + data[1];


    SONY_TRACE_RETURN(result);
}
sony_result_t CXD2837_Scan(struct cxd2837_state *state,uint32_t startFreqkHz,uint8_t bwMHz)
{
#ifndef CONFIG_TH_CXD2837_DVBC_ENABLE
  	unsigned int modulation_mode=state->mode;
#endif
//	sony_result_t result = SONY_RESULT_OK;
	sony_result_t tuneResult = SONY_RESULT_OK;
//	sony_integ_t integ;
//	sony_demod_t demod;
//	sony_tuner_terr_cable_t tunerTerrCable;
#ifdef SONY_EXAMPLE_TUNER_ASCOT2E
//	sony_ascot2e_t ascot2e;
#endif
#ifdef	SONY_EXAMPLE_TUNER_ASCOT3
//	sony_ascot3_t ascot3;
#endif
//	sony_i2c_t i2c;
#ifndef CONFIG_TH_CXD2837_DVBC_ENABLE
	sony_dvbt2_tune_param_t tuneParam;

        sony_dvbt_tune_param_t dvbttuneParam;
#endif
//	int i;

	#ifdef CONFIG_TH_CXD2837_DVBC_ENABLE
		sony_dvbc_tune_param_t dvtcTunerParam;
		dvtcTunerParam.centerFreqKHz = startFreqkHz/1000;

		printk (" Tune to DVB-C signal with the following parameters:\n");
		printk ("  - Center Freq    : %uKHz\n", dvtcTunerParam.centerFreqKHz);

		/* Perform DVBC Tune */
		tuneResult = sony_integ_dvbc_Tune (&(state->device), &dvtcTunerParam);
		printk ("  - DVBC - Result         : %s\n\n", Common_Result[tuneResult]);

		if (tuneResult == SONY_RESULT_OK) {
			 SONY_TRACE_RETURN (tuneResult);
		}
		return tuneResult;
	#else

		/*------------------------------------------------------------------------------
		   Scan - DVB-T/T2 multiple standard scan.
		  ------------------------------------------------------------------------------*/

		//	printk ("------------------------------------------\n");
		//	printk (" Demodulator configuration \n");
		//	printk ("------------------------------------------\n");
		if((modulation_mode==0))
		{
			/* Configure the DVBT tune parameters based on the channel requirements */
			dvbttuneParam.bandwidth = bwMHz;//SONY_DEMOD_BW_8_MHZ;          /* Channel bandwidth */
			dvbttuneParam.centerFreqKHz = startFreqkHz/1000;                   /* Channel centre frequency in KHz */
			dvbttuneParam.profile = SONY_DVBT_PROFILE_HP;           /* Channel profile for hierachical modes.  For non-hierachical use HP */

			printk (" Tune to DVB-T signal with the following parameters:\n");
			printk ("  - Center Freq    : %uKHz\n", dvbttuneParam.centerFreqKHz);
			printk ("  - Bandwidth      : %s\n", Common_Bandwidth[dvbttuneParam.bandwidth]);
			printk ("  - Profile        : %s\n", DVBT_Profile[dvbttuneParam.profile]);

			/* Perform DVBT Tune */
			tuneResult = sony_integ_dvbt_Tune (&(state->device), &dvbttuneParam);
			printk ("  - Result         : %s\n\n", Common_Result[tuneResult]);

			if (tuneResult == SONY_RESULT_OK) {
				 SONY_TRACE_RETURN (tuneResult);
			}

		}
		else
		{
			/* Configure the DVBT2 tune parameters based on the channel requirements */
			tuneParam.bandwidth = bwMHz;// SONY_DEMOD_BW_8_MHZ;          /* Channel bandwidth */
			tuneParam.centerFreqKHz = startFreqkHz/1000;                   /* Channel center frequency in KHz */
			tuneParam.dataPlpId = 0;                            /* PLP ID where multiple PLP's are available */
			tuneParam.profile = SONY_DVBT2_PROFILE_BASE;        /* Channel profile is T2-Base */
			/* Additional tune information fed back from the driver.  This parameter should be checked
			if the result from the tune call is SONY_RESULT_OK_CONFIRM. */
			tuneParam.tuneInfo = SONY_DEMOD_DVBT2_TUNE_INFO_OK;

		        tuneParam.dataPlpId = plpidnew;
			plpidold = plpidnew;

			printk (" Tune to DVB-T2 signal with the following parameters:\n");
			printk ("  - Center Freq    : %uKHz\n", tuneParam.centerFreqKHz);
			printk ("  - Bandwidth      : %s\n", Common_Bandwidth[tuneParam.bandwidth]);
			printk ("  - PLP ID         : %u\n", tuneParam.dataPlpId);
			printk ("  - Profile        : %s\n", DVBT2_Profile[tuneParam.profile]);
			/* Perform DVBT2 Tune */
			tuneResult = sony_integ_dvbt2_Tune (&(state->device), &tuneParam);
			printk ("  - Result         : %s\n", Common_Result[tuneResult]);
			printk ("  - Tune Info      : %s\n\n", DVBT2_TuneInfo[tuneParam.tuneInfo]);
		}
	#endif
	return tuneResult;
}