source: svn/newcon3bcm2_21bu/nexus/modules/display/7552/src/nexus_video_output.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 60.5 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_video_output.c $
39 * $brcm_Revision: 72 $
40 * $brcm_Date: 11/15/11 3:27p $
41 *
42 * Module Description:
43 *
44 * Revision History:
45 *
46 * $brcm_Log: /nexus/modules/display/7400/src/nexus_video_output.c $
47 *
48 * 72   11/15/11 3:27p erickson
49 * SW7425-1747: remove old code
50 *
51 * SW7425-1565/1   10/20/11 4:28p mlei
52 * SW7425-1565: [Display-Output]: the setting for mpaaDecimation doesn't
53 *  apply change.
54 *
55 * 70   7/28/11 3:37p erickson
56 * SW7346-319: merge
57 *
58 * 69   7/22/11 9:03a erickson
59 * SW7425-745: add NEXUS_VideoOutputSettings
60 *
61 * 68   7/19/11 11:14a erickson
62 * SW7408-291: add NEXUS_VideoOutput_SetVfFilter, requires reverse lookup
63 *  of DAC assignments
64 *
65 * 67   4/25/11 6:00p akam
66 * SWDTV-6275: Included build for 35233.
67 *
68 * 66   3/28/11 3:45p vsilyaev
69 * SW7335-1214: Added NEXUS_CallbackHandler framework
70 *
71 * 65   12/3/10 9:30a erickson
72 * SW7550-577: call BHDM_SetHdmiDataTransferMode based on
73 *  NEXUS_DisplayTimingGenerator_eHdmiDvo
74 *
75 * 64   12/2/10 8:14p spothana
76 * SW7420-1177: Adding nexus hdmi dvo module.
77 *
78 * SW7420-1177/2   11/5/10 3:28p spothana
79 * SW7420-1177: Display format changes require changes to HDMI rate
80 *  manager.
81 *
82 * SW7420-1177/1   11/1/10 8:48p spothana
83 * SW7420-1177: Adding nexus hdmi dvo module.
84 *
85 * 63   11/22/10 4:51p jhaberf
86 * SW35125-30: added rudimentary 35125 DTV chip support to nexus display
87 *
88 * 62   10/8/10 4:30p erickson
89 * SW7405-4782: merge
90 *
91 * SW7405-4782/2   10/7/10 12:04p vle
92 * SW7405-4782: Changing aspect ratio does not require HDCP re-
93 *  authentication - TAKE 2. First implementation attempt has a potential
94 *  race condition.
95 *
96 * SW7405-4782/1   9/10/10 8:42p vle
97 * SW7405-4782: Changing aspect ratio does not require HDCP re-
98 *  authentication.
99 *
100 * 61   2/23/10 5:16p petlee
101 * SW35230-18: Add check for BCHP_CHIP for 35230
102 *
103 * 60   1/25/10 4:43p erickson
104 * SW7405-3486: implement NEXUS_HdmiOutputSettings.syncOnly
105 *
106 * 59   12/21/09 4:07p erickson
107 * SW3556-935: VDC api change for spread spectrum
108 *
109 * 58   9/17/09 4:10p erickson
110 * SW7405-3033: back out last change. fix datatype instead.
111 *
112 * 56   9/4/09 5:03p jtna
113 * SW7405-2962: notify display on hotplug even if HDMI cable initially
114 *  unplugged
115 *
116 * 55   9/1/09 3:58p gmohile
117 * SW7403-869 : Fix mpaa mode for 7403
118 *
119 * 54   8/28/09 9:36a gmohile
120 * SW7403-796 : Add legacy vdc support
121 *
122 * 53   8/21/09 1:23p gmohile
123 * PR 57813: Merge legacy vdc support to mainline
124 *
125 * 52   7/15/09 1:40p erickson
126 * PR56609: merge
127 *
128 * PR56609/1   7/15/09 11:34a rgreen
129 * PR56609: Add HDMI Spread Spectrum support
130 *
131 * 51   6/12/09 11:13a erickson
132 * PR55952: handle default aspect ratio for 1920x1080 display formats in a
133 *  consistent way
134 *
135 * 50   6/8/09 7:06a erickson
136 * PR55617: rename NEXUS_P_DisplayAspectRatio_ToMagnum
137 *
138 * 49   5/20/09 11:29a erickson
139 * PR55292: call NEXUS_VideoOutput_P_DestroyLink in
140 *  NEXUS_Display_RemoveOutput
141 *
142 * 48   5/14/09 9:02a erickson
143 * PR55101: add NEXUS_ComponentOutputSettings.dacs.RGB.noSync
144 *
145 * 47   5/4/09 3:40p erickson
146 * PR53373: merge HDMI 1.3a support
147 *
148 * PR53373_DeepColor/1   4/16/09 3:58p vle
149 * PR53373: Add HDMI 1.3a support, deep color, to Brutus/nexus
150 *
151 * 46   4/7/09 11:42a erickson
152 * PR53623: change #define to NEXUS_NUM_656_OUTPUTS
153 *
154 * 45   4/1/09 12:16p erickson
155 * PR53623: merge 656 output support
156 *
157 * PR53623/2   3/31/09 11:57a mward
158 * PR 53623: Dummy to prevent compiler warning.  Add call to
159 *  NEXUS_VideoOutput_P_OpenCcir656() in NEXUS_P_VideoOutput_Link().
160 *
161 * PR53623/1   3/31/09 10:07a mward
162 * PR 53623: 656 output support.
163 *
164 * 44   3/25/09 5:26p erickson
165 * PR52818: remove 656 bypass. not supported.
166 *
167 * 43   3/24/09 2:36p erickson
168 * PR52818: added 656 bypass
169 *
170 * 42   3/16/09 4:37p erickson
171 * PR53271: added manual colorSpace option to NEXUS_HdmiOutputSettings
172 *
173 * 41   3/11/09 9:56a erickson
174 * PR52991: fix IFD bypass enum. added comment for future ccir656 support.
175 *
176 * 40   3/10/09 9:35a erickson
177 * PR52991: changed NEXUS_CompositeOutputSettings.analogVideoDecoder to
178 *  more generic NEXUS_CompositeOutputSettings.inputBypass
179 *
180 * 39   3/9/09 11:09a jtna
181 * PR52387: added NEXUS_Rfm_P_FormatChange
182 *
183 * 38   2/20/09 11:43a erickson
184 * PR52347: fix settop
185 *
186 * 37   2/20/09 11:31a erickson
187 * PR52347: update connected outputs in SetSettings in a standard way
188 *
189 * 36   2/20/09 10:55a erickson
190 * PR52270: allow composite output for HD display format if
191 *  NEXUS_CompositeOutputSettings.analogVideoDecoder is set
192 *
193 * 35   12/18/08 3:23p erickson
194 * PR50501: fix DTV
195 *
196 * 34   12/17/08 11:40p erickson
197 * PR50501: refactor HdmiOutput to remove double BVDC_ApplyChanges and 400
198 *  msec wait on format change
199 *
200 * HDMI_TX_Plugfest11_200811/1   11/10/08 7:12p vle
201 * PR48842: Fix HDCP in BRUTUS. Make sure to report the status to Brutus
202 *  and restart HDCP authentication process on each format change.
203 *
204 * 33   11/17/08 12:28p erickson
205 * PR49203: ensure there are no unnecessary unguarded BVDC_ApplyChanges
206 *  calls in Nexus
207 *
208 * 32   9/16/08 5:14p erickson
209 * PR46850: fix warning, improve error check
210 *
211 * 31   9/12/08 10:43a erickson
212 * PR46850: improve DBG feedback if HDMI output is not connected. don't
213 *  raise false errors.
214 *
215 * 30   8/20/08 11:58a erickson
216 * PR45794: remove bad assert
217 *
218 * 29   8/19/08 12:22p erickson
219 * PR45794: clarify internal function names. add ASSERT's and comments.
220 *
221 * 28   8/14/08 5:25p katrep
222 * PR45674: Fix compiiler warning in kernel mode non debug builds
223 *
224 * 27   8/1/08 5:38p erickson
225 * PR45361: c89 fixes
226 *
227 * 26   7/7/08 3:19p erickson
228 * PR44452: closing video outputs should automatically remove them from
229 *  displays
230 *
231 * 25   6/25/08 11:44a erickson
232 * PR39453: moved xvYccEnabled to NEXUS_DisplaySettings
233 *
234 * 24   6/19/08 2:32p vsilyaev
235 * PR 40921: There is no component output on the 93556 platform
236 *
237 * 23   6/17/08 4:06p vsilyaev
238 * PR 40921: Added output portion of scart inputs
239 *
240 * 22   6/13/08 11:06a erickson
241 * PR43651: fix BDBG_MODULE
242 *
243 * 21   6/7/08 2:42p jgarrett
244 * PR 43318: Initial 3549 bringup
245 *
246 * 20   5/21/08 11:29a erickson
247 * PR42678: rename NEXUS_DvoOutput to NEXUS_PanelOutput
248 *
249 * 19   5/21/08 10:33a erickson
250 * PR42678: rename NEXUS_DvoOutput to NEXUS_PanelOutput
251 *
252 * 18   5/12/08 4:55p erickson
253 * PR39453: add NEXUS_HdmiOutputSettings.xvYccEnabled
254 *
255 * 17   5/12/08 4:09p erickson
256 * PR42628: free NEXUS_VideoOutput_P_Link when DisplayModule closes
257 *
258 * 16   5/1/08 10:14a erickson
259 * PR39453: fix check if CompositeOutput is already connected
260 *
261 * 15   4/30/08 5:12p erickson
262 * PR39453: fix check
263 *
264 * 14   4/30/08 4:34p erickson
265 * PR39453: fix static init
266 *
267 * 13   4/30/08 3:08p erickson
268 * PR39453: add 3548/3556 features
269 *
270 * 12   4/17/08 11:24a erickson
271 * PR40157: use BVDC_DacOutput_eGreen_NoSync if dacHSync is set for VGA
272 *  output mode
273 *
274 * 11   4/11/08 11:05a erickson
275 * PR40157: add HSync option to ComponentOutput for VGA output
276 *
277 * 10   4/3/08 12:11p erickson
278 * PR41302: add MPAA decimation
279 *
280 * 9   4/2/08 10:09a erickson
281 * PR41222: check rc
282 *
283 * 8   4/1/08 1:46p jgarrett
284 * PR 40606: Caching rate information for HDMI
285 *
286 * 7   3/20/08 6:15p rjlewis
287 * PR40352: type mismatch compile error under VxWorks.
288 *
289 * 6   2/20/08 1:35p erickson
290 * PR39405: added RFM output
291 *
292 * 5   2/19/08 3:00p erickson
293 * PR39737: fix malloc check
294 *
295 * 4   2/5/08 2:17p jgarrett
296 * PR 39017: Forcing connect/disconnect/formatChange to always return
297 *  success, even if device disconnected (HDMI)
298 *
299 * 3   2/1/08 5:25p jgarrett
300 * PR 39017: Adding HdmiOutput
301 *
302 * 2   1/21/08 3:50p erickson
303 * PR38862: added NEXUS_DisplayType_eLvds which is the default. use
304 * DisplayType to select DVO or LVDS.
305 *
306 * 1   1/18/08 2:20p jgarrett
307 * PR 38808: Merging to main branch
308 *
309 * Nexus_Devel/8   11/15/07 1:37p erickson
310 * PR37136: added Dvo
311 *
312 * Nexus_Devel/7   11/6/07 1:28p erickson
313 * PR36570: remove static
314 *
315 * Nexus_Devel/6   11/6/07 1:13p erickson
316 * PR36570: merge 3563
317 *
318 * Nexus_Devel/5   11/2/07 4:42p vsilyaev
319 * PR 36696: Used connector model for VideoInput's and VideoOutput's
320 *
321 * Nexus_Devel/4   10/4/07 1:09p vsilyaev
322 * PR 34662: Removed VideoOutputDesc
323 *
324 * Nexus_Devel/3   9/25/07 3:13p vsilyaev
325 * PR 34662: Fixed video output
326 *
327 * Nexus_Devel/2   9/25/07 1:02p vsilyaev
328 * PR 34662: Fixed file names
329 *
330 * Nexus_Devel/1   9/17/07 6:58p vsilyaev
331 * PR 34662: Implementation of display module
332 *
333 **************************************************************************/
334#include "nexus_base.h"
335#include "nexus_display_module.h"
336#if NEXUS_NUM_HDMI_OUTPUTS
337#include "nexus_hdmi_output_hdcp.h"
338#endif
339BDBG_MODULE(nexus_video_output);
340
341#if NEXUS_NUM_RFM_OUTPUTS
342#include "priv/nexus_rfm_priv.h"
343#endif
344
345BDBG_OBJECT_ID(NEXUS_ComponentOutput);
346BDBG_OBJECT_ID(NEXUS_CompositeOutput);
347BDBG_OBJECT_ID(NEXUS_SvideoOutput);
348BDBG_OBJECT_ID(NEXUS_Ccir656Output);
349
350static const NEXUS_SvideoOutputSettings NEXUS_SvideoOutputDefaultSettings = {
351    NEXUS_VideoDac_eNone,
352    NEXUS_VideoDac_eNone
353};
354
355static const NEXUS_CompositeOutputSettings NEXUS_CompositeOutputDefaultSettings = {
356    NEXUS_VideoDac_eNone
357};
358
359static const NEXUS_Ccir656OutputSettings NEXUS_Ccir656OutputDefaultSettings = {
360    {0}
361};
362
363static BERR_Code NEXUS_ComponentOutput_P_Connect(void *output,  NEXUS_DisplayHandle display);
364static BERR_Code NEXUS_CompositeOutput_P_Connect(void *output,  NEXUS_DisplayHandle display);
365static BERR_Code NEXUS_SvideoOutput_P_Connect(void *output,  NEXUS_DisplayHandle display);
366static BERR_Code NEXUS_Ccir656Output_P_Connect(void *output,  NEXUS_DisplayHandle display);
367
368void
369NEXUS_VideoOutputs_P_Init(void)
370{
371    NEXUS_DisplayModule_State *state = &g_NEXUS_DisplayModule_State;
372    unsigned i;
373    BSTD_UNUSED(i);
374    BSTD_UNUSED(state);
375#if NEXUS_NUM_COMPONENT_OUTPUTS
376    for(i=0;i<sizeof(state->outputs.component)/sizeof(state->outputs.component[0]);i++) {
377        BDBG_OBJECT_INIT(&state->outputs.component[i], NEXUS_ComponentOutput);
378        NEXUS_ComponentOutput_GetDefaultSettings(&state->outputs.component[i].cfg);
379        state->outputs.component[i].opened = false;
380        NEXUS_VIDEO_OUTPUT_INIT(&state->outputs.component[i].output, NEXUS_VideoOutputType_eComponent, &state->outputs.component[i]);
381    }
382#endif
383#if NEXUS_NUM_COMPOSITE_OUTPUTS
384    for(i=0;i<sizeof(state->outputs.composite)/sizeof(state->outputs.composite[0]);i++) {
385        BDBG_OBJECT_INIT(&state->outputs.composite[i], NEXUS_CompositeOutput);
386        state->outputs.composite[i].cfg = NEXUS_CompositeOutputDefaultSettings;
387        state->outputs.composite[i].opened = false;
388        state->outputs.composite[i].dacOutputType = BVDC_DacOutput_eComposite;
389        NEXUS_VIDEO_OUTPUT_INIT(&state->outputs.composite[i].output, NEXUS_VideoOutputType_eComposite, &state->outputs.composite[i]);
390    }
391#endif
392#if NEXUS_NUM_SVIDEO_OUTPUTS
393    for(i=0;i<sizeof(state->outputs.svideo)/sizeof(state->outputs.svideo[0]);i++) {
394        BDBG_OBJECT_INIT(&state->outputs.svideo[i], NEXUS_SvideoOutput);
395        state->outputs.svideo[i].cfg = NEXUS_SvideoOutputDefaultSettings;
396        state->outputs.svideo[i].opened = false;
397        NEXUS_VIDEO_OUTPUT_INIT(&state->outputs.svideo[i].output, NEXUS_VideoOutputType_eSvideo, &state->outputs.svideo[i]);
398    }
399#endif
400#if NEXUS_NUM_656_OUTPUTS
401    for(i=0;i<sizeof(state->outputs.ccir656)/sizeof(state->outputs.ccir656[0]);i++) {
402        BDBG_OBJECT_INIT(&state->outputs.ccir656[i], NEXUS_Ccir656Output);
403        state->outputs.ccir656[i].cfg = NEXUS_Ccir656OutputDefaultSettings;
404        state->outputs.ccir656[i].opened = false;
405        NEXUS_VIDEO_OUTPUT_INIT(&state->outputs.ccir656[i].output, NEXUS_VideoOutputType_eCcir656, &state->outputs.ccir656[i]);
406    }
407#endif
408    return;
409}
410#if NEXUS_NUM_HDMI_DVO
411
412#if NEXUS_NUM_HDMI_DVO > 1
413#error Currently, only one HDMI output is supported
414#endif
415
416#include "nexus_hdmi_dvo.h"
417#include "priv/nexus_hdmi_dvo_priv.h"
418
419static void NEXUS_VideoOutput_P_HdmiDvoRateChange_isr(NEXUS_DisplayHandle display, void *pParam)
420{
421    NEXUS_HdmiDvoHandle hdmiDvo = pParam;
422    BDBG_ASSERT(NULL != hdmiDvo);
423    BDBG_MSG(("> NEXUS_VideoOutput_P_HdmiDvoRateChange_isr"));
424    NEXUS_HdmiDvo_VideoRateChange_isr(hdmiDvo, &display->hdmiDvo.rateInfo);
425    BDBG_MSG(("< NEXUS_VideoOutput_P_HdmiDvoRateChange_isr"));
426    return;
427}
428
429static BERR_Code NEXUS_VideoOutput_P_SetHdmiDvoFormat(void *output, NEXUS_DisplayHandle display, NEXUS_VideoFormat format, NEXUS_DisplayAspectRatio aspectRatio)
430{
431    BERR_Code rc;
432    NEXUS_HdmiDvoHandle hdmiDvo = output;
433    BFMT_VideoFmt videoFmt;
434#if NEXUS_HAS_HDMI_1_3
435    NEXUS_HdmiOutputSettings settings;
436    BAVC_HDMI_BitsPerPixel colorDepth;
437#endif
438    BDBG_MSG(("> NEXUS_VideoOutput_P_SetHdmiDvoFormat"));
439    BDBG_ASSERT(NULL != hdmiDvo); 
440
441    rc = NEXUS_P_VideoFormat_ToMagnum(format, &videoFmt);
442    if (rc) return BERR_TRACE(rc);
443
444    NEXUS_Module_Lock(g_NEXUS_DisplayModule_State.modules.hdmiDvo);
445    NEXUS_HdmiDvo_GetColorimetry_priv(hdmiDvo,&g_NEXUS_DisplayModule_State.hdmiDvo.colorimetry) ;
446    NEXUS_Module_Unlock(g_NEXUS_DisplayModule_State.modules.hdmiDvo);
447
448    /* Enable HDMI port in the VDC */
449    rc = BVDC_Display_SetHdmiConfiguration(display->displayVdc, BVDC_Hdmi_0, g_NEXUS_DisplayModule_State.hdmiDvo.colorimetry);
450    if (rc) return BERR_TRACE(rc);
451
452    /* Additional step to configure deep color mode */
453#if NEXUS_HAS_HDMI_1_3
454    /* Get color depth settings */
455    NEXUS_HdmiDvo_GetSettings(hdmiDvo, &settings);
456    colorDepth = NEXUS_P_HdmiDvoColorDepth_ToMagnum(settings.colorDepth);
457    rc = BVDC_Display_SetHdmiColorDepth(display->displayVdc, colorDepth);
458    if (rc) return BERR_TRACE(rc);
459#endif
460
461    NEXUS_HdmiDvo_SetDisplayParams_priv(hdmiDvo,videoFmt,g_NEXUS_DisplayModule_State.hdmiDvo.colorimetry,aspectRatio);
462    BVDC_ApplyChanges(g_NEXUS_DisplayModule_State.vdc);
463    g_NEXUS_DisplayModule_State.hdmiDvo.display = display;
464    g_NEXUS_DisplayModule_State.hdmiDvo.hdmiDvo = hdmiDvo;
465    g_NEXUS_DisplayModule_State.hdmiDvo.aspectRatio = aspectRatio;
466    g_NEXUS_DisplayModule_State.hdmiDvo.format = format;
467    BDBG_MSG(("< NEXUS_VideoOutput_P_SetHdmiDvoFormat"));
468    return 0;
469}
470
471static NEXUS_Error NEXUS_VideoOutput_P_HdmiDvoFormatChange(void *output, NEXUS_DisplayHandle display, NEXUS_VideoFormat format, NEXUS_DisplayAspectRatio aspectRatio)
472{
473    NEXUS_Error errCode= NEXUS_SUCCESS;
474    BDBG_MSG(("> NEXUS_VideoOutput_P_HdmiDvoFormatChange"));
475    (void)NEXUS_VideoOutput_P_SetHdmiDvoFormat(output, display, format, aspectRatio);
476    BDBG_MSG(("< NEXUS_VideoOutput_P_HdmiDvoFormatChange"));
477    return errCode;
478}
479
480
481static NEXUS_Error NEXUS_HdmiDvo_P_Disconnect(void *output, NEXUS_DisplayHandle display)
482{
483    NEXUS_HdmiDvoHandle hdmiDvo=output;
484    NEXUS_Error rc=NEXUS_SUCCESS;
485    BDBG_MSG(("> NEXUS_HdmiDvo_P_Disconnect"));
486    BDBG_ASSERT(NULL != hdmiDvo);
487    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
488    BVDC_Display_SetHdmiConfiguration(display->displayVdc, BVDC_Hdmi_0,BAVC_MatrixCoefficients_eUnknown);
489    BDBG_MSG(("< NEXUS_HdmiDvo_P_Disconnect"));
490    return rc;
491}
492
493static NEXUS_Error NEXUS_HdmiDvo_P_Connect(void *output,  NEXUS_DisplayHandle display)
494{
495    NEXUS_Error rc=NEXUS_SUCCESS;
496    NEXUS_HdmiDvoHandle hdmiDvo=output;
497    BDBG_MSG(("> NEXUS_HdmiDvo_P_Connect"));
498    BDBG_ASSERT(NULL != hdmiDvo);
499    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
500    (void)NEXUS_VideoOutput_P_SetHdmiDvoFormat(output, display, display->cfg.format, NEXUS_Display_P_ConvertAspectRatio(display->cfg.aspectRatio, display->cfg.format));
501
502    BKNI_EnterCriticalSection();
503    BDBG_ASSERT(NULL == display->hdmiDvo.rateChangeCb_isr);
504    display->hdmiDvo.rateChangeCb_isr = NEXUS_VideoOutput_P_HdmiDvoRateChange_isr;
505    display->hdmiDvo.pCbParam = hdmiDvo;
506    if ( display->hdmiDvo.rateInfoValid )
507    {
508        NEXUS_VideoOutput_P_HdmiDvoRateChange_isr(display, hdmiDvo);
509    }
510    BKNI_LeaveCriticalSection();
511    BDBG_MSG(("< NEXUS_HdmiDvo_P_Connect"));
512    return rc;
513}
514
515static NEXUS_VideoOutput_P_Link *
516NEXUS_VideoOutput_P_OpenHdmiDvo(NEXUS_VideoOutput output)
517{
518    NEXUS_VideoOutput_P_Link *link;
519    NEXUS_VideoOutput_P_Iface iface;
520    BDBG_MSG(("> NEXUS_VideoOutput_P_OpenHdmiDvo"));
521    BDBG_OBJECT_ASSERT(output, NEXUS_VideoOutput);
522    BDBG_ASSERT(output->type == NEXUS_VideoOutputType_eHdmiDvo);
523    iface.connect = NEXUS_HdmiDvo_P_Connect;
524    iface.disconnect = NEXUS_HdmiDvo_P_Disconnect;
525    iface.formatChange = NEXUS_VideoOutput_P_HdmiDvoFormatChange;
526    BDBG_MSG(("< NEXUS_VideoOutput_P_OpenHdmiDvo"));
527    link = NEXUS_VideoOutput_P_CreateLink(output, &iface, false);
528    if (link) {
529        link->displayOutput = BVDC_DisplayOutput_eDvo;
530    }
531    return link;
532}
533
534#endif
535
536void
537NEXUS_ComponentOutput_GetDefaultSettings(NEXUS_ComponentOutputSettings *pSettings)
538{
539    BKNI_Memset(pSettings, 0, sizeof(*pSettings));
540    pSettings->type = NEXUS_ComponentOutputType_eYPrPb;
541}
542
543NEXUS_ComponentOutputHandle
544NEXUS_ComponentOutput_Open(unsigned index, const NEXUS_ComponentOutputSettings *cfg)
545{
546    BERR_Code rc;
547#if NEXUS_NUM_COMPONENT_OUTPUTS
548    NEXUS_ComponentOutputHandle output;
549    NEXUS_DisplayModule_State *state = &g_NEXUS_DisplayModule_State;
550    NEXUS_ComponentOutputSettings defaultSettings;
551
552    BSTD_UNUSED(rc);
553
554    if(!cfg) {
555        NEXUS_ComponentOutput_GetDefaultSettings(&defaultSettings);
556        cfg = &defaultSettings;
557    }
558    if(index>=sizeof(state->outputs.component)/sizeof(state->outputs.component[0])) {
559        rc = BERR_TRACE(BERR_INVALID_PARAMETER);
560        return NULL;
561    }
562    output = &state->outputs.component[index];
563    if(output->opened) {
564        rc = BERR_TRACE(BERR_INVALID_PARAMETER);
565        return NULL;
566    }
567    output->opened = true;
568    output->index = index;
569    output->cfg = *cfg;
570    BDBG_OBJECT_SET(output, NEXUS_ComponentOutput);
571    return output;
572#else
573    BSTD_UNUSED(index);
574    BSTD_UNUSED(cfg);
575    rc = BERR_TRACE(BERR_INVALID_PARAMETER);
576    return NULL;
577#endif
578}
579
580void
581NEXUS_ComponentOutput_Close(NEXUS_ComponentOutputHandle output)
582{
583    NEXUS_DisplayHandle display;
584    BDBG_OBJECT_ASSERT(output, NEXUS_ComponentOutput);
585
586    /* auto-remove from any Display */
587    display = NEXUS_VideoOutput_P_GetDisplay(&output->output);
588    if (display) {
589        NEXUS_Display_RemoveOutput(display, &output->output);
590    }
591
592    BDBG_OBJECT_UNSET(output, NEXUS_ComponentOutput);
593    output->opened = false;
594    return;
595}
596
597NEXUS_VideoOutput
598NEXUS_ComponentOutput_GetConnector(NEXUS_ComponentOutputHandle output)
599{
600    BDBG_OBJECT_ASSERT(output, NEXUS_ComponentOutput);
601    return &output->output;
602}
603
604void
605NEXUS_ComponentOutput_GetSettings(NEXUS_ComponentOutputHandle output,  NEXUS_ComponentOutputSettings *pSettings)
606{
607    BDBG_OBJECT_ASSERT(output, NEXUS_ComponentOutput);
608    BDBG_ASSERT(pSettings);
609    *pSettings = output->cfg;
610    return;
611}
612
613NEXUS_Error
614NEXUS_ComponentOutput_SetSettings(NEXUS_ComponentOutputHandle output, const NEXUS_ComponentOutputSettings *pSettings)
615{
616    BDBG_OBJECT_ASSERT(output, NEXUS_ComponentOutput);
617    output->cfg = *pSettings;
618    if (output->output.destination) {
619        NEXUS_Error rc;
620        NEXUS_VideoOutput_P_Link *link = output->output.destination;
621        BDBG_OBJECT_ASSERT(link->display, NEXUS_Display);
622        rc = NEXUS_ComponentOutput_P_Connect(output, link->display);
623        if (rc) return BERR_TRACE(rc);
624        rc = NEXUS_Display_P_ApplyChanges();
625        if (rc) return BERR_TRACE(rc);
626    }
627    return BERR_SUCCESS;
628}
629
630void
631NEXUS_SvideoOutput_GetDefaultSettings(NEXUS_SvideoOutputSettings *pSettings)
632{
633    BDBG_ASSERT(pSettings);
634    *pSettings = NEXUS_SvideoOutputDefaultSettings;
635    return;
636}
637
638
639
640NEXUS_SvideoOutputHandle
641NEXUS_SvideoOutput_Open(unsigned index, const NEXUS_SvideoOutputSettings *cfg)
642{
643    BERR_Code rc;
644#if NEXUS_NUM_SVIDEO_OUTPUTS
645    NEXUS_SvideoOutputHandle  output;
646    NEXUS_DisplayModule_State *state = &g_NEXUS_DisplayModule_State;
647    BSTD_UNUSED(rc);
648
649    if(!cfg) {
650        cfg  = &NEXUS_SvideoOutputDefaultSettings;
651    }
652    if(index>=sizeof(state->outputs.svideo)/sizeof(state->outputs.svideo[0])) {
653        rc = BERR_TRACE(BERR_INVALID_PARAMETER);
654        return NULL;
655    }
656    output = &state->outputs.svideo[index];
657    if(output->opened) {
658        rc = BERR_TRACE(BERR_INVALID_PARAMETER);
659        return NULL;
660    }
661    output->opened = true;
662    output->cfg = *cfg;
663    BDBG_OBJECT_SET(output, NEXUS_SvideoOutput);
664    return output;
665#else
666    BSTD_UNUSED(index);
667    BSTD_UNUSED(cfg);
668    rc = BERR_TRACE(BERR_INVALID_PARAMETER);
669    return NULL;
670#endif
671}
672
673void
674NEXUS_SvideoOutput_Close(NEXUS_SvideoOutputHandle output)
675{
676    NEXUS_DisplayHandle display;
677    BDBG_OBJECT_ASSERT(output, NEXUS_SvideoOutput);
678
679    /* auto-remove from any Display */
680    display = NEXUS_VideoOutput_P_GetDisplay(&output->output);
681    if (display) {
682        NEXUS_Display_RemoveOutput(display, &output->output);
683    }
684
685    BDBG_OBJECT_UNSET(output, NEXUS_SvideoOutput);
686    output->opened = false;
687    return;
688}
689
690NEXUS_VideoOutput
691NEXUS_SvideoOutput_GetConnector(NEXUS_SvideoOutputHandle output)
692{
693    BDBG_OBJECT_ASSERT(output, NEXUS_SvideoOutput);
694    return &output->output;
695}
696
697void
698NEXUS_SvideoOutput_GetSettings(NEXUS_SvideoOutputHandle output,  NEXUS_SvideoOutputSettings *pSettings)
699{
700    BDBG_OBJECT_ASSERT(output, NEXUS_SvideoOutput);
701    BDBG_ASSERT(pSettings);
702    *pSettings = output->cfg;
703    return;
704}
705
706NEXUS_Error
707NEXUS_SvideoOutput_SetSettings(NEXUS_SvideoOutputHandle output, const NEXUS_SvideoOutputSettings *pSettings)
708{
709    BDBG_OBJECT_ASSERT(output, NEXUS_SvideoOutput);
710    output->cfg = *pSettings;
711    if (output->output.destination) {
712        NEXUS_Error rc;
713        NEXUS_VideoOutput_P_Link *link = output->output.destination;
714        BDBG_OBJECT_ASSERT(link->display, NEXUS_Display);
715        rc = NEXUS_SvideoOutput_P_Connect(output, link->display);
716        if (rc) return BERR_TRACE(rc);
717        rc = NEXUS_Display_P_ApplyChanges();
718        if (rc) return BERR_TRACE(rc);
719    }
720    return BERR_SUCCESS;
721}
722
723void
724NEXUS_CompositeOutput_GetDefaultSettings(NEXUS_CompositeOutputSettings *pSettings)
725{
726    BDBG_ASSERT(pSettings);
727    *pSettings = NEXUS_CompositeOutputDefaultSettings;
728    return;
729}
730
731
732NEXUS_CompositeOutputHandle
733NEXUS_CompositeOutput_Open(unsigned index, const NEXUS_CompositeOutputSettings *cfg)
734{
735    BERR_Code rc;
736#if NEXUS_NUM_COMPOSITE_OUTPUTS
737    NEXUS_CompositeOutputHandle  output;
738    NEXUS_DisplayModule_State *state = &g_NEXUS_DisplayModule_State;
739    BSTD_UNUSED(rc);
740
741    if(!cfg) {
742        cfg  = &NEXUS_CompositeOutputDefaultSettings;
743    }
744    if(index>=sizeof(state->outputs.composite)/sizeof(state->outputs.composite[0])) {
745        rc = BERR_TRACE(BERR_INVALID_PARAMETER);
746        return NULL;
747    }
748    output = &state->outputs.composite[index];
749    if(output->opened) {
750        rc = BERR_TRACE(BERR_INVALID_PARAMETER);
751        return NULL;
752    }
753    output->opened = true;
754    output->cfg = *cfg;
755    BDBG_OBJECT_SET(output, NEXUS_CompositeOutput);
756    return output;
757#else
758    BSTD_UNUSED(index);
759    BSTD_UNUSED(cfg);
760    rc = BERR_TRACE(BERR_INVALID_PARAMETER);
761    return NULL;
762#endif
763}
764
765void
766NEXUS_CompositeOutput_Close(NEXUS_CompositeOutputHandle output)
767{
768    NEXUS_DisplayHandle display;
769    BDBG_OBJECT_ASSERT(output, NEXUS_CompositeOutput);
770
771    /* auto-remove from any Display */
772    display = NEXUS_VideoOutput_P_GetDisplay(&output->output);
773    if (display) {
774        NEXUS_Display_RemoveOutput(display, &output->output);
775    }
776
777    BDBG_OBJECT_UNSET(output, NEXUS_CompositeOutput);
778    output->opened = false;
779    return;
780}
781
782NEXUS_VideoOutput
783NEXUS_CompositeOutput_GetConnector(NEXUS_CompositeOutputHandle output)
784{
785    BDBG_OBJECT_ASSERT(output, NEXUS_CompositeOutput);
786    return &output->output;
787}
788
789void
790NEXUS_CompositeOutput_GetSettings(NEXUS_CompositeOutputHandle output,  NEXUS_CompositeOutputSettings *pSettings)
791{
792    BDBG_OBJECT_ASSERT(output, NEXUS_CompositeOutput);
793    BDBG_ASSERT(pSettings);
794    *pSettings = output->cfg;
795    return;
796}
797
798NEXUS_Error
799NEXUS_CompositeOutput_SetSettings(NEXUS_CompositeOutputHandle output, const NEXUS_CompositeOutputSettings *pSettings)
800{
801    BDBG_OBJECT_ASSERT(output, NEXUS_CompositeOutput);
802    output->cfg = *pSettings;
803    if (output->output.destination) {
804        NEXUS_Error rc;
805        NEXUS_VideoOutput_P_Link *link = output->output.destination;
806        BDBG_OBJECT_ASSERT(link->display, NEXUS_Display);
807        rc = NEXUS_CompositeOutput_P_Connect(output, link->display);
808        if (rc) return BERR_TRACE(rc);
809        rc = NEXUS_Display_P_ApplyChanges();
810        if (rc) return BERR_TRACE(rc);
811    }
812    return BERR_SUCCESS;
813}
814
815void
816NEXUS_Ccir656Output_GetDefaultSettings(NEXUS_Ccir656OutputSettings *pSettings)
817{
818    BDBG_ASSERT(pSettings);
819    *pSettings = NEXUS_Ccir656OutputDefaultSettings;
820    return;
821}
822
823
824NEXUS_Ccir656OutputHandle
825NEXUS_Ccir656Output_Open(unsigned index, const NEXUS_Ccir656OutputSettings *cfg)
826{
827    BERR_Code rc;
828#if NEXUS_NUM_656_OUTPUTS
829    NEXUS_Ccir656OutputHandle  output;
830    NEXUS_DisplayModule_State *state = &g_NEXUS_DisplayModule_State;
831    BSTD_UNUSED(rc);
832
833    if(!cfg) {
834        cfg  = &NEXUS_Ccir656OutputDefaultSettings;
835    }
836    if(index>=sizeof(state->outputs.ccir656)/sizeof(state->outputs.ccir656[0])) {
837        rc = BERR_TRACE(BERR_INVALID_PARAMETER);
838        return NULL;
839    }
840    output = &state->outputs.ccir656[index];
841    if(output->opened) {
842        rc = BERR_TRACE(BERR_INVALID_PARAMETER);
843        return NULL;
844    }
845    output->opened = true;
846    output->cfg = *cfg;
847    BDBG_OBJECT_SET(output, NEXUS_Ccir656Output);
848    return output;
849#else
850    BSTD_UNUSED(index);
851    BSTD_UNUSED(cfg);
852    rc = BERR_TRACE(BERR_INVALID_PARAMETER);
853    return NULL;
854#endif
855}
856
857void
858NEXUS_Ccir656Output_Close(NEXUS_Ccir656OutputHandle output)
859{
860    NEXUS_DisplayHandle display;
861    BDBG_OBJECT_ASSERT(output, NEXUS_Ccir656Output);
862
863    /* auto-remove from any Display */
864    display = NEXUS_VideoOutput_P_GetDisplay(&output->output);
865    if (display) {
866        NEXUS_Display_RemoveOutput(display, &output->output);
867    }
868
869    BDBG_OBJECT_UNSET(output, NEXUS_Ccir656Output);
870    output->opened = false;
871    return;
872}
873
874NEXUS_VideoOutput
875NEXUS_Ccir656Output_GetConnector(NEXUS_Ccir656OutputHandle output)
876{
877    BDBG_OBJECT_ASSERT(output, NEXUS_Ccir656Output);
878    return &output->output;
879}
880
881void
882NEXUS_Ccir656Output_GetSettings(NEXUS_Ccir656OutputHandle output,  NEXUS_Ccir656OutputSettings *pSettings)
883{
884    BDBG_OBJECT_ASSERT(output, NEXUS_Ccir656Output);
885    BDBG_ASSERT(pSettings);
886    *pSettings = output->cfg;
887    return;
888}
889
890NEXUS_Error
891NEXUS_Ccir656Output_SetSettings(NEXUS_Ccir656OutputHandle output, const NEXUS_Ccir656OutputSettings *pSettings)
892{
893    BDBG_OBJECT_ASSERT(output, NEXUS_Ccir656Output);
894    output->cfg = *pSettings;
895    if (output->output.destination) {
896        NEXUS_Error rc;
897        NEXUS_VideoOutput_P_Link *link = output->output.destination;
898        BDBG_OBJECT_ASSERT(link->display, NEXUS_Display);
899        rc = NEXUS_Ccir656Output_P_Connect(output, link->display);
900        if (rc) return BERR_TRACE(rc);
901        rc = NEXUS_Display_P_ApplyChanges();
902        if (rc) return BERR_TRACE(rc);
903    }
904    return BERR_SUCCESS;
905}
906
907BDBG_OBJECT_ID(NEXUS_VideoOutput_P_Link);
908
909BERR_Code
910NEXUS_VideoOutput_P_SetDac(NEXUS_VideoOutput_P_Link *link, BVDC_Display_Handle display, NEXUS_VideoDac dac, BVDC_DacOutput type)
911{
912    uint32_t dacVdc;
913    BERR_Code rc;
914    switch(dac) {
915    default:
916    case NEXUS_VideoDac_eNone:
917        return BERR_TRACE(BERR_INVALID_PARAMETER);
918    case NEXUS_VideoDac_e0:
919        dacVdc = BVDC_Dac_0;
920        break;
921    case NEXUS_VideoDac_e1:
922        dacVdc = BVDC_Dac_1;
923        break;
924    case NEXUS_VideoDac_e2:
925        dacVdc = BVDC_Dac_2;
926        break;
927    case NEXUS_VideoDac_e3:
928        dacVdc = BVDC_Dac_3;
929        break;
930    case NEXUS_VideoDac_e4:
931        dacVdc = BVDC_Dac_4;
932        break;
933    case NEXUS_VideoDac_e5:
934        dacVdc = BVDC_Dac_5;
935        break;
936    case NEXUS_VideoDac_e6:
937        dacVdc = BVDC_Dac_6;
938        break;
939    }
940   
941    /* store DAC assignment for reverse lookup */
942    link->channel[dac - NEXUS_VideoDac_e0] = type;
943   
944    rc = BVDC_Display_SetDacConfiguration(display, dacVdc, type);
945    if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); }
946    return rc;
947}
948
949static BERR_Code
950NEXUS_CompositeOutput_P_Connect(void *output, NEXUS_DisplayHandle display)
951{
952    NEXUS_CompositeOutputHandle composite=output;
953    BERR_Code rc;
954    NEXUS_VideoOutput_P_Link *link;
955
956    BDBG_OBJECT_ASSERT(composite, NEXUS_CompositeOutput);
957    link = composite->output.destination;
958
959    rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, composite->cfg.dac, composite->dacOutputType);
960    if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); }
961    return rc;
962}
963
964static BERR_Code
965NEXUS_CompositeOutput_P_Disconnect(void *output, NEXUS_DisplayHandle display)
966{
967    BERR_Code rc;
968    NEXUS_CompositeOutputHandle composite = output;
969    NEXUS_VideoOutput_P_Link *link;
970
971    BDBG_OBJECT_ASSERT(composite, NEXUS_CompositeOutput);
972    link = composite->output.destination;
973   
974    rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, composite->cfg.dac, BVDC_DacOutput_eUnused);
975    if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); }
976    return rc;
977}
978
979static BERR_Code
980NEXUS_SvideoOutput_P_Connect(void *output,  NEXUS_DisplayHandle display)
981{
982    BERR_Code rc;
983    NEXUS_SvideoOutputHandle svideo=output;
984    NEXUS_VideoOutput_P_Link *link;
985
986    BDBG_OBJECT_ASSERT(svideo, NEXUS_SvideoOutput);
987    link = svideo->output.destination;
988   
989    rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, svideo->cfg.dacY, BVDC_DacOutput_eSVideo_Luma);
990    if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); goto err_dac; }
991    rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, svideo->cfg.dacC, BVDC_DacOutput_eSVideo_Chroma);
992    if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); goto err_dac; }
993err_dac:
994    return rc;
995}
996
997static BERR_Code
998NEXUS_SvideoOutput_P_Disconnect(void *output, NEXUS_DisplayHandle display)
999{
1000    NEXUS_SvideoOutputHandle svideo=output;
1001    BERR_Code rc;
1002    NEXUS_VideoOutput_P_Link *link;
1003
1004    BDBG_OBJECT_ASSERT(svideo, NEXUS_SvideoOutput);
1005    link = svideo->output.destination;
1006
1007    rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, svideo->cfg.dacY, BVDC_DacOutput_eUnused);
1008    if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); goto err_dac; }
1009    rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, svideo->cfg.dacC, BVDC_DacOutput_eUnused);
1010    if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); goto err_dac; }
1011err_dac:
1012    return rc;
1013}
1014
1015static BERR_Code
1016NEXUS_ComponentOutput_P_Connect(void *output, NEXUS_DisplayHandle display)
1017{
1018    NEXUS_ComponentOutputHandle component=output;
1019    BERR_Code rc;
1020    NEXUS_VideoOutput_P_Link *link;
1021
1022    BDBG_OBJECT_ASSERT(component, NEXUS_ComponentOutput);
1023    link = component->output.destination;
1024
1025    switch(component->cfg.type) {
1026    case NEXUS_ComponentOutputType_eYPrPb:
1027        rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, component->cfg.dacs.YPrPb.dacY, BVDC_DacOutput_eY);
1028        if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); goto err_dac; }
1029        rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, component->cfg.dacs.YPrPb.dacPr, BVDC_DacOutput_ePr);
1030        if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); goto err_dac; }
1031        rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, component->cfg.dacs.YPrPb.dacPb, BVDC_DacOutput_ePb);
1032        if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); goto err_dac; }
1033        break;
1034    case NEXUS_ComponentOutputType_eRGB:
1035        rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, component->cfg.dacs.RGB.dacGreen,
1036            (component->cfg.dacs.RGB.dacHSync != NEXUS_VideoDac_eNone || component->cfg.dacs.RGB.noSync) ? BVDC_DacOutput_eGreen_NoSync : BVDC_DacOutput_eGreen);
1037        if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); goto err_dac; }
1038        rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, component->cfg.dacs.RGB.dacRed, BVDC_DacOutput_eRed);
1039        if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); goto err_dac; }
1040        rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, component->cfg.dacs.RGB.dacBlue, BVDC_DacOutput_eBlue);
1041        if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); goto err_dac; }
1042        if (component->cfg.dacs.RGB.dacHSync != NEXUS_VideoDac_eNone && !component->cfg.dacs.RGB.noSync) {
1043            rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, component->cfg.dacs.RGB.dacHSync, BVDC_DacOutput_eHsync);
1044            if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); goto err_dac; }
1045        }
1046        break;
1047    default:
1048        rc = BERR_TRACE(BERR_INVALID_PARAMETER);
1049        goto err_dac;
1050    }
1051#if B_HAS_LEGACY_VDC || BCHP_CHIP == 7403
1052    if (display->cfg.format != NEXUS_VideoFormat_e1080i &&
1053            display->cfg.format != NEXUS_VideoFormat_e720p)
1054      component->cfg.mpaaDecimationEnabled = false;
1055#endif
1056    rc = BVDC_Display_SetMpaaDecimation(display->displayVdc, BVDC_MpaaDeciIf_eComponent, 1 << component->index, component->cfg.mpaaDecimationEnabled);
1057    if (rc) return BERR_TRACE(rc);
1058
1059err_dac:
1060    return rc;
1061}
1062
1063
1064static BERR_Code
1065NEXUS_ComponentOutput_P_Disconnect(void *output, NEXUS_DisplayHandle display)
1066{
1067    NEXUS_ComponentOutputHandle component=output;
1068    BERR_Code rc;
1069    NEXUS_VideoOutput_P_Link *link;
1070
1071    BDBG_OBJECT_ASSERT(component, NEXUS_ComponentOutput);
1072    link = component->output.destination;
1073
1074    switch(component->cfg.type) {
1075    case NEXUS_ComponentOutputType_eYPrPb:
1076        rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, component->cfg.dacs.YPrPb.dacY, BVDC_DacOutput_eUnused);
1077        if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); goto err_dac; }
1078        rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, component->cfg.dacs.YPrPb.dacPr, BVDC_DacOutput_eUnused);
1079        if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); goto err_dac; }
1080        rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, component->cfg.dacs.YPrPb.dacPb, BVDC_DacOutput_eUnused);
1081        if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); goto err_dac; }
1082        break;
1083    case NEXUS_ComponentOutputType_eRGB:
1084        rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, component->cfg.dacs.RGB.dacGreen, BVDC_DacOutput_eUnused);
1085        if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); goto err_dac; }
1086        rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, component->cfg.dacs.RGB.dacRed, BVDC_DacOutput_eUnused);
1087        if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); goto err_dac; }
1088        rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, component->cfg.dacs.RGB.dacBlue, BVDC_DacOutput_eUnused);
1089        if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); goto err_dac; }
1090        if (component->cfg.dacs.RGB.dacHSync != NEXUS_VideoDac_eNone) {
1091            rc = NEXUS_VideoOutput_P_SetDac(link, display->displayVdc, component->cfg.dacs.RGB.dacHSync, BVDC_DacOutput_eUnused);
1092            if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); goto err_dac; }
1093        }
1094        break;
1095    default:
1096        rc = BERR_TRACE(BERR_INVALID_PARAMETER);
1097        goto err_dac;
1098    }
1099
1100err_dac:
1101    return rc;
1102}
1103
1104static BERR_Code
1105NEXUS_Ccir656Output_P_Connect(void *output,  NEXUS_DisplayHandle display)
1106{
1107    NEXUS_Ccir656OutputHandle ccir656=output;
1108    BERR_Code rc = BERR_SUCCESS;
1109
1110    BDBG_OBJECT_ASSERT(ccir656, NEXUS_Ccir656Output);
1111
1112    rc = BVDC_Display_Set656Configuration(display->displayVdc, BVDC_Itur656Output_0, true); /* enable 656 out */
1113    if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); }
1114
1115    return rc;
1116}
1117
1118#if NEXUS_NUM_656_OUTPUTS
1119static BERR_Code
1120NEXUS_Ccir656Output_P_Disconnect(void *output, NEXUS_DisplayHandle display)
1121{
1122    NEXUS_Ccir656OutputHandle ccir656=output;
1123    BERR_Code rc = BERR_SUCCESS;
1124
1125    BDBG_OBJECT_ASSERT(ccir656, NEXUS_Ccir656Output);
1126
1127    rc = BVDC_Display_Set656Configuration(display->displayVdc, BVDC_Itur656Output_0, false); /* disable 656 out */
1128    if(rc!=BERR_SUCCESS) { rc=BERR_TRACE(rc); }
1129
1130    return rc;
1131}
1132#endif
1133
1134NEXUS_VideoOutput_P_Link *
1135NEXUS_VideoOutput_P_CreateLink(NEXUS_VideoOutput output, const NEXUS_VideoOutput_P_Iface *iface, bool sdOnly)
1136{
1137    NEXUS_VideoOutput_P_Link *link;
1138    unsigned i;
1139
1140    BDBG_OBJECT_ASSERT(output, NEXUS_VideoOutput);
1141    BDBG_ASSERT(iface);
1142
1143    link = BKNI_Malloc(sizeof(*link));
1144    if(!link) {
1145        BERR_Code rc = BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
1146        BSTD_UNUSED(rc);
1147        goto err_alloc;
1148    }
1149    BDBG_OBJECT_INIT(link, NEXUS_VideoOutput_P_Link);
1150    link->iface = *iface;
1151    link->output = output;
1152    link->display = NULL;
1153    link->sdOnly = sdOnly;
1154    link->displayOutput = 0; /* no unknown value */
1155    for (i=0;i<NEXUS_VideoDac_eMax;i++) {
1156        link->channel[i] = BVDC_DacOutput_eUnused;
1157    }
1158    output->destination = link;
1159    return link;
1160err_alloc:
1161    return NULL;
1162}
1163
1164/* this function is called from NEXUS_Display_Close and removes the link from the list */
1165void
1166NEXUS_VideoOutput_P_DestroyLink(NEXUS_VideoOutput_P_Link *link)
1167{
1168    BDBG_OBJECT_DESTROY(link, NEXUS_VideoOutput_P_Link);
1169    BKNI_Free(link);
1170}
1171
1172static NEXUS_VideoOutput_P_Link *
1173NEXUS_VideoOutput_P_OpenComposite(NEXUS_VideoOutput output)
1174{
1175    NEXUS_VideoOutput_P_Link *link;
1176    NEXUS_VideoOutput_P_Iface iface;
1177    NEXUS_CompositeOutputHandle compositeOutput = (NEXUS_CompositeOutputHandle)output->source;
1178
1179    BDBG_OBJECT_ASSERT(compositeOutput, NEXUS_CompositeOutput);
1180    iface.connect = NEXUS_CompositeOutput_P_Connect;
1181    iface.disconnect = NEXUS_CompositeOutput_P_Disconnect;
1182    iface.formatChange = NULL;
1183    link = NEXUS_VideoOutput_P_CreateLink(output, &iface, true);
1184    if (link) {
1185        link->displayOutput = BVDC_DisplayOutput_eComposite;
1186    }
1187    return link;
1188}
1189
1190static NEXUS_VideoOutput_P_Link *
1191NEXUS_VideoOutput_P_OpenSvideo(NEXUS_VideoOutput output)
1192{
1193    NEXUS_VideoOutput_P_Link *link;
1194    NEXUS_VideoOutput_P_Iface iface;
1195
1196    BDBG_OBJECT_ASSERT((NEXUS_SvideoOutputHandle)output->source, NEXUS_SvideoOutput);
1197    iface.connect = NEXUS_SvideoOutput_P_Connect;
1198    iface.disconnect = NEXUS_SvideoOutput_P_Disconnect;
1199    iface.formatChange = NULL;
1200    link = NEXUS_VideoOutput_P_CreateLink(output, &iface, true);
1201    if (link) {
1202        link->displayOutput = BVDC_DisplayOutput_eSVideo;
1203    }
1204    return link;
1205}
1206
1207static NEXUS_VideoOutput_P_Link *
1208NEXUS_VideoOutput_P_OpenComponent(NEXUS_VideoOutput output)
1209{
1210    NEXUS_VideoOutput_P_Link *link;
1211    NEXUS_VideoOutput_P_Iface iface;
1212
1213    BDBG_OBJECT_ASSERT((NEXUS_ComponentOutputHandle)output->source, NEXUS_ComponentOutput);
1214    iface.connect = NEXUS_ComponentOutput_P_Connect;
1215    iface.disconnect = NEXUS_ComponentOutput_P_Disconnect;
1216    iface.formatChange = NULL;
1217    link = NEXUS_VideoOutput_P_CreateLink(output, &iface, false);
1218    if (link) {
1219        link->displayOutput = BVDC_DisplayOutput_eComponent;
1220    }
1221    return link;
1222}
1223
1224#if NEXUS_NUM_656_OUTPUTS
1225static NEXUS_VideoOutput_P_Link *
1226NEXUS_VideoOutput_P_OpenCcir656(NEXUS_VideoOutput output)
1227{
1228    NEXUS_VideoOutput_P_Link *link;
1229    NEXUS_VideoOutput_P_Iface iface;
1230    BDBG_OBJECT_ASSERT((NEXUS_Ccir656OutputHandle)output->source, NEXUS_Ccir656Output);
1231    iface.connect = NEXUS_Ccir656Output_P_Connect;
1232    iface.disconnect = NEXUS_Ccir656Output_P_Disconnect;
1233    iface.formatChange = NULL;
1234    link = NEXUS_VideoOutput_P_CreateLink(output, &iface, false);
1235    if (link) {
1236        link->displayOutput = BVDC_DisplayOutput_e656;
1237    }
1238    return link;
1239}
1240#endif
1241
1242#if NEXUS_NUM_HDMI_OUTPUTS
1243
1244#if NEXUS_NUM_HDMI_OUTPUTS > 1
1245#error Currently, only one HDMI output is supported
1246#endif
1247
1248#include "nexus_hdmi_output.h"
1249#include "priv/nexus_hdmi_output_priv.h"
1250
1251static void
1252NEXUS_VideoOutput_P_HdmiRateChange_isr(NEXUS_DisplayHandle display, void *pParam)
1253{
1254    NEXUS_HdmiOutputHandle hdmi = pParam;
1255    BDBG_ASSERT(NULL != hdmi);
1256    NEXUS_HdmiOutput_VideoRateChange_isr(hdmi, &display->hdmi.rateInfo);
1257}
1258
1259void NEXUS_VideoOutput_P_SetHdmiSettings(void *context)
1260{
1261    BERR_Code rc;
1262    NEXUS_DisplayHandle display = (NEXUS_DisplayHandle)context;
1263    NEXUS_HdmiOutputHandle hdmiOutput = display->hdmi.outputNotify;
1264    NEXUS_HdmiOutputSettings settings;
1265    BFMT_VideoFmt videoFmt;
1266    BFMT_AspectRatio aspectRatioVdc;
1267#if NEXUS_HAS_HDMI_1_3
1268    BAVC_HDMI_BitsPerPixel colorDepth;
1269    NEXUS_Error errCode;
1270#endif
1271#if !B_HAS_LEGACY_VDC && BCHP_CHIP != 7403
1272    BVDC_Display_DvoSettings dvoSettings;
1273#endif
1274
1275    NEXUS_HdmiOutput_GetSettings(hdmiOutput, &settings);
1276
1277    (void)NEXUS_P_VideoFormat_ToMagnum(display->cfg.format, &videoFmt);
1278    (void)NEXUS_P_DisplayAspectRatio_ToMagnum(g_NEXUS_DisplayModule_State.hdmiOutput.aspectRatio, &aspectRatioVdc);
1279
1280    NEXUS_Module_Lock(g_NEXUS_DisplayModule_State.modules.hdmiOutput);
1281    /* NEXUS_HdmiOutput_GetColorimetry_priv returns bool for connected */
1282    rc = !NEXUS_HdmiOutput_GetColorimetry_priv(hdmiOutput, videoFmt, &g_NEXUS_DisplayModule_State.hdmiOutput.colorimetry);
1283    NEXUS_Module_Unlock(g_NEXUS_DisplayModule_State.modules.hdmiOutput);
1284    if (!rc) {
1285        rc = BVDC_Display_SetHdmiConfiguration(display->displayVdc, BVDC_Hdmi_0, g_NEXUS_DisplayModule_State.hdmiOutput.colorimetry);
1286        if (rc) {rc = BERR_TRACE(rc); goto done;}
1287    }
1288
1289    rc = BVDC_Display_SetHdmiSyncOnly(display->displayVdc, settings.syncOnly);
1290    if (rc) {rc = BERR_TRACE(rc); goto done;}
1291
1292#if B_HAS_LEGACY_VDC || BCHP_CHIP == 7403
1293    if (display->cfg.format != NEXUS_VideoFormat_e1080i &&
1294            display->cfg.format != NEXUS_VideoFormat_e720p)
1295      settings.mpaaDecimationEnabled = false;
1296#endif
1297    rc = BVDC_Display_SetMpaaDecimation(display->displayVdc, BVDC_MpaaDeciIf_eHdmi, 1, settings.mpaaDecimationEnabled);
1298    if (rc) {rc = BERR_TRACE(rc); goto done;}
1299
1300#if !B_HAS_LEGACY_VDC && BCHP_CHIP != 7403
1301    BVDC_Display_GetDvoConfiguration(display->displayVdc, &dvoSettings);
1302    dvoSettings.stSpreadSpectrum.bEnable = settings.spreadSpectrum.enable;
1303    dvoSettings.stSpreadSpectrum.ulFrequency  = settings.spreadSpectrum.frequency ;
1304    dvoSettings.stSpreadSpectrum.ulDelta = settings.spreadSpectrum.delta ;
1305    rc = BVDC_Display_SetDvoConfiguration(display->displayVdc, &dvoSettings);
1306    if (rc) {rc = BERR_TRACE(rc); goto done;}
1307#endif
1308
1309    /* set deep color mode in HDMI and VDC*/
1310#if NEXUS_HAS_HDMI_1_3
1311    NEXUS_Module_Lock(g_NEXUS_DisplayModule_State.modules.hdmiOutput);
1312    errCode = NEXUS_HdmiOutput_SetColorDepth_priv(hdmiOutput, settings.colorDepth);
1313    NEXUS_Module_Unlock(g_NEXUS_DisplayModule_State.modules.hdmiOutput);
1314    if (errCode) {errCode = BERR_TRACE(errCode); goto done;}
1315
1316    colorDepth = NEXUS_P_HdmiColorDepth_ToMagnum(settings.colorDepth);
1317    rc = BVDC_Display_SetHdmiColorDepth(display->displayVdc, colorDepth);
1318    if (rc) {rc = BERR_TRACE(rc); goto done;}
1319#endif
1320
1321    rc = BVDC_ApplyChanges(g_NEXUS_DisplayModule_State.vdc);
1322    if (rc) {rc = BERR_TRACE(rc); goto done;}
1323
1324    NEXUS_Module_Lock(g_NEXUS_DisplayModule_State.modules.hdmiOutput);
1325    (void)NEXUS_HdmiOutput_SetDisplayParams_priv(hdmiOutput, videoFmt, g_NEXUS_DisplayModule_State.hdmiOutput.colorimetry, aspectRatioVdc, 
1326        display->cfg.timingGenerator == NEXUS_DisplayTimingGenerator_eHdmiDvo,
1327        NULL /* no change */);
1328    NEXUS_Module_Unlock(g_NEXUS_DisplayModule_State.modules.hdmiOutput);
1329
1330done:
1331    return;
1332}
1333
1334static BERR_Code
1335NEXUS_VideoOutput_P_SetHdmiFormat(void *output, NEXUS_DisplayHandle display, NEXUS_VideoFormat format, NEXUS_DisplayAspectRatio aspectRatio)
1336{
1337    BERR_Code rc;
1338    NEXUS_HdmiOutputHandle hdmiOutput = output;
1339    BFMT_VideoFmt videoFmt;
1340    NEXUS_HdmiOutputStatus hdmiOutputStatus;
1341    bool aspectRatioChangeOnly;
1342#if NEXUS_HAS_HDMI_1_3
1343    NEXUS_HdmiOutputSettings settings;
1344    BAVC_HDMI_BitsPerPixel colorDepth;
1345#endif
1346
1347    BDBG_ASSERT(NULL != hdmiOutput); /* HdmiOutput will validate the handle */
1348
1349    rc = NEXUS_HdmiOutput_GetStatus(hdmiOutput, &hdmiOutputStatus);
1350    if (rc) return BERR_TRACE(rc);
1351    if (!hdmiOutputStatus.connected) {
1352        NEXUS_CallbackDesc notifyDisplay;
1353        BDBG_WRN(("HDMI output is not connected. Cannot apply format settings."));
1354
1355        /* set the callback so that when we do connect, the display is notified */
1356        display->hdmi.outputNotify = hdmiOutput;
1357        NEXUS_CallbackHandler_PrepareCallback(display->hdmi.outputNotifyDisplay, notifyDisplay);
1358       
1359        NEXUS_Module_Lock(g_NEXUS_DisplayModule_State.modules.hdmiOutput);
1360        NEXUS_HdmiOutput_SetDisconnectParams_priv(hdmiOutput, display->cfg.timingGenerator == NEXUS_DisplayTimingGenerator_eHdmiDvo, &notifyDisplay);
1361        NEXUS_Module_Unlock(g_NEXUS_DisplayModule_State.modules.hdmiOutput);
1362
1363        return -1; /* No need for BERR_TRACE. This is normal. */
1364    }
1365
1366    rc = NEXUS_P_VideoFormat_ToMagnum(format, &videoFmt);
1367    if (rc) return BERR_TRACE(rc);
1368
1369    NEXUS_Module_Lock(g_NEXUS_DisplayModule_State.modules.hdmiOutput);
1370
1371    /* If only aspect ratio is changing, set the aspectRatioChangeOnly flag for later use in hdmi_output module*/
1372    aspectRatioChangeOnly = ((g_NEXUS_DisplayModule_State.hdmiOutput.aspectRatio != aspectRatio) &&
1373        (g_NEXUS_DisplayModule_State.hdmiOutput.format == format));
1374
1375    rc = NEXUS_HdmiOutput_P_PreFormatChange_priv(hdmiOutput, aspectRatioChangeOnly);
1376    if (rc) {
1377        rc = BERR_TRACE(rc);
1378        /* Keep going, they asked for it... */
1379    }
1380
1381    if ( !NEXUS_HdmiOutput_GetColorimetry_priv(hdmiOutput, videoFmt, &g_NEXUS_DisplayModule_State.hdmiOutput.colorimetry) )
1382    {
1383        BDBG_WRN(("Video format %d does not seem to be supported by attached HDMI receiver.", format));
1384        /* Keep going, they asked for it... */
1385    }
1386    NEXUS_Module_Unlock(g_NEXUS_DisplayModule_State.modules.hdmiOutput);
1387
1388    /* Enable HDMI port in the VDC */
1389    rc = BVDC_Display_SetHdmiConfiguration(display->displayVdc, BVDC_Hdmi_0, g_NEXUS_DisplayModule_State.hdmiOutput.colorimetry);
1390    if (rc) return BERR_TRACE(rc);
1391
1392    /* Additional step to configure deep color mode */
1393#if NEXUS_HAS_HDMI_1_3
1394    /* Get color depth settings */
1395    NEXUS_HdmiOutput_GetSettings(hdmiOutput, &settings);
1396    colorDepth = NEXUS_P_HdmiColorDepth_ToMagnum(settings.colorDepth);
1397    rc = BVDC_Display_SetHdmiColorDepth(display->displayVdc, colorDepth);
1398    if (rc) return BERR_TRACE(rc);
1399#endif
1400
1401    /* don't call ApplyChanges here. this will be called by higher level Display code. after the ApplyChanges is done,
1402    the requiresHdmiOutputBringup flag will cause NEXUS_VideoOutput_P_PostSetHdmiFormat to be called. */
1403
1404    /* store information that we will need in NEXUS_VideoOutput_P_PostSetHdmiFormat */
1405    g_NEXUS_DisplayModule_State.hdmiOutput.display = display;
1406    g_NEXUS_DisplayModule_State.hdmiOutput.hdmiOutput = hdmiOutput;
1407    g_NEXUS_DisplayModule_State.hdmiOutput.aspectRatio = aspectRatio;
1408    g_NEXUS_DisplayModule_State.hdmiOutput.format = format;
1409
1410    return 0;
1411}
1412
1413void NEXUS_VideoOutput_P_PostSetHdmiFormat(void)
1414{
1415    BFMT_AspectRatio aspectRatioVdc;
1416    BFMT_VideoFmt videoFmt;
1417    NEXUS_CallbackDesc notifyDisplay;
1418    NEXUS_DisplayHandle display = g_NEXUS_DisplayModule_State.hdmiOutput.display;
1419    NEXUS_HdmiOutputHandle hdmiOutput = g_NEXUS_DisplayModule_State.hdmiOutput.hdmiOutput;
1420
1421    g_NEXUS_DisplayModule_State.hdmiOutput.display = NULL;
1422    g_NEXUS_DisplayModule_State.hdmiOutput.hdmiOutput = NULL;
1423
1424    (void)NEXUS_P_DisplayAspectRatio_ToMagnum(g_NEXUS_DisplayModule_State.hdmiOutput.aspectRatio, &aspectRatioVdc);
1425    (void)NEXUS_P_VideoFormat_ToMagnum(g_NEXUS_DisplayModule_State.hdmiOutput.format, &videoFmt);
1426
1427    /* now enable/set the HDMI changes */
1428    display->hdmi.outputNotify = hdmiOutput;
1429    NEXUS_CallbackHandler_PrepareCallback(display->hdmi.outputNotifyDisplay, notifyDisplay);
1430
1431#if NEXUS_HAS_HDMI_1_3
1432    {
1433    NEXUS_HdmiOutputSettings settings;
1434    (void) NEXUS_HdmiOutput_GetSettings(hdmiOutput, &settings);
1435    /* Set deep color mode */
1436    NEXUS_Module_Lock(g_NEXUS_DisplayModule_State.modules.hdmiOutput);
1437    (void) NEXUS_HdmiOutput_SetColorDepth_priv(hdmiOutput, settings.colorDepth);
1438    NEXUS_Module_Unlock(g_NEXUS_DisplayModule_State.modules.hdmiOutput);
1439    }
1440#endif
1441
1442    NEXUS_Module_Lock(g_NEXUS_DisplayModule_State.modules.hdmiOutput);
1443    (void)NEXUS_HdmiOutput_SetDisplayParams_priv(hdmiOutput, videoFmt, g_NEXUS_DisplayModule_State.hdmiOutput.colorimetry, aspectRatioVdc, 
1444        display->cfg.timingGenerator == NEXUS_DisplayTimingGenerator_eHdmiDvo,
1445        &notifyDisplay);
1446    (void)NEXUS_HdmiOutput_P_PostFormatChange_priv(hdmiOutput);
1447    NEXUS_Module_Unlock(g_NEXUS_DisplayModule_State.modules.hdmiOutput);
1448}
1449
1450static BERR_Code
1451NEXUS_VideoOutput_P_HdmiFormatChange(void *output, NEXUS_DisplayHandle display, NEXUS_VideoFormat format, NEXUS_DisplayAspectRatio aspectRatio)
1452{
1453    (void)NEXUS_VideoOutput_P_SetHdmiFormat(output, display, format, aspectRatio);
1454    return BERR_SUCCESS;
1455}
1456
1457static BERR_Code
1458NEXUS_VideoOutput_P_ConnectHdmi(void *output,  NEXUS_DisplayHandle display)
1459{
1460    NEXUS_HdmiOutputHandle hdmi = output;
1461
1462    BDBG_ASSERT(NULL != hdmi);
1463    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1464
1465    (void)NEXUS_VideoOutput_P_SetHdmiFormat(output, display, display->cfg.format, NEXUS_Display_P_ConvertAspectRatio(display->cfg.aspectRatio, display->cfg.format));
1466
1467    BKNI_EnterCriticalSection();
1468    BDBG_ASSERT(NULL == display->hdmi.rateChangeCb_isr);
1469    display->hdmi.rateChangeCb_isr = NEXUS_VideoOutput_P_HdmiRateChange_isr;
1470    display->hdmi.pCbParam = hdmi;
1471    if ( display->hdmi.rateInfoValid )
1472    {
1473        NEXUS_VideoOutput_P_HdmiRateChange_isr(display, hdmi);
1474    }
1475    BKNI_LeaveCriticalSection();
1476
1477    return BERR_SUCCESS;
1478}
1479
1480static BERR_Code
1481NEXUS_VideoOutput_P_DisconnectHdmi(void *output, NEXUS_DisplayHandle display)
1482{
1483    BERR_Code rc;
1484    NEXUS_HdmiOutputHandle hdmi = output;
1485    const NEXUS_DisplayModule_State *video= &g_NEXUS_DisplayModule_State;
1486
1487    BDBG_ASSERT(NULL != hdmi);
1488    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1489
1490    BKNI_EnterCriticalSection();
1491    BDBG_ASSERT(NULL != display->hdmi.rateChangeCb_isr);
1492    display->hdmi.rateChangeCb_isr = NULL;
1493    display->hdmi.pCbParam = NULL;
1494    BKNI_LeaveCriticalSection();
1495
1496    /* Disable HDMI in VDC */
1497    rc = BVDC_Display_SetHdmiConfiguration(display->displayVdc, BVDC_Hdmi_0, BAVC_MatrixCoefficients_eUnknown);
1498    if ( rc )
1499    {
1500        return BERR_TRACE(rc);
1501    }
1502
1503    /* APPLY VDC Changes */
1504    if(g_NEXUS_DisplayModule_State.updateMode != NEXUS_DisplayUpdateMode_eAuto) {rc=BERR_TRACE(NEXUS_NOT_SUPPORTED);}
1505    rc = BVDC_ApplyChanges(video->vdc);
1506    if ( rc )
1507    {
1508        return BERR_TRACE(rc);
1509    }
1510
1511    /* Turn off the transmitter itself */
1512    NEXUS_Module_Lock(video->modules.hdmiOutput);
1513    rc = NEXUS_HdmiOutput_Disconnect_priv(hdmi);
1514    NEXUS_Module_Unlock(video->modules.hdmiOutput);
1515    if ( rc )
1516    {
1517        rc = BERR_TRACE(rc);
1518        return BERR_SUCCESS;
1519    }
1520
1521    return rc;
1522}
1523
1524static NEXUS_VideoOutput_P_Link *
1525NEXUS_VideoOutput_P_OpenHdmi(NEXUS_VideoOutput output)
1526{
1527    NEXUS_VideoOutput_P_Link *link;
1528    NEXUS_VideoOutput_P_Iface iface;
1529
1530    BDBG_OBJECT_ASSERT(output, NEXUS_VideoOutput);
1531    BDBG_ASSERT(output->type == NEXUS_VideoOutputType_eHdmi);
1532
1533    iface.connect = NEXUS_VideoOutput_P_ConnectHdmi;
1534    iface.disconnect = NEXUS_VideoOutput_P_DisconnectHdmi;
1535    iface.formatChange = NEXUS_VideoOutput_P_HdmiFormatChange;
1536    link = NEXUS_VideoOutput_P_CreateLink(output, &iface, false);
1537    if (link) {
1538        link->displayOutput = BVDC_DisplayOutput_eDvo;
1539    }
1540    return link;
1541}
1542#endif
1543
1544#if NEXUS_NUM_RFM_OUTPUTS
1545static BERR_Code
1546NEXUS_Rfm_P_Connect(void *output,  NEXUS_DisplayHandle display)
1547{
1548    NEXUS_RfmHandle rfm = output;
1549    NEXUS_RfmConnectionSettings rfmConnectionSettings;
1550    unsigned index;
1551    BERR_Code rc;
1552    const NEXUS_DisplayModule_State *video = &g_NEXUS_DisplayModule_State;
1553
1554    NEXUS_Module_Lock(video->modules.rfm);
1555    NEXUS_Rfm_GetIndex_priv(rfm, &index);
1556    NEXUS_Module_Unlock(video->modules.rfm);
1557
1558    rc = BVDC_Display_SetRfmConfiguration(display->displayVdc, BVDC_Rfm_0 + index,  BVDC_RfmOutput_eCVBS, 0);
1559    if (rc) return BERR_TRACE(rc);
1560
1561    NEXUS_Module_Lock(video->modules.rfm);
1562    NEXUS_Rfm_GetConnectionSettings_priv(rfm, &rfmConnectionSettings);
1563    rfmConnectionSettings.videoEnabled = true;
1564    rfmConnectionSettings.videoFormat = display->cfg.format;
1565    rc = NEXUS_Rfm_SetConnectionSettings_priv(rfm, &rfmConnectionSettings);
1566    NEXUS_Module_Unlock(video->modules.rfm);
1567
1568    return rc;
1569}
1570
1571static BERR_Code
1572NEXUS_Rfm_P_Disconnect(void *output, NEXUS_DisplayHandle display)
1573{
1574    NEXUS_RfmHandle rfm = output;
1575    NEXUS_RfmConnectionSettings rfmConnectionSettings;
1576    unsigned index;
1577    BERR_Code rc;
1578    const NEXUS_DisplayModule_State *video = &g_NEXUS_DisplayModule_State;
1579
1580    NEXUS_Module_Lock(video->modules.rfm);
1581    NEXUS_Rfm_GetIndex_priv(rfm, &index);
1582    NEXUS_Module_Unlock(video->modules.rfm);
1583
1584    rc = BVDC_Display_SetRfmConfiguration(display->displayVdc, BVDC_Rfm_0 + index,  BVDC_RfmOutput_eUnused, 0);
1585    if (rc) return BERR_TRACE(rc);
1586
1587    NEXUS_Module_Lock(video->modules.rfm);
1588    NEXUS_Rfm_GetConnectionSettings_priv(rfm, &rfmConnectionSettings);
1589    rfmConnectionSettings.videoEnabled = false;
1590    rc = NEXUS_Rfm_SetConnectionSettings_priv(rfm, &rfmConnectionSettings);
1591    NEXUS_Module_Unlock(video->modules.rfm);
1592
1593    return rc;
1594}
1595
1596static BERR_Code
1597NEXUS_Rfm_P_FormatChange(void *output, NEXUS_DisplayHandle display, NEXUS_VideoFormat format, NEXUS_DisplayAspectRatio aspectRatio)
1598{
1599    NEXUS_RfmHandle rfm = output;
1600    NEXUS_RfmConnectionSettings rfmConnectionSettings;
1601    BERR_Code rc;
1602    const NEXUS_DisplayModule_State *video = &g_NEXUS_DisplayModule_State;
1603    BSTD_UNUSED(display);
1604    BSTD_UNUSED(aspectRatio);
1605
1606    NEXUS_Module_Lock(video->modules.rfm);
1607    NEXUS_Rfm_GetConnectionSettings_priv(rfm, &rfmConnectionSettings);
1608    rfmConnectionSettings.videoEnabled = true;
1609    rfmConnectionSettings.videoFormat = format;
1610    rc = NEXUS_Rfm_SetConnectionSettings_priv(rfm, &rfmConnectionSettings);
1611    NEXUS_Module_Unlock(video->modules.rfm);
1612
1613    return rc;
1614}
1615
1616static NEXUS_VideoOutput_P_Link *
1617NEXUS_VideoOutput_P_OpenRfm(NEXUS_VideoOutput output)
1618{
1619    NEXUS_VideoOutput_P_Link *link;
1620    NEXUS_VideoOutput_P_Iface iface;
1621    iface.connect = NEXUS_Rfm_P_Connect;
1622    iface.disconnect = NEXUS_Rfm_P_Disconnect;
1623    iface.formatChange = NEXUS_Rfm_P_FormatChange;
1624    link = NEXUS_VideoOutput_P_CreateLink(output, &iface, false);
1625    if (link) {
1626        link->displayOutput = BVDC_DisplayOutput_eComposite;
1627    }
1628    return link;
1629}
1630#endif
1631
1632NEXUS_VideoOutput_P_Link *
1633NEXUS_P_VideoOutput_Link(NEXUS_VideoOutput output)
1634{
1635    BERR_Code rc;
1636    BDBG_ASSERT(output->destination==NULL);
1637    switch(output->type) {
1638#if NEXUS_NUM_HDMI_DVO
1639    case NEXUS_VideoOutputType_eHdmiDvo:
1640        return NEXUS_VideoOutput_P_OpenHdmiDvo(output);
1641#endif
1642    case NEXUS_VideoOutputType_eComposite:
1643        return NEXUS_VideoOutput_P_OpenComposite(output);
1644    case NEXUS_VideoOutputType_eComponent:
1645        return NEXUS_VideoOutput_P_OpenComponent(output);
1646    case NEXUS_VideoOutputType_eSvideo:
1647        return NEXUS_VideoOutput_P_OpenSvideo(output);
1648#if NEXUS_NUM_HDMI_OUTPUTS
1649    case NEXUS_VideoOutputType_eHdmi:
1650        return NEXUS_VideoOutput_P_OpenHdmi(output);
1651#endif
1652#if NEXUS_NUM_RFM_OUTPUTS
1653    case NEXUS_VideoOutputType_eRfm:
1654        return NEXUS_VideoOutput_P_OpenRfm(output);
1655#endif
1656#if NEXUS_NUM_SCART_INPUTS
1657    case NEXUS_VideoOutputType_eScartInput:
1658        return NEXUS_VideoOutput_P_OpenScartInput(output);
1659#endif
1660#if NEXUS_NUM_656_OUTPUTS
1661    case NEXUS_VideoOutputType_eCcir656:
1662        return NEXUS_VideoOutput_P_OpenCcir656(output);
1663#endif
1664    default:
1665        rc=BERR_TRACE(NEXUS_NOT_SUPPORTED);
1666        return NULL;
1667    }
1668}
1669
1670void
1671NEXUS_VideoOutput_Shutdown(NEXUS_VideoOutput output)
1672{
1673    BDBG_OBJECT_ASSERT(output, NEXUS_VideoOutput);
1674    if (output->destination) {
1675        BDBG_WRN(("Cannot shutdown an output which is connected to a display"));
1676    }
1677    /* beyond a WRN, there is nothing we can do here. Links are destroyed when the last Display is closed. */
1678    return;
1679}
1680
1681NEXUS_DisplayHandle NEXUS_VideoOutput_P_GetDisplay(NEXUS_VideoOutput output)
1682{
1683    BDBG_OBJECT_ASSERT(output, NEXUS_VideoOutput);
1684
1685    if (output->destination) {
1686        NEXUS_VideoOutput_P_Link *link = output->destination;
1687        BDBG_OBJECT_ASSERT(link->display, NEXUS_Display);
1688        return link->display;
1689    }
1690    return NULL;
1691}
1692
1693void NEXUS_VideoOutput_GetVfFilter( NEXUS_VideoOutput output, NEXUS_VideoDac dac, NEXUS_VideoOutputVfFilter *pFilter )
1694{
1695    BERR_Code rc;
1696    bool override;
1697    NEXUS_VideoOutput_P_Link *link;
1698   
1699    BDBG_OBJECT_ASSERT(output, NEXUS_VideoOutput);
1700   
1701    BKNI_Memset(pFilter, 0, sizeof(*pFilter));
1702    if (!output->destination) {
1703        BERR_TRACE(NEXUS_NOT_AVAILABLE);
1704        goto done;
1705    }
1706    link = output->destination;
1707    BDBG_OBJECT_ASSERT(link->display, NEXUS_Display);
1708   
1709    if (dac >= NEXUS_VideoDac_eMax || dac == NEXUS_VideoDac_eNone) {
1710        BERR_TRACE(NEXUS_INVALID_PARAMETER);
1711        goto done;
1712    }
1713   
1714    rc = BVDC_Display_GetVfFilter(link->display->displayVdc, link->displayOutput, link->channel[dac-NEXUS_VideoDac_e0], &override, pFilter->filterRegs, NEXUS_MAX_VF_FILTER_ENTRIES);
1715    if (rc) {
1716        rc = BERR_TRACE(rc);
1717        pFilter->numEntries = 0;
1718    }
1719    /* TODO: VDC does not return actual number populated, so we just report back the max. */
1720    pFilter->numEntries = NEXUS_MAX_VF_FILTER_ENTRIES;
1721done:
1722    return;
1723}
1724
1725NEXUS_Error NEXUS_VideoOutput_SetVfFilter( NEXUS_VideoOutput output, NEXUS_VideoDac dac, const NEXUS_VideoOutputVfFilter *pFilter )
1726{
1727    BERR_Code rc;
1728    NEXUS_VideoOutput_P_Link *link;
1729   
1730    BDBG_OBJECT_ASSERT(output, NEXUS_VideoOutput);
1731    if (!output->destination) {
1732        return BERR_TRACE(NEXUS_NOT_AVAILABLE);
1733    }   
1734    link = output->destination;
1735    BDBG_OBJECT_ASSERT(link->display, NEXUS_Display);
1736   
1737    if (dac >= NEXUS_VideoDac_eMax || dac == NEXUS_VideoDac_eNone) {
1738        return BERR_TRACE(NEXUS_INVALID_PARAMETER);
1739    }
1740   
1741    if (pFilter) {
1742        rc = BVDC_Display_SetVfFilter(link->display->displayVdc, link->displayOutput, link->channel[dac-NEXUS_VideoDac_e0], true, (uint32_t*)pFilter->filterRegs, pFilter->numEntries);
1743        if (rc) return BERR_TRACE(rc);
1744    }
1745    else {
1746        rc = BVDC_Display_SetVfFilter(link->display->displayVdc, link->displayOutput, link->channel[dac-NEXUS_VideoDac_e0], false, NULL, 0);
1747        if (rc) return BERR_TRACE(rc);
1748    }
1749    return 0;
1750}
1751
1752void NEXUS_VideoOutput_GetSettings( NEXUS_VideoOutput output, NEXUS_VideoOutputSettings *pSettings )
1753{
1754    NEXUS_VideoOutput_P_Link *link;
1755    BDBG_OBJECT_ASSERT(output, NEXUS_VideoOutput);
1756    if (!output->destination) {
1757        BKNI_Memset(pSettings, 0, sizeof(*pSettings));
1758        return;
1759    }   
1760    link = output->destination;
1761    BDBG_OBJECT_ASSERT(link->display, NEXUS_Display);
1762    *pSettings = link->settings;
1763}
1764   
1765NEXUS_Error NEXUS_VideoOutput_SetSettings( NEXUS_VideoOutput output, const NEXUS_VideoOutputSettings *pSettings )
1766{
1767    NEXUS_VideoOutput_P_Link *link;
1768    NEXUS_Error rc;
1769    BDBG_OBJECT_ASSERT(output, NEXUS_VideoOutput);
1770    if (!output->destination) {
1771        return BERR_TRACE(NEXUS_NOT_AVAILABLE);
1772    }   
1773    link = output->destination;
1774    BDBG_OBJECT_ASSERT(link->display, NEXUS_Display);
1775   
1776    rc = BVDC_Display_SetMuteMode(link->display->displayVdc, link->displayOutput, pSettings->mute?BVDC_MuteMode_eConst:BVDC_MuteMode_eDisable);
1777    if (rc) return BERR_TRACE(rc);
1778   
1779    rc = NEXUS_Display_P_ApplyChanges();
1780    if (rc) return BERR_TRACE(rc);
1781   
1782    link->settings = *pSettings;
1783    return 0;
1784}
Note: See TracBrowser for help on using the repository browser.