source: svn/trunk/newcon3bcm2_21bu/nexus/modules/cec/7552/src/nexus_cec.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: 14.3 KB
Line 
1/***************************************************************************
2*          (c)2007-2011 Broadcom Corporation
3*
4* This program is the proprietary software of Broadcom Corporation and/or its licensors,
5* and may only be used, duplicated, modified or distributed pursuant to the terms and
6* conditions of a separate, written license agreement executed between you and Broadcom
7* (an "Authorized License").    Except as set forth in an Authorized License, Broadcom grants
8* no license (express or implied), right to use, or waiver of any kind with respect to the
9* Software, and Broadcom expressly reserves all rights in and to the Software and all
10* intellectual property rights therein.  IF YOU HAVE NO AUTHORIZED LICENSE, THEN YOU
11* HAVE NO RIGHT TO USE THIS SOFTWARE IN ANY WAY, AND SHOULD IMMEDIATELY
12* NOTIFY BROADCOM AND DISCONTINUE ALL USE OF THE SOFTWARE.
13*
14* Except as expressly set forth in the Authorized License,
15*
16* 1.       This program, including its structure, sequence and organization, constitutes the valuable trade
17* secrets of Broadcom, and you shall use all reasonable efforts to protect the confidentiality thereof,
18* and to use this information only in connection with your use of Broadcom integrated circuit products.
19*
20*       2.         TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS"
21* AND WITH ALL FAULTS AND BROADCOM MAKES NO PROMISES, REPRESENTATIONS OR
22* WARRANTIES, EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO
23* THE SOFTWARE.  BROADCOM SPECIFICALLY DISCLAIMS ANY AND ALL IMPLIED WARRANTIES
24* OF TITLE, MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE,
25* LACK OF VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION
26* OR CORRESPONDENCE TO DESCRIPTION. YOU ASSUME THE ENTIRE RISK ARISING OUT OF
27* USE OR PERFORMANCE OF THE SOFTWARE.
28*
29* 3.       TO THE MAXIMUM EXTENT PERMITTED BY LAW, IN NO EVENT SHALL BROADCOM OR ITS
30* LICENSORS BE LIABLE FOR (i) CONSEQUENTIAL, INCIDENTAL, SPECIAL, INDIRECT, OR
31* EXEMPLARY DAMAGES WHATSOEVER ARISING OUT OF OR IN ANY WAY RELATING TO YOUR
32* USE OF OR INABILITY TO USE THE SOFTWARE EVEN IF BROADCOM HAS BEEN ADVISED OF
33* THE POSSIBILITY OF SUCH DAMAGES; OR (ii) ANY AMOUNT IN EXCESS OF THE AMOUNT
34* ACTUALLY PAID FOR THE SOFTWARE ITSELF OR U.S. $1, WHICHEVER IS GREATER. THESE
35* LIMITATIONS SHALL APPLY NOTWITHSTANDING ANY FAILURE OF ESSENTIAL PURPOSE OF
36* ANY LIMITED REMEDY.
37*
38* $brcm_Workfile: nexus_cec.c $
39* $brcm_Revision: 2 $
40* $brcm_Date: 12/21/11 2:52p $
41*
42* Module Description:
43*
44* Revision History:
45*
46* $brcm_Log: /nexus/modules/cec/7425/src/nexus_cec.c $
47*
48* 2   12/21/11 2:52p vle
49* SW7405-4781: Merge to mainline
50*
51* SW7405-4781/1   12/21/11 12:12p vle
52* SW7405-4781: allow CEC device type to be configurable
53*
54* 1   12/15/11 4:27p vsilyaev
55* SW7425-1140: Merge NEXUS_Cec module support into main-line
56*
57* SW7425-1140/1   12/9/11 4:41p vle
58* SW7425-1140: Add NEXUS_Cec module support
59*
60***************************************************************************/
61
62#include "nexus_cec_module.h"
63#include "nexus_cec.h"
64#include "priv/nexus_core.h"
65
66
67BDBG_MODULE(nexus_cec);
68BDBG_OBJECT_ID(NEXUS_Cec);
69
70
71static NEXUS_Cec g_cec;
72static void NEXUS_Cec_P_AllocateLogicalAddress(NEXUS_CecHandle handle);
73
74
75void NEXUS_CecModule_Print(void)
76{
77        BDBG_MSG(("CEC: %s",g_cec.opened ? "opened" : "--"));
78}
79
80NEXUS_Error NEXUS_Cec_P_Init( NEXUS_CecHandle handle )
81{
82        BDBG_OBJECT_ASSERT(handle, NEXUS_Cec);
83        handle->status.physicalAddress[0] = 0xFF;
84        handle->status.physicalAddress[1] = 0xFF;
85        handle->status.logicalAddress = BCEC_CONFIG_UNINITIALIZED_LOGICAL_ADDR;
86        return 0;
87}
88
89NEXUS_Error NEXUS_Cec_P_Shutdown(void)
90{
91        if ( g_cec.opened )
92        {
93                BDBG_ERR(("Force closing CEC interface"));
94                NEXUS_Cec_Close(&g_cec);
95        }
96       
97        return NEXUS_SUCCESS;
98}
99
100void NEXUS_Cec_P_Callback(void *pContext)
101{
102        NEXUS_CecHandle handle = (NEXUS_CecHandle)pContext;
103        BCEC_MessageStatus stMessageStatus;
104        NEXUS_Error rc;
105
106        BDBG_OBJECT_ASSERT(handle, NEXUS_Cec);
107
108        rc = BCEC_GetMessageStatus(handle->cecHandle, &stMessageStatus);
109        if (rc) {
110                rc = BERR_TRACE(rc);
111        }
112        else {
113                if (stMessageStatus.eMessageType == BAVC_HDMI_CEC_IntMessageType_eTransmit) {
114                        if (handle->searchState < NEXUS_CecLogicalAddrSearch_eReady) {
115                                if (!stMessageStatus.uiStatus) {
116                                        handle->searchState = NEXUS_CecLogicalAddrSearch_eReady;
117                                }
118                                else {
119                                        handle->searchState = NEXUS_CecLogicalAddrSearch_eNext;
120                                }
121                                NEXUS_Cec_P_AllocateLogicalAddress(handle);
122                        }
123                        else {
124                                handle->status.messageTransmitPending = false;
125                                NEXUS_TaskCallback_Fire(handle->messageTransmittedCallback);
126                        }
127                }
128                else if (stMessageStatus.eMessageType == BAVC_HDMI_CEC_IntMessageType_eReceive)
129                {
130                        handle->status.messageReceived = true;
131                        NEXUS_TaskCallback_Fire(handle->messageReceivedCallback);                       
132                }
133                else {
134                        BDBG_ERR(("Unknown CEC message type: %d", stMessageStatus.eMessageType));
135                        BDBG_ASSERT(0);
136                }
137        }
138}
139
140
141/**
142Summary:
143Open a CEC interface
144**/
145NEXUS_CecHandle NEXUS_Cec_Open( /* attr{destructor=NEXUS_Cec_Close} */
146        unsigned index,
147        const NEXUS_CecSettings *pSettings
148)
149{
150        BERR_Code errCode;
151        NEXUS_Cec *pCec;
152        BKNI_EventHandle cecEvent;
153        BCEC_Dependencies stCecDependencies;
154
155        pCec = &g_cec;
156        BSTD_UNUSED(index);
157       
158        if ( pCec->opened )
159        {
160                BDBG_ERR(("CEC interface already opened"));
161                return NULL;
162        }
163
164        BKNI_Memset(pCec, 0, sizeof(*pCec));
165        BDBG_OBJECT_SET(pCec, NEXUS_Cec);
166
167        pCec->cecSettings = *pSettings;
168        pCec->messageTransmittedCallback = NEXUS_TaskCallback_Create(pCec, NULL);
169        pCec->messageReceivedCallback = NEXUS_TaskCallback_Create(pCec, NULL);
170        pCec->logicalAddressAcquiredCallback = NEXUS_TaskCallback_Create(pCec, NULL);           
171
172        /* must init CEC before allows CEC callback */
173        errCode = NEXUS_Cec_P_Init( pCec );
174        if ( errCode )
175        {
176                errCode = BERR_TRACE(errCode);
177                goto err_cec ;
178        }
179
180        stCecDependencies.hChip = g_pCoreHandles->chp;
181        stCecDependencies.hRegister = g_pCoreHandles->reg;
182        stCecDependencies.hInterrupt = g_pCoreHandles->bint;
183
184        errCode = BCEC_Open(&pCec->cecHandle, &stCecDependencies);
185        if ( errCode )
186        {
187                errCode = BERR_TRACE(errCode);
188                return NULL;
189        }
190
191        errCode = BCEC_GetEventHandle(pCec->cecHandle, BCEC_EventCec, &cecEvent) ;
192        if (errCode)
193                goto err_cec;
194        pCec->cecEventCallback = NEXUS_RegisterEvent(cecEvent, NEXUS_Cec_P_Callback, pCec);
195        if (!pCec->cecEventCallback)
196                goto err_cec;
197
198
199        pCec->opened = true;
200        return pCec;
201
202err_cec:
203        if ( pCec->cecEventCallback )
204        {
205                NEXUS_UnregisterEvent(pCec->cecEventCallback);
206        }
207
208        BCEC_Close(pCec->cecHandle);
209        return NULL;
210
211}
212
213
214/**
215Summary:
216Close the Cec interface
217**/
218void NEXUS_Cec_Close(   NEXUS_CecHandle handle)
219{
220        BDBG_OBJECT_ASSERT(handle, NEXUS_Cec);
221
222        if ( handle->cecEventCallback )
223        {
224                NEXUS_UnregisterEvent(handle->cecEventCallback);
225        }       
226        BCEC_Close(handle->cecHandle);
227
228        NEXUS_TaskCallback_Destroy(handle->messageTransmittedCallback);
229        NEXUS_TaskCallback_Destroy(handle->messageReceivedCallback);
230        NEXUS_TaskCallback_Destroy(handle->logicalAddressAcquiredCallback);     
231
232        /* memset of zero will also wipe out BDBG_OBJECT */
233        BKNI_Memset(handle, 0, sizeof(*handle));
234}
235
236
237void NEXUS_Cec_GetDefaultSettings(
238        NEXUS_CecSettings *pSettings /* [out] */
239)
240{
241        BKNI_Memset(pSettings, 0, sizeof(*pSettings));
242       
243        pSettings->physicalAddress[0]=0xFF;
244        pSettings->physicalAddress[1]=0xFF;     
245        return;
246}
247
248       
249void NEXUS_Cec_GetSettings(
250        NEXUS_CecHandle handle,
251        NEXUS_CecSettings *pSettings /* [out] */
252)
253{
254        BDBG_OBJECT_ASSERT(handle, NEXUS_Cec);
255        *pSettings = handle->cecSettings;
256}
257
258
259NEXUS_Error NEXUS_Cec_SetSettings(
260        NEXUS_CecHandle handle,
261        const NEXUS_CecSettings *pSettings
262)       
263{
264        NEXUS_Error rc = 0;
265
266        BDBG_OBJECT_ASSERT(handle, NEXUS_Cec);
267       
268        /* save physical address & device type */
269        BKNI_Memcpy(handle->status.physicalAddress, pSettings->physicalAddress, sizeof(pSettings->physicalAddress));
270        handle->status.deviceType = pSettings->deviceType;
271
272        rc = BCEC_Enable(handle->cecHandle, pSettings->enabled);
273        if (rc) return BERR_TRACE(rc);
274
275        if (pSettings->enabled && (handle->cecSettings.enabled != pSettings->enabled
276         || handle->status.logicalAddress == BCEC_CONFIG_UNINITIALIZED_LOGICAL_ADDR))
277        {
278                handle->searchState = NEXUS_CecLogicalAddrSearch_eInit;
279                NEXUS_Cec_P_AllocateLogicalAddress(handle);
280        }
281
282        /* Set callbacks */
283        NEXUS_TaskCallback_Set(handle->messageTransmittedCallback, &pSettings->messageTransmittedCallback);
284        NEXUS_TaskCallback_Set(handle->messageReceivedCallback, &pSettings->messageReceivedCallback);
285        NEXUS_TaskCallback_Set(handle->logicalAddressAcquiredCallback, &pSettings->logicalAddressAcquiredCallback);     
286
287        handle->cecSettings = *pSettings;
288        return rc;
289}
290
291
292NEXUS_Error NEXUS_Cec_GetStatus(
293        NEXUS_CecHandle handle,
294        NEXUS_CecStatus *pStatus /* [out] */
295)
296{
297        NEXUS_Error rc = BERR_SUCCESS;
298        BCEC_Settings stCecSettings;
299        BCEC_MessageStatus stMessageStatus;
300       
301        BDBG_OBJECT_ASSERT(handle, NEXUS_Cec);
302       
303        rc = BCEC_GetSettings(handle->cecHandle, &stCecSettings);       
304        /* device logical address has not yet been established */
305        if (rc == BERR_NOT_INITIALIZED)
306                handle->status.ready = false;
307        else
308                handle->status.ready = true;
309
310
311        /* Get device logical and physical address */
312        /* logical and physical address */
313        handle->status.logicalAddress = stCecSettings.CecLogicalAddr;
314        BKNI_Memcpy(handle->status.physicalAddress, stCecSettings.CecPhysicalAddr, 
315                         sizeof(stCecSettings.CecPhysicalAddr));
316       
317        /* Device type */
318        handle->status.deviceType = (NEXUS_CecDeviceType) stCecSettings.eDeviceType;
319
320        /* message status */
321        rc = BCEC_GetMessageStatus(handle->cecHandle, &stMessageStatus);
322        if (rc)
323        {
324                BDBG_ERR(("Error getting CEC message info"));
325                goto done;
326        }
327        handle->status.transmitMessageAcknowledged = (bool) stMessageStatus.uiStatus;
328
329done:
330        /* return status */
331        *pStatus = handle->status;
332        return rc;
333}
334
335
336NEXUS_Error NEXUS_Cec_ReceiveMessage(
337        NEXUS_CecHandle handle,
338        NEXUS_CecReceivedMessage *pReceivedMessage /* [out] */
339)
340{
341        NEXUS_Error rc = NEXUS_SUCCESS;
342        BAVC_HDMI_CEC_MessageData stMessageData;
343        BCEC_MessageStatus stMessageStatus;
344
345        BDBG_OBJECT_ASSERT(handle, NEXUS_Cec);
346
347        /* reset status */
348        handle->status.messageReceived = false;
349
350        rc = BCEC_GetReceivedMessage(handle->cecHandle, &stMessageData);
351        if (rc)
352        {
353                BDBG_ERR(("Error receiving CEC Msg")) ;
354                return BERR_TRACE(rc);
355        }
356
357        pReceivedMessage->data.initiatorAddr = stMessageData.initiatorAddr;
358        pReceivedMessage->data.destinationAddr = stMessageData.destinationAddr;
359        pReceivedMessage->data.length = stMessageData.messageLength;
360        BKNI_Memcpy(&pReceivedMessage->data.buffer, &stMessageData.messageBuffer,
361                        (sizeof(uint8_t) * stMessageData.messageLength));
362
363        /* message status */
364        rc = BCEC_GetMessageStatus(handle->cecHandle, &stMessageStatus);
365        if (rc)
366        {
367                BDBG_ERR(("Error getting CEC message info"));
368                goto done;
369        }
370        pReceivedMessage->receivedStatus.receivedMessageAcknowledged = (bool) stMessageStatus.uiStatus;
371        pReceivedMessage->receivedStatus.endOfMessage = (bool) stMessageStatus.uiEOM;
372
373
374        /* Re-enable the CEC core to receive the next incoming CEC message */   
375        rc = BCEC_EnableReceive(handle->cecHandle);
376        if (rc != BERR_SUCCESS)
377        {
378                BDBG_ERR(("Error enable CEC core to receive messages"));
379                goto done;
380        }
381
382done:   
383        return rc;
384}
385
386
387void NEXUS_Cec_GetDefaultMessageData(
388        NEXUS_CecMessage *pMessage /* [out] */
389)       
390{
391        BKNI_Memset(pMessage, 0, sizeof(pMessage));
392        return;
393}
394
395
396NEXUS_Error NEXUS_Cec_TransmitMessage(
397        NEXUS_CecHandle handle,
398        const NEXUS_CecMessage *pMessage
399)
400{
401        NEXUS_Error rc = NEXUS_SUCCESS;
402        BAVC_HDMI_CEC_MessageData stCecMessageData;
403
404        BDBG_OBJECT_ASSERT(handle, NEXUS_Cec);
405
406        if (handle->status.messageTransmitPending)
407        {
408                rc = NEXUS_NOT_AVAILABLE;
409                goto done;
410        }
411
412        /* prepare CEC message data */
413        stCecMessageData.initiatorAddr = pMessage->initiatorAddr;
414        stCecMessageData.destinationAddr = pMessage->destinationAddr;
415        stCecMessageData.messageLength = pMessage->length;
416        BKNI_Memcpy(stCecMessageData.messageBuffer, pMessage->buffer, 
417                        sizeof(pMessage->buffer));
418
419        /* transmit message */
420        rc = BCEC_XmitMessage(handle->cecHandle, &stCecMessageData);
421
422        /* set Pending if message successfuly sent */
423        if (!rc)
424                handle->status.messageTransmitPending = true;
425
426done:
427        return rc;
428}
429
430
431static uint8_t g_logicalAddrArray[] =
432{
433        BAVC_HDMI_CEC_StbDevices_eSTB1,
434        BAVC_HDMI_CEC_StbDevices_eSTB2,
435        BAVC_HDMI_CEC_StbDevices_eSTB3,
436        BAVC_HDMI_CEC_StbDevices_eSTB4,
437        BAVC_HDMI_CEC_StbDevices_eFreeUse,
438        BAVC_HDMI_CEC_AllDevices_eUnRegistered
439};
440
441
442static void NEXUS_Cec_P_AllocateLogicalAddress(NEXUS_CecHandle handle)
443{
444        NEXUS_Error rc;
445        uint8_t addr;
446        BCEC_Settings stCecSettings;
447
448        BDBG_OBJECT_ASSERT(handle, NEXUS_Cec);
449
450        switch (handle->searchState) 
451        {
452               
453        default:
454        case NEXUS_CecLogicalAddrSearch_eInit:  /* ping first Address */
455                addr = g_logicalAddrArray[handle->logAddrSearchIndex];
456                BDBG_MSG(("Starting search for CEC Logical Addr: %d...", addr)) ;
457                handle->logAddrSearchIndex = 0;
458                handle->status.logicalAddress = BCEC_CONFIG_UNINITIALIZED_LOGICAL_ADDR;
459                rc = BCEC_PingLogicalAddr(handle->cecHandle, addr);
460                if (rc) rc = BERR_TRACE(rc);
461
462                break;
463
464        case NEXUS_CecLogicalAddrSearch_eNext:
465                handle->logAddrSearchIndex++;
466                addr = g_logicalAddrArray[handle->logAddrSearchIndex];
467                BDBG_MSG(("Continuing search for CEC Logical Addr: %d...", addr)) ;
468
469                if (handle->logAddrSearchIndex == sizeof(g_logicalAddrArray)/sizeof(g_logicalAddrArray[0]) - 1) 
470                {
471                        BDBG_WRN(("All CEC Addrs used; device unregistered")) ;
472                        /* Update state and fall through */
473                        handle->searchState = NEXUS_CecLogicalAddrSearch_eReady;
474                }       
475                else {
476                        rc = BCEC_PingLogicalAddr(handle->cecHandle, addr);
477                        if (rc) rc = BERR_TRACE(rc);
478                        break;
479                }
480
481        case NEXUS_CecLogicalAddrSearch_eReady:
482                handle->status.logicalAddress = g_logicalAddrArray[handle->logAddrSearchIndex];
483
484                BDBG_MSG(("Found CEC Logical Addr: %d", handle->status.logicalAddress)) ;
485                stCecSettings.CecLogicalAddr = handle->status.logicalAddress;
486                BKNI_Memcpy(stCecSettings.CecPhysicalAddr, handle->status.physicalAddress, 
487                        sizeof(handle->status.physicalAddress));
488                stCecSettings.eDeviceType = handle->status.deviceType;
489                rc = BCEC_SetSettings(handle->cecHandle, &stCecSettings);
490                if (rc) rc = BERR_TRACE(rc);
491
492                rc = BCEC_GetSettings(handle->cecHandle, &stCecSettings);
493                if (rc != BERR_NOT_INITIALIZED)
494                {        /* BERR_NOT_INITIALIZED is normal for not connected to CEC compatible device */
495                        if (rc) {rc = BERR_TRACE(rc);} /* Other errors are worth noting.  fall through */
496
497                        /* Report Physical Address */
498                        rc = BCEC_ReportPhysicalAddress(handle->cecHandle);
499                        if (rc) rc = BERR_TRACE(rc);
500
501                        /* always enable receive after CEC msg is processed */
502                        rc = BCEC_EnableReceive(handle->cecHandle);
503                        if (rc) rc = BERR_TRACE(rc);
504                }
505
506                NEXUS_TaskCallback_Fire(handle->logicalAddressAcquiredCallback);
507                break;
508        }
509}
510
511
Note: See TracBrowser for help on using the repository browser.