On Wed, Aug 14, 2013 at 12:17 PM, Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> wrote: > On Wed, Aug 14, 2013 at 12:08:13PM -0400, Alex Deucher wrote: >> This adds a helper function to extract the speaker allocation >> data block from the EDID. This data block describes what speakers >> are present on the display device. >> >> v2: update per Ville Syrjälä's comments >> >> Signed-off-by: Alex Deucher <alexander.deucher@xxxxxxx> >> --- >> drivers/gpu/drm/drm_edid.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++ >> include/drm/drm_edid.h | 1 + >> 2 files changed, 53 insertions(+) >> >> diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c >> index 70fc133..2e36d28 100644 >> --- a/drivers/gpu/drm/drm_edid.c >> +++ b/drivers/gpu/drm/drm_edid.c >> @@ -2735,6 +2735,58 @@ int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads) >> EXPORT_SYMBOL(drm_edid_to_sad); >> >> /** >> + * drm_edid_to_speaker_allocation - extracts Speaker Allocation Data Blocks from EDID >> + * @edid: EDID to parse >> + * @sadb: pointer to the speaker block >> + * >> + * Looks for CEA EDID block and extracts the Speaker Allocation Data Block from it. >> + * Note: returned pointer needs to be kfreed >> + * >> + * Return number of found Speaker Allocation Blocks or negative number on error. >> + */ >> +int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb) >> +{ >> + int count = 0; >> + int i, start, end, dbl; >> + const u8 *cea; >> + >> + cea = drm_find_cea_extension(edid); >> + if (!cea) { >> + DRM_DEBUG_KMS("SAD: no CEA Extension found\n"); >> + return -ENOENT; >> + } >> + >> + if (cea_revision(cea) < 3) { >> + DRM_DEBUG_KMS("SAD: wrong CEA revision\n"); >> + return -ENOTSUPP; >> + } >> + >> + if (cea_db_offsets(cea, &start, &end)) { >> + DRM_DEBUG_KMS("SAD: invalid data block offsets\n"); >> + return -EPROTO; >> + } >> + >> + for_each_cea_db(cea, i, start, end) { >> + const u8 *db = &cea[i]; >> + >> + if (cea_db_tag(db) == SPEAKER_BLOCK) { >> + dbl = cea_db_payload_len(db); >> + >> + /* Speaker Allocation Data Block */ >> + if (dbl == 3) { >> + *sadb = kcalloc(count, dbl, GFP_KERNEL); > > 'count' not initialized yet. I suppose it was supposed to be just > kmalloc(dbl, GFP_KERNEL). But since it's just three bytes, making > the user just pass in a pointer to u32 would work just as well > w/o requiring the dynamic alloc/free. whoops, that was just a copy paste error. I'll fix that. I suppose we could just use a u32 unless the size of the block changes in the future. Alex > >> + memcpy(*sadb, &db[1], dbl); >> + count = dbl; >> + break; >> + } >> + } >> + } >> + >> + return count; >> +} >> +EXPORT_SYMBOL(drm_edid_to_speaker_allocation); >> + >> +/** >> * drm_av_sync_delay - HDMI/DP sink audio-video sync delay in millisecond >> * @connector: connector associated with the HDMI/DP sink >> * @mode: the display mode >> diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h >> index fc481fc..c76a129 100644 >> --- a/include/drm/drm_edid.h >> +++ b/include/drm/drm_edid.h >> @@ -259,6 +259,7 @@ struct hdmi_avi_infoframe; >> >> void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid); >> int drm_edid_to_sad(struct edid *edid, struct cea_sad **sads); >> +int drm_edid_to_speaker_allocation(struct edid *edid, u8 **sadb); >> int drm_av_sync_delay(struct drm_connector *connector, >> struct drm_display_mode *mode); >> struct drm_connector *drm_select_eld(struct drm_encoder *encoder, >> -- >> 1.8.3.1 >> >> _______________________________________________ >> dri-devel mailing list >> dri-devel@xxxxxxxxxxxxxxxxxxxxx >> http://lists.freedesktop.org/mailman/listinfo/dri-devel > > -- > Ville Syrjälä > Intel OTC _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel