[PATCH v2 12/14] ASoC: hdac_hdmi: Add infoframe support for dp audio
Daniel Stone
daniel at fooishbar.org
Thu Dec 3 09:13:16 PST 2015
Hi Subhransu,
On 3 December 2015 at 21:09, Subhransu S. Prusty
<subhransu.s.prusty at intel.com> wrote:
> + if (conn_type == DRM_ELD_CONN_TYPE_HDMI) {
> + hdmi_audio_infoframe_init(&frame);
> +
> + /* Default stereo for now */
> + frame.channels = channels;
> +
> + ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
> + if (ret < 0)
> + return ret;
> +
> + dip = (u8 *)&frame;
> +
> + } else if (conn_type == DRM_ELD_CONN_TYPE_DP) {
> + memset(&dp_ai, 0, sizeof(dp_ai));
> + dp_ai.type = 0x84;
> + dp_ai.len = 0x1b;
> + dp_ai.ver = 0x11 << 2;
> + dp_ai.CC02_CT47 = channels - 1;
> + dp_ai.CA = 0;
> +
> + dip = (u8 *)&dip;
Surely this should be dip = (u8 *) &dp_ai, instead of pointing to itself?
Cheers,
Daniel
On 3 December 2015 at 21:09, Subhransu S. Prusty
<subhransu.s.prusty at intel.com> wrote:
> This uses the get_conn_type API added in the previous patch to
> identify the type of display connected and fills the infoframe
> accordingly.
>
> Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty at intel.com>
> Signed-off-by: Vinod Koul <vinod.koul at intel.com>
> ---
> sound/soc/codecs/hdac_hdmi.c | 68 ++++++++++++++++++++++++++++++++++++++------
> 1 file changed, 59 insertions(+), 9 deletions(-)
>
> diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
> index 3ac3498..d963d92 100644
> --- a/sound/soc/codecs/hdac_hdmi.c
> +++ b/sound/soc/codecs/hdac_hdmi.c
> @@ -22,6 +22,7 @@
> #include <linux/module.h>
> #include <linux/pm_runtime.h>
> #include <linux/hdmi.h>
> +#include <drm/drm_edid.h>
> #include <sound/pcm_params.h>
> #include <sound/soc.h>
> #include <sound/hdaudio_ext.h>
> @@ -201,27 +202,70 @@ hdac_hdmi_set_dip_index(struct hdac_ext_device *hdac, hda_nid_t pin_nid,
> AC_VERB_SET_HDMI_DIP_INDEX, val);
> }
>
> +struct dp_audio_infoframe {
> + u8 type; /* 0x84 */
> + u8 len; /* 0x1b */
> + u8 ver; /* 0x11 << 2 */
> +
> + u8 CC02_CT47; /* match with HDMI infoframe from this on */
> + u8 SS01_SF24;
> + u8 CXT04;
> + u8 CA;
> + u8 LFEPBL01_LSV36_DM_INH7;
> +};
> +
> static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
> hda_nid_t cvt_nid, hda_nid_t pin_nid)
> {
> uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
> struct hdmi_audio_infoframe frame;
> + struct dp_audio_infoframe dp_ai;
> + struct hdac_hdmi_priv *hdmi = hdac->private_data;
> + struct hdac_hdmi_pin *pin;
> u8 *dip = (u8 *)&frame;
> int ret;
> int i;
> + const u8 *eld_buf;
> + u8 conn_type;
> + int channels = 2;
>
> - hdmi_audio_infoframe_init(&frame);
> + list_for_each_entry(pin, &hdmi->pin_list, head) {
> + if (pin->nid == pin_nid)
> + break;
> + }
>
> - /* Default stereo for now */
> - frame.channels = 2;
> + eld_buf = pin->eld.eld_buffer;
> + conn_type = drm_eld_get_conn_type(eld_buf);
>
> /* setup channel count */
> snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0,
> - AC_VERB_SET_CVT_CHAN_COUNT, frame.channels - 1);
> + AC_VERB_SET_CVT_CHAN_COUNT, channels - 1);
>
> - ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
> - if (ret < 0)
> - return ret;
> + if (conn_type == DRM_ELD_CONN_TYPE_HDMI) {
> + hdmi_audio_infoframe_init(&frame);
> +
> + /* Default stereo for now */
> + frame.channels = channels;
> +
> + ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
> + if (ret < 0)
> + return ret;
> +
> + dip = (u8 *)&frame;
> +
> + } else if (conn_type == DRM_ELD_CONN_TYPE_DP) {
> + memset(&dp_ai, 0, sizeof(dp_ai));
> + dp_ai.type = 0x84;
> + dp_ai.len = 0x1b;
> + dp_ai.ver = 0x11 << 2;
> + dp_ai.CC02_CT47 = channels - 1;
> + dp_ai.CA = 0;
> +
> + dip = (u8 *)&dip;
> + } else {
> + dev_err(&hdac->hdac.dev, "Invalid connection type: %d\n", conn_type);
> + return -EIO;
> + }
>
> /* stop infoframe transmission */
> hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
> @@ -231,9 +275,15 @@ static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
>
> /* Fill infoframe. Index auto-incremented */
> hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
> - for (i = 0; i < sizeof(frame); i++)
> - snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
> + if (conn_type == 0) {
> + for (i = 0; i < sizeof(frame); i++)
> + snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
> AC_VERB_SET_HDMI_DIP_DATA, dip[i]);
> + } else {
> + for (i = 0; i < sizeof(dp_ai); i++)
> + snd_hdac_codec_write(&hdac->hdac, pin_nid, 0,
> + AC_VERB_SET_HDMI_DIP_DATA, dip[i]);
> + }
>
> /* Start infoframe */
> hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
> --
> 1.9.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
More information about the dri-devel
mailing list