[PATCH v2 12/14] ASoC: hdac_hdmi: Add infoframe support for dp audio

2015-12-04 Thread Subhransu S. Prusty
On Thu, Dec 03, 2015 at 05:13:16PM +, Daniel Stone wrote:
> Hi Subhransu,
> 
> On 3 December 2015 at 21:09, Subhransu S. Prusty
>  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?

Thanks for pointing. It's a mistake, will fix it.

Regards,
Subhansu
> 
> Cheers,
> Daniel
> 

-- 


[PATCH v2 12/14] ASoC: hdac_hdmi: Add infoframe support for dp audio

2015-12-04 Thread Subhransu S. Prusty
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 
Signed-off-by: Vinod Koul 
---
 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 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -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



[PATCH v2 12/14] ASoC: hdac_hdmi: Add infoframe support for dp audio

2015-12-03 Thread Daniel Stone
Hi Subhransu,

On 3 December 2015 at 21:09, Subhransu S. Prusty
 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
 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 
> Signed-off-by: Vinod Koul 
> ---
>  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 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -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,
>