accessoryservices/pluggeddisplay/pluggeddisplayengine/src/edidhandler.cpp
changeset 0 4e1aa6a622a0
child 3 a811597961f0
child 12 e978f818f9bd
equal deleted inserted replaced
-1:000000000000 0:4e1aa6a622a0
       
     1 /*
       
     2  * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3  * All rights reserved.
       
     4  * This component and the accompanying materials are made available
       
     5  * under the terms of "Eclipse Public License v1.0"
       
     6  * which accompanies this distribution, and is available
       
     7  * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8  *
       
     9  * Initial Contributors:
       
    10  * Nokia Corporation - initial contribution.
       
    11  *
       
    12  * Contributors:
       
    13  *
       
    14  * Description:  EDID data Handler class for HDMI Cable Status FSM.
       
    15  *
       
    16  */
       
    17 
       
    18 #include <tvoutconfig.h>
       
    19 #include <accpolhdmisink.h>
       
    20 #include <accpolhdmiaudioformat.h>
       
    21 #include <accpolhdmivideoformat.h>
       
    22 #include <accpolhdmilatency.h>
       
    23 #include <accpolhdmispeakerallocation.h>
       
    24 #include <e32cmn.h>
       
    25 #include <e32math.h>
       
    26 #include <accessoriescrkeys.h>
       
    27 #include <centralrepository.h>
       
    28 
       
    29 #include "pdeconstants.h"
       
    30 #include "tvoutconfigforhdmi.h"
       
    31 #include "edidhandler.h"
       
    32 #include "edidparserbase.h"
       
    33 #include "cea861edidparser.h"
       
    34 #include "multifinitestatemachine.h"
       
    35 #include "trace.h"
       
    36 #include "traceediddata.h"
       
    37 
       
    38 const TReal K16d9 = 1.778;
       
    39 const TReal K4d3 = 1.333;
       
    40 
       
    41 const TInt KDefaultCEAMode = E640x480p59_94d60Hz4d3;
       
    42 const TInt KDefaultCEAModeIndex = 0;
       
    43 
       
    44 // Retry Delay for EDID access
       
    45 const TInt KRetryDelay = 50 * 1000; // 50 milliseconds
       
    46 
       
    47 // Maximum retry count for EDID access
       
    48 const TInt KMaxRetryCount = 40;  // 40 * 50ms = 2 Seconds
       
    49 
       
    50 const TUint16 KDefaultCEAModePhysImgAspRatioNr = 4;
       
    51 
       
    52 const TUint16 KDefaultCEAModePhysImgAspRatioDr = 3;
       
    53 
       
    54 //------------------------------------------------------------------------------
       
    55 // Symbian two-phased constructor
       
    56 //------------------------------------------------------------------------------
       
    57 //
       
    58 CEDIDHandler* CEDIDHandler::NewL( MFSMForBody& aFSM,
       
    59     CTVOutConfigForHDMI& aTVOutConfigForHDMI )
       
    60     {
       
    61     FUNC_LOG;
       
    62     CEDIDHandler* self = new ( ELeave ) CEDIDHandler(
       
    63             aFSM, aTVOutConfigForHDMI );
       
    64     CleanupStack::PushL( self );
       
    65     self->ConstructL();
       
    66     CleanupStack::Pop( self );
       
    67     return self;
       
    68     }
       
    69 
       
    70 //------------------------------------------------------------------------------
       
    71 // Destructor
       
    72 //------------------------------------------------------------------------------
       
    73 //
       
    74 CEDIDHandler::~CEDIDHandler()
       
    75     {
       
    76     FUNC_LOG;
       
    77     
       
    78     Cancel();
       
    79     delete iDdcPortAccess;
       
    80     delete iDataBlockPtr;
       
    81     delete iExtensionParserPtr;
       
    82     delete iEdidParserPtr;
       
    83     iRetryTimer.Close();
       
    84     }
       
    85 
       
    86 //------------------------------------------------------------------------------
       
    87 // FetchEDIDData
       
    88 //------------------------------------------------------------------------------
       
    89 //
       
    90 TInt CEDIDHandler::FetchEDIDData()
       
    91     {
       
    92     FUNC_LOG;
       
    93     
       
    94     TInt retVal( KErrNone );
       
    95     TUint apiVersion = iDdcPortAccess->ApiVersion();
       
    96     if( KDdcAccessVersion != apiVersion )
       
    97         {
       
    98         INFO_1( "iDdcPortAccess->ApiVersion() returned unsupported version != KDdcAccessVersion: %d", apiVersion );
       
    99         retVal = KErrNotSupported;
       
   100         }
       
   101     else
       
   102         {
       
   103         iRetryCounter = KErrNone;
       
   104         TInt err = KErrNone;
       
   105         TRAP( retVal , err = ReadEDIDDataL() );
       
   106         if ( err != KErrNone )
       
   107             {
       
   108             retVal = err;
       
   109             }
       
   110         }
       
   111     INFO_1( "CEDIDHandler::FetchEDIDData() retVal: %d", retVal );
       
   112     return retVal;
       
   113     }
       
   114 
       
   115 //------------------------------------------------------------------------------
       
   116 // SetVideoParameters
       
   117 //------------------------------------------------------------------------------
       
   118 //
       
   119 TInt CEDIDHandler::SetVideoParameters()
       
   120     {
       
   121     FUNC_LOG;
       
   122 
       
   123     TInt retVal = KErrNone;
       
   124     RArray<TTvSettings> analogConfigs;
       
   125     RArray<THdmiDviTimings> hdmiConfigs;
       
   126     
       
   127     // Update overscan values from cenrep
       
   128     UpdateOverscanValues();
       
   129 
       
   130     // Set video parameters
       
   131     INFO( "--------------------------------------------------------------------" );
       
   132     INFO( "SETTING CEA AND DMT TIMINGS:" );
       
   133     retVal = SetCeaModes( hdmiConfigs );
       
   134     ERROR( retVal, "Failed to set CEA modes" );
       
   135     
       
   136     if( KErrNone == retVal )
       
   137         {
       
   138         retVal = SetDmtModes( hdmiConfigs );
       
   139         ERROR( retVal, "Failed to set DMT modes" );
       
   140         INFO( "--------------------------------------------------------------------" );
       
   141         
       
   142         if( KErrNone == retVal )
       
   143             {
       
   144             // Filtering out the unsupported modes
       
   145             // Logical AND(Sink supported modes AND HW supported modes)
       
   146             INFO( "Filtering out the unsupported modes" );
       
   147             retVal = FilterAvailableTvConfigList( hdmiConfigs );
       
   148             ERROR( retVal, "Failed to filter the TV config list." );
       
   149     
       
   150             if( KErrNone == retVal )
       
   151                 {
       
   152                 retVal = iTVOutConfigForHDMI.SetAvailableTvConfigList( analogConfigs, hdmiConfigs );
       
   153                 ERROR( retVal, "Failed to set available TV config list." );
       
   154                 }            
       
   155             }
       
   156         }
       
   157     
       
   158     // Clean up
       
   159     hdmiConfigs.Close();
       
   160     analogConfigs.Close();
       
   161 
       
   162     return retVal;
       
   163     }
       
   164 
       
   165 //------------------------------------------------------------------------------
       
   166 // GetEDIDDataL
       
   167 //------------------------------------------------------------------------------
       
   168 //
       
   169 void CEDIDHandler::ResetData()
       
   170     {
       
   171     FUNC_LOG;
       
   172     
       
   173     delete iDataBlockPtr;
       
   174     iDataBlockPtr = NULL;
       
   175     delete iEdidParserPtr;
       
   176     iEdidParserPtr = NULL;
       
   177     delete iExtensionParserPtr;
       
   178     iExtensionParserPtr = NULL;
       
   179     }
       
   180 
       
   181 //------------------------------------------------------------------------------
       
   182 // CreateHdmiSinkL
       
   183 //------------------------------------------------------------------------------
       
   184 //
       
   185 CAccPolHdmiSink* CEDIDHandler::CreateHdmiSinkL()
       
   186     {
       
   187     FUNC_LOG;
       
   188     
       
   189     CAccPolHdmiSink* hdmiSink( NULL );
       
   190     if( iExtensionParserPtr && iTVOutConfigForHDMI.GetTvOutConfig() )
       
   191         {
       
   192         hdmiSink = CAccPolHdmiSink::NewL(
       
   193             iExtensionParserPtr->BasicAudio(),
       
   194             iTVOutConfigForHDMI.GetTvOutConfig()->CopyProtectionStatus() );
       
   195         }
       
   196     else
       
   197         {
       
   198         User::Leave( KErrNotFound );
       
   199         }
       
   200     
       
   201     return hdmiSink;
       
   202     }
       
   203 
       
   204 //------------------------------------------------------------------------------
       
   205 // CreateHdmiVideoFormatL
       
   206 //------------------------------------------------------------------------------
       
   207 //
       
   208 void CEDIDHandler::CreateHdmiVideoFormatL( RAccPolHdmiVideoFormatArray& aHdmiVideoFormatArray )
       
   209     {
       
   210     FUNC_LOG;
       
   211     
       
   212     // Active Video Format object values can be fetched from TvOutConfig interface.
       
   213     if( iEdidParserPtr && iTVOutConfigForHDMI.GetTvOutConfig() )
       
   214         {
       
   215         THdmiDviTimings hdmiDviTimings;
       
   216         TInt retVal = iTVOutConfigForHDMI.GetTvOutConfig()->GetConfig(
       
   217             hdmiDviTimings );
       
   218         if( KErrNone == retVal )
       
   219             {
       
   220             CAccPolHdmiVideoFormat* hdmiVideoFormat = CAccPolHdmiVideoFormat::NewLC();            
       
   221             hdmiVideoFormat->SetCeaFixedMode( hdmiDviTimings.iCeaMode );
       
   222             hdmiVideoFormat->SetDmtFixedMode( EDmtFixedModeNone );
       
   223             hdmiVideoFormat->SetPixelRepeat( hdmiDviTimings.iPixelRepeat );
       
   224             hdmiVideoFormat->SetInterlaced( hdmiDviTimings.iInterlaced );
       
   225             aHdmiVideoFormatArray.AppendL( hdmiVideoFormat );
       
   226             CleanupStack::Pop( hdmiVideoFormat );
       
   227             }
       
   228         else
       
   229             {
       
   230             User::Leave( retVal );
       
   231             }
       
   232         }
       
   233     else
       
   234         {
       
   235         User::Leave( KErrNotFound );
       
   236         }
       
   237     }
       
   238 
       
   239 //------------------------------------------------------------------------------
       
   240 // CreateHdmiLatencyL
       
   241 //------------------------------------------------------------------------------
       
   242 //
       
   243 void CEDIDHandler::CreateHdmiLatencyL( RAccPolHdmiLatencyArray& aHdmiLatencyArray )
       
   244     {
       
   245     FUNC_LOG;
       
   246     
       
   247     if( iEdidParserPtr && iExtensionParserPtr )
       
   248         {
       
   249         // Interlaced audio and video latency
       
   250         CAccPolHdmiLatency* hdmiLatency = CAccPolHdmiLatency::NewLC(
       
   251             HdmiLatency::KUidInterlacedLatency,
       
   252             iExtensionParserPtr->GetInterlacedAudioLatency(),
       
   253             iExtensionParserPtr->GetInterlacedVideoLatency() ); 
       
   254         aHdmiLatencyArray.AppendL( hdmiLatency );
       
   255         CleanupStack::Pop( hdmiLatency );
       
   256 
       
   257         // Progressive audio and video latency
       
   258         hdmiLatency = CAccPolHdmiLatency::NewLC(
       
   259             HdmiLatency::KUidLatency,
       
   260             iExtensionParserPtr->GetAudioLatency(),
       
   261             iExtensionParserPtr->GetVideoLatency() );
       
   262         aHdmiLatencyArray.AppendL( hdmiLatency );
       
   263         CleanupStack::Pop( hdmiLatency );
       
   264         }
       
   265     else
       
   266         {
       
   267         User::Leave( KErrNotFound );
       
   268         }
       
   269     }
       
   270 
       
   271 //------------------------------------------------------------------------------
       
   272 // CreateHdmiAudioFormatL
       
   273 //------------------------------------------------------------------------------
       
   274 //
       
   275 void CEDIDHandler::CreateHdmiAudioFormatL( RAccPolHdmiAudioFormatArray& aHdmiAudioFormatArray )
       
   276     {
       
   277     FUNC_LOG;
       
   278     
       
   279     if( iExtensionParserPtr )
       
   280         {
       
   281         if( iExtensionParserPtr->IsAudioDataBlockSupported() )
       
   282             {
       
   283             TCEA861AudioDataBlock
       
   284                 * audioDataBlock =
       
   285                     iExtensionParserPtr->GetParsedInformation()->iShortAudioDescriptors;
       
   286             while( audioDataBlock )
       
   287                 {
       
   288                     CAccPolHdmiAudioFormat* hdmiAudioFormat =
       
   289                         CAccPolHdmiAudioFormat::NewL();
       
   290                     CleanupStack::PushL( hdmiAudioFormat );
       
   291 
       
   292                     // Set audio format
       
   293                     TUid audioFormat;
       
   294                     audioFormat.iUid = audioDataBlock->iAudioFormatCode;
       
   295                     hdmiAudioFormat->SetAudioFormat( audioFormat ); // const TUid aAudioFormat,
       
   296 
       
   297                     // Set bit resolution
       
   298                     TUint32 bitResolution( CAccPolHdmiAudioFormat::EUnknownBitsPerSample );
       
   299                     if( audioDataBlock->iSupport24Bit )
       
   300                         {
       
   301                         bitResolution |= CAccPolHdmiAudioFormat::EBitsPerSample24;
       
   302                         }
       
   303                     if( audioDataBlock->iSupport20Bit )
       
   304                         {
       
   305                         bitResolution |= CAccPolHdmiAudioFormat::EBitsPerSample20;
       
   306                         }
       
   307                     if( audioDataBlock->iSupport16Bit )
       
   308                         {
       
   309                         bitResolution |= CAccPolHdmiAudioFormat::EBitsPerSample16;
       
   310                         }
       
   311                     hdmiAudioFormat->SetBitResolution( bitResolution ); // const TUint32 aBitResolution,
       
   312                     hdmiAudioFormat->SetMaxBitResolution( audioDataBlock->iMaxBitrate ); // const TUint32 aMaxBitResolution,
       
   313                     hdmiAudioFormat->SetChannelCount( audioDataBlock->iMaxChannels ); // const TUint32 aMaxChannelCount,
       
   314 
       
   315                     // Set sample frequency 
       
   316                     TUint32 samFreq( CAccPolHdmiAudioFormat::EUnknownFrequency );
       
   317                     if( audioDataBlock->iSupport192kHz )
       
   318                         {
       
   319                         samFreq
       
   320                             |= CAccPolHdmiAudioFormat::ESamplingFreq192KHz;
       
   321                         }
       
   322                     if( audioDataBlock->iSupport176kHz )
       
   323                         {
       
   324                         samFreq
       
   325                             |= CAccPolHdmiAudioFormat::ESamplingFreq176KHz;
       
   326                         }
       
   327                     if( audioDataBlock->iSupport96kHz )
       
   328                         {
       
   329                         samFreq
       
   330                             |= CAccPolHdmiAudioFormat::ESamplingFreq96KHz;
       
   331                         }
       
   332                     if( audioDataBlock->iSupport88kHz )
       
   333                         {
       
   334                         samFreq
       
   335                             |= CAccPolHdmiAudioFormat::ESamplingFreq88KHz;
       
   336                         }
       
   337                     if( audioDataBlock->iSupport48kHz )
       
   338                         {
       
   339                         samFreq
       
   340                             |= CAccPolHdmiAudioFormat::ESamplingFreq48KHz;
       
   341                         }
       
   342                     if( audioDataBlock->iSupport44kHz )
       
   343                         {
       
   344                         samFreq
       
   345                             |= CAccPolHdmiAudioFormat::ESamplingFreq44KHz;
       
   346                         }
       
   347                     if( audioDataBlock->iSupport32kHz )
       
   348                         {
       
   349                         samFreq
       
   350                             |= CAccPolHdmiAudioFormat::ESamplingFreq32KHz;
       
   351                         }
       
   352                     hdmiAudioFormat->SetSamFreq( samFreq ); // const TUint32 aSamFreq,
       
   353                     hdmiAudioFormat->SetFormatDependentValue( audioDataBlock->iAudioFormatCodeExtension ); // const TUint32 aFormatDependentValue
       
   354                     aHdmiAudioFormatArray.AppendL( hdmiAudioFormat );
       
   355                     CleanupStack::Pop( hdmiAudioFormat );
       
   356                     
       
   357                     audioDataBlock = audioDataBlock->iNext;
       
   358                 }
       
   359             }
       
   360         }
       
   361     else
       
   362         {
       
   363         User::Leave( KErrNotFound );
       
   364         }
       
   365     }
       
   366 
       
   367 //------------------------------------------------------------------------------
       
   368 // CreateHdmiAudioFormatL
       
   369 //------------------------------------------------------------------------------
       
   370 //
       
   371 CAccPolHdmiSpeakerAllocation* CEDIDHandler::CreateHdmiSpeakerAllocationL()
       
   372     {
       
   373     FUNC_LOG;
       
   374     
       
   375     CAccPolHdmiSpeakerAllocation* hdmiSpeakerAllocation( NULL );
       
   376     if( iExtensionParserPtr )
       
   377         {
       
   378         if( iExtensionParserPtr->IsSpeakerAllocationDataBlockSupported() )
       
   379             {
       
   380             TCEA861SpeakerAllocationData
       
   381                 * speakerAllocationData =
       
   382                     &( iExtensionParserPtr->GetParsedInformation()->iSpeakerAllocationData );
       
   383             if( speakerAllocationData )
       
   384                 {
       
   385                 hdmiSpeakerAllocation
       
   386                     = CAccPolHdmiSpeakerAllocation::NewL( speakerAllocationData->FL_FR(), //const TBool aFrontSpeakers,
       
   387                         speakerAllocationData->RL_RR(), //const TBool aRearSpeakers,
       
   388                         speakerAllocationData->LFE(), //const TBool aLowFrequencyEffect,
       
   389                         speakerAllocationData->FC(), //const TBool aFrontCenter,
       
   390                         speakerAllocationData->FCH(), //const TBool aFrontCenterHigh,
       
   391                         speakerAllocationData->TC(), //const TBool aTopCenter,
       
   392                         speakerAllocationData->RC(), //const TBool aRearCenter,
       
   393                         speakerAllocationData->FLC_FRC(), //const TBool aFrontLeftRightCenter,
       
   394                         speakerAllocationData->RLC_RRC(), //const TBool aRearLeftRightCenter,
       
   395                         speakerAllocationData->FLW_FRW(), //const TBool aFrontWideSpeakers,
       
   396                         speakerAllocationData->FLH_FRH() //const TBool aFrontHighSpeakers         
       
   397                     );
       
   398                 }
       
   399             }
       
   400         }
       
   401     else
       
   402         {
       
   403         User::Leave( KErrNotFound );
       
   404         }
       
   405     return hdmiSpeakerAllocation;
       
   406     }
       
   407 
       
   408 //------------------------------------------------------------------------------
       
   409 // GetHdcpSupportStatus
       
   410 //------------------------------------------------------------------------------
       
   411 //
       
   412 TInt CEDIDHandler::GetHdcpSupportStatus( TBool& aHdcpSupportStatus ) const
       
   413     {
       
   414     FUNC_LOG;
       
   415     
       
   416     TInt retVal( KErrNone );
       
   417     if( iTVOutConfigForHDMI.GetTvOutConfig() )
       
   418         {
       
   419         aHdcpSupportStatus
       
   420             = ( iTVOutConfigForHDMI.GetTvOutConfig() )->CopyProtectionStatus();
       
   421         }
       
   422     else
       
   423         {
       
   424         retVal = KErrNotFound;
       
   425         }
       
   426     return retVal;
       
   427     }
       
   428 
       
   429 //------------------------------------------------------------------------------
       
   430 // RunL
       
   431 //------------------------------------------------------------------------------
       
   432 //
       
   433 void CEDIDHandler::RunL()
       
   434     {
       
   435 
       
   436     FUNC_LOG;
       
   437     
       
   438     switch ( iRequestID )
       
   439         {
       
   440         case EDdcReadRequest:
       
   441             {
       
   442             if( KErrNone == iStatus.Int() )
       
   443                 {
       
   444                 TPtrC8
       
   445                     dataBlockDes( iDataBlockPtr->iDataBlock, sizeof( *iDataBlockPtr ) );
       
   446                 iEdidParserPtr = CEdidParserBase::NewL( dataBlockDes );
       
   447                 TInt nbrOfExtensions = iEdidParserPtr->GetNumberOfExtensions();
       
   448                 for( TInt i = 0; i < nbrOfExtensions; ++i )
       
   449                     {
       
   450                     if( ECea861Ext == iEdidParserPtr->GetExtensionType( i + 1 ) )
       
   451                         {
       
   452                         INFO_1( "ECea861Ext extension data block number: %d", ( i+1 ) );
       
   453                         iExtensionParserPtr
       
   454                             = iEdidParserPtr->CreateCea861ExtensionParserL( i + 1 );
       
   455                         break;
       
   456                         }
       
   457                     }
       
   458                 INFO_1( "Data block count in nbrOfExtensions: %d", nbrOfExtensions );
       
   459                 iFSM.Input( EPDEIfEDIDHandler, EPDEIfEDIDHandlerEventEdidDataFetched );
       
   460                 iRetryCounter = KErrNone;
       
   461                 }
       
   462             else
       
   463                 {
       
   464                 INFO_1( "CDdcPortAccess::Read failed, error code: %d", iStatus.Int() );
       
   465                 
       
   466                 if( (iStatus.Int() == KErrNotReady) && (iRetryCounter < KMaxRetryCount) )
       
   467                     {
       
   468                     iRetryCounter++;
       
   469                     iRequestID = ERetryTimerRequest;
       
   470                     iRetryTimer.After( iStatus, KRetryDelay );
       
   471                     SetActive();
       
   472                     }
       
   473                 else
       
   474                     {
       
   475                     iRetryCounter = KErrNone;
       
   476                     iFSM.Input( EPDEIfEDIDHandler,
       
   477                         EPDEIfEDIDHandlerEventEdidDataFetchFailed );
       
   478                     }
       
   479                 }
       
   480             break;
       
   481             }
       
   482         case ERetryTimerRequest:
       
   483             {
       
   484             INFO_1( "Retrying... count: %d", iRetryCounter );
       
   485             if( ReadEDIDDataL() != KErrNone )
       
   486                 {
       
   487                 iFSM.Input( EPDEIfEDIDHandler, EPDEIfEDIDHandlerEventEdidDataFetchFailed );
       
   488                 }
       
   489             break;
       
   490             }
       
   491         default:
       
   492             {
       
   493             INFO_1( "Undefined Request ID %d", iRequestID );
       
   494             break;
       
   495             }
       
   496         }
       
   497     }
       
   498 
       
   499 //------------------------------------------------------------------------------
       
   500 // From class CActive.
       
   501 // RunL
       
   502 //------------------------------------------------------------------------------
       
   503 //
       
   504 TInt CEDIDHandler::RunError( TInt aError )
       
   505     {
       
   506     FUNC_LOG;
       
   507     
       
   508     /*TInt err( aError );
       
   509     // Avoid Panic in CActiveScheduler
       
   510     if ( err )
       
   511         {
       
   512         INFO_1( "aError %d", err );
       
   513         }*/
       
   514     iFSM.Input( EPDEIfEDIDHandler, EPDEIfEDIDHandlerEventEdidDataFetchFailed );
       
   515         
       
   516     return KErrNone;
       
   517     }
       
   518 
       
   519 //-------------------------------------------------------------------------------
       
   520 // DoCancel
       
   521 //
       
   522 //-------------------------------------------------------------------------------
       
   523 //
       
   524 void CEDIDHandler::DoCancel()
       
   525     {
       
   526     FUNC_LOG;
       
   527     
       
   528     iDdcPortAccess->CancelAll();
       
   529     }
       
   530 
       
   531 //------------------------------------------------------------------------------
       
   532 // ReadEDIDDataL
       
   533 //------------------------------------------------------------------------------
       
   534 //
       
   535 TInt CEDIDHandler::ReadEDIDDataL()
       
   536     {
       
   537     FUNC_LOG;
       
   538     
       
   539     TInt retVal( KErrNone );
       
   540     
       
   541     iRequestID = EDdcReadRequest;
       
   542     
       
   543     if( iDataBlockPtr == NULL )
       
   544         {
       
   545         iDataBlockPtr = new(ELeave) TDataBlock;
       
   546         }
       
   547     
       
   548     retVal = iDdcPortAccess->Read( EMonitorPort, 0, // First block contains EDID data if that exists
       
   549         iDataBlockPtr->iDataBlock,
       
   550         iStatus );
       
   551         
       
   552     SetActive();
       
   553         
       
   554     ERROR(retVal, "iDdcPortAccess->Read failed" );
       
   555     
       
   556     return retVal;
       
   557     }
       
   558 
       
   559 //------------------------------------------------------------------------------
       
   560 // CEDIDHandler::FillCommonHdmiDviTimings
       
   561 //------------------------------------------------------------------------------
       
   562 //
       
   563 void CEDIDHandler::FillCommonHdmiDviTimings( THdmiDviTimings& aTimings ) const
       
   564     {
       
   565     FUNC_LOG;
       
   566     
       
   567     aTimings.iTvPhysicalImageWidthMm = iEdidParserPtr->GetHorizontalScreenSize() * 10;
       
   568     aTimings.iTvPhysicalImageHeightMm = iEdidParserPtr->GetVerticalScreenSize() * 10;
       
   569     aTimings.iTvPhysicalImageAspectRatioNumerator = 0;
       
   570     aTimings.iTvPhysicalImageAspectRatioDenominator = 0;
       
   571     aTimings.iHorizontalBorderPixels = 0;
       
   572     aTimings.iVerticalBorderLinesField1 = 0;
       
   573     aTimings.iVerticalBorderLinesField2 = 0;
       
   574     aTimings.iLeftBorderPixels = 0;
       
   575     aTimings.iRightBorderPixels = 0;
       
   576     aTimings.iUnderscanEnabled = EFalse;
       
   577     
       
   578     if( iExtensionParserPtr )
       
   579         {
       
   580         aTimings.iUnderscanEnabled = iExtensionParserPtr->Underscan();
       
   581         }
       
   582     
       
   583     if( aTimings.iUnderscanEnabled )
       
   584         {
       
   585         // Underscan
       
   586         aTimings.iLeftTopCorner.iX = 0;
       
   587         aTimings.iLeftTopCorner.iY = 0;
       
   588         aTimings.iRightBottomCorner.iX = aTimings.iHorizontalActivePixels;
       
   589         aTimings.iRightBottomCorner.iY = aTimings.iVerticalActiveLines;
       
   590         }
       
   591     else
       
   592         {
       
   593         // Calculate overscan
       
   594         CalculateOverscan( aTimings.iLeftTopCorner,
       
   595             aTimings.iRightBottomCorner );                
       
   596         }
       
   597     aTimings.iTvPhysicalImageAspectRatioNumerator = iEdidParserPtr->GetAspectRatioLandscape();
       
   598     aTimings.iTvPhysicalImageAspectRatioDenominator = iEdidParserPtr->GetAspectRatioPortrait();
       
   599     aTimings.iConnector = TTvSettings::EHDMI;
       
   600     aTimings.iTvColorCoordinates.iRed.iX = iEdidParserPtr->GetColorCoordinatesRedX();
       
   601     aTimings.iTvColorCoordinates.iRed.iY = iEdidParserPtr->GetColorCoordinatesRedY();
       
   602     aTimings.iTvColorCoordinates.iGreen.iX = iEdidParserPtr->GetColorCoordinatesGreenX();
       
   603     aTimings.iTvColorCoordinates.iGreen.iY = iEdidParserPtr->GetColorCoordinatesGreenY();
       
   604     aTimings.iTvColorCoordinates.iBlue.iX = iEdidParserPtr->GetColorCoordinatesBlueX();
       
   605     aTimings.iTvColorCoordinates.iBlue.iY = iEdidParserPtr->GetColorCoordinatesBlueY();
       
   606     aTimings.iTvColorCoordinates.iWhite.iX = iEdidParserPtr->GetColorCoordinatesWhiteX();
       
   607     aTimings.iTvColorCoordinates.iWhite.iY = iEdidParserPtr->GetColorCoordinatesWhiteY();
       
   608     aTimings.iTvHdmiVersion = iEdidParserPtr->GetVersion();
       
   609     aTimings.iTvHdmiRevision = iEdidParserPtr->GetRevision();
       
   610     Mem::FillZ( ( TAny* )&aTimings.iProductName, ( sizeof( TChar ) * KProductNameChars ) );
       
   611     Mem::FillZ( ( TAny* )&aTimings.iProductDescription, ( sizeof( TChar ) * KProductDescriptorsChars ) );
       
   612     aTimings.iSourceType = THdmiDviTimings::ESourceTypeUnknown;
       
   613     }
       
   614 
       
   615 //------------------------------------------------------------------------------
       
   616 // CEDIDHandler::FillHdmiDviTimings
       
   617 //------------------------------------------------------------------------------
       
   618 //
       
   619 void CEDIDHandler::FillHdmiDviTimings( const TTimingItem& aItem,
       
   620     THdmiDviTimings& aTimings ) const
       
   621     {
       
   622     FUNC_LOG;
       
   623     
       
   624     // Fill attributes from the static table
       
   625     if( aItem.iTimingType == ETimingModeCEA )
       
   626         {
       
   627         // CEA
       
   628         aTimings.iCeaMode = static_cast<TFixedModeCea>( aItem.iTimingId );
       
   629         }
       
   630     else
       
   631         {
       
   632         // DMT
       
   633         aTimings.iDmtMode = static_cast<TFixedModeDmt>( aItem.iTimingId );
       
   634         }
       
   635     aTimings.iPixelClockKHz = aItem.iDotClock;
       
   636     aTimings.iHorizontalActivePixels = aItem.iHorizontalActive;
       
   637     aTimings.iHorizontalBlankingPixels = aItem.iHorizontalBlanking;
       
   638     aTimings.iHorizontalSyncOffsetPixels = aItem.iHorizontalFrontPorch;
       
   639     aTimings.iHorizontalSyncPulseWidthPixels = aItem.iHorizontalSync;
       
   640     aTimings.iVerticalActiveLines = aItem.iVertical1stActive;
       
   641     aTimings.iVerticalBlankingLines = aItem.iVertical1stBlanking;
       
   642     aTimings.iVerticalSyncOffsetLinesField1 = aItem.iVertical1stFrontPorch;
       
   643     aTimings.iVerticalSyncPulseWidthLinesField1 = aItem.iVertical1stSync;
       
   644     aTimings.iVerticalSyncOffsetLinesField2 = aItem.iVertical2ndFrontPorch;
       
   645     aTimings.iVerticalSyncPulseWidthLinesField2 = aItem.iVertical2ndSync;
       
   646     aTimings.iInterlaced = aItem.iInterlaced;
       
   647     aTimings.iHorizontalSyncPolarity = aItem.iHorizontalSyncPolarity;
       
   648     aTimings.iVerticalSyncPolarity = aItem.iVerticalSyncPolarity;
       
   649     aTimings.iPixelRepeat = aItem.iPixelRepeat;
       
   650     aTimings.iRightBottomCorner.iX = aItem.iWidth;
       
   651     aTimings.iRightBottomCorner.iY = aItem.iHeight;
       
   652     aTimings.iImageAspectRatio = aItem.iAspectRatio;
       
   653     if( aTimings.iImageAspectRatio == TTvSettings::EUndefRatio )
       
   654         {
       
   655         // Resolve ratio from width and height
       
   656         aTimings.iImageAspectRatio = ResolveAspectRatio( aItem.iWidth, aItem.iHeight );
       
   657         }
       
   658     aTimings.iPixelAspectRatioNumerator = aItem.iPixelAspectRatioNumerator;
       
   659     aTimings.iPixelAspectRatioDenominator = aItem.iPixelAspectRatioDenominator;
       
   660 
       
   661     // Fill the common attributes 
       
   662     FillCommonHdmiDviTimings( aTimings );
       
   663     
       
   664     TRACE_TIMINGS( aTimings );
       
   665     }
       
   666 
       
   667 //------------------------------------------------------------------------------
       
   668 // CEDIDHandler::FillHdmiDviTimings
       
   669 //------------------------------------------------------------------------------
       
   670 //
       
   671 void CEDIDHandler::FillHdmiDviTimings( const TEdidDescriptorBlock& aDescBlock,
       
   672     THdmiDviTimings& aTimings ) const
       
   673     {
       
   674     FUNC_LOG;
       
   675 
       
   676     // Fill attributes from timing descriptor
       
   677     aTimings.iCeaMode = ECeaFixedModeNone;
       
   678     aTimings.iDmtMode = EDmtFixedModeNone;
       
   679     aTimings.iPixelClockKHz = aDescBlock.iPixelClock;
       
   680     aTimings.iHorizontalActivePixels = aDescBlock.iHorizontalAddressableVideoPixels;
       
   681     aTimings.iHorizontalBlankingPixels = aDescBlock.iHorizontalBlanking;
       
   682     aTimings.iHorizontalSyncOffsetPixels = aDescBlock.iHorizontalFrontPorch;
       
   683     aTimings.iHorizontalSyncPulseWidthPixels = aDescBlock.iHorizontalSyncPulse;
       
   684     aTimings.iHorizontalBorderPixels = aDescBlock.iHorizontalBorder;
       
   685     aTimings.iVerticalActiveLines = aDescBlock.iVerticalAddressableVideoPixels;
       
   686     aTimings.iVerticalBlankingLines = aDescBlock.iVerticalBlanking;
       
   687     aTimings.iVerticalSyncOffsetLinesField1 = aDescBlock.iVerticalFrontPorch;
       
   688     aTimings.iVerticalSyncPulseWidthLinesField1 = aDescBlock.iVerticalSyncPulse;
       
   689     aTimings.iVerticalBorderLinesField1 = aDescBlock.iVerticalBorder;
       
   690     aTimings.iInterlaced = aDescBlock.iInterlacedVideo;
       
   691     if( aDescBlock.iSyncs ==
       
   692         EDigitalSeparateSyncVerticalSyncIsNegativeHorizontalSyncIsNegative )
       
   693         {
       
   694         aTimings.iVerticalSyncPolarity = EFalse;
       
   695         aTimings.iHorizontalSyncPolarity = EFalse;
       
   696         }
       
   697     else if( aDescBlock.iSyncs ==
       
   698         EDigitalSeparateSyncVerticalSyncIsNegativeHorizontalSyncIsPositive )
       
   699         {
       
   700         aTimings.iVerticalSyncPolarity = EFalse;
       
   701         aTimings.iHorizontalSyncPolarity = ETrue;
       
   702         }
       
   703     else if( aDescBlock.iSyncs ==
       
   704         EDigitalSeparateSyncVerticalSyncIsPositiveHorizontalSyncIsNegative )
       
   705         {
       
   706         aTimings.iVerticalSyncPolarity = ETrue;
       
   707         aTimings.iHorizontalSyncPolarity = EFalse;
       
   708         }
       
   709     else if( aDescBlock.iSyncs ==
       
   710         EDigitalSeparateSyncVerticalSyncIsPositiveHorizontalSyncIsPositive )
       
   711         {
       
   712         aTimings.iVerticalSyncPolarity = ETrue;
       
   713         aTimings.iHorizontalSyncPolarity = ETrue;
       
   714         }
       
   715     aTimings.iPixelRepeat = 1;
       
   716     aTimings.iRightBottomCorner.iX = aDescBlock.iHorizontalAddressableVideoPixels;
       
   717     aTimings.iRightBottomCorner.iY = aDescBlock.iVerticalAddressableVideoPixels;
       
   718     aTimings.iImageAspectRatio = ResolveAspectRatio(
       
   719         aTimings.iHorizontalActivePixels,
       
   720         aTimings.iVerticalActiveLines );
       
   721 
       
   722     // Fill the common attributes 
       
   723     FillCommonHdmiDviTimings( aTimings );
       
   724 
       
   725     TRACE_TIMINGS( aTimings );
       
   726     }
       
   727 
       
   728 //------------------------------------------------------------------------------
       
   729 // SetCeaModes
       
   730 //------------------------------------------------------------------------------
       
   731 //
       
   732 TInt CEDIDHandler::SetCeaModes( RArray<THdmiDviTimings>& aTimings ) const
       
   733     {
       
   734     FUNC_LOG;
       
   735     
       
   736     TInt retVal(KErrNone);
       
   737 
       
   738     // Use only CEA-861 extension parser
       
   739     if( iExtensionParserPtr )
       
   740         {
       
   741         // Get parsed information
       
   742         CCea861ExtEdidInformation* info =
       
   743             iExtensionParserPtr->GetParsedInformation();
       
   744         if( info )
       
   745             {
       
   746             // Go through all supported CEA modes
       
   747             TCEA861VideoDataBlock* vdb = info->iShortVideoDescriptors;
       
   748             THdmiDviTimings timings;
       
   749             while( vdb )
       
   750                 {
       
   751                 // Get a timing item matched with the VIC mode
       
   752                 TInt index = vdb->iVIC - 1;
       
   753                 if( ( index >= 0 ) && ( index < KCEATimingCount ) )
       
   754                     {
       
   755                     const TTimingItem* item = TimingByIndex( index, ETimingModeCEA );
       
   756                     if( item )
       
   757                         {
       
   758                         Mem::FillZ( ( TAny* )&timings, sizeof( timings ) );
       
   759                         FillHdmiDviTimings( *item, timings );
       
   760                         retVal = aTimings.Append( timings );
       
   761                         ERROR_1( retVal, "Failed to append CEA timing: %S in array", item->iTimingName );
       
   762                         }
       
   763                     else
       
   764                         {
       
   765                         ERROR_1( KErrArgument, "CEA timing item not found for VIC mode: %d", index );
       
   766                         }
       
   767                     }
       
   768                 vdb = vdb->iNext;
       
   769                 }
       
   770             }
       
   771         }
       
   772     
       
   773     return retVal;
       
   774     }
       
   775 
       
   776 //------------------------------------------------------------------------------
       
   777 // SetDmtModes
       
   778 //------------------------------------------------------------------------------
       
   779 //
       
   780 TInt CEDIDHandler::SetDmtModes( RArray<THdmiDviTimings>& aTimings ) const
       
   781     {
       
   782     FUNC_LOG;
       
   783     
       
   784     TInt retVal(KErrNone);
       
   785     
       
   786     // Check established timings 1 and 2
       
   787     retVal = SetDmtModesFromEstablishedTimings( aTimings );
       
   788     
       
   789     if( KErrNone == retVal )
       
   790         {
       
   791         // Check standard timings
       
   792         retVal = SetDmtModesFromStandardTimings( aTimings );
       
   793         
       
   794         if( KErrNone == retVal )
       
   795             {
       
   796             // Check timing descriptors
       
   797             retVal = SetDmtModesFromTimingDescriptors( aTimings );        
       
   798             }
       
   799         }
       
   800     
       
   801     return retVal;
       
   802     }
       
   803 
       
   804 //------------------------------------------------------------------------------
       
   805 // SetDmtModesFromEstablishedTimings
       
   806 //------------------------------------------------------------------------------
       
   807 //
       
   808 TInt CEDIDHandler::SetDmtModesFromEstablishedTimings(
       
   809     RArray<THdmiDviTimings>& aTimings ) const
       
   810     {
       
   811     FUNC_LOG;
       
   812     
       
   813     TUint8 timings = 0;
       
   814     TUint16 width = 0;
       
   815     TUint16 height = 0;
       
   816     TUint16 refreshRate = 0;
       
   817     TInt retVal(KErrNone);
       
   818     
       
   819     // Established timings 1
       
   820     // Bits 4, 6 and 7 left out since these does not match to DMT
       
   821     timings = iEdidParserPtr->GetEstablishedTimings1();
       
   822     if( timings & E800x600_60Hz ) // Bit 0
       
   823         {
       
   824         width = 800;
       
   825         height = 600;
       
   826         refreshRate = 60;
       
   827         retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
       
   828         }
       
   829     if( timings & E800x600_56Hz ) // Bit 1
       
   830         {
       
   831         width = 800;
       
   832         height = 600;
       
   833         refreshRate = 56;
       
   834         retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
       
   835         }
       
   836     if( timings & E640x480_75Hz ) // Bit 2
       
   837         {
       
   838         width = 640;
       
   839         height = 480;
       
   840         refreshRate = 75;
       
   841         retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
       
   842         }
       
   843     if( timings & E640x480_72Hz ) // Bit 3
       
   844         {
       
   845         width = 640;
       
   846         height = 480;
       
   847         refreshRate = 72;
       
   848         retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
       
   849         }
       
   850     if( timings & E640x480_60Hz ) // Bit 5
       
   851         {
       
   852         width = 640;
       
   853         height = 480;
       
   854         refreshRate = 60;
       
   855         retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
       
   856         }
       
   857 
       
   858     // Established timings 2
       
   859     // Bit 5 left out since it does not match to DMT
       
   860     timings = iEdidParserPtr->GetEstablishedTimings2();
       
   861     if( timings & E1280x1024_75Hz ) // Bit 0
       
   862         {
       
   863         width = 1280;
       
   864         height = 1024;
       
   865         refreshRate = 75;
       
   866         retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
       
   867         }
       
   868     if( timings & E1024x768_75Hz ) // Bit 1
       
   869         {
       
   870         width = 1024;
       
   871         height = 768;
       
   872         refreshRate = 75;
       
   873         retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
       
   874         }
       
   875     if( timings & E1024x768_70Hz ) // Bit 2
       
   876         {
       
   877         width = 1280;
       
   878         height = 768;
       
   879         refreshRate = 70;
       
   880         retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
       
   881         }
       
   882     if( timings & E1024x768_60Hz ) // Bit 3
       
   883         {
       
   884         width = 1280;
       
   885         height = 768;
       
   886         refreshRate = 60;
       
   887         retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
       
   888         }
       
   889     if( timings & E1024x768_87Hz ) // Bit 4
       
   890         {
       
   891         width = 1280;
       
   892         height = 768;
       
   893         refreshRate = 87;
       
   894         retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
       
   895         }
       
   896     if( timings & E800x600_75Hz ) // Bit 6
       
   897         {
       
   898         width = 800;
       
   899         height = 600;
       
   900         refreshRate = 75;
       
   901         retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
       
   902         }
       
   903     if( timings & E800x600_72Hz ) // Bit 7
       
   904         {
       
   905         width = 800;
       
   906         height = 600;
       
   907         refreshRate = 72;
       
   908         retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
       
   909         }
       
   910     
       
   911     return retVal;
       
   912     }
       
   913 
       
   914 //------------------------------------------------------------------------------
       
   915 // SetDmtModesFromStandardTimings
       
   916 //------------------------------------------------------------------------------
       
   917 //
       
   918 TInt CEDIDHandler::SetDmtModesFromStandardTimings(
       
   919     RArray<THdmiDviTimings>& aTimings ) const
       
   920     {
       
   921     FUNC_LOG;
       
   922     
       
   923     // One timing descriptor is specified in two bytes:
       
   924     // 26h:
       
   925     // -------------------------------------------------------------------------
       
   926     //      01h-FFh:
       
   927     //      Horizontal addressable pixels: Value Stored (in hex) =
       
   928     //          (Horizontal addressable pixels / 8) – 31
       
   929     //      Range: 256 pixels -> 2288 pixels, in increments of 8 pixels
       
   930     //      --------------------------------------------------------------------
       
   931     //      00h:
       
   932     //      Reserved. Do not use!
       
   933     // -------------------------------------------------------------------------
       
   934     // 27h: 
       
   935     // -------------------------------------------------------------------------
       
   936     //      Bits 7 - 6:
       
   937     //      Image Aspect Ratio:
       
   938     //      0 0 _ _ _ _ _ _ (16 : 10 AR)
       
   939     //      0 1 _ _ _ _ _ _ ( 4 : 3  AR)
       
   940     //      1 0 _ _ _ _ _ _ ( 5 : 4  AR)
       
   941     //      1 1 _ _ _ _ _ _ (16 : 9  AR)
       
   942     //      --------------------------------------------------------------------
       
   943     //      Bits 0 - 5:
       
   944     //      Field Refresh Rate: Value Stored (in binary) =
       
   945     //          Field Refresh Rate (in Hz) – 60
       
   946     //      Range: 60 Hz -> 123Hz
       
   947     // -------------------------------------------------------------------------
       
   948     // 27h: 
       
   949     // 28h: 
       
   950     // -------------------------------------------------------------------------
       
   951     // etc.
       
   952 
       
   953     // There can be up to 8 standard timings (2 bytes * 8)
       
   954     const TInt KStandardTimingBytes = 16;
       
   955     const TUint KRefreshRateMask = 0x3F; // --XXXXXX
       
   956     TInt retVal(KErrNone);
       
   957     
       
   958     TUint16 width = 0;
       
   959     TUint16 height = 0;
       
   960     TUint16 refreshRate = 0;
       
   961     TUint8 byte1 = 0;
       
   962     TUint8 byte2 = 0;
       
   963     for( TInt i = 0; i < KStandardTimingBytes; i += 2 )
       
   964         {
       
   965         byte1 = iEdidParserPtr->GetStandardTimings( i );
       
   966         byte2 = iEdidParserPtr->GetStandardTimings( i + 1 );
       
   967         
       
   968         // Horizontal pixels
       
   969         width = ( byte1 + 31 ) * 8;
       
   970         
       
   971         // Aspect ratio & vertical lines
       
   972         if( !( byte2 & KBit7 ) && !( byte2 & KBit6 ) )
       
   973             {
       
   974             // 16 : 10 AR
       
   975             height = ( width * 10 ) / 16;
       
   976             }
       
   977         else if( !( byte2& KBit7 ) && ( byte2 & KBit6 ) )
       
   978             {
       
   979             // 4 : 3 AR
       
   980             height = ( width * 3 ) / 4;
       
   981             }
       
   982         else if( ( byte2 & KBit7 ) && !( byte2& KBit6 ) )
       
   983             {
       
   984             // 5 : 4 AR
       
   985             height = ( width * 4 ) / 5;
       
   986             }
       
   987         else // ( byte2 & KBit7 ) && ( byte2 & KBit6 )
       
   988             {
       
   989             // 16 : 9 AR
       
   990             height = ( width * 9 ) / 16;
       
   991             }
       
   992         
       
   993         // Refresh rate
       
   994         // Nullify bits 6 and 7
       
   995         byte2 = byte2 & KRefreshRateMask;
       
   996         refreshRate = byte2 + 60;
       
   997         
       
   998         // Set timing item by resolution
       
   999         retVal = SetDmtModeByResolution( aTimings, width, height, refreshRate );
       
  1000         }
       
  1001     
       
  1002     return retVal;
       
  1003     }
       
  1004 
       
  1005 //------------------------------------------------------------------------------
       
  1006 // SetDmtModesFromTimingDescriptors
       
  1007 //------------------------------------------------------------------------------
       
  1008 //
       
  1009 TInt CEDIDHandler::SetDmtModesFromTimingDescriptors(
       
  1010     RArray<THdmiDviTimings>& aTimings ) const
       
  1011     {
       
  1012     FUNC_LOG;
       
  1013     
       
  1014     // 1st 18 byte timing descriptor
       
  1015     THdmiDviTimings timings;
       
  1016     TInt retVal(KErrNone);
       
  1017     
       
  1018     TEdidDescriptorBlock first =
       
  1019         iEdidParserPtr->GetDescriptorBlock( EEdidDescriptorBlockFirstTiming );
       
  1020     FillHdmiDviTimings( first, timings );
       
  1021     retVal = aTimings.Append( timings );
       
  1022     ERROR( retVal, "Failed to append 1st timing descriptor in array" );
       
  1023 
       
  1024     if( KErrNone == retVal )
       
  1025         {
       
  1026         // 2nd 18 byte timing descriptor
       
  1027         Mem::FillZ( ( TAny* )&timings, sizeof( timings ) );
       
  1028         TEdidDescriptorBlock second =
       
  1029             iEdidParserPtr->GetDescriptorBlock( EEdidDescriptorBlockSecondTiming );
       
  1030         FillHdmiDviTimings( second, timings );
       
  1031         retVal = aTimings.Append( timings );
       
  1032         ERROR( retVal, "Failed to append 2nd timing descriptor in array" );
       
  1033         }
       
  1034     
       
  1035     return retVal;
       
  1036     }
       
  1037 
       
  1038 //------------------------------------------------------------------------------
       
  1039 // TimingByIndex
       
  1040 //------------------------------------------------------------------------------
       
  1041 //
       
  1042 const TTimingItem* CEDIDHandler::TimingByIndex( TInt aIndex,
       
  1043     TTimingModeType aType ) const
       
  1044     {
       
  1045     FUNC_LOG;
       
  1046     
       
  1047     const TTimingItem* item = NULL;
       
  1048     if( aIndex >= 0 )
       
  1049         {
       
  1050         if( aType == ETimingModeCEA )
       
  1051             {
       
  1052             if( aIndex < KCEATimingCount )
       
  1053                 {
       
  1054                 item = &KCEATimings[aIndex];
       
  1055                 }
       
  1056             }
       
  1057         else
       
  1058             {
       
  1059             if( aIndex < KDMTTimingCount )
       
  1060                 {
       
  1061                 item = &KDMTTimings[aIndex];
       
  1062                 }
       
  1063             }
       
  1064         }
       
  1065 
       
  1066     return item;
       
  1067     }
       
  1068 
       
  1069 //------------------------------------------------------------------------------
       
  1070 // TimingByResolution
       
  1071 //------------------------------------------------------------------------------
       
  1072 //
       
  1073 const TTimingItem* CEDIDHandler::TimingByResolution( TUint16 aWidth,
       
  1074     TUint16 aHeight,
       
  1075     TUint16 aRefreshRate,
       
  1076     TTimingModeType aType ) const
       
  1077     {
       
  1078     FUNC_LOG;
       
  1079 
       
  1080     const TTimingItem* item = NULL;
       
  1081     if( aType == ETimingModeCEA )
       
  1082         {
       
  1083         // CEA mode
       
  1084         for( TInt i = 0; i < KCEATimingCount; i++ )
       
  1085             {
       
  1086             item = &KCEATimings[i];
       
  1087             if( item->iWidth == aWidth &&
       
  1088                 item->iHeight == aHeight &&
       
  1089                 item->iFieldRate == aRefreshRate )
       
  1090                 {
       
  1091                 // Item found, break
       
  1092                 break;
       
  1093                 }
       
  1094             item = NULL;
       
  1095             }
       
  1096         }
       
  1097     else
       
  1098         {
       
  1099         // DMT mode
       
  1100         for( TInt i = 0; i < KDMTTimingCount; i++ )
       
  1101             {
       
  1102             item = &KDMTTimings[i];
       
  1103             if( item->iWidth == aWidth &&
       
  1104                 item->iHeight == aHeight &&
       
  1105                 item->iFieldRate == aRefreshRate )
       
  1106                 {
       
  1107                 // Item found, break
       
  1108                 break;
       
  1109                 }
       
  1110             item = NULL;
       
  1111             }
       
  1112         }
       
  1113 
       
  1114     return item;
       
  1115     }
       
  1116 
       
  1117 //------------------------------------------------------------------------------
       
  1118 // SetDmtModeByResolution
       
  1119 //------------------------------------------------------------------------------
       
  1120 //
       
  1121 TInt CEDIDHandler::SetDmtModeByResolution( RArray<THdmiDviTimings>& aTimings,
       
  1122     TUint16 aWidth,
       
  1123     TUint16 aHeight,
       
  1124     TUint16 aRefreshRate ) const
       
  1125     {
       
  1126     FUNC_LOG;
       
  1127     
       
  1128     TInt retVal(KErrNone);
       
  1129 
       
  1130     const TTimingItem* item = TimingByResolution( aWidth,
       
  1131         aHeight, aRefreshRate, ETimingModeDMT );
       
  1132     if( item )
       
  1133         {
       
  1134         THdmiDviTimings timings;
       
  1135         FillHdmiDviTimings( *item, timings );
       
  1136         retVal = aTimings.Append( timings );
       
  1137         ERROR_1( retVal, "Failed to append DMT timing: %S in array",
       
  1138             item->iTimingName );
       
  1139         }
       
  1140     else
       
  1141         {
       
  1142         ERROR_3( KErrArgument, "DMT timing item not found for width: %d, height: %d, refresh rate: %d",
       
  1143             aWidth, aHeight, aRefreshRate );
       
  1144         }
       
  1145     
       
  1146     return retVal;
       
  1147     }
       
  1148 
       
  1149 //------------------------------------------------------------------------------
       
  1150 // SetDmtModeByResolution
       
  1151 //------------------------------------------------------------------------------
       
  1152 //
       
  1153 TTvSettings::TAspectRatio CEDIDHandler::ResolveAspectRatio( TUint16 aWidth,
       
  1154     TUint16 aHeight ) const
       
  1155     {
       
  1156     FUNC_LOG;
       
  1157     
       
  1158     TTvSettings::TAspectRatio aspectRatio = TTvSettings::EUndefRatio;
       
  1159     TReal source = ( TReal )aWidth / ( TReal )aHeight;
       
  1160     TReal target = 0.0;
       
  1161     if( Math::Round( target, source, 3 ) == KErrNone )
       
  1162         {
       
  1163         if( target == K16d9 )
       
  1164             {
       
  1165             // 16:9
       
  1166             aspectRatio = TTvSettings::E16d9;
       
  1167             }
       
  1168         else if( target == K4d3 )
       
  1169             {
       
  1170             // 4:3
       
  1171             aspectRatio = TTvSettings::E4d3;
       
  1172             }
       
  1173         }
       
  1174     
       
  1175     return aspectRatio;
       
  1176     }
       
  1177 
       
  1178 //------------------------------------------------------------------------------
       
  1179 // CalculateOverscan
       
  1180 //------------------------------------------------------------------------------
       
  1181 //
       
  1182 void CEDIDHandler::CalculateOverscan( TPoint& aTLCorner,
       
  1183     TPoint& aBRCorner ) const
       
  1184     {
       
  1185     FUNC_LOG;
       
  1186 
       
  1187     // No need to calculate if the screen size is zero
       
  1188     if( aBRCorner.iX > 0 && aBRCorner.iY > 0 )
       
  1189         {
       
  1190         // hOverscanPixels = ( ( Width * hOverscan ) + 50 ) / 20000
       
  1191         //
       
  1192         //  hOverscanPixels:
       
  1193         //      pixels which are needed to be added to top left X
       
  1194         //      pixels which are needed to be reduced from bottom right X
       
  1195         //  Width:
       
  1196         //      Horizontal resolution
       
  1197         //  hOverscan:
       
  1198         //      Horizontal overscan in percents (1% == 100)
       
  1199         //  50:
       
  1200         //      Used to round up possible decimals
       
  1201         //  20000:
       
  1202         //      Used to get rid of percentage multiplier and to get the overscan value
       
  1203         //      for one side
       
  1204         TInt hOverscanPixels = ( aBRCorner.iX * iHOverscan + 50 ) / 20000;
       
  1205         aTLCorner.iX = hOverscanPixels;
       
  1206         aBRCorner.iX = ( aBRCorner.iX - hOverscanPixels );
       
  1207         
       
  1208         // vOverscanPixels = ( ( Height * vOverscan ) + 50 ) / 20000
       
  1209         //
       
  1210         //  vOverscanPixels:
       
  1211         //      pixels which are needed to be added to top left Y
       
  1212         //      pixels which are needed to be reduced from bottom right Y
       
  1213         //  Height:
       
  1214         //      Horizontal resolution
       
  1215         //  vOverscan:
       
  1216         //      Vertical overscan in percents (1% == 100)
       
  1217         //  50:
       
  1218         //      Used to round up possible decimals
       
  1219         //  20000:
       
  1220         //      Used to get rid of percentage multiplier and to get the overscan value
       
  1221         //      for one side
       
  1222         TInt vOverscanPixels = ( aBRCorner.iY * iVOverscan + 50 ) / 20000;
       
  1223         aTLCorner.iY = vOverscanPixels;
       
  1224         aBRCorner.iY = ( aBRCorner.iY - vOverscanPixels );
       
  1225         }
       
  1226     }
       
  1227 
       
  1228 //------------------------------------------------------------------------------
       
  1229 // CalculateOverscan
       
  1230 //------------------------------------------------------------------------------
       
  1231 //
       
  1232 void CEDIDHandler::UpdateOverscanValues()
       
  1233     {
       
  1234     FUNC_LOG;
       
  1235 
       
  1236     // Overscan from cenrep
       
  1237     TInt hOverscan = 0;
       
  1238     TInt vOverscan = 0;
       
  1239     CRepository* cenRep = NULL;
       
  1240     TInt err = KErrNone;
       
  1241     
       
  1242     TRAP( err, cenRep = CRepository::NewL( KCRUidTvoutSettings ) );
       
  1243     if( err == KErrNone )
       
  1244         {
       
  1245         
       
  1246         // Horizontal
       
  1247         err = cenRep->Get( KSettingsTvoutHorizontalOverscan, hOverscan );
       
  1248         if( err != KErrNone )
       
  1249             {
       
  1250             hOverscan = 0;
       
  1251             }
       
  1252         
       
  1253         // Vertical
       
  1254         err = cenRep->Get( KSettingsTvoutVerticalOverscan, vOverscan );
       
  1255         if( err != KErrNone )
       
  1256             {
       
  1257             vOverscan = 0;
       
  1258             }
       
  1259         
       
  1260         // Cleanup
       
  1261         delete cenRep;
       
  1262         }
       
  1263     
       
  1264     // Update overscan values
       
  1265     iHOverscan = hOverscan;
       
  1266     iVOverscan = vOverscan;
       
  1267     }
       
  1268 
       
  1269 // ----------------------------------------------------------------------------
       
  1270 // CEDIDHandler::FilterAvailableTvConfigList
       
  1271 //
       
  1272 // ----------------------------------------------------------------------------
       
  1273 //
       
  1274 TInt CEDIDHandler::FilterAvailableTvConfigList( RArray<THdmiDviTimings>& aHdmiConfigs )
       
  1275     {
       
  1276     FUNC_LOG;
       
  1277     
       
  1278 	TUint supportedCount;
       
  1279 	TInt  retVal( KErrNotFound );
       
  1280 	TInt  availableCount( aHdmiConfigs.Count() );
       
  1281 	RArray<TSupportedHdmiDviMode> supportedModes;
       
  1282 
       
  1283 	INFO_1( "HDMI CONFIGS --- From SINK -- Total : %d", availableCount );
       
  1284 
       
  1285 	retVal = iTVOutConfigForHDMI.GetSupportedHdmiModes( supportedModes );
       
  1286 
       
  1287 	if( KErrNone == retVal )
       
  1288 		{
       
  1289 		TInt availableIndex = 0;
       
  1290 		TBool found( EFalse );
       
  1291 		TBool defaultCEAmode( EFalse );
       
  1292 		supportedCount = supportedModes.Count();
       
  1293 		INFO_1( "HDMI CONFIGS --- From HW -- Total : %d", supportedCount );
       
  1294 
       
  1295 		INFO( "Filtered list -- START" );
       
  1296 		while( availableIndex < availableCount )
       
  1297 			{
       
  1298 			found = EFalse;
       
  1299 			
       
  1300 			for( TInt supportedIndex = 0; (supportedIndex < supportedCount); supportedIndex++ )
       
  1301 				{
       
  1302 				// Check CEA mode
       
  1303 				if( aHdmiConfigs[ availableIndex ].iCeaMode && 
       
  1304 					(TSupportedHdmiDviMode::ECea == supportedModes[ supportedIndex ].iStandardModeType) &&
       
  1305 					(aHdmiConfigs[ availableIndex ].iCeaMode == supportedModes[ supportedIndex ].iStandardMode) )
       
  1306 					{
       
  1307 					found = ETrue;
       
  1308 					if( aHdmiConfigs[ availableIndex].iCeaMode == KDefaultCEAMode )
       
  1309 					    {
       
  1310 					    defaultCEAmode = ETrue;
       
  1311 					    }
       
  1312 					TRACE_TIMINGS( (aHdmiConfigs[ availableIndex ]) );
       
  1313 					break;
       
  1314 					}
       
  1315 
       
  1316 				// Check DMT mode
       
  1317 				if( aHdmiConfigs[ availableIndex ].iDmtMode &&
       
  1318 					(TSupportedHdmiDviMode::EDmt == supportedModes[ supportedIndex ].iStandardModeType) &&
       
  1319 					(aHdmiConfigs[ availableIndex ].iDmtMode == supportedModes[ supportedIndex ].iStandardMode) )
       
  1320 					{
       
  1321 					found = ETrue;
       
  1322 					TRACE_TIMINGS( (aHdmiConfigs[ availableIndex ]) );
       
  1323 					break;
       
  1324 					}
       
  1325 				}
       
  1326 
       
  1327 			if( EFalse == found )
       
  1328 				{
       
  1329 				// Remove from the list
       
  1330 				aHdmiConfigs.Remove( availableIndex );
       
  1331 				availableCount--;
       
  1332 				continue;
       
  1333 				}
       
  1334 
       
  1335 			availableIndex++;
       
  1336 			}
       
  1337 		
       
  1338 		    if( ( (KDefaultCEAModePhysImgAspRatioNr == iEdidParserPtr->GetAspectRatioLandscape()) 
       
  1339 		            && (KDefaultCEAModePhysImgAspRatioDr == iEdidParserPtr->GetAspectRatioPortrait()) ) 
       
  1340 		            && !defaultCEAmode )		    
       
  1341 
       
  1342 			{
       
  1343             THdmiDviTimings timings;
       
  1344             
       
  1345             // Get a timing item for default CEA Mode (1)
       
  1346             const TTimingItem* item = TimingByIndex( KDefaultCEAModeIndex, ETimingModeCEA );
       
  1347             if( item )
       
  1348                 {
       
  1349                 Mem::FillZ( ( TAny* )&timings, sizeof( timings ) );
       
  1350                 FillHdmiDviTimings( *item, timings );
       
  1351                 retVal = aHdmiConfigs.Append( timings );
       
  1352                 ERROR( retVal, "Failed to append CEA timing in available config array" );
       
  1353                 }
       
  1354 			}
       
  1355 
       
  1356 		INFO( "Filtered list -- END" );
       
  1357 		supportedModes.Close();
       
  1358 		}
       
  1359 
       
  1360 	return retVal;
       
  1361     }
       
  1362 
       
  1363 //------------------------------------------------------------------------------
       
  1364 // C++ constructor
       
  1365 //------------------------------------------------------------------------------
       
  1366 //
       
  1367 CEDIDHandler::CEDIDHandler( MFSMForBody& aFSM,
       
  1368     CTVOutConfigForHDMI& aTVOutConfigForHDMI ) :
       
  1369     CActive( CActive::EPriorityLow ),
       
  1370     iFSM( aFSM ),
       
  1371     iTVOutConfigForHDMI( aTVOutConfigForHDMI ),
       
  1372     iRetryCounter( 0 ),
       
  1373     iRequestID( EUndefRequest )
       
  1374     {
       
  1375     FUNC_LOG;
       
  1376     }
       
  1377 
       
  1378 //------------------------------------------------------------------------------
       
  1379 // ConstructL
       
  1380 //------------------------------------------------------------------------------
       
  1381 //
       
  1382 void CEDIDHandler::ConstructL()
       
  1383     {
       
  1384     FUNC_LOG;
       
  1385     
       
  1386     INFO( "Creating Retry Timer object" );
       
  1387     User::LeaveIfError(iRetryTimer.CreateLocal());
       
  1388     
       
  1389     INFO( "Creating CDdcPortAccess object" );
       
  1390     iDdcPortAccess = CDdcPortAccess::NewL();
       
  1391 
       
  1392     CActiveScheduler::Add( this );
       
  1393     }
       
  1394 
       
  1395 // ======== GLOBAL FUNCTIONS ========
       
  1396 
       
  1397