source: svn/trunk/newcon3bcm2_21bu/magnum/portinginterface/cec/7552/bcec.c

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

first commit

  • Property svn:executable set to *
File size: 40.1 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: bcec.c $
39 * $brcm_Revision: Hydra_Software_Devel/10 $
40 * $brcm_Date: 3/26/12 6:43p $
41 *
42 * Module Description:
43 *
44 * Revision History:
45 *
46 * $brcm_Log: /magnum/portinginterface/cec/7425/bcec.c $
47 *
48 * Hydra_Software_Devel/10   3/26/12 6:43p vle
49 * SW7420-2283: Fix build warning for 65nm builds.
50 *
51 * Hydra_Software_Devel/9   3/6/12 1:48p vle
52 * SW7425-2289: Disable AutoOn feature by default
53 *
54 * Hydra_Software_Devel/8   3/1/12 1:19p vle
55 * SW7425-2289: Additional update to make sure only AutoOn CEC is active
56 *
57 * Hydra_Software_Devel/7   2/28/12 10:56a vle
58 * SW7425-2289, SW7420-2256: Add more debug messages, fix compiler
59 * warnings for 65nm platforms
60 *
61 * Hydra_Software_Devel/6   2/24/12 4:06p vle
62 * SW7425-2289: Merge to mainline
63 *
64 * Hydra_Software_Devel/SW7425-2289/1   2/22/12 6:10p vle
65 * SW7425-2289: Add support for CEC AutoOn
66 *
67 * Hydra_Software_Devel/5   2/21/12 4:32p vle
68 * SW7425-2279: Update for 65nm platform support.
69 *
70 * Hydra_Software_Devel/4   2/17/12 3:44p vle
71 * SW7425-2279: Merge to mainline
72 *
73 * Hydra_Software_Devel/SW7425-2279/7   2/16/12 4:55p vle
74 * SW7425-2279: Additional updates after 2nd review. Still need to rework
75 * Standby/Resume function to use CEC autoOn feature.
76 *
77 * Hydra_Software_Devel/SW7425-2279/6   2/15/12 3:47p vle
78 * SW7425-2279: Additionals updates after a quick review.
79 *
80 * Hydra_Software_Devel/SW7425-2279/5   2/15/12 3:05p vle
81 * SW7425-2279: fix typo
82 *
83 * Hydra_Software_Devel/SW7425-2279/4   2/14/12 5:56p vle
84 * SW7425-2279: More updates improving implementations.
85 *
86 * Hydra_Software_Devel/SW7425-2279/3   2/13/12 3:32p vle
87 * SW7420-682: Merge to SW7425-2279 branch
88 *
89 * Hydra_Software_Devel/SW7425-2279/2   2/9/12 3:35p vle
90 * SW7425-2279: Update BCEC PI implementations. Use separate events for
91 * transmit and receive.
92 *
93 * Hydra_Software_Devel/SW7425-2279/1   1/30/12 7:14p vle
94 * SW7425-2279: Fix incorrect return of received CEC message
95 *
96 * Hydra_Software_Devel/SW7420-682/1   2/3/12 6:41p vle
97 * SW7420-682: First attempt at enable Auto-on CEC. Code hasn't gone
98 * through testing.
99 *
100 * Hydra_Software_Devel/3   12/21/11 1:40p vle
101 * SW7405-4781: merge to mainline
102 *
103 * Hydra_Software_Devel/SW7405-4781/1   12/21/11 12:12p vle
104 * SW7405-4781: allow CEC device type to be configurable
105 *
106 * Hydra_Software_Devel/2   12/9/11 11:00a vle
107 * SW7425-1140: fix comments and add GetDefaultSettings API
108 *
109 * Hydra_Software_Devel/1   11/22/11 6:23p vle
110 * SW7425-1140: Add BCEC PI support
111 *
112 * Hydra_Software_Devel/SW7425-1140/2   11/22/11 3:50p rgreen
113 * SW7425-1140: Add macros for debug support
114 *
115 * Hydra_Software_Devel/SW7425-1140/1   11/16/11 12:14p vle
116 * SW7425-1140: Add CEC PI support for 7425
117 *
118 ***************************************************************************/
119
120#include "bstd.h"
121#include "berr_ids.h"
122
123#include "bcec.h"
124#include "bcec_priv.h"
125#include "bcec_config.h"
126#include "bavc_hdmi.h"
127
128
129BDBG_MODULE(BCEC) ;
130BDBG_OBJECT_ID(BCEC_P_Handle);
131
132 
133#define BCEC_CHECK_RC( rc, func )                                 \
134do                                                                                                \
135{                                                                                                 \
136        if( (rc = BERR_TRACE(func)) != BERR_SUCCESS ) \
137        {                                                                                         \
138                goto done;                                                                \
139        }                                                                                         \
140} while(0)
141
142
143#define BCEC_REG_OFFSET 0
144
145#if BCEC_CONFIG_DEBUG_OPCODE
146
147BCEC_OpcodeTextTable opCodeTextTable[BCEC_MAX_OPCODES] = {
148{ BCEC_OpCode_FeatureAbort,                     "FeatureAbort" },                         
149{ BCEC_OpCode_ImageViewOn,                              "ImageViewOn" },                         
150{ BCEC_OpCode_TunerStepIncrement,               "TunerStepIncrement" },           
151{ BCEC_OpCode_TunerStepDecrement,               "TunerStepDecrement" },           
152{ BCEC_OpCode_TunerDeviceStatus,                "TunerDeviceStatus" },           
153{ BCEC_OpCode_DiveTunerDeviceStatus,    "DiveTunerDeviceStatus" },       
154{ BCEC_OpCode_RecordOn,                                 "RecordOn" },                             
155{ BCEC_OpCode_RecordStatus,                     "RecordStatus" },                         
156{ BCEC_OpCode_RecordOff,                                "RecordOff" },                           
157{ BCEC_OpCode_TextViewOn,                               "TextViewOn" },                           
158{ BCEC_OpCode_RecordTVScreen,                   "RecordTVScreen" },               
159{ BCEC_OpCode_GiveDeckStatus,                   "GiveDeckStatus" },               
160{ BCEC_OpCode_DecStatus,                                "DecStatus" },                           
161{ BCEC_OpCode_SetMenuLanguage,                  "SetMenuLanguage" },             
162{ BCEC_OpCode_ClearAnalogueTimer,               "ClearAnalogueTimer" },           
163{ BCEC_OpCode_SetAnalogueTimer,                 "SetAnalogueTimer" },             
164{ BCEC_OpCode_TimerStatus,                              "TimerStatus" },                         
165{ BCEC_OpCode_Standby,                                  "Standby" },                             
166{ BCEC_OpCode_Play,                                     "Play" },                                         
167{ BCEC_OpCode_DeckControl,                              "DeckControl" },                         
168{ BCEC_OpCode_TimerClearedStatus,               "TimerClearedStatus" },           
169{ BCEC_OpCode_UserControlPressed,               "UserControlPressed" },           
170{ BCEC_OpCode_UserControlReleased,              "UserControlReleased" },         
171{ BCEC_OpCode_GiveOSDName,                              "GiveOSDName" },                         
172{ BCEC_OpCode_SetOSDName,                               "SetOSDName" },                           
173{ BCEC_OpCode_SetOSDString,                     "SetOSDString" },                         
174{ BCEC_OpCode_SetTimerProgramTitle,     "SetTimerProgramTitle" },         
175{ BCEC_OpCode_SystemAudioModeRequest,   "SystemAudioModeRequest" },   
176{ BCEC_OpCode_GiveAudioStatus,                  "GiveAudioStatus" },             
177{ BCEC_OpCode_SetSystemAudioMode,               "SetSystemAudioMode" },           
178{ BCEC_OpCode_ReportAudioStatus,                "ReportAudioStatus" },           
179{ BCEC_OpCode_GiveSystemAudioModeStatus,"GiveSystemAudioModeStatus" },
180{ BCEC_OpCode_SystemAudioModeStatus,    "SystemAudioModeStatus" },       
181{ BCEC_OpCode_RoutingChange,                    "RoutingChange" },                       
182{ BCEC_OpCode_RoutingInformation,               "RoutingInformation" },           
183{ BCEC_OpCode_ActiveSource,                     "ActiveSource" },                         
184{ BCEC_OpCode_GivePhysicalAddress,              "GivePhysicalAddress" },         
185{ BCEC_OpCode_ReportPhysicalAddress,    "ReportPhysicalAddress" },       
186{ BCEC_OpCode_RequestActiveSource,              "RequestActiveSource" },         
187{ BCEC_OpCode_SetStreamPath,                    "SetStreamPath" },                       
188{ BCEC_OpCode_DeviceVendorID,                   "DeviceVendorID" },               
189{ BCEC_OpCode_VendorCommand,                    "VendorCommand" },                       
190{ BCEC_OpCode_VendorRemoteButtonDown,   "VendorRemoteButtonDown" },   
191{ BCEC_OpCode_VendorRemoteButtonUp,     "VendorRemoteButtonUp" },         
192{ BCEC_OpCode_GiveDeviceVendorID,               "GiveDeviceVendorID" },           
193{ BCEC_OpCode_MenuRequest,                              "MenuRequest" },                         
194{ BCEC_OpCode_MenuStatus,                               "MenuStatus" },                           
195{ BCEC_OpCode_GiveDevicePowerStatus,    "GiveDevicePowerStatus" },       
196{ BCEC_OpCode_ReportPowerStatus,                "ReportPowerStatus" },           
197{ BCEC_OpCode_GetMenuLanguage,                  "GetMenuLanguage" },             
198{ BCEC_OpCode_SelectAnalogueService,    "SelectAnalogueService" },       
199{ BCEC_OpCode_SelectDigitalService,     "SelectDigitalService" },         
200{ BCEC_OpCode_SetDigitalTimer,                  "SetDigitalTimer" },             
201{ BCEC_OpCode_ClearDigitalTimer,                "ClearDigitalTimer" },           
202{ BCEC_OpCode_SetAudioRate,                     "SetAudioRate" },                         
203{ BCEC_OpCode_InActiveSource,                   "InActiveSource" },               
204{ BCEC_OpCode_CECVersion,                               "CECVersion" },                           
205{ BCEC_OpCode_GetCECVersion,                    "GetCECVersion" },                       
206{ BCEC_OpCode_VendorCommandWithID,              "VendorCommandWithID" },         
207{ BCEC_OpCode_ClearExternalTimer,               "ClearExternalTimer" },           
208{ BCEC_OpCode_SetExternalTimer,                 "SetExternalTimer" },             
209{ BCEC_OpCode_Abort,                                    "Abort" } 
210} ;
211
212static char unsupportedOpCode[] = "Unsupported OpCode" ;
213static const char *BCEC_OpcodeToString(uint8_t cecOpCode)
214{
215        uint8_t i ;
216
217        i = 0 ;
218        while  (i < BCEC_MAX_OPCODES)
219        {
220                if (opCodeTextTable[i].opCode == cecOpCode)
221                        return opCodeTextTable[i].opText ;
222                i++ ;
223        }
224        return unsupportedOpCode ;
225}
226#endif
227
228
229/******************************************************************************
230Summary:
231Interrupt Callback Table to describe interrupt Names, ISRs, and Masks
232*******************************************************************************/
233typedef struct BCEC_P_InterruptCbTable
234{
235        BINT_Id                   IntrId;
236        BINT_CallbackFunc pfCallback;
237        int                       iParam2; 
238        bool                      enable ; /* debug purposes */
239} BCEC_P_InterruptCbTable ;
240
241
242#define BCEC_INT_CB_DEF(intr,  id, enable) \
243        {intr, BCEC_P_HandleInterrupt_isr, id, enable},
244
245
246static const BCEC_P_InterruptCbTable BCEC_Interrupts[] =
247{
248#if BCEC_CONFIG_DUAL_INTERRUPT
249        BCEC_INT_CB_DEF(BCHP_INT_ID_CEC_RCVD_INTR_TX,
250                BCEC_INTR_eRECEIVED, 1)
251        BCEC_INT_CB_DEF(BCHP_INT_ID_CEC_SENT_INTR_TX,
252                BCEC_INTR_eSENT, 1)
253
254#elif BCEC_CONFIG_SINGLE_INTERRUPT
255        BCEC_INT_CB_DEF(BCHP_INT_ID_CEC_INTR_TX,
256                BCEC_INTR_eCEC, 1)
257               
258#else   /* legacy platforms 65nm and earlier */
259        BCEC_INT_CB_DEF(BCHP_INT_ID_CEC_INTR,
260                BCEC_INTR_eCEC, 1)
261#endif         
262} ;
263
264
265/********************
266*       PRIVATE APIs    *
267*********************/ 
268static void BCEC_P_Initialize(BCEC_Handle hCEC) 
269{
270        BREG_Handle hRegister ;
271        uint32_t Register ;
272        uint32_t ulOffset ;
273
274        BDBG_ENTER(BCEC_P_Initialize) ;
275
276        hRegister = hCEC->stDependencies.hRegister ;
277        ulOffset = BCEC_REG_OFFSET ;
278
279        /*************************     
280        ** adjust default CEC timing **
281        **************************/
282        Register = BREG_Read32(hRegister, REGADDR_CEC_CNTRL_1 + ulOffset) ;
283        Register &= ~BCHP_MASK_DVP(CEC_CNTRL_1, DIV_CLK_CNT);
284        Register |= BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_1, DIV_CLK_CNT, 
285                                BCEC_CNTRL_1_DIV_CLK_CNT_VALUE);
286        BREG_Write32(hRegister, REGADDR_CEC_CNTRL_1 + ulOffset, Register) ;
287
288        Register = BREG_Read32(hRegister, REGADDR_CEC_CNTRL_2 + ulOffset) ;
289        Register &= 
290                ~(BCHP_MASK_DVP(CEC_CNTRL_2, CNT_TO_400_US)
291                | BCHP_MASK_DVP(CEC_CNTRL_2, CNT_TO_600_US)
292                | BCHP_MASK_DVP(CEC_CNTRL_2, CNT_TO_800_US)
293                | BCHP_MASK_DVP(CEC_CNTRL_2, CNT_TO_1300_US)
294                | BCHP_MASK_DVP(CEC_CNTRL_2, CNT_TO_1500_US));
295       
296        Register |= 
297                  BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_2, CNT_TO_400_US, 
298                                BCEC_CNTRL_2_CNT_TO_400_US_VALUE)
299                | BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_2, CNT_TO_600_US, 
300                                BCEC_CNTRL_2_CNT_TO_600_US_VALUE)       
301                | BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_2, CNT_TO_800_US, 
302                                BCEC_CNTRL_2_CNT_TO_800_US_VALUE)
303                | BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_2, CNT_TO_1300_US, 
304                                BCEC_CNTRL_2_CNT_TO_1300_US_VALUE)
305                | BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_2, CNT_TO_1500_US, 
306                                BCEC_CNTRL_2_CNT_TO_1500_US_VALUE);
307        BREG_Write32(hRegister, REGADDR_CEC_CNTRL_2 + ulOffset, Register) ;
308
309
310        Register = BREG_Read32(hRegister, REGADDR_CEC_CNTRL_3 + ulOffset) ;
311        Register &= 
312                ~(BCHP_MASK_DVP(CEC_CNTRL_3, CNT_TO_1700_US)
313                | BCHP_MASK_DVP(CEC_CNTRL_3, CNT_TO_2050_US)
314                | BCHP_MASK_DVP(CEC_CNTRL_3, CNT_TO_2400_US)
315                | BCHP_MASK_DVP(CEC_CNTRL_3, CNT_TO_2750_US));
316       
317        Register |= 
318                  BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_3, CNT_TO_1700_US, 
319                                BCEC_CNTRL_3_CNT_TO_1700_US_VALUE)
320                | BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_3, CNT_TO_2050_US, 
321                                BCEC_CNTRL_3_CNT_TO_2050_US_VALUE)     
322                | BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_3, CNT_TO_2400_US, 
323                                BCEC_CNTRL_3_CNT_TO_2400_US_VALUE)
324                | BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_3, CNT_TO_2750_US, 
325                                BCEC_CNTRL_3_CNT_TO_2750_US_VALUE);
326        BREG_Write32(hRegister, REGADDR_CEC_CNTRL_3 + ulOffset, Register) ;
327
328       
329        Register = BREG_Read32(hRegister, REGADDR_CEC_CNTRL_4 + ulOffset) ;
330        Register &= 
331                ~(BCHP_MASK_DVP(CEC_CNTRL_4, CNT_TO_3500_US)
332                | BCHP_MASK_DVP(CEC_CNTRL_4, CNT_TO_3600_US)
333                | BCHP_MASK_DVP(CEC_CNTRL_4, CNT_TO_3900_US)           
334                | BCHP_MASK_DVP(CEC_CNTRL_4, CNT_TO_4300_US));
335       
336        Register |= 
337                  BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_4, CNT_TO_3500_US, 
338                                BCEC_CNTRL_4_CNT_TO_3500_US_VALUE)
339                | BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_4, CNT_TO_3600_US, 
340                                BCEC_CNTRL_4_CNT_TO_3600_US_VALUE)     
341                | BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_4, CNT_TO_3900_US, 
342                                BCEC_CNTRL_4_CNT_TO_3900_US_VALUE)
343                | BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_4, CNT_TO_4300_US, 
344                                BCEC_CNTRL_4_CNT_TO_4300_US_VALUE);
345        BREG_Write32(hRegister, REGADDR_CEC_CNTRL_4 + ulOffset, Register) ;
346
347
348        Register = BREG_Read32(hRegister, REGADDR_CEC_CNTRL_5 + ulOffset) ;
349        Register &= 
350                ~(BCHP_MASK_DVP(CEC_CNTRL_5, CNT_TO_4500_US)
351                | BCHP_MASK_DVP(CEC_CNTRL_5, CNT_TO_4700_US));
352 
353        Register |= 
354                  BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_5, CNT_TO_4500_US, 
355                                BCEC_CNTRL_5_CNT_TO_4500_US_VALUE)
356                | BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_5, CNT_TO_4700_US, 
357                                BCEC_CNTRL_5_CNT_TO_4700_US_VALUE) ;
358        BREG_Write32(hRegister, REGADDR_CEC_CNTRL_5 + ulOffset, Register) ;
359
360
361#if BCEC_CONFIG_DEBUG_CEC_TIMING
362        BDBG_WRN(("CNT_TO_400_US_VALUE %d", BCEC_CNTRL_2_CNT_TO_400_US_VALUE )) ;
363        BDBG_WRN(("CNT_TO_600_US_VALUE %d", BCEC_CNTRL_2_CNT_TO_600_US_VALUE )) ;
364        BDBG_WRN(("CNT_TO_800_US_VALUE %d", BCEC_CNTRL_2_CNT_TO_800_US_VALUE )) ;
365        BDBG_WRN(("CNT_TO_1300_US_VALUE %d", BCEC_CNTRL_2_CNT_TO_1300_US_VALUE)) ;
366        BDBG_WRN(("CNT_TO_1500_US_VALUE %d", BCEC_CNTRL_2_CNT_TO_1500_US_VALUE)) ;
367
368
369        BDBG_WRN(("CNT_TO_1700_US_VALUE %d", BCEC_CNTRL_3_CNT_TO_1700_US_VALUE));
370        BDBG_WRN(("CNT_TO_2050_US_VALUE %d", BCEC_CNTRL_3_CNT_TO_2050_US_VALUE)) ;
371        BDBG_WRN(("CNT_TO_2400_US_VALUE %d", BCEC_CNTRL_3_CNT_TO_2400_US_VALUE)) ;
372        BDBG_WRN(("CNT_TO_2750_US_VALUE %d", BCEC_CNTRL_3_CNT_TO_2750_US_VALUE)) ;
373                                                                                                                                                 
374        BDBG_WRN(("CNT_TO_3500_US_VALUE %d", BCEC_CNTRL_4_CNT_TO_3500_US_VALUE)) ;
375        BDBG_WRN(("CNT_TO_3600_US_VALUE %d", BCEC_CNTRL_4_CNT_TO_3600_US_VALUE)) ;
376        BDBG_WRN(("CNT_TO_3900_US_VALUE %d", BCEC_CNTRL_4_CNT_TO_3900_US_VALUE)) ;
377        BDBG_WRN(("CNT_TO_4300_US_VALUE", BCEC_CNTRL_4_CNT_TO_4300_US_VALUE)) ;
378                                                                                                                                                 
379                                                                                                                                                 
380        BDBG_WRN(("CNT_TO_4500_US_VALUE %d", BCEC_CNTRL_5_CNT_TO_4500_US_VALUE)) ;
381        BDBG_WRN(("CNT_TO_4700_US_VALUE %d", BCEC_CNTRL_5_CNT_TO_4700_US_VALUE)) ;
382#endif
383
384        /* set flag to indicate first CEC message */
385        hCEC->firstCecMessage = true ;
386       
387        BDBG_LEAVE(BCEC_P_Initialize) ; 
388}
389
390
391/***************************************************************************
392BERR_Code BCEC_P_ResetCore_isr
393Summary: Reset CEC core
394****************************************************************************/
395static void BCEC_P_ResetCore_isr (BCEC_Handle hCEC, bool bReset)
396{
397        uint32_t Register;
398        BREG_Handle hRegister ;
399        uint32_t ulOffset;
400       
401        hRegister = hCEC->stDependencies.hRegister ;
402        ulOffset = BCEC_REG_OFFSET ;
403
404
405        Register = BREG_Read32(hRegister, REGADDR_CEC_CNTRL_5 + ulOffset) ;
406
407#if BCEC_CONFIG_40NM_SUPPORT
408        Register &= ~(BCHP_MASK_DVP(CEC_CNTRL_5, CEC_TX_SW_INIT)
409                                | BCHP_MASK_DVP(CEC_CNTRL_5, CEC_RX_SW_INIT));
410       
411        Register |= BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_5, CEC_TX_SW_INIT, bReset)
412                        | BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_5, CEC_RX_SW_INIT, bReset);
413       
414#else
415        Register &= ~(BCHP_MASK_DVP(CEC_CNTRL_5, CEC_TX_SW_RESET)
416                                | BCHP_MASK_DVP(CEC_CNTRL_5, CEC_RX_SW_RESET));
417       
418        Register |= BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_5, CEC_TX_SW_RESET, bReset)
419                        | BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_5, CEC_RX_SW_RESET, bReset);
420#endif 
421
422        BREG_Write32(hRegister, REGADDR_CEC_CNTRL_5 + ulOffset, Register) ;
423
424
425#ifdef BCEC_CONFIG_CEC_USE_PAD_SW_RESET
426        Register = BREG_Read32(hRegister, REGADDR_CEC_CNTRL_5 + ulOffset) ;
427        Register &= ~(BCHP_MASK_DVP(CEC_CNTRL_5, CEC_PAD_SW_RESET));
428
429        Register |= BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_5, CEC_PAD_SW_RESET, bReset);
430        BREG_Write32(hRegister, REGADDR_CEC_CNTRL_5 + ulOffset, Register) ; 
431#endif
432
433        return;
434}
435
436
437/***************************************************************************
438BERR_Code BCEC_P_EnableReceive_isr
439Summary: Enable Receive - isr
440****************************************************************************/
441static void BCEC_P_EnableReceive_isr(
442        BCEC_Handle hCEC         /* [in] HDMI handle */
443) 
444{ 
445        BREG_Handle hRegister ;
446        uint32_t Register ;
447        uint32_t ulOffset ;
448
449        BDBG_ENTER(BCEC_P_EnableReceive_isr);
450       
451        hRegister = hCEC->stDependencies.hRegister ;
452        ulOffset = BCEC_REG_OFFSET ;
453       
454        /* Enable Receive */
455        Register = BREG_Read32(hRegister, REGADDR_CEC_CNTRL_1 + ulOffset) ;
456       
457        Register |= BCHP_MASK_DVP(CEC_CNTRL_1, CLEAR_RECEIVE_OFF) ;
458        BREG_Write32(hRegister, REGADDR_CEC_CNTRL_1 + ulOffset, Register) ;  /* Wr 1 */
459       
460        Register &= ~ BCHP_MASK_DVP(CEC_CNTRL_1, CLEAR_RECEIVE_OFF) ;
461        BREG_Write32(hRegister, REGADDR_CEC_CNTRL_1 + ulOffset, Register) ;  /* Wr 0 */
462
463        BDBG_LEAVE(BCEC_P_EnableReceive_isr);
464        return ;
465}
466
467
468/********************
469*       PUBLIC APIs             *
470*********************/ 
471
472/******************************************************************************
473BERR_Code BCEC_Open
474Summary: Open/Initialize the CEC device
475*******************************************************************************/
476BERR_Code BCEC_Open(
477   BCEC_Handle *phCEC,    /* [out] CEC handle */
478   const BCEC_Dependencies *pstDependencies
479) 
480{
481        BERR_Code       rc = BERR_SUCCESS;
482        BCEC_Handle hCEC = NULL ;
483        uint32_t Register ;
484        uint8_t i ;
485
486        BDBG_ENTER(BCEC_Open) ;
487
488       
489        /* verify parameters */
490        BDBG_ASSERT(pstDependencies->hChip) ;
491        BDBG_ASSERT(pstDependencies->hRegister) ;
492        BDBG_ASSERT(pstDependencies->hInterrupt) ;
493
494        /* create the CEC Handle */
495        hCEC = BKNI_Malloc(sizeof(BCEC_P_Handle)) ;
496        if (!hCEC)
497        {
498                BDBG_ERR(("Unable to allocate memory for CEC Handle")) ;
499                rc = BERR_OUT_OF_SYSTEM_MEMORY ;
500                BERR_TRACE(rc);
501                goto done ;
502        }
503
504        /* zero out all memory associated with the HDMI Device Handle before using */
505        BKNI_Memset(hCEC, 0, sizeof(BCEC_P_Handle)) ;
506        BDBG_OBJECT_SET(hCEC, BCEC_P_Handle) ;
507
508        /* assign the handles passed in as parameters */
509        BKNI_Memcpy(&hCEC->stDependencies, pstDependencies, sizeof(BCEC_Dependencies)) ;
510
511        /* Initialize CEC core */
512        BCEC_P_Initialize(hCEC);
513
514        /* set default CEC address to 15 */
515        Register = BREG_Read32(hCEC->stDependencies.hRegister, REGADDR_CEC_CNTRL_1) ;
516        Register &= ~ BCHP_MASK_DVP(CEC_CNTRL_1, CEC_ADDR);
517        Register |= BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_1, CEC_ADDR, 
518                                                        BAVC_HDMI_CEC_AllDevices_eUnRegistered);
519        BREG_Write32(hCEC->stDependencies.hRegister, REGADDR_CEC_CNTRL_1, Register) ;
520
521
522        hCEC->stSettings.CecLogicalAddr = BCEC_CONFIG_UNINITIALIZED_LOGICAL_ADDR;
523
524#if BCEC_CONFIG_40NM_SUPPORT    /* the default value works for 40nm rev2 */
525        Register = BREG_Read32(hCEC->stDependencies.hRegister, REGADDR_CEC_CNTRL_6) ;
526        Register &= ~ ( BCHP_MASK_DVP(CEC_CNTRL_6, CEC_ADDR_1)
527                        | BCHP_MASK_DVP(CEC_CNTRL_6, CEC_ADDR_2));
528       
529        Register |= 
530                        ( BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_6, CEC_ADDR_1, 
531                                                        BAVC_HDMI_CEC_AllDevices_eUnRegistered)
532                        | BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_6, CEC_ADDR_2, 
533                                                        BAVC_HDMI_CEC_AllDevices_eUnRegistered));
534        BREG_Write32(hCEC->stDependencies.hRegister, REGADDR_CEC_CNTRL_6, Register) ;
535
536#elif BCEC_CONFIG_65NM_SUPPORT
537        Register = BREG_Read32(hCEC->stDependencies.hRegister, 
538                                                        BCHP_HDMI_TX_PHY_HDMI_TX_PHY_RESET_CTL) ;
539        Register &= ~BCHP_MASK(HDMI_TX_PHY_HDMI_TX_PHY_RESET_CTL, PWRDN_CEC) ;
540        BREG_Write32(hCEC->stDependencies.hRegister, 
541                BCHP_HDMI_TX_PHY_HDMI_TX_PHY_RESET_CTL, Register) ;
542#endif 
543
544
545        /* Create Events for use with Interrupts */
546        BCEC_CHECK_RC(rc, BKNI_CreateEvent(&(hCEC->BCEC_EventCec_Transmitted))) ;
547        BCEC_CHECK_RC(rc, BKNI_CreateEvent(&(hCEC->BCEC_EventCec_Received))) ;
548       
549        /* register/enable interrupt callbacks */
550        for( i = 0; i < BCEC_MAKE_INTR_ENUM(LAST) ; i++ )
551        {
552                /*
553                ** DEBUG
554                ** Create ALL interrupt callbacks
555                ** enable debug callbacks as needed;
556                */
557       
558                BCEC_CHECK_RC( rc, BINT_CreateCallback(
559                        &(hCEC->hCallback[i]), hCEC->stDependencies.hInterrupt, 
560                        BCEC_Interrupts[i].IntrId,
561                        BCEC_P_HandleInterrupt_isr, (void *) hCEC, i ));
562                       
563                /* clear interrupt callback */
564                BCEC_CHECK_RC(rc, BINT_ClearCallback( hCEC->hCallback[i])) ;
565               
566                /* now enable it; if specified for startup */   
567                if (!BCEC_Interrupts[i].enable)
568                        continue ;
569                       
570                BCEC_CHECK_RC( rc, BINT_EnableCallback( hCEC->hCallback[i] ) );
571        }
572
573       
574        /* keep created pointer */
575        *phCEC = hCEC ;
576
577done:
578        if (rc != BERR_SUCCESS) 
579        {
580                if (hCEC != NULL)       
581                {
582                        /* destroy cec events if needed */
583                        if (hCEC->BCEC_EventCec_Transmitted!= NULL)
584                                BKNI_DestroyEvent(hCEC->BCEC_EventCec_Transmitted);
585
586                        if (hCEC->BCEC_EventCec_Received!= NULL)
587                                BKNI_DestroyEvent(hCEC->BCEC_EventCec_Received);
588
589                        for( i = 0; i < BCEC_MAKE_INTR_ENUM(LAST); i++ )
590                        {
591                                if (hCEC->hCallback[i]) {
592                                        /* all interrupts are now created; disable and destroy all on close */
593                                        BINT_DisableCallback( hCEC->hCallback[i] );
594                                        BINT_DestroyCallback( hCEC->hCallback[i] );
595                                }
596                        }
597                       
598                        BKNI_Free(hCEC);       
599                }
600                *phCEC=NULL;
601        }
602       
603        BDBG_LEAVE(BCEC_Open);
604        return rc;
605       
606}
607
608
609/******************************************************************************
610BERR_Code BCEC_Close
611Summary: Close the CEC handle
612*******************************************************************************/
613void BCEC_Close(
614   BCEC_Handle hCEC  /* [in] CEC handle */
615)
616{
617        uint32_t i ;
618
619        BDBG_ENTER(BCEC_Close) ;
620        BDBG_ASSERT( hCEC );
621
622        /* Disable and Destroy the HDMI Callbacks */
623        for( i = 0; i < BCEC_MAKE_INTR_ENUM(LAST); i++ )
624        {
625                if (hCEC->hCallback[i]) {       
626                        /* all interrupts are now created; disable and destroy all on close */
627                        BINT_DisableCallback( hCEC->hCallback[i] );
628                        BINT_DestroyCallback( hCEC->hCallback[i] );
629                }
630        }
631
632        /* destroy Cec events if needed */
633        if (hCEC->BCEC_EventCec_Transmitted!= NULL)
634                BKNI_DestroyEvent(hCEC->BCEC_EventCec_Transmitted);
635       
636        if (hCEC->BCEC_EventCec_Received!= NULL)
637                BKNI_DestroyEvent(hCEC->BCEC_EventCec_Received);
638
639#if BCEC_CONFIG_AUTO_ON_SUPPORT
640        /* if autoOn feature is enabled, do not hold CEC core in reset */
641        if (hCEC->stSettings.enableAutoOn)
642                goto done;
643#endif 
644
645        BKNI_EnterCriticalSection();
646                /* Hold CEC core in reset; i.e. CEC will not respond */
647                BCEC_P_ResetCore_isr (hCEC, 1);
648        BKNI_LeaveCriticalSection();
649
650
651#if BCEC_CONFIG_AUTO_ON_SUPPORT
652done:   
653#endif
654
655        /* free memory associated with the HDMI handle */
656        BKNI_Memset(hCEC, 0, sizeof(BCEC_P_Handle)) ;
657        BKNI_Free( (void *) hCEC) ;
658       
659
660        BDBG_LEAVE(BCEC_Close) ;
661        return ;
662}
663
664
665/***************************************************************************
666BERR_Code BCEC_GetEventHandle
667Summary: Get the event handle for checking CEC events.
668****************************************************************************/
669BERR_Code BCEC_GetEventHandle(
670   BCEC_Handle hCEC,                    /* [in] HDMI handle */
671   BCEC_EventType eEventType,
672   BKNI_EventHandle *pBCECEvent /* [out] event handle */
673)
674{
675        BERR_Code          rc = BERR_SUCCESS;
676
677        BDBG_ENTER(BCEC_GetEventHandle) ;
678        BDBG_ASSERT( hCEC );               
679
680        switch (eEventType)
681        {
682        case BCEC_EventCec_eTransmitted:
683                *pBCECEvent = hCEC->BCEC_EventCec_Transmitted ;
684                break ;
685
686        case BCEC_EventCec_eReceived:
687                *pBCECEvent = hCEC->BCEC_EventCec_Received ;
688                break ;
689
690        default :
691                BDBG_ERR(("Invalid Event Type: %d", eEventType)) ;
692                rc = BERR_INVALID_PARAMETER ;
693                goto done ;
694        }
695
696
697done:
698        BDBG_LEAVE(BCEC_GetEventHandle) ;
699        return rc ;
700}
701
702
703void BCEC_GetDefaultSettings(
704        BCEC_Settings *pstDefaultCecSettings
705)
706{
707        BKNI_Memset(pstDefaultCecSettings,0,sizeof(BCEC_Settings));
708
709        pstDefaultCecSettings->enable = true;
710        pstDefaultCecSettings->CecLogicalAddr = BCEC_CONFIG_UNINITIALIZED_LOGICAL_ADDR;
711        pstDefaultCecSettings->CecPhysicalAddr[0] = 0xFF;
712        pstDefaultCecSettings->CecPhysicalAddr[1] = 0xFF;
713        pstDefaultCecSettings->eDeviceType = BCEC_CONFIG_DEVICE_TYPE;
714        pstDefaultCecSettings->enableAutoOn = false;
715        return ;
716}
717
718
719BERR_Code BCEC_GetSettings(
720        BCEC_Handle hCEC,                 /* [in] CEC handle */
721        BCEC_Settings *pstCecSettings
722)
723{
724        BERR_Code rc = BERR_SUCCESS ;
725        BREG_Handle hRegister ;
726        uint32_t ulOffset ;
727
728        BDBG_ENTER(BCEC_GetSettings);
729
730        BKNI_Memset(pstCecSettings, 0, sizeof(BCEC_Settings));
731
732        hRegister = hCEC->stDependencies.hRegister ;
733        ulOffset = BCEC_REG_OFFSET ;
734
735        if (hCEC->stSettings.CecLogicalAddr == BCEC_CONFIG_UNINITIALIZED_LOGICAL_ADDR) {       
736                BDBG_WRN(("CEC Logical Address Uninitialized"));       
737        }
738
739        pstCecSettings->enable = hCEC->stSettings.enable;
740        pstCecSettings->CecLogicalAddr = hCEC->stSettings.CecLogicalAddr;       
741        BKNI_Memcpy(pstCecSettings->CecPhysicalAddr, &hCEC->stSettings.CecPhysicalAddr[0], 2); 
742        pstCecSettings->eDeviceType = hCEC->stSettings.eDeviceType;
743        pstCecSettings->enableAutoOn = hCEC->stSettings.enableAutoOn;
744
745        BDBG_MSG(("BCM%d Device's Logical Addr: %d", BCHP_CHIP, pstCecSettings->CecLogicalAddr));
746        BDBG_MSG(("BCM%d Device's Physical Addr: %02X %02X", BCHP_CHIP,
747                pstCecSettings->CecPhysicalAddr[0], pstCecSettings->CecPhysicalAddr[1])) ;
748
749
750        BDBG_LEAVE(BCEC_GetSettings);
751        return rc ;
752}
753
754
755BERR_Code BCEC_SetSettings(
756        BCEC_Handle hCEC,                 /* [in] CEC handle */
757        const BCEC_Settings *pstCecSettings
758)
759{
760        BERR_Code rc = BERR_SUCCESS ;
761        BREG_Handle hRegister ;
762        uint32_t Register ;
763        uint32_t ulOffset ;
764
765        BDBG_ENTER(BCEC_SetSettings);
766
767        hRegister = hCEC->stDependencies.hRegister ;
768        ulOffset = BCEC_REG_OFFSET ;
769       
770        BKNI_EnterCriticalSection();
771                if (pstCecSettings->enable)
772                {
773                        /* a change in logical address require a reset of the CEC core */
774                        if ((pstCecSettings->CecLogicalAddr != hCEC->stSettings.CecLogicalAddr)
775                        || (!hCEC->stSettings.enable))
776                        {
777                                Register = BREG_Read32(hRegister, REGADDR_CEC_CNTRL_1 + ulOffset) ;
778                                        Register &= ~ BCHP_MASK_DVP(CEC_CNTRL_1, CEC_ADDR) ;
779                                        Register |= BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_1, CEC_ADDR, pstCecSettings->CecLogicalAddr) ;
780                                BREG_Write32(hRegister, REGADDR_CEC_CNTRL_1 + ulOffset, Register) ;
781
782                                /* if current state is enabled */
783                                if (hCEC->stSettings.enable)
784                                {
785                                        /* toggle reset CEC core */
786                                        BCEC_P_ResetCore_isr (hCEC, 1);
787                                        BCEC_P_ResetCore_isr (hCEC, 0);
788                                }
789                        }       
790                }
791
792                /* only enable/disable CEC core when there's a change  */
793                if (hCEC->stSettings.enable != pstCecSettings->enable) {
794                        BCEC_P_ResetCore_isr (hCEC, !pstCecSettings->enable);
795                }
796        BKNI_LeaveCriticalSection();   
797
798
799        /* Save settings */
800        hCEC->stSettings.enable = pstCecSettings->enable;
801        BKNI_Memcpy(hCEC->stSettings.CecPhysicalAddr, pstCecSettings->CecPhysicalAddr, 2) ;
802        hCEC->stSettings.eDeviceType = pstCecSettings->eDeviceType;
803        hCEC->stSettings.CecLogicalAddr = pstCecSettings->CecLogicalAddr;               
804        hCEC->stSettings.enableAutoOn = pstCecSettings->enableAutoOn;
805
806        /* Reset FirstCecMessage */
807        hCEC->firstCecMessage = true; 
808
809        BDBG_LEAVE(BCEC_SetSettings);   
810        return rc ;
811}
812
813
814BERR_Code BCEC_GetTransmitMessageStatus(
815        BCEC_Handle hCEC,          /* [in] CEC handle */
816        BCEC_MessageStatus *pstCecMessageStatus
817)       
818{
819        BERR_Code rc = BERR_SUCCESS;
820       
821        BDBG_ENTER(BCEC_GetTransmitMessageStatus);
822        BDBG_ASSERT(pstCecMessageStatus);
823
824        BKNI_EnterCriticalSection();
825                pstCecMessageStatus->uiStatus = hCEC->lastTransmitMessageStatus.uiStatus;
826                pstCecMessageStatus->uiMessageLength = hCEC->lastTransmitMessageStatus.uiMessageLength;
827                pstCecMessageStatus->uiEOM = hCEC->lastTransmitMessageStatus.uiEOM;
828        BKNI_LeaveCriticalSection();
829
830        BDBG_LEAVE(BCEC_GetTransmitMessageStatus);
831        return rc;
832}
833
834
835BERR_Code BCEC_GetReceivedMessageStatus(
836        BCEC_Handle hCEC,          /* [in] CEC handle */
837        BCEC_MessageStatus *pstCecMessageStatus
838)       
839{
840        BERR_Code rc = BERR_SUCCESS;
841
842        BDBG_ENTER(BCEC_GetReceivedMessageStatus);
843        BDBG_ASSERT(pstCecMessageStatus);
844       
845        BKNI_EnterCriticalSection();
846                pstCecMessageStatus->uiStatus = hCEC->lastReceivedMessageStatus.uiStatus;
847                pstCecMessageStatus->uiMessageLength = hCEC->lastReceivedMessageStatus.uiMessageLength;
848                pstCecMessageStatus->uiEOM = hCEC->lastReceivedMessageStatus.uiEOM;
849        BKNI_LeaveCriticalSection();
850       
851        BDBG_LEAVE(BCEC_GetReceivedMessageStatus);
852        return rc;
853}
854
855
856BERR_Code BCEC_PingLogicalAddr(
857   BCEC_Handle hCEC,      /* [in] HDMI handle */
858   uint8_t uiLogicalAddr        /* [in] device logical address */
859) 
860{
861        BERR_Code rc = BERR_SUCCESS ;
862        BREG_Handle hRegister ;
863        uint32_t Register ;
864        uint32_t ulOffset ;
865        uint8_t i ;
866
867        BDBG_ENTER(BCEC_PingLogicalAddr);
868        BDBG_ASSERT(hCEC);
869
870        hRegister = hCEC->stDependencies.hRegister ;
871        ulOffset = BCEC_REG_OFFSET ;
872       
873        BKNI_EnterCriticalSection();
874                if (hCEC->firstCecMessage)
875                {
876                        hCEC->firstCecMessage = false ;
877                }
878                else
879                {
880                        /* verify no message is currently being transmitted */
881                        Register = BREG_Read32(hRegister, REGADDR_CEC_CNTRL_1 + ulOffset) ;
882                        i = BCHP_GET_FIELD_DATA(Register, REGNAME_CEC_CNTRL_1, TX_EOM) ;
883                        if (i == 0)
884                        {
885                                BDBG_WRN(("Transmit CEC is Busy (TX_EOM: %d)!!... retry Ping later", i)) ;
886                                rc = BCEC_TRANSMIT_BUSY ;
887                                goto done ;
888                        }
889                }
890               
891                Register = 0 ;
892                /* load the first nibble with the source/destination addr */
893                Register = (uiLogicalAddr << 4) | uiLogicalAddr ;
894                BDBG_MSG(("CecMsg[00]: Initiator %02X, Destination %02X", (Register >> 4),(Register & 0x0F))) ;
895
896                /* write the first nibble in case there is no PayLoad i.e zero length message */
897                BREG_Write32(hRegister, REGADDR_CEC_TX_DATA_1 + ulOffset, Register) ;
898               
899                /* set up the message length (=0) before xmit */
900                Register = BREG_Read32(hRegister, REGADDR_CEC_CNTRL_1 + ulOffset) ;
901                Register &= ~ BCHP_MASK_DVP(CEC_CNTRL_1, MESSAGE_LENGTH) ;
902                Register |= BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_1, MESSAGE_LENGTH, 0) ;
903                BREG_Write32(hRegister, REGADDR_CEC_CNTRL_1 + ulOffset, Register) ;
904               
905                /* toggle the start xmit bit */ 
906                Register &=  ~ BCHP_MASK_DVP(CEC_CNTRL_1, START_XMIT_BEGIN) ;
907                BREG_Write32(hRegister, REGADDR_CEC_CNTRL_1 + ulOffset, Register) ;   /* 0 */
908               
909                Register |= BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_1, START_XMIT_BEGIN, 1) ;
910                BREG_Write32(hRegister, REGADDR_CEC_CNTRL_1 + ulOffset, Register) ;   /* 1 */
911done:
912        BKNI_LeaveCriticalSection();
913       
914        BDBG_LEAVE(BCEC_PingLogicalAddr);
915        return rc ; 
916}
917
918
919
920BERR_Code BCEC_XmitMessage(
921        BCEC_Handle hCEC,         /* [in] CEC handle */
922        const BAVC_HDMI_CEC_MessageData *pMessageData   /* [in] ptr to storage for CEC msg */
923)
924{
925        BERR_Code rc = BERR_SUCCESS ;
926        BREG_Handle hRegister ;
927        uint32_t Register ;
928        uint32_t ulOffset ;
929        uint32_t TxDataRegisterOffset ;
930        uint8_t i, j ;
931        uint8_t XmitMessageLength ;
932       
933#if BCEC_CONFIG_DEBUG_MESSAGE_TX
934        /* allocate 3 bytes  for each OpCode / Parameter followed by a space i.e. "%02X "
935                Also allow for message header byte */
936        char XmitMessage[3 *(BCEC_CONFIG_P_MAX_MESSAGE_BUFFER + 1)];
937        uint8_t debugMsgOffset = 0;
938#endif 
939
940        BDBG_ENTER(BCEC_XmitMessage);
941
942        hRegister = hCEC->stDependencies.hRegister ;
943        ulOffset = BCEC_REG_OFFSET ;
944        if (pMessageData->messageLength > BAVC_HDMI_CEC_MAX_XMIT_LENGTH) 
945        {
946                /* configure for Continuous Mode */
947                BDBG_ERR(("CEC Continuous Mode not implemented yet")) ;
948                rc = BCEC_NOT_IMPLEMENTED ;
949                BERR_TRACE(rc);
950                goto done ;
951        }
952
953        if (hCEC->stSettings.CecLogicalAddr == BCEC_CONFIG_UNINITIALIZED_LOGICAL_ADDR)
954        {
955                BDBG_WRN(("CEC Logical Address has not been initialized; Unable to Send message")) ;
956                rc = BERR_NOT_INITIALIZED ;
957                BERR_TRACE(rc);
958                goto done ;
959        }
960
961
962        if (hCEC->firstCecMessage)
963        {
964                hCEC->firstCecMessage = false ;
965        }
966        else
967        {
968                /*      verify no message is currently being transmitted.
969                        TX_EOM field is not modified in any other software context (only update by the hardware)
970                        Thus, this is essentially an atomic read
971                */
972                Register = BREG_Read32(hRegister, REGADDR_CEC_CNTRL_1 + ulOffset) ;
973                i = BCHP_GET_FIELD_DATA(Register, REGNAME_CEC_CNTRL_1, TX_EOM) ;
974                if (i == 0)
975                {
976                        BDBG_WRN(("Transmit CEC is Busy (TX_EOM: %d)!!... retry transmit later", i)) ;
977                        rc = BCEC_TRANSMIT_BUSY ;
978                        BERR_TRACE(rc);
979                        goto done ;
980                }
981        }
982
983       
984        /* load the CEC Msg Bytes */
985        Register = 0 ;
986        TxDataRegisterOffset = 0 ;
987       
988        /* load the first nibble with the source/destination addr */
989        j = 1 ;
990        Register = (hCEC->stSettings.CecLogicalAddr << 4) | pMessageData->destinationAddr;
991
992#if BCEC_CONFIG_DEBUG_MESSAGE_TX       
993        /* Only fordebug purposes. BKNI_Snprintf should never be used in production
994                code due to timing effects */
995        debugMsgOffset += BKNI_Snprintf(XmitMessage+debugMsgOffset, 
996                sizeof (XmitMessage) - debugMsgOffset, "%02X ", Register) ;
997#endif
998
999        /* write the first nibble in case there is no PayLoad i.e zero length message */
1000        BREG_Write32(hRegister, REGADDR_CEC_TX_DATA_1 + ulOffset + TxDataRegisterOffset, Register) ;
1001       
1002        XmitMessageLength = pMessageData->messageLength /*+ 1*/ ;
1003        for ( i = 0 ; XmitMessageLength && (i <= XmitMessageLength) ; i = i + 4) 
1004        {
1005                for ( ; j < 4 ; j++)
1006                {
1007                        Register |= pMessageData->messageBuffer[j+i-1] << (8 * j) ;
1008                       
1009                        if (j + i == XmitMessageLength)
1010                                break ;
1011                }
1012                       
1013                BREG_Write32(hRegister, REGADDR_CEC_TX_DATA_1  + ulOffset + TxDataRegisterOffset, Register) ;
1014                       
1015                BDBG_MSG(("CEC TxReg %#08x: %#08x", 
1016                        REGADDR_CEC_TX_DATA_1 + ulOffset + TxDataRegisterOffset, Register)) ;
1017                       
1018                j = 0 ;
1019                Register = 0 ;
1020                TxDataRegisterOffset += 4 ;
1021        }
1022
1023
1024        /* set up  the length */
1025        BKNI_EnterCriticalSection();
1026        Register = BREG_Read32(hRegister, REGADDR_CEC_CNTRL_1 + ulOffset) ;
1027        Register &= ~BCHP_MASK_DVP(CEC_CNTRL_1, MESSAGE_LENGTH) ;
1028        Register |= BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_1, MESSAGE_LENGTH, pMessageData->messageLength) ;
1029        BREG_Write32(hRegister, REGADDR_CEC_CNTRL_1 + ulOffset, Register) ;
1030       
1031        /* toggle the start xmit bit */ 
1032        Register &=  ~ BCHP_MASK_DVP(CEC_CNTRL_1, START_XMIT_BEGIN) ;
1033        BREG_Write32(hRegister, REGADDR_CEC_CNTRL_1 + ulOffset, Register) ;   /* 0 */
1034       
1035        Register |= BCHP_FIELD_DATA(REGNAME_CEC_CNTRL_1, START_XMIT_BEGIN, 1) ;
1036        BREG_Write32(hRegister, REGADDR_CEC_CNTRL_1 + ulOffset, Register) ;   /* 1 */
1037        BKNI_LeaveCriticalSection();
1038       
1039
1040#if BCEC_CONFIG_DEBUG_MESSAGE_TX
1041        /* CEC print/process message, only for debug purposes.
1042                BKNI_Snprintf should never be used in production code due to timing effects */
1043        for (i = 0; i < XmitMessageLength && debugMsgOffset<sizeof(XmitMessage); i++) 
1044        {
1045                debugMsgOffset += BKNI_Snprintf(XmitMessage+debugMsgOffset, 
1046                        sizeof (XmitMessage) - debugMsgOffset, "%02X ", pMessageData->messageBuffer[i]) ;
1047        }
1048
1049        BDBG_WRN(("CEC Message Length %d transmitted: %s", XmitMessageLength, XmitMessage)) ;
1050#endif
1051
1052#if BCEC_CONFIG_DEBUG_OPCODE
1053        BDBG_WRN(("Transmitted CEC Mesage <%s> - Opcode [0x%x]", 
1054                BCEC_OpcodeToString(pMessageData->messageBuffer[0]),
1055                pMessageData->messageBuffer[0]));
1056#endif
1057
1058done:
1059       
1060        BDBG_LEAVE(BCEC_XmitMessage);
1061        return rc ; 
1062}
1063
1064
1065BERR_Code BCEC_GetReceivedMessage(
1066        BCEC_Handle hCEC,                       /* [in] HDMI handle */
1067        BAVC_HDMI_CEC_MessageData *pRecvMessageData     /* [out] ptr to storage for received CEC msg */
1068) 
1069{
1070        BERR_Code rc = BERR_SUCCESS ;
1071        uint8_t cecMessageBuffer[BCEC_CONFIG_P_MAX_MESSAGE_BUFFER];
1072        uint8_t i, j ;
1073        uint8_t RxCecWordCount ;
1074        uint32_t RegisterOffset ;
1075        uint32_t Register ;
1076       
1077#if BCEC_CONFIG_DEBUG_MESSAGE_RX
1078        /* allocate 3 bytes  for each OpCode / Parameter followed by a space i.e. "%02X "
1079                Also allow for message header byte */
1080        char receivedMsg[3 * (BCEC_CONFIG_P_MAX_MESSAGE_BUFFER + 1)];
1081#endif
1082       
1083        BDBG_ENTER(BCEC_GetReceivedMessage);
1084
1085
1086        Register = BREG_Read32(hCEC->stDependencies.hRegister, REGADDR_CEC_CNTRL_1) ;
1087        RxCecWordCount = BCHP_GET_FIELD_DATA(Register, REGNAME_CEC_CNTRL_1, REC_WRD_CNT) ;
1088        pRecvMessageData->messageLength = RxCecWordCount ;
1089
1090        RxCecWordCount++ ;     
1091        /* get the received words and place into the buffer */
1092        RegisterOffset = 0 ;
1093        for (i = 0 ; i < RxCecWordCount ; i = i + 4)
1094        {
1095                Register = BREG_Read32(hCEC->stDependencies.hRegister, REGADDR_CEC_RX_DATA_1 + RegisterOffset) ;
1096                for (j = 0 ; j + i < RxCecWordCount; j++)
1097                        cecMessageBuffer[i+j] = Register >> (8 * j) & 0xFF ;
1098                       
1099                RegisterOffset = RegisterOffset + 4 ;
1100        }
1101
1102        /* save the received message */
1103        pRecvMessageData->initiatorAddr = (cecMessageBuffer[0] >> 4) & 0x0F;
1104        pRecvMessageData->destinationAddr = cecMessageBuffer[0] & 0x0F;
1105        BKNI_Memcpy(pRecvMessageData->messageBuffer, cecMessageBuffer+1, pRecvMessageData->messageLength);
1106
1107#if BCEC_CONFIG_DEBUG_MESSAGE_RX
1108        /* For debugging purposes only. BKNI_Snprintf should never be used
1109                in production code due to timing effects */
1110        for (i = 0, j = 0; i < pRecvMessageData->messageLength && j<(sizeof(receivedMsg)-1); i++) {
1111                j += BKNI_Snprintf(receivedMsg+j, sizeof(receivedMsg)-j, "%02X ", 
1112                        pRecvMessageData->messageBuffer[i]) ;
1113        }
1114       
1115        BDBG_MSG(("CEC Message Length %d Received: %s", 
1116                pRecvMessageData->messageLength, receivedMsg)) ;
1117#endif 
1118
1119
1120#if BCEC_CONFIG_DEBUG_OPCODE
1121        BDBG_WRN(("Received CEC Mesage <%s> - Opcode [0x%x]", 
1122                BCEC_OpcodeToString(pRecvMessageData->messageBuffer[0]),
1123                pRecvMessageData->messageBuffer[0]));
1124#endif
1125
1126
1127        BDBG_LEAVE(BCEC_GetReceivedMessage);   
1128        return rc ;
1129}
1130
1131
1132BERR_Code BCEC_EnableReceive(
1133        BCEC_Handle hCEC         /* [in] HDMI handle */
1134) 
1135{
1136        BERR_Code rc = BERR_SUCCESS ;
1137        BDBG_ENTER(BCEC_EnableReceive);
1138       
1139        BDBG_MSG(("Enable CEC Receive Mode")) ;
1140        BKNI_EnterCriticalSection();
1141                BCEC_P_EnableReceive_isr(hCEC);
1142        BKNI_LeaveCriticalSection();
1143
1144        BDBG_LEAVE(BCEC_EnableReceive);
1145        return rc ;
1146}
1147
1148
1149BERR_Code BCEC_ReportPhysicalAddress(
1150        BCEC_Handle hCEC          /* [in] HDMI handle */
1151) 
1152{
1153        BERR_Code rc = BERR_SUCCESS ;
1154        BAVC_HDMI_CEC_MessageData stMessageData;
1155
1156        BDBG_ENTER(BCEC_ReportPhysicalAddress);
1157        BKNI_Memset(&stMessageData, 0, sizeof(BAVC_HDMI_CEC_MessageData));
1158
1159        if (hCEC->stSettings.CecLogicalAddr == BCEC_CONFIG_UNINITIALIZED_LOGICAL_ADDR)
1160        {
1161                BDBG_WRN(("CEC Logical Address has not been initialized; Unable to Send message")) ;
1162                rc = BERR_NOT_INITIALIZED ;
1163                BERR_TRACE(rc);
1164                goto done ;
1165        }
1166
1167        /**********************************
1168                CEC Message Buffer consists of:
1169                        hexOpCode
1170                        device physical address
1171                        device type
1172        ***********************************/
1173       
1174        /* CEC message opcode = 0x84 */
1175        stMessageData.messageBuffer[0] = BCEC_OpCode_ReportPhysicalAddress;
1176
1177        /* [Device Physical Address] */ 
1178        stMessageData.messageBuffer[1] = hCEC->stSettings.CecPhysicalAddr[0];
1179        stMessageData.messageBuffer[2] = hCEC->stSettings.CecPhysicalAddr[1];
1180
1181        /* Device Type */
1182        stMessageData.messageBuffer[3] = hCEC->stSettings.eDeviceType;
1183
1184        /* Broadcast CEC message */
1185        stMessageData.initiatorAddr = hCEC->stSettings.CecLogicalAddr;
1186        stMessageData.destinationAddr = BCEC_BROADCAST_ADDR;
1187        stMessageData.messageLength = 4;
1188        rc = BCEC_XmitMessage(hCEC, &stMessageData);
1189
1190done:
1191        BDBG_LEAVE(BCEC_ReportPhysicalAddress);
1192        return rc ;
1193}
1194
1195
1196/******************************************************************************
1197Summary: Enter standby mode
1198*******************************************************************************/
1199BERR_Code BCEC_Standby(
1200        BCEC_Handle hCEC, /* [in] CEC Handle */
1201        const BCEC_StandbySettings *pSettings
1202        )
1203{
1204        BERR_Code rc = BERR_SUCCESS;
1205        BSTD_UNUSED(pSettings);
1206       
1207#if BCEC_CONFIG_AUTO_ON_SUPPORT
1208        uint8_t i;
1209
1210        if (hCEC->standby) {
1211                BDBG_ERR(("Already in standby"));
1212                rc = BERR_UNKNOWN;
1213                BERR_TRACE(rc);
1214                goto done;
1215        }
1216       
1217        if (!hCEC->stSettings.enableAutoOn)
1218        {
1219                BDBG_ERR(("AutoOn feature is disabled. Enable through CEC settings"));
1220                rc = BERR_NOT_SUPPORTED;
1221                BERR_TRACE(rc);
1222                goto done;
1223        }
1224
1225        /** Disable ALL interrupt before going to standby */
1226        for( i = 0; i < BCEC_MAKE_INTR_ENUM(LAST) ; i++ ) {
1227                BCEC_CHECK_RC( rc, BINT_DisableCallback( hCEC->hCallback[i] ) );
1228        }
1229
1230
1231        /* enable autoOn CEC */ 
1232        BCEC_P_EnableAutoOn(hCEC, true);
1233        hCEC->standby = true;
1234       
1235done:   
1236       
1237#else
1238        BSTD_UNUSED(hCEC);
1239#endif
1240       
1241        return rc; 
1242}
1243
1244
1245/******************************************************************************
1246Summary: Resume standby mode
1247*******************************************************************************/
1248BERR_Code BCEC_Resume(
1249        BCEC_Handle hCEC /* [in] CEC Handle */
1250        )
1251{
1252        BERR_Code rc = BERR_SUCCESS;
1253
1254#if BCEC_CONFIG_AUTO_ON_SUPPORT
1255        uint8_t i;
1256
1257        if (!hCEC->standby) 
1258        {
1259                BDBG_ERR(("Not in standby"));
1260                rc = BERR_UNKNOWN;             
1261                BERR_TRACE(rc);
1262                goto done;
1263        }
1264
1265        hCEC->standby = false;
1266        BCEC_P_EnableAutoOn(hCEC, false);
1267
1268        /** Enable ALL interrupts after resume from standby */
1269        for( i = 0; i < BCEC_MAKE_INTR_ENUM(LAST) ; i++ ) {
1270                BCEC_CHECK_RC( rc, BINT_EnableCallback( hCEC->hCallback[i] ) );
1271        }
1272       
1273done:           
1274       
1275#else
1276        BSTD_UNUSED(hCEC);
1277#endif
1278       
1279        return rc ;
1280}
1281
1282
1283
1284/* End of file. */
1285
Note: See TracBrowser for help on using the repository browser.