source: svn/newcon3bcm2_21bu/nexus/modules/display/7552/src/nexus_display_vbi.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: 46.9 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_display_vbi.c $
39 * $brcm_Revision: 50 $
40 * $brcm_Date: 10/6/11 3:42p $
41 *
42 * Module Description:
43 *
44 * Revision History:
45 *
46 * $brcm_Log: /nexus/modules/display/7400/src/nexus_display_vbi.c $
47 *
48 * 50   10/6/11 3:42p erickson
49 * SW7420-2070: add NEXUS_VBI_ENCODER_QUEUE_SIZE macro to control vbilib
50 *  allocations using (NEXUS_VBI_ENCODER_QUEUE_SIZE+1)*NEXUS_NUM_DISPLAYS
51 *  formula.
52 *
53 * 49   2/25/11 4:37p erickson
54 * SW7422-255: add AMOL support
55 *
56 * 48   1/3/11 11:29a erickson
57 * SW7420-1336: use BVDC_Display_GetInterruptName for VBI encode
58 *
59 * 47   12/23/10 12:50p erickson
60 * SW7425-34: use BAVC_VbiPath_eUnknown to determine if display is VBI
61 *  capable
62 *
63 * 46   12/1/10 10:31a erickson
64 * SW7405-5028: fix BVBI_Field_SetPolarity_isr for progressive displays
65 *
66 * 45   11/30/10 2:07p VISHK
67 * SW7208-114: "Unable to set HD path display settings" if building with
68 *  MACROVISION ON
69 *
70 * 44   10/18/10 2:12p VISHK
71 * SW7401-4457: Settop API shim causes crash when macrovision is enabled
72 *  for component via Brutus
73 *
74 * 43   10/18/10 11:21a katrep
75 * SW7405-4950:add check to see if cgms-b in enabled in platform setting
76 *
77 * 42   10/5/10 4:47p erickson
78 * SW7405-4916: CGMS A/B not supported for PAL
79 *
80 * 41   5/20/10 5:03p mphillip
81 * SW7335-666: Enable CGMSA and CGMSB to work together
82 *
83 * 40   5/11/10 5:03p jtna
84 * SW7125-307: Coverity - check for null pointer arguments before
85 *  dereferencing them
86 *
87 * 39   5/4/10 10:12a erickson
88 * SW7335-666: fix bottom field polarity in NEXUS_Display_P_DequeVbi_isr
89 *
90 * 38   4/6/10 10:17a erickson
91 * SW7405-4171: revise NEXUS_DisplayDcsType. add eOn1, eOn2, eOn2. fix
92 *  naming convention issues.
93 *
94 * 37   3/5/10 4:03p erickson
95 * SW3556-1043: check in CASSERT that works with dtv and settop
96 *
97 * 36   3/5/10 12:35p erickson
98 * SW3556-1043: clarify logic in NEXUS_Display_WriteTeletext, avoid VBI
99 *  line 16 collisions with VPS, clarify mapping of SW arrays to VBI
100 *  lines, note possible future options for lineNumber, avoid BKNI_Memcpy
101 *  for BVBI_TT_INVALID_FRAMING_CODE lines
102 *
103 * 35   1/8/10 3:18p erickson
104 * SW3556-979: rework VPS, CGMS, CGMS-B and WSS encoding. instead of
105 *  trying to get into the VBIlib encoder queue, we just intercept the
106 *  queue in the VEC isr. this removes the BKNI_Sleep and possible Set
107 *  failure.
108 *
109 * 34   11/23/09 11:56a erickson
110 * SW7550-29: replace BCHP_CHIP list with a test for an RDB define
111 *
112 * 33   11/19/09 4:21p gmohile
113 * SW7408-1 : Add 7408 support
114 *
115 * 32   11/19/09 3:27p erickson
116 * SW7468-24: BVBI_Encode_SetGemstarOptions change
117 *
118 * 31   8/26/09 6:59p mphillip
119 * SW7405-2810: Clear framing code when resetting to a new set of input
120 *  teletext lines
121 *
122 * 30   8/19/09 11:14a mward
123 * PR55545: Add 7125 support.
124 *
125 * 29   8/10/09 8:17a gmohile
126 * PR 56400 : Merge legacy vdc support to main line
127 *
128 * 28   8/5/09 4:55p jrubio
129 * PR55232: add 7342/7340 support
130 *
131 * 27   7/8/09 10:28a mward
132 * PR 56640: Compiler warning for unused variable 'video'.
133 *
134 * 26   5/15/09 1:06p erickson
135 * PR55187: set either top or bottom in NEXUS_Display_WriteClosedCaption,
136 *  not either
137 *
138 * 25   3/10/09 10:58a erickson
139 * PR51253: added NEXUS_TeletextLine.topField
140 *
141 * 24   3/9/09 10:11a erickson
142 * PR51253: fix line_offset bug with NEXUS_Display_WriteTeletext
143 *
144 * 23   2/27/09 10:11a erickson
145 * PR52115: convert BERR_TRACE to more clear BDBG_WRN. this is normal for
146 *  bad video inputs.
147 *
148 * 22   1/15/09 9:51a katrep
149 * PR47111: Fixed compiler warning
150 *
151 * 21   12/24/08 12:40p jgarrett
152 * PR 50703: Disabling VBI for 7420
153 *
154 * 20   12/9/08 6:27p nickh
155 * PR48963: Add support for 7420 VBI INT_ID name changes
156 *
157 * 19   12/8/08 5:04p erickson
158 * PR50058: rework internal VideoInput vbi accounting, don't store refcnt
159 *
160 * 18   11/17/08 12:28p erickson
161 * PR49203: ensure there are no unnecessary unguarded BVDC_ApplyChanges
162 *  calls in Nexus
163 *
164 * 17   10/24/08 4:06p erickson
165 * PR48340: don't call VBI PI with NULL handle on DTV platform
166 *
167 * 16   10/16/08 1:56p erickson
168 * PR47892: add VBI PI calls for gemstar
169 *
170 * 15   10/16/08 12:39p jtna
171 * PR47892: Added GemStar encoding interface
172 *
173 * 14   9/18/08 4:19p erickson
174 * PR47111: fix warnings
175 *
176 * 13   7/17/08 6:36p jgarrett
177 * PR 44919: Only enabling SEC_VEC interrupt for platforms that have one
178 *
179 * 12   7/17/08 4:17p erickson
180 * PR44919: one display still requires SEC VBI
181 *
182 * 11   7/15/08 5:21p erickson
183 * PR38679: don't fail display SetSettings if the display format doesn't
184 *  support VBI
185 *
186 * 10   6/3/08 9:39a ahulse
187 * PR43266: Add support for DCS in nexus
188 *
189 * 9   4/30/08 11:14a erickson
190 * PR41371: add CGMS-B support
191 *
192 * 8   3/26/08 1:22p vsilyaev
193 * PR 40862: Fixed support for 1080p formats
194 *
195 * 7   2/7/08 2:31p erickson
196 * PR38701: added macrovision implementation with appropriate #deifne
197 *
198 * 6   2/7/08 12:10p erickson
199 * PR38679: adds comments and DBG
200 *
201 * 5   2/5/08 10:12a erickson
202 * PR38679: impl WriteTeletext, update SetWss, change to SetVps
203 *
204 * 4   2/4/08 10:40a erickson
205 * PR38679: added NEXUS_Display_WriteClosedCaption
206 *
207 * 3   2/4/08 9:35a erickson
208 * PR38679: impl SetWss and SetCgms
209 *
210 * 2   2/1/08 3:20p erickson
211 * PR38679: add vbi support
212 *
213 * 1   1/18/08 2:20p jgarrett
214 * PR 38808: Merging to main branch
215 *
216 * Nexus_Devel/12   1/15/08 10:51a vsilyaev
217 * PR 38701: Added macrovision API
218 *
219 * Nexus_Devel/11   1/11/08 1:51p erickson
220 * PR38679: add vbi read/write api's
221 *
222 * Nexus_Devel/10   12/28/07 5:19p erickson
223 * PR38470: move conversion functions to core
224 *
225 * Nexus_Devel/9   11/6/07 1:13p erickson
226 * PR36570: merge 3563
227 *
228 * Nexus_Devel/8   11/5/07 3:46p vsilyaev
229 * PR 36696: Fixed user data handling
230 *
231 * Nexus_Devel/7   11/2/07 4:42p vsilyaev
232 * PR 36696: Used connector model for VideoInput's and VideoOutput's
233 *
234 * Nexus_Devel/6   10/17/07 3:20p vsilyaev
235 * PR 34662: Used number of display from the platform layer
236 *
237 * Nexus_Devel/5   10/8/07 12:11p vsilyaev
238 * PR 34662: PR34926: reworked VBI interface
239 *
240 * Nexus_Devel/4   10/4/07 6:44p vsilyaev
241 * PR 34662: Use bitfield for the field polarity, disable VBI on the
242 * format change
243 *
244 * Nexus_Devel/3   10/4/07 4:01p vsilyaev
245 * PR 34662: Activated closed captioning
246 *
247 * Nexus_Devel/2   10/4/07 3:05p vsilyaev
248 * PR 34662: Fixed typo
249 *
250 * Nexus_Devel/1   10/4/07 12:21p vsilyaev
251 * PR 34662: VBI support
252 *
253 **************************************************************************/
254#include "nexus_base.h"
255#include "nexus_display_module.h"
256#include "priv/nexus_core.h"
257
258BDBG_MODULE(nexus_display_vbi);
259
260#if B_HAS_VBI
261#if B_HAS_VBI_ENCODE
262
263#define BDBG_MSG_TRACE(X) /* BDBG_MSG(X) */
264
265static void
266NEXUS_Display_P_DequeVbi_isr(void* parm1, int parm2)
267{
268    NEXUS_DisplayHandle display = parm1;
269    BERR_Code rc;
270    BAVC_Polarity polarity = (BAVC_Polarity)parm2;
271    BVBI_Field_Handle field;
272    bool isTop, isBottom;
273
274    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
275    BDBG_ASSERT(display->vbi.enc);
276
277    /* PR 21710 - for progressive displays, pass vbilib eFrame */
278    polarity = display->vbi.progressive ? BAVC_Polarity_eFrame  : (BAVC_Polarity)parm2;
279    isTop = (polarity == BAVC_Polarity_eTopField) || (polarity == BAVC_Polarity_eFrame);
280    isBottom = (polarity == BAVC_Polarity_eBotField) || (polarity == BAVC_Polarity_eFrame);
281
282    rc = BVBIlib_Encode_GetOldestDatum_isr(display->vbi.enc, &field);
283    if (!rc) {
284        bool somethingSet =
285            display->vbi.pending.wssSet ||
286            display->vbi.pending.vpsSet ||
287            display->vbi.pending.cgmsTopSet ||
288            display->vbi.pending.cgmsBottomSet ||
289            display->vbi.pending.cgmsBTopSet ||
290            display->vbi.pending.cgmsBBottomSet;
291        bool obtained = false;
292
293        if (!field && somethingSet) {
294            rc = BVBIlib_List_Obtain_isr(g_NEXUS_DisplayModule_State.vbilist, &field);
295            if (rc) {field = NULL; rc = BERR_TRACE(rc);}
296            /* if we can't get one, just let the data stay pending.
297            we still need to fall through and allow VBIlib to empty its queue. */
298
299            if (field) {
300                unsigned polarityMask;
301
302                obtained = true;
303
304                if (polarity == BAVC_Polarity_eFrame) {
305                    polarityMask = (1<<BAVC_Polarity_eTopField)|(1<<BAVC_Polarity_eBotField);
306                }
307                else {
308                    polarityMask = 1<<polarity;
309                }
310                (void)BVBI_Field_SetPolarity_isr(field, polarityMask);
311            }
312
313        }
314        if (field) {
315            /* set non-streaming data. these types of VBI just require the last value set to be
316            applied. this code bypassing the queue logic needed for cc, tt and gs. */
317            if (display->vbi.pending.wssSet && isTop) {
318                rc = BVBI_Field_SetWSSData_isr(field, display->vbi.pending.wssData);
319                if (!rc) {
320                    BDBG_MSG_TRACE(("wss %x set", display->vbi.pending.wssData));
321                    display->vbi.pending.wssSet = false;
322                }
323            }
324            if (display->vbi.pending.vpsSet && isTop) {
325                rc = BVBI_Field_SetVPSData_isr(field, &display->vbi.pending.vpsData);
326                if (!rc) {
327                    BDBG_MSG_TRACE(("vps set"));
328                    display->vbi.pending.vpsSet = false;
329                }
330            }
331            if (display->vbi.pending.cgmsTopSet && isTop) {
332                rc = BVBI_Field_SetCGMSData_isr(field, display->vbi.pending.cgmsData);
333                if (!rc) {
334                    BDBG_MSG_TRACE(("cgms top %x set", display->vbi.pending.cgmsData));
335                    display->vbi.pending.cgmsTopSet = false;
336                }
337            }
338            if (display->vbi.pending.cgmsBottomSet && isBottom) {
339                rc = BVBI_Field_SetCGMSData_isr(field, display->vbi.pending.cgmsData);
340                if (!rc) {
341                    BDBG_MSG_TRACE(("cgms bottom %x set", display->vbi.pending.cgmsData));
342                    display->vbi.pending.cgmsBottomSet = false;
343                }
344            }
345            if (display->vbi.pending.cgmsBTopSet && isTop) {
346                rc = BVBI_Field_SetCGMSBData_isr(field, (BVBI_CGMSB_Datum*)display->vbi.pending.cgmsBData);
347                if (!rc) {
348                    BDBG_MSG_TRACE(("cgmsB top set"));
349                    display->vbi.pending.cgmsBTopSet = false;
350                }
351            }
352            if (display->vbi.pending.cgmsBBottomSet && isBottom) {
353                rc = BVBI_Field_SetCGMSBData_isr(field, (BVBI_CGMSB_Datum*)display->vbi.pending.cgmsBData);
354                if (!rc) {
355                    BDBG_MSG_TRACE(("cgmsB bottom set"));
356                    display->vbi.pending.cgmsBBottomSet = false;
357                }
358            }
359        }
360        if (obtained) {
361            rc = BVBIlib_Encode_Enqueue_isr(display->vbi.enc, field);
362            if (rc) {
363                BVBIlib_List_Return_isr(g_NEXUS_DisplayModule_State.vbilist, field);
364            }
365        }
366    }
367
368    rc = BVBIlib_Encode_Data_isr(display->vbi.enc, polarity);
369    if (rc!=BERR_SUCCESS) { rc = BERR_TRACE(rc);}
370}
371
372
373BERR_Code
374NEXUS_Display_P_ConnectVbi(NEXUS_DisplayHandle display)
375{
376    BAVC_VbiPath vbi_path;
377    BERR_Code rc;
378    BERR_Code cleanup_rc; /* preserve original error code */
379    BINT_Id tf_isr, bf_isr;
380    const NEXUS_DisplayModule_State *video = &g_NEXUS_DisplayModule_State;
381
382    BDBG_MSG(("connect display%d to vbi", display->index));
383
384    rc = BVDC_Display_GetVbiPath(display->displayVdc, &vbi_path);
385    if (rc!=BERR_SUCCESS) { rc = BERR_TRACE(rc); goto err_vbi_path;}
386
387    if (vbi_path == BAVC_VbiPath_eUnknown) {
388        /* if this display doesn't support VBI, it is not a failure. return success. */
389        /* make sure this is null so that NEXUS_Display_P_DisconnectVbi will short circuit as well */
390        BDBG_ASSERT(!display->vbi.enc_core);
391        return 0;
392    }
393
394    rc = BVDC_Display_GetInterruptName(display->displayVdc, BAVC_Polarity_eTopField, &tf_isr);
395    if (rc!=BERR_SUCCESS) { rc = BERR_TRACE(rc); goto err_vbi_path;}
396    rc = BVDC_Display_GetInterruptName(display->displayVdc, BAVC_Polarity_eBotField, &bf_isr);
397    if (rc!=BERR_SUCCESS) { rc = BERR_TRACE(rc); goto err_vbi_path;}
398
399    display->vbi.progressive = false;
400
401    /* unfortunately we have to recreate everything because the vbi_path might change. */
402    rc = BVBI_Encode_Create (video->vbi, vbi_path, &display->vbi.enc_core);
403    if (rc!=BERR_SUCCESS) { rc = BERR_TRACE(rc); goto err_vbi_encode;}
404
405    rc = BVBIlib_Encode_Create(video->vbilib, video->vbilist, display->vbi.enc_core,
406        NEXUS_VBI_ENCODER_QUEUE_SIZE,
407        &display->vbi.enc);
408    if (rc!=BERR_SUCCESS) { rc = BERR_TRACE(rc); goto err_vbilib_encode;}
409
410    /* we are using top ISR to feed bottom field data and bottom field isr to feed top field data */
411    rc = BINT_CreateCallback( &display->vbi.tf_isr, g_pCoreHandles->bint, tf_isr, NEXUS_Display_P_DequeVbi_isr, display, BAVC_Polarity_eBotField);
412    if (rc!=BERR_SUCCESS) { rc = BERR_TRACE(rc); goto err_tf_isr;}
413
414    rc = BINT_CreateCallback( &display->vbi.bf_isr, g_pCoreHandles->bint, bf_isr, NEXUS_Display_P_DequeVbi_isr, display, BAVC_Polarity_eTopField);
415    if (rc!=BERR_SUCCESS) { rc = BERR_TRACE(rc); goto err_bf_isr;}
416
417    rc = BINT_EnableCallback(display->vbi.tf_isr);
418    if (rc!=BERR_SUCCESS) { rc = BERR_TRACE(rc); goto err_isr_cfg;}
419
420    rc = BINT_EnableCallback(display->vbi.bf_isr);
421    if (rc!=BERR_SUCCESS) { rc = BERR_TRACE(rc); goto err_isr_cfg;}
422
423    rc = NEXUS_Display_P_EnableVbi(display, display->cfg.format);
424    if (rc!=BERR_SUCCESS) { rc = BERR_TRACE(rc); goto err_enable_vbi;}
425
426    BDBG_ASSERT(display->vbi.tf_isr && display->vbi.bf_isr);
427    return BERR_SUCCESS;
428
429err_enable_vbi:
430err_isr_cfg:
431    cleanup_rc = BINT_DestroyCallback(display->vbi.bf_isr);
432    if (cleanup_rc!=BERR_SUCCESS) { cleanup_rc = BERR_TRACE(cleanup_rc); }
433err_bf_isr:
434    cleanup_rc = BINT_DestroyCallback(display->vbi.tf_isr);
435    if (cleanup_rc!=BERR_SUCCESS) { cleanup_rc = BERR_TRACE(cleanup_rc); }
436err_tf_isr:
437    cleanup_rc = BVBIlib_Encode_Destroy(display->vbi.enc);
438    if (cleanup_rc!=BERR_SUCCESS) { cleanup_rc = BERR_TRACE(cleanup_rc); }
439    display->vbi.enc = NULL;
440err_vbilib_encode:
441    cleanup_rc = BVBI_Encode_Destroy(display->vbi.enc_core);
442    if (cleanup_rc!=BERR_SUCCESS) { cleanup_rc = BERR_TRACE(cleanup_rc); }
443    display->vbi.enc_core = NULL;
444err_vbi_encode:
445err_vbi_path:
446    return rc;
447}
448
449void
450NEXUS_Display_P_DisconnectVbi(NEXUS_DisplayHandle display)
451{
452    BERR_Code rc;
453
454    BDBG_MSG(("disconnect display%d from vbi", display->index));
455
456    if (display->vbi.enc_core) {
457        NEXUS_Display_P_DisableVbi(display);
458
459        rc = BINT_DestroyCallback(display->vbi.bf_isr);
460        if (rc!=BERR_SUCCESS) { rc = BERR_TRACE(rc); }
461        rc = BINT_DestroyCallback(display->vbi.tf_isr);
462        if (rc!=BERR_SUCCESS) { rc = BERR_TRACE(rc); }
463        rc = BVBIlib_Encode_Destroy(display->vbi.enc);
464        if (rc!=BERR_SUCCESS) { rc = BERR_TRACE(rc); }
465        display->vbi.enc = NULL;
466        rc = BVBI_Encode_Destroy(display->vbi.enc_core);
467        if (rc!=BERR_SUCCESS) { rc = BERR_TRACE(rc); }
468        display->vbi.enc_core = NULL;
469    }
470
471    return;
472}
473
474BERR_Code
475NEXUS_Display_P_VbiData_isr(NEXUS_DisplayHandle display, BVBI_Field_Handle vbiData)
476{
477    BERR_Code rc;
478
479    if (!display->vbi.enc_core) {
480        /* we did not consume BVBI_Field_Handle, so we can't return 0. */
481        return -1;
482    }
483    /* NOTE: display->vbi.enc_core != NULL is the test for VBI capability. display->vbi.enc should track with it. */
484    BDBG_ASSERT(display->vbi.enc);
485
486    rc = BVBIlib_Encode_Enqueue_isr(display->vbi.enc, vbiData);
487    if (rc) {
488        BDBG_WRN(("Flushing VBI encoder queue because of overflow."));
489        /* If we can't enqueue, the buffer is probably full. Try to recover by flushing. */
490        BVBIlib_Encode_Flush_isr(display->vbi.enc);
491    }
492    return rc;
493}
494
495void
496NEXUS_Display_P_DisableVbi(NEXUS_DisplayHandle display)
497{
498    BERR_Code rc;
499
500    if (!display->vbi.enc_core) {
501        return;
502    }
503
504    rc = BVBI_Encode_SetCC(display->vbi.enc_core, false);
505    if (rc!=BERR_SUCCESS) {rc = BERR_TRACE(rc);}
506
507    rc = BVBI_Encode_SetTeletext(display->vbi.enc_core, false);
508    if (rc!=BERR_SUCCESS) {rc = BERR_TRACE(rc);}
509
510    rc = BVBI_Encode_SetWSS(display->vbi.enc_core, false);
511    if (rc!=BERR_SUCCESS) {rc = BERR_TRACE(rc);}
512
513    rc = BVBI_Encode_SetCGMS(display->vbi.enc_core, false);
514    if (rc!=BERR_SUCCESS) {rc = BERR_TRACE(rc);}
515
516    rc = BVBI_Encode_SetVPS(display->vbi.enc_core, false);
517    if (rc!=BERR_SUCCESS) {rc = BERR_TRACE(rc);}
518
519    rc = BVBI_Encode_SetGemstar(display->vbi.enc_core, false);
520    if (rc!=BERR_SUCCESS) {rc = BERR_TRACE(rc);}
521
522    rc = BVBI_Encode_SetAMOL(display->vbi.enc_core, false);
523    if (rc!=BERR_SUCCESS) {rc = BERR_TRACE(rc);}
524
525    rc = BVBI_Encode_ApplyChanges(display->vbi.enc_core);
526    if (rc!=BERR_SUCCESS) {rc = BERR_TRACE(rc);}
527
528    BKNI_EnterCriticalSection();
529    BVBIlib_Encode_Flush_isr(display->vbi.enc);
530    BKNI_LeaveCriticalSection();
531
532    return ;
533}
534
535BERR_Code
536NEXUS_Display_P_EnableVbi(NEXUS_DisplayHandle display, NEXUS_VideoFormat format)
537{
538    BERR_Code rc;
539    bool isSd = NEXUS_P_VideoFormat_IsSd(format);
540    BFMT_VideoFmt formatVdc;
541
542    if (!display->vbi.enc_core) {
543        BDBG_MSG(("Display does not support VBI encoding."));
544        return 0;
545    }
546
547    /* for formats that don't support VBI, print a WRN but succeed. this will allow the other display settings to be applied */
548    switch (format) {
549    case NEXUS_VideoFormat_e1080p24hz:
550    case NEXUS_VideoFormat_e1080p25hz:
551    case NEXUS_VideoFormat_e1080p30hz:
552    case NEXUS_VideoFormat_e1080p50hz:
553    case NEXUS_VideoFormat_e1080p60hz:
554        BDBG_MSG(("Display VideoFormat %d does not support VBI encoding.", format));
555        return 0;
556    default:
557        break;
558    }
559
560    /* No VESA modes */
561    if (format >= NEXUS_VideoFormat_eVesa640x480p60hz)  {
562        BDBG_MSG(("VESA display formats (%d) do not support VBI encoding.", format));
563        return 0;
564    }
565
566    display->vbi.progressive = !NEXUS_P_VideoFormat_IsInterlaced(format);
567
568    rc = NEXUS_P_VideoFormat_ToMagnum(format, &formatVdc);
569    if (rc) {return BERR_TRACE(rc);}
570
571    rc = BVBI_Encode_SetVideoFormat(display->vbi.enc_core,  formatVdc);
572    if (rc) {
573        BDBG_WRN(("NEXUS_Display_P_EnableVbi: %#lx VBI not supported for %u", (unsigned long)display, (unsigned)format));
574        return BERR_TRACE(rc);
575    }
576
577    rc = BVBI_Encode_SetCC(display->vbi.enc_core, isSd && display->vbi.settings.closedCaptionEnabled);
578    if (rc) {
579        BDBG_WRN(("ClosedCaption is not supported for this display format"));
580        return BERR_TRACE(rc);
581    }
582
583    rc = BVBI_Encode_SetTeletext(display->vbi.enc_core, isSd && display->vbi.settings.teletextEnabled);
584    if (rc) {
585        BDBG_WRN(("Teletext is not supported for this display format"));
586        return BERR_TRACE(rc);
587    }
588
589    rc = BVBI_Encode_SetWSS(display->vbi.enc_core, display->vbi.settings.wssEnabled);
590    if (rc) {
591        BDBG_WRN(("WSS is not supported for this display format"));
592        return BERR_TRACE(rc);
593    }
594
595#ifndef B_HAS_LEGACY_VDC
596    if(g_NEXUS_DisplayModule_State.moduleSettings.vbi.allowCgmsB){
597        /* CGMS is supported for NTSC and 50/60Hz HD, but not PAL. */
598        rc = BVBI_Encode_SetCGMSB(display->vbi.enc_core, (format != NEXUS_VideoFormat_ePal) && display->vbi.settings.cgmsEnabled);
599        if (rc) {
600            BDBG_WRN(("CGMS B is not supported for this display format"));
601            return BERR_TRACE(rc);
602        }
603    }
604
605#endif
606    /* CGMS is supported for NTSC and 50/60Hz HD, but not PAL. */
607    rc = BVBI_Encode_SetCGMS(display->vbi.enc_core, (format != NEXUS_VideoFormat_ePal) && display->vbi.settings.cgmsEnabled);
608    if (rc) {
609        BDBG_WRN(("CGMS A is not supported for this display format"));
610        return BERR_TRACE(rc);
611    }
612
613    rc = BVBI_Encode_SetVPS(display->vbi.enc_core, display->vbi.settings.vpsEnabled);
614    if (rc) {
615        BDBG_WRN(("VPS is not supported for this display format"));
616        return BERR_TRACE(rc);
617    }
618
619    if (display->vbi.settings.gemStarEnabled) {
620        BVBI_GSOptions gsOptions;
621        (void)BVBI_Encode_GetGemstarOptions(display->vbi.enc_core, &gsOptions);
622        gsOptions.baseline_top = display->vbi.settings.gemStar.baseLineTop;
623        gsOptions.linemask_top = display->vbi.settings.gemStar.lineMaskTop;
624        gsOptions.baseline_bot = display->vbi.settings.gemStar.baseLineBottom;
625        gsOptions.linemask_bot = display->vbi.settings.gemStar.lineMaskBottom;
626        rc = BVBI_Encode_SetGemstarOptions(display->vbi.enc_core, &gsOptions);
627        if (rc) return BERR_TRACE(rc);
628    }
629
630    rc = BVBI_Encode_SetGemstar(display->vbi.enc_core, display->vbi.settings.gemStarEnabled);
631    if (rc) {
632        BDBG_WRN(("GemStar is not supported for this display format"));
633        return BERR_TRACE(rc);
634    }
635
636    if (display->vbi.settings.amolEnabled) {
637        switch (display->vbi.settings.amol.type) {
638        case NEXUS_AmolType_eI:
639            display->vbi.amolType = BVBI_AMOL_Type_I; break;
640        case NEXUS_AmolType_eII_Lowrate:
641            display->vbi.amolType = BVBI_AMOL_Type_II_Lowrate; break;
642        case NEXUS_AmolType_eII_Highrate:
643            display->vbi.amolType = BVBI_AMOL_Type_II_Highrate; break;
644        default:
645            return BERR_TRACE(NEXUS_INVALID_PARAMETER);
646        }
647        rc = BVBI_Encode_SetAMOLOptions(display->vbi.enc_core, display->vbi.amolType);
648        if (rc) return BERR_TRACE(rc);
649    }
650
651    rc = BVBI_Encode_SetAMOL(display->vbi.enc_core,
652        /* AMOL only supported for NTSC and NTSC-J */
653        (format == NEXUS_VideoFormat_eNtsc || format == NEXUS_VideoFormat_eNtscJapan) && display->vbi.settings.amolEnabled);
654    if (rc) {
655        BDBG_WRN(("AMOL is not supported"));
656        return BERR_TRACE(rc);
657    }
658
659
660    rc = BVBI_Encode_ApplyChanges(display->vbi.enc_core);
661    if (rc) {return BERR_TRACE(rc);}
662
663    return BERR_SUCCESS;
664}
665
666#endif /* B_HAS_VBI_ENCODE */
667
668void NEXUS_Display_GetVbiSettings(NEXUS_DisplayHandle display, NEXUS_DisplayVbiSettings *pSettings)
669{
670    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
671    *pSettings = display->vbi.settings;
672}
673
674NEXUS_Error NEXUS_Display_SetVbiSettings(NEXUS_DisplayHandle display, const NEXUS_DisplayVbiSettings *pSettings)
675{
676    NEXUS_Error rc;
677    NEXUS_VideoInput prevInput;
678
679    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
680
681    prevInput = display->vbi.settings.vbiSource;
682
683    display->vbi.settings = *pSettings;
684
685    if (prevInput) {
686        NEXUS_VideoInput_P_SetVbiState(prevInput);
687    }
688    if (pSettings->vbiSource && pSettings->vbiSource != prevInput) {
689        NEXUS_VideoInput_P_SetVbiState(pSettings->vbiSource);
690    }
691
692    rc = NEXUS_Display_P_EnableVbi(display, display->cfg.format);
693    if (rc) return BERR_TRACE(rc);
694
695    return 0;
696}
697
698static BERR_Code NEXUS_Display_P_SendTeletextField(NEXUS_DisplayHandle display, BVBI_TT_Line *ttLines, unsigned ttLineCount, bool topField)
699{
700    BERR_Code rc;
701    BVBI_Field_Handle field = NULL;
702    const NEXUS_DisplayModule_State *video = &g_NEXUS_DisplayModule_State;
703    BFMT_VideoFmt formatVdc;
704
705    rc = NEXUS_P_VideoFormat_ToMagnum(display->cfg.format, &formatVdc);
706    if (rc) {return BERR_TRACE(rc);}
707
708    BKNI_EnterCriticalSection();
709    /* Set up the field. If we fail, make sure to exit the critical section
710    and free memory */
711    /* VBI PI memory allocation for TT was already done at BVBIlist create time. */
712    rc = BVBIlib_List_Obtain_isr(video->vbilist, &field);
713    if (rc) {rc = BERR_TRACE(rc);goto done_critsec;}
714
715    rc = BVBI_Field_SetTTData_isr(field, formatVdc, ttLineCount, ttLines);
716    if (rc) {rc = BERR_TRACE(rc);goto done_critsec;}
717
718    /* We are encoding on either field. I don't believe it matters if the data is transmitted top or bottom.
719    If it does, we will need to modify. */
720    rc = BVBI_Field_SetPolarity_isr(field, topField ? (1<<BAVC_Polarity_eTopField) : (1<<BAVC_Polarity_eBotField));
721    if (rc) {rc = BERR_TRACE(rc);goto done_critsec;}
722
723    /* This actually sends it to the VEC and consumes the field */
724    if (BVBIlib_Encode_Enqueue_isr(display->vbi.enc, field)) {
725        /* if it fails, assume it's a queue overflow and we're done */
726        BVBIlib_List_Return_isr(video->vbilist, field);
727        rc = -1;
728    }
729
730done_critsec:
731    BKNI_LeaveCriticalSection();
732    return rc;
733}
734
735/**
736The following comments apply to NEXUS_Display_WriteTeletext and the PAL display format.
737
738Teletext goes out on VBI lines 5..24. This is 20 lines.
739The VBI PI has a hardcoded BVBI_TT_MAX_LINES, which is 18. Nexus uses this number.
740The VBI PI's BVBI_TT_Line[0] corresponds to VBI line 5, BVBI_TT_Line[19] correponds to VBI line 24.
741VBI line 5 must be skipped because the HW does not support it. TT_START_OFFSET specifies that 1 must be skipped.
742    Apparently 5,6&7 had to be skipped on a 3563.
743If VPS is enabled, VBI line 16 must be skipped.
744If CC is enabled, VBI line 22 must be skipped.
745If WSS is enabled, VBI line 23 must be skipped.
746NEXUS_Display_WriteTeletext can skip these lines by setting an invalid framing code.
747Therefore, if neither VPS, CC or WSS are used, the max # of TT lines/field is 19. If all three are in use, the max is 16.
748
749TODO: if a user needs exactly lineNumber control in the application, I recommend we add bool NEXUS_DisplayVbiSettings.teletextLinenumEnabled
750to enable this. it would default to false so this code remains backward compatible.
751we might also want an option to just ignore lineNumber completely. In that case, NEXUS_DisplayVbiSettings.teletextLinenumMode w/ a tristate enum.
752**/
753#define MAX_TT_LINES_PER_FIELD (BVBI_TT_MAX_LINES)
754#define TT_VBI_LINE_OFFSET 5
755#if BCHP_CHIP == 3563
756#define TT_START_OFFSET 3
757#else
758#define TT_START_OFFSET 1
759#endif
760
761NEXUS_Error NEXUS_Display_WriteTeletext(NEXUS_DisplayHandle display, const NEXUS_TeletextLine *pLines,
762    size_t numLines, size_t *pNumLinesWritten)
763{
764    BERR_Code rc = 0;
765    unsigned i;
766
767    if (numLines && !pLines) return BERR_TRACE(NEXUS_INVALID_PARAMETER);
768    *pNumLinesWritten = 0; /* in case of error, assigned early */
769    if (!display->vbi.settings.teletextEnabled) {
770        BDBG_WRN(("NEXUS_DisplayVbiSettings.teletextEnabled is false"));
771        return BERR_TRACE(NEXUS_NOT_SUPPORTED);
772    }
773
774    for (i=0;i<numLines;) {
775        /* prep ttLines[] */
776        BVBI_TT_Line ttLines[MAX_TT_LINES_PER_FIELD];
777        unsigned ttLineCount = 0;
778        unsigned prevLineNumber = 0;
779        unsigned j;
780
781        for (j=0;j<MAX_TT_LINES_PER_FIELD;j++) {
782            ttLines[j].ucFramingCode = BVBI_TT_INVALID_FRAMING_CODE;
783        }
784
785        /* skip the initial number of lines that can't be output */
786        ttLineCount += TT_START_OFFSET;
787
788        for (;i<numLines && ttLineCount<MAX_TT_LINES_PER_FIELD;i++,ttLineCount++) {
789            if (pLines[i].lineNumber < prevLineNumber) {
790                /* the app wants a field break here */
791                break;
792            }
793
794            /* skip lines which are used by other VBI standards */
795            if ((ttLineCount == 16 - TT_VBI_LINE_OFFSET) && display->vbi.settings.vpsEnabled) ttLineCount++;
796            /* NOTE: these conflicts aren't even possible if TT_VBI_LINE_OFFSET==1 and MAX_TT_LINES_PER_FIELD==18, but they are here for completeness. */
797            if ((ttLineCount == 22 - TT_VBI_LINE_OFFSET) && display->vbi.settings.closedCaptionEnabled) ttLineCount++;
798            if ((ttLineCount == 23 - TT_VBI_LINE_OFFSET) && display->vbi.settings.wssEnabled) ttLineCount++;
799
800            if (ttLineCount >= MAX_TT_LINES_PER_FIELD) {
801                /* need a field break here */
802                break;
803            }
804
805            /* only do work if not BVBI_TT_INVALID_FRAMING_CODE. but always consume the pLines[i] line. */
806            if (pLines[i].framingCode != BVBI_TT_INVALID_FRAMING_CODE) {
807                ttLines[ttLineCount].ucFramingCode = pLines[i].framingCode;
808                BDBG_CASSERT(NEXUS_TELETEXT_LINESIZE == sizeof(ttLines[0].aucData));
809                BKNI_Memcpy(ttLines[ttLineCount].aucData, pLines[i].data, NEXUS_TELETEXT_LINESIZE);
810                BDBG_MSG_TRACE(("copying line[%d] to ttLines[%d]: %02x", i, ttLineCount, ttLines[ttLineCount].ucFramingCode));
811            }
812
813            prevLineNumber = pLines[i].lineNumber;
814        }
815
816        rc = NEXUS_Display_P_SendTeletextField(display, ttLines, ttLineCount, pLines->topField);
817        if (rc) {return 0;} /* Failure is normal for flow control. */
818
819        BDBG_MSG_TRACE(("NEXUS_Display_WriteTeletext: sent %d VBI lines, %d of %d user lines consumed", ttLineCount, i, numLines));
820        (*pNumLinesWritten) = i; /* total actually consumed */
821    }
822
823    BDBG_ASSERT(*pNumLinesWritten <= i);
824
825    return rc;
826}
827
828NEXUS_Error NEXUS_Display_WriteClosedCaption(NEXUS_DisplayHandle display, const NEXUS_ClosedCaptionData *pEntries,
829    size_t numEntries, size_t *pNumEntriesWritten)
830{
831    BVBI_Field_Handle field = NULL;
832    BERR_Code rc = 0;
833    unsigned i;
834    int full = 0;
835    const NEXUS_DisplayModule_State *video = &g_NEXUS_DisplayModule_State;
836
837    *pNumEntriesWritten = 0; /* in case of error, assigned early */
838    if (!display->vbi.settings.closedCaptionEnabled) {
839        BDBG_WRN(("NEXUS_DisplayVbiSettings.closedCaptionEnabled is false"));
840        return BERR_TRACE(NEXUS_NOT_SUPPORTED);
841    }
842
843    for (i=0;i<numEntries;i++) {
844        uint32_t polarityMask;
845
846        BKNI_EnterCriticalSection();
847
848        /* Set up the field. If we fail, make sure to exit the critical section
849        and free memory */
850        rc = BVBIlib_List_Obtain_isr(video->vbilist, &field);
851        if (rc) {rc = 0;goto done_critsec;} /* running out of fields is normal flow control */
852
853        rc = BVBI_Field_SetCCData_isr(field, pEntries[i].data[0], pEntries[i].data[1]);
854        if (rc) {rc = BERR_TRACE(rc);goto done_critsec;}
855
856        switch (pEntries[i].field) {
857        case 0: polarityMask = (1<<BAVC_Polarity_eTopField); break;
858        case 1: polarityMask = (1<<BAVC_Polarity_eBotField); break;
859        default: rc = BERR_TRACE(NEXUS_INVALID_PARAMETER); goto done_critsec;
860        }
861        rc = BVBI_Field_SetPolarity_isr(field, polarityMask);
862        if (rc) {rc = BERR_TRACE(rc);goto done_critsec;}
863
864        /* This actually sends it to the VEC and consumes the field */
865        if (BVBIlib_Encode_Enqueue_isr(display->vbi.enc, field)) {
866            /* if it fails, assume it's a queue overflow and we're done */
867            full = 1;
868        }
869        else {
870            field = NULL;
871        }
872
873done_critsec:
874        if (field) {
875            BVBIlib_List_Return_isr(video->vbilist, field);
876        }
877        BKNI_LeaveCriticalSection();
878
879        if (full || rc)
880            break;
881
882        field = NULL; /* consumed */
883        (*pNumEntriesWritten)++;
884    }
885
886    return rc;
887}
888
889NEXUS_Error NEXUS_Display_WriteGemStar(NEXUS_DisplayHandle display, const NEXUS_GemStarData *pEntries,
890    size_t numEntries, size_t *pNumEntriesWritten)
891{
892
893    BVBI_Field_Handle field = NULL;
894    BERR_Code rc = 0;
895    unsigned i;
896    int full = 0;
897    const NEXUS_DisplayModule_State *video = &g_NEXUS_DisplayModule_State;
898
899    *pNumEntriesWritten = 0; /* in case of error, assigned early */
900
901    if (!g_NEXUS_DisplayModule_State.moduleSettings.vbi.allowGemStar) {
902        BDBG_WRN(("NEXUS_DisplayModuleSettings.vbi.allowGemStar is false"));
903        return BERR_TRACE(NEXUS_NOT_SUPPORTED);
904    }
905    if (!display->vbi.settings.gemStarEnabled) {
906        BDBG_WRN(("NEXUS_DisplayVbiSettings.gemStarEnabled is false"));
907        return BERR_TRACE(NEXUS_NOT_SUPPORTED);
908    }
909
910    for (i=0;i<numEntries;i++) {
911        /* Convert from Nexus to Magnum */
912        BVBI_GSData gsData;
913#ifndef B_HAS_LEGACY_VDC
914        gsData.ulDataLines = pEntries[i].lineMask;
915        gsData.ulErrorLines = 0;
916#endif
917        BDBG_CASSERT(sizeof(pEntries[0].data) == sizeof(gsData.ulData));
918        BKNI_Memcpy(gsData.ulData, pEntries[i].data, sizeof(pEntries[i].data));
919
920        BKNI_EnterCriticalSection();
921
922        /* Set up the field. If we fail, make sure to exit the critical section
923        and free memory */
924        rc = BVBIlib_List_Obtain_isr(video->vbilist, &field);
925        if (rc) {rc = BERR_TRACE(rc);goto done_critsec;}
926        rc = BVBI_Field_SetGSData_isr(field, &gsData);
927        if (rc) {rc = BERR_TRACE(rc);goto done_critsec;}
928
929        if (pEntries[i].topField) {
930            rc = BVBI_Field_SetPolarity_isr(field, 1<<BAVC_Polarity_eTopField);
931            if (rc) {rc = BERR_TRACE(rc);goto done_critsec;}
932        }
933        else {
934            rc = BVBI_Field_SetPolarity_isr(field, 1<<BAVC_Polarity_eBotField);
935            if (rc) {rc = BERR_TRACE(rc);goto done_critsec;}
936        }
937
938        /* This actually sends it to the VEC and consumes the field */
939        if (BVBIlib_Encode_Enqueue_isr(display->vbi.enc, field)) {
940            /* if it fails, assume it's a queue overflow and we're done */
941            full = 1;
942        }
943        else {
944            field = NULL;
945        }
946
947done_critsec:
948        if (field) {
949            BVBIlib_List_Return_isr(video->vbilist, field);
950        }
951        BKNI_LeaveCriticalSection();
952
953        if (full || rc)
954            break;
955
956        field = NULL; /* consumed */
957        (*pNumEntriesWritten)++;
958    }
959
960    return rc;
961}
962
963NEXUS_Error NEXUS_Display_SetWss(NEXUS_DisplayHandle display, uint16_t wssData)
964{
965    if (!display->vbi.settings.wssEnabled) {
966        BDBG_WRN(("NEXUS_DisplayVbiSettings.wssEnabled is false"));
967        return BERR_TRACE(NEXUS_NOT_SUPPORTED);
968    }
969
970    BKNI_EnterCriticalSection();
971    display->vbi.pending.wssSet = true;
972    display->vbi.pending.wssData = wssData;
973    BKNI_LeaveCriticalSection();
974
975    return 0;
976}
977
978NEXUS_Error NEXUS_Display_SetCgms(NEXUS_DisplayHandle display, uint32_t cgmsData)
979{
980    if (!display->vbi.settings.cgmsEnabled) {
981        BDBG_WRN(("NEXUS_DisplayVbiSettings.cgmsEnabled is false"));
982        return BERR_TRACE(NEXUS_NOT_SUPPORTED);
983    }
984
985    BKNI_EnterCriticalSection();
986    /* must queue CGMS value for both top & bottom fields */
987    display->vbi.pending.cgmsTopSet = true;
988    display->vbi.pending.cgmsBottomSet = true;
989    display->vbi.pending.cgmsData = cgmsData;
990    BKNI_LeaveCriticalSection();
991
992    return 0;
993}
994
995NEXUS_Error NEXUS_Display_SetCgmsB(NEXUS_DisplayHandle display, const uint32_t *pCgmsData, unsigned size )
996{
997#if B_HAS_LEGACY_VDC
998    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
999    BSTD_UNUSED(pCgmsData);
1000    BSTD_UNUSED(size);
1001    return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1002#else
1003    if (!pCgmsData) return BERR_TRACE(NEXUS_INVALID_PARAMETER);
1004    if (!g_NEXUS_DisplayModule_State.moduleSettings.vbi.allowCgmsB) {
1005        BDBG_WRN(("NEXUS_DisplayModuleSettings.vbi.allowCgmsB is false"));
1006        return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1007    }
1008    if (!display->vbi.settings.cgmsEnabled) {
1009        BDBG_WRN(("NEXUS_DisplayVbiSettings.cgmsEnabled is false"));
1010        return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1011    }
1012    if (size < 5) {
1013        BDBG_WRN(("CGMS-B requires an array of 5 uint32_t's"));
1014        return BERR_TRACE(NEXUS_INVALID_PARAMETER);
1015    }
1016
1017    BKNI_EnterCriticalSection();
1018    /* must queue CGMS-B value for both top & bottom fields */
1019    display->vbi.pending.cgmsBTopSet = true;
1020    display->vbi.pending.cgmsBBottomSet = true;
1021    BKNI_Memcpy(display->vbi.pending.cgmsBData, pCgmsData, sizeof(uint32_t)*5);
1022    BKNI_LeaveCriticalSection();
1023
1024    return 0;
1025#endif
1026}
1027
1028NEXUS_Error NEXUS_Display_SetVps(NEXUS_DisplayHandle display, const NEXUS_VpsData *pData)
1029{
1030    if (!display->vbi.settings.vpsEnabled) {
1031        BDBG_WRN(("NEXUS_DisplayVbiSettings.vpsEnabled is false"));
1032        return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1033    }
1034
1035    /* only enqueue top field for VPS */
1036    BKNI_EnterCriticalSection();
1037    display->vbi.pending.vpsSet = true;
1038    display->vbi.pending.vpsData.ucByte05 = pData->byte05;
1039    display->vbi.pending.vpsData.ucByte11 = pData->byte11;
1040    display->vbi.pending.vpsData.ucByte12 = pData->byte12;
1041    display->vbi.pending.vpsData.ucByte13 = pData->byte13;
1042    display->vbi.pending.vpsData.ucByte14 = pData->byte14;
1043    display->vbi.pending.vpsData.ucByte15 = pData->byte15;
1044    BKNI_LeaveCriticalSection();
1045
1046    return 0;
1047}
1048
1049/* bvdc_nomacrovision_priv.c does not provide stubs for public API, so we must #if */
1050#ifdef MACROVISION_SUPPORT
1051#include "bvdc_macrovision.h"
1052#endif
1053
1054NEXUS_Error NEXUS_Display_SetMacrovision( NEXUS_DisplayHandle display, NEXUS_DisplayMacrovisionType type, const NEXUS_DisplayMacrovisionTables *pTable)
1055{
1056#ifdef MACROVISION_SUPPORT
1057    BERR_Code rc;
1058    BVDC_MacrovisionType mv_type;
1059
1060    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1061
1062    switch (type) {
1063    case NEXUS_DisplayMacrovisionType_eAgcOnly:
1064        mv_type = BVDC_MacrovisionType_eAgcOnly;
1065        break;
1066    case NEXUS_DisplayMacrovisionType_eAgc2Lines:
1067        mv_type = BVDC_MacrovisionType_eAgc2Lines;
1068        break;
1069    case NEXUS_DisplayMacrovisionType_eAgc4Lines:
1070        mv_type = BVDC_MacrovisionType_eAgc4Lines;
1071        break;
1072    case NEXUS_DisplayMacrovisionType_eAgcOnlyRgb:
1073        mv_type = BVDC_MacrovisionType_eAgcOnly_Rgb;
1074        break;
1075    case NEXUS_DisplayMacrovisionType_eAgc2LinesRgb:
1076        mv_type = BVDC_MacrovisionType_eAgc2Lines_Rgb;
1077        break;
1078    case NEXUS_DisplayMacrovisionType_eAgc4LinesRgb:
1079        mv_type = BVDC_MacrovisionType_eAgc4Lines_Rgb;
1080        break;
1081    case NEXUS_DisplayMacrovisionType_eTest01:
1082        mv_type = BVDC_MacrovisionType_eTest01;
1083        break;
1084    case NEXUS_DisplayMacrovisionType_eTest02:
1085        mv_type = BVDC_MacrovisionType_eTest02;
1086        break;
1087    case NEXUS_DisplayMacrovisionType_eCustom:
1088        mv_type = BVDC_MacrovisionType_eCustomized;
1089        break;
1090    default:
1091    case NEXUS_DisplayMacrovisionType_eNone:
1092        mv_type = BVDC_MacrovisionType_eNoProtection;
1093        break;
1094    }
1095
1096    rc = BVDC_Display_SetMacrovisionType(display->displayVdc, mv_type);
1097    if (rc) return BERR_TRACE(rc);
1098
1099    if (type == NEXUS_DisplayMacrovisionType_eCustom && pTable) {
1100        rc = BVDC_Display_SetMacrovisionTable(display->displayVdc, pTable->cpcTable, pTable->cpsTable);
1101        if (rc) return BERR_TRACE(rc);
1102    }
1103    rc = NEXUS_Display_P_ApplyChanges();
1104    if (rc) return BERR_TRACE(rc);
1105    return 0;
1106#else
1107    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1108    BSTD_UNUSED(type);
1109    BSTD_UNUSED(pTable);
1110    return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1111#endif
1112}
1113
1114/* bvdc_nodcs_priv.c does not provide stubs for public API, so we must #if */
1115#ifdef DCS_SUPPORT
1116#include "bvdc_dcs.h"
1117#endif
1118
1119NEXUS_Error NEXUS_Display_SetDcs( NEXUS_DisplayHandle display, NEXUS_DisplayDcsType type )
1120{
1121#ifdef DCS_SUPPORT
1122    BERR_Code rc;
1123
1124    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1125
1126    rc = BVDC_Display_SetDcsKey( display->displayVdc, (int)type - (int)NEXUS_DisplayDcsType_eOff, 0x0 );
1127    if (rc) return BERR_TRACE(rc);
1128
1129    rc = NEXUS_Display_P_ApplyChanges();
1130    if (rc) return BERR_TRACE(rc);
1131    return 0;
1132#else
1133    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1134    BSTD_UNUSED(type);
1135
1136    return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1137#endif
1138}
1139
1140NEXUS_Error NEXUS_Display_WriteAmol( NEXUS_DisplayHandle display, const NEXUS_AmolData *pEntries, size_t numEntries, size_t *pNumEntriesWritten )
1141{
1142    BVBI_Field_Handle field = NULL;
1143    BERR_Code rc = 0;
1144    unsigned i;
1145    int full = 0;
1146    const NEXUS_DisplayModule_State *video = &g_NEXUS_DisplayModule_State;
1147
1148    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1149
1150    *pNumEntriesWritten = 0; /* in case of error, assigned early */
1151    if (!g_NEXUS_DisplayModule_State.moduleSettings.vbi.allowAmol) {
1152        BDBG_WRN(("NEXUS_DisplayModuleSettings.vbi.allowAmol is false"));
1153        return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1154    }
1155    if (!display->vbi.settings.amolEnabled) {
1156        BDBG_WRN(("NEXUS_DisplayVbiSettings.amolEnabled is false"));
1157        return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1158    }
1159
1160    for (i=0;i<numEntries;i++) {
1161        uint32_t polarityMask;
1162
1163        BKNI_EnterCriticalSection();
1164
1165        /* Set up the field. If we fail, make sure to exit the critical section
1166        and free memory */
1167        rc = BVBIlib_List_Obtain_isr(video->vbilist, &field);
1168        if (rc) {rc = 0;goto done_critsec;} /* running out of fields is normal flow control */
1169
1170        rc = BVBI_Field_SetAMOLData_isr(field, display->vbi.amolType, (uint8_t*)pEntries[i].data, pEntries[i].length);
1171        if (rc) {rc = BERR_TRACE(rc);goto done_critsec;}
1172
1173        polarityMask = pEntries[i].topField ? (1<<BAVC_Polarity_eTopField) : (1<<BAVC_Polarity_eBotField);
1174        rc = BVBI_Field_SetPolarity_isr(field, polarityMask);
1175        if (rc) {rc = BERR_TRACE(rc);goto done_critsec;}
1176
1177        /* This actually sends it to the VEC and consumes the field */
1178        if (BVBIlib_Encode_Enqueue_isr(display->vbi.enc, field)) {
1179            /* if it fails, assume it's a queue overflow and we're done */
1180            full = 1;
1181        }
1182        else {
1183            field = NULL;
1184        }
1185
1186done_critsec:
1187        if (field) {
1188            BVBIlib_List_Return_isr(video->vbilist, field);
1189        }
1190        BKNI_LeaveCriticalSection();
1191
1192        if (full || rc)
1193            break;
1194
1195        field = NULL; /* consumed */
1196        (*pNumEntriesWritten)++;
1197    }
1198    return rc;
1199}
1200
1201#else /* B_HAS_VBI */
1202
1203BERR_Code
1204NEXUS_Display_P_ConnectVbi(NEXUS_DisplayHandle display)
1205{
1206    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1207    return 0;
1208}
1209
1210void
1211NEXUS_Display_P_DisconnectVbi(NEXUS_DisplayHandle display)
1212{
1213    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1214}
1215
1216BERR_Code
1217NEXUS_Display_P_VbiData_isr(NEXUS_DisplayHandle display, BVBI_Field_Handle vbiData)
1218{
1219    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1220    BSTD_UNUSED(vbiData);
1221    return 0;
1222}
1223
1224void
1225NEXUS_Display_P_DisableVbi(NEXUS_DisplayHandle display)
1226{
1227    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1228}
1229
1230BERR_Code
1231NEXUS_Display_P_EnableVbi(NEXUS_DisplayHandle display, NEXUS_VideoFormat format)
1232{
1233    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1234    BSTD_UNUSED(format);
1235    return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1236}
1237
1238void NEXUS_Display_GetVbiSettings(NEXUS_DisplayHandle display, NEXUS_DisplayVbiSettings *pSettings)
1239{
1240    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1241    BSTD_UNUSED(pSettings);
1242}
1243
1244NEXUS_Error NEXUS_Display_SetVbiSettings(NEXUS_DisplayHandle display, const NEXUS_DisplayVbiSettings *pSettings)
1245{
1246    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1247    BSTD_UNUSED(pSettings);
1248    return BERR_SUCCESS;
1249}
1250
1251BERR_Code NEXUS_Display_P_SendTeletextField(NEXUS_DisplayHandle display, BVBI_TT_Line *ttLines, unsigned ttLineCount)
1252{
1253    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1254    BSTD_UNUSED(ttLines);
1255    BSTD_UNUSED(ttLineCount);
1256    return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1257}
1258
1259NEXUS_Error NEXUS_Display_WriteTeletext(NEXUS_DisplayHandle display, const NEXUS_TeletextLine *pLines,
1260    size_t numLines, size_t *pNumLinesWritten)
1261{
1262    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1263    BSTD_UNUSED(pLines);
1264    BSTD_UNUSED(numLines);
1265    BSTD_UNUSED(pNumLinesWritten);
1266    return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1267}
1268
1269NEXUS_Error NEXUS_Display_WriteClosedCaption(NEXUS_DisplayHandle display, const NEXUS_ClosedCaptionData *pEntries,
1270    size_t numEntries, size_t *pNumEntriesWritten)
1271{
1272    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1273    BSTD_UNUSED(pEntries);
1274    BSTD_UNUSED(numEntries);
1275    BSTD_UNUSED(pNumEntriesWritten);
1276    return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1277}
1278
1279NEXUS_Error NEXUS_Display_WriteGemStar(NEXUS_DisplayHandle display, const NEXUS_GemStarData *pEntries,
1280    size_t numEntries, size_t *pNumEntriesWritten)
1281{
1282    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1283    BSTD_UNUSED(pEntries);
1284    BSTD_UNUSED(numEntries);
1285    BSTD_UNUSED(pNumEntriesWritten);
1286    return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1287}
1288
1289
1290NEXUS_Error NEXUS_Display_SetWss(NEXUS_DisplayHandle display, uint16_t wssData)
1291{
1292    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1293    BSTD_UNUSED(wssData);
1294    return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1295}
1296
1297NEXUS_Error NEXUS_Display_SetCgms(NEXUS_DisplayHandle display, uint32_t cgmsData)
1298{
1299    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1300    BSTD_UNUSED(cgmsData);
1301    return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1302}
1303
1304NEXUS_Error NEXUS_Display_SetCgmsB(NEXUS_DisplayHandle display, const uint32_t *pCgmsData, unsigned size )
1305{
1306    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1307    BSTD_UNUSED(pCgmsData);
1308    BSTD_UNUSED(size);
1309    return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1310}
1311
1312NEXUS_Error NEXUS_Display_SetVps(NEXUS_DisplayHandle display, const NEXUS_VpsData *pData)
1313{
1314    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1315    BSTD_UNUSED(pData);
1316    return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1317}
1318
1319NEXUS_Error NEXUS_Display_SetMacrovision( NEXUS_DisplayHandle display, NEXUS_DisplayMacrovisionType type, const NEXUS_DisplayMacrovisionTables *pTable)
1320{
1321    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1322    BSTD_UNUSED(type);
1323    BSTD_UNUSED(pTable);
1324    return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1325}
1326
1327NEXUS_Error NEXUS_Display_SetDcs( NEXUS_DisplayHandle display, NEXUS_DisplayDcsType type )
1328{
1329    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1330    BSTD_UNUSED(type);
1331    return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1332}
1333
1334NEXUS_Error NEXUS_Display_WriteAmol( NEXUS_DisplayHandle display, const NEXUS_AmolData *pEntries, size_t numEntries, size_t *pNumEntriesWritten )
1335{
1336    BDBG_OBJECT_ASSERT(display, NEXUS_Display);
1337    BSTD_UNUSED(pEntries);
1338    BSTD_UNUSED(numEntries);
1339    BSTD_UNUSED(pNumEntriesWritten);
1340    return BERR_TRACE(NEXUS_NOT_SUPPORTED);
1341}
1342
1343#endif /* B_HAS_VBI */
Note: See TracBrowser for help on using the repository browser.