diff options
-rw-r--r-- | include/hdmi_service_api.h | 2 | ||||
-rw-r--r-- | include/hdmi_service_local.h | 7 | ||||
-rw-r--r-- | src/edid.c | 12 | ||||
-rw-r--r-- | src/hdmi_service.c | 29 |
4 files changed, 33 insertions, 17 deletions
diff --git a/include/hdmi_service_api.h b/include/hdmi_service_api.h index 8133d33..53dd08b 100644 --- a/include/hdmi_service_api.h +++ b/include/hdmi_service_api.h @@ -16,7 +16,7 @@ extern "C" { * Set to 1 to stay alive when system suspends. * Set to 0 to sleep when system suspends. */ -#define HDMI_SERVICE_STAY_ALIVE_DURING_SUSPEND 1 +#define HDMI_SERVICE_STAY_ALIVE_DURING_SUSPEND 0 /* If defined, socket usage is hidden for messages from service, * and a callback function is used instead diff --git a/include/hdmi_service_local.h b/include/hdmi_service_local.h index 8e6afdb..d3ea3db 100644 --- a/include/hdmi_service_local.h +++ b/include/hdmi_service_local.h @@ -216,6 +216,7 @@ int hdmi_service_vesa_cea_prio_set(__u8 vesa_cea1, __u8 nr1, #define EDIDREAD_FAIL -3 #define EDIDREAD_NOEXT -4 #define EDIDREAD_NOVIDEO -5 +#define EDIDREAD_BL1_TAG_REV_ERR -6 #define HDCP_OK 0 #define AESKEYS_FAIL -1 #define HDCPSTATE_FAIL -2 @@ -230,6 +231,7 @@ int hdmi_service_vesa_cea_prio_set(__u8 vesa_cea1, __u8 nr1, #define EDID_BL0_ESTTIM1_OFFSET 0x23 #define EDID_BL0_ESTTIM2_OFFSET 0x24 #define EDID_BL0_STDTIM1_OFFSET 0x26 +#define EDID_BL1_TAG_OFFSET 0x00 #define EDID_BL1_REVNR_OFFSET 0x01 #define EDID_BL1_OFFSET_OFFSET 0x02 #define EDID_BL1_AUDIO_SUPPORT_OFFSET 0x03 @@ -242,6 +244,8 @@ int hdmi_service_vesa_cea_prio_set(__u8 vesa_cea1, __u8 nr1, #define EDID_BL1_STDTIM9_2_FLAG_OFFSET 0x5A #define EDID_BL1_STDTIM9_3_FLAG_OFFSET 0x6C #define EDID_BL1_STDTIM9_BYTE_START 5 +#define EDID_BL1_TAG_EXPECTED 0x02 +#define EDID_BL1_REV_EXPECTED 0x03 #define EDID_SVD_ID_MASK 0x7F #define EDID_EXTVER_3 0x03 #define EDID_NO_DATA 0x04 @@ -282,7 +286,8 @@ int hdmi_service_vesa_cea_prio_set(__u8 vesa_cea1, __u8 nr1, #define STARTUP_DELAY_US 6000000 #define HDCPAUTH_WAITTIME 1000000 #define LOADAES_WAITTIME 250000 -#define EDIDREAD_WAITTIME 2000000 +#define EDIDREAD_WAITTIME0 2000000 +#define EDIDREAD_WAITTIME1 100000 /* Socket listen thread */ #define SOCKET_DATA_MAX 256 @@ -322,6 +322,7 @@ int edid_parse0(__u8 *data, __u8 *extension, struct video_format formats[], int edid_parse1(__u8 *data, struct video_format formats[], int nr_formats, int *basic_audio_support, struct edid_latency *edid_latency) { + __u8 tag; __u8 rev; __u8 offset; __u8 blockp; @@ -342,11 +343,16 @@ int edid_parse1(__u8 *data, struct video_format formats[], int nr_formats, __u8 edidp; __u8 *p; + tag = *(data + EDID_BL1_TAG_OFFSET); rev = *(data + EDID_BL1_REVNR_OFFSET); + if ((tag != EDID_BL1_TAG_EXPECTED) || rev != EDID_BL1_REV_EXPECTED) { + LOGHDMILIB("edid bl1 tag:%02x or rev:%02x invalid", tag, rev); + return EDIDREAD_BL1_TAG_REV_ERR; + } + offset = *(data + EDID_BL1_OFFSET_OFFSET); LOGHDMILIB("rev:%d offset:%d", rev, offset); - if ((rev != EDID_EXTVER_3) || (offset == 0) || (offset == EDID_NO_DATA)) { LOGHDMILIB("%s", "No video block"); @@ -403,7 +409,7 @@ int edid_parse1(__u8 *data, struct video_format formats[], int nr_formats, /* Video and Audio latency */ if ((length >= EDID_VSD_AUD_LAT) && (*(p + EDID_VSD_LATENCY_IND) & - EDID_VSD_LAT_FLD_MASK )) { + EDID_VSD_LAT_FLD_MASK)) { edid_latency->video_latency = 2 * (*(p + EDID_VSD_VID_LAT) - 1); edid_latency->audio_latency = @@ -413,7 +419,7 @@ int edid_parse1(__u8 *data, struct video_format formats[], int nr_formats, /* Interlaced Video and Audio latency */ if ((length >= EDID_VSD_INTLCD_AUD_LAT) && (*(p + EDID_VSD_LATENCY_IND) & - EDID_VSD_INTLCD_LAT_FLD_MASK )) { + EDID_VSD_INTLCD_LAT_FLD_MASK)) { edid_latency->intlcd_video_latency = 2 * (*(p + EDID_VSD_INTLCD_VID_LAT) - 1); edid_latency->audio_latency = diff --git a/src/hdmi_service.c b/src/hdmi_service.c index 7e4ea08..e262f8b 100644 --- a/src/hdmi_service.c +++ b/src/hdmi_service.c @@ -35,7 +35,7 @@ void (*hdmi_callback_fn)(int cmd, int data_length, __u8 *data) = NULL; #endif /*HDMI_SERVICE_USE_CALLBACK_FN*/ int hdmi_events; enum hdmi_fb_state hdmi_fb_state; -enum hdmi_plug_state hdmi_plug_state; +enum hdmi_plug_state hdmi_plug_state = HDMI_PLUGUNDEF; struct cmd_data *cmd_data; int cmd_id_ind; @@ -199,11 +199,6 @@ int hdmiplug_subscribe(void) goto hdmiplug_subscribe_err2; } - /* Unsubscribe */ - res = write(plugdetenfd, plugdetdis_val, sizeof(plugdetdis_val)); - if (res != sizeof(plugdetdis_val)) - goto hdmiplug_subscribe_err1; - /* Subscribe */ res = write(plugdetenfd, plugdeten_val, sizeof(plugdeten_val)); if (res != sizeof(plugdeten_val)) @@ -296,7 +291,7 @@ static int hdmiplugged_handle(int *basic_audio_support) res = edid_parse0(data + 1, &extension, formats, nr_formats); if (res && (cnt < 2)) - usleep(EDIDREAD_WAITTIME); + usleep(EDIDREAD_WAITTIME0); cnt++; } if (res) { @@ -306,13 +301,23 @@ static int hdmiplugged_handle(int *basic_audio_support) if (extension) { /* Extension data exists */ - if (edid_read(1, data) != 0) { - ret = -2; - goto hdmiplugged_handle_end; + cnt = 0; + res = -1; + while (res && (cnt < 3)) { + res = edid_read(1, data); + if (res == 0) + res = edid_parse1(data + 1, formats, nr_formats, + basic_audio_support, + &edid_latency); + if (res && (cnt < 2)) + usleep(EDIDREAD_WAITTIME1); + cnt++; } - edid_parse1(data + 1, formats, nr_formats, - basic_audio_support, &edid_latency); + if (res) { + ret = -1; + goto hdmiplugged_handle_end; + } /* Set hdmi format to hdmi */ hdmi_format_set(HDMI_FORMAT_HDMI); |