| 1 | /*************************************************************************** |
|---|
| 2 | * Copyright (c) 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: $ |
|---|
| 11 | * $brcm_Revision: $ |
|---|
| 12 | * $brcm_Date: $ |
|---|
| 13 | * |
|---|
| 14 | * Module Description: |
|---|
| 15 | * |
|---|
| 16 | * Revision History: |
|---|
| 17 | * |
|---|
| 18 | * $brcm_Log: $ |
|---|
| 19 | * |
|---|
| 20 | ***************************************************************************/ |
|---|
| 21 | #include "bsettop_display.h" |
|---|
| 22 | #include "gist.h" |
|---|
| 23 | |
|---|
| 24 | #include "nexus_platform.h" |
|---|
| 25 | #include "nexus_display.h" |
|---|
| 26 | #include "nexus_display_vbi.h" |
|---|
| 27 | #include "nexus_video_window.h" |
|---|
| 28 | #include "nexus_video_adj.h" |
|---|
| 29 | #include "nexus_hdmi_output_hdcp.h" |
|---|
| 30 | #include "nexus_hdmi_output_cec.h" |
|---|
| 31 | |
|---|
| 32 | #include "bsettop_display.h" |
|---|
| 33 | #include "bsettop_hdmi.h" |
|---|
| 34 | #include "bsettop_display_n_priv.h" |
|---|
| 35 | |
|---|
| 36 | #include "bkni_event_group.h" |
|---|
| 37 | #include "bos_task_priorities.h" |
|---|
| 38 | |
|---|
| 39 | struct bdisplay |
|---|
| 40 | { |
|---|
| 41 | bool open; |
|---|
| 42 | NEXUS_DisplayHandle handle[eBDISPLAY_ID_MAX]; |
|---|
| 43 | NEXUS_VideoWindowHandle window[eBDISPLAY_ID_MAX]; |
|---|
| 44 | NEXUS_VideoFormat format; |
|---|
| 45 | |
|---|
| 46 | bdisplay_settings settings; |
|---|
| 47 | bsettop_hdcp_authentication_cb_t hdcp_authentication_cb; /* hdcp check callback */ |
|---|
| 48 | }; |
|---|
| 49 | |
|---|
| 50 | |
|---|
| 51 | #define HDMI_TASK_STACK_SIZE 1024 |
|---|
| 52 | struct bsettop_hdmi |
|---|
| 53 | { |
|---|
| 54 | NEXUS_HdmiOutputHandle handle; |
|---|
| 55 | NEXUS_DisplayHandle display; |
|---|
| 56 | |
|---|
| 57 | bool connected; |
|---|
| 58 | bool hdcpStarted; |
|---|
| 59 | bool native; |
|---|
| 60 | |
|---|
| 61 | BKNI_EventHandle hotplugEvent; |
|---|
| 62 | BKNI_EventHandle hdcpEvent; |
|---|
| 63 | BKNI_EventHandle cecEvent; |
|---|
| 64 | BKNI_EventGroupHandle hdmiEvent; |
|---|
| 65 | |
|---|
| 66 | b_task_t task_h; |
|---|
| 67 | unsigned int task_stack[HDMI_TASK_STACK_SIZE]; |
|---|
| 68 | bsettop_hdcp_authentication_cb_t hdcp_authentication_cb; |
|---|
| 69 | |
|---|
| 70 | bool transmitEncrypted; |
|---|
| 71 | bool pjCheckEnabled; |
|---|
| 72 | bool checkHDCP; |
|---|
| 73 | }; |
|---|
| 74 | |
|---|
| 75 | static struct bdisplay s_display = { |
|---|
| 76 | false, /*open*/ |
|---|
| 77 | {NULL, NULL}, /*display handle*/ |
|---|
| 78 | {NULL, NULL}, /*window handle*/ |
|---|
| 79 | NEXUS_VideoFormat_e720p, /*format*/ |
|---|
| 80 | { |
|---|
| 81 | bdisplay_format_auto, |
|---|
| 82 | NULL, /* normaly used to notify HDMI of rate change */ |
|---|
| 83 | NULL, /* passed to rate_change_cb */ |
|---|
| 84 | NULL, /* RF output */ |
|---|
| 85 | NULL, /* SPDIF output */ |
|---|
| 86 | NULL, /* I2S output */ |
|---|
| 87 | bdisplay_sd_output_options_auto, |
|---|
| 88 | bdisplay_hd_output_options_auto, |
|---|
| 89 | 0, /* sharpness */ |
|---|
| 90 | false, /* force_change_format */ |
|---|
| 91 | false, /* deinterlace */ |
|---|
| 92 | false, /* shrink_width */ |
|---|
| 93 | 0 /* deinterlacer_affinity */ |
|---|
| 94 | }, |
|---|
| 95 | NULL |
|---|
| 96 | }; |
|---|
| 97 | |
|---|
| 98 | static struct bsettop_hdmi s_hdmi_output; |
|---|
| 99 | |
|---|
| 100 | bvideo_format nexus2dta_vformat(NEXUS_VideoFormat vformat); |
|---|
| 101 | boutput_hdmi_hdcp_state nexus2dta_hdcp_state(NEXUS_HdmiOutputHdcpState hdcpState); |
|---|
| 102 | extern bresult bgraphics_p_format_change(NEXUS_DisplayHandle display, int id); |
|---|
| 103 | |
|---|
| 104 | BDBG_MODULE(bdisplay); |
|---|
| 105 | |
|---|
| 106 | bdisplay_t bdisplay_open(int id) |
|---|
| 107 | { |
|---|
| 108 | NEXUS_PlatformConfiguration platformConfig; |
|---|
| 109 | NEXUS_DisplaySettings displaySettings; |
|---|
| 110 | int i; |
|---|
| 111 | |
|---|
| 112 | BSTD_UNUSED(id); |
|---|
| 113 | NEXUS_Platform_GetConfiguration(&platformConfig); |
|---|
| 114 | |
|---|
| 115 | NEXUS_Display_GetDefaultSettings(&displaySettings); |
|---|
| 116 | displaySettings.format = s_display.format; |
|---|
| 117 | |
|---|
| 118 | s_display.handle[eBDISPLAY_HDMI] = NEXUS_Display_Open(0, &displaySettings); |
|---|
| 119 | |
|---|
| 120 | NEXUS_Display_GetDefaultSettings(&displaySettings); |
|---|
| 121 | displaySettings.format = NEXUS_VideoFormat_eNtsc; |
|---|
| 122 | s_display.handle[eBDISPLAY_COMPOSITE] = NEXUS_Display_Open(1, &displaySettings); |
|---|
| 123 | NEXUS_Display_AddOutput(s_display.handle[eBDISPLAY_COMPOSITE], |
|---|
| 124 | NEXUS_CompositeOutput_GetConnector(platformConfig.outputs.composite[0])); |
|---|
| 125 | #if NEXUS_NUM_RFM_OUTPUTS |
|---|
| 126 | NEXUS_Display_AddOutput(s_display.handle[eBDISPLAY_COMPOSITE], |
|---|
| 127 | NEXUS_Rfm_GetVideoConnector(platformConfig.outputs.rfm[0])); |
|---|
| 128 | #endif |
|---|
| 129 | for (i=0; i<eBDISPLAY_ID_MAX; i++) { |
|---|
| 130 | s_display.window[i] = NEXUS_VideoWindow_Open(s_display.handle[i], 0); |
|---|
| 131 | if (i == 0) { |
|---|
| 132 | NEXUS_VideoWindowSettings windowSettings; |
|---|
| 133 | NEXUS_VideoWindowScalerSettings scalerSettings; |
|---|
| 134 | NEXUS_VideoWindow_GetSettings(s_display.window[0], &windowSettings); |
|---|
| 135 | windowSettings.allocateFullScreen = true; |
|---|
| 136 | windowSettings.scaleFactorRounding.enabled = true; |
|---|
| 137 | windowSettings.scaleFactorRounding.horizontalTolerance = 0; |
|---|
| 138 | windowSettings.scaleFactorRounding.verticalTolerance = 0; |
|---|
| 139 | windowSettings.minimumSourceFormat = NEXUS_VideoFormat_e1080i; |
|---|
| 140 | windowSettings.minimumDisplayFormat = NEXUS_VideoFormat_e1080i; |
|---|
| 141 | NEXUS_VideoWindow_SetSettings(s_display.window[0], &windowSettings); |
|---|
| 142 | |
|---|
| 143 | NEXUS_VideoWindow_GetScalerSettings(s_display.window[0], &scalerSettings); |
|---|
| 144 | scalerSettings.bandwidthEquationParams.bias = NEXUS_ScalerCaptureBias_eScalerBeforeCapture; |
|---|
| 145 | scalerSettings.bandwidthEquationParams.delta = 1*1000*1000; |
|---|
| 146 | NEXUS_VideoWindow_SetScalerSettings(s_display.window[0], &scalerSettings); |
|---|
| 147 | } |
|---|
| 148 | } |
|---|
| 149 | |
|---|
| 150 | return &s_display; |
|---|
| 151 | } |
|---|
| 152 | |
|---|
| 153 | NEXUS_VideoWindowHandle bdisplay_p_get_window(bdisplay_t display, int index) |
|---|
| 154 | { |
|---|
| 155 | BDBG_ASSERT(display); |
|---|
| 156 | return display->window[index]; |
|---|
| 157 | } |
|---|
| 158 | |
|---|
| 159 | /* |
|---|
| 160 | * Summary: |
|---|
| 161 | * to set initial hdmi video format if not default 720p |
|---|
| 162 | * Description: |
|---|
| 163 | * to set initial hdmi video format if not default 720p |
|---|
| 164 | **/ |
|---|
| 165 | bresult bdisplay_set_init_format(bobject_t display_id, bsettop_display_format_t format) |
|---|
| 166 | { |
|---|
| 167 | NEXUS_VideoFormat fmt = NEXUS_VideoFormat_eUnknown; |
|---|
| 168 | if (eBDISPLAY_HDMI != display_id) |
|---|
| 169 | return berr_not_supported; |
|---|
| 170 | |
|---|
| 171 | if (bdisplay_format_1080i == format) |
|---|
| 172 | fmt = NEXUS_VideoFormat_e1080i; |
|---|
| 173 | else if (bdisplay_format_480i == format) |
|---|
| 174 | fmt = NEXUS_VideoFormat_eNtsc; |
|---|
| 175 | else if (bdisplay_format_480p == format) |
|---|
| 176 | fmt = NEXUS_VideoFormat_e480p; |
|---|
| 177 | |
|---|
| 178 | if (fmt != NEXUS_VideoFormat_eUnknown) |
|---|
| 179 | s_display.format = fmt; |
|---|
| 180 | return b_ok; |
|---|
| 181 | } |
|---|
| 182 | |
|---|
| 183 | NEXUS_DisplayHandle bdisplay_p_get_handle(bdisplay_t display, int id) |
|---|
| 184 | { |
|---|
| 185 | if (id >= eBDISPLAY_ID_MAX) |
|---|
| 186 | return NULL; |
|---|
| 187 | return display->handle[id]; |
|---|
| 188 | } |
|---|
| 189 | |
|---|
| 190 | NEXUS_VideoFormat bdisplay_hdmi_format_auto(void) |
|---|
| 191 | { |
|---|
| 192 | return NEXUS_VideoFormat_e720p; |
|---|
| 193 | } |
|---|
| 194 | |
|---|
| 195 | bresult bdisplay_set(bdisplay_t display, bdisplay_settings *settings) |
|---|
| 196 | { |
|---|
| 197 | NEXUS_VideoFormat vformat; |
|---|
| 198 | NEXUS_DisplaySettings dsettings; |
|---|
| 199 | NEXUS_DisplayAspectRatio aspect; |
|---|
| 200 | |
|---|
| 201 | NEXUS_Display_GetSettings(display->handle[eBDISPLAY_HDMI], &dsettings); |
|---|
| 202 | |
|---|
| 203 | switch (settings->format) { |
|---|
| 204 | case bdisplay_format_480i: vformat = NEXUS_VideoFormat_eNtsc; break; |
|---|
| 205 | case bdisplay_format_480p: vformat = NEXUS_VideoFormat_e480p; break; |
|---|
| 206 | case bdisplay_format_720p: vformat = NEXUS_VideoFormat_e720p; break; |
|---|
| 207 | case bdisplay_format_1080p24: vformat = NEXUS_VideoFormat_e1080p24hz; break; |
|---|
| 208 | case bdisplay_format_1080p30: vformat = NEXUS_VideoFormat_e1080p30hz; break; |
|---|
| 209 | case bdisplay_format_auto: vformat = bdisplay_hdmi_format_auto(); break; |
|---|
| 210 | case bdisplay_format_1080i: |
|---|
| 211 | default: |
|---|
| 212 | vformat = NEXUS_VideoFormat_e1080i; break; |
|---|
| 213 | } |
|---|
| 214 | switch (settings->hd_options) { |
|---|
| 215 | case bdisplay_hd_output_options_stretch: aspect = NEXUS_DisplayAspectRatio_e16x9; break; |
|---|
| 216 | case bdisplay_hd_output_options_pillarbox: aspect = NEXUS_DisplayAspectRatio_e4x3; break; |
|---|
| 217 | case bdisplay_hd_output_options_auto: |
|---|
| 218 | default: |
|---|
| 219 | aspect = NEXUS_DisplayAspectRatio_eAuto; break; |
|---|
| 220 | } |
|---|
| 221 | if (dsettings.format != vformat) { |
|---|
| 222 | dsettings.format = vformat; |
|---|
| 223 | dsettings.aspectRatio = aspect; |
|---|
| 224 | display->format = vformat; |
|---|
| 225 | NEXUS_Display_SetSettings(display->handle[eBDISPLAY_HDMI], &dsettings); |
|---|
| 226 | bgraphics_p_format_change(display->handle[eBDISPLAY_HDMI], eBDISPLAY_HDMI); |
|---|
| 227 | } |
|---|
| 228 | else if (dsettings.aspectRatio != aspect) { |
|---|
| 229 | dsettings.aspectRatio = aspect; |
|---|
| 230 | NEXUS_Display_SetSettings(display->handle[eBDISPLAY_HDMI], &dsettings); |
|---|
| 231 | } |
|---|
| 232 | |
|---|
| 233 | if ((settings->deinterlace != display->settings.deinterlace) || |
|---|
| 234 | (settings->shrink_width != display->settings.shrink_width) || |
|---|
| 235 | (settings->deinterlacer_affinity != display->settings.deinterlacer_affinity)) |
|---|
| 236 | { |
|---|
| 237 | display->settings.shrink_width = settings->shrink_width; |
|---|
| 238 | bdisplay_set_deinterlacer(display, settings->deinterlacer_affinity, settings->deinterlace); |
|---|
| 239 | |
|---|
| 240 | } |
|---|
| 241 | |
|---|
| 242 | display->settings = *settings; |
|---|
| 243 | return b_ok; |
|---|
| 244 | } |
|---|
| 245 | |
|---|
| 246 | |
|---|
| 247 | void bdisplay_get(bdisplay_t display, bdisplay_settings *settings) |
|---|
| 248 | { |
|---|
| 249 | BDBG_ASSERT(display); |
|---|
| 250 | BDBG_ASSERT(settings); |
|---|
| 251 | *settings = display->settings; |
|---|
| 252 | } |
|---|
| 253 | |
|---|
| 254 | void bdisplay_get_default_settings(bdisplay_settings *psettings) |
|---|
| 255 | { |
|---|
| 256 | if (psettings) BKNI_Memcpy(psettings, &s_display.settings, sizeof(bdisplay_settings)); |
|---|
| 257 | } |
|---|
| 258 | |
|---|
| 259 | void bdisplay_set_deinterlacer(bdisplay_t display, int id, bool enable) |
|---|
| 260 | { |
|---|
| 261 | int alt_id; |
|---|
| 262 | NEXUS_VideoWindowMadSettings madSettings; |
|---|
| 263 | |
|---|
| 264 | alt_id = (id == eBDISPLAY_HDMI)?eBDISPLAY_COMPOSITE:eBDISPLAY_HDMI; |
|---|
| 265 | NEXUS_VideoWindow_GetMadSettings(display->window[alt_id], &madSettings); |
|---|
| 266 | madSettings.deinterlace = false; |
|---|
| 267 | NEXUS_VideoWindow_SetMadSettings(display->window[alt_id], &madSettings); |
|---|
| 268 | |
|---|
| 269 | NEXUS_VideoWindow_GetMadSettings(display->window[id], &madSettings); |
|---|
| 270 | #ifdef SHRINK_WIDTH |
|---|
| 271 | if ((display->format != NEXUS_VideoFormat_e1080p24hz) && (display->format != NEXUS_VideoFormat_e1080p30hz)) |
|---|
| 272 | madSettings.shrinkWidth = display->settings.shrink_width; |
|---|
| 273 | #endif |
|---|
| 274 | madSettings.deinterlace = enable; |
|---|
| 275 | NEXUS_VideoWindow_SetMadSettings(display->window[id], &madSettings); |
|---|
| 276 | } |
|---|
| 277 | |
|---|
| 278 | void bdisplay_set_coefficient_index(bdisplay_t display, bool horiz, int output, int coeff_idx) |
|---|
| 279 | { |
|---|
| 280 | BSTD_UNUSED(display); |
|---|
| 281 | BSTD_UNUSED(horiz); |
|---|
| 282 | BSTD_UNUSED(output); |
|---|
| 283 | BSTD_UNUSED(coeff_idx); |
|---|
| 284 | } |
|---|
| 285 | |
|---|
| 286 | bresult bdisplay_set_vbi_rating_info(bdisplay_t display, unsigned int ratings_tv, unsigned int ratings_movie, |
|---|
| 287 | unsigned int content_v, unsigned int content_s, unsigned int content_l, unsigned int content_d) |
|---|
| 288 | { |
|---|
| 289 | NEXUS_ClosedCaptionData xds_data[3]; |
|---|
| 290 | size_t written; |
|---|
| 291 | |
|---|
| 292 | BSTD_UNUSED(content_v); |
|---|
| 293 | xds_data[0].field = 1; /* bottom field */ |
|---|
| 294 | xds_data[0].data[0] = 0x01; |
|---|
| 295 | xds_data[0].data[1] = 0x05; |
|---|
| 296 | |
|---|
| 297 | xds_data[1].field = 1; |
|---|
| 298 | /* character 1 : x 1 D/a2 a1 a0 r2 r1 r0 |
|---|
| 299 | * character 2 : x 1 (F)V S L/a3 g2 g1 g0 */ |
|---|
| 300 | xds_data[1].data[0] = (ratings_movie|0x40) | 0x08 | (content_d<<5); |
|---|
| 301 | xds_data[1].data[1] = (ratings_tv|0x40) | (content_l<<3) | (content_s<<4) | (content_s<<5); |
|---|
| 302 | |
|---|
| 303 | xds_data[2].field = 1; |
|---|
| 304 | xds_data[2].data[0] = 0x0f; |
|---|
| 305 | xds_data[2].data[1] = 0x1d; |
|---|
| 306 | |
|---|
| 307 | NEXUS_Display_WriteClosedCaption(display->handle[eBDISPLAY_COMPOSITE], xds_data, 3, &written); |
|---|
| 308 | if (written != 3) { |
|---|
| 309 | BDBG_WRN(("Rating info wasn't fully written on VBI (%d)", written)); |
|---|
| 310 | } |
|---|
| 311 | return BERR_SUCCESS; |
|---|
| 312 | } |
|---|
| 313 | |
|---|
| 314 | /* --------------------------------------------------------------------------- |
|---|
| 315 | * HDMI |
|---|
| 316 | * --------------------------------------------------------------------------- */ |
|---|
| 317 | /* following should match with bsettop_display_format_t */ |
|---|
| 318 | static NEXUS_VideoFormat s_display_format_to_nexus[] = |
|---|
| 319 | { |
|---|
| 320 | NEXUS_VideoFormat_eMax, /* bdisplay_format_auto */ |
|---|
| 321 | NEXUS_VideoFormat_e1080i, |
|---|
| 322 | NEXUS_VideoFormat_e720p, |
|---|
| 323 | NEXUS_VideoFormat_eNtsc, |
|---|
| 324 | NEXUS_VideoFormat_e480p, |
|---|
| 325 | NEXUS_VideoFormat_e1080p, |
|---|
| 326 | NEXUS_VideoFormat_e1080p24hz, |
|---|
| 327 | NEXUS_VideoFormat_e1080p30hz |
|---|
| 328 | }; |
|---|
| 329 | |
|---|
| 330 | static int s_num_display_format_to_nexus = sizeof(s_display_format_to_nexus)/sizeof(NEXUS_VideoFormat); |
|---|
| 331 | |
|---|
| 332 | static void bsettop_hdmi_p_connect(bsettop_hdmi_t hdmi); |
|---|
| 333 | static void bsettop_hdmi_p_disconnect(bsettop_hdmi_t hdmi); |
|---|
| 334 | static void bsettop_hdmi_task(void *data); |
|---|
| 335 | |
|---|
| 336 | static void bsettop_hdmi_p_hotplug_cb(void *pparam, int iparam) |
|---|
| 337 | { |
|---|
| 338 | BSTD_UNUSED(iparam); |
|---|
| 339 | BKNI_SetEvent((BKNI_EventHandle)pparam); |
|---|
| 340 | } |
|---|
| 341 | |
|---|
| 342 | #ifdef HDCPLIB |
|---|
| 343 | static void bsettop_hdmi_p_hdcp_state_cb(void *pparam, int iparam) |
|---|
| 344 | { |
|---|
| 345 | BSTD_UNUSED(iparam); |
|---|
| 346 | BKNI_SetEvent((BKNI_EventHandle)pparam); |
|---|
| 347 | } |
|---|
| 348 | #endif |
|---|
| 349 | |
|---|
| 350 | static void bsettop_hdmi_p_cec_cb(void *pparam, int iparam) |
|---|
| 351 | { |
|---|
| 352 | BSTD_UNUSED(iparam); |
|---|
| 353 | BKNI_SetEvent((BKNI_EventHandle)pparam); |
|---|
| 354 | } |
|---|
| 355 | |
|---|
| 356 | bresult bsettop_hdmi_open(bsettop_hdmi_t *h_hdmi, |
|---|
| 357 | bdisplay_t display, |
|---|
| 358 | baudio_decode_t audio_decode, |
|---|
| 359 | bsettop_hdcp_authentication_cb_t hdcp_authentication_cb) |
|---|
| 360 | { |
|---|
| 361 | NEXUS_PlatformConfiguration platformConfig; |
|---|
| 362 | NEXUS_HdmiOutputSettings hdmiSettings; |
|---|
| 363 | #ifdef HDCPLIB |
|---|
| 364 | NEXUS_HdmiOutputHdcpSettings hdcpSettings; |
|---|
| 365 | #endif |
|---|
| 366 | #if BHDM_CEC_SUPPORT |
|---|
| 367 | NEXUS_HdmiOutputCecSettings cecSettings; |
|---|
| 368 | #endif |
|---|
| 369 | b_task_params task_params; |
|---|
| 370 | |
|---|
| 371 | BSTD_UNUSED(audio_decode); |
|---|
| 372 | |
|---|
| 373 | BKNI_Memset(&s_hdmi_output, 0, sizeof(s_hdmi_output)); |
|---|
| 374 | |
|---|
| 375 | NEXUS_Platform_GetConfiguration(&platformConfig); |
|---|
| 376 | s_hdmi_output.handle = platformConfig.outputs.hdmi[0]; |
|---|
| 377 | s_hdmi_output.display = display->handle[eBDISPLAY_HDMI]; |
|---|
| 378 | s_hdmi_output.hdcp_authentication_cb = hdcp_authentication_cb; |
|---|
| 379 | BKNI_CreateEventGroup(&s_hdmi_output.hdmiEvent); |
|---|
| 380 | BKNI_CreateEvent(&s_hdmi_output.hotplugEvent); |
|---|
| 381 | BKNI_CreateEvent(&s_hdmi_output.hdcpEvent); |
|---|
| 382 | BKNI_CreateEvent(&s_hdmi_output.cecEvent); |
|---|
| 383 | BKNI_AddEventGroup(s_hdmi_output.hdmiEvent, s_hdmi_output.hotplugEvent); |
|---|
| 384 | BKNI_AddEventGroup(s_hdmi_output.hdmiEvent, s_hdmi_output.hdcpEvent); |
|---|
| 385 | BKNI_AddEventGroup(s_hdmi_output.hdmiEvent, s_hdmi_output.cecEvent); |
|---|
| 386 | |
|---|
| 387 | bsettop_hdmi_p_connect(&s_hdmi_output); |
|---|
| 388 | |
|---|
| 389 | NEXUS_HdmiOutput_GetSettings(s_hdmi_output.handle, &hdmiSettings); |
|---|
| 390 | hdmiSettings.hotplugCallback.callback = bsettop_hdmi_p_hotplug_cb; |
|---|
| 391 | hdmiSettings.hotplugCallback.context = s_hdmi_output.hotplugEvent; |
|---|
| 392 | hdmiSettings.cecCallback.callback = bsettop_hdmi_p_cec_cb; |
|---|
| 393 | hdmiSettings.cecCallback.context = &s_hdmi_output; |
|---|
| 394 | NEXUS_HdmiOutput_SetSettings(s_hdmi_output.handle, &hdmiSettings); |
|---|
| 395 | |
|---|
| 396 | #ifdef HDCPLIB |
|---|
| 397 | NEXUS_HdmiOutput_GetHdcpSettings(s_hdmi_output.handle, &hdcpSettings); |
|---|
| 398 | hdcpSettings->stateChangedCallback.callback = bsettop_hdmi_p_hdcp_state_cb; |
|---|
| 399 | hdcpSettings->stateChangedCallback.context = s_hdmi_output.hdcpEvent; |
|---|
| 400 | hdcpSettings->successCallback.callback = bsettop_hdmi_p_hdcp_state_cb; |
|---|
| 401 | hdcpSettings->successCallback.context = s_hdmi_output.hdcpEvent; |
|---|
| 402 | hdcpSettings->failureCallback.callback = bsettop_hdmi_p_hdcp_state_cb; |
|---|
| 403 | hdcpSettings->failureCallback.context = s_hdmi_output.hdcpEvent; |
|---|
| 404 | NEXUS_HdmiOutput_SetHdcpSettings(s_hdmi_output.handle, &hdcpSettings); |
|---|
| 405 | #endif |
|---|
| 406 | |
|---|
| 407 | #if BHDM_CEC_SUPPORT |
|---|
| 408 | NEXUS_HdmiOutput_GetCecSettings(s_hdmi_output.handle, &cecSettings); |
|---|
| 409 | cecSettings.enabled = true; |
|---|
| 410 | NEXUS_HdmiOutput_SetCecSettingS(s_hdmi_output.handle, &cecSettings); |
|---|
| 411 | #endif |
|---|
| 412 | task_params.name = "HDMI"; |
|---|
| 413 | task_params.priority = HDMI_PRIORITY; |
|---|
| 414 | task_params.stack_size = HDMI_TASK_STACK_SIZE; |
|---|
| 415 | task_params.stack = s_hdmi_output.task_stack; |
|---|
| 416 | |
|---|
| 417 | bos_start_task(&(s_hdmi_output.task_h), &task_params, bsettop_hdmi_task, &s_hdmi_output); |
|---|
| 418 | |
|---|
| 419 | s_hdmi_output.connected = true; |
|---|
| 420 | *h_hdmi = &s_hdmi_output; |
|---|
| 421 | return b_ok; |
|---|
| 422 | } |
|---|
| 423 | |
|---|
| 424 | void bsettop_hdmi_close(bsettop_hdmi_t h_hdmi) |
|---|
| 425 | { |
|---|
| 426 | if (h_hdmi->task_h) |
|---|
| 427 | bos_stop_task(h_hdmi->task_h); |
|---|
| 428 | |
|---|
| 429 | BKNI_RemoveEventGroup(h_hdmi->hdmiEvent, h_hdmi->hotplugEvent); |
|---|
| 430 | BKNI_RemoveEventGroup(h_hdmi->hdmiEvent, h_hdmi->hdcpEvent); |
|---|
| 431 | BKNI_RemoveEventGroup(h_hdmi->hdmiEvent, h_hdmi->cecEvent); |
|---|
| 432 | |
|---|
| 433 | BKNI_DestroyEvent(h_hdmi->hotplugEvent); |
|---|
| 434 | BKNI_DestroyEvent(h_hdmi->hdcpEvent); |
|---|
| 435 | BKNI_DestroyEvent(h_hdmi->cecEvent); |
|---|
| 436 | BKNI_DestroyEventGroup(h_hdmi->hdmiEvent); |
|---|
| 437 | } |
|---|
| 438 | |
|---|
| 439 | bool bsettop_hdmi_is_video_fmt_supported(bsettop_display_format_t format) |
|---|
| 440 | { |
|---|
| 441 | NEXUS_HdmiOutputStatus status; |
|---|
| 442 | |
|---|
| 443 | if (format == bdisplay_format_auto) |
|---|
| 444 | return true; |
|---|
| 445 | |
|---|
| 446 | if (format >= bdisplay_format_max) { |
|---|
| 447 | BDBG_ERR(("%s: Invalid format", __func__)); |
|---|
| 448 | return false; |
|---|
| 449 | } |
|---|
| 450 | |
|---|
| 451 | NEXUS_HdmiOutput_GetStatus(s_hdmi_output.handle, &status); |
|---|
| 452 | if (status.videoFormatSupported[s_display_format_to_nexus[format]]) |
|---|
| 453 | return true; |
|---|
| 454 | else |
|---|
| 455 | return false; |
|---|
| 456 | } |
|---|
| 457 | |
|---|
| 458 | bool bsettop_hdmi_get_RGB_output(void) |
|---|
| 459 | { |
|---|
| 460 | NEXUS_HdmiOutputSettings settings; |
|---|
| 461 | |
|---|
| 462 | NEXUS_HdmiOutput_GetSettings(s_hdmi_output.handle, &settings); |
|---|
| 463 | if (settings.colorSpace == NEXUS_ColorSpace_eRgb) |
|---|
| 464 | return true; |
|---|
| 465 | else |
|---|
| 466 | return false; |
|---|
| 467 | } |
|---|
| 468 | |
|---|
| 469 | bresult bsettop_hdmi_set_RGB_output(bool bRGB) |
|---|
| 470 | { |
|---|
| 471 | NEXUS_HdmiOutputSettings settings; |
|---|
| 472 | |
|---|
| 473 | NEXUS_HdmiOutput_GetSettings(s_hdmi_output.handle, &settings); |
|---|
| 474 | |
|---|
| 475 | if (bRGB) |
|---|
| 476 | settings.colorSpace = NEXUS_ColorSpace_eRgb; |
|---|
| 477 | else |
|---|
| 478 | settings.colorSpace = NEXUS_ColorSpace_eYCbCr444; |
|---|
| 479 | |
|---|
| 480 | NEXUS_HdmiOutput_SetSettings(s_hdmi_output.handle, &settings); |
|---|
| 481 | return b_ok; |
|---|
| 482 | } |
|---|
| 483 | |
|---|
| 484 | /* TODO:: |
|---|
| 485 | * does it require new NEXUs API? such as NEXUS_HdmiOutput_SetAudioParams_priv.. |
|---|
| 486 | */ |
|---|
| 487 | bool bsettop_hdmi_get_native_audio_mode(void) |
|---|
| 488 | { |
|---|
| 489 | return s_hdmi_output.native; |
|---|
| 490 | } |
|---|
| 491 | |
|---|
| 492 | BERR_Code bsettop_hdmi_set_native_audio_mode(bool native) |
|---|
| 493 | { |
|---|
| 494 | s_hdmi_output.native = native; |
|---|
| 495 | return b_ok; |
|---|
| 496 | } |
|---|
| 497 | |
|---|
| 498 | /** |
|---|
| 499 | * Summary: |
|---|
| 500 | * Get the current HDMI status |
|---|
| 501 | */ |
|---|
| 502 | bresult boutput_hdmi_get_status(bsettop_hdmi_t h_hdmi, |
|---|
| 503 | boutput_hdmi_status *status /* [out] */ |
|---|
| 504 | ) |
|---|
| 505 | { |
|---|
| 506 | NEXUS_HdmiOutputStatus hdmiStatus; |
|---|
| 507 | NEXUS_HdmiOutputHdcpStatus hdcpStatus; |
|---|
| 508 | |
|---|
| 509 | BDBG_ASSERT(h_hdmi); |
|---|
| 510 | BDBG_ASSERT(status); |
|---|
| 511 | |
|---|
| 512 | NEXUS_HdmiOutput_GetStatus(h_hdmi->handle, &hdmiStatus); |
|---|
| 513 | NEXUS_HdmiOutput_GetHdcpStatus(h_hdmi->handle, &hdcpStatus); |
|---|
| 514 | status->connected = hdmiStatus.connected; |
|---|
| 515 | status->is_hdmi = hdmiStatus.hdmiDevice; |
|---|
| 516 | |
|---|
| 517 | status->preferred = bvideo_format_count; |
|---|
| 518 | switch (hdmiStatus.preferredVideoFormat) { |
|---|
| 519 | case NEXUS_VideoFormat_eNtsc: status->preferred = bvideo_format_ntsc; break; |
|---|
| 520 | case NEXUS_VideoFormat_e480p: status->preferred = bvideo_format_480p; break; |
|---|
| 521 | case NEXUS_VideoFormat_e720p: status->preferred = bvideo_format_720p; break; |
|---|
| 522 | case NEXUS_VideoFormat_e1080i: status->preferred = bvideo_format_1080i; break; |
|---|
| 523 | default: break; |
|---|
| 524 | } |
|---|
| 525 | |
|---|
| 526 | if (hdcpStatus.hdcpState == NEXUS_HdmiOutputHdcpState_eEncryptionEnabled) |
|---|
| 527 | status->hdcp_state = boutput_hdmi_hdcp_state_enabled; |
|---|
| 528 | else |
|---|
| 529 | status->hdcp_state = boutput_hdmi_hdcp_state_internal_err; |
|---|
| 530 | |
|---|
| 531 | return b_ok; |
|---|
| 532 | } |
|---|
| 533 | |
|---|
| 534 | static void bsettop_hdmi_p_disconnect(bsettop_hdmi_t hdmi) |
|---|
| 535 | { |
|---|
| 536 | NEXUS_DisplaySettings displaySettings; |
|---|
| 537 | #ifdef HDCPLIB |
|---|
| 538 | if (hdmi->hdcpStarted) |
|---|
| 539 | { |
|---|
| 540 | NEXUS_HdmiOutput_DisableHdcpAuthentication(hdmi->handle); |
|---|
| 541 | hdmi->hdcpStarted = false; |
|---|
| 542 | } |
|---|
| 543 | #endif |
|---|
| 544 | NEXUS_Display_GetSettings(hdmi->display, &displaySettings); |
|---|
| 545 | NEXUS_Display_RemoveOutput(hdmi->display, NEXUS_HdmiOutput_GetVideoConnector(hdmi->handle)); |
|---|
| 546 | NEXUS_Display_SetSettings(hdmi->display, &displaySettings); |
|---|
| 547 | } |
|---|
| 548 | |
|---|
| 549 | static void bsettop_hdmi_p_connect(bsettop_hdmi_t hdmi) |
|---|
| 550 | { |
|---|
| 551 | NEXUS_DisplaySettings displaySettings; |
|---|
| 552 | |
|---|
| 553 | NEXUS_Display_AddOutput(hdmi->display, NEXUS_HdmiOutput_GetVideoConnector(hdmi->handle)); |
|---|
| 554 | NEXUS_Display_GetSettings(hdmi->display, &displaySettings); |
|---|
| 555 | NEXUS_Display_SetSettings(hdmi->display, &displaySettings); |
|---|
| 556 | } |
|---|
| 557 | |
|---|
| 558 | static void bsettop_hdmi_task(void *data) |
|---|
| 559 | { |
|---|
| 560 | bsettop_hdmi_t hdmi = (bsettop_hdmi_t)data; |
|---|
| 561 | BKNI_EventHandle events[3]; |
|---|
| 562 | |
|---|
| 563 | unsigned i, nevents; |
|---|
| 564 | int j; |
|---|
| 565 | NEXUS_HdmiOutputStatus status; |
|---|
| 566 | NEXUS_HdmiOutputHandle handle = hdmi->handle; |
|---|
| 567 | NEXUS_DisplaySettings displaySettings; |
|---|
| 568 | #if HDCPLIB |
|---|
| 569 | NEXUS_HdmiOutputHdcpStatus hdcpStatus; |
|---|
| 570 | #endif |
|---|
| 571 | NEXUS_HdmiOutputCecStatus cecStatus; |
|---|
| 572 | #if BHDM_CEC_SUPPORT |
|---|
| 573 | NEXUS_HdmiOutputCecMessageData cecMsg; |
|---|
| 574 | #endif |
|---|
| 575 | while (1) |
|---|
| 576 | { |
|---|
| 577 | BKNI_WaitForGroup(hdmi->hdmiEvent, -1, events, sizeof(events)/sizeof(*events), &nevents); |
|---|
| 578 | |
|---|
| 579 | for (i=0; i<nevents; i++) |
|---|
| 580 | { |
|---|
| 581 | if (events[i] == hdmi->hotplugEvent) |
|---|
| 582 | { /* process hot plug events */ |
|---|
| 583 | NEXUS_HdmiOutput_GetStatus(handle, &status); |
|---|
| 584 | if (hdmi->connected == status.connected) { |
|---|
| 585 | BDBG_WRN(("hotplug state not changed : %d", hdmi->connected)); |
|---|
| 586 | continue; |
|---|
| 587 | } |
|---|
| 588 | |
|---|
| 589 | hdmi->connected = status.connected; |
|---|
| 590 | if (hdmi->connected) |
|---|
| 591 | { /* disconnected -> connected */ |
|---|
| 592 | BDBG_WRN(("%s:%d HDMI connected", __func__, __LINE__)); |
|---|
| 593 | |
|---|
| 594 | NEXUS_Display_GetSettings(hdmi->display, &displaySettings); |
|---|
| 595 | if (!status.videoFormatSupported[displaySettings.format]) { |
|---|
| 596 | for (j = 1; j< s_num_display_format_to_nexus; j++) { |
|---|
| 597 | if (status.videoFormatSupported[s_display_format_to_nexus[j]]) break; |
|---|
| 598 | } |
|---|
| 599 | if (j==s_num_display_format_to_nexus) { |
|---|
| 600 | BDBG_WRN(("%s:%d device doesn't support valid format", __func__, __LINE__)); |
|---|
| 601 | continue; |
|---|
| 602 | } |
|---|
| 603 | displaySettings.format = s_display_format_to_nexus[j]; |
|---|
| 604 | NEXUS_Display_SetSettings(hdmi->display, &displaySettings); |
|---|
| 605 | BDBG_WRN(("%s:%d video format not supported. use %d instead", displaySettings.format)); |
|---|
| 606 | } |
|---|
| 607 | bsettop_hdmi_p_connect(hdmi); |
|---|
| 608 | } |
|---|
| 609 | else |
|---|
| 610 | { /* connected -> disconnected */ |
|---|
| 611 | BDBG_WRN(("%s:%d HDMI disconnected", __func__, __LINE__)); |
|---|
| 612 | bsettop_hdmi_p_disconnect(hdmi); |
|---|
| 613 | } |
|---|
| 614 | } |
|---|
| 615 | #ifdef HDCPLIB |
|---|
| 616 | /* TODO:: HDCP/CEC event handling */ |
|---|
| 617 | else if (events[i] == hdmi->hdcpEvent) |
|---|
| 618 | { /* process hdcp events */ |
|---|
| 619 | } |
|---|
| 620 | #endif |
|---|
| 621 | else if (events[i] == hdmi->cecEvent) |
|---|
| 622 | { /* process cec events */ |
|---|
| 623 | NEXUS_HdmiOutput_GetCecStatus(hdmi->handle, &cecStatus); |
|---|
| 624 | } |
|---|
| 625 | } |
|---|
| 626 | } |
|---|
| 627 | } |
|---|
| 628 | |
|---|
| 629 | /* TODO:: platform will handle */ |
|---|
| 630 | void bsettop_hdmi_standby(bsettop_hdmi_t h_hdmi, bool standby) |
|---|
| 631 | { |
|---|
| 632 | BSTD_UNUSED(h_hdmi); |
|---|
| 633 | BSTD_UNUSED(standby); |
|---|
| 634 | } |
|---|
| 635 | |
|---|
| 636 | bresult bdisplay_vbi_clear_cc(void) |
|---|
| 637 | { |
|---|
| 638 | NEXUS_ClosedCaptionData ccData[6]; |
|---|
| 639 | size_t i, num; |
|---|
| 640 | |
|---|
| 641 | /* Force send EDM command to clear */ |
|---|
| 642 | for (i=0; i<2; i++) { |
|---|
| 643 | ccData[i].field = 0; |
|---|
| 644 | ccData[i].data[0] = 0x14; |
|---|
| 645 | ccData[i].data[1] = 0x2c; |
|---|
| 646 | } |
|---|
| 647 | |
|---|
| 648 | /* Force send ENM command to clear */ |
|---|
| 649 | for (i=2; i<4; i++) { |
|---|
| 650 | ccData[i].field = 0; |
|---|
| 651 | ccData[i].data[0] = 0x14; |
|---|
| 652 | ccData[i].data[1] = 0x2e; |
|---|
| 653 | } |
|---|
| 654 | |
|---|
| 655 | /* EOC command */ |
|---|
| 656 | for (i=4; i<6; i++) { |
|---|
| 657 | ccData[i].field = 0; |
|---|
| 658 | ccData[i].data[0] = 0x14; |
|---|
| 659 | ccData[i].data[1] = 0x2f; |
|---|
| 660 | } |
|---|
| 661 | NEXUS_Display_WriteClosedCaption(s_display.handle[eBDISPLAY_COMPOSITE], ccData, 6, &num); |
|---|
| 662 | return b_ok; |
|---|
| 663 | } |
|---|
| 664 | |
|---|
| 665 | bresult bdisplay_vbi_enable_amol_gs(bool enable) |
|---|
| 666 | { |
|---|
| 667 | BSTD_UNUSED(enable); |
|---|
| 668 | return b_ok; |
|---|
| 669 | } |
|---|
| 670 | |
|---|
| 671 | void bsettop_hdmi_mark_dsp_fmt_valid(bsettop_hdmi_t h_hdmi) |
|---|
| 672 | { |
|---|
| 673 | BSTD_UNUSED(h_hdmi); |
|---|
| 674 | } |
|---|