Iterate through all CEA data blocks across all CEA extensions and DisplayID data blocks. This may gather more data than before, and if there's duplicated data, some is overwritten by whichever comes last. Signed-off-by: Jani Nikula <jani.nikula@xxxxxxxxx> --- drivers/gpu/drm/drm_edid.c | 64 +++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index d4bf9ef09c3c..ccbaa91b171d 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -4758,12 +4758,12 @@ static void clear_eld(struct drm_connector *connector) */ static void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) { + const struct cea_db *db; + struct cea_db_iter iter; uint8_t *eld = connector->eld; const u8 *cea; - const u8 *db; int total_sad_count = 0; int mnl; - int dbl; clear_eld(connector); @@ -4789,43 +4789,37 @@ static void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) eld[DRM_ELD_PRODUCT_CODE0] = edid->prod_code[0]; eld[DRM_ELD_PRODUCT_CODE1] = edid->prod_code[1]; - if (cea_revision(cea) >= 3) { - int i, start, end; + cea_db_iter_edid_begin(edid, &iter); + cea_db_iter_for_each(db, &iter) { + const u8 *data = cea_db_data(db); + int len = cea_db_payload_len(db); int sad_count; - if (cea_db_offsets(cea, &start, &end)) { - start = 0; - end = 0; - } - - for_each_cea_db(cea, i, start, end) { - db = &cea[i]; - dbl = cea_db_payload_len(db); - - switch (cea_db_tag(db)) { - case CEA_DB_AUDIO: - /* Audio Data Block, contains SADs */ - sad_count = min(dbl / 3, 15 - total_sad_count); - if (sad_count >= 1) - memcpy(&eld[DRM_ELD_CEA_SAD(mnl, total_sad_count)], - &db[1], sad_count * 3); - total_sad_count += sad_count; - break; - case CEA_DB_SPEAKER: - /* Speaker Allocation Data Block */ - if (dbl >= 1) - eld[DRM_ELD_SPEAKER] = db[1]; - break; - case CEA_DB_VENDOR: - /* HDMI Vendor-Specific Data Block */ - if (cea_db_is_hdmi_vsdb(db)) - drm_parse_hdmi_vsdb_audio(connector, db); - break; - default: - break; - } + switch (cea_db_tag(db)) { + case CEA_DB_AUDIO: + /* Audio Data Block, contains SADs */ + sad_count = min(len / 3, 15 - total_sad_count); + if (sad_count >= 1) + memcpy(&eld[DRM_ELD_CEA_SAD(mnl, total_sad_count)], + data, sad_count * 3); + total_sad_count += sad_count; + break; + case CEA_DB_SPEAKER: + /* Speaker Allocation Data Block */ + if (len >= 1) + eld[DRM_ELD_SPEAKER] = data[0]; + break; + case CEA_DB_VENDOR: + /* HDMI Vendor-Specific Data Block */ + if (cea_db_is_hdmi_vsdb(db)) + drm_parse_hdmi_vsdb_audio(connector, (const u8 *)db); + break; + default: + break; } } + cea_db_iter_end(&iter); + eld[DRM_ELD_SAD_COUNT_CONN_TYPE] |= total_sad_count << DRM_ELD_SAD_COUNT_SHIFT; if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort || -- 2.30.2