source: svn/trunk/newcon3bcm2_21bu/magnum/portinginterface/hdm/7552/bhdm_edid.c

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

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 147.2 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2002-2012, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bhdm_edid.c $
11 * $brcm_Revision: Hydra_Software_Devel/162 $
12 * $brcm_Date: 3/23/12 10:30a $
13 *
14 * Module Description:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/portinginterface/hdm/7038/bhdm_edid.c $
19 *
20 * Hydra_Software_Devel/162   3/23/12 10:30a rgreen
21 * SW7346-745: check scan width for all EDID versions to determine if
22 * detailed timing support is for 50 vs 60hz
23 *
24 * Hydra_Software_Devel/161   3/19/12 11:34a rgreen
25 * SW7425-2650: Fix memory leak in HDM PI; Delcare/store supported Video
26 * ID Codes in hdm handlle vs mallocing to build list each time
27 *
28 * Hydra_Software_Devel/160   3/14/12 1:22p rgreen
29 * SW7420-2277: Fix incorrectly reported 1080p 24 or 1080p 30 support from
30 * BHDM_EDID_GetVideoInfo function
31 *
32 * Hydra_Software_Devel/159   11/22/11 6:02p vle
33 * SW7425-1140: Merge to mainline.  Remove all CEC functionality out of
34 * HDM PI.
35 *
36 * Hydra_Software_Devel/SW7425-1140/2   11/22/11 5:48p vle
37 * SW7425-1140: Add BHDM_CONFIG_CEC_LEGACY_SUPPORT for backward compatible
38 * for CEC legacy platforms.
39 *
40 * Hydra_Software_Devel/SW7425-1140/1   11/16/11 12:16p vle
41 * SW7425-1140: Remove all CEC functionalities out of HDM PI
42 *
43 * Hydra_Software_Devel/158   10/18/11 5:16p vle
44 * SW7125-1091: should not stop parsing DTD in EDID extension even if
45 * there's no NativeFormatDescriptors
46 *
47 * Hydra_Software_Devel/157   9/15/11 6:07p vle
48 * SW7420-2056: merge to mainline
49 *
50 * Hydra_Software_Devel/SW7420-2056/1   9/15/11 3:51p vle
51 * SW7420-2056: Fix incorrect Hdmi 3D formats support from parsing EDID
52 *
53 * Hydra_Software_Devel/156   6/24/11 5:11p rgreen
54 * SW7405-5358, SW7405-5312: always indicate 3D formats have been checked
55 * whenever HDMI VSDB is parsed
56 *
57 * Hydra_Software_Devel/155   6/17/11 5:36p vle
58 * SW7405-5318: Fix bug where variable was used before being populated.
59 *
60 * Hydra_Software_Devel/154   6/17/11 1:42p vle
61 * SW7405-5358, SW7405-5312: Separate 3D support from EDID parser to allow
62 * easier back port
63 *
64 * Hydra_Software_Devel/153   5/4/11 1:03p vle
65 * SW7405-5208: Merge to mainline
66 *
67 * Hydra_Software_Devel/SW7405-5208/1   4/5/11 6:48p vle
68 * SW7405-5208: Fix incorrect parsing of VSDB in some cases.
69 *
70 * Hydra_Software_Devel/152   1/7/11 3:54p vle
71 * SW7405-5076: merge to mainline
72 *
73 * Hydra_Software_Devel/SW7405-5076/1   1/4/11 4:48p vle
74 * SW7405-5076: Fix EDID parser when HDMI_3D_Present bit set to 0.
75 *
76 * Hydra_Software_Devel/150   10/14/10 5:34p rgreen
77 * SW7125-659: Indicate HDMI support only if VSDB has IEEE Registration ID
78 * 0x000C03.  Clear RxVSDB in IsRxDeviceHdmi;  Report 3d Formats for HDMI
79 * devices only Force Full Range RGB for supported Colorimetry for DVI
80 * formats
81 *
82 * Hydra_Software_Devel/149   9/3/10 4:08p vle
83 * SW7400-2868: Fix potential bug from previous implementation
84 *
85 * Hydra_Software_Devel/148   8/27/10 7:48p vle
86 * SW7400-2868: Fix potential EDID parser issue when parsing 3D supports
87 * on the first 16 video descriptor
88 *
89 * Hydra_Software_Devel/147   8/19/10 6:28p vle
90 * SW7335-815: Fix error passing bool by value instead of reference
91 *
92 * Hydra_Software_Devel/146   7/15/10 1:37p erickson
93 * SW7400-2855: init BCM_VideoFmt out param in BHDM_EDID_GetDetailTiming
94 * for error path
95 *
96 * Hydra_Software_Devel/145   6/22/10 6:57p vle
97 * SW7405-3994: Add support to parse all Shorthand and additional 3D
98 * Timing/Structure support indication in HDMI 1.4a
99 *
100 * Hydra_Software_Devel/144   6/7/10 7:16p vle
101 * SW7405-3994: Make sure no misleading error messages are printed for
102 * non-3D TV EDID.
103 *
104 * Hydra_Software_Devel/143   6/4/10 6:09p vle
105 * SW7405-3994: Merge to main branch
106 *
107 * Hydra_Software_Devel/SW7405-3994/2   6/4/10 2:37p vle
108 * SW7405-3994: Need to check monitor vertical range, not max vertical
109 * rate, for 50/60Hz support.
110 *
111 * Hydra_Software_Devel/SW7405-3994/1   5/14/10 6:12p vle
112 * SW7405-3994: Add support to check for supported 3D formats.
113 *
114 * Hydra_Software_Devel/142   5/27/10 11:37a vle
115 * SW7550-438: Fix Coverity issue.
116 *
117 * Hydra_Software_Devel/141   5/11/10 7:14p vle
118 * SW7405-3994: Add topAndBottom 3D Structure
119 *
120 * Hydra_Software_Devel/140   5/10/10 10:58a erickson
121 * SW7405-3994: fix compilation error
122 *
123 * Hydra_Software_Devel/139   5/7/10 5:45p rgreen
124 * SW7405-3994: Update EDID parsing for 3D structure
125 *
126 * Hydra_Software_Devel/138   4/23/10 10:43a vle
127 * SW7420-676: merge to main branch
128 *
129 * Hydra_Software_Devel/SW7420-676/2   4/22/10 4:54p vle
130 * SW7420-676: Fix incorrect programming in return size.
131 *
132 * Hydra_Software_Devel/SW7420-676/1   4/21/10 2:27p vle
133 * SW7420-676: Add API to return supported video info
134 *
135 * Hydra_Software_Devel/137   4/16/10 1:37p rgreen
136 * SW7405-3994: Fix overwriting of RxSupported features when parsing the
137 * VSDB
138 *
139 * Hydra_Software_Devel/136   4/5/10 10:12a rgreen
140 * SW7405-3994: Merge support for parsing HDMI 1.4 EDID VSDB
141 *
142 * Hydra_Software_Devel/SW7401-4363/3   3/5/10 4:11p rgreen
143 * JIRA:SW7405-3994: Update HDMI 1.4 parsing for 3D Structure fields in
144 * the VSDB
145 *
146 * Hydra_Software_Devel/SW7401-4363/2   3/1/10 7:23p rgreen
147 * SW7401-4363: Update the EDID parsing of the Vendor Specific Data Block
148 *
149 * Hydra_Software_Devel/SW7401-4363/1   3/1/10 3:35p rgreen
150 * SW7401-4363: Add Support to parse 3D information in the VSDB portion of the EDID
151 *
152 * Hydra_Software_Devel/135   3/1/10 11:32a rgreen
153 * SW7420-579: Rename DetailedTiming to SupportedDetailTiming to eliminate
154 * confusion when reading code
155 *
156 * Hydra_Software_Devel/134   2/26/10 5:18p vle
157 * SW7405-3016: Remove software i2c settings from HDM PI. This mode is
158 * configure in I2C module
159 *
160 * Hydra_Software_Devel/133   9/24/09 3:40p vle
161 * SW7405-2871: Reduce HDMI I2C failure retry count from 10 to 1 since
162 * each retry can wait up to 30seconds.
163 *
164 * Hydra_Software_Devel/132   9/23/09 11:15a vle
165 * SW7601-168: Fix mistake on merging changes from bdvd_v3.0 branch.
166 *
167 * Hydra_Software_Devel/131   9/22/09 1:37p vle
168 * SW7601-168: Merge in changes from bdvd_v3.0 branch.
169 *
170 * Hydra_Software_Devel/bdvd_v3.0/4   9/17/09 1:57p rbshah
171 * PR16614[DVD]:[ see HiDef-DVD bug tracking system for more info ].  Add
172 * missing check for 4x pixel repetition capability in the
173 * VSDB block parsing. This would prevent 480i,p or 576i,p from
174 * being detected if 1x or 2x repetition was not supported by
175 * the receiver.
176 *
177 * Reviewed by: Eric Trudeau
178 *
179 * Hydra_Software_Devel/bdvd_v3.0/3   9/17/09 10:25a rbshah
180 * PR16611[DVD]:[ see HiDef-DVD bug tracking system for more info ].
181 * Enhance EDID parsing of detailed timing descriptor so we can
182 * differentiate between 24Hz, 25/50Hz, and 30/60Hz refresh rates
183 * properly. This is really needed for v1/v2 CEA Extensions because
184 * explicit video codes are not used as they are in v3.
185 *
186 * Reviewed by: Eric Trudeau
187 *
188 * Hydra_Software_Devel/130   9/15/09 5:59p vle
189 * SW7601-168: Merge fixes from bdvd_v3.0 branch.
190 *
191 * Hydra_Software_Devel/bdvd_v3.0/2   9/2/09 3:31p rbshah
192 * PR16468[DVD]:[ see HiDef-DVD bug tracking system for more info ].
193 * Merged with the latest portinginterface/hdm and syslib/hdcplib files.
194 *
195 * Hydra_Software_Devel/bdvd_v2.0/11   6/29/09 11:19a rbshah
196 * PR_15307[DVD]:[ see HiDef-DVD bug tracking system for more info ].  Fix
197 * problem in parsing EDID Extension version 3. The Data Block collection
198 * was being dropped completely. Re-worked the logic so things are
199 * processed in order.
200 *
201 * Hydra_Software_Devel/129   9/1/09 3:51p vle
202 * SW7403-870: Fix build issues for 7403/7401.
203 *
204 * Hydra_Software_Devel/128   8/28/09 3:59p vle
205 * SW7403-870: 720p 25/30Hz are not supported by 7401/7403
206 *
207 * Hydra_Software_Devel/127   6/23/09 5:08p rgreen
208 * PR56323: Compile in debug EDID based on
209 * BHDM_CONFIG_DEBUG_EDID_PROCESSING only
210 *
211 * Hydra_Software_Devel/126   6/23/09 3:34p vle
212 * PR55934: Merge bdvd fixes into main branch.
213 *
214 * Hydra_Software_Devel/125   5/19/09 7:29p vle
215 * PR 55080: EDID parsing should not stop if an error was found in a
216 * detail timing block.
217 *
218 * Hydra_Software_Devel/124   5/15/09 4:58p rgreen
219 * PR54128: Update EDID processing to add DDP audio passthrough support
220 *
221 * Hydra_Software_Devel/123   5/6/09 1:57p vle
222 * PR 54882: Fix EDID parser bug in parsing Vendor Specific Data Block
223 * (VSDB)
224 *
225 * Hydra_Software_Devel/bdvd_v2.0/10   6/10/09 4:30p rbshah
226 * PR_14564[DVD]:[ see HiDef-DVD bug tracking system for more info ].
227 * Bring forward fix from v1.4 & Hydra into v2.* branches.
228 *
229 * Hydra_Software_Devel/bdvd_v2.0/9   6/8/09 12:44p rbshah
230 * PR_14946[DVD]:[ see HiDef-DVD bug tracking system for more info ].  Add
231 * missing code in the EDID parser to stash away the Product ID.
232 *
233 * Code reviewer: Ashish Koul.
234 *
235 * Hydra_Software_Devel/bdvd_v2.0/8   6/4/09 11:36a rbshah
236 * PR_14898[DVD]:[ see HiDef-DVD bug tracking system for more info ].  Fix
237 * EDID parsing logic so it doesn't pick up 25Hz, 30Hz, and 50Hz
238 * refresh rates unless these are explicitly indicated as being supported
239 * by the receiver. These rates were considered valid by the old code if
240 * the TV supported 24Hz (because they fell in the 24-60Hz range).
241 *
242 * Reviewed by: Eric Trudeau.
243 *
244 * Hydra_Software_Devel/bdvd_v2.0/7   5/5/09 4:07p rbshah
245 * PR_14433[DVD]:[ see HiDef-DVD bug tracking system for more info ].  Fix
246 * bug in parsing the Vendor Specific Data Block (VSDB). The size of
247 * this block wasn't being taken into account correctly all the time and
248 * a random byte was getting used to determine whether or not the TV
249 * supports Deep Color.
250 *
251 * Hydra_Software_Devel/122   3/23/09 7:30p vle
252 * PR52390:Merge to main branch
253 * PAL/576p format uses ITU_R_601 colorimetry.
254 *
255 * Hydra_Software_Devel/121   3/9/09 3:20p vle
256 * PR50570, PR50918, PR49277, PR49652, PR52873:
257 * Add API to mute/unmute audio, update pixel repitition support, add
258 * SetPixelDataOverride API for transmission of black video. Merge
259 * changes/updates from bdvd_v2.0 to main branch.
260 *
261 * Hydra_Software_Devel/PR52390/2   3/10/09 3:32p vle
262 * PR52390: 576p format also uses ITU_R_601 colorimetry.
263 *
264 * Hydra_Software_Devel/PR52390/1   3/4/09 8:29p vle
265 * PR52390: PAL formats uses ITU_R_601 colorimetry.
266 *
267 * Hydra_Software_Devel/120   2/27/09 8:56p vle
268 * PR52505: Fix non-const global data in HDM and HDCPLIB
269 *
270 * Hydra_Software_Devel/119   2/2/09 7:18p vle
271 * PR51682: Add BREG_I2C_ReadSwEDDC support for EDID read.
272 *
273 * Hydra_Software_Devel/bdvd_v2.0/2   1/30/09 1:04p rbshah
274 * PR_10346 [ see HiDef-DVD bug tracking system for more info ].  Fix bug
275 * in BHDM-EDID: get a false positive for pixel repetition on
276 * DVI monitors. This is in response to CSP 206270 (No HDCP event
277 * with DVI TV/Monitor).
278 *
279 * Also turned all BDBG_ERR and BDBG_WRN messages to BKNI_Prints in
280 * bdvd-hdmi for now.
281 *
282 * Hydra_Software_Devel/bdvd_v2.0/1   1/19/09 3:35p rbshah
283 * PR_12621 [ see HiDef-DVD bug tracking system for more info ].
284 * BHDM_EDID_CheckRxHdmiVideoSupport() was reading EDID over DDC even
285 * when
286 * there was a cached copy.
287 *
288 * Hydra_Software_Devel/118   12/23/08 7:57p vle
289 * PR50081, PR49866: Merge to main branch
290 * Add new API allowing application to get the device physical address
291 * even without CEC support.
292 * Add deep color support.
293 *
294 * Hydra_Software_Devel/PR50081/2   12/11/08 2:24p vle
295 * PR49866: Add new API allowing application to get the device physical
296 * address even without CEC support.
297 *
298 * Hydra_Software_Devel/PR50081/1   12/8/08 5:29p vle
299 * PR50081: add deep color support.
300 *
301 * Hydra_Software_Devel/117   10/30/08 5:51p vle
302 * PR47447: Merge to main branch.
303 * Add new GetReceivedMessage API. Use same CEC configuration for
304 * transmitter and receiver.
305 *
306 * Hydra_Software_Devel/116   10/24/08 5:56p vle
307 * PR 44535: Merge from bdvd v2.0 branch
308 *
309 * Hydra_Software_Devel/115   10/17/08 12:33p vle
310 * PR 47470: Check for the returned format pointer info. If a custom
311 * format is used, there is no information available from BFMT
312 *
313 * Hydra_Software_Devel/114   10/10/08 6:29p vle
314 * PR 47470: Update to fix build issues with older, legacy platforms.
315 *
316 * Hydra_Software_Devel/113   10/8/08 6:29p vle
317 * PR 47470: Check for the returned format pointer info. If a custom
318 * format is used, there is no information available from BFMT
319 *
320 * Hydra_Software_Devel/PR47447/1   9/30/08 7:04p vle
321 * PR47447: Add new GetReceivedMessage API. Use same CEC configuration for
322 * transmitter and receiver.
323 *
324 * Hydra_Software_Devel/112   9/23/08 4:56p rgreen
325 * PR47281: Enable WMA Support
326 *
327 * Hydra_Software_Devel/111   7/9/08 3:31p vishk
328 * PR 43983: KLOCWORK: bhdm_edid.c, buffer overflow.
329 *
330 * Hydra_Software_Devel/110   7/7/08 5:52p vle
331 * PR44482, PR43424: set default device (HDMI vs DVI) and colorimetry when
332 * no EDID found.
333 *
334 * Hydra_Software_Devel/109   6/6/08 6:24p vle
335 * PR 43424: Do not ignore EDID Checksum error.
336 *
337 * Hydra_Software_Devel/108   4/15/08 2:37p vishk
338 * PR 41193: BHDM_EDID_DumpRawEDID can't dump all blocks when there is
339 * blockmap in EDID
340 *
341 * Hydra_Software_Devel/107   4/12/08 5:08p vishk
342 * PR 41193: BHDM_EDID_DumpRawEDID can't dump all blocks when there is
343 * blockmap in EDID
344 *
345 * Hydra_Software_Devel/106   4/2/08 10:18a mward
346 * PR40681: null version of BHDM_EDID_P_PrintEdid(),
347 * BHDM_EDID_DumpRawEDID() for DEBUG=n.
348 *
349 * Hydra_Software_Devel/105   3/27/08 4:22p vishk
350 * PR 40681: Added support to parse extended EDID.
351 *
352 * Hydra_Software_Devel/104   3/27/08 11:24a vishk
353 * PR 40681: Added support to parse extended EDID.
354 *
355 * Hydra_Software_Devel/103   3/18/08 2:34p rgreen
356 * PR39705: Support reading CEA Timing Extenstion V4 as V3
357 *
358 * Hydra_Software_Devel/102   3/13/08 4:44p rgreen
359 * PR39988: Fix compilation error for 7401,7038
360 *
361 * Hydra_Software_Devel/101   2/27/08 2:16p rgreen
362 * PR40063,PR24461: Support parsing DVI V3 Timing Extensions
363 * Specify HDMI Audio Support only VSDB Audio Bit is set
364 *
365 * Hydra_Software_Devel/100   2/11/08 11:56a rgreen
366 * PR39232: Merge changes
367 *
368 * Hydra_Software_Devel/bdvd_v10/4   2/7/08 12:53p rbshah
369 * PR_7515 [ Use latest hdm and hdmlib porting interfaces (for HDCP
370 * related fixes) ].
371 *
372 * Hydra_Software_Devel/bdvd_v10/3   2/1/08 11:13a mpeteri
373 * PR_7394 [ Export setting required to choose between reencode or pcm ].
374 * Fixes for PR7394 and PR6652 - this checkin is built upon 1/31 RAP
375 * label and requires that the RAP label be below v10 latest rule in the
376 * config spec.  An updated config spec will be sent out to demonstrate
377 * this requirement.  NOTE this is temporary and will go back to normal
378 * when RAP label picks up the branched changes.
379 * RAP label to use - RAP_7440_FW_Phase2D_20080131
380 *
381 * Hydra_Software_Devel/99   1/28/08 2:39p vle
382 * PR 26877: Force to alternate preferred format when DVI 1360x768p 60Hz
383 * or DVI 1366x768p 60Hz is detected.
384 *
385 * Hydra_Software_Devel/98   1/22/08 7:02p rgreen
386 * PR38489: Force supported formats to remember the highest number of
387 * supported audio channels.  Add additional debug messages for Sample
388 * Rate.
389 *
390 * Hydra_Software_Devel/97   11/9/07 4:48p mward
391 * PR36915: Eliminate compiler warning for DEBUG=n.
392 *
393 * Hydra_Software_Devel/96   10/9/07 6:43p rgreen
394 * PR35740: fix C99 declaration compilation error for xvd_vdc_test
395 *
396 * Hydra_Software_Devel/95   10/9/07 4:21p vle
397 * PR 35085: HDM-Coverity (CID 371): NO_EFFECT. Fix coverity issue for
398 * comparing array against NULL
399 *
400 * Hydra_Software_Devel/94   10/4/07 1:30p rgreen
401 * PR35740: Add support to parse new audio formats in CEA861C and 861D.
402 * Update debug messages
403 *
404 * Hydra_Software_Devel/93   10/2/07 11:22a vle
405 * PR 35085: Fix coverity issue for comparing array against NULL
406 *
407 * Hydra_Software_Devel/92   9/24/07 6:25p rgreen
408 * PR35326:  Check/report for 1080p 60Hz support based on platform
409 *
410 * Hydra_Software_Devel/91   9/18/07 5:33p rgreen
411 * PR27746,PR31853:
412 * fix debug bug to print last line of Raw EDID dump
413 * fix bug to correctly interpret the number of bytes in the Vendor
414 * Specific DB
415 * Display HDMI 1.3 EDID Info only when it exists
416 *
417 * Hydra_Software_Devel/90   8/23/07 4:56p vle
418 * PR 34249: Check BCM supported format for 24, 25, and 30Hz formats.
419 *
420 * Hydra_Software_Devel/89   8/3/07 4:17p vle
421 * PR 33783: Fix incorrectly stored audio sampling size in the audio
422 * descriptor (3rd byte)
423 *
424 * Hydra_Software_Devel/88   8/1/07 8:04p vle
425 * PR 33721: VGA format (640x480p) should be supported by all HDMI
426 * receivers.
427 *
428 * Hydra_Software_Devel/87   7/19/07 7:57p vle
429 * PR 28667: Verify buffer size before memcpy
430 *
431 * Hydra_Software_Devel/86   6/6/07 3:29p vle
432 * PR 31853: Update array range of EDID data array
433 *
434 * Hydra_Software_Devel/85   5/24/07 12:15p vle
435 * PR 31570: Add capability to parse CEA Colorimetry Data Block
436 *
437 * Hydra_Software_Devel/84   5/14/07 2:02p vle
438 * PR 30730: Modify EDID parser to parse all EDID blocks including those
439 * V3 Timing Extension blocks
440 *
441 * Hydra_Software_Devel/83   2/15/07 2:47p vle
442 * PR 27746: Added Support to EDID parser to process VSDB fields contained
443 * in HDMI 1.3
444 *
445 * Hydra_Software_Devel/82   2/8/07 12:16p rgreen
446 * PR27746: Add 3563 EDID for debugging EDIDs containing HDMI 1.3 support
447 *
448 * Hydra_Software_Devel/81   1/29/07 6:52p vle
449 * PR 26912: Ensure a valid supported video format is returned for
450 * corrupted or badly formed EDID.
451 *
452 * Hydra_Software_Devel/80   1/17/07 8:07p vle
453 * PR 20872: Abort parsing invalid EDID info and check for validation of
454 * EDID before accessing EDID info.
455 *
456 * Hydra_Software_Devel/79   1/11/07 6:36p vle
457 * PR 26877:
458 * Force to alternate preferred format when 1366x768 is detected.
459 * Added Dummy descriptor tag.
460 *
461 * Hydra_Software_Devel/78   12/21/06 2:59p rgreen
462 * PR26531: Should use #if instead of #ifdef for compile flag
463 * BDBG_DEBUG_BUILD
464 *
465 * Hydra_Software_Devel/77   10/20/06 11:28a rgreen
466 * PR20526: Fix release code warning
467 *
468 * Hydra_Software_Devel/76   10/2/06 7:29p rgreen
469 * PR24461: Always report PCM Audio Support for HDMI Rx
470 *
471 * Hydra_Software_Devel/75   9/20/06 9:53p rgreen
472 * PR24304: Clean up debug output for EDID dump. Fix mislabeled vertical
473 * parameters (lines vs pixels)
474 *
475 * Hydra_Software_Devel/74   9/14/06 8:01p rgreen
476 * PR24291: Do not check for 1080p 60Hz Support
477 *
478 * Hydra_Software_Devel/73   7/13/06 11:26a rgreen
479 * PR22588: Copy additional fields to Basic EDID data structure: Vendor
480 * ID, Manufacturer week/year, feature support, and Serial Number
481 *
482 * Hydra_Software_Devel/72   6/22/06 2:34p rgreen
483 * PR22104: Add BHDM_EDID_GetSupportedColorimetry function to return
484 * preferred *and* supported format.  Use instead of BHDM_GetColorimetry
485 *
486 * Hydra_Software_Devel/71   6/12/06 5:14p rgreen
487 * PR22104: Force HDMI RGB when YCrCb not supported; Update BHDM_EDID
488 * debug messages
489 *
490 * Hydra_Software_Devel/70   5/26/06 4:16p rgreen
491 * PR21621: enhance audio format debug messages to show format names vs
492 * codes
493 *
494 * Hydra_Software_Devel/69   5/10/06 9:57a rgreen
495 * PR21039: Use magnum naming conventions for macros BHDM_CEC_SUPPORT vs
496 * HDMI_CEC_SUPPORT
497 *
498 * Hydra_Software_Devel/68   5/2/06 6:33p rgreen
499 * PR21039: Update macros to magnum naming conventions. Fix CEC support
500 * and DVO support macros
501 *
502 * Hydra_Software_Devel/67   4/21/06 4:23p rgreen
503 * PR20871: Fix HDMI EDID Parsing for 1080p formats (various Hz)
504 * Add debug mode for checking EDIDs
505 *
506 * Hydra_Software_Devel/66   4/7/06 5:50p rgreen
507 * PR20721: Copy Cached EDID Block for return in BHDM_EDID_GetNthBlock
508 *
509 * Hydra_Software_Devel/65   3/23/06 7:55p rgreen
510 * PR20327:
511 * Add 7438 Compilation Support
512 *
513 * Add new compilation configuration macros to remove BCHP_XXX references
514 * from source files
515 * BHDM_CONFIG_DVO_7038BX_VERSION compilation macro
516 * BHDM_CONFIG_88_2__176_4__192_SAMPLE_RATES
517 *
518 * Hydra_Software_Devel/64   2/28/06 3:30p rgreen
519 * PR18147: Add support for HDMI 1080p/30 Hz
520 *
521 * Hydra_Software_Devel/63   2/8/06 5:00p rgreen
522 * PR8896: Fix compilation warnings.
523 *
524 * Hydra_Software_Devel/62   2/3/06 4:08p rgreen
525 * PR17778: Account for new frequencies for PC formats
526 *
527 * Hydra_Software_Devel/61   2/2/06 5:22p rgreen
528 * PR19283,PR8896: Copy physical address to hdmi handle
529 * Add debug info for PC formats used when searching EDIDs
530 *
531 * Hydra_Software_Devel/60   1/10/06 12:11p rgreen
532 * PR16966: Fix compilation warning
533 *
534 * Hydra_Software_Devel/59   1/9/06 3:19p rgreen
535 * PR 18790: Update HDM with C3 defines using new version method
536 * PR 18394: Fix PC format found table for 1024x768 and 800x600
537 *
538 * Hydra_Software_Devel/58   12/5/05 10:37a rgreen
539 * PR18394: HDMI connection fails with Sagem HD-L32 TV (PAL) monitor.
540 * Indicate supported video formats have been checked if a) Detail Timing
541 * is found, b) Established Timing is found, or c) CEA Version 3 Video
542 * Block is found
543 *
544 * Hydra_Software_Devel/57   11/29/05 2:38p rgreen
545 * PR16966: Fix "if" comparison when checking for video formats
546 *
547 * Hydra_Software_Devel/56   9/23/05 4:59p rgreen
548 * PR17297: Relax EDID checking;
549 *
550 * Hydra_Software_Devel/55   9/14/05 6:33p rgreen
551 * PR16538,PR12828: Prevent failure of bdisplay_set when display format
552 * not supported by attached DVI/HDMI monitor.
553 *
554 * Implement HDMI AvMute in SettopAPI
555 *
556 * Hydra_Software_Devel/54   9/1/05 5:34p rgreen
557 * PR16966: Relax EDID checking; fixes problems with EDIDs specified with
558 * 50Hz formats and monitor vertical ranges of 59-61
559 *
560 ***************************************************************************/
561#include "breg_endian.h"
562
563#include "bhdm.h"
564#include "bhdm_edid.h"
565#include "bhdm_priv.h"
566#include "bavc.h"
567
568#if BHDM_CONFIG_HDMI_3D_SUPPORT
569#include "bhdm_edid_3d.h"
570#endif
571
572
573/*=************************ Module Overview ********************************
574  The EDID (Enhanced Display Identification Data) functions provide support
575  for reading/interpretting the EDID prom contained in the DVI/HDMI Receiver.
576
577  The PROM has an I2C address of 0xA0.  These functions support the Enhanced
578  DDC protocol as needed.
579***************************************************************************/
580
581
582BDBG_MODULE(BHDM_EDID) ;
583
584
585#define BHDM_CHECK_RC( rc, func )                     \
586do                                                \
587{                                                                                         \
588        if( (rc = BERR_TRACE(func)) != BERR_SUCCESS ) \
589        {                                                                                     \
590                goto done;                                                            \
591        }                                                                                     \
592} while(0)
593
594
595
596/******************************************************************************
597Summary:
598Enumeration containing Audio Formats specified in CEA Short Audio Descriptors
599*******************************************************************************/
600typedef enum BHDM_EDID_P_AudioFormat
601{
602        BHDM_EDID_P_AudioFormat_eReserved,
603        BHDM_EDID_P_AudioFormat_ePCM,
604        BHDM_EDID_P_AudioFormat_eAC3,
605        BHDM_EDID_P_AudioFormat_eMPEG1,
606        BHDM_EDID_P_AudioFormat_eMP3,
607        BHDM_EDID_P_AudioFormat_eMPEG2,
608        BHDM_EDID_P_AudioFormat_eAAC,
609        BHDM_EDID_P_AudioFormat_eDTS,
610        BHDM_EDID_P_AudioFormat_eATRAC,
611        BHDM_EDID_P_AudioFormat_eOneBit,
612        BHDM_EDID_P_AudioFormat_eDDPlus,
613        BHDM_EDID_P_AudioFormat_eDTSHD,
614        BHDM_EDID_P_AudioFormat_eMATMLP,
615        BHDM_EDID_P_AudioFormat_eDST,
616        BHDM_EDID_P_AudioFormat_eWMAPro,
617        BHDM_EDID_P_AudioFormat_eMaxCount
618} BHDM_EDID_P_AudioFormat ;
619
620
621
622/******************************************************************************
623Summary:
624Enumeration containing Sample Rates specified in CEA Short Audio Descriptors
625*******************************************************************************/
626typedef enum BHDM_EDID_P_AudioSampleRate
627{
628        BHDM_EDID_P_AudioSampleRate_e32KHz  =  1,
629        BHDM_EDID_P_AudioSampleRate_e44KHz  =  2,
630        BHDM_EDID_P_AudioSampleRate_e48KHz  =  4,
631        BHDM_EDID_P_AudioSampleRate_e88KHz  =  8,
632        BHDM_EDID_P_AudioSampleRate_e96KHz  = 16,
633        BHDM_EDID_P_AudioSampleRate_e176KHz = 32,
634        BHDM_EDID_P_AudioSampleRate_e192KHz = 64
635} BHDM_EDID_P_AudioSampleRate;
636
637
638
639typedef struct _BHDM_EDID_P_CEA_861B_VIDEO_FORMAT_
640{
641        uint8_t            CeaVideoCode ;      /* Short Descriptor */
642        uint16_t           HorizontalPixels ;  /* Horiz Active Pixels */
643        uint16_t           VerticalPixels ;       /* Vertical Active Pixels */
644        BAVC_ScanType      eScanType ;         /* Progressive, Interlaced */
645        BAVC_FrameRateCode eFrameRateCode ;    /* Vertical Frequency */
646        BFMT_AspectRatio   eAspectRatio ;      /* Horiz  to Vertical Ratio */
647} BHDM_EDID_P_CEA_861B_VIDEO_FORMAT ;
648
649
650const BHDM_EDID_P_CEA_861B_VIDEO_FORMAT BHDM_EDID_P_Cea861bFormats[] =
651{
652/* Video        Horizontal      Vertical */
653/* Codes        (pixels)        (pixels)                  i/p                   Vertical Freq                           Aspect Ratio                    Remark */
654
655        { 1,    640,            480,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e59_94,      BFMT_AspectRatio_e4_3},         /* Default format */
656        { 2,    720,            480,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e59_94,      BFMT_AspectRatio_e4_3},         /* EDTV */
657        { 3,    720,            480,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e59_94,      BFMT_AspectRatio_e16_9},        /* EDTV */
658        { 4,    1280,           720,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e59_94,      BFMT_AspectRatio_e16_9},        /* HDTV */
659        { 5,    1920,           1080,   BAVC_ScanType_eInterlaced,      BAVC_FrameRateCode_e59_94,      BFMT_AspectRatio_e16_9},        /* HDTV */
660        { 6,    /*720*/1440,    480,    BAVC_ScanType_eInterlaced,      BAVC_FrameRateCode_e59_94,      BFMT_AspectRatio_e4_3},         /* Optional Double clock for 720x480i */
661        { 7,    /*720*/1440,    480,    BAVC_ScanType_eInterlaced,      BAVC_FrameRateCode_e59_94,      BFMT_AspectRatio_e16_9},        /* Optional Double clock for 720x480i */
662        {10,    2880,           480,    BAVC_ScanType_eInterlaced,      BAVC_FrameRateCode_e59_94,      BFMT_AspectRatio_e4_3},         /* Game Console */
663        {11,    2880,           480,    BAVC_ScanType_eInterlaced,      BAVC_FrameRateCode_e59_94,      BFMT_AspectRatio_e16_9},        /* Game Console */
664        {14,    1440,           480,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e59_94,      BFMT_AspectRatio_e4_3},         /* high-end DVD */
665        {15,    1440,           480,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e59_94,      BFMT_AspectRatio_e16_9},        /* high-end DVD */
666        {16,    1920,           1080,   BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e59_94,      BFMT_AspectRatio_e16_9},        /* Optional HDTV */
667
668        {17,    720,            576,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e50,         BFMT_AspectRatio_e4_3},         /* EDTV */
669        {18,    720,            576,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e50,         BFMT_AspectRatio_e16_9},        /* EDTV */
670        {19,    1280,           720,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e50,         BFMT_AspectRatio_e16_9},        /* HDTV */
671        {20,    1920,           1080,   BAVC_ScanType_eInterlaced,      BAVC_FrameRateCode_e50,         BFMT_AspectRatio_e16_9},        /* HDTV */
672        {21,    /*720*/1440,    576,    BAVC_ScanType_eInterlaced,      BAVC_FrameRateCode_e50,         BFMT_AspectRatio_e4_3},         /* Optional Double clock for 720x576i */
673        {22,    /*720*/1440,    576,    BAVC_ScanType_eInterlaced,      BAVC_FrameRateCode_e50,         BFMT_AspectRatio_e16_9},        /* Optional Double clock for 720x576i */
674        {25,    2880,           576,    BAVC_ScanType_eInterlaced,      BAVC_FrameRateCode_e50,         BFMT_AspectRatio_e4_3},         /* Game Console */
675        {26,    2880,           576,    BAVC_ScanType_eInterlaced,      BAVC_FrameRateCode_e50,         BFMT_AspectRatio_e16_9},        /* Game Console */
676        {29,    1440,           576,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e50,         BFMT_AspectRatio_e4_3},         /* high-end DVD */
677        {30,    1440,           576,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e50,         BFMT_AspectRatio_e16_9},        /* high-end DVD */
678        {31,    1920,           1080,   BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e50,         BFMT_AspectRatio_e16_9},        /* Optional HDTV */
679
680        {32,    1920,           1080,   BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e23_976, BFMT_AspectRatio_e16_9},    /* Optional HDTV */
681        {33,    1920,           1080,   BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e25,     BFMT_AspectRatio_e16_9},    /* Optional HDTV */
682        {34,    1920,           1080,   BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e30, BFMT_AspectRatio_e16_9},               /* Optional HDTV */
683        {35,    2880,           480,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e59_94,      BFMT_AspectRatio_e4_3},         /* 4x Pixel Rep */
684        {36,    2880,           480,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e59_94,      BFMT_AspectRatio_e16_9},        /* 4x Pixel Rep */
685        {37,    2880,           576,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e50,         BFMT_AspectRatio_e4_3},         /* 4x Pixel Rep */
686        {38,    2880,           576,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e50,         BFMT_AspectRatio_e16_9},        /* 4x Pixel Rep */
687
688#ifdef UNSUPPORTED
689        { 8,    720(1440),      240,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e59_94,      BFMT_AspectRatio_e4_3},         /* Double clock for 720x240p */
690        { 9,    720(1440),      240,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e59_94,      BFMT_AspectRatio_e16_9},        /* Double clock for 720x240p */
691        {12,    (2880),         240,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e59_94,      BFMT_AspectRatio_e4_3},         /* Game Console */
692        {13,    (2880),         240,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e59_94,      BFMT_AspectRatio_e16_9},        /* Game Console */
693        {23,    720(1440),      288,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e50,         BFMT_AspectRatio_e4_3},         /* Double clock for 720x288p */
694        {24,    720(1440),      288,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e50,         BFMT_AspectRatio_e16_9},        /* Double clock for 720x288p */
695        {27,    (2880),         288,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e50,         BFMT_AspectRatio_e4_3},         /* Game Console */
696        {28,    (2880),         288,    BAVC_ScanType_eProgressive,     BAVC_FrameRateCode_e50,         BFMT_AspectRatio_e16_9},        /* Game Console */
697#endif
698
699/*  0 No Video Code Available (Used with AVI InfoFrame only) */
700/*      {35,-127 Reserved for the Future */
701} ;
702
703
704typedef struct _BHDM_EDID_P_ALT_PREFERRED_VIDEOFMT
705{
706        BFMT_VideoFmt format;
707        char *formattext;
708}BHDM_EDID_P_ALT_PREFERRED_VIDEOFMT;
709
710const BHDM_EDID_P_ALT_PREFERRED_VIDEOFMT BHDM_EDID_P_AltPreferredFormats[] = {
711        {BFMT_VideoFmt_e720p, "BFMT_VideoFmt_e720p"},
712        {BFMT_VideoFmt_e1080i, "BFMT_VideoFmt_e1080i"},
713        {BFMT_VideoFmt_e480p, "BFMT_VideoFmt_e480p"},
714        {BFMT_VideoFmt_eNTSC, "BFMT_VideoFmt_eNTSC"},
715        {BFMT_VideoFmt_eDVI_1024x768p, "BFMT_VideoFmt_eDVI_1024x768p"},
716        {BFMT_VideoFmt_eDVI_640x480p, "BFMT_VideoFmt_eDVI_640x480p"}
717};
718
719#define BHDM_EDID_P_ALT_PREFERRED_VIDEOFMT_MAX \
720        (sizeof(BHDM_EDID_P_AltPreferredFormats) / sizeof(BHDM_EDID_P_ALT_PREFERRED_VIDEOFMT))
721
722#if BDBG_DEBUG_BUILD
723        static const char Mode[3] = "pi"  ; /* 1080i 480P etc. for debug msg only */
724#endif
725
726#define BHDM_EDID_P_BCM_VIDEO_FORMATS_MAX \
727        (sizeof(BHDM_EDID_P_Cea861bFormats) / sizeof(BHDM_EDID_P_CEA_861B_VIDEO_FORMAT))
728
729
730static uint8_t BHDM_EDID_P_EdidCheckSum(uint8_t *pEDID) ;
731
732
733static BERR_Code BHDM_EDID_P_ParseVideoDB(
734        BHDM_Handle hHDMI,                   /* [in] HDMI handle  */
735        uint8_t DataBlockIndex,              /* [in] start offset of Video Data Block */
736        uint8_t DataBlockLength              /* [in] length (number) of Video ID codes */
737) ;
738
739static BERR_Code BHDM_EDID_P_ParseAudioDB(
740        BHDM_Handle hHDMI,                   /* [in] HDMI handle  */
741        uint8_t DataBlockIndex,              /* [in] start offset of Video Data Block */
742        uint8_t DataBlockLength             /* [in] length (number) of Video ID codes */
743) ;
744
745static BERR_Code BHDM_EDID_P_ParseEstablishedTimingFormats(
746        BHDM_Handle hHDMI) ;                  /* [in] HDMI handle  */
747
748static BERR_Code BHDM_EDID_P_ParseV1V2TimingExtension(BHDM_Handle hHDMI) ;
749
750static BERR_Code BHDM_EDID_P_ParseV3TimingExtension(BHDM_Handle hHDMI);
751
752static BERR_Code BHDM_EDID_P_GetVerticalFrequency(
753        uint32_t ulVertFreqMask,            /* [in] Vertical Frequency Mask (bfmt) */
754        uint16_t *uiVerticalFrequency)  ;   /* [out] Vertical Frequency value */
755
756static BERR_Code BHDM_EDID_P_GetMonitorRange(
757        BHDM_Handle hHDMI, uint8_t offset) ;
758
759static BERR_Code BHDM_EDID_P_DetailTiming2VideoFmt(
760        BHDM_Handle hHDMI,
761        BHDM_EDID_DetailTiming *pBHDM_EDID_DetailTiming,
762        BFMT_VideoFmt *Detail_VideoFmt) ;
763
764
765#if BDBG_DEBUG_BUILD
766static void BHDM_EDID_P_PrintEdid(uint8_t *pEDID) ;
767
768
769static int _strlen(const char *s) {
770        int i=0;
771        while (*s++) i++;
772        return i;
773}
774
775static const char *CeaTagName[] =
776{
777        "Reserved0  ",
778        "Audio    DB",
779        "Video    DB",
780        "VendorSp DB",
781        "Speaker  DB",
782        "Reserved5  ",
783        "Reserved6  ",
784        "Extended DB"
785} ;
786
787static const char *g_status[] = {"No", "Yes"} ;
788
789static const unsigned char EDIDByPassedText[] = "BYPASSED EDID" ;
790
791#endif
792
793#define BHDM_EDID_USE_DEBUG_EDID 0
794
795#if BHDM_EDID_USE_DEBUG_EDID
796#undef BHDM_CONFIG_DEBUG_EDID_PROCESSING
797#define BHDM_CONFIG_DEBUG_EDID_PROCESSING 1
798#endif
799
800#if BHDM_CONFIG_DEBUG_EDID_PROCESSING
801/*
802the following EDID can be used to debug any Rx EDID that a BCMxxxx chip may have problems parsing.
803a copy of the EDID must first be obtained from the Receiever and copied here;
804Use BHDM_EDID_DumpRawEDID to get a copy of the EDID
805
806NOTE: This following EDID is used for DEBUGGING ONLY! i.e. debugging the parsing of an EDID which
807you may not have the HDMI Rx.  Presumeably the EDID was provided by the user with the TV.
808
809*/
810
811#if 1
812uint8_t DebugRxEdid[] = /* BCM97403 Extended-EDID test blocks*/
813{
814        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x08, 0x6D, 0x48, 0x56, 0xA0, 0xA0, 0xA0, 0xA0,
815        0x14, 0x14, 0x01, 0x03, 0x81, 0x5D, 0x34, 0x78, 0x0A, 0x55, 0x50, 0xA7, 0x55, 0x46, 0x99, 0x24,
816        0x12, 0x49, 0x4B, 0x21, 0x08, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
817        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xE4, 0x57, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C,
818        0x45, 0x00, 0xA2, 0x08, 0x32, 0x00, 0x00, 0x1E, 0xC0, 0x2B, 0x00, 0x72, 0x51, 0xD0, 0x1E, 0x20,
819        0x6E, 0x28, 0x55, 0x00, 0xA2, 0x08, 0x32, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x42,
820        0x43, 0x4D, 0x33, 0x35, 0x34, 0x38, 0x5F, 0x35, 0x36, 0x20, 0x33, 0x44, 0x00, 0x00, 0x00, 0xFD,
821        0x00, 0x32, 0x4B, 0x0F, 0x50, 0x17, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0x25,
822       
823        0x02, 0x03, 0x3D, 0x71, 0x78, 0x03, 0x0C, 0x00, 0x10, 0x00, 0xB8, 0x2D, 0x20, 0xC0, 0x0E, 0x01,
824        0x01, 0x0F, 0x3F, 0x08, 0x00, 0x20, 0x40, 0x56, 0x16, 0x90, 0x88, 0x00, 0xE6, 0x52, 0x05, 0x04,
825        0x40, 0x02, 0x22, 0x20, 0x21, 0x1F, 0x13, 0x11, 0x14, 0x18, 0x15, 0x16, 0x1A, 0x07, 0x06, 0x01,
826        0x29, 0x09, 0x07, 0x07, 0x15, 0x50, 0xFF, 0x19, 0x50, 0xFF, 0x82, 0x01, 0x00, 0xE4, 0x57, 0x80,
827        0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C, 0x45, 0x00, 0x13, 0x8E, 0x21, 0x00, 0x00, 0x1E, 0x00,
828        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
829        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
830        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE
831} ;
832
833
834#else
835uint8_t DebugRxEdid[] = /* BCM93563 EDID */
836{
837
838        0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x08, 0x6D, 0x63, 0x35, 0x01, 0x01, 0x01, 0x01,
839        0x14, 0x11, 0x01, 0x03, 0x81, 0x5D, 0x34, 0x78, 0x0A, 0x55, 0x50, 0xA7, 0x55, 0x46, 0x99, 0x24,
840        0x12, 0x49, 0x4B, 0x21, 0x08, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
841        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x3A, 0x80, 0x18, 0x71, 0x38, 0x2D, 0x40, 0x58, 0x2C,
842        0x45, 0x00, 0xA2, 0x08, 0x32, 0x00, 0x00, 0x1E, 0x01, 0x1D, 0x00, 0x72, 0x51, 0xD0, 0x1E, 0x20,
843        0x6E, 0x28, 0x55, 0x00, 0xA2, 0x08, 0x32, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x39,
844        0x33, 0x35, 0x36, 0x33, 0x5F, 0x31, 0x30, 0x38, 0x30, 0x70, 0x0A, 0x20, 0x00, 0x00, 0x00, 0xFD,
845        0x00, 0x32, 0x4B, 0x0F, 0x50, 0x0F, 0x00, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x01, 0xB9,
846
847        0x02, 0x03, 0x29, 0x71, 0x50, 0x90, 0x04, 0x05, 0x03, 0x20, 0x21, 0x22, 0x06, 0x13, 0x14, 0x11,
848        0x15, 0x02, 0x07, 0x12, 0x16, 0x23, 0x09, 0x07, 0x07, 0x83, 0x01, 0x00, 0x00, 0x67, 0x03, 0x0C,
849        0x00, 0x10, 0x00, 0xB8, 0x2D, 0xE3, 0x05, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
850        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
851        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
852        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
853        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
854        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79
855
856} ;
857#endif
858
859
860#endif
861static const struct  {
862        BHDM_EDID_P_AudioFormat EdidAudioFormat ;
863        BAVC_AudioFormat BcmAudioFormat ;
864} BHDM_EDID_P_BcmSupportedFormats [] =
865{
866        {BHDM_EDID_P_AudioFormat_ePCM,   BAVC_AudioFormat_ePCM},
867        {BHDM_EDID_P_AudioFormat_eAC3,   BAVC_AudioFormat_eAC3},
868        {BHDM_EDID_P_AudioFormat_eMPEG1, BAVC_AudioFormat_eMPEG1},
869        {BHDM_EDID_P_AudioFormat_eMP3,   BAVC_AudioFormat_eMP3},
870        {BHDM_EDID_P_AudioFormat_eMPEG2, BAVC_AudioFormat_eMPEG2},
871        {BHDM_EDID_P_AudioFormat_eAAC,   BAVC_AudioFormat_eAAC},
872        {BHDM_EDID_P_AudioFormat_eDTS,   BAVC_AudioFormat_eDTS}
873
874#if BHDM_CONFIG_AUDIO_SUPPORT_DDP
875        , {BHDM_EDID_P_AudioFormat_eDDPlus, BAVC_AudioFormat_eDDPlus}
876#endif
877
878#if BHDM_CONFIG_AUDIO_SUPPORT_DTSHD
879        , {BHDM_EDID_P_AudioFormat_eDTSHD, BAVC_AudioFormat_eDTSHD}
880#endif
881
882#if BHDM_CONFIG_AUDIO_SUPPORT_MATMLP
883        , {BHDM_EDID_P_AudioFormat_eMATMLP, BAVC_AudioFormat_eMATMLP}
884#endif
885
886#if BHDM_CONFIG_AUDIO_SUPPORT_WMAPRO
887        , {BHDM_EDID_P_AudioFormat_eWMAPro, BAVC_AudioFormat_eWMAPro}
888#endif
889
890#if 0
891        , {BHDM_EDID_P_AudioFormat_eATRAC, BAVC_AudioFormat_eATRAC}
892        , {BHDM_EDID_P_AudioFormat_eOneBit, BAVC_AudioFormat_eOneBit}
893        , {BHDM_EDID_P_AudioFormat_eDST,         BAVC_AudioFormat_eDST}
894#endif
895
896 } ;
897
898static const struct {
899        BHDM_EDID_P_AudioSampleRate EdidAudioSampleRate ;
900        BAVC_AudioSamplingRate BcmAudioSampleRate ;
901} EdidAudioSampleRateTable[] =
902{
903
904        {BHDM_EDID_P_AudioSampleRate_e32KHz, BAVC_AudioSamplingRate_e32k},
905        {BHDM_EDID_P_AudioSampleRate_e44KHz, BAVC_AudioSamplingRate_e44_1k},
906        {BHDM_EDID_P_AudioSampleRate_e48KHz, BAVC_AudioSamplingRate_e48k},
907        {BHDM_EDID_P_AudioSampleRate_e96KHz, BAVC_AudioSamplingRate_e96k}
908
909#if BHDM_CONFIG_88_2KHZ_AUDIO_SUPPORT
910        , {BHDM_EDID_P_AudioSampleRate_e88KHz,  BAVC_AudioSamplingRate_e88_2k}
911#endif
912
913#if BHDM_CONFIG_176_4KHZ_AUDIO_SUPPORT
914        , {BHDM_EDID_P_AudioSampleRate_e176KHz, BAVC_AudioSamplingRate_e176_4k}
915#endif
916
917#if BHDM_CONFIG_192KHZ_AUDIO_SUPPORT
918        , {BHDM_EDID_P_AudioSampleRate_e192KHz, BAVC_AudioSamplingRate_e192k}
919#endif
920
921} ;
922
923#if BDBG_DEBUG_BUILD
924static char *CeaAudioSampleRateTypeText[] =
925{
926        "32 kHz",
927        "44.1 kHz (CD)",
928        "48 kHz",
929        "96 kHz"
930#if BHDM_CONFIG_88_2KHZ_AUDIO_SUPPORT
931        , "88.2 kHz"
932#endif
933
934#if BHDM_CONFIG_176_4KHZ_AUDIO_SUPPORT
935        , "176.4 kHz"
936#endif
937
938#if BHDM_CONFIG_192KHZ_AUDIO_SUPPORT
939        , "192 kHz"
940#endif
941} ;
942#endif
943
944/******************************************************************************
945uint8_t BHDM_EDID_P_EdidCheckSum
946Summary:Verify the checksum on an EDID block
947*******************************************************************************/
948uint8_t BHDM_EDID_P_EdidCheckSum(uint8_t *pEDID)
949{
950        uint8_t i ;
951        uint8_t checksum = 0 ;
952
953
954        for (i = 0 ; i < BHDM_EDID_BLOCKSIZE ; i++)
955                checksum = checksum + (uint8_t) pEDID[i]  ;
956
957#if BDBG_DEBUG_BUILD
958        /*
959        -- Determine Checksum if an error (non-zero)
960        -- correct value can be inserted above if desired
961        */
962        if (checksum % 256)
963        {
964                BDBG_WRN(("Checksum:      %#X", checksum)) ;
965                BDBG_WRN(("Invalid Checksum Byte: %#02X", (unsigned char) pEDID[BHDM_EDID_CHECKSUM])) ;
966
967                /* determine the correct checksum value */
968                BDBG_WRN(("Correct Checksum Byte = %#02X",
969                        (uint8_t) (256 - (checksum - (unsigned int) pEDID[BHDM_EDID_CHECKSUM])))) ;
970        }
971#endif
972
973        return ( (checksum % 256) ? 0 : 1) ;
974} /* end BHDM_EDID_P_EdidCheckSum */
975
976
977
978/******************************************************************************
979BERR_Code BHDM_EDID_GetNthBlock
980Summary:Retrieve the Nth 128-byte EDID block
981*******************************************************************************/
982BERR_Code BHDM_EDID_GetNthBlock(
983   BHDM_Handle hHDMI,   /* [in] HDMI handle */
984   uint8_t BlockNumber, /* [in] EDID Block Number to read */
985   uint8_t *pBuffer,    /* [out] pointer to input buffer */
986   uint16_t uiBufSize    /* [in] Size of input buffer to write EDID to */
987)
988{
989        BERR_Code rc = BERR_SUCCESS ;
990        uint8_t uiSegment ;
991#if ! BHDM_CONFIG_DEBUG_EDID_PROCESSING
992        uint8_t timeoutMs ;
993#endif
994        uint8_t RxDeviceAttached ;
995
996
997        /* make sure HDMI Cable is connected to something... */
998        BHDM_CHECK_RC(rc, BHDM_RxDeviceAttached(hHDMI, &RxDeviceAttached));
999        if (!RxDeviceAttached)
1000        {
1001                return BHDM_NO_RX_DEVICE ;
1002        }
1003
1004        if (hHDMI->edidStatus == BHDM_EDID_STATE_eInvalid) {
1005                return BHDM_EDID_NOT_FOUND;
1006        }
1007
1008        /* check if the requested block already cached */
1009        if ((BlockNumber == hHDMI->AttachedEDID.CachedBlock)
1010        && (hHDMI->edidStatus == BHDM_EDID_STATE_eOK))
1011        {
1012                BDBG_MSG(("Skip reading EDID; Block %d already cached", BlockNumber)) ;
1013
1014                /* copy the cached EDID block to the user buffer */
1015                BKNI_Memcpy(pBuffer, hHDMI->AttachedEDID.Block, BHDM_EDID_BLOCKSIZE) ;
1016
1017                rc = BERR_SUCCESS ;
1018                goto done ;
1019        }
1020
1021        if (uiBufSize <  BHDM_EDID_BLOCKSIZE)
1022        {
1023                BDBG_ERR(("Incorrect Specified EDID Block Size: %d; expecting %d",
1024                        uiBufSize, BHDM_EDID_BLOCKSIZE)) ;
1025                rc = BERR_INVALID_PARAMETER ;
1026                goto done ;
1027        }
1028
1029
1030        /* Use E-DDC protocol for reading the EDID... */
1031
1032        /* each segment can hold two EDID blocks of 128 bytes each */
1033        /* determine which segment the requested block lies in */
1034        uiSegment = BlockNumber / 2 ;
1035
1036
1037#if BHDM_CONFIG_DEBUG_EDID_PROCESSING
1038        /* copy the EDID from the debugging EDID instead of the connected monitor */
1039
1040        BDBG_WRN(("BHDM_CONFIG_DEBUG_EDID_PROCESSING is enabled")) ;
1041        BDBG_WRN(("EDID declared in bdhm_edid.c is being used")) ;
1042        BKNI_Memcpy(pBuffer,
1043                DebugRxEdid + (uint8_t) (BHDM_EDID_BLOCKSIZE * (BlockNumber % 2)) + (BHDM_EDID_BLOCKSIZE * 2 * uiSegment),
1044                BHDM_EDID_BLOCKSIZE) ;
1045#else
1046        /* Read the EDID block; sometimes the EDID block is not ready/available */
1047        /* try again if a READ failure occurs */
1048
1049        timeoutMs = 1 ;
1050        do
1051        {
1052                rc = BREG_I2C_ReadEDDC(hHDMI->hI2cRegHandle, (uint8_t) BHDM_EDID_I2C_ADDR,
1053                        (uint8_t) uiSegment,
1054                        (uint8_t) (BHDM_EDID_BLOCKSIZE * (BlockNumber % 2)), /* offset */
1055                        pBuffer, (uint16_t) BHDM_EDID_BLOCKSIZE) ;      /* storage & length  */
1056
1057                if (rc == BERR_SUCCESS)
1058                        break ;
1059
1060                BDBG_WRN(("Error reading EDID Block; Attempt to re-read...")) ;
1061                BKNI_Sleep(1) ;
1062        } while ( timeoutMs-- ) ;
1063
1064        if (rc != BERR_SUCCESS)
1065        {
1066                BDBG_ERR(("Can't find/read Rx EDID device")) ;
1067                rc = BHDM_NO_RX_DEVICE ;
1068                goto done ;
1069        }
1070#endif
1071
1072        /* copy the EDID block to the EDID handle */
1073        BKNI_Memcpy(hHDMI->AttachedEDID.Block, pBuffer, BHDM_EDID_BLOCKSIZE) ;
1074
1075        /* check for a valid checksum */
1076        if (!BHDM_EDID_P_EdidCheckSum(hHDMI->AttachedEDID.Block))
1077        {
1078                BDBG_WRN(("Checksum Error for EDID Block #%d Ignored", BlockNumber)) ;
1079#if 0
1080                rc = BHDM_EDID_CHECKSUM_ERROR ;
1081                goto done ;
1082#endif
1083        }
1084
1085        hHDMI->AttachedEDID.CachedBlock = BlockNumber ;
1086        hHDMI->edidStatus = BHDM_EDID_STATE_eOK;
1087
1088done:
1089        return rc ;
1090} /* end BHDM_EDID_GetNthBlock */
1091
1092
1093#if BDBG_DEBUG_BUILD
1094/******************************************************************************
1095BERR_Code BHDM_EDID_P_PrintEdid
1096Summary: Print EDID Messages
1097*******************************************************************************/
1098void BHDM_EDID_P_PrintEdid(uint8_t *pEDID)
1099{
1100        uint8_t i ;
1101        uint8_t display_string[128] = "" ;
1102        uint8_t *ptr ;
1103
1104        i = 0 ;
1105        do
1106        {
1107                if ((i % BHDM_EDID_BLOCKSIZE == 0) /* add a blank line between blocks*/
1108                &&  (i != 0)
1109                &&  (i != BHDM_EDID_BLOCKSIZE))
1110                        BDBG_MSG(("")) ;
1111
1112                if ((i % 16 == 0) )                /* 16 bytes per line */
1113                {
1114                        BDBG_MSG(("%s", display_string)) ;
1115                        BKNI_Snprintf((char *) display_string, BHDM_EDID_BLOCKSIZE, "%04X> ", i) ;
1116                }
1117
1118                ptr = display_string + _strlen((char *) display_string) ;
1119                BKNI_Snprintf((char *) ptr, BHDM_EDID_BLOCKSIZE, "%02X ", pEDID[i]) ;
1120                i++ ;
1121        } while (i < BHDM_EDID_BLOCKSIZE) ;
1122
1123        /* pirint last line */
1124        BDBG_MSG(("%s", display_string)) ;
1125
1126
1127        BDBG_MSG(("")) ;
1128}
1129
1130
1131
1132/******************************************************************************
1133BERR_Code BHDM_EDID_DumpRawEDID
1134Summary: Dump EDID data
1135*******************************************************************************/
1136BERR_Code BHDM_EDID_DumpRawEDID(BHDM_Handle hHDMI)
1137{
1138        BERR_Code rc = BERR_SUCCESS ;
1139        uint8_t NumExtensions ;
1140        uint8_t i ;
1141
1142        /* read the 1st EDID Block */
1143        BHDM_CHECK_RC(rc, BHDM_EDID_GetNthBlock(hHDMI,
1144                0, hHDMI->AttachedEDID.Block, BHDM_EDID_BLOCKSIZE)) ;
1145
1146        BDBG_MSG(("RAW EDID DUMP: ")) ;
1147
1148        BHDM_EDID_P_PrintEdid( hHDMI->AttachedEDID.Block ) ;
1149
1150        NumExtensions = hHDMI->AttachedEDID.BasicData.Extensions;
1151        /* Search EDID Extension blocks for additional timing descriptors */
1152        for (i = 1 ; i <= NumExtensions; i++)
1153        {
1154                BDBG_MSG(("")) ;
1155                BDBG_MSG(("EXTENSION BLOCK %d", i)) ;
1156
1157                /* read the next 128 Byte EDID block */
1158                BHDM_CHECK_RC(rc, BHDM_EDID_GetNthBlock(hHDMI, i,
1159                        hHDMI->AttachedEDID.Block, BHDM_EDID_BLOCKSIZE)) ;
1160
1161                BHDM_EDID_P_PrintEdid( hHDMI->AttachedEDID.Block ) ;
1162        }
1163
1164done :
1165        return rc ;
1166}
1167#else
1168void BHDM_EDID_P_PrintEdid(uint8_t *pEDID)
1169{
1170        BSTD_UNUSED(pEDID);
1171}
1172BERR_Code BHDM_EDID_DumpRawEDID(BHDM_Handle hHDMI)
1173{
1174        BSTD_UNUSED(hHDMI);
1175        return BERR_SUCCESS;
1176}
1177#endif
1178
1179
1180
1181
1182/******************************************************************************
1183BERR_Code BHDM_EDID_GetBasicData
1184Summary: Retrieve the basic EDID data
1185*******************************************************************************/
1186BERR_Code BHDM_EDID_GetBasicData(
1187   BHDM_Handle hHDMI,               /* [in] HDMI handle */
1188   BHDM_EDID_BasicData *pMonitorData /* [out] pointer to structure to hold Basic
1189                                            EDID Data */
1190)
1191{
1192        BERR_Code rc = BERR_SUCCESS ;
1193        uint8_t RxDeviceAttached ;
1194
1195        /* make sure HDMI Cable is connected to something... */
1196        BHDM_CHECK_RC(rc, BHDM_RxDeviceAttached(hHDMI, &RxDeviceAttached));
1197        if (!RxDeviceAttached)
1198        {
1199                return BHDM_NO_RX_DEVICE ;
1200        }
1201
1202        if (hHDMI->edidStatus == BHDM_EDID_STATE_eInvalid) {
1203                return BHDM_EDID_NOT_FOUND;
1204        }
1205
1206        /* copy the EDID Basic Data */
1207        BKNI_Memcpy(pMonitorData, (void *) &(hHDMI->AttachedEDID.BasicData),
1208                sizeof(BHDM_EDID_BasicData)) ;
1209
1210done:
1211        return rc ;
1212}/* end BHDM_EDID_GetBasicData */
1213
1214
1215
1216/******************************************************************************
1217static void BHDM_EDID_ParseDetailedTimingDescriptor
1218Summary: Parse a Detailed Timing Descriptor Block
1219*******************************************************************************/
1220static void BHDM_EDID_ParseDetailedTimingDescriptor
1221        (unsigned char *pDescriptor, BHDM_EDID_DetailTiming *DetailedTiming)
1222{
1223
1224        BDBG_ENTER(BHDM_EDID_ParseDetailedTimingDescriptor) ;
1225
1226        DetailedTiming->PixelClock =
1227        ( ((pDescriptor[BHDM_EDID_DESC_PIXEL_CLOCK_HI]) << 8)
1228                | ((pDescriptor[BHDM_EDID_DESC_PIXEL_CLOCK_LO]))) / 100 ;
1229
1230
1231        DetailedTiming->HorizActivePixels =
1232                    pDescriptor[BHDM_EDID_DESC_HACTIVE_PIXELS_LSB]
1233                | ((pDescriptor[BHDM_EDID_DESC_HACTIVE_PIXELS_UN_F0] & 0xF0) << 4) ;
1234
1235        DetailedTiming->HorizBlankingPixels =
1236                pDescriptor[ BHDM_EDID_DESC_HBLANK_PIXELS_LSB]
1237                | (((pDescriptor[BHDM_EDID_DESC_HBLANK_PIXELS_UN_0F] & 0x0F) << 8)) ;
1238
1239
1240
1241        DetailedTiming->VerticalActiveLines =
1242                    pDescriptor[BHDM_EDID_DESC_VACTIVE_LINES_LSB]
1243                | ((pDescriptor[BHDM_EDID_DESC_VACTIVE_LINES_UN_F0] & 0xF0) << 4) ;
1244
1245        DetailedTiming->VerticalBlankingLines =
1246                pDescriptor[BHDM_EDID_DESC_VBLANK_LINES_LSB]
1247                | (((pDescriptor[BHDM_EDID_DESC_VBLANK_LINES_UN_0F] & 0x0F) << 8)) ;
1248
1249        /* Mode */
1250        DetailedTiming->Mode =
1251                (pDescriptor[BHDM_EDID_DESC_PREFERRED_FLAGS] & 0x80) ? 1 : 0 ;
1252
1253
1254        /* HSync Offset / Width */
1255        DetailedTiming->HSyncOffset =
1256                   pDescriptor[BHDM_EDID_DESC_HSYNC_OFFSET_LSB]
1257                | (pDescriptor[BHDM_EDID_DESC_HSYNC_OFFSET_U2_C0] & 0xC0) << 2 ;
1258
1259        DetailedTiming->HSyncWidth =
1260                   pDescriptor[BHDM_EDID_DESC_HSYNC_WIDTH_LSB]
1261                | (pDescriptor[BHDM_EDID_DESC_HSYNC_WIDTH_U2_30] & 0x30) << 4 ;
1262
1263
1264        /* VSync Offset / Width */
1265        DetailedTiming->VSyncOffset =
1266                  ((pDescriptor[BHDM_EDID_DESC_VSYNC_OFFSET_LN_F0] & 0xF0) >> 4)
1267                | ((pDescriptor[BHDM_EDID_DESC_VSYNC_OFFSET_U2_0C] & 0x0C) << 2) ;
1268
1269        DetailedTiming->VSyncWidth =
1270                   (pDescriptor[BHDM_EDID_DESC_VSYNC_WIDTH_LN_0F] & 0x0F)
1271                | ((pDescriptor[BHDM_EDID_DESC_VSYNC_WIDTH_U2_03] & 0x03) << 4) ;
1272
1273        /*Screen Size */
1274        DetailedTiming->HSize_mm =
1275                    pDescriptor[BHDM_EDID_DESC_HSIZE_MM_LSB]
1276                | ((pDescriptor[BHDM_EDID_DESC_HSIZE_UN_F0] & 0xF0) << 4) ;
1277
1278        DetailedTiming->VSize_mm =
1279                    pDescriptor[BHDM_EDID_DESC_VSIZE_MM_LSB]
1280                | ((pDescriptor[BHDM_EDID_DESC_VSIZE_UN_0F] & 0x0F) << 8) ;
1281
1282        DetailedTiming->HorizBorderPixels = pDescriptor[BHDM_EDID_DESC_HBORDER_PIXELS] ;
1283        DetailedTiming->VerticalBorderLines = pDescriptor[BHDM_EDID_DESC_VBORDER_LINES] ;
1284
1285        BDBG_LEAVE(BHDM_EDID_ParseDetailedTimingDescriptor) ;
1286        return ;
1287} /* END BHDM_EDID_ParseDetailedTimingDescriptor */
1288
1289
1290
1291/******************************************************************************
1292BERR_Code BHDM_EDID_P_DetailTiming2VideoFmt(
1293Summary: Determine the BFMT_VideoFmt for the associated Detailed Timing Format
1294*******************************************************************************/
1295static BERR_Code BHDM_EDID_P_DetailTiming2VideoFmt(
1296        BHDM_Handle hHDMI,
1297        BHDM_EDID_DetailTiming *pBHDM_EDID_DetailTiming,
1298        BFMT_VideoFmt *Detail_VideoFmt
1299)
1300{
1301        BERR_Code rc = BHDM_EDID_DETAILTIMING_NOT_SUPPORTED ;
1302        const BFMT_VideoInfo *pVideoFormatInfo ;
1303        BFMT_VideoFmt eVideoFmt ;
1304
1305        uint8_t i ;
1306        bool Interlaced ;
1307        uint16_t
1308                uiVerticalFrequency ;
1309        uint16_t AdjustedHorizPixels ;
1310        uint16_t AdjustedVerticalLines ;
1311
1312        /* default to NTSC format */
1313        *Detail_VideoFmt = BFMT_VideoFmt_eDVI_640x480p  ;
1314
1315        /* adjust Detailed Timing vertical parameters for interlaced formats */
1316        /* Do not adjust the original number of pixels in the Detail Timing  */
1317        Interlaced = pBHDM_EDID_DetailTiming->Mode ? true : false ;
1318        if (Interlaced)
1319                AdjustedVerticalLines = pBHDM_EDID_DetailTiming->VerticalActiveLines * 2 ;
1320        else
1321                AdjustedVerticalLines = pBHDM_EDID_DetailTiming->VerticalActiveLines ;
1322
1323        /* adjust any pixel repititions to match the formats */
1324        /* as specified in BFMT (e.g 1440 -> 720) */
1325
1326        if ((pBHDM_EDID_DetailTiming->HorizActivePixels == 1440)
1327        ||  (pBHDM_EDID_DetailTiming->HorizActivePixels == 2880))
1328                AdjustedHorizPixels = 720 ;
1329        else
1330                AdjustedHorizPixels = pBHDM_EDID_DetailTiming->HorizActivePixels ;
1331
1332
1333        for (i = 0; i < BFMT_VideoFmt_eMaxCount; i++)
1334        {
1335                eVideoFmt = (BFMT_VideoFmt) i ;
1336
1337                pVideoFormatInfo = BFMT_GetVideoFormatInfoPtr(eVideoFmt) ;
1338                if (!pVideoFormatInfo)
1339                        continue;
1340
1341                /* check if the specified parameters match the requested formats */
1342
1343                /* 1st, Check if Pixel Format matches */
1344                if ((pVideoFormatInfo->ulDigitalWidth != AdjustedHorizPixels)
1345                || (pVideoFormatInfo->ulDigitalHeight != AdjustedVerticalLines))
1346                        continue ;
1347
1348                /* 2nd, Check Scan Type (i/p) */
1349                if (pVideoFormatInfo->bInterlaced != Interlaced)
1350                        continue ;
1351
1352               
1353                /* 3rd, for all 720p and 1080i,p formats, make another
1354                check to help differentiate the 24, 50, and 60Hz formats.
1355                This is needed for Detailed Timing Descriptors because the
1356                format width is the same so the blanking time must also be considered
1357                when matching formats */
1358
1359                if ((pVideoFormatInfo->ulDigitalWidth == BFMT_1080I_WIDTH) 
1360                || (pVideoFormatInfo->ulDigitalWidth == BFMT_1080P_WIDTH) 
1361                || (pVideoFormatInfo->ulDigitalWidth == BFMT_720P_WIDTH))
1362                {
1363                        uint16_t ulHorizontalScanWidth ;
1364
1365                        ulHorizontalScanWidth =
1366                                   pBHDM_EDID_DetailTiming->HorizActivePixels
1367                                + pBHDM_EDID_DetailTiming->HorizBlankingPixels ;
1368
1369                        if (pVideoFormatInfo->ulScanWidth != ulHorizontalScanWidth)
1370                                continue ;
1371                }
1372
1373                /* use the BFMT freqency parameter to get the Vertical Frequency */
1374                /* Ignore rc; default of 60Hz will be used for unknown Frequency */
1375                BHDM_EDID_P_GetVerticalFrequency(
1376                        pVideoFormatInfo->ulVertFreqMask, &uiVerticalFrequency) ;
1377
1378#if !defined(BHDM_CONFIG_1080P_5060HZ_SUPPORT)
1379                if ((eVideoFmt == BFMT_VideoFmt_e1080p)
1380                && (uiVerticalFrequency >= 50))
1381                {
1382                        /* 1080p 60hz */
1383                        /* assign format but return unsupported */
1384
1385                        *Detail_VideoFmt = eVideoFmt ;
1386                        rc = BHDM_EDID_DETAILTIMING_NOT_SUPPORTED ;
1387                        break ;
1388                }
1389#endif
1390
1391                /* 3rd check the vertical frequency range */
1392                if  ((uiVerticalFrequency >= hHDMI->AttachedEDID.MonitorRange.MinVertical)
1393                &&  (uiVerticalFrequency <= hHDMI->AttachedEDID.MonitorRange.MaxVertical))
1394                {
1395#if 0
1396                        /* debug Vertical Frequency */
1397                        BDBG_MSG(("Vertical Frequency %d <= %d <=%d",
1398                                hHDMI->AttachedEDID.MonitorRange.MinVertical,
1399                                uiVerticalFrequency,
1400                                hHDMI->AttachedEDID.MonitorRange.MaxVertical));
1401#endif
1402                        BDBG_MSG(("   %s (#%d) %4d x %4d %c %dHz",
1403                                pVideoFormatInfo->pchFormatStr, i,
1404                                pVideoFormatInfo->ulDigitalWidth, pVideoFormatInfo->ulDigitalHeight,
1405                                Mode[pVideoFormatInfo->bInterlaced], uiVerticalFrequency)) ;
1406
1407                        /* found associated BFMT_eVideoFmt */
1408                        *Detail_VideoFmt = eVideoFmt ;
1409                        rc = BERR_SUCCESS ;
1410                        break ;
1411                }
1412                else
1413                {
1414                        BDBG_MSG(("   Format %s does not match ", pVideoFormatInfo->pchFormatStr)) ;
1415                }
1416        }
1417
1418        return rc ;
1419}
1420
1421
1422/******************************************************************************
1423BERR_Code BHDM_EDID_GetDetailTiming
1424Summary: Retrieve EDID Detail Timing Data
1425*******************************************************************************/
1426BERR_Code BHDM_EDID_GetDetailTiming(
1427        BHDM_Handle hHDMI,                      /* [in] HDMI handle */
1428        uint8_t NthTimingRequested, /* [in] number of the Detail Block to get */
1429        BHDM_EDID_DetailTiming
1430                *pBHDM_EDID_DetailTiming, /* [out] pointer to a BHDM_EDID_DetailTiming
1431                                                                   structure to hold the data */
1432        BFMT_VideoFmt *BCM_VideoFmt
1433)
1434{
1435        /* the first 128 bytes of the EDID should contain the preferred
1436         * timing block.  It should be in the first Descriptor Block...
1437         */
1438
1439        /*
1440         *      LISTED HERE FOR DOCUMENTATION PURPOSES ONLY...
1441         *
1442         *  By searching for the following DESCRIPTOR BLOCKS
1443         *  EDID information (Name, S/N etc) can be gathered from the
1444         *  Display Device; the search and retrieval of such data
1445         *  could be implemented in this function
1446         *
1447         *      static DESCRIPTOR_BLOCK TimingDescriptors[] =
1448         *      {
1449         *              {0x00, 0x00, 0x00, 0xFF, 0x00}, -- Monitor Serial Number
1450         *              {0x00, 0x00, 0x00, 0xFE, 0x00}, -- ASCII String
1451         *              {0x00, 0x00, 0x00, 0xFD, 0x00}, -- Monitor Range Limits
1452         *              {0x00, 0x00, 0x00, 0xFC, 0x00}, -- Monitor Name (ASCII)
1453         *              {0x00, 0x00, 0x00, 0xFB, 0x00}, -- Color Point Data
1454         *              {0x00, 0x00, 0x00, 0xFA, 0x00}, -- Additional Standard Timings
1455         *                                                      -- F9 - 11 Unused
1456         *                                                  -- 0F - 00 Manufacturer Descriptor
1457         *              {0x00, 0x00, 0x00, 0x10, 0x00}, -- Dummy Descriptor
1458         *      } ;
1459         */
1460
1461        BERR_Code rc = BERR_SUCCESS ;
1462
1463        uint8_t i, j ;
1464        uint8_t offset ;
1465        uint8_t MaxDescriptors ;
1466        uint8_t extensions, DataOffset ;
1467        uint8_t NumDetailedTimingsFound = 0 ;
1468        uint8_t RxDeviceAttached ;
1469
1470        BDBG_ENTER(BHDM_EDID_GetDetailTiming) ;
1471
1472        *BCM_VideoFmt = BFMT_VideoFmt_eNTSC; /* initialize the out param for error path */
1473
1474        /* make sure HDMI Cable is connected to something... */
1475        BHDM_CHECK_RC(rc, BHDM_RxDeviceAttached(hHDMI, &RxDeviceAttached));
1476        if (!RxDeviceAttached)
1477                return BHDM_NO_RX_DEVICE ;
1478
1479#if BDBG_DEBUG_BUILD
1480        if (hHDMI->DeviceSettings.BypassEDIDChecking)
1481        {
1482                BDBG_WRN(("EDID is ByPassed; All formats will attempt to display")) ;
1483                goto done ;
1484        }
1485#endif
1486
1487        if (hHDMI->edidStatus == BHDM_EDID_STATE_eInvalid)
1488        {
1489                rc = BHDM_EDID_NOT_FOUND;
1490                goto done;
1491        }
1492
1493
1494        if (!NthTimingRequested)
1495        {
1496                rc = BERR_INVALID_PARAMETER ;
1497                BDBG_ERR(("Incorrectly specified Detail Timing: %d", NthTimingRequested)) ;
1498                goto done ;
1499        }
1500
1501        /* set Number of Detailed Timings Found to 2; number in 1st Block */
1502        NumDetailedTimingsFound = hHDMI->AttachedEDID.SupportedDetailTimingsIn1stBlock ;
1503
1504        /* up to two preferred formats should be stored in handle; if requested copy and exit */
1505        if ((NumDetailedTimingsFound) && (NthTimingRequested <= NumDetailedTimingsFound))
1506        {
1507                BKNI_Memcpy(pBHDM_EDID_DetailTiming,
1508                        &(hHDMI->AttachedEDID.SupportedDetailTimings[NthTimingRequested - 1]),
1509                        sizeof(BHDM_EDID_DetailTiming)) ;
1510
1511                /* function below displays just the BFMT name; parse/display done at Initialize */
1512                rc = BHDM_EDID_P_DetailTiming2VideoFmt(hHDMI, pBHDM_EDID_DetailTiming, BCM_VideoFmt);
1513                if (rc == BERR_SUCCESS) {
1514                        goto BcmSupportedFormatFound;
1515                }
1516                else {
1517                        goto BcmSupportedFormatNotFound;
1518                }
1519        }
1520
1521        /* otherwise search the extensions for the requested format */
1522        extensions = hHDMI->AttachedEDID.BasicData.Extensions ;
1523        if (!extensions)
1524                goto BcmSupportedFormatNotFound;
1525
1526        /* Search EDID Extension blocks for additional timing descriptors */
1527        for (i = 1 ; i <= extensions; i++)
1528        {
1529                /* read the next 128 Byte EDID block */
1530                BHDM_CHECK_RC(rc, BHDM_EDID_GetNthBlock(hHDMI, i, hHDMI->AttachedEDID.Block, BHDM_EDID_BLOCKSIZE)) ;
1531
1532                /* check Extension Tag type for Timing Data */
1533                offset = 0 ;
1534                if (hHDMI->AttachedEDID.Block[BHDM_EDID_EXT_TAG] != BHDM_EDID_EXT_TIMING_DATA)
1535                        continue ;
1536
1537                /* check if data blocks exist before the 18 Byte Detailed Timing data */
1538                DataOffset = hHDMI->AttachedEDID.Block[BHDM_EDID_EXT_DATA_OFFSET] ;
1539                if (DataOffset == 0) /* no timing info in the block */
1540                {
1541                        BDBG_MSG(("EDID Ext contains no Detail Timing Descriptors")) ;
1542                        continue ;          /* continue to the next Timing Extension */
1543                }
1544
1545                /* determine the number of timing data */
1546                switch (hHDMI->AttachedEDID.Block[BHDM_EDID_EXT_VERSION])
1547                {
1548                case 0x01 :  /* Version 1 See CEA-861        */
1549                        MaxDescriptors = 6 ;
1550                        break ;
1551
1552                case 0x02 :  /* Version 2 See CEA-861 A Spec */
1553                case 0x03 :  /* Version 3 See CEA-861 B Spec */
1554                        MaxDescriptors = hHDMI->AttachedEDID.Block[BHDM_EDID_EXT_MONITOR_SUPPORT] ;
1555                        MaxDescriptors = MaxDescriptors & 0x0F ;
1556                        MaxDescriptors = MaxDescriptors - NumDetailedTimingsFound ;
1557
1558                        break ;
1559
1560                default :
1561                        /* Check all blocks regardless of */
1562                        /* the version of the EDID Extension */
1563                        BDBG_MSG(("Timing Extension Version '%d' Not Supported",
1564                                hHDMI->AttachedEDID.Block[offset+1])) ;
1565                        rc = BHDM_EDID_EXT_VERSION_NOT_SUPPORTED ;
1566                        goto BcmSupportedFormatNotFound;
1567                }
1568
1569                BDBG_MSG(("EDID Extension #%d contains additional Timing Data", i)) ;
1570
1571
1572                /* skip start of EDID Extension Block */
1573                offset = offset + hHDMI->AttachedEDID.Block[offset + 2] ;
1574
1575                for (j = 0 ; j < MaxDescriptors; j++)
1576                {
1577                        /* advance to next descriptor in the extension */
1578                        offset = offset + 18 * j ;
1579
1580                        /* skip any Detailed Timing blocks used as descriptors */
1581                        /* Descriptor Blocks begin with 0x00 0x00 0x00...      */
1582                        /* Timing Blocks do not...                                                 */
1583
1584#ifdef DEBUG_DESCRIPTOR
1585                        BDBG_MSG(("COMPARE %02X %02X %02X %02X %02X ",
1586                                hHDMI->AttachedEDID.Block[offset],
1587                                hHDMI->AttachedEDID.Block[offset+1],hHDMI->AttachedEDID.Block[offset+2],
1588                                hHDMI->AttachedEDID.Block[offset+3], hHDMI->AttachedEDID.Block[offset+4])) ;
1589                        BDBG_MSG(("COMPARE %02X %02X %02X %02X %02X ",
1590                                hHDMI->AttachedEDID.DescriptorHeader[0],
1591                                hHDMI->AttachedEDID.DescriptorHeader[1], hHDMI->AttachedEDID.DescriptorHeader[2],
1592                                hHDMI->AttachedEDID.DescriptorHeader[3], hHDMI->AttachedEDID.DescriptorHeader[4])) ;
1593
1594                        BDBG_MSG(("Check Timing Block #%d of possible %d ", j+1, MaxDescriptors)) ;
1595                        BDBG_MSG(("DescriptorHeader %02X %02X %02X %02X %02X",
1596                                hHDMI->AttachedEDID.Block[offset],
1597                                hHDMI->AttachedEDID.Block[offset+1],    hHDMI->AttachedEDID.Block[offset+2],
1598                                hHDMI->AttachedEDID.Block[offset+3],    hHDMI->AttachedEDID.Block[offset+4])) ;
1599#endif
1600
1601                        /* skip EDID descriptor blocks */
1602                        if (BKNI_Memcmp(&hHDMI->AttachedEDID.Block[offset], (void *) &hHDMI->AttachedEDID.DescriptorHeader, 3) == 0)
1603                                continue ;
1604
1605
1606                        /* stop searching if the Requested Timing is found */
1607                        if (++NumDetailedTimingsFound == NthTimingRequested)
1608                        {
1609                                BHDM_EDID_ParseDetailedTimingDescriptor(
1610                                        &hHDMI->AttachedEDID.Block[offset], pBHDM_EDID_DetailTiming ) ;
1611
1612                                BDBG_MSG(("Detailed Timing #%d found in EDID Extension #%d, Descriptor Block #%d",
1613                                        NthTimingRequested, i, j+1)) ;
1614
1615                                rc = BHDM_EDID_P_DetailTiming2VideoFmt(hHDMI, pBHDM_EDID_DetailTiming, BCM_VideoFmt);
1616                                if (rc != BERR_SUCCESS)
1617                                        goto BcmSupportedFormatNotFound;
1618
1619                                break ;  /* falls to BcmSupportedFormatFound: label */
1620                        }
1621                }
1622        }
1623
1624
1625
1626BcmSupportedFormatFound:
1627        if (*BCM_VideoFmt == BFMT_VideoFmt_eCUSTOM_1366x768p
1628        || *BCM_VideoFmt == BFMT_VideoFmt_eCUSTOM_1366x768p_50Hz
1629#if BHDM_CONFIG_1366_FORMAT_CHECK
1630        || *BCM_VideoFmt == BFMT_VideoFmt_eDVI_1366x768p_60Hz
1631        || *BCM_VideoFmt == BFMT_VideoFmt_eDVI_1360x768p_60Hz
1632#endif
1633        )
1634        {
1635                if (hHDMI->AttachedEDID.BcmSupportedVideoFormats[BFMT_VideoFmt_e720p])
1636                {
1637                        BDBG_WRN(("Overriding DetailTiming #%d (1366x768p/1360x768p) to BFMT_VideoFmt_e720p",
1638                                NthTimingRequested));
1639                        *BCM_VideoFmt = BFMT_VideoFmt_e720p ;
1640                        goto done ;
1641                }
1642                /*      else fall to BcmSupportedFormatNotFound: label  */
1643                goto BcmSupportedFormatNotFound;
1644        }
1645        else if (BFMT_IS_VESA_MODE(*BCM_VideoFmt))
1646        {
1647                *BCM_VideoFmt = BFMT_VideoFmt_eDVI_640x480p ;
1648                BDBG_WRN(("Requested Detail Timing #%d is a PC format; Override with HDMI supported VGA\n\n",
1649                        NthTimingRequested)) ;
1650        }
1651       
1652        goto done ;
1653
1654
1655BcmSupportedFormatNotFound:
1656        rc = BHDM_EDID_DETAILTIMING_NOT_SUPPORTED;
1657        /* Detailed Timing Request Not Found */
1658        BDBG_WRN(("Requested Detailed Timing %d NOT SUPPORTED - Detailed Timings found: %d",
1659                NthTimingRequested, NumDetailedTimingsFound)) ;
1660        for (i=0; i<BHDM_EDID_P_ALT_PREFERRED_VIDEOFMT_MAX; i++) {
1661                if (hHDMI->AttachedEDID.BcmSupportedVideoFormats[BHDM_EDID_P_AltPreferredFormats[i].format])
1662                {
1663                        BDBG_WRN(("Overriding to %s format", BHDM_EDID_P_AltPreferredFormats[i].formattext));
1664                        *BCM_VideoFmt = BHDM_EDID_P_AltPreferredFormats[i].format;
1665                        break;
1666                }
1667        }
1668
1669
1670done:
1671        BDBG_LEAVE(BHDM_EDID_GetDetailTiming) ;
1672
1673        return rc ;
1674}
1675
1676
1677/******************************************************************************
1678BERR_Code BHDM_EDID_GetVideoDescriptor
1679Summary: Retrieve EDID Detail Timing Data
1680*******************************************************************************/
1681BERR_Code BHDM_EDID_GetVideoDescriptor(
1682        BHDM_Handle hHDMI,                       /* [in] HDMI handle */
1683        uint8_t NthIdCode,           /* [in] number of the Video ID Code to get */
1684        uint8_t *VideoIdCode,        /* [out] 861B Video ID Code  */
1685        BFMT_VideoFmt *BCM_VideoFmt, /* [out] associated BFMT */
1686        uint8_t *NativeFormat        /* Native Monitor Format */
1687)
1688{
1689        BERR_Code rc = BERR_SUCCESS ;
1690
1691        uint8_t i ;
1692        uint8_t RxDeviceAttached ;
1693        BHDM_EDID_P_VideoDescriptor  *pVideoDescriptor ;
1694
1695        BDBG_ENTER(BHDM_EDID_GetVideoDescriptor) ;
1696
1697        /* make sure HDMI Cable is connected to something... */
1698        BHDM_CHECK_RC(rc, BHDM_RxDeviceAttached(hHDMI, &RxDeviceAttached));
1699        if (!RxDeviceAttached)
1700                return BHDM_NO_RX_DEVICE ;
1701
1702#if BDBG_DEBUG_BUILD
1703        if (hHDMI->DeviceSettings.BypassEDIDChecking)
1704        {
1705                BDBG_WRN(("EDID is ByPassed; All formats will attempt to display")) ;
1706                goto done ;
1707        }
1708#endif
1709
1710        if (hHDMI->edidStatus == BHDM_EDID_STATE_eInvalid)
1711        {
1712                rc = BHDM_EDID_NOT_FOUND;
1713                goto done;
1714        }
1715
1716        if (!hHDMI->AttachedEDID.RxHasHdmiSupport)
1717        {
1718                rc = BHDM_EDID_HDMI_NOT_SUPPORTED ;
1719                goto done ;
1720        }
1721
1722        if (!NthIdCode)
1723        {
1724                rc = BERR_INVALID_PARAMETER ;
1725                BDBG_ERR(("Incorrectly specified Id Code: %d", NthIdCode)) ;
1726                goto done ;
1727        }
1728
1729        i = 1 ;
1730        for( pVideoDescriptor = BLST_Q_FIRST(&hHDMI->AttachedEDID.VideoDescriptorList);
1731                        pVideoDescriptor ; pVideoDescriptor = BLST_Q_NEXT(pVideoDescriptor, link))
1732        {
1733                if (i++ == NthIdCode)
1734                {
1735                        *VideoIdCode  = (uint8_t) pVideoDescriptor->VideoIdCode ;
1736                        *BCM_VideoFmt = (BFMT_VideoFmt) pVideoDescriptor->eVideoFmt  ;
1737                        *NativeFormat = (uint8_t) pVideoDescriptor->NativeFormat ;
1738
1739                        BDBG_MSG(("VICn: %d; BCM_Fmt: %d; Native Fmt: %d",
1740                                *VideoIdCode, *BCM_VideoFmt, *NativeFormat)) ;
1741                        goto done ;
1742                }
1743        }
1744
1745done:
1746        BDBG_LEAVE(BHDM_EDID_GetVideoDescriptor) ;
1747
1748        return rc ;
1749}
1750/*
1751*** BASE_HDMI: Attached Monitor VESA Formats Only
1752--- BHDM_EDID: 2 VICn: 6; BCM_Fmt: 26; Monitor Native Format: 0
1753*/
1754
1755/******************************************************************************
1756BERR_Code BHDM_EDID_GetDescriptor
1757Summary: Retrieve a specified EDID descriptor
1758*******************************************************************************/
1759BERR_Code BHDM_EDID_GetDescriptor(
1760   BHDM_Handle hHDMI, /* [in] HDMI handle */
1761   BHDM_EDID_Tag tag, /* [in] id of the descriptor tag to retrieve */
1762   uint8_t *pDescriptorText, /* [out] pointer to memory to hold retrieved tag data */
1763   uint8_t uiBufSize         /* [in ] mem size in bytes of pDescriptorText */
1764)
1765{
1766        uint8_t TagId ;
1767        uint8_t i, j ;
1768        uint8_t offset ;
1769        uint8_t extensions ;
1770        uint8_t MaxDescriptors ;
1771        uint8_t RxDeviceAttached ;
1772
1773        BERR_Code rc = BERR_SUCCESS ;
1774
1775        BDBG_ENTER(BHDM_EDID_GetDescriptor) ;
1776
1777        /* make sure HDMI Cable is connected to something... */
1778        BHDM_CHECK_RC(rc, BHDM_RxDeviceAttached(hHDMI, &RxDeviceAttached));
1779        if (!RxDeviceAttached)
1780        {
1781                return BHDM_NO_RX_DEVICE ;
1782        }
1783
1784        if (hHDMI->edidStatus == BHDM_EDID_STATE_eInvalid)
1785        {
1786                rc = BHDM_EDID_NOT_FOUND;
1787                goto done;
1788        }
1789
1790
1791#if BDBG_DEBUG_BUILD
1792        if (hHDMI->DeviceSettings.BypassEDIDChecking)
1793        {
1794                BKNI_Memcpy(pDescriptorText, EDIDByPassedText,
1795                        BHDM_EDID_MONITOR_DESC_SIZE - BHDM_EDID_DESC_HEADER_LEN) ;
1796                goto done ;
1797        }
1798#endif
1799
1800        if ((!uiBufSize)
1801        ||  (uiBufSize > BHDM_EDID_MONITOR_DESC_SIZE)
1802        ||  (uiBufSize < BHDM_EDID_MONITOR_DESC_SIZE - BHDM_EDID_DESC_HEADER_LEN))
1803        {
1804                BDBG_ERR(("Incorrect Specified Descriptor Length: %d", uiBufSize)) ;
1805                rc = BERR_INVALID_PARAMETER ;
1806                goto done ;
1807        }
1808
1809
1810        /* check for valid tag */
1811        switch (tag)
1812        {
1813        case BHDM_EDID_Tag_eMONITOR_NAME  :
1814                /* monitor name should have been read at EDID_Initialize */
1815                if (hHDMI->AttachedEDID.MonitorName[0] == 0x00)
1816                {
1817                        BKNI_Memcpy(pDescriptorText, &hHDMI->AttachedEDID.MonitorName,
1818                                BHDM_EDID_MONITOR_DESC_SIZE - BHDM_EDID_DESC_HEADER_LEN) ;
1819
1820                        rc = BERR_SUCCESS ;  /* Descriptor Found and Copied */
1821                        goto done ;
1822                }
1823                TagId = BHDM_EDID_TAG_MONITOR_NAME ;
1824                break ;
1825
1826        case BHDM_EDID_Tag_eMONITOR_ASCII :
1827                TagId = BHDM_EDID_TAG_MONITOR_ASCII ;
1828                break ;
1829
1830        case BHDM_EDID_Tag_eMONITOR_SN    :
1831                TagId = BHDM_EDID_TAG_MONITOR_SN ;
1832                break ;
1833
1834        default :
1835                BDBG_ERR(("Invalid Descriptor Tag: %d", tag)) ;
1836                rc = BERR_INVALID_PARAMETER ;
1837                goto done ;
1838        }
1839
1840        /* Insert the Tag we are searching for in the Descriptor Header */
1841        BKNI_Memset((void *) &hHDMI->AttachedEDID.DescriptorHeader, 0x0, BHDM_EDID_DESC_HEADER_LEN);
1842        hHDMI->AttachedEDID.DescriptorHeader[BHDM_EDID_DESC_TAG] = TagId ;
1843
1844        /* read the 1st EDID Block */
1845        BHDM_CHECK_RC(rc, BHDM_EDID_GetNthBlock(hHDMI,
1846                0, hHDMI->AttachedEDID.Block, BHDM_EDID_BLOCKSIZE)) ;
1847
1848        /* Check the four Descriptor Blocks in the initial 128 EDID  bytes */
1849        for (i = 0 ; i < 4; i++)   /* 1-4 Detailed Timing Descriptor */
1850        {
1851                offset = BHDM_EDID_MONITOR_DESC_1 + BHDM_EDID_MONITOR_DESC_SIZE * i ;
1852
1853                /*
1854                ** Check if we've found the Descriptor tag we're looking for
1855                ** Descriptor Blocks begin with 0x00 0x00 0x00 <tag> 0x00
1856                ** Detailed Timings do not...
1857                */
1858                if (BKNI_Memcmp(&hHDMI->AttachedEDID.Block[offset], (void *) &hHDMI->AttachedEDID.DescriptorHeader,
1859                        BHDM_EDID_DESC_HEADER_LEN) == 0)
1860                {
1861                        BKNI_Memcpy(pDescriptorText, &hHDMI->AttachedEDID.Block[offset + BHDM_EDID_DESC_DATA],
1862                                BHDM_EDID_MONITOR_DESC_SIZE - BHDM_EDID_DESC_HEADER_LEN) ;
1863
1864                        rc = BERR_SUCCESS ;  /* Descriptor Found and Copied */
1865                        goto done ;
1866                }
1867        }
1868
1869        /* Descriptor Not Found...check extension blocks */
1870        extensions = hHDMI->AttachedEDID.BasicData.Extensions;
1871        if (!extensions)
1872        {
1873                rc = BHDM_EDID_DESCRIPTOR_NOT_FOUND ;
1874                goto done ;
1875        }
1876
1877
1878        /* Search EDID Extension blocks for additional descriptors */
1879        for (i = 1 ; i <= extensions; i++)
1880        {
1881                /* read the next 128 Byte EDID block */
1882                BHDM_CHECK_RC(rc, BHDM_EDID_GetNthBlock(hHDMI,
1883                        i, hHDMI->AttachedEDID.Block, BHDM_EDID_BLOCKSIZE)) ;
1884
1885
1886                /* check Extension Tag type for Timing Data */
1887                offset = 0 ;
1888                if (hHDMI->AttachedEDID.Block[offset] != BHDM_EDID_EXT_TIMING_DATA)
1889                        continue ;
1890
1891                /* determine the number of Detailed Timing Descripors */
1892                switch (hHDMI->AttachedEDID.Block[offset+1])
1893                {
1894                case 0x01 :  /* Check all blocks regardless of */
1895                        MaxDescriptors = 6 ;   /* (128 - 6) / 18 */
1896                        break ;
1897
1898                case 0x02 :  /* the version of the EDID Extension */
1899                case 0x03 :  /* See EA-861 B Spec */
1900                        MaxDescriptors = hHDMI->AttachedEDID.Block[BHDM_EDID_EXT_MONITOR_SUPPORT] ;
1901                        MaxDescriptors = MaxDescriptors & 0x0F ;
1902                        break ;
1903
1904                default :
1905                        BDBG_ERR(("Timing Extension Version '%d' Not Supported",
1906                                hHDMI->AttachedEDID.Block[offset+1])) ;
1907                        rc = BHDM_EDID_EXT_VERSION_NOT_SUPPORTED ;
1908                        goto done ;
1909                }
1910
1911
1912                /* skip start of EDID Extension Block */
1913                offset = offset + hHDMI->AttachedEDID.Block[offset + 2] ;
1914
1915                for (j = 0 ; j < MaxDescriptors; j++)
1916                {
1917                        if (BKNI_Memcmp(&hHDMI->AttachedEDID.Block[offset + BHDM_EDID_MONITOR_DESC_SIZE*j],
1918                                       (void *) &hHDMI->AttachedEDID.DescriptorHeader, BHDM_EDID_DESC_HEADER_LEN) == 0)
1919                        {
1920                                BKNI_Memcpy(pDescriptorText, &hHDMI->AttachedEDID.Block[offset + BHDM_EDID_DESC_DATA],
1921                                        BHDM_EDID_MONITOR_DESC_SIZE - BHDM_EDID_DESC_HEADER_LEN) ;
1922                                rc = BERR_SUCCESS ;  /* Descriptor Found and Copied */
1923                                goto done ;
1924                        }
1925                }
1926        }
1927
1928done:
1929        BDBG_LEAVE(BHDM_EDID_GetDescriptor) ;
1930        return rc ;
1931} /* end BHDM_EDID_GetDescriptor */
1932
1933
1934
1935BERR_Code BHDM_EDID_P_GetMonitorRange(BHDM_Handle hHDMI, uint8_t offset)
1936{
1937        BERR_Code rc = BERR_SUCCESS ;
1938
1939        hHDMI->AttachedEDID.MonitorRange.MinVertical =
1940                hHDMI->AttachedEDID.Block[offset + BHDM_EDID_DESC_RANGE_MIN_V_RATE] ;
1941
1942        hHDMI->AttachedEDID.MonitorRange.MaxVertical =
1943                hHDMI->AttachedEDID.Block[offset +  BHDM_EDID_DESC_RANGE_MAX_V_RATE] ;
1944
1945        hHDMI->AttachedEDID.MonitorRange.MinHorizontal =
1946                hHDMI->AttachedEDID.Block[offset +  BHDM_EDID_DESC_RANGE_MIN_H_RATE] ;
1947
1948        hHDMI->AttachedEDID.MonitorRange.MaxHorizontal =
1949                hHDMI->AttachedEDID.Block[offset +  BHDM_EDID_DESC_RANGE_MAX_H_RATE] ;
1950
1951        hHDMI->AttachedEDID.MonitorRange.MaxPixelClock
1952                = hHDMI->AttachedEDID.Block[offset + BHDM_EDID_DESC_RANGE_MAX_PCLOCK] * 10 ;
1953
1954        /*
1955        ** check for secondary timing formula but don't decode it...
1956        ** make the bytes available for decoding by caller..
1957        */
1958        hHDMI->AttachedEDID.MonitorRange.SecondaryTiming =
1959                hHDMI->AttachedEDID.Block[offset + EDID_DESC_TIMING_FORMULA] ;
1960
1961        BKNI_Memcpy(hHDMI->AttachedEDID.MonitorRange.SecondaryTimingParameters,
1962                   &hHDMI->AttachedEDID.Block[offset + EDID_DESC_TIMING_FORMULA + 1], 7) ;
1963
1964#if BDBG_DEBUG_BUILD
1965        /* Display DEBUG Messages */
1966        BDBG_MSG(("Min - Max Vertical:   %d - %d Hz",
1967                hHDMI->AttachedEDID.MonitorRange.MinVertical,   hHDMI->AttachedEDID.MonitorRange.MaxVertical)) ;
1968
1969        BDBG_MSG(("Min - Max Horizontal: %d - %d kHz",
1970                hHDMI->AttachedEDID.MonitorRange.MinHorizontal, hHDMI->AttachedEDID.MonitorRange.MaxHorizontal)) ;
1971
1972        BDBG_MSG(("Max Pixel Clock %d MHz", hHDMI->AttachedEDID.MonitorRange.MaxPixelClock)) ;
1973
1974#if 0
1975        /* Display More DEBUG messages for Timing Support */
1976        switch (hHDMI->AttachedEDID.MonitorRange.SecondaryTiming)
1977        {
1978        case 0x00 : BDBG_MSG(("No Timing Formula Support")) ;     break ;
1979        case 0x02 : BDBG_MSG(("Secondary GTF curve supported")) ; break ;
1980        default :   BDBG_MSG(("Other secondary timing formula")) ;
1981        }
1982#endif
1983        BDBG_MSG(("[END Monitor Range Descriptor]")) ; /* add a blank line */
1984#endif
1985
1986        return rc ;
1987}
1988
1989
1990
1991/******************************************************************************
1992BERR_Code BHDM_EDID_GetMonitorRange
1993Summary: Retrieve the monitor ranges supported as specified in the EDID
1994*******************************************************************************/
1995BERR_Code BHDM_EDID_GetMonitorRange(
1996   BHDM_Handle hHDMI,                    /* [in] HDMI handle */
1997   BHDM_EDID_MonitorRange *pMonitorRange /* [out] pointer to BHDM_EDID_MonitorRange
1998                                                                                    to hold the retrieved data */
1999)
2000{
2001        BERR_Code rc = BERR_SUCCESS ;
2002        uint8_t RxDeviceAttached ;
2003
2004        BDBG_ENTER(BHDM_EDID_GetMonitorRange) ;
2005
2006        /* make sure HDMI Cable is connected to something... */
2007        BHDM_CHECK_RC(rc, BHDM_RxDeviceAttached(hHDMI, &RxDeviceAttached));
2008        if (!RxDeviceAttached)
2009        {
2010                return BHDM_NO_RX_DEVICE ;
2011        }
2012
2013        if (hHDMI->AttachedEDID.MonitorRange.MinVertical == 0)
2014                return BHDM_EDID_NOT_IMPLEMENTED ;
2015
2016        if (hHDMI->edidStatus == BHDM_EDID_STATE_eInvalid) {
2017                return BHDM_EDID_NOT_FOUND;
2018        }
2019
2020        BKNI_Memcpy(pMonitorRange, &hHDMI->AttachedEDID.MonitorRange, sizeof(BHDM_EDID_MonitorRange)) ;
2021
2022done:
2023        BDBG_LEAVE(BHDM_EDID_GetMonitorRange) ;
2024        return rc ;
2025} /* BHDM_EDID_GetMonitorRange */
2026
2027
2028
2029/******************************************************************************
2030BERR_Code BHDM_EDID_IsRxDeviceHdmi
2031Summary: Retrieve the Vendor Specific Data Block from the first Version 3 Timing
2032Extension in the EDID
2033*******************************************************************************/
2034BERR_Code BHDM_EDID_IsRxDeviceHdmi(
2035   BHDM_Handle hHDMI,                  /* [in] HDMI handle */
2036   BHDM_EDID_RxVendorSpecificDB *RxVSDB,  /* [out] pointer to Vendor Specific Data
2037                                            Block to hold the retrieved data */
2038   bool *bHdmiDevice
2039)
2040{
2041        uint8_t RxDeviceAttached ;
2042        BERR_Code rc = BERR_SUCCESS ;
2043
2044
2045        BDBG_ENTER(BHDM_EDID_IsRxDeviceHdmi) ;
2046
2047        BKNI_Memset(RxVSDB, 0, sizeof(BHDM_EDID_RxVendorSpecificDB)) ;
2048               
2049
2050        *bHdmiDevice = false ;  /* assume device is not HDMI */
2051
2052        /* make sure HDMI Cable is connected to something... */
2053        BHDM_CHECK_RC(rc, BHDM_RxDeviceAttached(hHDMI, &RxDeviceAttached));
2054        if (!RxDeviceAttached)
2055        {
2056                rc = BHDM_NO_RX_DEVICE ;
2057                goto done ;
2058        }
2059
2060#if BDBG_DEBUG_BUILD
2061        if (hHDMI->DeviceSettings.BypassEDIDChecking)
2062        {
2063                BDBG_WRN(("EDID is ByPassed; Assuming DVI monitor attached")) ;
2064                goto done ;
2065        }
2066#endif
2067
2068        if (hHDMI->edidStatus == BHDM_EDID_STATE_eInvalid) {
2069                BDBG_WRN(("No Valid EDID Found. Default to DVI Device"));
2070                goto done;
2071        }
2072
2073        *bHdmiDevice = hHDMI->AttachedEDID.RxHasHdmiSupport ;
2074        if (!*bHdmiDevice)
2075                goto done ;
2076
2077        /* EDID processed at initialization; copy information */
2078        BKNI_Memcpy(RxVSDB,  &hHDMI->AttachedEDID.RxVSDB, sizeof(BHDM_EDID_RxVendorSpecificDB)) ;
2079
2080
2081#if BDBG_DEBUG_BUILD
2082        if (hHDMI->edidStatus == BHDM_EDID_STATE_eInitialize)
2083        {
2084                BDBG_MSG(("HDMI Rx Supported Features (%#x):", RxVSDB)) ;
2085                BDBG_MSG(("\tUnderscan:    %s", g_status[RxVSDB->Underscan ? 1 : 0])) ;
2086                BDBG_MSG(("\tAudio Caps:   %s", g_status[RxVSDB->Audio ? 1 : 0])) ;
2087                BDBG_MSG(("\tYCbCr: 4:2:2 %s   4:4:4 %s",
2088                        g_status[RxVSDB->YCbCr422 ? 1 : 0],
2089                        g_status[RxVSDB->YCbCr444 ? 1 : 0])) ;
2090
2091                BDBG_MSG(("\tNative Formats in Descriptors: %d",
2092                        RxVSDB->NativeFormatsInDescriptors)) ;
2093
2094                BDBG_MSG(("END HDMI Rx Supported Features")) ;
2095                hHDMI->edidStatus = BHDM_EDID_STATE_eProcessing ;
2096        }
2097#endif
2098
2099
2100done:
2101        BDBG_LEAVE(BHDM_EDID_IsRxDeviceHdmi) ;
2102        return  rc ;
2103} /* BHDM_EDID_IsRxDeviceHdmi */
2104
2105
2106
2107/******************************************************************************
2108BERR_Code BHDM_EDID_CheckRxHdmiAudioSupport
2109Summary: Check if the input Audio Format is supported by the attached HDMI
2110Receiver
2111*******************************************************************************/
2112BERR_Code BHDM_EDID_CheckRxHdmiAudioSupport(
2113   BHDM_Handle hHDMI,                         /* [in] HDMI handle  */
2114   BAVC_AudioFormat       eAudioFormat,       /* [in] Audio Format */
2115   BAVC_AudioSamplingRate eAudioSamplingRate, /* [in] Audio Rate to check for */
2116   BAVC_AudioBits         eAudioBits,         /* [in] Quantization Bits to search for */
2117   uint16_t               iCompressedBitRate, /* [in] Bit Rate if Compressed Audio */
2118   uint8_t                *iSupported         /* [out] audio format is supported */
2119)
2120{
2121        BERR_Code rc = BERR_SUCCESS ;
2122
2123        uint8_t
2124                i,
2125                FormatFound,
2126                EdidAudioSamplingRate,
2127                EdidAudioBits,
2128                EdidMaxCompressedBitRate ;
2129
2130        uint8_t RxDeviceAttached ;
2131
2132        BDBG_ENTER(BHDM_EDID_CheckRxHdmiAudioSupport) ;
2133
2134        *iSupported = 0 ;
2135
2136        /* make sure HDMI Cable is connected to something... */
2137        BHDM_CHECK_RC(rc, BHDM_RxDeviceAttached(hHDMI, &RxDeviceAttached));
2138        if (!RxDeviceAttached)
2139        {
2140                return BHDM_NO_RX_DEVICE ;
2141        }
2142
2143        if (hHDMI->edidStatus == BHDM_EDID_STATE_eInvalid) {
2144                return BHDM_EDID_NOT_FOUND;
2145        }
2146
2147        /* 1st check for requested format */
2148        if(!hHDMI->AttachedEDID.BcmSupportedAudioFormats[eAudioFormat].Supported)
2149                goto done ;
2150
2151        /**********************************************/
2152        /* 2nd, Check for requested Audio Sample Rate */
2153        /* convert the BAVC_AudioSampleRate to EdidAudioSampleRate */
2154
2155        EdidAudioSamplingRate = BAVC_AudioSamplingRate_eUnknown  ;
2156        for (i = 0; i < sizeof(EdidAudioSampleRateTable) / sizeof(*EdidAudioSampleRateTable) ; i++)
2157                if (eAudioSamplingRate == EdidAudioSampleRateTable[i].BcmAudioSampleRate)
2158                {
2159                        EdidAudioSamplingRate = EdidAudioSampleRateTable[i].EdidAudioSampleRate ;
2160                        break ;
2161                }
2162
2163        if (EdidAudioSamplingRate == BAVC_AudioSamplingRate_eUnknown)
2164                goto done ;
2165
2166        if (!(EdidAudioSamplingRate
2167                & hHDMI->AttachedEDID.BcmSupportedAudioFormats[i].ucCeaSampleRates))
2168                goto done ;
2169
2170
2171        /********************************************************/
2172        /* 3rd, Get the number of Audio Bits (quantization) the */
2173        /* monitor supports for the requested Audio Format etc  */
2174
2175
2176        EdidAudioBits =
2177                hHDMI->AttachedEDID.BcmSupportedAudioFormats[i].ucCeaNBits_BitRate ;
2178
2179        FormatFound = 0 ;
2180        /* get the number of bits supported by this format */
2181        if (eAudioFormat != BAVC_AudioFormat_ePCM) /* compressed */
2182        {                                                                                  /*  formats   */
2183                /* Max Bit Rate = EdidAudioBits * 8 */
2184                EdidMaxCompressedBitRate = EdidAudioBits * 8 ;
2185                if (iCompressedBitRate  <= EdidMaxCompressedBitRate)
2186                {
2187                        BDBG_MSG(("<%.*s> Max Bit Rate Supported: %d",
2188                                        BHDM_EDID_DESC_ASCII_STRING_LEN, hHDMI->AttachedEDID.MonitorName,
2189                                        EdidMaxCompressedBitRate)) ;
2190                        FormatFound = 1 ;
2191                }
2192        } /* if compressed formats */
2193        else                                                                     /* uncompressed */
2194        {                                                                                /*     PCM      */
2195                if (EdidAudioBits & 0x01)           EdidAudioBits = 16 ;
2196                else if (EdidAudioBits & 0x02)          EdidAudioBits = 20 ;
2197                else if (EdidAudioBits & 0x04)          EdidAudioBits = 24 ;
2198                else
2199                {
2200                        BDBG_WRN(("Unknown Supported Bit Rate")) ;
2201                        rc = BHDM_EDID_HDMI_UNKNOWN_BIT_RATE ;
2202                        goto done ;
2203                }
2204
2205                /* check if the number of bits matches the requested value */
2206                if (eAudioBits == BAVC_AudioBits_e16)           FormatFound = (EdidAudioBits == 16) ;
2207                else if (eAudioBits == BAVC_AudioBits_e20)      FormatFound = (EdidAudioBits == 20) ;
2208                else if (eAudioBits == BAVC_AudioBits_e24)      FormatFound = (EdidAudioBits == 24) ;
2209        } /* else uncompressed formats */
2210
2211
2212        if (FormatFound)
2213                *iSupported = 1 ;
2214
2215done:
2216        BDBG_LEAVE(BHDM_EDID_CheckRxHdmiAudioSupport) ;
2217        return  rc ;
2218} /* BHDM_EDID_CheckRxHdmiAudioSupport */
2219
2220
2221
2222/******************************************************************************
2223BERR_Code BHDM_EDID_CheckRxHdmiVideoSupport
2224Summary: Check if the input Audio Format is supported by the attached HDMI
2225Receiver
2226*******************************************************************************/
2227BERR_Code BHDM_EDID_CheckRxHdmiVideoSupport(
2228        BHDM_Handle hHDMI,                    /* [in] HDMI handle  */
2229        uint16_t           HorizontalPixels,  /* [in] Horiz Active Pixels */
2230        uint16_t           VerticalPixels,    /* [in] Vertical Active Pixels */
2231        BAVC_ScanType      eScanType,         /* [in] Progressive, Interlaced */
2232        BAVC_FrameRateCode eFrameRateCode,    /* [in] Vertical Frequency */
2233        BFMT_AspectRatio   eAspectRatio,      /* [in] Horiz to Vertical Ratio */
2234        uint8_t            *pNativeFormat         /* [out] Requested format is a
2235                                                                                      native format to the monitor */
2236)
2237{
2238        BERR_Code rc = BHDM_EDID_HDMI_VIDEO_FORMAT_UNSUPPORTED ;
2239
2240        uint8_t
2241                i, j, k, /* indexes */
2242                extensions,
2243                DataOffset,
2244                DataBlockIndex,
2245                DataBlockTag,
2246                DataBlockLength,
2247                FormatFound,
2248                NumVideoDescriptors,
2249                EdidVideoIDCode ;
2250
2251        uint8_t RxDeviceAttached ;
2252
2253        BDBG_ENTER(BHDM_EDID_CheckRxHdmiVideoSupport) ;
2254
2255
2256        /* make sure HDMI Cable is connected to something... */
2257        BHDM_CHECK_RC(rc, BHDM_RxDeviceAttached(hHDMI, &RxDeviceAttached));
2258        if (!RxDeviceAttached)
2259        {
2260                return BHDM_NO_RX_DEVICE ;
2261        }
2262
2263        if (hHDMI->edidStatus == BHDM_EDID_STATE_eInvalid) {
2264                return BHDM_EDID_NOT_FOUND;
2265        }
2266
2267        /* first get the number of extensions in the EDID */
2268        /* audio support is always in first V3 Timing Extension; never in block 0 */
2269        extensions = hHDMI->AttachedEDID.BasicData.Extensions ;
2270
2271        if (!extensions)
2272        {
2273                BDBG_WRN(("No EDID Extensions Found... No HDMI Support")) ;
2274                rc = BHDM_EDID_HDMI_VIDEO_FORMAT_UNSUPPORTED ;
2275                goto done ;
2276        }
2277
2278        /* check ALL extensions for Version 3 Timing Extensions */
2279        for (i = 1 ; i <= extensions; i++)
2280        {
2281                if (hHDMI->edidStatus != BHDM_EDID_STATE_eOK)
2282                {
2283                        BHDM_CHECK_RC(rc,
2284                                BHDM_EDID_GetNthBlock(hHDMI, i, (uint8_t *) &hHDMI->AttachedEDID.Block, BHDM_EDID_BLOCKSIZE)) ;
2285                }
2286
2287                /* check for Timing Data Extension */
2288                if (hHDMI->AttachedEDID.Block[BHDM_EDID_EXT_TAG] != BHDM_EDID_EXT_TIMING_DATA)
2289                        continue ;
2290
2291                /* check for Version 3 Timing Data Extension */
2292                if (hHDMI->AttachedEDID.Block[BHDM_EDID_EXT_VERSION] != BHDM_EDID_TIMING_VERSION_3)
2293                        continue ;
2294
2295
2296                BDBG_MSG(("V3 Timing Extension found in EDID Extension #%d", i)) ;
2297
2298                /* check if data blocks exist before the 18 Byte Detailed Timing data */
2299                DataOffset = hHDMI->AttachedEDID.Block[BHDM_EDID_EXT_DATA_OFFSET] ;
2300                if ((DataOffset == 0)
2301                ||  (DataOffset == 4)) /* no Reserved Data is Available */
2302                {
2303                        BDBG_MSG(("-----V3 Timing Extension contains no CEA Data Blocks")) ;
2304                        continue ;          /* continue to the next Timing Extension */
2305                }
2306                BDBG_MSG(("-----CEA Data Blocks found in V3 Timing Extension")) ;
2307
2308
2309                /* set the index to the start of Data Blocks */
2310                DataBlockIndex = BHDM_EDID_EXT_DATA_BLOCK_COLLECTION ;
2311
2312                /* scan through the data blocks and retrieve the necessary information */
2313                while (DataBlockIndex < DataOffset)
2314                {
2315                        /* get the Data Block type */
2316                        DataBlockTag =
2317                                hHDMI->AttachedEDID.Block[DataBlockIndex] >> 5 ;
2318
2319                        /* get the Data Block length */
2320                        DataBlockLength =
2321                                hHDMI->AttachedEDID.Block[DataBlockIndex] & 0x1F ;
2322
2323                        BDBG_MSG(("\n[%02X] CEA-861 %s (0x%02x) found; %d bytes",
2324                                hHDMI->AttachedEDID.Block[DataBlockIndex],
2325                                CeaTagName[DataBlockTag], DataBlockTag, DataBlockLength)) ;
2326
2327                        switch (DataBlockTag)
2328                        {
2329
2330                        /* return error on unknown Tags */
2331                        default :
2332                                BDBG_WRN(("\nCEA-861 Data Block Tag Code <%d> is not supported",
2333                                        DataBlockTag)) ;
2334                                rc = BHDM_EDID_HDMI_UNKNOWN_CEA_TAG ;
2335                                goto done ;
2336
2337                        /* skip Block Tags that are of no interest to this function */
2338                        case BHDM_EDID_CeaDataBlockTag_eVSDB :      /* Vendor Specific DB */
2339                        case BHDM_EDID_CeaDataBlockTag_eAudioDB :   /* Audio DB */
2340                        case BHDM_EDID_CeaDataBlockTag_eSpeakerDB : /* Speaker Allocation DB */
2341                        case BHDM_EDID_CeaDataBlockTag_eReserved0 :
2342                        case BHDM_EDID_CeaDataBlockTag_eReserved5 :
2343                        case BHDM_EDID_CeaDataBlockTag_eReserved6 :
2344                        case BHDM_EDID_CeaDataBlockTag_eExtendedDB:
2345                                break ;
2346
2347                        case BHDM_EDID_CeaDataBlockTag_eVideoDB :   /* Video DB */
2348                                /* check each video descriptor for requested video support */
2349
2350                                FormatFound = 0 ;
2351                                NumVideoDescriptors = DataBlockLength ;
2352
2353                                /* for each CEA Video ID Code Found */
2354                                for (j = 0 ; j < NumVideoDescriptors && !FormatFound ; j++ )
2355                                {
2356                                        /* get the supported Video Code ID; check if a native format */
2357                                        EdidVideoIDCode = hHDMI->AttachedEDID.Block[DataBlockIndex + j + 1] ;
2358                                        EdidVideoIDCode = EdidVideoIDCode  & 0x7F ;
2359
2360                                        *pNativeFormat = EdidVideoIDCode & 0x80 ;
2361
2362                                        BDBG_MSG(("Find CEA Video ID Code %02d parameters...",
2363                                                EdidVideoIDCode)) ;
2364
2365                                        /* search BCM 861-B supported formats for format found in EDID */
2366                                        for (k = 0 ; k < BHDM_EDID_P_BCM_VIDEO_FORMATS_MAX ; k++)
2367                                        {
2368                                                if (EdidVideoIDCode != BHDM_EDID_P_Cea861bFormats[k].CeaVideoCode)
2369                                                        continue ;
2370
2371                                                BDBG_MSG(("Found supported CEA Video ID Code: %02d (%d x %d)",
2372                                                        EdidVideoIDCode,
2373                                                        BHDM_EDID_P_Cea861bFormats[k].HorizontalPixels,
2374                                                        BHDM_EDID_P_Cea861bFormats[k].VerticalPixels)) ;
2375
2376                                                /* check if the specified parameters match the requested formats */
2377                                                /* 1st, Check if Pixel Format matches */
2378                                                if ((HorizontalPixels != BHDM_EDID_P_Cea861bFormats[k].HorizontalPixels)
2379                                                ||      (VerticalPixels != BHDM_EDID_P_Cea861bFormats[k].VerticalPixels))
2380                                                        break  ;
2381                                                BDBG_MSG(("Pixel Format Match")) ;
2382
2383
2384                                                /* 2nd, Check Scan Type (i/p) */
2385                                                if (eScanType != BHDM_EDID_P_Cea861bFormats[k].eScanType)
2386                                                        break  ;
2387                                                BDBG_MSG(("Scan Type Match..")) ;
2388
2389
2390                                                /* 3rd, Check Vertical Frequency */
2391                                                if (eFrameRateCode != BHDM_EDID_P_Cea861bFormats[k].eFrameRateCode)
2392                                                        break ;
2393                                                BDBG_MSG(("Frame Rate Match..")) ;
2394
2395
2396                                                /* 4th  Check Aspect Ratio (4:3, 16:9) etc. */
2397                                                if (eAspectRatio != BHDM_EDID_P_Cea861bFormats[k].eAspectRatio)
2398                                                        break ;
2399
2400                                                BDBG_MSG(("Requested format is supported..")) ;
2401                                                rc = BERR_SUCCESS ;
2402                                                goto done ;
2403                                        } /* for each BCM Supported CEA Video ID Code */
2404                                } /* for each Supported CEA Video ID Code */
2405                        } /* for each CEA Video ID Code found */
2406
2407
2408                        DataBlockIndex += DataBlockLength + 1;
2409
2410                } /* while DataBlockIndex < DataOffset */
2411
2412        } /* for each extension */
2413
2414        rc = BHDM_EDID_HDMI_VIDEO_FORMAT_UNSUPPORTED ;
2415
2416done:
2417        BDBG_LEAVE(BHDM_EDID_CheckRxHdmiVideoSupport) ;
2418        return  rc ;
2419} /* BHDM_EDID_CheckRxHdmiVideoSupport */
2420
2421
2422
2423/******************************************************************************
2424BERR_Code BHDM_EDID_VideoFmtSupported
2425Summary: Check if the requested VideoFmt is supported by the attached HDMI Rx
2426*******************************************************************************/
2427BERR_Code BHDM_EDID_VideoFmtSupported(
2428        BHDM_Handle hHDMI,        /* [in] HDMI handle  */
2429        BFMT_VideoFmt eVideoFmt,  /* requested video format */
2430        uint8_t *Supported        /* [out] true/false Requested format is
2431                                                            supported by the monitor */
2432)
2433{
2434        BERR_Code rc = BERR_SUCCESS  ;
2435        const BFMT_VideoInfo *pVideoFormatInfo ;
2436        uint8_t RxDeviceAttached ;
2437
2438        BDBG_ENTER(BHDM_EDID_VideoFmtSupported) ;
2439
2440        /* default to format not supported */
2441        *Supported = 0 ;
2442
2443        BHDM_CHECK_RC(rc, BHDM_RxDeviceAttached(hHDMI, &RxDeviceAttached));
2444        if (!RxDeviceAttached)
2445                goto done ;
2446
2447#if BDBG_DEBUG_BUILD
2448        if (hHDMI->DeviceSettings.BypassEDIDChecking)
2449        {
2450                *Supported = 1 ;
2451                BDBG_WRN(("EDID is ByPassed; all formats will attempt to display")) ;
2452                goto done ;
2453        }
2454#endif
2455
2456        if (hHDMI->edidStatus == BHDM_EDID_STATE_eInvalid) {
2457                rc = BHDM_EDID_NOT_FOUND;
2458                goto error;
2459        }
2460
2461        pVideoFormatInfo = BFMT_GetVideoFormatInfoPtr(eVideoFmt) ;
2462
2463        if (hHDMI->AttachedEDID.BcmVideoFormatsChecked == 0)
2464        {
2465                rc = BHDM_EDID_VIDEO_FORMATS_UNAVAILABLE ;
2466                goto error ;
2467        }
2468
2469        if (hHDMI->AttachedEDID.BcmSupportedVideoFormats[eVideoFmt])
2470        {
2471                *Supported = 1 ;
2472                goto done;
2473        }
2474        else
2475        {
2476                /* Warn the format is not supported */
2477                BDBG_WRN(("%-30s %4d x %4d %c NOT SUPPORTED by attached <%.13s> receiver",
2478                        pVideoFormatInfo->pchFormatStr,
2479                        pVideoFormatInfo->ulDigitalWidth, pVideoFormatInfo->ulDigitalHeight,
2480                        Mode[pVideoFormatInfo->bInterlaced],
2481                        hHDMI->AttachedEDID.MonitorName)) ;
2482                goto done;
2483        }
2484
2485error:
2486        if (eVideoFmt == BFMT_VideoFmt_eDVI_640x480p) {
2487
2488                BDBG_MSG(("Can't find/read EDID. Assume HDMI receiver supports VGA (640x480p)"));
2489                *Supported = 1;
2490                rc = BERR_SUCCESS;
2491        }
2492
2493done:
2494        BDBG_LEAVE(BHDM_EDID_VideoFmtSupported) ;
2495        return  rc ;
2496} /* BHDM_EDID_VideoFmtSupported */
2497
2498
2499BERR_Code BHDM_EDID_P_GetVerticalFrequency(
2500        uint32_t ulVertFreqMask, uint16_t *uiVerticalFrequency)
2501{
2502        BERR_Code rc = BERR_SUCCESS ;
2503        uint8_t i ;
2504
2505static const struct {
2506        uint32_t ulVertFreqMask ;
2507        uint32_t uiVerticalFrequency ;
2508        } VerticalFrequencies[] =
2509        {
2510                {BFMT_VERT_50Hz,        50},
2511                {BFMT_VERT_59_94Hz,   59},
2512                {BFMT_VERT_60Hz,        60},
2513
2514                {BFMT_VERT_59_94Hz | BFMT_VERT_60Hz,        60},
2515                {BFMT_VERT_50Hz | BFMT_VERT_59_94Hz | BFMT_VERT_60Hz,        60},
2516
2517                {BFMT_VERT_66Hz,        66},
2518                {BFMT_VERT_70Hz,        70},
2519                {BFMT_VERT_72Hz,        72},
2520                {BFMT_VERT_75Hz,        75},
2521                {BFMT_VERT_85Hz,        85},
2522                       
2523                {BFMT_VERT_23_976Hz, 23},
2524                {BFMT_VERT_24Hz,        24},
2525                {BFMT_VERT_23_976Hz  | BFMT_VERT_24Hz, 24},
2526
2527                {BFMT_VERT_25Hz,        25},
2528
2529                {BFMT_VERT_29_97Hz,   29},
2530                {BFMT_VERT_30Hz,        30},
2531                {BFMT_VERT_29_97Hz  | BFMT_VERT_30Hz, 30},                     
2532        };
2533
2534        for (i=0; i < sizeof(VerticalFrequencies) / sizeof(*VerticalFrequencies); i++)
2535        {
2536                if (ulVertFreqMask & VerticalFrequencies[i].ulVertFreqMask)
2537                {
2538                        *uiVerticalFrequency = VerticalFrequencies[i].uiVerticalFrequency ;
2539                        return rc ;
2540                }
2541        }
2542
2543        BDBG_WRN(("Unknown Vertical Frequency Mask %#08X; using 60", ulVertFreqMask)) ;
2544        *uiVerticalFrequency = 60 ;
2545
2546        return rc ;
2547}
2548
2549
2550/******************************************************************************
2551Summary:
2552Parse the Established Timings to check for CEA 861 B video formats
2553*******************************************************************************/
2554static BERR_Code BHDM_EDID_P_ParseEstablishedTimingFormats(
2555        BHDM_Handle hHDMI                  /* [in] HDMI handle  */
2556)
2557{
2558        BERR_Code rc = BERR_SUCCESS ;
2559        uint8_t EstablishedTimings ;
2560
2561#if BDBG_DEBUG_BUILD
2562        uint8_t i ;
2563         static char *EstablishedTimingsIText[8] =
2564        {
2565                 "800 x 600 @ 60Hz VESA",
2566                 "800 x 600 @ 56Hz VESA",
2567                 "640 x 480 @ 75Hz VESA",
2568                 "640 x 480 @ 72Hz VESA",
2569                 "640 x 480 @ 67Hz Apple, Mac II",
2570                 "640 x 480 @ 60Hz IBM, VGA",
2571                 "720 x 400 @ 88Hz IBM, XGA2",
2572                 "720 x 400 @ 70Hz IBM, VGA"
2573         } ;
2574
2575         static char *EstablishedTimingsIIText[8] =
2576        {
2577                 "1280 x 1024 @ 75Hz VESA",
2578                 "1024 x 768 @ 75Hz VESA",
2579                 "1024 x 768 @ 70Hz VESA",
2580                 "1024 x 768 @ 60Hz VESA",
2581                 "1024 x 768 @ 87Hz(I) IBM",
2582                 "832 x 624 @ 75Hz Apple, Mac II",
2583                 "800 x 600 @ 75Hz VESA",
2584                "800 x 600 @ 72Hz VESA"
2585         } ;
2586#endif
2587
2588        /* assumes current block is 0 */
2589
2590        /* ESTABLISHED #1 */
2591
2592
2593        EstablishedTimings = hHDMI->AttachedEDID.Block[BHDM_EDID_ESTABLISHED_TIMINGS1] ;
2594#if BDBG_DEBUG_BUILD
2595      if (!EstablishedTimings)
2596                goto CheckEstablishTiming2 ;
2597
2598        BDBG_MSG(("Monitor Established Timings  I (%#02x)", EstablishedTimings)) ;
2599        for (i = 0 ;< 8; i++)
2600        {
2601                if (EstablishedTimings & (1 << i))
2602                        BDBG_MSG(("%s", EstablishedTimingsIText[i])) ;
2603        }
2604#endif
2605
2606        if (EstablishedTimings & BHDM_EDID_ESTABLISHED_TIMINGS_1_640x480_60HZ)
2607        {
2608                BDBG_MSG(("Found BCM Supported 640x480p")) ;
2609                hHDMI->AttachedEDID.BcmSupportedVideoFormats[BFMT_VideoFmt_eDVI_640x480p] = true ;
2610        }
2611
2612        if (EstablishedTimings & BHDM_EDID_ESTABLISHED_TIMINGS_1_800x600_60HZ)
2613        {
2614                BDBG_MSG(("Found BCM Supported 800x600p")) ;
2615                hHDMI->AttachedEDID.BcmSupportedVideoFormats[BFMT_VideoFmt_eDVI_800x600p] = true ;
2616        }
2617
2618
2619#if BDBG_DEBUG_BUILD
2620CheckEstablishTiming2 :
2621#endif
2622        /* ESTABLISHED #2 */
2623        EstablishedTimings = hHDMI->AttachedEDID.Block[BHDM_EDID_ESTABLISHED_TIMINGS2] ;
2624      if (!EstablishedTimings)
2625                goto done ;
2626#if BDBG_DEBUG_BUILD
2627        BDBG_MSG(("Monitor Established Timings II (%#02x)", EstablishedTimings)) ;
2628        for (i = 0 ;< 8; i++)
2629        {
2630                if (EstablishedTimings & (1 << i))
2631                        BDBG_MSG(("%s", EstablishedTimingsIIText[i])) ;
2632        }
2633#endif
2634
2635        if (EstablishedTimings & BHDM_EDID_ESTABLISHED_TIMINGS_2_1024x768_60HZ)
2636        {
2637                BDBG_MSG(("Found BCM Supported 1024x768p")) ;
2638                hHDMI->AttachedEDID.BcmSupportedVideoFormats[BFMT_VideoFmt_eDVI_1024x768p] = true ;
2639        }
2640
2641done:
2642        /* indicate formats have been checked */
2643        hHDMI->AttachedEDID.BcmVideoFormatsChecked = 1 ;
2644        return rc ;
2645}
2646
2647
2648/******************************************************************************
2649Summary:
2650Return all CEA 861 B video formats supported by the attached monitor as
2651sepecified in the V3 Timing Ext Video Data Block.
2652*******************************************************************************/
2653BERR_Code BHDM_EDID_P_ParseVideoDB(
2654        BHDM_Handle hHDMI,              /* [in] HDMI handle  */
2655        uint8_t DataBlockIndex,         /* [in] start offset of Video Data Block */
2656        uint8_t DataBlockLength         /* [in] length (number) of Video ID codes */
2657)
2658{
2659        BERR_Code rc = BERR_SUCCESS ;
2660        const BFMT_VideoInfo *pVideoFormatInfo ;
2661        uint8_t
2662                j, k, l, /* indexes */
2663                NumVideoDescriptors,
2664                EdidVideoIDCode,
2665                NativeFormat,
2666                LastIdAdded,
2667                SupportedIdCount ;
2668       
2669        BFMT_VideoFmt eVideoFmt ;
2670        uint16_t temp ;
2671        uint16_t tempH;
2672        BHDM_EDID_P_VideoDescriptor     *pVideoDescriptor = NULL ;
2673
2674
2675        /* indicate formats have been checked */
2676        hHDMI->AttachedEDID.BcmVideoFormatsChecked = 1 ;
2677
2678        /* set the number of video descriptors to look at  */
2679        NumVideoDescriptors = DataBlockLength ;
2680
2681        LastIdAdded = 0 ;
2682        SupportedIdCount = 0 ;
2683       
2684#if BHDM_CONFIG_HDMI_3D_SUPPORT
2685        hHDMI->AttachedEDID.First16VideoDescriptorsMask = 0;
2686#endif
2687
2688        /* for each CEA Video ID Code Found */
2689        BDBG_MSG(("<%s> CEA-861 Supported Video Formats (%d):",
2690                hHDMI->AttachedEDID.MonitorName, NumVideoDescriptors)) ;
2691
2692        for (j = 0 ; j < NumVideoDescriptors ; j++ )
2693        {
2694                /* get the supported Video Code ID; check if a native format */
2695                EdidVideoIDCode = hHDMI->AttachedEDID.Block[DataBlockIndex + j + 1] ;
2696                NativeFormat = (EdidVideoIDCode & 0x80) ? 1 : 0 ;
2697                EdidVideoIDCode = EdidVideoIDCode  & 0x7F ;
2698
2699
2700                /* search BCM 861-B supported formats for format found in EDID */
2701                for (k = 0 ; k < BHDM_EDID_P_BCM_VIDEO_FORMATS_MAX ; k++)
2702                {
2703                        /* find the retrieved Video ID Code in our table */
2704                        if (EdidVideoIDCode != BHDM_EDID_P_Cea861bFormats[k].CeaVideoCode)
2705                                continue ;
2706
2707                        /* a BCM supported Video ID code has been found; add it to our list */
2708                        /* since this is a loop make sure it is added only once */
2709
2710#if BHDM_CONFIG_HDMI_3D_SUPPORT
2711                        BDBG_MSG(("Found BCM supported CEA-861 Video ID: %02d (%s)",
2712                                EdidVideoIDCode,
2713                                (char *) BAVC_HDMI_AviInfoFrame_VideoIdCodeToStr(EdidVideoIDCode))) ;
2714
2715                        /* Set the support mask for the first 16 video descriptors for later use on parsing 3D support */
2716                        if (j < 16)
2717                                hHDMI->AttachedEDID.First16VideoDescriptorsMask |= (uint16_t) (1 << j);
2718#endif
2719
2720                       
2721                        if (LastIdAdded != EdidVideoIDCode)
2722                        {
2723                                pVideoDescriptor = (BHDM_EDID_P_VideoDescriptor  *)
2724                                        BKNI_Malloc(sizeof(BHDM_EDID_P_VideoDescriptor )) ;
2725                                if (pVideoDescriptor == NULL)
2726                                {
2727                                        rc = BERR_TRACE(BERR_OUT_OF_DEVICE_MEMORY);
2728                                        return rc;
2729                                }
2730                                pVideoDescriptor->VideoIdCode  = EdidVideoIDCode ;
2731                                pVideoDescriptor->NativeFormat = NativeFormat ;
2732
2733                                BLST_Q_INSERT_TAIL(&hHDMI->AttachedEDID.VideoDescriptorList, pVideoDescriptor, link) ;
2734
2735                                /* add Video Id code to supported list for GetVideoInfo */
2736                                hHDMI->AttachedEDID.BcmSupportedVideoIdCodes[SupportedIdCount++] = EdidVideoIDCode ;
2737                               
2738#if BHDM_CONFIG_HDMI_3D_SUPPORT
2739                                hHDMI->AttachedEDID.NumBcmSupportedVideoDescriptors++;
2740#endif
2741                        }
2742
2743                        /* adjust pixel repeat formats if necessary */
2744                        if ((BHDM_EDID_P_Cea861bFormats[k].HorizontalPixels == 1440) ||
2745                                (BHDM_EDID_P_Cea861bFormats[k].HorizontalPixels == 2880))
2746                                tempH = 720 ;
2747                        else
2748                                tempH = BHDM_EDID_P_Cea861bFormats[k].HorizontalPixels ;
2749
2750                        /* set all matching BFMT_VideoFmts as supported */
2751                        for (l = 0; l < BFMT_VideoFmt_eMaxCount; l++)
2752                        {
2753                                /* no longer skip the already supported formats; since the corresponding
2754                                   BCM_VideoFmt has to also be added to the VideoIdCode structure */
2755
2756                                eVideoFmt = (BFMT_VideoFmt) l ;
2757                                pVideoFormatInfo = BFMT_GetVideoFormatInfoPtr(eVideoFmt) ;
2758                                if (!pVideoFormatInfo)
2759                                        continue;
2760
2761                                /* Skip 3D formats */
2762                                if (BFMT_IS_3D_MODE(eVideoFmt)) {
2763                                        continue;
2764                                }
2765
2766                                /* check if the specified parameters match the requested formats */
2767                                /* 1st, Check if Pixel Format matches */
2768
2769                                if ((pVideoFormatInfo->ulDigitalWidth != tempH)
2770                                ||      (pVideoFormatInfo->ulDigitalHeight != BHDM_EDID_P_Cea861bFormats[k].VerticalPixels))
2771                                {
2772#if 0
2773                                        BDBG_MSG(("BFMT%d %d x %d <> %d x %d", l,
2774                                                pVideoFormatInfo->ulDigitalWidth, pVideoFormatInfo->ulDigitalHeight,
2775                                                tempH, BHDM_EDID_P_Cea861bFormats[k].VerticalPixels)) ;
2776#endif
2777                                        continue ;
2778                                }
2779
2780                                /* 2nd, Check Scan Type (i/p) */
2781                                if (pVideoFormatInfo->bInterlaced !=
2782                                                (BAVC_ScanType_eInterlaced == BHDM_EDID_P_Cea861bFormats[k].eScanType))
2783                                        continue  ;
2784
2785                                /* use the BFMT frequency parameter to get the Vertical Frequency */
2786                                /* Ignore rc; default of 60Hz will be used for unknown Frequency */
2787                                BHDM_EDID_P_GetVerticalFrequency(
2788                                        pVideoFormatInfo->ulVertFreqMask, &temp) ;
2789
2790                                /* 3rd check the 861 vertical frequency matches the BCM format  */
2791                                if ((temp == 59) || (temp == 60))
2792                                {
2793                                        if ((BHDM_EDID_P_Cea861bFormats[k].eFrameRateCode != BAVC_FrameRateCode_e59_94)
2794                                        &&  (BHDM_EDID_P_Cea861bFormats[k].eFrameRateCode != BAVC_FrameRateCode_e60))
2795                                                continue ;
2796                                }
2797                                else if  ((temp == 50)
2798                                &&   (BHDM_EDID_P_Cea861bFormats[k].eFrameRateCode != BAVC_FrameRateCode_e50))
2799                                        continue ;
2800
2801                                else if (((temp == 23) || (temp == 24))
2802                                &&   (BHDM_EDID_P_Cea861bFormats[k].eFrameRateCode != BAVC_FrameRateCode_e23_976)
2803                                &&   (BHDM_EDID_P_Cea861bFormats[k].eFrameRateCode != BAVC_FrameRateCode_e24))
2804                                        continue;
2805
2806                                else if ((temp == 25)
2807                                &&   (BHDM_EDID_P_Cea861bFormats[k].eFrameRateCode != BAVC_FrameRateCode_e25))
2808                                        continue;
2809
2810                                else if (((temp == 29) || (temp == 30))
2811                                &&   (BHDM_EDID_P_Cea861bFormats[k].eFrameRateCode != BAVC_FrameRateCode_e30))
2812                                        continue;
2813
2814
2815                                /* format matches */
2816#if 0
2817                                BDBG_WRN(("        %s is supported", pVideoFormatInfo->pchFormatStr)) ;
2818#endif
2819                                hHDMI->AttachedEDID.BcmSupportedVideoFormats[l] = true ;
2820                                if ((LastIdAdded != EdidVideoIDCode) && (pVideoDescriptor))
2821                                {
2822                                        pVideoDescriptor->eVideoFmt    = eVideoFmt ;
2823                                        LastIdAdded = EdidVideoIDCode ;
2824                                }
2825                        } /* for each BCM BFMT_VideoFmt */
2826                } /* for each BCM Supported CEA-861-B Video ID Code */
2827        } /* for each CEA-861-B Video Descriptor */
2828
2829
2830        return rc ;
2831}
2832
2833
2834
2835/******************************************************************************
2836Summary:
2837Return all CEA 861 B video formats supported by the attached monitor as
2838sepecified in the V3 Timing Ext Video Data Block.
2839*******************************************************************************/
2840BERR_Code BHDM_EDID_P_ParseAudioDB(
2841        BHDM_Handle hHDMI,             /* [in] HDMI handle  */
2842        uint8_t DataBlockIndex,        /* [in] start offset of Video Data Block */
2843        uint8_t DataBlockLength        /* [in] length (number) of Video ID codes */
2844)
2845{
2846
2847        BERR_Code rc = BERR_SUCCESS ;
2848
2849#if BDBG_DEBUG_BUILD
2850        static char *CeaAudioTypeText[] =
2851        {
2852                "Reserved",     "PCM",
2853                "AC3",          "MPEG1",
2854                "MP3",          "MPEG2",
2855                "AAC",          "DTS",
2856                "ATRAC",                "One Bit Audio",
2857                "DDP",          "DTS-HD",
2858                "MAT (MLP)",    "DST",
2859                "WMA Pro",      "Reserved15"
2860        } ;
2861#endif
2862
2863
2864        uint8_t
2865                i, j, /* indexes */
2866                NumAudioDescriptors,
2867                BcmAudioFormat,
2868                SampleRateFound,
2869                EdidAudioFormat,
2870                EdidAudioMaxChannels,
2871                EdidAudioSampleRate,
2872                EdidAudioBits ;
2873
2874
2875        NumAudioDescriptors = DataBlockLength / 3 ;
2876
2877        /* for each CEA Audio Format Code Found */
2878        BDBG_MSG(("<%s> CEA-861 Supported audio format:",
2879                hHDMI->AttachedEDID.MonitorName)) ;
2880
2881        for (j = 0 ; j < NumAudioDescriptors ; j++)
2882        {
2883                EdidAudioFormat        = hHDMI->AttachedEDID.Block[DataBlockIndex+ j*3 + 1] ;
2884                EdidAudioSampleRate = hHDMI->AttachedEDID.Block[DataBlockIndex+ j*3 + 2] ;
2885                EdidAudioBits             = hHDMI->AttachedEDID.Block[DataBlockIndex+ j*3 + 3] ;
2886
2887                EdidAudioFormat = EdidAudioFormat & 0x7F ; /* clear reserved bit */
2888                EdidAudioMaxChannels = (EdidAudioFormat & 0x07) + 1 ; /* max channels */
2889                EdidAudioFormat = EdidAudioFormat >> 3 ;
2890
2891                /************************************************/
2892                /* 1st check if format is supported  */
2893                BcmAudioFormat = BAVC_AudioFormat_eMaxCount ;
2894                for (i = 0; i < sizeof(BHDM_EDID_P_BcmSupportedFormats) / sizeof(*BHDM_EDID_P_BcmSupportedFormats) ; i++)
2895                        if (EdidAudioFormat == BHDM_EDID_P_BcmSupportedFormats[i].EdidAudioFormat)
2896                        {
2897                                BcmAudioFormat = BHDM_EDID_P_BcmSupportedFormats[i].BcmAudioFormat;
2898                                break ;
2899                        }
2900
2901                if (BcmAudioFormat == BAVC_AudioFormat_eMaxCount)
2902                {
2903                        BDBG_WRN(("%s - **** NOT Implemented/Supported by BCM%d ; [%02X %02X %02X]",
2904                                CeaAudioTypeText[EdidAudioFormat],  BCHP_CHIP,
2905                                hHDMI->AttachedEDID.Block[DataBlockIndex+ j*3 + 1],
2906                                hHDMI->AttachedEDID.Block[DataBlockIndex+ j*3 + 2],
2907                                hHDMI->AttachedEDID.Block[DataBlockIndex+ j*3 + 3])) ;
2908
2909                        continue ;
2910                }
2911
2912                hHDMI->AttachedEDID.BcmAudioFormatsChecked = 1 ;
2913
2914                /**********************************************/
2915                /* 2nd, Check for supported Audio Sample Rate */
2916                EdidAudioSampleRate &= 0x7F ; /* clear reserved bit */
2917
2918                SampleRateFound = 0 ;
2919                for (i = 0; i < sizeof(EdidAudioSampleRateTable) / sizeof(*EdidAudioSampleRateTable); i++)
2920                        /* check that at least one sample rate is supported */
2921                        if (EdidAudioSampleRate & EdidAudioSampleRateTable[i].EdidAudioSampleRate)
2922                        {
2923                                SampleRateFound = 1 ;
2924                                break ;
2925                        }
2926
2927                if (!SampleRateFound)
2928                        continue ;
2929
2930                /********************************************************/
2931                /* 3rd, Determine the number of Audio Bits (quantization) the */
2932                /* monitor supports for the requested Audio Format etc  */
2933
2934                /* get the number of bits supported by this format */
2935                if (EdidAudioFormat != BHDM_EDID_P_AudioFormat_ePCM) /* compressed */
2936                {                                                                                          /*  formats   */
2937                        /* Max Bit Rate = EdidAudioBits * 8 */
2938                        EdidAudioBits = EdidAudioBits /** 8*/ ;
2939
2940                        /* display debug information */
2941                        BDBG_MSG(("Found BCM supported CEA-861 Audio: %s - %d Ch [%d max bit rate] ; [%02X %02X %02X]",
2942                                CeaAudioTypeText[EdidAudioFormat],
2943                                EdidAudioMaxChannels, EdidAudioBits *8,
2944                                hHDMI->AttachedEDID.Block[DataBlockIndex+ j*3 + 1],
2945                                hHDMI->AttachedEDID.Block[DataBlockIndex+ j*3 + 2],
2946                                hHDMI->AttachedEDID.Block[DataBlockIndex+ j*3 + 3])) ;
2947
2948#if BDBG_DEBUG_BUILD
2949                        /* show the supported sample rates */
2950                        for (i = 0; i < sizeof(EdidAudioSampleRateTable) / sizeof(*EdidAudioSampleRateTable); i++)
2951                                /* check that at least one sample rate is supported */
2952                                if (EdidAudioSampleRate & EdidAudioSampleRateTable[i].EdidAudioSampleRate)
2953                                {
2954                                        BDBG_MSG(("\tSample Rate %s", CeaAudioSampleRateTypeText[i])) ;
2955                                }
2956#endif
2957                } /* END if compressed formats */
2958                else                                                                     /* uncompressed */
2959                {                                                                                /*     PCM      */
2960                        uint8_t uiAudioSampleSize ;
2961
2962                        if (EdidAudioBits & 0x04)       uiAudioSampleSize = 24 ;
2963                        else if (EdidAudioBits & 0x02)  uiAudioSampleSize = 20 ;
2964                        else if (EdidAudioBits & 0x01)  uiAudioSampleSize = 16 ;
2965                        else
2966                        {
2967                                BDBG_WRN(("Unknown/Un-Supported Bit Rate")) ;
2968                                rc = BHDM_EDID_HDMI_UNKNOWN_BIT_RATE ;
2969                                continue ;
2970                        }
2971
2972                        /* display debug information */
2973                        BDBG_MSG(("Found BCM supported CEA-861 Audio: %s - %d Ch [up to %d bits] ; [%02X %02X %02X]",
2974                                CeaAudioTypeText[EdidAudioFormat],
2975                                EdidAudioMaxChannels, uiAudioSampleSize,
2976                                hHDMI->AttachedEDID.Block[DataBlockIndex+ j*3 + 1],
2977                                hHDMI->AttachedEDID.Block[DataBlockIndex+ j*3 + 2],
2978                                hHDMI->AttachedEDID.Block[DataBlockIndex+ j*3 + 3])) ;
2979
2980#if BDBG_DEBUG_BUILD
2981                        /* show the supported sample rates */
2982                        for (i = 0; i < sizeof(EdidAudioSampleRateTable) / sizeof(*EdidAudioSampleRateTable); i++)
2983                                /* check that at least one sample rate is supported */
2984                                if (EdidAudioSampleRate & EdidAudioSampleRateTable[i].EdidAudioSampleRate)
2985                                {
2986                                        BDBG_MSG(("\tSample Rate %s", CeaAudioSampleRateTypeText[i])) ;
2987                                }
2988#endif
2989                } /* END ELSE uncompressed formats */
2990
2991                /* update audio supported information */
2992
2993                hHDMI->AttachedEDID.BcmSupportedAudioFormats[BcmAudioFormat].Supported = 1 ;
2994
2995                /* update supported format only if descriptor contains a larger number of Audio Channels */
2996                if (EdidAudioMaxChannels > hHDMI->AttachedEDID.BcmSupportedAudioFormats[BcmAudioFormat].AudioChannels )
2997                {
2998                        hHDMI->AttachedEDID.BcmSupportedAudioFormats[BcmAudioFormat].AudioChannels
2999                                = EdidAudioMaxChannels ;
3000                }
3001
3002                hHDMI->AttachedEDID.BcmSupportedAudioFormats[BcmAudioFormat].ucCeaSampleRates
3003                        = EdidAudioSampleRate ;
3004
3005                hHDMI->AttachedEDID.BcmSupportedAudioFormats[BcmAudioFormat].ucCeaNBits_BitRate
3006                        = EdidAudioBits ;
3007        } /* for each CEA Audio Format Code Found in EDID */
3008
3009        return rc ;
3010}
3011
3012
3013/******************************************************************************
3014Summary:
3015Set all BCM_VideoFmts that match eVideoFmt as being supported.
3016*******************************************************************************/
3017void BHDM_EDID_P_SetSupportedMatchingFmts(
3018        BHDM_Handle hHDMI, BFMT_VideoFmt eVideoFmt)
3019{
3020        uint8_t i ;
3021
3022        uint16_t
3023                uiVerticalFrequency ,
3024                uiSupportedVerticalFrequency ;
3025
3026        BFMT_VideoInfo
3027                *pVideoFormatInfo,
3028                *pSupportedVideoFormatInfo ;
3029
3030        pSupportedVideoFormatInfo = (BFMT_VideoInfo *) BFMT_GetVideoFormatInfoPtr(eVideoFmt) ;
3031        if (!pSupportedVideoFormatInfo)
3032        {
3033                /* BFMT_VideoFmt_eCustom2 is used. BFMT does not have any
3034                                information on this format so it returns NULL.
3035                                HDMI does not support this custom format */
3036
3037                BDBG_WRN(("No support for custom user defined format"));
3038                return;
3039        }
3040
3041        BHDM_EDID_P_GetVerticalFrequency(pSupportedVideoFormatInfo->ulVertFreqMask,
3042                         &uiSupportedVerticalFrequency) ;
3043
3044        hHDMI->AttachedEDID.BcmSupportedVideoFormats[eVideoFmt] = true ;
3045
3046        for (i = 0 ; i < BFMT_VideoFmt_eMaxCount ; i++)
3047        {
3048                /* skip if already listed as supported */
3049                if (hHDMI->AttachedEDID.BcmSupportedVideoFormats[i])
3050                        continue ;
3051
3052                pVideoFormatInfo = (BFMT_VideoInfo *) BFMT_GetVideoFormatInfoPtr((BFMT_VideoFmt) i) ;
3053                if (!pVideoFormatInfo)
3054                        continue;
3055
3056                /* 1st, Check if Pixel Format matches */
3057                /* check the width/height, and interlace parameters */
3058                if ((pVideoFormatInfo->ulDigitalWidth != pSupportedVideoFormatInfo->ulDigitalWidth)
3059                ||  (pVideoFormatInfo->ulDigitalHeight != pSupportedVideoFormatInfo->ulDigitalHeight)
3060                ||  (pVideoFormatInfo->bInterlaced != pSupportedVideoFormatInfo->bInterlaced))
3061                        continue ;
3062
3063                /* 2nd make sure the Video Format's frequency is supported by the monitor */
3064                BHDM_EDID_P_GetVerticalFrequency(
3065                        pVideoFormatInfo->ulVertFreqMask, &uiVerticalFrequency) ;
3066
3067                /* if the frequency does not fall into the range the monitor supports */
3068                /* the format cannot be supported */
3069                if  ((uiVerticalFrequency < hHDMI->AttachedEDID.MonitorRange.MinVertical)
3070                ||   (uiVerticalFrequency > hHDMI->AttachedEDID.MonitorRange.MaxVertical))
3071                        continue ;
3072
3073                /* Finally, we don't want to falsely conclude that
3074                   25Hz, 30Hz, and 50Hz are supported if 24Hz is
3075                   supported (by virtue of the above range check).
3076                   This is only pertinent for 720p and 1080i,p. */
3077                if ((pVideoFormatInfo->ulDigitalWidth == BFMT_1080I_WIDTH) 
3078                || (pVideoFormatInfo->ulDigitalWidth == BFMT_1080P_WIDTH) 
3079                || (pVideoFormatInfo->ulDigitalWidth == BFMT_720P_WIDTH))
3080                {
3081                        if (uiVerticalFrequency != uiSupportedVerticalFrequency)
3082                                continue;
3083                }
3084
3085                /* set as supported */
3086                hHDMI->AttachedEDID.BcmSupportedVideoFormats[i] = true ;
3087        }
3088
3089}  /* BHDM_EDID_P_SetSupportedMatchingFmts */
3090
3091
3092/******************************************************************************
3093Summary:
3094Return all video formats supported by the attached monitor.
3095*******************************************************************************/
3096BERR_Code BHDM_EDID_GetSupportedVideoFormats(
3097        BHDM_Handle hHDMI,                   /* [in] HDMI handle  */
3098        bool *VideoFormats                   /* [out] supported true/false */
3099)
3100{
3101        BERR_Code rc = BERR_SUCCESS ;
3102
3103        BDBG_ENTER(BHDM_EDID_GetSupportedVideoFormats) ;
3104
3105        if (hHDMI->edidStatus == BHDM_EDID_STATE_eInvalid) {
3106                return BHDM_EDID_NOT_FOUND;
3107        }
3108
3109        if (hHDMI->AttachedEDID.BcmVideoFormatsChecked == 0)
3110                return BHDM_EDID_VIDEO_FORMATS_UNAVAILABLE ;
3111
3112        BKNI_Memcpy(VideoFormats, &hHDMI->AttachedEDID.BcmSupportedVideoFormats,
3113                sizeof(hHDMI->AttachedEDID.BcmSupportedVideoFormats)) ;
3114
3115        BDBG_LEAVE(BHDM_EDID_GetSupportedVideoFormats) ;
3116        return rc ;
3117
3118} /* BHDM_EDID_GetSupportedVideoFormats */
3119
3120
3121#if BHDM_CONFIG_HDMI_3D_SUPPORT
3122/******************************************************************************
3123Summary:
3124Return all video information (video formats, video ID code) supported by the attached monitor.
3125*******************************************************************************/
3126BERR_Code BHDM_EDID_GetSupportedVideoInfo(
3127        BHDM_Handle hHDMI,                                       /* [in] HDMI handle  */
3128        BHDM_EDID_VideoDescriptorInfo *stSupportedVideoInfo       /* [out] supported true/false */
3129)
3130{
3131        BERR_Code rc = BERR_SUCCESS ;
3132
3133        BDBG_ENTER(BHDM_EDID_GetSupportedVideoInfo) ;
3134
3135        if (hHDMI->edidStatus == BHDM_EDID_STATE_eInvalid) {
3136                rc = BHDM_EDID_NOT_FOUND;
3137                goto done;
3138        }
3139
3140        if (hHDMI->AttachedEDID.BcmVideoFormatsChecked == 0) {
3141                rc = BHDM_EDID_VIDEO_FORMATS_UNAVAILABLE ;
3142                goto done;
3143        }
3144
3145        /* zero out return structure */
3146        BKNI_Memset(stSupportedVideoInfo, 0, sizeof(BHDM_EDID_VideoDescriptorInfo));
3147
3148
3149        stSupportedVideoInfo->numDescriptors
3150                = hHDMI->AttachedEDID.NumBcmSupportedVideoDescriptors ;
3151
3152        BDBG_MSG(("Num Supported Descriptors: %d", 
3153                hHDMI->AttachedEDID.NumBcmSupportedVideoDescriptors)) ;
3154
3155        BKNI_Memcpy(
3156                stSupportedVideoInfo->VideoIDCode, hHDMI->AttachedEDID.BcmSupportedVideoIdCodes, 
3157                hHDMI->AttachedEDID.NumBcmSupportedVideoDescriptors) ;
3158
3159done:
3160
3161        BDBG_LEAVE(BHDM_EDID_GetSupportedVideoInfo) ;
3162        return rc ;
3163       
3164}
3165#endif
3166
3167
3168/******************************************************************************
3169Summary:
3170Return all audio formats supported by the attached monitor.
3171*******************************************************************************/
3172BERR_Code BHDM_EDID_GetSupportedAudioFormats(
3173        BHDM_Handle hHDMI,                          /* [in] HDMI handle  */
3174        BHDM_EDID_AudioDescriptor *BcmAudioFormats  /* [out] supported formats */
3175)
3176{
3177        BERR_Code rc = BERR_SUCCESS ;
3178
3179        BDBG_ENTER(BHDM_EDID_GetSupportedAudioFormats) ;
3180
3181        if (hHDMI->edidStatus == BHDM_EDID_STATE_eInvalid) {
3182                return BHDM_EDID_NOT_FOUND;
3183        }
3184
3185        BKNI_Memset(BcmAudioFormats, 0, sizeof(hHDMI->AttachedEDID.BcmSupportedAudioFormats)) ;
3186
3187        if (hHDMI->AttachedEDID.BcmAudioFormatsChecked == 0)
3188                return BHDM_EDID_AUDIO_FORMATS_UNAVAILABLE ;
3189
3190        BKNI_Memcpy(BcmAudioFormats, &hHDMI->AttachedEDID.BcmSupportedAudioFormats,
3191                sizeof(hHDMI->AttachedEDID.BcmSupportedAudioFormats)) ;
3192
3193        BDBG_LEAVE(BHDM_EDID_GetSupportedAudioFormats) ;
3194        return rc ;
3195
3196} /* BHDM_EDID_GetSupportedAudioFormats */
3197
3198void BHDM_EDID_P_ParseExtendedColorimetryDB(BHDM_Handle hHDMI, uint8_t DataBlockIndex)
3199{
3200        /* Check for xvYCC support      */
3201        hHDMI->AttachedEDID.ColorimetryData.bxvYCC601= (hHDMI->AttachedEDID.Block[DataBlockIndex+2] & 0x01);
3202        hHDMI->AttachedEDID.ColorimetryData.bxvYCC709= (hHDMI->AttachedEDID.Block[DataBlockIndex+2] & 0x02) >> 1;
3203
3204        /* Check for metadata support in colorimetry block      */
3205        hHDMI->AttachedEDID.ColorimetryData.bMetadataProfile0= (hHDMI->AttachedEDID.Block[DataBlockIndex+3] & 0x01);
3206        hHDMI->AttachedEDID.ColorimetryData.bMetadataProfile1 = (hHDMI->AttachedEDID.Block[DataBlockIndex+3] & 0x02) >> 1;
3207        hHDMI->AttachedEDID.ColorimetryData.bMetadataProfile2 = (hHDMI->AttachedEDID.Block[DataBlockIndex+3] & 0x04) >> 2;
3208
3209#if BDBG_DEBUG_BUILD
3210        BDBG_MSG(("Support for xvYCC601: %s,  xvYCC709: %s",
3211                g_status[hHDMI->AttachedEDID.ColorimetryData.bxvYCC601 ? 1 : 0],
3212                g_status[hHDMI->AttachedEDID.ColorimetryData.bxvYCC709 ? 1 : 0])) ;
3213
3214        BDBG_MSG(("Gamut Metadata profile support: MD0: %s, MD1: %s, MD2: %s",
3215                g_status[hHDMI->AttachedEDID.ColorimetryData.bMetadataProfile0 ? 1 : 0],
3216                g_status[hHDMI->AttachedEDID.ColorimetryData.bMetadataProfile1 ? 1 : 0],
3217                g_status[hHDMI->AttachedEDID.ColorimetryData.bMetadataProfile2 ? 1 : 0])) ;
3218#endif
3219}
3220
3221
3222void BHDM_EDID_P_ParseVendorSpecificDB(BHDM_Handle hHDMI, uint8_t DataBlockIndex, uint8_t DataBlockLength)
3223{
3224        static const uint8_t ucpIEEE_RegId[3] = {0x03, 0x0C, 0x00} ; /* LSB.. MSB */
3225        uint8_t offset ;
3226        uint8_t offsetByte;
3227
3228        BKNI_Memset(&hHDMI->AttachedEDID.RxVSDB, 0, sizeof(BHDM_EDID_RxVendorSpecificDB)) ;
3229
3230        /* get the 24 bit IEEE Registration Identifier */
3231        BKNI_Memcpy(&hHDMI->AttachedEDID.RxVSDB.ucpIEEE_RegId, &hHDMI->AttachedEDID.Block[DataBlockIndex+1], 3) ;
3232
3233#if BHDM_CONFIG_HDMI_3D_SUPPORT
3234        /* indicate 3D Formats checked even if we do not proces due to DVI device (no HDMI) or no 3D Support */
3235        hHDMI->AttachedEDID.Bcm3DFormatsChecked = true;
3236#endif
3237
3238        /* make sure it is the correct IEEE Registration ID */
3239        if (BKNI_Memcmp(hHDMI->AttachedEDID.RxVSDB.ucpIEEE_RegId, ucpIEEE_RegId, 3) != 0)
3240        {
3241                BDBG_ERR(("VSDB IEEE Reg ID <%02X%02X%02X> != HDMI Reg ID <%02X%02X%02X>",
3242                        hHDMI->AttachedEDID.RxVSDB.ucpIEEE_RegId[2], hHDMI->AttachedEDID.RxVSDB.ucpIEEE_RegId[1],
3243                        hHDMI->AttachedEDID.RxVSDB.ucpIEEE_RegId[0],
3244                        ucpIEEE_RegId[2], ucpIEEE_RegId[1], ucpIEEE_RegId[0])) ;
3245               
3246                BDBG_ERR(("Rx Device will be treated as a DVI device...")) ;
3247                hHDMI->AttachedEDID.RxHasHdmiSupport = 0 ;
3248                return ;
3249        }
3250        else
3251        {
3252                BDBG_MSG(("HDMI VSDB IEEE Registration ID %02X%02X%02X Found",
3253                        hHDMI->AttachedEDID.RxVSDB.ucpIEEE_RegId[2],
3254                        hHDMI->AttachedEDID.RxVSDB.ucpIEEE_RegId[1],
3255                        hHDMI->AttachedEDID.RxVSDB.ucpIEEE_RegId[0])) ;
3256                hHDMI->AttachedEDID.RxHasHdmiSupport = 1 ;
3257               
3258        }
3259
3260        /* get the components of My Source Physical Address */
3261        hHDMI->AttachedEDID.RxVSDB.PhysAddr_A = (hHDMI->AttachedEDID.Block[DataBlockIndex+4] & 0xF0) >> 4 ;
3262        hHDMI->AttachedEDID.RxVSDB.PhysAddr_B = (hHDMI->AttachedEDID.Block[DataBlockIndex+4] & 0x0F) ;
3263        hHDMI->AttachedEDID.RxVSDB.PhysAddr_C = (hHDMI->AttachedEDID.Block[DataBlockIndex+5] & 0xF0) >> 4 ;
3264        hHDMI->AttachedEDID.RxVSDB.PhysAddr_D = (hHDMI->AttachedEDID.Block[DataBlockIndex+5] & 0x0F) ;
3265        BDBG_MSG(("my_address (CEC physical) = (%d.%d.%d.%d)",
3266                hHDMI->AttachedEDID.RxVSDB.PhysAddr_A, hHDMI->AttachedEDID.RxVSDB.PhysAddr_B,
3267                hHDMI->AttachedEDID.RxVSDB.PhysAddr_C, hHDMI->AttachedEDID.RxVSDB.PhysAddr_D)) ;
3268
3269#if BHDM_CONFIG_CEC_LEGACY_SUPPORT && BHDM_CEC_SUPPORT
3270        BKNI_Memcpy(hHDMI->cecConfiguration.CecPhysicalAddr,
3271                &hHDMI->AttachedEDID.Block[DataBlockIndex+4], 2) ;
3272#endif
3273
3274        /* DataBlockLength is N (which is 1 less than actual length). */
3275        if (DataBlockLength >= 6)
3276        {
3277                /* for HDMI 1.1 Check if Rx supports ACP or ISRC packets */
3278                hHDMI->AttachedEDID.RxVSDB.SupportsAI = (hHDMI->AttachedEDID.Block[DataBlockIndex+6] & 0x80) >> 7 ;
3279                BDBG_MSG(("Supports AI = %d", hHDMI->AttachedEDID.RxVSDB.SupportsAI)) ;
3280
3281                /* retrieve support for Deep Color modes        */
3282                hHDMI->AttachedEDID.RxVSDB.DeepColor_48bit = (hHDMI->AttachedEDID.Block[DataBlockIndex+6] & 0x40) >> 6;
3283                hHDMI->AttachedEDID.RxVSDB.DeepColor_36bit = (hHDMI->AttachedEDID.Block[DataBlockIndex+6] & 0x20) >> 5;
3284                hHDMI->AttachedEDID.RxVSDB.DeepColor_30bit = (hHDMI->AttachedEDID.Block[DataBlockIndex+6] & 0x10) >> 4;
3285                hHDMI->AttachedEDID.RxVSDB.DeepColor_Y444 = (hHDMI->AttachedEDID.Block[DataBlockIndex+6] & 0x08) >> 3;
3286                hHDMI->AttachedEDID.RxVSDB.DVI_Dual = (hHDMI->AttachedEDID.Block[DataBlockIndex+6] & 0x01);
3287        }
3288        else
3289        {
3290                hHDMI->AttachedEDID.RxVSDB.SupportsAI = false;
3291                hHDMI->AttachedEDID.RxVSDB.DeepColor_48bit = false;
3292                hHDMI->AttachedEDID.RxVSDB.DeepColor_36bit = false;
3293                hHDMI->AttachedEDID.RxVSDB.DeepColor_30bit = false;
3294                hHDMI->AttachedEDID.RxVSDB.DeepColor_Y444 = false;
3295                hHDMI->AttachedEDID.RxVSDB.DVI_Dual = false;
3296        }
3297
3298        if (DataBlockLength >= 7)
3299        {
3300                /* get the maximum TMDS clock rate supported    */
3301                hHDMI->AttachedEDID.RxVSDB.Max_TMDS_Clock_Rate =
3302                        hHDMI->AttachedEDID.Block[DataBlockIndex+7] * 5;
3303        }
3304
3305        /* determine present/non present fields */
3306        if (DataBlockLength >= 8)
3307        {
3308                offsetByte = hHDMI->AttachedEDID.Block[DataBlockIndex+8] ;
3309
3310                /* get lipsync-related fields   */
3311                hHDMI->AttachedEDID.RxVSDB.Latency_Fields_Present =
3312                        offsetByte >> 7 ;
3313
3314                hHDMI->AttachedEDID.RxVSDB.Interlaced_Latency_Fields_Present =
3315                        (offsetByte & 0x40) >> 6 ;
3316
3317#if BHDM_CONFIG_HDMI_3D_SUPPORT
3318                /* HDMI Video Present */
3319                hHDMI->AttachedEDID.RxVSDB.HDMI_Video_Present=
3320                        (offsetByte & 0x20) >> 5 ;
3321
3322
3323                /* get Content Type related fields */
3324                hHDMI->AttachedEDID.RxVSDB.SupportedContentTypeGraphicsText =
3325                        offsetByte & 0x01 ;
3326
3327                hHDMI->AttachedEDID.RxVSDB.SupportedContentTypePhoto =
3328                        offsetByte & 0x02 ;
3329
3330                hHDMI->AttachedEDID.RxVSDB.SupportedContentTypeCinema =
3331                        offsetByte & 0x04 ;
3332
3333                hHDMI->AttachedEDID.RxVSDB.SupportedContentTypeGame =
3334                        offsetByte & 0x08 ;
3335#endif         
3336        }
3337
3338
3339        offset = 9 ;  /* earliest byte where optional data can be located */
3340        if (offset > DataBlockLength)  /* no more optional data */
3341                goto done ;
3342
3343        /* retrieve Video and Audio Latency if available        */
3344        if (hHDMI->AttachedEDID.RxVSDB.Latency_Fields_Present)
3345        {
3346                hHDMI->AttachedEDID.RxVSDB.Video_Latency =
3347                                hHDMI->AttachedEDID.Block[DataBlockIndex + offset] ;
3348                offset++  ;
3349
3350                hHDMI->AttachedEDID.RxVSDB.Audio_Latency =
3351                                hHDMI->AttachedEDID.Block[DataBlockIndex + offset] ;
3352                offset++ ;
3353        }
3354        else
3355        {
3356                /* force Interlaced Latency Fields Present to false when no Progressive Latency fields */
3357                /* cannot have Interlaced Latency Fields without Progressive Latency Fields */
3358                hHDMI->AttachedEDID.RxVSDB.Interlaced_Latency_Fields_Present = false ;
3359        }
3360
3361        /* retrieve Video and Audio Latency for interlaced formats if available */
3362        if (hHDMI->AttachedEDID.RxVSDB.Interlaced_Latency_Fields_Present)
3363        {
3364                hHDMI->AttachedEDID.RxVSDB.Interlaced_Video_Latency =
3365                                hHDMI->AttachedEDID.Block[DataBlockIndex + offset] ;
3366                offset++ ;
3367
3368                hHDMI->AttachedEDID.RxVSDB.Interlaced_Audio_Latency =
3369                                hHDMI->AttachedEDID.Block[DataBlockIndex + offset] ;
3370                offset++ ;
3371        }
3372
3373        /* AV and interlaced AV latencies have been retrieved */
3374        if (offset > DataBlockLength)
3375                goto done ;  /* no more optional data */
3376
3377
3378#if BHDM_CONFIG_HDMI_3D_SUPPORT
3379        /* Now check for HDMI VICs and 3D support info */
3380        BHDM_EDID_P_ParseVSDB3D(hHDMI, DataBlockIndex, &offset, DataBlockLength);
3381#endif
3382
3383
3384done:
3385#if BHDM_CONFIG_DEBUG_EDID_VSDB
3386        if ((DataBlockLength < 7)
3387        && (hHDMI->AttachedEDID.RxVSDB.DeepColor_48bit
3388        ||  hHDMI->AttachedEDID.RxVSDB.DeepColor_36bit
3389        ||  hHDMI->AttachedEDID.RxVSDB.DeepColor_30bit
3390        ||  hHDMI->AttachedEDID.RxVSDB.DeepColor_Y444
3391        ||  hHDMI->AttachedEDID.RxVSDB.DVI_Dual))
3392        {
3393                BDBG_WRN(("Found HDMI 1.3 Features")) ;
3394                BDBG_WRN(("Deep Color Support")) ;
3395                BDBG_WRN(("\t 48bit: %s, 36bit: %s, 30bit: %s,  Y444: %s",
3396                        g_status[hHDMI->AttachedEDID.RxVSDB.DeepColor_48bit ? 1 : 0],
3397                        g_status[hHDMI->AttachedEDID.RxVSDB.DeepColor_36bit ? 1 : 0],
3398                        g_status[hHDMI->AttachedEDID.RxVSDB.DeepColor_30bit ? 1 : 0],
3399                        g_status[hHDMI->AttachedEDID.RxVSDB.DeepColor_Y444 ? 1 : 0])) ;
3400
3401                BDBG_WRN(("DVI Dual Link Support: %s",
3402                        g_status[hHDMI->AttachedEDID.RxVSDB.DVI_Dual ? 1 : 0]));
3403                return ;
3404        }
3405
3406        BDBG_WRN(("Max TMDS Clock Rate: %d",
3407                        hHDMI->AttachedEDID.RxVSDB.Max_TMDS_Clock_Rate));
3408
3409        BDBG_WRN(("Video Latency Data Present:            %s",
3410                g_status[hHDMI->AttachedEDID.RxVSDB.Latency_Fields_Present ? 1 : 0])) ;
3411        if (hHDMI->AttachedEDID.RxVSDB.Latency_Fields_Present)
3412        {
3413                BDBG_WRN(("\tVideo: %d, Audio: %d",
3414                        hHDMI->AttachedEDID.RxVSDB.Video_Latency,
3415                        hHDMI->AttachedEDID.RxVSDB.Audio_Latency)) ;
3416        }
3417
3418        BDBG_WRN(("Interlaced Video Latency Data Present: %s",
3419                g_status[hHDMI->AttachedEDID.RxVSDB.Interlaced_Latency_Fields_Present ? 1 : 0])) ;
3420        if (hHDMI->AttachedEDID.RxVSDB.Interlaced_Latency_Fields_Present)
3421        {
3422                BDBG_WRN(("\tVideo: %d, Audio: %d",
3423                        hHDMI->AttachedEDID.RxVSDB.Interlaced_Video_Latency,
3424                        hHDMI->AttachedEDID.RxVSDB.Interlaced_Audio_Latency));
3425        }
3426
3427        BDBG_WRN(("HDMI Video Present: %s",
3428                g_status[hHDMI->AttachedEDID.RxVSDB.HDMI_Video_Present ? 1 : 0])) ;
3429
3430#if BHDM_CONFIG_HDMI_3D_SUPPORT
3431        if (hHDMI->AttachedEDID.RxVSDB.HDMI_Video_Present)
3432        {
3433                BDBG_WRN(("Found HDMI 1.4 Features")) ;
3434                BDBG_WRN(("Content Types Supported")) ;
3435                BDBG_WRN(("\tGraphics (Text): %s",
3436                        g_status[hHDMI->AttachedEDID.RxVSDB.SupportedContentTypeGraphicsText ? 1 : 0])) ;
3437                BDBG_WRN(("\tCinema: %s",
3438                        g_status[hHDMI->AttachedEDID.RxVSDB.SupportedContentTypeCinema ? 1 : 0])) ;
3439                BDBG_WRN(("\tPhoto: %s",
3440                        g_status[hHDMI->AttachedEDID.RxVSDB.SupportedContentTypePhoto ? 1 : 0])) ;
3441                BDBG_WRN(("\tGame: %s",
3442                        g_status[hHDMI->AttachedEDID.RxVSDB.SupportedContentTypeGame ? 1 : 0])) ;
3443
3444                BDBG_WRN(("HDMI 3D Present: %s",
3445                        g_status[hHDMI->AttachedEDID.RxVSDB.HDMI_3D_Present ? 1 : 0])) ;
3446
3447                BDBG_WRN(("HDMI Multi 3D Present (Optional): %#x",
3448                        hHDMI->AttachedEDID.RxVSDB.HDMI_3D_Multi_Present)) ;
3449
3450
3451                BDBG_WRN(("HDMI VIC LEN: %d",
3452                        hHDMI->AttachedEDID.RxVSDB.HDMI_VIC_Len)) ;
3453
3454                BDBG_WRN(("HDMI  3D LEN: %d",
3455                        hHDMI->AttachedEDID.RxVSDB.HDMI_3D_Len)) ;
3456
3457                BDBG_WRN(("Image Size: %d",
3458                        hHDMI->AttachedEDID.RxVSDB.HDMI_Image_Size)) ;
3459
3460
3461                if (hHDMI->AttachedEDID.RxVSDB.HDMI_3D_Present)
3462                {
3463                        uint8_t i;
3464                        BDBG_WRN(("Broadcom 3D Formats Supported:")) ;
3465                        for (i = 0 ; i < BFMT_VideoFmt_eMaxCount; i++)
3466                        {
3467                                const BFMT_VideoInfo *pVideoFormatInfo ;
3468                                pVideoFormatInfo = (BFMT_VideoInfo *) BFMT_GetVideoFormatInfoPtr((BFMT_VideoFmt) i) ;
3469
3470                                if (hHDMI->AttachedEDID.BcmSupported3DFormats[i] & BHDM_EDID_VSDB_3D_STRUCTURE_ALL_FRAME_PACKING) {
3471                                        BDBG_WRN(("\t%s Frame Packing ", pVideoFormatInfo->pchFormatStr)) ;
3472                                }
3473
3474                                if (hHDMI->AttachedEDID.BcmSupported3DFormats[i] & BHDM_EDID_VSDB_3D_STRUCTURE_ALL_FIELD_ALTERNATIVE) {
3475                                        BDBG_WRN(("\t%s FieldAlternative ",     pVideoFormatInfo->pchFormatStr)) ;
3476                                }
3477
3478                                if (hHDMI->AttachedEDID.BcmSupported3DFormats[i] & BHDM_EDID_VSDB_3D_STRUCTURE_ALL_LINE_ALTERNATIVE) {
3479                                        BDBG_WRN(("\t%s LineAlternative ", pVideoFormatInfo->pchFormatStr)) ;
3480                                }
3481
3482                                if (hHDMI->AttachedEDID.BcmSupported3DFormats[i] & BHDM_EDID_VSDB_3D_STRUCTURE_ALL_LDEPTH) {
3483                                        BDBG_WRN(("\t%s LDepth ", pVideoFormatInfo->pchFormatStr)) ;
3484                                }
3485
3486                                if (hHDMI->AttachedEDID.BcmSupported3DFormats[i] & BHDM_EDID_VSDB_3D_STRUCTURE_ALL_LDEPTH_GFX)  {
3487                                        BDBG_WRN(("\t%s LDepth+Graphics ", pVideoFormatInfo->pchFormatStr)) ;
3488                                }
3489
3490                                if (hHDMI->AttachedEDID.BcmSupported3DFormats[i] & BHDM_EDID_VSDB_3D_STRUCTURE_ALL_TOP_BOTTOM) {
3491                                        BDBG_WRN(("\t%s TopAndBottom ", pVideoFormatInfo->pchFormatStr)) ;
3492                                }
3493
3494                                if (hHDMI->AttachedEDID.BcmSupported3DFormats[i] & BHDM_EDID_VSDB_3D_STRUCTURE_ALL_SBS_FULL) {
3495                                        BDBG_WRN(("\t%s SideBySide_Full ", pVideoFormatInfo->pchFormatStr)) ;
3496                                }
3497
3498                                if (hHDMI->AttachedEDID.BcmSupported3DFormats[i] & BHDM_EDID_VSDB_3D_STRUCTURE_ALL_SBS_HALF_HORIZ) {
3499                                        BDBG_WRN(("\t%s SideBySide_Half_Horizontal ", pVideoFormatInfo->pchFormatStr)) ;
3500                                }
3501
3502                                if (hHDMI->AttachedEDID.BcmSupported3DFormats[i] & BHDM_EDID_VSDB_3D_STRUCTURE_ALL_SBS_HALF_QUINC) {
3503                                        BDBG_WRN(("\t%s SideBySide_Half_QuincunxMatrix ", pVideoFormatInfo->pchFormatStr)) ;
3504                                }
3505                        }
3506                }
3507        }
3508#endif 
3509#endif
3510
3511        return;
3512
3513}
3514
3515BERR_Code BHDM_EDID_P_ParseV1V2TimingExtension(BHDM_Handle hHDMI)
3516{
3517        BERR_Code rc = BERR_SUCCESS ;
3518        uint8_t
3519                i, offset,
3520                DataOffset ;
3521        BFMT_VideoFmt eVideoFmt ;
3522        BHDM_EDID_DetailTiming DetailTimingBlock ;
3523
3524#if BDBG_DEBUG_BUILD
3525        uint8_t TimingsFound = 0 ;
3526#endif
3527
3528
3529        /* check if data blocks exist before the detailed timing data */
3530        DataOffset = hHDMI->AttachedEDID.Block[BHDM_EDID_EXT_DATA_OFFSET] ;
3531        if (DataOffset == 0)  /* no detailed timing descriptors */
3532                return rc ;
3533
3534        i = 0 ;
3535        offset = DataOffset ;
3536
3537        BKNI_Memset((void *) &hHDMI->AttachedEDID.DescriptorHeader, 0x0, BHDM_EDID_DESC_HEADER_LEN) ;
3538
3539
3540        while (offset < BHDM_EDID_BLOCKSIZE)
3541        {
3542                if (BKNI_Memcmp(&hHDMI->AttachedEDID.Block[offset], hHDMI->AttachedEDID.DescriptorHeader,
3543                        BHDM_EDID_DESC_HEADER_LEN) == 0)
3544                {
3545                        break ;
3546                }
3547
3548                /* skip EDID descriptor blocks */
3549                if (BKNI_Memcmp(&hHDMI->AttachedEDID.Block[offset], (void *) &hHDMI->AttachedEDID.DescriptorHeader, 3) == 0)
3550                {
3551                        offset = DataOffset + BHDM_EDID_MONITOR_DESC_SIZE * i++ ;
3552                        continue ;
3553                }
3554
3555                BHDM_EDID_ParseDetailedTimingDescriptor(
3556                        &hHDMI->AttachedEDID.Block[offset], &DetailTimingBlock) ;
3557
3558                /* convert the DetailTiming to BFMT_eVideoFmt type */
3559                if (BHDM_EDID_P_DetailTiming2VideoFmt(hHDMI, &DetailTimingBlock, &eVideoFmt)
3560                == BERR_SUCCESS)
3561                {
3562                        /* set BFMTs that match this Detailed Timing Format as being supported */
3563                        BHDM_EDID_P_SetSupportedMatchingFmts(hHDMI, eVideoFmt) ;
3564
3565#if BDBG_DEBUG_BUILD
3566                        BDBG_MSG(("Preferred Timing #%d found in V1/2 Timing Ext block", ++TimingsFound)) ;
3567#endif
3568                }
3569
3570                offset = DataOffset + BHDM_EDID_MONITOR_DESC_SIZE * i++ ;
3571        }
3572        return rc ;
3573}
3574
3575
3576BERR_Code BHDM_EDID_P_ParseV3TimingExtension (BHDM_Handle hHDMI)
3577{
3578        BERR_Code rc = BERR_SUCCESS;
3579        uint8_t
3580                DataOffset,
3581                DataBlockIndex,
3582                DataBlockTag,
3583                DataBlockLength,
3584                MonitorSupport,
3585                ExtendedTagCode;
3586
3587        DataOffset = hHDMI->AttachedEDID.Block[BHDM_EDID_EXT_DATA_OFFSET] ;
3588
3589        /* check if data blocks exist before the detailed timing data */
3590        if ((DataOffset != 0) &&
3591                (DataOffset != 4)) /* yes, data blocks exist. */
3592        {
3593                /* Look for Video Data Block and parse it first
3594                Set the index to the start of Data Blocks */
3595                DataBlockIndex = BHDM_EDID_EXT_DATA_BLOCK_COLLECTION ;
3596               
3597                while (DataBlockIndex < DataOffset)
3598                {
3599                        /* get the Data Block type */
3600                        DataBlockTag =
3601                                          hHDMI->AttachedEDID.Block[DataBlockIndex] >> 5 ;
3602               
3603                        /* get the Data Block length */
3604                        DataBlockLength =
3605                                          hHDMI->AttachedEDID.Block[DataBlockIndex] & 0x1F ;
3606
3607                        if (DataBlockTag == BHDM_EDID_CeaDataBlockTag_eVideoDB)
3608                        {                       
3609                                BDBG_MSG(("\n[%#02X] CEA-861 %s (%#02x) found; %d bytes",
3610                                                  hHDMI->AttachedEDID.Block[DataBlockIndex],
3611                                                  CeaTagName[DataBlockTag], DataBlockTag, DataBlockLength)) ;
3612
3613                                /* adds to supported BCM video formats */
3614                                BHDM_EDID_P_ParseVideoDB(hHDMI, DataBlockIndex, DataBlockLength) ;
3615                                break ;
3616                        }       
3617                        DataBlockIndex += DataBlockLength + 1;
3618                } /* while DataBlockIndex < DataOffset */
3619
3620
3621                /* scan through the data blocks once again and retrieve all other the necessary information.
3622                Set the index to the start of Data Blocks */
3623                DataBlockIndex = BHDM_EDID_EXT_DATA_BLOCK_COLLECTION ;
3624               
3625                while (DataBlockIndex < DataOffset)
3626                {
3627                        /* get the Data Block type */
3628                        DataBlockTag =
3629                                          hHDMI->AttachedEDID.Block[DataBlockIndex] >> 5 ;
3630
3631                        /* get the Data Block length */
3632                        DataBlockLength =
3633                                          hHDMI->AttachedEDID.Block[DataBlockIndex] & 0x1F ;
3634
3635                        BDBG_MSG(("\n[%#02X] CEA-861 %s (%#02x) found; %d bytes",
3636                                          hHDMI->AttachedEDID.Block[DataBlockIndex],
3637                                          CeaTagName[DataBlockTag], DataBlockTag, DataBlockLength)) ;
3638
3639                        switch (DataBlockTag)
3640                        {
3641                        case BHDM_EDID_CeaDataBlockTag_eAudioDB :       /* Audio DB */
3642                                /* adds to supported BCM audio formats */
3643                                BHDM_EDID_P_ParseAudioDB(hHDMI, DataBlockIndex, DataBlockLength) ;
3644                                break ;
3645
3646                        case BHDM_EDID_CeaDataBlockTag_eVideoDB :       /* Video DB */
3647                                /* Video Data Block already parse at this point */
3648                                break ;
3649
3650                        case BHDM_EDID_CeaDataBlockTag_eVSDB :          /* Vendor Specific DB */
3651                                /* populates RxVSDB */
3652                                BHDM_EDID_P_ParseVendorSpecificDB(hHDMI, DataBlockIndex, DataBlockLength) ;
3653                                break ;
3654
3655                        case BHDM_EDID_CeaDataBlockTag_eSpeakerDB : /* Speaker Allocation DB */
3656                                break ;
3657
3658                        case BHDM_EDID_CeaDataBlockTag_eExtendedDB:
3659                                ExtendedTagCode = hHDMI->AttachedEDID.Block[DataBlockIndex+1];
3660                                if (ExtendedTagCode == 5)
3661                                        BHDM_EDID_P_ParseExtendedColorimetryDB(hHDMI, DataBlockIndex) ;
3662                                else
3663                                {
3664                                        BDBG_MSG((" Extended Tag Code <%d> is not supported",
3665                                                        ExtendedTagCode)) ;
3666                                }
3667                                break;
3668
3669                        case BHDM_EDID_CeaDataBlockTag_eReserved0 :
3670                        case BHDM_EDID_CeaDataBlockTag_eReserved5 :
3671                        case BHDM_EDID_CeaDataBlockTag_eReserved6 :
3672
3673
3674                        default : /* note any Unknown/Unsupported Tags */
3675                                BDBG_WRN(("CEA Data Block Tag Code %d is not supported",
3676                                           DataBlockTag)) ;
3677                                break ;
3678                        }
3679
3680                        DataBlockIndex += DataBlockLength + 1;
3681
3682                } /* while DataBlockIndex < DataOffset */
3683        }
3684
3685
3686        /* check what the monitor supports */
3687        MonitorSupport = hHDMI->AttachedEDID.Block[BHDM_EDID_EXT_MONITOR_SUPPORT] ;
3688       
3689        hHDMI->AttachedEDID.RxVSDB.Underscan = MonitorSupport & 0x80 ;
3690        hHDMI->AttachedEDID.RxVSDB.Audio         = MonitorSupport & 0x40 ;
3691        hHDMI->AttachedEDID.RxVSDB.YCbCr444  = MonitorSupport & 0x20 ;
3692        hHDMI->AttachedEDID.RxVSDB.YCbCr422  = MonitorSupport & 0x10 ;
3693        hHDMI->AttachedEDID.RxVSDB.NativeFormatsInDescriptors = MonitorSupport & 0xF ;
3694
3695        /* check if there are any detailed timing descriptors. */
3696        if (DataOffset > 0)
3697        {
3698                uint16_t offset = DataOffset ;
3699                BHDM_EDID_DetailTiming DetailTimingBlock ;
3700                BFMT_VideoFmt eVideoFmt ;
3701
3702                BKNI_Memset((void *) &hHDMI->AttachedEDID.DescriptorHeader, 0x0, BHDM_EDID_DESC_HEADER_LEN);
3703
3704                while ((offset > 0) && (offset < BHDM_EDID_BLOCKSIZE)
3705                        && BKNI_Memcmp( /* detailed timing descriptors contain non-zeros */
3706                                &hHDMI->AttachedEDID.Block[offset],
3707                                &hHDMI->AttachedEDID.DescriptorHeader, 3))
3708                {
3709                        BHDM_EDID_ParseDetailedTimingDescriptor(
3710                                &hHDMI->AttachedEDID.Block[offset], &DetailTimingBlock) ;
3711
3712                        /* convert the DetailTiming to BFMT_eVideoFmt type */
3713                        rc = BHDM_EDID_P_DetailTiming2VideoFmt(hHDMI, &DetailTimingBlock, &eVideoFmt) ;
3714                        if (rc == BERR_SUCCESS)
3715                        {
3716                                /* set BFMTs that match this Detailed Timing Format as being supported */
3717                                BHDM_EDID_P_SetSupportedMatchingFmts(hHDMI, eVideoFmt) ;
3718                        }
3719
3720                        /* skip to next descriptor */
3721                        offset = offset + BHDM_EDID_MONITOR_DESC_SIZE ;
3722                }
3723        }
3724
3725        /* RxVSDB has been  parsed at this point load additional values found in the V3 timing extension */
3726        /* all HDMI Rx that set VSDB.Audio must support Basic Audio (i.e 2 Channel PCM)
3727                 although not all devices explicitly specify it in Audio Descriptors */
3728        if (!hHDMI->AttachedEDID.RxVSDB.Audio)
3729        {
3730                BDBG_WRN(("Attached HDMI device '%s' does not support audio",
3731                        hHDMI->AttachedEDID.MonitorName)) ;
3732        }
3733        else if (!hHDMI->AttachedEDID.BcmSupportedAudioFormats[BAVC_AudioFormat_ePCM].Supported)
3734        {
3735                BDBG_WRN(("VSDB indicates audio support, but no PCM Audio Descriptors found!")) ;
3736                BDBG_WRN(("Assuming 2 channel PCM is supported")) ;
3737
3738                /* all HDMI Rxs are required to support PCM Audio; list 48KHz PCM as supported */
3739                hHDMI->AttachedEDID.BcmSupportedAudioFormats[BAVC_AudioFormat_ePCM].Supported = 1 ;
3740                hHDMI->AttachedEDID.BcmSupportedAudioFormats[BAVC_AudioFormat_ePCM].AudioChannels = 2 ;
3741                hHDMI->AttachedEDID.BcmSupportedAudioFormats[BAVC_AudioFormat_ePCM].ucCeaSampleRates
3742                        = BAVC_AudioSamplingRate_e48k ;
3743                hHDMI->AttachedEDID.BcmSupportedAudioFormats[BAVC_AudioFormat_ePCM].ucCeaNBits_BitRate
3744                        = 1 ;   /* 16 bits */
3745                hHDMI->AttachedEDID.BcmAudioFormatsChecked = 1 ;
3746        }
3747
3748        return rc;
3749
3750}
3751
3752
3753BERR_Code BHDM_EDID_P_ProcessTimingExtension (BHDM_Handle hHDMI)
3754{
3755        BERR_Code rc = BERR_SUCCESS;
3756
3757        /* check for Version 1/2/3 Timing Data Extensions */
3758        switch (hHDMI->AttachedEDID.Block[BHDM_EDID_EXT_VERSION])
3759        {
3760        case BHDM_EDID_TIMING_VERSION_1 :
3761        case BHDM_EDID_TIMING_VERSION_2 :
3762                BDBG_MSG(("Parse Version 1/2 Timing Extension ")) ;
3763                BHDM_EDID_P_ParseV1V2TimingExtension(hHDMI) ;
3764                break  ;
3765
3766        case BHDM_EDID_TIMING_VERSION_3 :
3767                BDBG_MSG(("V3 Timing Extension Found in EDID Extension.")) ;
3768                BHDM_EDID_P_ParseV3TimingExtension(hHDMI) ;
3769                break ;
3770
3771        case BHDM_EDID_TIMING_VERSION_4 :
3772                BDBG_WRN(("Parsing Timing Extension Version 4 as Version 3")) ;
3773                BHDM_EDID_P_ParseV3TimingExtension(hHDMI) ;
3774                break ;
3775
3776        default :
3777                BDBG_WRN(("Uknown/Unsupported Timing Extension Version %d",
3778                        hHDMI->AttachedEDID.Block[BHDM_EDID_EXT_VERSION])) ;
3779        }
3780
3781        return rc;
3782}
3783
3784BERR_Code BHDM_EDID_P_ProcessExtensionBlock (BHDM_Handle hHDMI)
3785{
3786        BERR_Code rc = BERR_SUCCESS;
3787
3788        /* check for Extension type */
3789        switch (hHDMI->AttachedEDID.Block[BHDM_EDID_EXT_TAG])
3790        {
3791        case BHDM_EDID_EXT_TIMING_DATA :
3792                BDBG_MSG(("Timing Extension Block Found in EDID Extension Blocks")) ;
3793                BHDM_EDID_P_ProcessTimingExtension(hHDMI) ;
3794                break;
3795
3796        case BHDM_EDID_EXT_LCD_TIMINGS :
3797        case BHDM_EDID_EXT_EDID_2_0 :
3798        case BHDM_EDID_EXT_COLOR_INFO :
3799        case BHDM_EDID_EXT_DVI_FEATURE :
3800        case BHDM_EDID_EXT_TOUCH_SCREEN :
3801        case BHDM_EDID_EXT_MANUFACTURER :
3802        default :
3803                BDBG_WRN(("Uknown/Unsupported Extension  %d",
3804                        hHDMI->AttachedEDID.Block[BHDM_EDID_EXT_TAG])) ;
3805        }
3806
3807        return rc;
3808}
3809
3810BERR_Code BHDM_EDID_P_ProcessBlockMap (BHDM_Handle hHDMI)
3811{
3812        BERR_Code rc = BERR_SUCCESS;
3813        uint8_t block_map[BHDM_EDID_BLOCKSIZE];
3814        uint8_t i, index;
3815
3816        index = hHDMI->AttachedEDID.CachedBlock;
3817
3818        /* Copy the block map from the hHDMI handle */
3819        for(i=0; i< BHDM_EDID_BLOCKSIZE; i++){
3820                block_map[i]=hHDMI->AttachedEDID.Block[i];
3821        }
3822
3823        i = 1;
3824        while((i < (BHDM_EDID_BLOCKSIZE-1)) && (block_map[i])){
3825                BHDM_CHECK_RC(rc, BHDM_EDID_GetNthBlock(hHDMI, (i + index), hHDMI->AttachedEDID.Block, BHDM_EDID_BLOCKSIZE)) ;
3826                BHDM_EDID_P_ProcessExtensionBlock (hHDMI);
3827                i++;
3828        }
3829
3830        if(hHDMI->AttachedEDID.BasicData.Extensions < BHDM_EDID_BLOCKSIZE) {
3831                if(hHDMI->AttachedEDID.BasicData.Extensions != i) {
3832                        hHDMI->AttachedEDID.BasicData.Extensions = i;
3833                }
3834        }
3835        else {
3836                if(hHDMI->AttachedEDID.BasicData.Extensions != (i+index)) {
3837                        hHDMI->AttachedEDID.BasicData.Extensions = i;
3838                }
3839        }
3840
3841done:
3842        return rc;
3843}
3844
3845/******************************************************************************
3846Summary:
3847Notify the EDID Block to re-read the EDID; initializing the values read from the EDID
3848*******************************************************************************/
3849BERR_Code BHDM_EDID_Initialize(
3850        BHDM_Handle hHDMI                    /* [in] HDMI handle  */
3851)
3852{
3853        BERR_Code rc ;
3854        uint8_t
3855                offset,
3856                Tag ;
3857        uint8_t SupportedTimingsFound = 0 ;
3858        BFMT_VideoFmt eVideoFmt ;
3859
3860        uint8_t i; /* indexes */
3861
3862        uint8_t RxDeviceAttached ;
3863        static const uint8_t ucEdidHeader[BHDM_EDID_HEADER_SIZE] =
3864                { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00} ;
3865
3866        BHDM_EDID_DetailTiming DetailTiming ;
3867        BHDM_EDID_P_VideoDescriptor *pVideoDescriptor ;
3868
3869
3870        /* make sure HDMI Cable is connected to something... */
3871        BHDM_CHECK_RC(rc, BHDM_RxDeviceAttached(hHDMI, &RxDeviceAttached));
3872        if (!RxDeviceAttached)
3873        {
3874                return BHDM_NO_RX_DEVICE ;
3875        }
3876
3877        /* dont bother reading if EDID has been bypassed (DEBUG mode only) */
3878#if BDBG_DEBUG_BUILD
3879        if (hHDMI->DeviceSettings.BypassEDIDChecking)
3880        {
3881                BDBG_WRN(("EDID is ByPassed; all formats will attempt to display")) ;
3882
3883                for (i = 0 ; i < BFMT_VideoFmt_eMaxCount ; i++)
3884                        hHDMI->AttachedEDID.BcmSupportedVideoFormats[i] = true ; /* set as supported */
3885                hHDMI->AttachedEDID.BcmVideoFormatsChecked = 1 ;
3886
3887                goto done ;
3888        }
3889#endif
3890
3891        /* delete previous video descriptors if they exist */
3892        if (!BLST_Q_EMPTY(&hHDMI->AttachedEDID.VideoDescriptorList))
3893        {
3894                for (pVideoDescriptor=BLST_Q_FIRST(&hHDMI->AttachedEDID.VideoDescriptorList) ;
3895                        pVideoDescriptor ;
3896                        pVideoDescriptor=BLST_Q_FIRST(&hHDMI->AttachedEDID.VideoDescriptorList))
3897                {
3898                        BLST_Q_REMOVE_HEAD(&hHDMI->AttachedEDID.VideoDescriptorList, link);
3899                        BKNI_Free(pVideoDescriptor); /* free memory */
3900                }
3901        }
3902        /* clear all current EDID information */
3903        BKNI_Memset((void *) &hHDMI->AttachedEDID, 0, sizeof(BHDM_EDID_DATA)) ;
3904
3905        BDBG_MSG(("Initializing/Reading EDID Information")) ;
3906
3907        /* read the 1st EDID Block and parse the information of interest it contains */
3908
3909        /* during InitializeEDID, always force the reading of EDID block 0 */
3910        /* incorrectly implemented Hot Plug signals sometimes cause a problem */
3911        hHDMI->edidStatus = BHDM_EDID_STATE_eInitialize;
3912        BHDM_CHECK_RC(rc, BHDM_EDID_GetNthBlock(hHDMI, 0, hHDMI->AttachedEDID.Block, BHDM_EDID_BLOCKSIZE)) ;
3913
3914        /**************************************
3915         Parse Basic EDID Data
3916        **************************************/
3917
3918        if (BKNI_Memcmp(&ucEdidHeader[0], &hHDMI->AttachedEDID.Block[0],
3919                BHDM_EDID_HEADER_SIZE))
3920        {
3921                BDBG_WRN(("Invalid/Missing EDID Header %02X %02X %02X %02X %02X %02X %02X %02X... ignoring",
3922                        hHDMI->AttachedEDID.Block[0], hHDMI->AttachedEDID.Block[1],
3923                        hHDMI->AttachedEDID.Block[2], hHDMI->AttachedEDID.Block[3],
3924                        hHDMI->AttachedEDID.Block[4], hHDMI->AttachedEDID.Block[5],
3925                        hHDMI->AttachedEDID.Block[6], hHDMI->AttachedEDID.Block[7])) ;
3926        }
3927
3928        BKNI_Memcpy(&hHDMI->AttachedEDID.BasicData.VendorID,
3929                &hHDMI->AttachedEDID.Block[BHDM_EDID_VENDOR_ID], 2) ;
3930
3931        BKNI_Memcpy(&hHDMI->AttachedEDID.BasicData.ProductID,
3932                &hHDMI->AttachedEDID.Block[BHDM_EDID_PRODUCT_ID], 2) ;
3933
3934        BKNI_Memcpy(&hHDMI->AttachedEDID.BasicData.SerialNum,
3935                &hHDMI->AttachedEDID.Block[BHDM_EDID_SERIAL_NO], 4) ;
3936
3937         hHDMI->AttachedEDID.BasicData.ManufWeek=
3938                hHDMI->AttachedEDID.Block[BHDM_EDID_MANUFACTURE_WEEK] ;
3939         hHDMI->AttachedEDID.BasicData.ManufYear =
3940                hHDMI->AttachedEDID.Block[BHDM_EDID_MANUFACTURE_YEAR] ;
3941         hHDMI->AttachedEDID.BasicData.features =
3942                hHDMI->AttachedEDID.Block[BHDM_EDID_FEATURE_SUPPORT] ;
3943
3944
3945        hHDMI->AttachedEDID.BasicData.EdidVersion = hHDMI->AttachedEDID.Block[BHDM_EDID_VERSION] ;
3946        hHDMI->AttachedEDID.BasicData.EdidRevision = hHDMI->AttachedEDID.Block[BHDM_EDID_REVISION] ;
3947        hHDMI->AttachedEDID.BasicData.Extensions = hHDMI->AttachedEDID.Block[BHDM_EDID_EXTENSION] ;
3948
3949        if ((hHDMI->AttachedEDID.BasicData.EdidVersion == 0xFF)
3950        ||  (hHDMI->AttachedEDID.BasicData.EdidRevision == 0xFF)
3951        ||  (hHDMI->AttachedEDID.BasicData.Extensions == 0xFF)
3952        || ( (hHDMI->AttachedEDID.BasicData.EdidVersion == 0x00) &&
3953                (hHDMI->AttachedEDID.BasicData.EdidRevision == 0x00) &&
3954                (hHDMI->AttachedEDID.BasicData.Extensions == 0x00) ))
3955        {
3956                /* probably read all 0xFF or 0x00; invalid EDID */
3957                BDBG_ERR(("EDID returns all 0xFF or 0x00 values. Invalid EDID information"));
3958                hHDMI->edidStatus = BHDM_EDID_STATE_eInvalid;
3959                return BHDM_EDID_NOT_FOUND;
3960        }
3961
3962        BDBG_MSG(("Version %d.%d  Number of Extensions: %d",
3963                hHDMI->AttachedEDID.BasicData.EdidVersion,
3964                hHDMI->AttachedEDID.BasicData.EdidRevision, hHDMI->AttachedEDID.BasicData.Extensions)) ;
3965
3966        hHDMI->AttachedEDID.BasicData.MaxHorizSize = hHDMI->AttachedEDID.Block[BHDM_EDID_MAX_HORIZ_SIZE] ;
3967        hHDMI->AttachedEDID.BasicData.MaxVertSize  = hHDMI->AttachedEDID.Block[BHDM_EDID_MAX_VERT_SIZE] ;
3968        BDBG_MSG(("H x V Size (cm): %d x %d",
3969                hHDMI->AttachedEDID.BasicData.MaxHorizSize,
3970                hHDMI->AttachedEDID.BasicData.MaxVertSize)) ;
3971
3972        /*
3973        ** Additional Information for Display Purposes only
3974        ** Add to EDID Data structure if desired...
3975        */
3976        BDBG_MSG(("Manufacture Week / Year: %d / %d",
3977                hHDMI->AttachedEDID.Block[BHDM_EDID_MANUFACTURE_WEEK],
3978                hHDMI->AttachedEDID.Block[BHDM_EDID_MANUFACTURE_YEAR] + 1990)) ;
3979
3980        /* Serial Number may also be placed in a Descriptor Tag */
3981        BDBG_MSG(("Serial Number: %02X %02X %02X %02X",
3982                hHDMI->AttachedEDID.Block[BHDM_EDID_SERIAL_NO], hHDMI->AttachedEDID.Block[BHDM_EDID_SERIAL_NO+1],
3983                hHDMI->AttachedEDID.Block[BHDM_EDID_SERIAL_NO+2], hHDMI->AttachedEDID.Block[BHDM_EDID_SERIAL_NO+3])) ;
3984
3985        {
3986         #if BDBG_DEBUG_BUILD
3987                 static const char *DisplayType[] =
3988                 {
3989                        "Monochrome Display",
3990                        "RGB Display",
3991                        "Non-RGB Display",
3992                        "Undefined"
3993                 } ;
3994                 #endif
3995                 BDBG_MSG(("Feature Support: <%#x>", hHDMI->AttachedEDID.BasicData.features)) ;
3996                 BDBG_MSG(("\tStandby Supported: %s",
3997                        g_status[(hHDMI->AttachedEDID.BasicData.features & 0x80) ? 1 : 0])) ;
3998                 BDBG_MSG(("\tSuspend Supported: %s",
3999                         g_status[(hHDMI->AttachedEDID.BasicData.features & 0x40) ? 1 : 0])) ;
4000                 BDBG_MSG(("\tActive Off Supported: %s",
4001                         g_status[(hHDMI->AttachedEDID.BasicData.features & 0x20) ? 1 : 0])) ;
4002                 BDBG_MSG(("\tDisplay Type: %s",
4003                        DisplayType[ (hHDMI->AttachedEDID.BasicData.features & 0x18) >> 3])) ;
4004                 BDBG_MSG(("\tsRGB Colorspace Supported: %s",
4005                         g_status[(hHDMI->AttachedEDID.BasicData.features & 0x04) ? 1 : 0])) ;
4006                 BDBG_MSG(("\tPreferred Timing in Block 1 (must always be set): %s",
4007                         g_status[(hHDMI->AttachedEDID.BasicData.features & 0x02) ? 1 : 0])) ;
4008                 BDBG_MSG(("\tDefault GTF Supported: %s",
4009                         g_status[(hHDMI->AttachedEDID.BasicData.features & 0x01) ? 1 : 0])) ;
4010        }
4011
4012        /*************************************************************************
4013         Parse the 4 Detailed Timing Blocks contained in this EDID Block.
4014         Should contain:
4015                 1 Monitor Name,
4016                 1 Monitor Range,
4017                 and 1 to 2 Detailed Timing Descriptors
4018         EDID Version 1.3 and up
4019        **************************************************************************/
4020
4021        BKNI_Memset((void *) &hHDMI->AttachedEDID.DescriptorHeader, 0x0, BHDM_EDID_DESC_HEADER_LEN);
4022
4023        /* Check the four Descriptor Blocks in the initial 128 EDID  bytes */
4024        /* search for non-timing desriptors first.  Especially the Monitor Range */
4025        for (i = 0 ; i < 4 ; i++)
4026        {
4027                offset = BHDM_EDID_MONITOR_DESC_1 + BHDM_EDID_MONITOR_DESC_SIZE * i ;
4028
4029                /* Non-timing descriptors start with 0x00, 0x00, 0x00, <tag>, 0x00 */
4030                if (BKNI_Memcmp(&hHDMI->AttachedEDID.Block[offset],
4031                        (void *) &hHDMI->AttachedEDID.DescriptorHeader, 3) == 0)
4032                {
4033                        Tag = hHDMI->AttachedEDID.Block[offset+3] ;
4034
4035                        /* Check which descriptor tag we found */
4036                        switch (Tag)
4037                        {
4038                        case BHDM_EDID_TAG_MONITOR_RANGE :      /* Range Limits found */
4039                                BDBG_MSG(("Monitor Range found in Descriptor %d", i + 1)) ;
4040                                BHDM_EDID_P_GetMonitorRange(hHDMI, offset) ;
4041                                break ;
4042
4043                        case BHDM_EDID_TAG_MONITOR_NAME : /* Monitor Name found */
4044                                BKNI_Memcpy(
4045                                        hHDMI->AttachedEDID.MonitorName, &hHDMI->AttachedEDID.Block[offset + BHDM_EDID_DESC_DATA],
4046                                        BHDM_EDID_MONITOR_DESC_SIZE - BHDM_EDID_DESC_HEADER_LEN) ;
4047
4048#if BDBG_DEBUG_BUILD
4049                                /* replace linefeed with NULL; use offset variable as index */
4050                                for (offset = 0 ; offset < BHDM_EDID_DESC_ASCII_STRING_LEN; offset++)
4051                                {
4052                                        if (hHDMI->AttachedEDID.MonitorName[offset] == '\n')
4053                                        {
4054                                                hHDMI->AttachedEDID.MonitorName[offset] = '\0' ;
4055                                                break ;
4056                                        }
4057                                }
4058#endif
4059
4060                                BDBG_MSG(("Monitor Name  found in Descriptor %d", i + 1)) ;
4061                                BDBG_MSG(("   %s ", hHDMI->AttachedEDID.MonitorName)) ;
4062                                break ;
4063
4064                        case BHDM_EDID_TAG_MONITOR_SN :
4065                                BDBG_MSG(("Monitor S/N   found in Descriptor %d", i + 1)) ;
4066                                break ;
4067
4068                        case BHDM_EDID_TAG_MONITOR_ASCII :
4069                                /* no support using this in EDID structure */
4070                                break ;
4071
4072                        case BHDM_EDID_TAG_DUMMY_DESC:
4073                                /* descriptor space is unsed. */
4074                                break;
4075
4076                        default :
4077                                /* unknown; continue processing anyway */
4078                                BDBG_WRN(("Unknown Tag <%X> found in Descriptor %d; continue...",
4079                                        Tag, i+1)) ;
4080                        }
4081                }
4082        }
4083
4084
4085        /* now process the timing descriptors */
4086        BDBG_MSG(("Detailed Timing (Preferred) Formats:")) ;
4087        BDBG_MSG(("Format             HBlnk HOfst HWidth  VBlnk VOfst HWidth  PxlClk  ScrSz")) ;
4088
4089        for (i = 0 ; i < 4 ; i++)
4090        {
4091                offset = BHDM_EDID_MONITOR_DESC_1 + BHDM_EDID_MONITOR_DESC_SIZE * i ;
4092
4093                if (BKNI_Memcmp(&hHDMI->AttachedEDID.Block[offset],
4094                        (void *) &hHDMI->AttachedEDID.DescriptorHeader, 3) != 0)
4095                {
4096
4097                        /* at least one Detail Timing Format has been found; */
4098                        /* indicate formats have been checked */
4099                        hHDMI->AttachedEDID.BcmVideoFormatsChecked = 1 ;
4100
4101                        BHDM_EDID_ParseDetailedTimingDescriptor(
4102                                &hHDMI->AttachedEDID.Block[offset], &DetailTiming) ;
4103
4104                        BDBG_MSG(("%4d x %d (%4d%c)  %3d   %3d   %3d      %2d   %2d    %2d      %dMHz   %dx%d",
4105                                DetailTiming.HorizActivePixels, DetailTiming.VerticalActiveLines,
4106                                DetailTiming.Mode ?
4107                                        DetailTiming.VerticalActiveLines * 2 : DetailTiming.VerticalActiveLines, Mode[DetailTiming.Mode],
4108                                DetailTiming.HorizBlankingPixels, DetailTiming.HSyncOffset, DetailTiming.HSyncWidth,
4109                                DetailTiming.VerticalBlankingLines, DetailTiming.VSyncOffset, DetailTiming.VSyncWidth,
4110                                DetailTiming.PixelClock, DetailTiming.HSize_mm, DetailTiming.VSize_mm)) ;
4111
4112                        /* convert the DetailTiming to BFMT_eVideoFmt type; */
4113                        if (BHDM_EDID_P_DetailTiming2VideoFmt(hHDMI, &DetailTiming, &eVideoFmt)
4114                        != BERR_SUCCESS)
4115                        {
4116                                BDBG_WRN(("Unknown/Unsupported Detailed Timing Format %4d x %d (%4d%c)\n",
4117                                        DetailTiming.HorizActivePixels, DetailTiming.VerticalActiveLines,
4118                                        DetailTiming.Mode ?
4119                                                DetailTiming.VerticalActiveLines * 2 : DetailTiming.VerticalActiveLines,
4120                                        Mode[DetailTiming.Mode])) ;
4121                                continue /* if not a valid format */ ;
4122                        }
4123                        BDBG_WRN(("\n")) ;
4124
4125                        /* keep a copy of first two supported detailed timings for quick retrieval */
4126                        if (SupportedTimingsFound < 2)
4127                        {
4128                                BKNI_Memcpy(
4129                                        &(hHDMI->AttachedEDID.SupportedDetailTimings[SupportedTimingsFound]),
4130                                        &DetailTiming, sizeof(BHDM_EDID_DetailTiming)) ;
4131                        }
4132
4133                        /* set BFMTs that match this Detailed Timing Format as being supported */
4134                        BHDM_EDID_P_SetSupportedMatchingFmts(hHDMI, eVideoFmt) ;
4135
4136                        SupportedTimingsFound++ ;
4137
4138                }
4139        }
4140
4141        BHDM_EDID_P_ParseEstablishedTimingFormats(hHDMI) ;
4142
4143        hHDMI->AttachedEDID.SupportedDetailTimingsIn1stBlock = SupportedTimingsFound ;
4144
4145        /******************************************************************
4146         Parse Extension Blocks - primarily interested in Timing Extensions
4147        ******************************************************************/
4148
4149        if (!hHDMI->AttachedEDID.BasicData.Extensions)
4150        {
4151                hHDMI->AttachedEDID.RxHasHdmiSupport = 0 ;
4152                /* Its not mandatory to have extension blocks. so, i dont think this is an Error. It should just spit out a message and continue. */
4153                BDBG_ERR(("No EDID Extensions Found... No HDMI Support")) ;
4154                goto done ;
4155        }
4156
4157        /* Read the 1st EDID Block and parse to see if its a block map or an extension block(extensions count should be 1). */
4158        BHDM_CHECK_RC(rc, BHDM_EDID_GetNthBlock(hHDMI, 1, hHDMI->AttachedEDID.Block, BHDM_EDID_BLOCKSIZE)) ;
4159
4160        if(hHDMI->AttachedEDID.BasicData.Extensions == 1) {
4161                rc = BHDM_EDID_P_ProcessExtensionBlock(hHDMI);
4162        }
4163        else if(hHDMI->AttachedEDID.Block[0] == BHDM_EDID_EXT_BLOCK_MAP){
4164                rc = BHDM_EDID_P_ProcessBlockMap(hHDMI);
4165
4166                /* If the number of extension blocks are more than 127, the standard needs  one more block map to accomodate their extension tags. */
4167                if(hHDMI->AttachedEDID.BasicData.Extensions >= BHDM_EDID_BLOCKSIZE){
4168                        /* Read the 128th EDID Block which should be a block map. */
4169                        BHDM_CHECK_RC(rc, BHDM_EDID_GetNthBlock(hHDMI, 128, hHDMI->AttachedEDID.Block, BHDM_EDID_BLOCKSIZE));
4170
4171                        if(hHDMI->AttachedEDID.Block[0] == BHDM_EDID_EXT_BLOCK_MAP){
4172                                rc = BHDM_EDID_P_ProcessBlockMap(hHDMI);
4173                        }
4174                        else {
4175                                BDBG_ERR(("Wrong EDID extension tag of %d found in Block 128(Block Map); should be 0xF0",hHDMI->AttachedEDID.Block[0])) ;
4176                        }
4177                }
4178        }
4179        else {
4180                BDBG_ERR(("Wrong coding of the EDID Extension count in Block 0...")) ;
4181                goto done ;
4182        }
4183
4184#if BDBG_DEBUG_BUILD
4185                /* print raw EDID info */
4186                BHDM_EDID_DumpRawEDID(hHDMI);
4187#endif
4188
4189done:
4190        hHDMI->edidStatus = BHDM_EDID_STATE_eOK;
4191
4192        return rc ;
4193} /* BHDM_EDID_Initialize */
4194
4195
4196/******************************************************************************
4197BERR_Code BHDM_EDID_GetMonitorName
4198Summary: Retrieve a copy of the Monitor Name stored in the EDID
4199*******************************************************************************/
4200BERR_Code BHDM_EDID_GetMonitorName(
4201   BHDM_Handle hHDMI, /* [in] HDMI handle */
4202   uint8_t *pDescriptorText /* [out] pointer to memory to hold retrieved name */
4203)
4204{
4205        BERR_Code rc = BERR_SUCCESS ;
4206        uint8_t RxDeviceAttached ;
4207
4208        BDBG_ENTER(BHDM_EDID_GetMonitorName) ;
4209
4210        BHDM_CHECK_RC(rc, BHDM_RxDeviceAttached(hHDMI, &RxDeviceAttached));
4211        if (!RxDeviceAttached)
4212        {
4213                return BHDM_NO_RX_DEVICE ;
4214        }
4215
4216        if (hHDMI->edidStatus == BHDM_EDID_STATE_eInvalid) {
4217                return BHDM_EDID_NOT_FOUND;
4218        }
4219
4220#if BDBG_DEBUG_BUILD
4221        if (hHDMI->DeviceSettings.BypassEDIDChecking)
4222        {
4223                BKNI_Memcpy(pDescriptorText, EDIDByPassedText,
4224                        BHDM_EDID_MONITOR_DESC_SIZE - BHDM_EDID_DESC_HEADER_LEN) ;
4225                goto done ;
4226        }
4227#endif
4228
4229        BKNI_Memcpy(pDescriptorText, hHDMI->AttachedEDID.MonitorName, BHDM_EDID_DESC_ASCII_STRING_LEN) ;
4230
4231done:
4232#if BDBG_DEBUG_BUILD
4233        BDBG_MSG(("Monitor Name: <%.*s>",
4234                BHDM_EDID_DESC_ASCII_STRING_LEN, pDescriptorText)) ;
4235#endif
4236
4237        BDBG_LEAVE(BHDM_EDID_GetMonitorName) ;
4238        return rc ;
4239} /* end BHDM_EDID_GetMonitorName */
4240
4241
4242BERR_Code BHDM_EDID_GetSupportedColorimetry(
4243        BHDM_Handle hHDMI, BHDM_OutputFormat eOutputFormat,
4244        BFMT_VideoFmt eVideoFmt, BAVC_MatrixCoefficients *eColorimetry)
4245{
4246        BERR_Code       rc = BERR_SUCCESS ;
4247
4248        *eColorimetry = BAVC_MatrixCoefficients_eDvi_Full_Range_RGB;
4249        if (hHDMI->edidStatus == BHDM_EDID_STATE_eInvalid) {
4250                /* Default to Full range RGB */
4251                rc = BHDM_EDID_NOT_FOUND;
4252                goto done ;
4253        }
4254
4255        if (!hHDMI->AttachedEDID.RxHasHdmiSupport)
4256        {
4257                goto done ;
4258        }
4259
4260        /* default to Limited Range RGB */
4261        *eColorimetry = BAVC_MatrixCoefficients_eHdmi_RGB ;
4262
4263        /* use YPrPb for HDMI monitors */
4264        if ((eOutputFormat == BHDM_OutputFormat_eHDMIMode)
4265        && (hHDMI->AttachedEDID.RxVSDB.YCbCr444))  /* if supported by attached monitor */
4266        {
4267                switch (eVideoFmt)
4268                {
4269                case BFMT_VideoFmt_eDVI_640x480p  :  /* except for VGA mode */
4270                        BDBG_MSG(("Use Full Range RGB")) ;
4271                        *eColorimetry = BAVC_MatrixCoefficients_eDvi_Full_Range_RGB ;
4272                        break ;
4273
4274                case BFMT_VideoFmt_eNTSC :
4275                case BFMT_VideoFmt_eNTSC_J :
4276                case BFMT_VideoFmt_e480p :
4277                case BFMT_VideoFmt_ePAL_B :
4278                case BFMT_VideoFmt_ePAL_B1 :
4279                case BFMT_VideoFmt_ePAL_D :
4280                case BFMT_VideoFmt_ePAL_D1 :
4281                case BFMT_VideoFmt_ePAL_G :
4282                case BFMT_VideoFmt_ePAL_H :
4283                case BFMT_VideoFmt_ePAL_K :
4284                case BFMT_VideoFmt_ePAL_I :
4285                case BFMT_VideoFmt_ePAL_M :
4286                case BFMT_VideoFmt_ePAL_N :
4287                case BFMT_VideoFmt_ePAL_NC :
4288                case BFMT_VideoFmt_ePAL_60 :
4289                case BFMT_VideoFmt_eSECAM_L :
4290                case BFMT_VideoFmt_eSECAM_B :
4291                case BFMT_VideoFmt_eSECAM_G :
4292                case BFMT_VideoFmt_eSECAM_D :
4293                case BFMT_VideoFmt_eSECAM_K :
4294                case BFMT_VideoFmt_eSECAM_H :
4295                case BFMT_VideoFmt_e576p_50Hz :
4296                        BDBG_MSG(("Use YCrCb SD")) ;
4297                        *eColorimetry = BAVC_MatrixCoefficients_eSmpte_170M ;   /* SD Colorspace */
4298                        break ;
4299
4300                default : /* all others */
4301                        BDBG_MSG(("Use YCrCb HD")) ;
4302                        *eColorimetry = BAVC_MatrixCoefficients_eItu_R_BT_709 ; /* HD Colorspace */
4303                }
4304        }
4305#if BDBG_DEBUG_BUILD
4306        else
4307                BDBG_MSG(("DVI Monitors/Mode support RGB Only")) ;
4308#endif
4309
4310
4311        /* use full range rgb for DVI and HDMI 640x480 */
4312        if (*eColorimetry == BAVC_MatrixCoefficients_eHdmi_RGB)
4313        {
4314                switch (eVideoFmt)
4315                {
4316                default :
4317                        BDBG_MSG(("Use Limited Range RGB")) ;
4318                        /* keep limited range RGB */
4319                        break ;
4320
4321                case BFMT_VideoFmt_eDVI_640x480p  :
4322                case BFMT_VideoFmt_eDVI_800x600p  :
4323                case BFMT_VideoFmt_eDVI_1024x768p :
4324                case BFMT_VideoFmt_eDVI_1280x768p :
4325                case BFMT_VideoFmt_eDVI_1280x720p_50Hz :
4326                case BFMT_VideoFmt_eDVI_1280x720p :
4327                case BFMT_VideoFmt_eDVI_1280x720p_ReducedBlank :
4328                        BDBG_MSG(("Use Full Range RGB")) ;
4329                        *eColorimetry = BAVC_MatrixCoefficients_eDvi_Full_Range_RGB ;
4330                        break ;
4331                }
4332        }
4333
4334done:
4335        return rc  ;
4336}
4337
4338
4339/******************************************************************************
4340BERR_Code BHDM_EDID_GetExtendedColorimetry
4341Summary: Retrieve xvYCC colorimetry info stored in the EDID
4342*******************************************************************************/
4343BERR_Code BHDM_EDID_GetExtendedColorimetry(
4344        BHDM_Handle hHDMI,
4345        BHDM_EDID_ExtendedColorimetry *pExtendedColorimetry)
4346{
4347        BERR_Code rc = BERR_SUCCESS ;
4348
4349        if (hHDMI->edidStatus == BHDM_EDID_STATE_eInvalid)
4350        {
4351                return BHDM_EDID_NOT_FOUND;
4352        }
4353
4354        pExtendedColorimetry->bxvYCC601 = hHDMI->AttachedEDID.ColorimetryData.bxvYCC601 ? true : false ;
4355        pExtendedColorimetry->bxvYCC709 = hHDMI->AttachedEDID.ColorimetryData.bxvYCC709 ? true : false ;
4356
4357        return rc  ;
4358}
4359
4360/******************************************************************************
4361BERR_Code BHDM_EDID_GetSupportedColorDepth
4362Summary: Retrieve a copy of the Monitor Name stored in the EDID
4363*******************************************************************************/
4364BERR_Code BHDM_EDID_GetSupportedColorDepth(
4365        BHDM_Handle hHDMI,
4366        BHDM_EDID_ColorDepth *stSuppotedColorDepth,     /* [out] */
4367        bool *bYCbCrPixelEncoding       /* [out] */
4368)
4369{
4370        BERR_Code rc = BERR_SUCCESS;
4371
4372        if (hHDMI->edidStatus == BHDM_EDID_STATE_eInvalid)
4373        {
4374                return BHDM_EDID_NOT_FOUND;
4375        }
4376
4377        stSuppotedColorDepth->bColorDepth24bit = true; /* standard color depth, always supported */
4378        stSuppotedColorDepth->bColorDepth30bit =
4379                hHDMI->AttachedEDID.RxVSDB.DeepColor_30bit ? true : false;
4380        stSuppotedColorDepth->bColorDepth36bit =
4381                hHDMI->AttachedEDID.RxVSDB.DeepColor_36bit ? true : false;
4382        stSuppotedColorDepth->bColorDepth48bit =
4383                hHDMI->AttachedEDID.RxVSDB.DeepColor_48bit ? true : false;
4384
4385        *bYCbCrPixelEncoding = hHDMI->AttachedEDID.RxVSDB.DeepColor_Y444 ? true : false;
4386
4387        return rc;
4388}
4389
4390
4391
4392/******************************************************************************
4393BERR_Code BHDM_EDID_GetMyCecPhysicalAddr
4394Summary: Retrieve CEC Physical info stored in the EDID
4395*******************************************************************************/
4396BERR_Code BHDM_EDID_GetMyCecPhysicalAddr(
4397        BHDM_Handle hHDMI,
4398        uint8_t *pMyPhysicalAddr)
4399{
4400        BERR_Code rc = BERR_SUCCESS ;
4401
4402        if (hHDMI->edidStatus != BHDM_EDID_STATE_eOK)
4403        {
4404                return BHDM_EDID_NOT_FOUND;
4405        }
4406
4407        pMyPhysicalAddr[0] = hHDMI->AttachedEDID.RxVSDB.PhysAddr_A;
4408        pMyPhysicalAddr[0] <<= 4;
4409        pMyPhysicalAddr[0] |= hHDMI->AttachedEDID.RxVSDB.PhysAddr_B;
4410
4411        pMyPhysicalAddr[1] = hHDMI->AttachedEDID.RxVSDB.PhysAddr_C;
4412        pMyPhysicalAddr[1] <<= 4;
4413        pMyPhysicalAddr[1] |= hHDMI->AttachedEDID.RxVSDB.PhysAddr_D;
4414
4415        return rc  ;
4416}
4417
4418
Note: See TracBrowser for help on using the repository browser.