ASoC: hdac_hdmi: Add infoframe support for dp audio
For DP audio support, infoframe needs to be different. Based on get_conn_type result we pack either HDMI or DP infoframe. Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
148569fddb
commit
478f544e5b
|
@ -253,27 +253,75 @@ hdac_hdmi_set_dip_index(struct hdac_ext_device *hdac, hda_nid_t pin_nid,
|
||||||
AC_VERB_SET_HDMI_DIP_INDEX, val);
|
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,
|
static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
|
||||||
hda_nid_t cvt_nid, hda_nid_t pin_nid)
|
hda_nid_t cvt_nid, hda_nid_t pin_nid)
|
||||||
{
|
{
|
||||||
uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
|
uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
|
||||||
struct hdmi_audio_infoframe frame;
|
struct hdmi_audio_infoframe frame;
|
||||||
u8 *dip = (u8 *)&frame;
|
struct dp_audio_infoframe dp_ai;
|
||||||
|
struct hdac_hdmi_priv *hdmi = hdac->private_data;
|
||||||
|
struct hdac_hdmi_pin *pin;
|
||||||
|
u8 *dip;
|
||||||
int ret;
|
int ret;
|
||||||
int i;
|
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 */
|
eld_buf = pin->eld.eld_buffer;
|
||||||
frame.channels = 2;
|
conn_type = drm_eld_get_conn_type(eld_buf);
|
||||||
|
|
||||||
/* setup channel count */
|
/* setup channel count */
|
||||||
snd_hdac_codec_write(&hdac->hdac, cvt_nid, 0,
|
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));
|
switch (conn_type) {
|
||||||
if (ret < 0)
|
case DRM_ELD_CONN_TYPE_HDMI:
|
||||||
return ret;
|
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;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 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 *)&dp_ai;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dev_err(&hdac->hdac.dev, "Invalid connection type: %d\n",
|
||||||
|
conn_type);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
/* stop infoframe transmission */
|
/* stop infoframe transmission */
|
||||||
hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
|
hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
|
||||||
|
@ -283,9 +331,15 @@ static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
|
||||||
|
|
||||||
/* Fill infoframe. Index auto-incremented */
|
/* Fill infoframe. Index auto-incremented */
|
||||||
hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
|
hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
|
||||||
for (i = 0; i < sizeof(frame); i++)
|
if (conn_type == DRM_ELD_CONN_TYPE_HDMI) {
|
||||||
snd_hdac_codec_write(&hdac->hdac, pin_nid, 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]);
|
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 */
|
/* Start infoframe */
|
||||||
hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
|
hdac_hdmi_set_dip_index(hdac, pin_nid, 0x0, 0x0);
|
||||||
|
|
Loading…
Reference in New Issue