source: svn/trunk/newcon3bcm2_21bu/dta/src/settop_api/bsettop_hdmi.c

Last change on this file was 2, checked in by phkim, 11 years ago

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 49.4 KB
Line 
1
2#include "bsettop_hdmi.h"
3#include "bsettop.h"
4#include "bsettop_display_priv.h"
5#include "bstd.h"
6#include "bkni.h"
7#include "bkni_multi.h"
8#include "bhdm.h"
9#ifdef HDCPLIB
10#define BHDM_HAS_SECURITY
11#if (CONFIG_ENABLE_SCM != 1)
12#include "bhsm.h"
13#include "bhsm_keyladder.h"
14#include "bhdcplib_keyloader.h"
15#endif
16#include "bhdcplib.h"
17#endif
18#include "bhdm_edid.h"
19#include "bvdc.h"
20#include "gist.h"
21#include "bos_task_priorities.h"
22#if BHDM_CEC_SUPPORT
23        #include "bhdm_cec.h"
24#endif
25
26BDBG_MODULE(bsettop_hdmi);
27
28bsettop_hdmi_t s_bsettop_hdmi = NULL;
29
30#if BHDM_CEC_SUPPORT
31
32/**
33Summary:
34        HdmiOutput CEC settings
35**/
36typedef struct HdmiOutputCecSettings
37{
38        bool enabled; /* enable the CEC core */
39} HdmiOutputCecSettings;
40
41/**
42Summary:
43        Status returned by HdmiOutput_GetCecStatus
44**/
45typedef struct HdmiOutputCecStatus
46{
47        uint8_t physicalAddress[2];
48        uint8_t logicalAddress;         /* Until logical address is obtained by Nexus, the CEC Send/Receive functions cannot be used.
49                                                                   0xFF means no address. */
50
51        bool messageReceived;           /* If true, call HdmiOutput_ReceiveCecMessage to receive a message. */
52        bool messageSendPending;        /* If true, you must wait before calling HdmiOutput_SendCecMessage again. */
53} HdmiOutputCecStatus;
54
55typedef enum HdmiOutputLogicalAddrSearch
56{
57        HdmiOutputLogicalAddrSearch_eInit,
58        HdmiOutputLogicalAddrSearch_eNext,
59        HdmiOutputLogicalAddrSearch_eReady
60} HdmiOutputLogicalAddrSearch;
61
62/**
63Summary:
64        Holds data of CEC message to be transmitted or received message
65**/
66typedef struct HdmiOutputCecMessageData
67{
68        uint8_t initiatorAddr ;
69        uint8_t destinationAddr ;
70        uint8_t messageBuffer[16] ;
71        uint8_t messageLength ;
72} HdmiOutputCecMessageData;
73
74static uint8_t g_logicalAddrArray[] =
75{
76        BAVC_HDMI_CEC_StbDevices_eSTB1,
77        BAVC_HDMI_CEC_StbDevices_eSTB2,
78        BAVC_HDMI_CEC_StbDevices_eSTB3,
79        BAVC_HDMI_CEC_StbDevices_eSTB4,
80        BAVC_HDMI_CEC_StbDevices_eFreeUse,
81        BAVC_HDMI_CEC_AllDevices_eUnRegistered
82};
83
84static HdmiOutputCecSettings    g_cecSettings;
85static HdmiOutputCecStatus  g_cecStatus;
86
87BERR_Code HdmiOutput_GetCecStatus( bsettop_hdmi_t hdmiOutput, HdmiOutputCecStatus *pStatus );
88BERR_Code HdmiOutput_SendCecMessage( bsettop_hdmi_t hdmiOutput, const HdmiOutputCecMessageData *pXmitCecMessage);
89
90#endif
91
92/* Global Types */
93typedef enum HdmiOutputState
94{
95        HdmiOutputState_eDisconnected,
96        HdmiOutputState_eConnected,
97        HdmiOutputState_ePoweredDown,
98        HdmiOutputState_eMax
99} HdmiOutputState;
100
101
102#define HDMI_STK_SIZE   1024
103struct bsettop_hdmi
104{
105        bool done;
106        bool bDspFmtValid;
107        bdisplay_t display;
108        BHDM_Handle hHDMI;
109        BAVC_MatrixCoefficients hdmiMatrixCoef;
110        BHDM_Settings hdmiSettings;
111        BKNI_EventHandle hdmEvent;
112#if BHDM_CEC_SUPPORT
113        BKNI_EventHandle cecEvent;
114        HdmiOutputCecSettings   cecSettings;   
115        HdmiOutputCecStatus cecStatus;
116        HdmiOutputLogicalAddrSearch searchState;
117        unsigned logAddrSearchIndex;
118#if 0
119        unsigned int hdmi_cec_stack[HDMI_STK_SIZE];
120#endif
121        bool av_mute;
122    uint8_t initiatorAddr;
123    uint8_t destinationAddr;   
124    uint8_t physicalAddress[2];
125#endif
126        b_task_t  h_hdmi_task;
127        unsigned int hdmi_stack[HDMI_STK_SIZE];
128        int maxEdidRetries;
129
130        BI2C_ChannelHandle i2cChannelHandle;
131        BREG_I2C_Handle i2cRegHandle;
132
133        baudio_decode_t audio_decode;
134        BAVC_Audio_Info audioInfo;
135
136        HdmiOutputState lastState;
137        HdmiOutputState newState;
138
139#ifdef HDCPLIB
140        BHDCPlib_State hdcpState;
141        BHDCPlib_Configuration hdcpConfig;
142        BHDCPlib_Dependencies hdcpDependencies;
143        BHDCPlib_Handle hHDCPlib;
144#if (CONFIG_ENABLE_SCM!=1)
145        BHSM_Handle hHsm;
146#endif
147        BKNI_EventHandle hHDCPRiEvent;
148        BKNI_EventHandle hHDCPRjEvent;
149        BHDCPlib_HdcpError hdcpError;
150#endif
151
152        bool transmitEncrypted;                                         /* If true, transmission will be encrypted once authenticated */
153        bool pjCheckEnabled;                                            /* If true, the HDCP Pj key will be checked */
154        bool checkHDCP;
155        bool hdcpStarted;
156
157        bool native;                                    /* to use native audio mode for dolby digital bit stream test */
158        bsettop_hdcp_authentication_cb_t hdcp_authentication_cb;        /* hdcp check callback */
159};
160
161BFMT_AspectRatio bsettop_hdmi_check_aspect_ratio(bsettop_hdmi_t h_hdmi)
162{
163    bdisplay_t display;
164        bdisplay_settings display_settings;
165
166    BDBG_ASSERT(h_hdmi);
167    BDBG_ASSERT(h_hdmi->display);
168
169    display = h_hdmi->display;
170        bdisplay_get(display,&display_settings);
171       
172        switch (display_settings.format) 
173        {
174                case bdisplay_format_auto:
175                case bdisplay_format_720p:
176        case bdisplay_format_1080i:
177        case bdisplay_format_1080p24:
178        case bdisplay_format_1080p30:
179                        return BFMT_AspectRatio_e16_9;
180       
181                default:
182                        break;
183        }
184        return BFMT_AspectRatio_e4_3;
185}
186
187static BFMT_AspectRatio bsettop_hdmi_auto_aspect_ratio(bsettop_hdmi_t h_hdmi, BFMT_VideoFmt eFmt)
188{
189    bdisplay_t display;
190        uint8_t native;
191
192    BDBG_ASSERT(h_hdmi);
193    BDBG_ASSERT(h_hdmi->display);
194
195    display = h_hdmi->display;
196
197        switch (eFmt)
198        {
199                case BFMT_VideoFmt_e1080i:
200                case BFMT_VideoFmt_e720p:
201                        return BFMT_AspectRatio_e16_9;
202                case BFMT_VideoFmt_eNTSC:
203                        if (BERR_SUCCESS == BHDM_EDID_CheckRxHdmiVideoSupport(
204                                h_hdmi->hHDMI, 720, 480, BAVC_ScanType_eInterlaced,
205                                BAVC_FrameRateCode_e59_94, BFMT_AspectRatio_e16_9, &native))
206                        {
207                                return BFMT_AspectRatio_e16_9;
208                        }
209                        else if (BERR_SUCCESS == BHDM_EDID_CheckRxHdmiVideoSupport(
210                                h_hdmi->hHDMI, 720, 480, BAVC_ScanType_eInterlaced,
211                                BAVC_FrameRateCode_e60, BFMT_AspectRatio_e16_9, &native))
212                        {
213                                return BFMT_AspectRatio_e16_9;
214                        }
215                        else
216                        {
217                                return BFMT_AspectRatio_e4_3;
218                        }
219                case BFMT_VideoFmt_e480p:
220                        if (BERR_SUCCESS == BHDM_EDID_CheckRxHdmiVideoSupport(
221                                h_hdmi->hHDMI, 720, 480, BAVC_ScanType_eProgressive,
222                                BAVC_FrameRateCode_e59_94, BFMT_AspectRatio_e16_9, &native))
223                        {
224                                return BFMT_AspectRatio_e16_9;
225                        }
226                        else if (BERR_SUCCESS == BHDM_EDID_CheckRxHdmiVideoSupport(
227                                h_hdmi->hHDMI, 720, 480, BAVC_ScanType_eProgressive,
228                                BAVC_FrameRateCode_e60, BFMT_AspectRatio_e16_9, &native))
229                        {
230                                return BFMT_AspectRatio_e16_9;
231                        }
232                        else
233                        {
234                                return BFMT_AspectRatio_e4_3;
235                        }
236                default:
237                        return BFMT_AspectRatio_e16_9;
238        }
239}
240
241static void bsettop_hdmi_set_display_format(bsettop_hdmi_t h_hdmi)
242{
243    bdisplay_t display;
244        bdisplay_settings display_settings;
245        BFMT_AspectRatio asp_r_480i, asp_r_480p;
246
247    BDBG_ASSERT(h_hdmi);
248    BDBG_ASSERT(h_hdmi->display);
249
250        display = h_hdmi->display;
251        asp_r_480i = bsettop_hdmi_auto_aspect_ratio(h_hdmi, BFMT_VideoFmt_eNTSC);
252        asp_r_480p = bsettop_hdmi_auto_aspect_ratio(h_hdmi, BFMT_VideoFmt_e480p);
253        bdisplay_record_hdmi_auto_aspect_ratio(display, (uint32_t) asp_r_480i, (uint32_t) asp_r_480p);
254
255        if (h_hdmi->bDspFmtValid)
256        {
257                bdisplay_get(display,&display_settings);
258                bdisplay_set(display,&display_settings);
259        }
260}
261
262void bsettop_hdmi_mark_dsp_fmt_valid(bsettop_hdmi_t h_hdmi)
263{
264    BDBG_ASSERT(h_hdmi);
265        h_hdmi->bDspFmtValid = true;
266}
267
268bool bsettop_hdmi_get_native_audio_mode(void)
269{
270    if (s_bsettop_hdmi)
271        return s_bsettop_hdmi->native;
272    else {
273        return false;
274    }
275}
276
277BERR_Code bsettop_hdmi_set_native_audio_mode(bool native)
278{
279    if (s_bsettop_hdmi) {
280        s_bsettop_hdmi->native = native ? true : false;
281                return BERR_SUCCESS;
282        }
283    else {
284        return BERR_NOT_INITIALIZED;
285    }
286}
287
288BERR_Code bsettop_hdmi_p_set_native_audio_mode(bsettop_hdmi_t h_hdmi, bool native)
289{
290        BERR_Code rc = BERR_SUCCESS;
291        BHDM_Settings st;
292
293        rc = BHDM_GetDefaultSettings(&st);
294        if (native) {
295                /* overwrite default for using native mode? */
296            /**** AUDIO Info Frame Structure *****/
297        h_hdmi->hdmiSettings.stAudioInfoFrame.ChannelCount = BAVC_HDMI_AudioInfoFrame_ChannelCount_eReferToStreamHeader;
298                /* TODO how to overwrite this value? */
299        //h_hdmi->hdmiSettings.stAudioInfoFrame.SpeakerAllocation = BHDM_ChannelAllocation_eStereo;
300        }       
301        else {
302        h_hdmi->hdmiSettings.stAudioInfoFrame.ChannelCount = BAVC_HDMI_AudioInfoFrame_ChannelCount_e2Channels;
303        }
304        return rc;
305}
306
307#if BHDM_CEC_SUPPORT
308
309#define CEC_SEND_MSG_DELAY      5000
310
311/* send CEC command */
312BERR_Code bsettop_hdmi_cec_cmd(int cecCmd, int destinationAddr)
313{
314        BERR_Code errCode = BERR_SUCCESS;
315        static HdmiOutputCecMessageData msgData;
316
317        BDBG_MSG(("%s: cmd=0x%02x", __func__, cecCmd));
318
319        bsettop_hdmi_t h_hdmi = s_bsettop_hdmi;
320
321        if (!h_hdmi) {
322                return BERR_NOT_INITIALIZED;
323        }       
324
325        HdmiOutput_GetCecStatus(h_hdmi, &g_cecStatus);
326        if (0xff == g_cecStatus.logicalAddress ) {
327                return BERR_NOT_INITIALIZED;
328        }
329
330        /*  default for one byte command */
331        msgData.messageBuffer[0] = cecCmd;
332        msgData.messageLength = 1;
333    msgData.initiatorAddr = destinationAddr;
334    //msgData.destinationAddr = 0xF;            /* broadcast */
335    msgData.destinationAddr = h_hdmi->initiatorAddr;            /* target to sender */
336
337        switch (cecCmd) {
338                case CEC_CMD_REQUEST_ACTIVE_SOURCE:
339                        BDBG_MSG(("send CEC_CMD_REQUEST_ACTIVE_SOURCE cmd"));
340                        break;
341
342                case CEC_CMD_ACTIVE_SOURCE:
343                        BDBG_MSG(("send CEC_CMD_ACTIVE_SOURCE cmd"));
344                        //msgData.messageBuffer[1] = h_hdmi->cecStatus.physicalAddress[0];
345                        //msgData.messageBuffer[2] = h_hdmi->cecStatus.physicalAddress[1];
346                        msgData.messageBuffer[1] = h_hdmi->physicalAddress[0];
347                        msgData.messageBuffer[2] = h_hdmi->physicalAddress[1];
348                        msgData.messageLength = 3;
349                        break;
350
351                case CEC_CMD_INACTIVE_SOURCE:
352                        BDBG_MSG(("send CEC_CMD_INACTIVE_SOURCE cmd"));
353                        //msgData.messageBuffer[1] = h_hdmi->cecStatus.physicalAddress[0];
354                        //msgData.messageBuffer[2] = h_hdmi->cecStatus.physicalAddress[1];
355                        msgData.messageBuffer[1] = h_hdmi->physicalAddress[0];
356                        msgData.messageBuffer[2] = h_hdmi->physicalAddress[1];
357                        msgData.messageLength = 3;
358                        break;
359
360                case CEC_CMD_IMAGE_VIEW_ON:
361                        BDBG_MSG(("send CEC_CMD_IMAGE_VIEW_ON cmd"));
362                        break;
363
364                case CEC_CMD_TEXT_VIEW_ON:
365                        BDBG_MSG(("send CEC_CMD_TEXT_VIEW_ON cmd"));
366                        break;
367
368                case CEC_CMD_STANDBY:
369                        BDBG_MSG(("send CEC_CMD_STANDBY cmd"));
370                        break;
371
372                case CEC_CMD_CEC_VERSION:
373                        BDBG_MSG(("send CEC_CMD_CEC_VERSION cmd"));
374                        msgData.messageBuffer[1] = 0x05;                /* 1.4a ? */
375                        msgData.messageLength = 2;
376                        break;
377
378                case CEC_CMD_REPORT_PHYSICAL_ADDRESS:
379                        BDBG_MSG(("send CEC_CMD_REPORT_PHYSICAL_ADDRESS cmd"));
380                        BHDM_CEC_ReportPhysicalAddress(h_hdmi->hHDMI);
381                        return BERR_SUCCESS;
382
383                case CEC_CMD_GIVE_DEVICE_VENDOR_ID:
384                        BDBG_MSG(("send CEC_CMD_GIVE_DEVICE_VENDOR_ID cmd"));
385                        break;
386
387                case CEC_CMD_DEVICE_VENDOR_ID:
388                        BDBG_MSG(("send CEC_CMD_DEVICE_VENDOR_ID cmd"));
389                        msgData.messageBuffer[1] = 0x1;
390                        msgData.messageBuffer[2] = 0x2;
391                        msgData.messageLength = 3;
392                        break;
393
394                case CEC_CMD_GIVE_DEVICE_POWER_STATUS:
395                        BDBG_MSG(("send CEC_CMD_GIVE_DEVICE_POWER_STATUS cmd"));
396                        break;
397
398                case CEC_CMD_REPORT_POWER_STATUS:
399                        BDBG_MSG(("send CEC_CMD_REPORT_POWER_STATUS cmd"));
400                        msgData.messageBuffer[1] = 0;           /* power on */
401                        msgData.messageLength = 2;
402                        break;
403
404                case CEC_CMD_GIVE_AUDIO_STATUS:
405                        BDBG_MSG(("send CEC_CMD_GIVE_AUDIO_STATUS cmd"));
406                        break;
407
408                case CEC_CMD_REPORT_AUDIO_STATUS:
409                        BDBG_MSG(("send CEC_CMD_REPORT_AUDIO_STATUS cmd"));
410                        msgData.messageBuffer[1] = h_hdmi->av_mute;
411                        msgData.messageLength = 2;
412                        break;
413
414                case CEC_CMD_GET_PHYSICAL_ADDRESS:
415                        BDBG_MSG(("send CEC_CMD_GET_PHYSICAL_ADDRESS cmd"));
416                        break;
417
418                default:
419                        BDBG_WRN(("unsupport CEC cmd %02x", cecCmd));
420                        return BERR_UNKNOWN;
421        }
422        errCode = HdmiOutput_SendCecMessage(h_hdmi, &msgData);
423        BHDM_CEC_EnableReceive(h_hdmi->hHDMI);
424        //bos_sleep(CEC_SEND_MSG_DELAY);               
425
426        return errCode;
427}
428
429/**
430Summary:
431        HdmiOutput CEC settings
432**/
433static BERR_Code GetCecLogicalAddress(bsettop_hdmi_t hdmiOutput)
434{
435        BERR_Code rc;
436        uint8_t addr;
437
438        switch (hdmiOutput->searchState)
439        {
440        default:
441        case HdmiOutputLogicalAddrSearch_eInit:  /* ping first Address */
442                addr = g_logicalAddrArray[hdmiOutput->logAddrSearchIndex];
443                BDBG_MSG(("Starting search for CEC Logical Addr: %d...", addr)) ;
444                hdmiOutput->logAddrSearchIndex = 0;
445                hdmiOutput->cecStatus.logicalAddress = BHDM_CONFIG_CEC_UNINITIALIZED_LOGICAL_ADDR;
446                rc = BHDM_CEC_PingLogicalAddr(hdmiOutput->hHDMI, addr);
447                if (rc)
448                {
449                        BDBG_ERR(("BHDM_CEC_PingLogicalAddr failed")) ;
450                        return rc;
451                }
452                break;
453
454        case HdmiOutputLogicalAddrSearch_eNext:
455                hdmiOutput->logAddrSearchIndex++;
456                addr = g_logicalAddrArray[hdmiOutput->logAddrSearchIndex];
457                BDBG_MSG(("Continuing search for CEC Logical Addr: %d...", addr)) ;
458
459                if (hdmiOutput->logAddrSearchIndex == sizeof(g_logicalAddrArray)/sizeof(g_logicalAddrArray[0]) - 1)
460                {
461                        BDBG_MSG(("All CEC Addrs used; device unregistered")) ;
462                        /* Update state and fall through */
463                        hdmiOutput->searchState = HdmiOutputLogicalAddrSearch_eReady;
464                }
465                else
466                {
467                        rc = BHDM_CEC_PingLogicalAddr(hdmiOutput->hHDMI, addr);
468                        if (rc)
469                        {
470                                BDBG_ERR(("BHDM_CEC_PingLogicalAddr failed")) ;
471                        }
472                        break;
473                }
474                /* pass through */
475
476        case HdmiOutputLogicalAddrSearch_eReady:
477                hdmiOutput->cecStatus.logicalAddress = g_logicalAddrArray[hdmiOutput->logAddrSearchIndex];
478
479                BDBG_MSG(("Found CEC Logical Addr: %d", hdmiOutput->cecStatus.logicalAddress)) ;
480                rc = BHDM_CEC_SetMyAddr(hdmiOutput->hHDMI, hdmiOutput->cecStatus.logicalAddress);
481                if (rc)
482                {
483                        BDBG_ERR(("BHDM_CEC_SetMyAddr failed")) ;
484                        break;
485                }
486
487                rc = BHDM_CEC_GetMyAddrs(hdmiOutput->hHDMI, hdmiOutput->cecStatus.physicalAddress, &hdmiOutput->cecStatus.logicalAddress);
488                if (rc != BERR_NOT_INITIALIZED)
489                {       /* BERR_NOT_INITIALIZED is normal for not connected to CEC compatible device */
490                        if (rc)
491                        {
492                                BDBG_ERR(("BHDM_CEC_GetMyAddr failed")) ;
493                                break;
494                        }
495
496                        /* Report Physical Address */
497                        rc = BHDM_CEC_ReportPhysicalAddress(hdmiOutput->hHDMI);
498                        if (rc)
499                        {
500                                BDBG_ERR(("BHDM_CEC_ReportPhysicalAddress failed")) ;
501                                break;
502                        }
503
504                        /* always enable receive after CEC msg is processed */
505                        rc = BHDM_CEC_EnableReceive(hdmiOutput->hHDMI);
506                        if (rc)
507                        {
508                                BDBG_ERR(("BHDM_CEC_EnableReceive failed")) ;
509                                break;
510                        }
511                        BDBG_MSG(("BHDM_CEC_EnableReceive. ready to receive data")) ;
512                }
513                break;
514        }
515        return rc;
516}
517
518/**
519Summary:
520        Get CEC settings
521**/
522void HdmiOutput_GetCecSettings( bsettop_hdmi_t hdmiOutput, HdmiOutputCecSettings *pSettings )
523{
524        *pSettings = hdmiOutput->cecSettings;
525}
526
527
528/**
529Summary:
530        Set CEC settings
531**/
532BERR_Code HdmiOutput_SetCecSettings( bsettop_hdmi_t hdmiOutput, HdmiOutputCecSettings *pSettings )
533{
534        BERR_Code rc = 0;
535
536        rc = BHDM_CEC_Enable(hdmiOutput->hHDMI, pSettings->enabled);
537        if (rc)
538        {
539                BDBG_ERR(("BHDM_CEC_Enable failed"));
540                return rc;
541        }
542
543        if (pSettings->enabled && (hdmiOutput->cecSettings.enabled != pSettings->enabled
544                                                           || hdmiOutput->cecStatus.logicalAddress == BHDM_CONFIG_CEC_UNINITIALIZED_LOGICAL_ADDR))
545        {
546                hdmiOutput->searchState = HdmiOutputLogicalAddrSearch_eInit;
547                GetCecLogicalAddress(hdmiOutput);
548        }
549
550        hdmiOutput->cecSettings = *pSettings;
551        return rc;
552}
553
554/**
555Summary:
556        Get CEC status
557**/
558BERR_Code HdmiOutput_GetCecStatus( bsettop_hdmi_t hdmiOutput, HdmiOutputCecStatus *pStatus )
559{
560        *pStatus = hdmiOutput->cecStatus;
561        return BERR_SUCCESS;
562}
563
564/**
565Summary:
566        CecCallback
567**/
568void HdmiOutput_P_CecCallback(void *pContext)
569{
570        //HdmiOutputHandle hdmiOutput = (HdmiOutputHandle)pContext;
571        bsettop_hdmi_t hdmiOutput = (bsettop_hdmi_t)pContext;
572        BAVC_HDMI_CEC_IntMessageType messageType;
573        uint8_t messageAck;
574        uint8_t CECMsgLength;
575        uint8_t EOM;
576        BERR_Code rc;
577
578        rc = BHDM_CEC_GetMsgInfo(hdmiOutput->hHDMI, &messageType, &messageAck, &CECMsgLength, &EOM);
579        if (rc)
580        {
581                BDBG_ERR(("BHDM_CEC_GetMsgInfo failed"));
582        }
583        else
584        {
585                if (messageType == BAVC_HDMI_CEC_IntMessageType_eTransmit)
586                {
587                        if (hdmiOutput->searchState < HdmiOutputLogicalAddrSearch_eReady)
588                        {
589                                if (!messageAck)
590                                {
591                                        hdmiOutput->searchState = HdmiOutputLogicalAddrSearch_eReady;
592                                }
593                                else
594                                {
595                                        hdmiOutput->searchState = HdmiOutputLogicalAddrSearch_eNext;
596                                }
597                                GetCecLogicalAddress(hdmiOutput);
598                        }
599                        else
600                        {
601                                hdmiOutput->cecStatus.messageSendPending = false;
602                        }
603                }
604                else
605                {
606                        hdmiOutput->cecStatus.messageReceived = true;
607                }
608        }
609        //TaskCallback_Fire(hdmiOutput->cecCallback);
610}
611
612
613/**
614Summary:
615        Send CEC message
616**/
617BERR_Code HdmiOutput_SendCecMessage( bsettop_hdmi_t hdmiOutput, const HdmiOutputCecMessageData *pXmitCecMessage)
618{
619        BERR_Code rc = BERR_SUCCESS;
620
621        rc = BHDM_CEC_XmitMsg(hdmiOutput->hHDMI, pXmitCecMessage->destinationAddr,
622                                                  (uint8_t *)pXmitCecMessage->messageBuffer, pXmitCecMessage->messageLength);
623
624        /* set Pending if message successfuly sent */
625        if (!rc)
626                hdmiOutput->cecStatus.messageSendPending = true;
627
628        return rc;
629}
630
631/**
632Summary:
633        Receive CEC message
634**/
635BERR_Code HdmiOutput_ReceiveCecMessage( bsettop_hdmi_t hdmiOutput, HdmiOutputCecMessageData *pRecvCecMessage )
636{
637        BERR_Code rc = BERR_SUCCESS;
638        BAVC_HDMI_CEC_MessageData stMessageData;
639
640        hdmiOutput->cecStatus.messageReceived = false;
641        rc = BHDM_CEC_GetReceivedMessage(hdmiOutput->hHDMI, &stMessageData);
642        if (rc)
643        {
644                BDBG_ERR(("Error receiving CEC Msg")) ;
645                return rc;
646        }
647
648        pRecvCecMessage->initiatorAddr = stMessageData.initiatorAddr;
649        pRecvCecMessage->destinationAddr = stMessageData.destinationAddr;
650        pRecvCecMessage->messageLength = stMessageData.messageLength;
651        if (pRecvCecMessage->messageLength > 0)
652                BKNI_Memcpy(&pRecvCecMessage->messageBuffer, &stMessageData.messageBuffer,
653                        (sizeof(uint8_t) * stMessageData.messageLength));
654
655        /* remember these values for later use */
656    hdmiOutput->initiatorAddr = stMessageData.initiatorAddr;
657    hdmiOutput->destinationAddr = stMessageData.destinationAddr;
658
659        return rc;
660}
661void bsettop_handle_cec_event(bsettop_hdmi_t h_hdmi)
662{
663        static HdmiOutputCecMessageData msgData;
664        BERR_Code rc;
665        uint8_t cecOpCode;
666
667        BDBG_MSG(("CEC Event received"));
668
669        HdmiOutput_P_CecCallback(h_hdmi);
670        rc = HdmiOutput_GetCecStatus(h_hdmi, &g_cecStatus);
671        if (0 == g_cecStatus.messageReceived) {
672                /* Tx message */
673                return;
674        }
675        BDBG_MSG(("CEC RX Event received"));
676        if (BHDM_CONFIG_CEC_UNINITIALIZED_LOGICAL_ADDR == g_cecStatus.logicalAddress) {
677                BDBG_MSG(("not got logical address yet"));
678                return;
679        }
680        rc = HdmiOutput_ReceiveCecMessage(h_hdmi, &msgData);
681        if (rc)
682        {
683                BDBG_ERR(("HdmiOutput_ReceiveCecMessage failed, rc=0x%x", rc));
684                /* do dump recieved data? */
685                return;
686        }
687        /* looks like the lenght of ping command from QuantumData 882 is 0 */
688        if (0 == msgData.messageLength) {
689                BDBG_MSG(("Recevied 0 bytes, ping?"));
690                return;
691        }
692
693        msgData.destinationAddr = h_hdmi->initiatorAddr;
694        cecOpCode = msgData.messageBuffer[0];
695        BDBG_MSG(("Recevied CEC message of %d bytes, op=0x%2x, initiator=0x%x, destination=0x%x", msgData.messageLength, cecOpCode, h_hdmi->initiatorAddr, h_hdmi->destinationAddr));
696        switch (cecOpCode) {
697                case CEC_CMD_ABORT:
698                        BDBG_MSG(("======CEC feature about, do nothing"));
699                        break;
700
701                case CEC_CMD_STANDBY:
702                        BDBG_MSG(("======HDMI standby"));
703                        /* to remove input, AvMute */
704                        h_hdmi->av_mute = true;
705                        BHDM_SetAvMute(h_hdmi->hHDMI, true);
706                        break;
707
708                case CEC_CMD_IMAGE_VIEW_ON:
709                        BDBG_MSG(("======Image view on"));
710                        /* to add input */
711                        h_hdmi->av_mute = false;
712                        BHDM_SetAvMute(h_hdmi->hHDMI, false);
713                        break;
714
715                case CEC_CMD_TEXT_VIEW_ON:
716                        BDBG_MSG(("======Text view on"));
717                        /* to add input */
718                        h_hdmi->av_mute = false;
719                        BHDM_SetAvMute(h_hdmi->hHDMI, false);
720                        break;
721
722                case CEC_CMD_GET_PHYSICAL_ADDRESS:
723                        BDBG_MSG(("======CEC_CMD_GET_PHYSICAL_ADDRESS received"));
724                        bsettop_hdmi_cec_cmd(CEC_CMD_REPORT_PHYSICAL_ADDRESS, msgData.destinationAddr);
725                        break;
726
727                case CEC_CMD_REPORT_PHYSICAL_ADDRESS:
728                        BDBG_MSG(("======Physical address = %02x%04x", msgData.messageBuffer[1], msgData.messageBuffer[2]));
729                        h_hdmi->physicalAddress[0] = msgData.messageBuffer[1];
730                        h_hdmi->physicalAddress[1] = msgData.messageBuffer[2];
731                        break;
732
733                case CEC_CMD_GET_CEC_VERSION:
734                        BDBG_MSG(("======CEC_CMD_GET_CEC_VERSION received"));
735                        bsettop_hdmi_cec_cmd(CEC_CMD_CEC_VERSION, msgData.destinationAddr);
736                        break;
737
738                case CEC_CMD_CEC_VERSION:
739                        BDBG_MSG(("======CEC version = %02x", msgData.messageBuffer[1]));
740                        break;
741
742                case CEC_CMD_GIVE_DEVICE_VENDOR_ID:
743                        bsettop_hdmi_cec_cmd(CEC_CMD_DEVICE_VENDOR_ID, msgData.destinationAddr);
744                        break;
745
746                case CEC_CMD_DEVICE_VENDOR_ID:
747                        BDBG_MSG(("======Device vendor ID = %02x%02x%02x", msgData.messageBuffer[1], 
748                                                msgData.messageBuffer[2], msgData.messageBuffer[3]));
749                        break;
750
751                case CEC_CMD_GIVE_DEVICE_POWER_STATUS:
752                        BDBG_MSG(("======CEC_CMD_GIVE_DEVICE_POWER_STATUS received"));
753                        bsettop_hdmi_cec_cmd(CEC_CMD_REPORT_POWER_STATUS, msgData.destinationAddr);
754                        break;
755
756                case CEC_CMD_REPORT_POWER_STATUS:
757                        BDBG_MSG(("======Device power status= %s", 0 == msgData.messageBuffer[1] ? "on" : 
758                                                1 == msgData.messageBuffer[1] ? "off" : 
759                                                2 == msgData.messageBuffer[1] ? "standby to on" : "On to standby"));
760                        break;
761
762                case CEC_CMD_GIVE_AUDIO_STATUS:
763                        bsettop_hdmi_cec_cmd(CEC_CMD_REPORT_AUDIO_STATUS, msgData.destinationAddr);
764                        break;
765
766                case CEC_CMD_REPORT_AUDIO_STATUS:
767                        BDBG_MSG(("======Device power status= %s", 0 == msgData.messageBuffer[1] ? "on" : 
768                                                1 == msgData.messageBuffer[1] ? "off" : 
769                                                2 == msgData.messageBuffer[1] ? "standby to on" : "On to standby"));
770                        break;
771
772                case CEC_CMD_REQUEST_ACTIVE_SOURCE:
773                        bsettop_hdmi_cec_cmd(CEC_CMD_ACTIVE_SOURCE, msgData.destinationAddr);
774                        break;
775
776                case CEC_CMD_DEVICE_VENDOR_CMD:
777                        BDBG_MSG(("======CEC_CMD_DEVICE_VENDOR_CMD received"));
778                        break;
779
780                default:
781                        BDBG_WRN(("OpCode %02x not supported", cecOpCode));
782                        msgData.messageBuffer[0] = 0;   /* abort */
783                        msgData.messageBuffer[1] = cecOpCode;
784                        msgData.messageBuffer[2] = 0;   /* unsupported */
785                        msgData.messageLength = 3;
786                        rc = HdmiOutput_SendCecMessage(h_hdmi, &msgData);
787                        break;
788        }                                       
789
790}
791#else
792BERR_Code bsettop_hdmi_cec_cmd(int cecCmd, int destinationAddr)
793{
794        return BERR_SUCCESS;
795}
796#endif
797
798
799/**
800Summary:
801get hdmi state
802 **/
803
804HdmiOutputState bsettop_hdmi_get_state(bsettop_hdmi_t h_hdmi,bool double_check)
805{
806        BERR_Code errCode;
807        uint8_t rxSense=0, attached=1;
808
809        BHDM_RxDeviceAttached(h_hdmi->hHDMI, &attached);
810        if (attached)
811        {
812
813#ifdef HDCPLIB
814                /* as long as encryption is enabled; no need to check for receiver sense */
815                if (h_hdmi->hdcpState == BHDCPlib_State_eEncryptionEnabled)
816                        return HdmiOutputState_eConnected;
817#endif
818                errCode = BHDM_GetReceiverSense(h_hdmi->hHDMI, &rxSense);
819                BDBG_MSG(("BHDM_GetReceiverSense rxSense = 0x%02x",rxSense));
820                if ( errCode == BERR_SUCCESS )
821                {
822                        if ( rxSense )
823                        {
824                                return HdmiOutputState_eConnected;
825                        }
826                        else if (double_check)
827                        {
828                                bos_sleep(50);
829
830                                /* Double check the receiver sense */
831                                errCode = BHDM_GetReceiverSense(h_hdmi->hHDMI, &rxSense);
832                                BDBG_ERR(("BHDM_GetReceiverSense rxSense = 0x%02x",rxSense));
833
834                                if ( rxSense )
835                                {
836                                        return HdmiOutputState_eConnected;
837                                }
838                                else
839                                {
840                                        return HdmiOutputState_ePoweredDown;
841                                }
842                        }
843                        else
844                        {
845                                return HdmiOutputState_ePoweredDown;
846                        }
847                }
848        }
849
850        /* device disconnected*/
851        return HdmiOutputState_eDisconnected;
852}
853
854/**
855Summary:
856handle updating hdcp state
857 **/
858#ifdef HDCPLIB
859
860static void bsettop_update_hdcp_state(bsettop_hdmi_t h_hdmi)
861{
862        bool ready;
863        BHDCPlib_Status hdcpStatus;
864
865        BHDCPlib_GetHdcpStatus(h_hdmi->hHDCPlib, &hdcpStatus);
866        ready = BHDCPlib_LinkReadyForEncryption(h_hdmi->hHDCPlib);
867
868        /* Save last HDCP error */
869        h_hdmi->hdcpError = hdcpStatus.eHdcpError;
870
871        BDBG_MSG(("Updating HDCP State from %d -> %d", h_hdmi->hdcpState, hdcpStatus.eAuthenticationState));
872
873        if ( hdcpStatus.eAuthenticationState != h_hdmi->hdcpState )
874        {
875                h_hdmi->hdcpState = hdcpStatus.eAuthenticationState;
876        }
877
878        if ( ready )
879        {
880                BDBG_MSG(("Authentication complete"));
881
882                if ( h_hdmi->transmitEncrypted )
883                {
884                        BERR_Code errCode;
885
886                        BDBG_WRN(("Enabling Encryption"));
887
888                        errCode = BHDCPlib_TransmitEncrypted(h_hdmi->hHDCPlib);
889                        if ( errCode )
890                        {
891                                errCode = BERR_TRACE(errCode);
892                        }
893                        if (h_hdmi->hdcp_authentication_cb) {
894                                /* tell the application to enable video/audio/CC on HDMI port after authencation successful */
895                                h_hdmi->hdcp_authentication_cb(true);
896                        }
897                }
898        }
899}
900
901
902/**
903Summary:
904Restart hdcp
905 **/
906
907static bresult bsettop_hdmi_restart_hdcp(bsettop_hdmi_t h_hdmi)
908{
909        BERR_Code rc;
910
911        if (h_hdmi->hdcpStarted)
912        {
913                BHDCPlib_DisableAuthentication(h_hdmi->hHDCPlib);
914                h_hdmi->hdcpStarted = false;
915        }
916
917        /* Reset Auth State */
918        rc = BHDCPlib_StartAuthentication(h_hdmi->hHDCPlib);
919
920        if ( rc )
921        {
922                return BERR_TRACE(rc);
923        }
924
925        h_hdmi->hdcpStarted = true;
926        h_hdmi->checkHDCP = true;
927
928        bsettop_update_hdcp_state(h_hdmi);
929        return BERR_SUCCESS;
930}
931#else /* HDCPLIB */
932static void bsettop_update_hdcp_state(bsettop_hdmi_t h_hdmi)
933{
934}
935static bresult bsettop_hdmi_restart_hdcp(bsettop_hdmi_t h_hdmi)
936{
937        return b_ok;
938}
939#endif /* HDCPLIB */
940
941static bool g_RGB_verification = false;
942
943bool bsettop_hdmi_get_RGB_output(void)
944{
945        return g_RGB_verification;
946}
947
948/**
949Summary:
950set RGB output for HDMI verification sake.
951 **/
952bresult bsettop_hdmi_set_RGB_output(bool bRGB)
953{
954        g_RGB_verification = bRGB;
955        return b_ok;
956}
957
958/**
959Summary:
960check if the video format is supported by the TV connected
961 **/
962bool bsettop_hdmi_p_is_video_fmt_supported(bsettop_hdmi_t h_hdmi, BFMT_VideoFmt eFmt)
963{
964        BERR_Code rc;
965        uint8_t supported;
966
967        rc = BHDM_EDID_VideoFmtSupported(h_hdmi->hHDMI, eFmt, &supported);
968        if (BERR_SUCCESS == rc)
969                return (bool)supported ? true : false;
970
971        /* if don't get video format, then assume it is available and try and error */
972        if (BHDM_EDID_VIDEO_FORMATS_UNAVAILABLE == rc)
973                return true;
974
975        return false;
976}
977
978static BFMT_VideoFmt s_display_formate_to_bfmt[] =
979{
980        BFMT_VideoFmt_eMaxCount,
981        BFMT_VideoFmt_e1080i,
982        BFMT_VideoFmt_e720p,
983        BFMT_VideoFmt_eNTSC,
984        BFMT_VideoFmt_e480p,
985        BFMT_VideoFmt_e1080p,
986        BFMT_VideoFmt_e1080p_24Hz,
987        BFMT_VideoFmt_e1080p_30Hz
988};
989
990bool bsettop_hdmi_is_video_fmt_supported(bsettop_display_format_t fmt)
991{
992        if (fmt == bdisplay_format_auto)
993                return true;
994       
995        if (fmt >= bdisplay_format_max)
996        {
997                BDBG_ERR(("%s: Invalid format",__func__));
998                return false;
999        }
1000
1001        if (s_bsettop_hdmi)
1002                return bsettop_hdmi_p_is_video_fmt_supported(s_bsettop_hdmi, s_display_formate_to_bfmt[fmt]);
1003        else 
1004        {
1005                BDBG_ERR(("%s: hdmi not initialized",__func__));
1006                return false;
1007        }
1008}
1009
1010/**
1011Summary:
1012Handle connect for VDC purposes
1013 **/
1014
1015static bresult bsettop_hdmi_vdc_connect(bsettop_hdmi_t h_hdmi)
1016{
1017        BERR_Code rc = 0;
1018#if HAS_HDMI
1019        uint8_t ucRxAttached;
1020        BFMT_VideoFmt eFmt;
1021        bdisplay_t display;
1022        BDBG_ASSERT(h_hdmi);
1023        BDBG_ASSERT(h_hdmi->display);
1024        BHDM_OutputFormat       eOutputFormat = BHDM_OutputFormat_eHDMIMode;
1025        BHDM_OutputPort         eOutputPort = BHDM_OutputPort_eHDMI;
1026        static BHDM_EDID_RxVendorSpecificDB     RxVSDB;
1027        bool bHdmiDevice;
1028    BAVC_HDMI_AudioInfoFrame audioInfoFrame;
1029
1030        display = h_hdmi->display;
1031        /* Verify there is an attached Receiver Device */
1032        rc = BHDM_RxDeviceAttached(h_hdmi->hHDMI, &ucRxAttached);
1033        if (ucRxAttached == 0)
1034        {
1035                BDBG_ERR(("No DVI RX device is attached."));
1036                return berr_not_supported;
1037        }
1038        BDBG_ERR(("++++++++++++++++++++++++++++++++"));
1039        BDBG_ERR(("+  DVI RX device is attached!  +"));
1040        BDBG_ERR(("++++++++++++++++++++++++++++++++"));
1041
1042        BVDC_Display_GetVideoFormat( display->disp[eBDISPLAY_HDMI].hDisplay, &eFmt );
1043
1044        rc = BHDM_EDID_IsRxDeviceHdmi(h_hdmi->hHDMI, &RxVSDB, &bHdmiDevice);
1045        if (BERR_SUCCESS != rc) {
1046                BDBG_ERR(("%s BHDM_EDID_IsRxDeviceHdmi failed %x",__func__,rc));
1047        }
1048        else {
1049                if (!bHdmiDevice) {
1050                        eOutputFormat = BHDM_OutputFormat_eDVIMode;
1051                        eOutputPort = BHDM_OutputPort_eDVI;
1052                }
1053        }
1054
1055        rc = BHDM_EDID_GetSupportedColorimetry(h_hdmi->hHDMI, 
1056                        eOutputFormat,
1057                        display->hdmiFmt,&(h_hdmi->hdmiMatrixCoef));
1058        if (rc != BERR_SUCCESS)
1059        {
1060                BDBG_ERR(("%s:%d BHDM_EDID_GetSupportedColorimetry failed %d",__FUNCTION__,__LINE__,rc));
1061        }
1062
1063        //BVDC_Display_GetHdmiConfiguration(display->disp[eBDISPLAY_HDMI].hDisplay, BVDC_Hdmi_0, &(h_hdmi->hdmiMatrixCoef));
1064        h_hdmi->hdmiSettings.eInputVideoFmt = eFmt;
1065        h_hdmi->hdmiSettings.eOutputPort = eOutputPort;
1066        h_hdmi->hdmiSettings.eColorimetry = h_hdmi->hdmiMatrixCoef;
1067        BDBG_MSG(("%s: RGB output=%d",__func__, g_RGB_verification));
1068        if (g_RGB_verification) {
1069                h_hdmi->hdmiMatrixCoef = BAVC_MatrixCoefficients_eUnknown;     
1070                BVDC_Display_SetHdmiConfiguration(display->disp[eBDISPLAY_HDMI].hDisplay, BVDC_Hdmi_0,h_hdmi->hdmiMatrixCoef);
1071                rc = BVDC_ApplyChanges(display->hVdc);
1072
1073                h_hdmi->hdmiSettings.eColorimetry = BAVC_MatrixCoefficients_eHdmi_RGB;
1074                h_hdmi->hdmiMatrixCoef = BAVC_MatrixCoefficients_eHdmi_RGB;
1075        }
1076        BVDC_Display_SetHdmiConfiguration(display->disp[eBDISPLAY_HDMI].hDisplay, BVDC_Hdmi_0,h_hdmi->hdmiMatrixCoef);
1077        rc = BVDC_ApplyChanges(display->hVdc);
1078        if (rc != BERR_SUCCESS)
1079        {
1080                BDBG_ERR(("%s:%d BVDC_ApplyChanges failed %d",__FUNCTION__,__LINE__,rc));
1081        }
1082        /* check if need bypass to use native dolby audio, is there a need to change HDMI PI code also? */
1083        /* test it, but may need test streams */
1084        //h_hdmi->native = true;
1085        bsettop_hdmi_p_set_native_audio_mode(h_hdmi, h_hdmi->native);   
1086
1087        h_hdmi->hdmiSettings.eOutputFormat = eOutputFormat;
1088        //h_hdmi->hdmiSettings.eAudioBits = BAVC_AudioBits_e24;
1089        //h_hdmi->hdmiSettings.eTimebase = BAVC_Timebase_e0;
1090        //h_hdmi->hdmiSettings.stColorDepth.eBitsPerPixel = BAVC_HDMI_BitsPerPixel_e24bit;
1091        //h_hdmi->hdmiSettings.eAudioFormat = BAVC_AudioFormat_ePCM;;
1092        h_hdmi->hdmiSettings.eAspectRatio = bsettop_hdmi_check_aspect_ratio(h_hdmi);
1093        BHDM_EnableDisplay(h_hdmi->hHDMI, &h_hdmi->hdmiSettings);
1094#if 0
1095        rc = BVDC_ApplyChanges(display->hVdc);
1096        if (rc != BERR_SUCCESS)
1097        {
1098                BDBG_ERR(("%s:%d BVDC_ApplyChanges failed %d",__FUNCTION__,__LINE__,rc));
1099        }
1100#endif
1101        /* audio */
1102        rc = BHDM_GetAudioInfoFramePacket(h_hdmi->hHDMI, &audioInfoFrame);
1103        if (rc)
1104        {
1105                BDBG_WRN(("BHDM_GetAudioInfoFramePacket failed %d", rc));
1106        }
1107        else {
1108                audioInfoFrame.ChannelCount = BAVC_HDMI_AudioInfoFrame_ChannelCount_e2Channels;
1109        }
1110        audioInfoFrame.SpeakerAllocation = BHDM_ChannelAllocation_eStereo;
1111        audioInfoFrame.DownMixInhibit = 0;  /* default */
1112        audioInfoFrame.LevelShift = 0;  /* default */
1113        rc = BHDM_SetAudioInfoFramePacket(h_hdmi->hHDMI, &audioInfoFrame);
1114        if ( rc )
1115        {
1116                BDBG_WRN(("BHDM_SetAudioInfoFramePacket failed %d", rc));
1117        }
1118        h_hdmi->hdmiSettings.eAudioSamplingRate = BAVC_AudioSamplingRate_e48k;
1119        h_hdmi->audioInfo.eAudioSamplingRate = BAVC_AudioSamplingRate_e48k;
1120        h_hdmi->hdmiSettings.eAudioBits = BAVC_AudioBits_e24;
1121        rc = BHDM_EnableDisplay(h_hdmi->hHDMI, &h_hdmi->hdmiSettings);
1122
1123        rc =  bsettop_hdmi_restart_hdcp(h_hdmi);
1124        if (rc != BERR_SUCCESS)
1125        {
1126                BDBG_ERR(("%s:%d bsettop_hdmi_restart_hdcp failed %d",__FUNCTION__,__LINE__,rc));
1127        }
1128
1129        if (h_hdmi->hdcpStarted && h_hdmi->checkHDCP && h_hdmi->hdcp_authentication_cb) {
1130                /* tell the application to disable video/audio/CC on HDMI port */
1131                h_hdmi->hdcp_authentication_cb(false);
1132        }
1133
1134        h_hdmi->lastState = bsettop_hdmi_get_state(h_hdmi, true);   
1135#endif
1136        return rc;
1137
1138}
1139
1140/**
1141Summary:
1142Handle hdmi events
1143 **/
1144
1145static void bsettop_handle_hdmi_event(bsettop_hdmi_t h_hdmi)
1146{
1147#if HAS_HDMI
1148        BVDC_Display_DvoSettings dvoSettings;
1149        BERR_Code rc;
1150        BFMT_VideoFmt eFmt;
1151        BAVC_MatrixCoefficients hdmiOutputCoef;
1152        bdisplay_t                      display;
1153
1154        display = h_hdmi->display;
1155
1156        h_hdmi->newState = bsettop_hdmi_get_state(h_hdmi,true);
1157
1158        BDBG_WRN(("%s:%d newState = %d, lastState = %d", __FUNCTION__,__LINE__,h_hdmi->newState,h_hdmi->lastState));
1159
1160        if (h_hdmi->newState == h_hdmi->lastState)
1161        {
1162                BDBG_WRN(("%s:%d newState = %d == lastState = %d", __FUNCTION__,__LINE__,h_hdmi->newState,h_hdmi->lastState));
1163                return;
1164        }
1165
1166        b_lock_vdc();
1167        /* Check transitions */
1168        if ( h_hdmi->lastState == HdmiOutputState_eConnected )
1169        {
1170                BDBG_WRN(("%s:%d Pervious state HdmiOutputState_eConnected", __FUNCTION__,__LINE__));
1171                /* Connected -> disconnected or Connected -> powered down.  Disable output and fire callback */
1172                BHDM_DisableDisplay(h_hdmi->hHDMI);
1173
1174#ifdef HDCPLIB
1175                if (h_hdmi->hdcpStarted)
1176                {
1177                        BHDCPlib_DisableAuthentication(h_hdmi->hHDCPlib);
1178                        h_hdmi->hdcpStarted = false;
1179                }
1180#endif /* HDCPLIB */
1181                BVDC_Display_GetVideoFormat(display->disp[eBDISPLAY_HDMI].hDisplay, &eFmt );
1182                if (BHDM_EDID_GetSupportedColorimetry(h_hdmi->hHDMI, 
1183                                        BHDM_OutputFormat_eHDMIMode,
1184                                        display->hdmiFmt,&(hdmiOutputCoef)) == BERR_SUCCESS)
1185                {
1186                        BDBG_WRN(("%s:%d", __FUNCTION__,__LINE__));
1187                        hdmiOutputCoef = BAVC_MatrixCoefficients_eUnknown;
1188
1189                        BVDC_Display_SetHdmiConfiguration(display->disp[eBDISPLAY_HDMI].hDisplay, BVDC_Hdmi_0,hdmiOutputCoef);
1190                        dvoSettings.stSpreadSpectrum.bEnable = false;
1191                        BVDC_Display_GetDvoConfiguration(display->disp[eBDISPLAY_HDMI].hDisplay, &dvoSettings);
1192                        rc = BVDC_Display_SetDvoConfiguration(display->disp[eBDISPLAY_HDMI].hDisplay, &dvoSettings);
1193                        //BHDM_DisableDisplay(h_hdmi->hHDMI);
1194                        rc = BVDC_ApplyChanges(display->hVdc);
1195                        if (rc != BERR_SUCCESS)
1196                        {
1197                                BDBG_WRN(("%s:%d BVDC_ApplyChanges failed %d", __FUNCTION__,__LINE__,rc));
1198                        }
1199                }
1200
1201#if BHDM_CEC_SUPPORT
1202                h_hdmi->cecStatus.physicalAddress[0] = 0xFF;
1203                h_hdmi->cecStatus.physicalAddress[1] = 0xFF;
1204                h_hdmi->cecStatus.logicalAddress = BHDM_CONFIG_CEC_UNINITIALIZED_LOGICAL_ADDR;
1205                HdmiOutput_GetCecSettings(h_hdmi, &g_cecSettings);
1206                g_cecSettings.enabled = false;
1207                rc = HdmiOutput_SetCecSettings(h_hdmi, &g_cecSettings);
1208                /* clear any pending event */
1209                BKNI_ResetEvent(h_hdmi->cecEvent);
1210#endif
1211        }
1212        if ( h_hdmi->newState == HdmiOutputState_eConnected )
1213        {
1214                unsigned i=0;
1215
1216                /* Disconnected -> Connected or Powered down -> connected.  Read EDID */
1217                BDBG_WRN(("%s:%d", __FUNCTION__,__LINE__));
1218                do
1219                {
1220                        rc = BHDM_EDID_Initialize(h_hdmi->hHDMI);
1221                } while ( rc != BERR_SUCCESS && rc != BHDM_NO_RX_DEVICE && i++ < h_hdmi->maxEdidRetries );
1222
1223                if ( rc == BHDM_NO_RX_DEVICE )
1224                {
1225                        /* Device was disconnected during retries.  Abort */
1226                        h_hdmi->lastState = HdmiOutputState_eDisconnected;
1227                        b_unlock_vdc();
1228                        return;
1229                }
1230                else if ( i >= h_hdmi->maxEdidRetries )
1231                {
1232                        BDBG_ERR(("Unable to read EDID after %d attempts", i));
1233                        /* TODO: Bail out here or continue? -- currently continuing. */
1234                }
1235#if 1
1236                bsettop_hdmi_set_display_format(h_hdmi);
1237                bsettop_hdmi_vdc_connect(h_hdmi);       
1238#else
1239                BHDM_OutputFormat   eOutputFormat = BHDM_OutputFormat_eHDMIMode;
1240                BHDM_OutputPort     eOutputPort = BHDM_OutputPort_eHDMI;
1241                static BHDM_EDID_RxVendorSpecificDB RxVSDB;
1242                bool bHdmiDevice;
1243
1244                rc = BHDM_EDID_IsRxDeviceHdmi(h_hdmi->hHDMI, &RxVSDB, &bHdmiDevice);
1245                if (BERR_SUCCESS != rc) {
1246                        BDBG_ERR(("%s BHDM_EDID_IsRxDeviceHdmi failed %x",__func__,rc));
1247                }
1248                else {
1249                        /* should not support it */
1250                        if (!bHdmiDevice) {
1251                                eOutputFormat = BHDM_OutputFormat_eDVIMode;
1252                                eOutputPort = BHDM_OutputPort_eDVI;
1253                        }
1254                }
1255
1256                BVDC_Display_GetVideoFormat(display->disp[eBDISPLAY_HDMI].hDisplay, &eFmt );
1257                if (BHDM_EDID_GetSupportedColorimetry(h_hdmi->hHDMI, 
1258                                        eOutputFormat,
1259                                        display->hdmiFmt,&(hdmiOutputCoef)) == BERR_SUCCESS)
1260                {
1261
1262                        BDBG_WRN(("%s:%d", __FUNCTION__,__LINE__));
1263                        BVDC_Display_SetHdmiConfiguration(display->disp[eBDISPLAY_HDMI].hDisplay, 
1264                                        BVDC_Hdmi_0,hdmiOutputCoef);
1265#if 0
1266                        rc = BHDM_EDID_GetSupportedColorimetry(h_hdmi->hHDMI,
1267                                        BHDM_OutputFormat_eHDMIMode,
1268                                        display->hdmiFmt,&(h_hdmi->hdmiMatrixCoef));
1269                        if (rc != BERR_SUCCESS)
1270                        {
1271                                BDBG_WRN(("%s:%d BHDM_EDID_GetSupportedColorimetry failed %d", __FUNCTION__,__LINE__,rc));
1272                        }
1273                        BVDC_Display_GetHdmiConfiguration(display->disp[eBDISPLAY_HDMI].hDisplay, BVDC_Hdmi_0, &(h_hdmi->hdmiMatrixCoef));
1274#endif
1275                        rc = BVDC_ApplyChanges(display->hVdc);
1276                        if (rc != BERR_SUCCESS)
1277                        {
1278                                BDBG_WRN(("%s:%d BVDC_ApplyChanges failed %d", __FUNCTION__,__LINE__,rc));
1279                        }
1280                }
1281
1282                BHDM_GetHdmiSettings(h_hdmi->hHDMI, &(h_hdmi->hdmiSettings));
1283                h_hdmi->hdmiSettings.eInputVideoFmt = eFmt;
1284                h_hdmi->hdmiSettings.eOutputPort = eOutputPort;
1285                h_hdmi->hdmiSettings.eColorimetry = h_hdmi->hdmiMatrixCoef;
1286                h_hdmi->hdmiSettings.eOutputFormat = eOutputFormat;
1287                h_hdmi->hdmiSettings.eAspectRatio = bsettop_hdmi_check_aspect_ratio(h_hdmi);
1288                rc = BHDM_EnableDisplay(h_hdmi->hHDMI,&(h_hdmi->hdmiSettings));
1289                if (rc != BERR_SUCCESS)
1290                {
1291                        BDBG_WRN(("%s:%d BHDM_EnableDisplay failed %d", __FUNCTION__,__LINE__,rc));
1292                }
1293
1294#endif
1295#if BHDM_CEC_SUPPORT
1296                /* clear any pending event */
1297                BKNI_ResetEvent(h_hdmi->cecEvent);
1298
1299                HdmiOutput_GetCecSettings(h_hdmi, &g_cecSettings);
1300                g_cecSettings.enabled = true;
1301                rc = HdmiOutput_SetCecSettings(h_hdmi, &g_cecSettings);
1302                if ( rc )
1303                        BDBG_ERR(("Unable to enable CEC core"));
1304                else
1305                {
1306                        BDBG_WRN(("CEC enabled!"));
1307                }
1308                //HdmiOutput_P_CecCallback(h_hdmi);
1309#endif
1310#if 0
1311                rc = bsettop_hdmi_restart_hdcp(h_hdmi);
1312                if ( rc )
1313                {
1314                        BDBG_ERR(("Unable to restart HDCP"));
1315                }
1316                else
1317                {
1318                        BDBG_WRN(("HDCP restarted"));
1319                }
1320#endif
1321        }
1322        else if ( h_hdmi->newState == HdmiOutputState_ePoweredDown )
1323        {
1324                /* Disconnected -> powered down - treat as no event */
1325                BDBG_WRN(("Receiver powered down, no hotplug event."));
1326        }
1327
1328        b_unlock_vdc();
1329        h_hdmi->lastState = h_hdmi->newState;           
1330#endif
1331}
1332
1333
1334/**
1335Summary:
1336check hdcp state
1337 **/
1338#ifdef HDCPLIB
1339
1340static void bsettop_hdcp_cb(bsettop_hdmi_t h_hdmi)
1341{
1342        BHDCPlib_Status hdcpStatus;
1343        BERR_Code errCode;
1344
1345        BDBG_MSG(("HDCP State Machine Timer"));
1346
1347        errCode = BHDCPlib_ProcessAuthentication(h_hdmi->hHDCPlib, &hdcpStatus);
1348
1349        if ( errCode )
1350        {
1351                /* All failures will eventually wind up here */
1352                errCode = BERR_TRACE(errCode);
1353                BDBG_ERR(("HDCP error occurred, aborting authentication"));
1354                bsettop_update_hdcp_state(h_hdmi);
1355                bsettop_hdmi_restart_hdcp(h_hdmi);
1356                return;
1357        }
1358
1359        bsettop_update_hdcp_state(h_hdmi);
1360
1361        if ( hdcpStatus.msRecommendedWaitTime > 0 )
1362        {
1363                BDBG_MSG(("Continue check HDCP state - %d\n",hdcpStatus.msRecommendedWaitTime));
1364        }
1365        else
1366        {
1367                BDBG_WRN(("HDCP state machine will stop now.\n"));
1368                h_hdmi->checkHDCP = false;
1369        }
1370}
1371#else /* HDCPLIB */
1372
1373static void bsettop_hdcp_cb(bsettop_hdmi_t h_hdmi)
1374{
1375}
1376#endif /* HDCPLIB */
1377
1378/**
1379Summary:
1380hdmi task
1381 **/
1382
1383void bsettop_hdmi_task(void *data)
1384{
1385        bsettop_hdmi_t h_hdmi = (bsettop_hdmi_t)data;
1386
1387        h_hdmi->lastState = HdmiOutputState_eMax;
1388
1389        while (!h_hdmi->done)
1390        {
1391                if (BKNI_WaitForEvent(h_hdmi->hdmEvent, 5) == BERR_SUCCESS)
1392                {
1393                        bsettop_handle_hdmi_event(h_hdmi);     
1394                }
1395
1396#if BHDM_CEC_SUPPORT
1397                if (BKNI_WaitForEvent(h_hdmi->cecEvent, 5) == BERR_SUCCESS)
1398                {
1399                        bsettop_handle_cec_event(h_hdmi);       
1400                }
1401#endif
1402#ifdef HDCPLIB
1403                if (BKNI_WaitForEvent(h_hdmi->hHDCPRiEvent, 5) == BERR_SUCCESS)
1404                {
1405                        BHDCPlib_Event event = {BHDM_EventHDCPRiValue};
1406
1407                        BHDCPlib_ProcessEvent(h_hdmi->hHDCPlib, &event);
1408
1409                        bsettop_update_hdcp_state(h_hdmi);
1410                }
1411
1412                if (BKNI_WaitForEvent(h_hdmi->hHDCPRjEvent, 5) == BERR_SUCCESS)
1413                {
1414                        BHDCPlib_Event event = {BHDM_EventHDCPPjValue};
1415
1416                        BHDCPlib_ProcessEvent(h_hdmi->hHDCPlib, &event);
1417
1418                        bsettop_update_hdcp_state(h_hdmi);
1419                }
1420
1421                if (h_hdmi->checkHDCP)
1422                {
1423                        bsettop_hdcp_cb(h_hdmi);
1424                }
1425#endif /* HDCPLIB */
1426        }
1427}
1428
1429/**
1430Summary:
1431Display rate changed callback.
1432 **/
1433
1434void  bsettop_display_rate_change_cb(bdisplay_t display,        /* display contect handle */
1435                void *data_ptr,          /* rate_change_data* */
1436                void *cbData                     /* BAVC_VdcDisplay_Info* */
1437                )
1438{
1439        bsettop_hdmi_t h_hdmi = (bsettop_hdmi_t)data_ptr;
1440        BAVC_VdcDisplay_Info *pDisplayInfo = (BAVC_VdcDisplay_Info*)cbData;
1441        BDBG_ASSERT(display);
1442
1443        if (pDisplayInfo)
1444        {
1445                BDBG_WRN(("%s: refreshrate=%d, clkrate=%d.\n", __func__, pDisplayInfo->ulVertRefreshRate, pDisplayInfo->ulPixelClkRate));
1446                BHDM_AudioVideoRateChangeCB_isr(h_hdmi->hHDMI,BHDM_Callback_Type_eVideoChange,pDisplayInfo);
1447
1448        }
1449        else
1450        {
1451                BHDM_SetAvMute(h_hdmi->hHDMI, true);
1452                BHDM_DisableDisplay(h_hdmi->hHDMI);
1453                bos_sleep(100);
1454                bsettop_hdmi_vdc_connect(h_hdmi);       
1455                BHDM_SetAvMute(h_hdmi->hHDMI, false);
1456        }
1457}
1458
1459static BAVC_AudioSamplingRate bsettop_audio_get_sr(unsigned sampleRate)
1460{
1461        switch (sampleRate)
1462        {
1463                case 32000: return BAVC_AudioSamplingRate_e32k;    /* 32K Sample rate */
1464                case 44100: return BAVC_AudioSamplingRate_e44_1k;    /* 44.1K Sample rate */
1465                case 48000: return BAVC_AudioSamplingRate_e48k;      /* 48K Sample rate */
1466                case 96000: return BAVC_AudioSamplingRate_e96k;      /* 96K Sample rate */
1467                case 16000: return BAVC_AudioSamplingRate_e16k;      /* 16K Sample rate */
1468                case 22050: return BAVC_AudioSamplingRate_e22_05k;   /* 22.05K Sample rate */
1469                case 24000: return BAVC_AudioSamplingRate_e24k;      /* 24K Sample rate */
1470                case 64000: return BAVC_AudioSamplingRate_e64k;      /* 64K Sample rate */
1471                case 88200: return BAVC_AudioSamplingRate_e88_2k;    /* 88.2K Sample rate */
1472                case 128000: return BAVC_AudioSamplingRate_e128k;     /* 128K Sample rate */
1473                case 176400: return BAVC_AudioSamplingRate_e176_4k;   /* 176.4K Sample rate */
1474                case 192000: return BAVC_AudioSamplingRate_e192k;     /* 192K Sample rate */
1475                case 8000: return BAVC_AudioSamplingRate_e8k;       /* 8K Sample rate */
1476                case 12000: return BAVC_AudioSamplingRate_e12k;      /* 12K Sample rate */
1477                case 11025: return BAVC_AudioSamplingRate_e11_025k;  /* 11.025K Sample rate */
1478                default: return BAVC_AudioSamplingRate_e48k;
1479        }
1480}
1481/**
1482Summary:
1483Audio rate changed callback.
1484 **/
1485
1486
1487void bsettop_audio_rate_change_cb (baudio_decode_t audio,       /* audio decode contect handle */
1488                void *data_ptr,            /* rate_change_data */
1489                void *cbData                       /* BRAP_DSPCHN_SampleRateChangeInfo* */
1490                )
1491{
1492        bsettop_hdmi_t h_hdmi = (bsettop_hdmi_t)data_ptr;
1493        BSTD_UNUSED(h_hdmi);
1494
1495        BAVC_AudioSamplingRate sr = bsettop_audio_get_sr((unsigned)cbData);     
1496        BDBG_WRN(("%s, new rate=%d, old rate=%d",__func__, sr, h_hdmi->audioInfo.eAudioSamplingRate));
1497        if (h_hdmi->audioInfo.eAudioSamplingRate != sr)
1498        {
1499                h_hdmi->audioInfo.eAudioSamplingRate = sr;
1500                BHDM_AudioVideoRateChangeCB_isr(h_hdmi->hHDMI,BHDM_Callback_Type_eAudioChange,&(h_hdmi->audioInfo));
1501        }
1502        BDBG_ERR(("%s",__func__));
1503}
1504
1505/**
1506Summary:
1507Allocate and initialize hdmi resources.
1508 **/
1509
1510bresult bsettop_hdmi_open(bsettop_hdmi_t *h_hdmi,
1511                bdisplay_t display, /* display on which the graphics are displayed */
1512                baudio_decode_t audio_decode,
1513                bsettop_hdcp_authentication_cb_t hdcp_authentication_cb         /* pointer to a callback function to let hdcp ahthentication to call the app */
1514                )
1515{
1516        BERR_Code rc = 0;
1517#if HAS_HDMI
1518        b_task_params task_params;
1519        BI2C_ChannelSettings defChnSettings;
1520        //BHDM_ColorDepth_Settings colorDepthSettings;
1521        bdisplay_settings display_settings;
1522        baudio_decode_config audio_config;
1523#ifdef HDCPLIB
1524        BHDCPlib_Dependencies *pDefaultDependencies;
1525        BHDCPlib_Configuration *pHdcpConfiguration;
1526#if (CONFIG_ENABLE_SCM != 1)
1527        BHSM_Settings hsmSettings;
1528#endif
1529#endif
1530        BAVC_VdcDisplay_Info DisplayInfo;
1531    unsigned int flags;
1532
1533        BDBG_ASSERT(display);
1534        BDBG_ASSERT(audio_decode);
1535
1536        *h_hdmi = (bsettop_hdmi_t)BKNI_Malloc(sizeof(struct bsettop_hdmi));
1537
1538        if (!(*h_hdmi))
1539                return berr_out_of_memory;
1540
1541#if 0
1542        BDBG_SetModuleLevel("BHDM_CEC", BDBG_eMsg);
1543        BDBG_SetModuleLevel("BHDM_CEC_PRIV", BDBG_eMsg);
1544        BDBG_SetModuleLevel("BHDM_EDID", BDBG_eMsg);
1545        BDBG_SetModuleLevel("BHSM",BDBG_eTrace);
1546        BDBG_SetModuleLevel("BHDM",BDBG_eTrace);
1547        BDBG_SetModuleLevel("BHDM_HDCP",BDBG_eTrace);
1548        BDBG_SetModuleLevel("BHDM_EDID",BDBG_eMsg);
1549#endif
1550
1551        BKNI_Memset(*h_hdmi,0,sizeof(struct bsettop_hdmi));
1552#if BHDM_CEC_SUPPORT
1553        BKNI_Memset(&g_cecSettings,0,sizeof(g_cecSettings));
1554        BKNI_Memset(&g_cecStatus,0,sizeof(g_cecStatus));
1555#endif
1556        (*h_hdmi)->audio_decode = audio_decode;
1557        (*h_hdmi)->display = display;
1558        (*h_hdmi)->maxEdidRetries = 3;
1559        BI2C_GetChannelDefaultSettings( GetI2C(), 0, &defChnSettings );
1560        defChnSettings.clkRate = BI2C_Clk_eClk100Khz;
1561        BI2C_OpenChannel( GetI2C(), &((*h_hdmi)->i2cChannelHandle), 0, &defChnSettings );
1562        BDBG_ASSERT((*h_hdmi)->i2cChannelHandle);
1563        BI2C_CreateI2cRegHandle ((*h_hdmi)->i2cChannelHandle, &((*h_hdmi)->i2cRegHandle));
1564        BDBG_ASSERT((*h_hdmi)->i2cRegHandle);
1565
1566        BHDM_GetDefaultSettings(&((*h_hdmi)->hdmiSettings));
1567        (*h_hdmi)->hdmiSettings.eOutputFormat = BHDM_OutputFormat_eHDMIMode;
1568        (*h_hdmi)->hdmiSettings.eAudioBits = BAVC_AudioBits_e24;
1569        (*h_hdmi)->hdmiSettings.eTimebase = BAVC_Timebase_e0;
1570        (*h_hdmi)->hdmiSettings.stColorDepth.eBitsPerPixel = BAVC_HDMI_BitsPerPixel_e24bit;
1571        (*h_hdmi)->hdmiSettings.eAudioFormat = BAVC_AudioFormat_ePCM;;
1572
1573        /*RLQ, new HDMI code requires the timer handler */
1574        //(*h_hdmi)->hdmiSettings.hTMR = GetTMR();
1575       
1576        rc = BHDM_Open(&((*h_hdmi)->hHDMI), GetCHP(), GetREG(), GetINT(), (*h_hdmi)->i2cRegHandle, &((*h_hdmi)->hdmiSettings));
1577        BDBG_ASSERT(rc == BERR_SUCCESS);
1578
1579        /* get Hot Plug Event Handle */
1580        rc = BHDM_GetEventHandle((*h_hdmi)->hHDMI, BHDM_EventHotPlug, &((*h_hdmi)->hdmEvent));
1581        BDBG_ASSERT(rc == BERR_SUCCESS);
1582#if BHDM_CEC_SUPPORT
1583
1584        /* get cec event handle */
1585        rc = BHDM_GetEventHandle((*h_hdmi)->hHDMI, BHDM_EventCEC, &((*h_hdmi)->cecEvent));
1586        BDBG_ASSERT(rc == BERR_SUCCESS);
1587
1588        (*h_hdmi)->cecStatus.physicalAddress[0] = 0xFF;
1589        (*h_hdmi)->cecStatus.physicalAddress[1] = 0xFF;
1590        (*h_hdmi)->cecStatus.logicalAddress = BHDM_CONFIG_CEC_UNINITIALIZED_LOGICAL_ADDR;
1591#endif
1592
1593        /* set initial fresh rate and pixel clock in case on a turn on channel is audio only channel and no default info from EDID */
1594        DisplayInfo.ulVertRefreshRate = 5994;
1595        DisplayInfo.ulPixelClkRate = 16;
1596    flags = bos_enter_critical();
1597        BHDM_AudioVideoRateChangeCB_isr((*h_hdmi)->hHDMI,BHDM_Callback_Type_eVideoChange,&DisplayInfo);
1598    bos_exit_critical(flags);
1599
1600        task_params.name="HDMI";
1601        task_params.priority = HDMI_PRIORITY;
1602        task_params.stack_size = HDMI_STK_SIZE;
1603        task_params.stack = (*h_hdmi)->hdmi_stack;
1604
1605        bos_start_task(&((*h_hdmi)->h_hdmi_task), &task_params, bsettop_hdmi_task,(*h_hdmi));
1606
1607        BVDC_Display_SetHdmiConfiguration( display->disp[eBDISPLAY_HDMI].hDisplay, BVDC_Hdmi_0, BAVC_MatrixCoefficients_eItu_R_BT_709);
1608
1609        /* the changes in BDM module fixed BHDM_SetAvMute */
1610        //colorDepthSettings.eBitsPerPixel = BAVC_HDMI_BitsPerPixel_e24bit;
1611        //rc = BHDM_SetColorDepth((*h_hdmi)->hHDMI, &colorDepthSettings);
1612        //BDBG_ASSERT(rc == BERR_SUCCESS);
1613
1614        rc = BVDC_ApplyChanges(display->hVdc);
1615        BDBG_ASSERT(rc == BERR_SUCCESS);
1616
1617#ifdef HDCPLIB
1618#if (CONFIG_ENABLE_SCM != 1)
1619        BHSM_GetDefaultSettings(&hsmSettings, GetCHP());
1620        hsmSettings.eCustMode = BHSM_CustMode_eGeneric;
1621
1622        rc = BHSM_Open(&((*h_hdmi)->hHsm), GetREG(), GetCHP() , &hsmSettings);
1623        BDBG_ASSERT(rc == BERR_SUCCESS);
1624#endif
1625        pHdcpConfiguration = &((*h_hdmi)->hdcpConfig);
1626        pDefaultDependencies = &((*h_hdmi)->hdcpDependencies);
1627
1628        BHDCPlib_GetDefaultConfiguration(pHdcpConfiguration);
1629        BHDCPlib_GetDefaultDependencies(pDefaultDependencies);
1630
1631        pDefaultDependencies->hHdm = (*h_hdmi)->hHDMI;
1632#if (CONFIG_ENABLE_SCM != 1)
1633        pDefaultDependencies->hHsm = (*h_hdmi)->hHsm;
1634#endif
1635        pDefaultDependencies->hTmr = GetTMR();
1636
1637#ifdef BHDM_HAS_SECURITY
1638        (*h_hdmi)->transmitEncrypted = true;
1639#endif
1640
1641        rc = BHDCPlib_Open(&((*h_hdmi)->hHDCPlib), pDefaultDependencies);
1642        BDBG_ASSERT(rc == BERR_SUCCESS);
1643
1644        rc = BHDCPlib_GetKeySet(pHdcpConfiguration->TxKeySet.TxAksv, pHdcpConfiguration->TxKeySet.TxKeyStructure);
1645        BDBG_ASSERT(rc == BERR_SUCCESS);
1646
1647        rc = BHDCPlib_SetConfiguration((*h_hdmi)->hHDCPlib, pHdcpConfiguration);
1648        BDBG_ASSERT(rc == BERR_SUCCESS);
1649
1650        /* get HDCP Ri Event Handle */
1651        rc = BHDM_GetEventHandle((*h_hdmi)->hHDMI, BHDM_EventHDCPRiValue,&((*h_hdmi)->hHDCPRiEvent));
1652        BDBG_ASSERT(rc == BERR_SUCCESS);
1653
1654        /* get HDCP Pj Event Handle */
1655        rc = BHDM_GetEventHandle((*h_hdmi)->hHDMI, BHDM_EventHDCPPjValue, &((*h_hdmi)->hHDCPRjEvent));
1656        BDBG_ASSERT(rc == BERR_SUCCESS);
1657#endif /* HDCPLIB */
1658
1659
1660        /* initialize here first so that we can get EDID information */
1661        BHDM_EDID_Initialize((*h_hdmi)->hHDMI);
1662        s_bsettop_hdmi = *h_hdmi;
1663        bsettop_hdmi_vdc_connect(*h_hdmi);
1664
1665        bdisplay_get(display,&display_settings);
1666
1667        display_settings.rate_change_cb = bsettop_display_rate_change_cb;
1668        display_settings.rate_change_data = (void*)(*h_hdmi);
1669        rc = bdisplay_set(display,&display_settings);
1670        if (rc != BERR_SUCCESS)
1671        {
1672                BDBG_ERR(("bdisplay_set failed %d.",rc));
1673        }
1674
1675        baudio_decode_get_config(audio_decode,&audio_config);
1676
1677        audio_config.rate_change_cb = bsettop_audio_rate_change_cb;
1678        audio_config.rate_change_data = (void*)(*h_hdmi);
1679        rc = baudio_decode_set_config(audio_decode,&audio_config);
1680        if (rc != BERR_SUCCESS)
1681        {
1682                BDBG_ERR(("baudio_decode_set_config failed %d.",rc));
1683        }
1684        s_bsettop_hdmi->hdcp_authentication_cb = hdcp_authentication_cb;
1685        (*h_hdmi)->lastState = HdmiOutputState_eDisconnected;
1686        bsettop_handle_hdmi_event((*h_hdmi));
1687
1688#if BHDM_CEC_SUPPORT
1689        HdmiOutput_GetCecSettings(*h_hdmi, &g_cecSettings);
1690        g_cecSettings.enabled = true;
1691        rc = HdmiOutput_SetCecSettings(*h_hdmi, &g_cecSettings);
1692        HdmiOutput_P_CecCallback(*h_hdmi);
1693#endif
1694#endif
1695        return b_ok;
1696}
1697
1698
1699/**
1700Summary:
1701Release hdmi resources.
1702 **/
1703
1704void bsettop_hdmi_close(bsettop_hdmi_t h_hdmi)
1705{
1706        BDBG_ASSERT(h_hdmi);
1707        BDBG_ASSERT(h_hdmi->hHDMI);
1708#ifdef HDCPLIB
1709        BDBG_ASSERT(h_hdmi->hHDCPlib);
1710#if (CONFIG_ENABLE_SCM!=1)
1711        BDBG_ASSERT(h_hdmi->hHsm);
1712#endif
1713        BHDCPlib_Close(h_hdmi->hHDCPlib);
1714#if (CONFIG_ENABLE_SCM!=1)
1715        BHSM_Close(h_hdmi->hHsm);
1716#endif
1717#endif /* HDCPLIB */
1718        BHDM_Close(h_hdmi->hHDMI);
1719        BKNI_Free(h_hdmi);
1720}
1721
1722bresult boutput_hdmi_get_status(bsettop_hdmi_t h_hdmi,
1723                boutput_hdmi_status *status /* [out] */
1724                )
1725{
1726        HdmiOutputState hdmi_state;
1727        BERR_Code rc;
1728        BHDM_EDID_RxVendorSpecificDB RxVSDB;
1729        BFMT_VideoFmt magnumFormat;
1730        BHDM_EDID_DetailTiming detailedTiming;
1731        unsigned int detailTimingNum = 1;
1732        bool bHdmiDevice = false;
1733
1734        BDBG_ASSERT(h_hdmi);
1735        BDBG_ASSERT(status);
1736
1737        BKNI_Memset(status, 0, sizeof(boutput_hdmi_status));
1738
1739        hdmi_state = bsettop_hdmi_get_state(h_hdmi,false);
1740        if (hdmi_state == HdmiOutputState_eConnected)
1741        {
1742                status->connected = true;
1743
1744                rc = BHDM_EDID_IsRxDeviceHdmi(h_hdmi->hHDMI, &RxVSDB, &bHdmiDevice);
1745                if ((rc == BERR_SUCCESS) && bHdmiDevice) {
1746                        status->is_hdmi = true;
1747                }       
1748                /* retrieve the preferred */
1749                status->preferred = bvideo_format_count;
1750                magnumFormat = BFMT_VideoFmt_eDVI_640x480p; /* default to safe mode */
1751                while (1)
1752                {
1753                        rc = BHDM_EDID_GetDetailTiming(h_hdmi->hHDMI, detailTimingNum, &detailedTiming, &magnumFormat);
1754                        if (rc == BERR_SUCCESS)
1755                        {
1756                                detailTimingNum++;
1757                                if (!BFMT_SUPPORT_HDMI(magnumFormat)) {
1758                                        continue;
1759                                }
1760                                if (magnumFormat == BFMT_VideoFmt_e720p) { status->preferred = bvideo_format_720p; break; }
1761                                else if (magnumFormat == BFMT_VideoFmt_e1080i) { status->preferred = bvideo_format_1080i; break; }
1762                                else if (magnumFormat == BFMT_VideoFmt_eNTSC) { status->preferred = bvideo_format_ntsc; break; }
1763                                else if (magnumFormat == BFMT_VideoFmt_e480p) { status->preferred = bvideo_format_480p; break; }
1764                                else { continue; }
1765                        }
1766                        else { break; }
1767                }
1768                /* HDCP status */
1769#ifdef HDCPLIB
1770                if (h_hdmi->hdcpState == BHDCPlib_State_eEncryptionEnabled) 
1771                        status->hdcp_state = boutput_hdmi_hdcp_state_enabled;
1772                else 
1773#endif
1774                        status->hdcp_state = boutput_hdmi_hdcp_state_internal_err;
1775        }
1776        else
1777        { 
1778                status->connected = false;
1779        }
1780        return b_ok;
1781}
1782
1783/**
1784Summary:
1785check if HDCP authentication is successful or not
1786 **/
1787bool bsettop_hdmi_check_hdcp_authentication_status(bsettop_hdmi_t h_hdmi)
1788{
1789#ifdef HDCPLIB
1790        BDBG_ASSERT(h_hdmi);
1791        return (BHDCPlib_State_eEncryptionEnabled == h_hdmi->hdcpState);
1792#else
1793        return true;
1794#endif
1795}
1796
1797/*
1798 * Summary:
1799 * power management for HDM block
1800 */
1801void bsettop_hdmi_standby(bsettop_hdmi_t h_hdmi, bool standby)
1802{
1803        if (standby) {
1804                BHDM_Standby(h_hdmi->hHDMI, NULL);     
1805        }
1806        else {
1807                BHDM_Resume(h_hdmi->hHDMI);
1808        }
1809}
Note: See TracBrowser for help on using the repository browser.