All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/4] ASoC: hdac_hdmi: refine the hdac_hdmi jacks
@ 2019-05-27  9:07 libin.yang
  2019-05-27  9:07 ` [RFC PATCH 1/4] ASoC: hdac_hdmi: amixer kctl setting should not impact on jack status libin.yang
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: libin.yang @ 2019-05-27  9:07 UTC (permalink / raw)
  To: alsa-devel; +Cc: tiwai, libin.yang, broonie, pierre-louis.bossart

From: Libin Yang <libin.yang@intel.com>

This patchset refines the hdac_hdmi jacks:
1. kctl setting should not impact on hdmi jack status
2. bind jack to pin-port instead of pcm
3. move creating jack into hdac_hdmi from machine drivers

Libin Yang (4):
  ASoC: hdac_hdmi: amixer kctl setting should not impact on jack status
  ASoC: hdac_hdmi: jack_event represents the status
  ASoC: hdac_hdmi: refine hdmi jacks
  ASoC: hdac_hdmi: fix some coding style issue

 sound/soc/codecs/hdac_hdmi.c                       | 176 +++++++++++----------
 sound/soc/intel/boards/bxt_da7219_max98357a.c      |  10 --
 sound/soc/intel/boards/bxt_rt298.c                 |  10 --
 sound/soc/intel/boards/glk_rt5682_max98357a.c      |  10 --
 sound/soc/intel/boards/kbl_da7219_max98357a.c      |  10 --
 sound/soc/intel/boards/kbl_da7219_max98927.c       |  10 --
 sound/soc/intel/boards/kbl_rt5660.c                |  10 --
 sound/soc/intel/boards/kbl_rt5663_max98927.c       |  10 --
 .../soc/intel/boards/kbl_rt5663_rt5514_max98927.c  |   9 --
 sound/soc/intel/boards/skl_hda_dsp_common.c        |   9 --
 sound/soc/intel/boards/skl_nau88l25_max98357a.c    |  11 --
 sound/soc/intel/boards/skl_nau88l25_ssm4567.c      |  11 --
 sound/soc/intel/boards/skl_rt286.c                 |  10 --
 sound/soc/intel/boards/sof_rt5682.c                |  11 --
 14 files changed, 92 insertions(+), 215 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [RFC PATCH 1/4] ASoC: hdac_hdmi: amixer kctl setting should not impact on jack status
  2019-05-27  9:07 [RFC PATCH 0/4] ASoC: hdac_hdmi: refine the hdac_hdmi jacks libin.yang
@ 2019-05-27  9:07 ` libin.yang
  2019-05-27  9:07 ` [RFC PATCH 2/4] ASoC: hdac_hdmi: jack_event represents the status libin.yang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 15+ messages in thread
From: libin.yang @ 2019-05-27  9:07 UTC (permalink / raw)
  To: alsa-devel; +Cc: tiwai, libin.yang, broonie, pierre-louis.bossart

From: Libin Yang <libin.yang@intel.com>

Amixer kctl setting should not impact on the jack connection status.
In hdac_hdmi_present_sense(), it will call hdac_hdmi_jack_report() to
report the monitor connection status. This means the jack status represents
the HDMI monitor connection status.

However, in the original code, hdac_hdmi_set_pin_port_mux() will also
call hdac_hdmi_jack_report() when "pinx-porty Mux" setting is changed. This
means the kctl setting will also impact on the jack status regardless of
the monitor connection. This will introduce some troubles. For example,
assuming the original amixer setting is:
"pin5-port0 Mux" is set "cvt 2"
"pin5-port1 Mux" is set "cvt 2"
HDMI uses pin5 and HDMI is connected to the machine.
After booting the system, setting "pin5-port1 Mux" to "NONE" will
trigger hdac_hdmi_set_pin_port_mux() calling hdac_hdmi_jack_report(false)
In this situation, user space will get the wrong status.

This patch removes calling hdac_hdmi_jack_report() in
hdac_hdmi_set_pin_port_mux(). This makes jack status always represents
the monitor connection status.

Signed-off-by: Libin Yang <libin.yang@intel.com>
---
 sound/soc/codecs/hdac_hdmi.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 660e058..5a9e7f9 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -855,7 +855,6 @@ static int hdac_hdmi_pin_mux_widget_event(struct snd_soc_dapm_widget *w,
 static int hdac_hdmi_set_pin_port_mux(struct snd_kcontrol *kcontrol,
 		struct snd_ctl_elem_value *ucontrol)
 {
-	int ret;
 	struct hdac_hdmi_port *p, *p_next;
 	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 	struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol);
@@ -865,6 +864,7 @@ static int hdac_hdmi_set_pin_port_mux(struct snd_kcontrol *kcontrol,
 	struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
 	struct hdac_hdmi_pcm *pcm = NULL;
 	const char *cvt_name =  e->texts[ucontrol->value.enumerated.item[0]];
+	int ret;
 
 	ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);
 	if (ret < 0)
@@ -880,10 +880,8 @@ static int hdac_hdmi_set_pin_port_mux(struct snd_kcontrol *kcontrol,
 
 		list_for_each_entry_safe(p, p_next, &pcm->port_list, head) {
 			if (p == port && p->id == port->id &&
-					p->pin == port->pin) {
-				hdac_hdmi_jack_report(pcm, port, false);
+			    p->pin == port->pin)
 				list_del(&p->head);
-			}
 		}
 	}
 
@@ -895,7 +893,6 @@ static int hdac_hdmi_set_pin_port_mux(struct snd_kcontrol *kcontrol,
 		if (!strcmp(cvt_name, pcm->cvt->name)) {
 			list_add_tail(&port->head, &pcm->port_list);
 			if (port->eld.monitor_present && port->eld.eld_valid) {
-				hdac_hdmi_jack_report(pcm, port, true);
 				mutex_unlock(&hdmi->pin_mutex);
 				return ret;
 			}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC PATCH 2/4] ASoC: hdac_hdmi: jack_event represents the status
  2019-05-27  9:07 [RFC PATCH 0/4] ASoC: hdac_hdmi: refine the hdac_hdmi jacks libin.yang
  2019-05-27  9:07 ` [RFC PATCH 1/4] ASoC: hdac_hdmi: amixer kctl setting should not impact on jack status libin.yang
@ 2019-05-27  9:07 ` libin.yang
  2019-05-27  9:07 ` [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks libin.yang
  2019-05-27  9:07 ` [RFC PATCH 4/4] ASoC: hdac_hdmi: fix some coding style issue libin.yang
  3 siblings, 0 replies; 15+ messages in thread
From: libin.yang @ 2019-05-27  9:07 UTC (permalink / raw)
  To: alsa-devel; +Cc: tiwai, libin.yang, broonie, pierre-louis.bossart

From: Libin Yang <libin.yang@intel.com>

As jack status represents the monitor connected or not, it represents
a status. So it should not be used as a counter. If driver receives
a monitor disconnection event, it should report this disconnection event
to userspace. For example, if the monitor connection event is sent to
driver twice (this should not happen, but in case there is some mistake),
when driver receives monitor disconnection event, it should still send the
disconnection event to user space.

Signed-off-by: Libin Yang <libin.yang@intel.com>
---
 sound/soc/codecs/hdac_hdmi.c | 15 ++-------------
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 5a9e7f9..90c2ee3 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -177,11 +177,6 @@ static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
 		snd_soc_dapm_disable_pin(port->dapm, port->jack_pin);
 
 	if (is_connect) {
-		/*
-		 * Report Jack connect event when a device is connected
-		 * for the first time where same PCM is attached to multiple
-		 * ports.
-		 */
 		if (pcm->jack_event == 0) {
 			dev_dbg(&hdev->dev,
 					"jack report for pcm=%d\n",
@@ -189,17 +184,11 @@ static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
 			snd_soc_jack_report(pcm->jack, SND_JACK_AVOUT,
 						SND_JACK_AVOUT);
 		}
-		pcm->jack_event++;
+		pcm->jack_event = 1;
 	} else {
-		/*
-		 * Report Jack disconnect event when a device is disconnected
-		 * is the only last connected device when same PCM is attached
-		 * to multiple ports.
-		 */
 		if (pcm->jack_event == 1)
 			snd_soc_jack_report(pcm->jack, 0, SND_JACK_AVOUT);
-		if (pcm->jack_event > 0)
-			pcm->jack_event--;
+		pcm->jack_event = 0;
 	}
 
 	snd_soc_dapm_sync(port->dapm);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks
  2019-05-27  9:07 [RFC PATCH 0/4] ASoC: hdac_hdmi: refine the hdac_hdmi jacks libin.yang
  2019-05-27  9:07 ` [RFC PATCH 1/4] ASoC: hdac_hdmi: amixer kctl setting should not impact on jack status libin.yang
  2019-05-27  9:07 ` [RFC PATCH 2/4] ASoC: hdac_hdmi: jack_event represents the status libin.yang
@ 2019-05-27  9:07 ` libin.yang
  2019-05-30  7:13   ` Takashi Iwai
  2019-05-27  9:07 ` [RFC PATCH 4/4] ASoC: hdac_hdmi: fix some coding style issue libin.yang
  3 siblings, 1 reply; 15+ messages in thread
From: libin.yang @ 2019-05-27  9:07 UTC (permalink / raw)
  To: alsa-devel; +Cc: tiwai, libin.yang, broonie, pierre-louis.bossart

From: Libin Yang <libin.yang@intel.com>

This patch does the following actions:
1) move snd_soc_card_jack_new() from machine driver to codec driver.
   This is because the jack information is more lated to the codec
   Also this patch calls snd_jack_add_new_kctl() to export the jack kctl
   to userspace.

2) jack is bound to pcm in origal code. The patch binds jack to pin-port.
   This mean each pin-port (3x3) has a jack. pin-port is used for DP-MST
   mode. The port means device entry for DP-MST in hdac_hdmi
   As hdac_hdmi allows user to map the pin-port to a pcm manually, the jack
   is bound to pcm is not accurate.
   However, PA assumes jack is bound to PCM for the legacy mode.
   For example, for ubuntu, in
   /usr/share/pulseaudio/alsa-mixer/paths/hdmi-output-x.conf uses
   "Jack HDMI/DP,pcm=n" to find which jack event is used.
   This main issue is: pcm number is fixed (3, 7, 8, 9, 10) for hdmi in
   legacy mode. But it is not always the same for ASoC hdmi audio.

Signed-off-by: Libin Yang <libin.yang@intel.com>
---
 sound/soc/codecs/hdac_hdmi.c                       | 127 ++++++++++++---------
 sound/soc/intel/boards/bxt_da7219_max98357a.c      |  10 --
 sound/soc/intel/boards/bxt_rt298.c                 |  10 --
 sound/soc/intel/boards/glk_rt5682_max98357a.c      |  10 --
 sound/soc/intel/boards/kbl_da7219_max98357a.c      |  10 --
 sound/soc/intel/boards/kbl_da7219_max98927.c       |  10 --
 sound/soc/intel/boards/kbl_rt5660.c                |  10 --
 sound/soc/intel/boards/kbl_rt5663_max98927.c       |  10 --
 .../soc/intel/boards/kbl_rt5663_rt5514_max98927.c  |   9 --
 sound/soc/intel/boards/skl_hda_dsp_common.c        |   9 --
 sound/soc/intel/boards/skl_nau88l25_max98357a.c    |  11 --
 sound/soc/intel/boards/skl_nau88l25_ssm4567.c      |  11 --
 sound/soc/intel/boards/skl_rt286.c                 |  10 --
 sound/soc/intel/boards/sof_rt5682.c                |  11 --
 14 files changed, 74 insertions(+), 184 deletions(-)

diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index 90c2ee3..ed267fa 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -4,6 +4,7 @@
  *  Copyright (C) 2014-2015 Intel Corp
  *  Author: Samreen Nilofer <samreen.nilofer@intel.com>
  *	    Subhransu S. Prusty <subhransu.s.prusty@intel.com>
+ *	    Libin Yang <libin.yang@intel.com>
  *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -30,6 +31,7 @@
 #include <sound/hda_i915.h>
 #include <sound/pcm_drm_eld.h>
 #include <sound/hda_chmap.h>
+#include <sound/hda_codec.h>
 #include "../../hda/local.h"
 #include "hdac_hdmi.h"
 
@@ -95,6 +97,8 @@ struct hdac_hdmi_port {
 	int num_mux_nids;
 	hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
 	struct hdac_hdmi_eld eld;
+	struct snd_soc_jack jack;
+	int jack_event;
 	const char *jack_pin;
 	struct snd_soc_dapm_context *dapm;
 	const char *output_pin;
@@ -105,14 +109,12 @@ struct hdac_hdmi_pcm {
 	int pcm_id;
 	struct list_head port_list;
 	struct hdac_hdmi_cvt *cvt;
-	struct snd_soc_jack *jack;
 	int stream_tag;
 	int channels;
 	int format;
 	bool chmap_set;
 	unsigned char chmap[8]; /* ALSA API channel-map */
 	struct mutex lock;
-	int jack_event;
 };
 
 struct hdac_hdmi_dai_port_map {
@@ -166,8 +168,7 @@ hdac_hdmi_get_pcm_from_cvt(struct hdac_hdmi_priv *hdmi,
 	return pcm;
 }
 
-static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
-		struct hdac_hdmi_port *port, bool is_connect)
+static void hdac_hdmi_jack_report(struct hdac_hdmi_port *port, bool is_connect)
 {
 	struct hdac_device *hdev = port->pin->hdev;
 
@@ -176,19 +177,25 @@ static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
 	else
 		snd_soc_dapm_disable_pin(port->dapm, port->jack_pin);
 
+	/* if jack is not ready, skip reporting jack status */
+	if (!port->jack.jack) {
+		snd_soc_dapm_sync(port->dapm);
+		return;
+	}
+
 	if (is_connect) {
-		if (pcm->jack_event == 0) {
+		if (port->jack_event == 0) {
 			dev_dbg(&hdev->dev,
-					"jack report for pcm=%d\n",
-					pcm->pcm_id);
-			snd_soc_jack_report(pcm->jack, SND_JACK_AVOUT,
-						SND_JACK_AVOUT);
+				"jack report for pin:port = %d:%d\n",
+				port->id, port->pin->nid);
+			snd_soc_jack_report(&port->jack, SND_JACK_AVOUT,
+					    SND_JACK_AVOUT);
 		}
-		pcm->jack_event = 1;
+		port->jack_event = 1;
 	} else {
-		if (pcm->jack_event == 1)
-			snd_soc_jack_report(pcm->jack, 0, SND_JACK_AVOUT);
-		pcm->jack_event = 0;
+		if (port->jack_event == 1)
+			snd_soc_jack_report(&port->jack, 0, SND_JACK_AVOUT);
+		port->jack_event = 0;
 	}
 
 	snd_soc_dapm_sync(port->dapm);
@@ -1235,26 +1242,15 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin,
 	pcm = hdac_hdmi_get_pcm(hdev, port);
 
 	if (!port->eld.monitor_present || !port->eld.eld_valid) {
-
 		dev_err(&hdev->dev, "%s: disconnect for pin:port %d:%d\n",
 						__func__, pin->nid, port->id);
-
-		/*
-		 * PCMs are not registered during device probe, so don't
-		 * report jack here. It will be done in usermode mux
-		 * control select.
-		 */
-		if (pcm)
-			hdac_hdmi_jack_report(pcm, port, false);
-
+		hdac_hdmi_jack_report(port, false);
 		mutex_unlock(&hdmi->pin_mutex);
 		return;
 	}
 
 	if (port->eld.monitor_present && port->eld.eld_valid) {
-		if (pcm)
-			hdac_hdmi_jack_report(pcm, port, true);
-
+		hdac_hdmi_jack_report(port, true);
 		print_hex_dump_debug("ELD: ", DUMP_PREFIX_OFFSET, 16, 1,
 			  port->eld.eld_buffer, port->eld.eld_size, false);
 
@@ -1650,6 +1646,30 @@ static int create_fill_jack_kcontrols(struct snd_soc_card *card,
 	return snd_soc_add_card_controls(card, kc, i);
 }
 
+static void hdac_hdmi_present_sense_all_pins(struct hdac_device *hdev,
+			struct hdac_hdmi_priv *hdmi, bool detect_pin_caps)
+{
+	int i;
+	struct hdac_hdmi_pin *pin;
+
+	list_for_each_entry(pin, &hdmi->pin_list, head) {
+		if (detect_pin_caps) {
+
+			if (hdac_hdmi_get_port_len(hdev, pin->nid)  == 0)
+				pin->mst_capable = false;
+			else
+				pin->mst_capable = true;
+		}
+
+		for (i = 0; i < pin->num_ports; i++) {
+			if (!pin->mst_capable && i > 0)
+				continue;
+
+			hdac_hdmi_present_sense(pin, &pin->ports[i]);
+		}
+	}
+}
+
 int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
 			struct snd_soc_dapm_context *dapm)
 {
@@ -1659,6 +1679,7 @@ int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
 	struct snd_soc_dapm_widget *widgets;
 	struct snd_soc_dapm_route *route;
 	char w_name[NAME_SIZE];
+	char jack_name[NAME_SIZE];
 	int i = 0, j, ret;
 
 	widgets = devm_kcalloc(dapm->dev, hdmi->num_ports,
@@ -1687,6 +1708,30 @@ int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
 			pin->ports[j].jack_pin = widgets[i].name;
 			pin->ports[j].dapm = dapm;
 
+			/*
+			 * Create pin-port jack. Each port (device entry) of
+			 * the pin has a corresponding jack
+			 */
+			snprintf(jack_name, sizeof(jack_name),
+				 "HDMI/DP, pin:port=%d:%d Jack",
+				  pin->nid, pin->ports[j].id);
+			ret = snd_soc_card_jack_new(dapm->card, jack_name,
+						    SND_JACK_AVOUT,
+						    &(pin->ports[j].jack),
+						    NULL, 0);
+			if (ret)
+				return ret;
+
+			/* create the jack kctl */
+			ret = snd_jack_add_new_kctl(pin->ports[j].jack.jack,
+						    jack_name, SND_JACK_AVOUT);
+			/*
+			 * It's not a critical issue if driver fails to
+			 * create jack kctl.
+			 */
+			if (ret)
+				dev_warn(&hdev->dev, "failed creating Jack kctl\n");
+
 			/* add to route from Jack widget to output */
 			hdac_hdmi_fill_route(&route[i], pin->ports[j].jack_pin,
 					NULL, pin->ports[j].output_pin, NULL);
@@ -1695,6 +1740,9 @@ int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
 		}
 	}
 
+	/* now jack is ready, let's update the status */
+	hdac_hdmi_present_sense_all_pins(hdev, hdmi, true);
+
 	/* Add Route from Jack widget to the output widget */
 	ret = snd_soc_dapm_new_controls(dapm, widgets, hdmi->num_ports);
 	if (ret < 0)
@@ -1744,8 +1792,6 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device,
 		return -ENOMEM;
 	pcm->pcm_id = device;
 	pcm->cvt = hdmi->dai_map[dai->id].cvt;
-	pcm->jack_event = 0;
-	pcm->jack = jack;
 	mutex_init(&pcm->lock);
 	INIT_LIST_HEAD(&pcm->port_list);
 	snd_pcm = hdac_hdmi_get_pcm_from_id(dai->component->card, device);
@@ -1765,30 +1811,6 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device,
 }
 EXPORT_SYMBOL_GPL(hdac_hdmi_jack_init);
 
-static void hdac_hdmi_present_sense_all_pins(struct hdac_device *hdev,
-			struct hdac_hdmi_priv *hdmi, bool detect_pin_caps)
-{
-	int i;
-	struct hdac_hdmi_pin *pin;
-
-	list_for_each_entry(pin, &hdmi->pin_list, head) {
-		if (detect_pin_caps) {
-
-			if (hdac_hdmi_get_port_len(hdev, pin->nid)  == 0)
-				pin->mst_capable = false;
-			else
-				pin->mst_capable = true;
-		}
-
-		for (i = 0; i < pin->num_ports; i++) {
-			if (!pin->mst_capable && i > 0)
-				continue;
-
-			hdac_hdmi_present_sense(pin, &pin->ports[i]);
-		}
-	}
-}
-
 static int hdmi_codec_probe(struct snd_soc_component *component)
 {
 	struct hdac_hdmi_priv *hdmi = snd_soc_component_get_drvdata(component);
@@ -1823,7 +1845,6 @@ static int hdmi_codec_probe(struct snd_soc_component *component)
 		return ret;
 	}
 
-	hdac_hdmi_present_sense_all_pins(hdev, hdmi, true);
 	/* Imp: Store the card pointer in hda_codec */
 	hdmi->card = dapm->card->snd_card;
 
diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c
index 5cadb7f..c69cfa9 100644
--- a/sound/soc/intel/boards/bxt_da7219_max98357a.c
+++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
@@ -573,14 +573,12 @@ static const struct x86_cpu_id glk_ids[] = {
 	{}
 };
 
-#define NAME_SIZE	32
 static int bxt_card_late_probe(struct snd_soc_card *card)
 {
 	struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card);
 	struct bxt_hdmi_pcm *pcm;
 	struct snd_soc_component *component = NULL;
 	int err, i = 0;
-	char jack_name[NAME_SIZE];
 
 	if (x86_match_cpu(glk_ids))
 		snd_soc_dapm_add_routes(&card->dapm, gemini_map,
@@ -591,14 +589,6 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
 		component = pcm->codec_dai->component;
-		snprintf(jack_name, sizeof(jack_name),
-			"HDMI/DP, pcm=%d Jack", pcm->device);
-		err = snd_soc_card_jack_new(card, jack_name,
-					SND_JACK_AVOUT, &broxton_hdmi[i],
-					NULL, 0);
-
-		if (err)
-			return err;
 
 		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
 						&broxton_hdmi[i]);
diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c
index e91057f..d1372891 100644
--- a/sound/soc/intel/boards/bxt_rt298.c
+++ b/sound/soc/intel/boards/bxt_rt298.c
@@ -507,25 +507,15 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
 	},
 };
 
-#define NAME_SIZE	32
 static int bxt_card_late_probe(struct snd_soc_card *card)
 {
 	struct bxt_rt286_private *ctx = snd_soc_card_get_drvdata(card);
 	struct bxt_hdmi_pcm *pcm;
 	struct snd_soc_component *component = NULL;
 	int err, i = 0;
-	char jack_name[NAME_SIZE];
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
 		component = pcm->codec_dai->component;
-		snprintf(jack_name, sizeof(jack_name),
-			"HDMI/DP, pcm=%d Jack", pcm->device);
-		err = snd_soc_card_jack_new(card, jack_name,
-					SND_JACK_AVOUT, &broxton_hdmi[i],
-					NULL, 0);
-
-		if (err)
-			return err;
 
 		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
 						&broxton_hdmi[i]);
diff --git a/sound/soc/intel/boards/glk_rt5682_max98357a.c b/sound/soc/intel/boards/glk_rt5682_max98357a.c
index d17126f..2a35974 100644
--- a/sound/soc/intel/boards/glk_rt5682_max98357a.c
+++ b/sound/soc/intel/boards/glk_rt5682_max98357a.c
@@ -29,7 +29,6 @@
 #define MAXIM_DEV0_NAME "MX98357A:00"
 #define DUAL_CHANNEL 2
 #define QUAD_CHANNEL 4
-#define NAME_SIZE 32
 
 static struct snd_soc_jack geminilake_hdmi[3];
 
@@ -523,21 +522,12 @@ static int glk_card_late_probe(struct snd_soc_card *card)
 {
 	struct glk_card_private *ctx = snd_soc_card_get_drvdata(card);
 	struct snd_soc_component *component = NULL;
-	char jack_name[NAME_SIZE];
 	struct glk_hdmi_pcm *pcm;
 	int err = 0;
 	int i = 0;
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
 		component = pcm->codec_dai->component;
-		snprintf(jack_name, sizeof(jack_name),
-			"HDMI/DP, pcm=%d Jack", pcm->device);
-		err = snd_soc_card_jack_new(card, jack_name,
-					SND_JACK_AVOUT, &geminilake_hdmi[i],
-					NULL, 0);
-
-		if (err)
-			return err;
 
 		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
 						&geminilake_hdmi[i]);
diff --git a/sound/soc/intel/boards/kbl_da7219_max98357a.c b/sound/soc/intel/boards/kbl_da7219_max98357a.c
index 07491a0..f293307 100644
--- a/sound/soc/intel/boards/kbl_da7219_max98357a.c
+++ b/sound/soc/intel/boards/kbl_da7219_max98357a.c
@@ -519,25 +519,15 @@ static struct snd_soc_dai_link kabylake_dais[] = {
 	},
 };
 
-#define NAME_SIZE	32
 static int kabylake_card_late_probe(struct snd_soc_card *card)
 {
 	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
 	struct kbl_hdmi_pcm *pcm;
 	struct snd_soc_component *component = NULL;
 	int err, i = 0;
-	char jack_name[NAME_SIZE];
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
 		component = pcm->codec_dai->component;
-		snprintf(jack_name, sizeof(jack_name),
-			"HDMI/DP, pcm=%d Jack", pcm->device);
-		err = snd_soc_card_jack_new(card, jack_name,
-					SND_JACK_AVOUT, &skylake_hdmi[i],
-					NULL, 0);
-
-		if (err)
-			return err;
 
 		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
 				&skylake_hdmi[i]);
diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c b/sound/soc/intel/boards/kbl_da7219_max98927.c
index f72a7bf..84d3609 100644
--- a/sound/soc/intel/boards/kbl_da7219_max98927.c
+++ b/sound/soc/intel/boards/kbl_da7219_max98927.c
@@ -34,7 +34,6 @@
 
 #define DUAL_CHANNEL	2
 #define QUAD_CHANNEL	4
-#define NAME_SIZE	32
 
 static struct snd_soc_card *kabylake_audio_card;
 static struct snd_soc_jack kabylake_hdmi[3];
@@ -952,18 +951,9 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
 	struct kbl_hdmi_pcm *pcm;
 	struct snd_soc_component *component = NULL;
 	int err, i = 0;
-	char jack_name[NAME_SIZE];
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
 		component = pcm->codec_dai->component;
-		snprintf(jack_name, sizeof(jack_name),
-			"HDMI/DP, pcm=%d Jack", pcm->device);
-		err = snd_soc_card_jack_new(card, jack_name,
-					SND_JACK_AVOUT, &kabylake_hdmi[i],
-					NULL, 0);
-
-		if (err)
-			return err;
 
 		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
 						&kabylake_hdmi[i]);
diff --git a/sound/soc/intel/boards/kbl_rt5660.c b/sound/soc/intel/boards/kbl_rt5660.c
index 3255e00..06411bf 100644
--- a/sound/soc/intel/boards/kbl_rt5660.c
+++ b/sound/soc/intel/boards/kbl_rt5660.c
@@ -447,25 +447,15 @@ static struct snd_soc_dai_link kabylake_rt5660_dais[] = {
 };
 
 
-#define NAME_SIZE	32
 static int kabylake_card_late_probe(struct snd_soc_card *card)
 {
 	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
 	struct kbl_hdmi_pcm *pcm;
 	struct snd_soc_component *component = NULL;
 	int err, i = 0;
-	char jack_name[NAME_SIZE];
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
 		component = pcm->codec_dai->component;
-		snprintf(jack_name, sizeof(jack_name),
-			"HDMI/DP, pcm=%d Jack", pcm->device);
-		err = snd_soc_card_jack_new(card, jack_name,
-					SND_JACK_AVOUT, &skylake_hdmi[i],
-					NULL, 0);
-
-		if (err)
-			return err;
 
 		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
 				&skylake_hdmi[i]);
diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c
index d714752..9c43c6c 100644
--- a/sound/soc/intel/boards/kbl_rt5663_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c
@@ -898,25 +898,15 @@ static struct snd_soc_dai_link kabylake_5663_dais[] = {
 	},
 };
 
-#define NAME_SIZE	32
 static int kabylake_card_late_probe(struct snd_soc_card *card)
 {
 	struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(card);
 	struct kbl_hdmi_pcm *pcm;
 	struct snd_soc_component *component = NULL;
 	int err, i = 0;
-	char jack_name[NAME_SIZE];
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
 		component = pcm->codec_dai->component;
-		snprintf(jack_name, sizeof(jack_name),
-			"HDMI/DP, pcm=%d Jack", pcm->device);
-		err = snd_soc_card_jack_new(card, jack_name,
-					SND_JACK_AVOUT, &skylake_hdmi[i],
-					NULL, 0);
-
-		if (err)
-			return err;
 
 		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
 						&skylake_hdmi[i]);
diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
index 879f142..8fe4007 100644
--- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
+++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
@@ -40,7 +40,6 @@
 #define RT5663_DEV_NAME "i2c-10EC5663:00"
 #define RT5514_AIF1_BCLK_FREQ (48000 * 8 * 16)
 #define RT5514_AIF1_SYSCLK_FREQ 12288000
-#define NAME_SIZE 32
 
 #define DMIC_CH(p) p->list[p->count-1]
 
@@ -600,18 +599,10 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
 	struct kbl_hdmi_pcm *pcm;
 	struct snd_soc_component *component = NULL;
 	int err, i = 0;
-	char jack_name[NAME_SIZE];
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
 		component = pcm->codec_dai->component;
-		snprintf(jack_name, sizeof(jack_name),
-			"HDMI/DP,pcm=%d Jack", pcm->device);
-		err = snd_soc_card_jack_new(card, jack_name,
-				SND_JACK_AVOUT, &ctx->kabylake_hdmi[i],
-				NULL, 0);
 
-		if (err)
-			return err;
 		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
 						&ctx->kabylake_hdmi[i]);
 		if (err < 0)
diff --git a/sound/soc/intel/boards/skl_hda_dsp_common.c b/sound/soc/intel/boards/skl_hda_dsp_common.c
index 8b68f41..0f57fc2 100644
--- a/sound/soc/intel/boards/skl_hda_dsp_common.c
+++ b/sound/soc/intel/boards/skl_hda_dsp_common.c
@@ -118,19 +118,10 @@ int skl_hda_hdmi_jack_init(struct snd_soc_card *card)
 	struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card);
 	struct snd_soc_component *component = NULL;
 	struct skl_hda_hdmi_pcm *pcm;
-	char jack_name[NAME_SIZE];
 	int err;
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
 		component = pcm->codec_dai->component;
-		snprintf(jack_name, sizeof(jack_name),
-			 "HDMI/DP, pcm=%d Jack", pcm->device);
-		err = snd_soc_card_jack_new(card, jack_name,
-					    SND_JACK_AVOUT, &pcm->hdmi_jack,
-					    NULL, 0);
-
-		if (err)
-			return err;
 
 		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
 					  &pcm->hdmi_jack);
diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
index 0922106..aca426f 100644
--- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
+++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
@@ -587,26 +587,15 @@ static struct snd_soc_dai_link skylake_dais[] = {
 	},
 };
 
-#define NAME_SIZE	32
 static int skylake_card_late_probe(struct snd_soc_card *card)
 {
 	struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(card);
 	struct skl_hdmi_pcm *pcm;
 	struct snd_soc_component *component = NULL;
 	int err, i = 0;
-	char jack_name[NAME_SIZE];
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
 		component = pcm->codec_dai->component;
-		snprintf(jack_name, sizeof(jack_name),
-			"HDMI/DP, pcm=%d Jack", pcm->device);
-		err = snd_soc_card_jack_new(card, jack_name,
-					SND_JACK_AVOUT,
-					&skylake_hdmi[i],
-					NULL, 0);
-
-		if (err)
-			return err;
 
 		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
 						&skylake_hdmi[i]);
diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
index 8433c52..788a837 100644
--- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
+++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
@@ -638,26 +638,15 @@ static struct snd_soc_dai_link skylake_dais[] = {
 	},
 };
 
-#define NAME_SIZE	32
 static int skylake_card_late_probe(struct snd_soc_card *card)
 {
 	struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(card);
 	struct skl_hdmi_pcm *pcm;
 	struct snd_soc_component *component = NULL;
 	int err, i = 0;
-	char jack_name[NAME_SIZE];
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
 		component = pcm->codec_dai->component;
-		snprintf(jack_name, sizeof(jack_name),
-			"HDMI/DP, pcm=%d Jack", pcm->device);
-		err = snd_soc_card_jack_new(card, jack_name,
-					SND_JACK_AVOUT,
-					&skylake_hdmi[i],
-					NULL, 0);
-
-		if (err)
-			return err;
 
 		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
 						&skylake_hdmi[i]);
diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c
index 0e1818d..5d245f5 100644
--- a/sound/soc/intel/boards/skl_rt286.c
+++ b/sound/soc/intel/boards/skl_rt286.c
@@ -473,25 +473,15 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
 	},
 };
 
-#define NAME_SIZE	32
 static int skylake_card_late_probe(struct snd_soc_card *card)
 {
 	struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(card);
 	struct skl_hdmi_pcm *pcm;
 	struct snd_soc_component *component = NULL;
 	int err, i = 0;
-	char jack_name[NAME_SIZE];
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
 		component = pcm->codec_dai->component;
-		snprintf(jack_name, sizeof(jack_name),
-			"HDMI/DP, pcm=%d Jack", pcm->device);
-		err = snd_soc_card_jack_new(card, jack_name,
-					SND_JACK_AVOUT, &skylake_hdmi[i],
-					NULL, 0);
-
-		if (err)
-			return err;
 
 		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
 						&skylake_hdmi[i]);
diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c
index f28fb98..660e4a6 100644
--- a/sound/soc/intel/boards/sof_rt5682.c
+++ b/sound/soc/intel/boards/sof_rt5682.c
@@ -22,8 +22,6 @@
 #include "../../codecs/rt5682.h"
 #include "../../codecs/hdac_hdmi.h"
 
-#define NAME_SIZE 32
-
 #define SOF_RT5682_SSP_CODEC(quirk)		((quirk) & GENMASK(2, 0))
 #define SOF_RT5682_SSP_CODEC_MASK			(GENMASK(2, 0))
 #define SOF_RT5682_MCLK_EN			BIT(3)
@@ -216,7 +214,6 @@ static int sof_card_late_probe(struct snd_soc_card *card)
 {
 	struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
 	struct snd_soc_component *component = NULL;
-	char jack_name[NAME_SIZE];
 	struct sof_hdmi_pcm *pcm;
 	int err = 0;
 	int i = 0;
@@ -227,14 +224,6 @@ static int sof_card_late_probe(struct snd_soc_card *card)
 
 	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
 		component = pcm->codec_dai->component;
-		snprintf(jack_name, sizeof(jack_name),
-			 "HDMI/DP, pcm=%d Jack", pcm->device);
-		err = snd_soc_card_jack_new(card, jack_name,
-					    SND_JACK_AVOUT, &sof_hdmi[i],
-					    NULL, 0);
-
-		if (err)
-			return err;
 
 		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
 					  &sof_hdmi[i]);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC PATCH 4/4] ASoC: hdac_hdmi: fix some coding style issue
  2019-05-27  9:07 [RFC PATCH 0/4] ASoC: hdac_hdmi: refine the hdac_hdmi jacks libin.yang
                   ` (2 preceding siblings ...)
  2019-05-27  9:07 ` [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks libin.yang
@ 2019-05-27  9:07 ` libin.yang
  3 siblings, 0 replies; 15+ messages in thread
From: libin.yang @ 2019-05-27  9:07 UTC (permalink / raw)
  To: alsa-devel; +Cc: tiwai, libin.yang, broonie, pierre-louis.bossart

From: Libin Yang <libin.yang@intel.com>

This patch fixes some coding style issue

Signed-off-by: Libin Yang <libin.yang@intel.com>
---
 sound/soc/codecs/hdac_hdmi.c | 31 ++++++++++++++++---------------
 1 file changed, 16 insertions(+), 15 deletions(-)

diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
index ed267fa..a52d236 100644
--- a/sound/soc/codecs/hdac_hdmi.c
+++ b/sound/soc/codecs/hdac_hdmi.c
@@ -477,8 +477,8 @@ static int hdac_hdmi_query_port_connlist(struct hdac_device *hdev,
 {
 	if (!(get_wcaps(hdev, pin->nid) & AC_WCAP_CONN_LIST)) {
 		dev_warn(&hdev->dev,
-			"HDMI: pin %d wcaps %#x does not support connection list\n",
-			pin->nid, get_wcaps(hdev, pin->nid));
+			 "HDMI: pin %d wcaps %#x does not support connection list\n",
+			 pin->nid, get_wcaps(hdev, pin->nid));
 		return -EINVAL;
 	}
 
@@ -489,11 +489,11 @@ static int hdac_hdmi_query_port_connlist(struct hdac_device *hdev,
 			port->mux_nids, HDA_MAX_CONNECTIONS);
 	if (port->num_mux_nids == 0)
 		dev_warn(&hdev->dev,
-			"No connections found for pin:port %d:%d\n",
-						pin->nid, port->id);
+			 "No connections found for pin:port %d:%d\n",
+			 pin->nid, port->id);
 
 	dev_dbg(&hdev->dev, "num_mux_nids %d for pin:port %d:%d\n",
-			port->num_mux_nids, pin->nid, port->id);
+		port->num_mux_nids, pin->nid, port->id);
 
 	return port->num_mux_nids;
 }
@@ -572,9 +572,9 @@ static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
 			(!port->eld.eld_valid)) {
 
 		dev_warn(&hdev->dev,
-			"Failed: present?:%d ELD valid?:%d pin:port: %d:%d\n",
-			port->eld.monitor_present, port->eld.eld_valid,
-			port->pin->nid, port->id);
+			 "Failed: present?:%d ELD valid?:%d pin:port: %d:%d\n",
+			 port->eld.monitor_present, port->eld.eld_valid,
+			 port->pin->nid, port->id);
 
 		return 0;
 	}
@@ -734,7 +734,7 @@ static int hdac_hdmi_pin_output_widget_event(struct snd_soc_dapm_widget *w,
 	struct hdac_hdmi_pcm *pcm;
 
 	dev_dbg(&hdev->dev, "%s: widget: %s event: %x\n",
-			__func__, w->name, event);
+		__func__, w->name, event);
 
 	pcm = hdac_hdmi_get_pcm(hdev, port);
 	if (!pcm)
@@ -780,7 +780,7 @@ static int hdac_hdmi_cvt_output_widget_event(struct snd_soc_dapm_widget *w,
 	struct hdac_hdmi_pcm *pcm;
 
 	dev_dbg(&hdev->dev, "%s: widget: %s event: %x\n",
-			__func__, w->name, event);
+		__func__, w->name, event);
 
 	pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, cvt);
 	if (!pcm)
@@ -826,7 +826,7 @@ static int hdac_hdmi_pin_mux_widget_event(struct snd_soc_dapm_widget *w,
 	int mux_idx;
 
 	dev_dbg(&hdev->dev, "%s: widget: %s event: %x\n",
-			__func__, w->name, event);
+		__func__, w->name, event);
 
 	if (!kc)
 		kc  = w->kcontrols[0];
@@ -1142,7 +1142,7 @@ static int hdac_hdmi_init_dai_map(struct hdac_device *hdev)
 
 		if (dai_id == HDA_MAX_CVTS) {
 			dev_warn(&hdev->dev,
-				"Max dais supported: %d\n", dai_id);
+				 "Max dais supported: %d\n", dai_id);
 			break;
 		}
 	}
@@ -1242,8 +1242,8 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin,
 	pcm = hdac_hdmi_get_pcm(hdev, port);
 
 	if (!port->eld.monitor_present || !port->eld.eld_valid) {
-		dev_err(&hdev->dev, "%s: disconnect for pin:port %d:%d\n",
-						__func__, pin->nid, port->id);
+		dev_info(&hdev->dev, "%s: disconnect for pin:port %d:%d\n",
+			 __func__, pin->nid, port->id);
 		hdac_hdmi_jack_report(port, false);
 		mutex_unlock(&hdmi->pin_mutex);
 		return;
@@ -1281,6 +1281,7 @@ static int hdac_hdmi_add_ports(struct hdac_device *hdev,
 	}
 	pin->ports = ports;
 	pin->num_ports = max_ports;
+
 	return 0;
 }
 
@@ -1544,7 +1545,7 @@ static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)
 	}
 
 	dev_dbg(&hdev->dev, "%s: for pin:%d port=%d\n", __func__,
-							pin_nid, pipe);
+		pin_nid, pipe);
 
 	/*
 	 * skip notification during system suspend (but not in runtime PM);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks
  2019-05-27  9:07 ` [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks libin.yang
@ 2019-05-30  7:13   ` Takashi Iwai
  2019-05-30 15:00     ` Yang, Libin
  0 siblings, 1 reply; 15+ messages in thread
From: Takashi Iwai @ 2019-05-30  7:13 UTC (permalink / raw)
  To: libin.yang; +Cc: alsa-devel, broonie, pierre-louis.bossart

On Mon, 27 May 2019 11:07:26 +0200,
libin.yang@intel.com wrote:
> 
> From: Libin Yang <libin.yang@intel.com>
> 
> This patch does the following actions:
> 1) move snd_soc_card_jack_new() from machine driver to codec driver.
>    This is because the jack information is more lated to the codec
>    Also this patch calls snd_jack_add_new_kctl() to export the jack kctl
>    to userspace.
> 
> 2) jack is bound to pcm in origal code. The patch binds jack to pin-port.
>    This mean each pin-port (3x3) has a jack. pin-port is used for DP-MST
>    mode. The port means device entry for DP-MST in hdac_hdmi
>    As hdac_hdmi allows user to map the pin-port to a pcm manually, the jack
>    is bound to pcm is not accurate.
>    However, PA assumes jack is bound to PCM for the legacy mode.
>    For example, for ubuntu, in
>    /usr/share/pulseaudio/alsa-mixer/paths/hdmi-output-x.conf uses
>    "Jack HDMI/DP,pcm=n" to find which jack event is used.
>    This main issue is: pcm number is fixed (3, 7, 8, 9, 10) for hdmi in
>    legacy mode. But it is not always the same for ASoC hdmi audio.

The question is what brings this change practically.  On the legacy
driver, as the jack is bound with the PCM, user-space (typically PA)
who receives a jack connection event opens simply the corresponding
PCM substream.  Now, for ASoC:
  1. Which PCM substream?
  2. How to set up the routing?

I assume the 1 doens't matter, any substream, unlike the legacy case.
But how is 2 done automatically?


thanks,

Takashi

> 
> Signed-off-by: Libin Yang <libin.yang@intel.com>
> ---
>  sound/soc/codecs/hdac_hdmi.c                       | 127 ++++++++++++---------
>  sound/soc/intel/boards/bxt_da7219_max98357a.c      |  10 --
>  sound/soc/intel/boards/bxt_rt298.c                 |  10 --
>  sound/soc/intel/boards/glk_rt5682_max98357a.c      |  10 --
>  sound/soc/intel/boards/kbl_da7219_max98357a.c      |  10 --
>  sound/soc/intel/boards/kbl_da7219_max98927.c       |  10 --
>  sound/soc/intel/boards/kbl_rt5660.c                |  10 --
>  sound/soc/intel/boards/kbl_rt5663_max98927.c       |  10 --
>  .../soc/intel/boards/kbl_rt5663_rt5514_max98927.c  |   9 --
>  sound/soc/intel/boards/skl_hda_dsp_common.c        |   9 --
>  sound/soc/intel/boards/skl_nau88l25_max98357a.c    |  11 --
>  sound/soc/intel/boards/skl_nau88l25_ssm4567.c      |  11 --
>  sound/soc/intel/boards/skl_rt286.c                 |  10 --
>  sound/soc/intel/boards/sof_rt5682.c                |  11 --
>  14 files changed, 74 insertions(+), 184 deletions(-)
> 
> diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c
> index 90c2ee3..ed267fa 100644
> --- a/sound/soc/codecs/hdac_hdmi.c
> +++ b/sound/soc/codecs/hdac_hdmi.c
> @@ -4,6 +4,7 @@
>   *  Copyright (C) 2014-2015 Intel Corp
>   *  Author: Samreen Nilofer <samreen.nilofer@intel.com>
>   *	    Subhransu S. Prusty <subhransu.s.prusty@intel.com>
> + *	    Libin Yang <libin.yang@intel.com>
>   *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>   *
>   *  This program is free software; you can redistribute it and/or modify
> @@ -30,6 +31,7 @@
>  #include <sound/hda_i915.h>
>  #include <sound/pcm_drm_eld.h>
>  #include <sound/hda_chmap.h>
> +#include <sound/hda_codec.h>
>  #include "../../hda/local.h"
>  #include "hdac_hdmi.h"
>  
> @@ -95,6 +97,8 @@ struct hdac_hdmi_port {
>  	int num_mux_nids;
>  	hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
>  	struct hdac_hdmi_eld eld;
> +	struct snd_soc_jack jack;
> +	int jack_event;
>  	const char *jack_pin;
>  	struct snd_soc_dapm_context *dapm;
>  	const char *output_pin;
> @@ -105,14 +109,12 @@ struct hdac_hdmi_pcm {
>  	int pcm_id;
>  	struct list_head port_list;
>  	struct hdac_hdmi_cvt *cvt;
> -	struct snd_soc_jack *jack;
>  	int stream_tag;
>  	int channels;
>  	int format;
>  	bool chmap_set;
>  	unsigned char chmap[8]; /* ALSA API channel-map */
>  	struct mutex lock;
> -	int jack_event;
>  };
>  
>  struct hdac_hdmi_dai_port_map {
> @@ -166,8 +168,7 @@ hdac_hdmi_get_pcm_from_cvt(struct hdac_hdmi_priv *hdmi,
>  	return pcm;
>  }
>  
> -static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
> -		struct hdac_hdmi_port *port, bool is_connect)
> +static void hdac_hdmi_jack_report(struct hdac_hdmi_port *port, bool is_connect)
>  {
>  	struct hdac_device *hdev = port->pin->hdev;
>  
> @@ -176,19 +177,25 @@ static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
>  	else
>  		snd_soc_dapm_disable_pin(port->dapm, port->jack_pin);
>  
> +	/* if jack is not ready, skip reporting jack status */
> +	if (!port->jack.jack) {
> +		snd_soc_dapm_sync(port->dapm);
> +		return;
> +	}
> +
>  	if (is_connect) {
> -		if (pcm->jack_event == 0) {
> +		if (port->jack_event == 0) {
>  			dev_dbg(&hdev->dev,
> -					"jack report for pcm=%d\n",
> -					pcm->pcm_id);
> -			snd_soc_jack_report(pcm->jack, SND_JACK_AVOUT,
> -						SND_JACK_AVOUT);
> +				"jack report for pin:port = %d:%d\n",
> +				port->id, port->pin->nid);
> +			snd_soc_jack_report(&port->jack, SND_JACK_AVOUT,
> +					    SND_JACK_AVOUT);
>  		}
> -		pcm->jack_event = 1;
> +		port->jack_event = 1;
>  	} else {
> -		if (pcm->jack_event == 1)
> -			snd_soc_jack_report(pcm->jack, 0, SND_JACK_AVOUT);
> -		pcm->jack_event = 0;
> +		if (port->jack_event == 1)
> +			snd_soc_jack_report(&port->jack, 0, SND_JACK_AVOUT);
> +		port->jack_event = 0;
>  	}
>  
>  	snd_soc_dapm_sync(port->dapm);
> @@ -1235,26 +1242,15 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin,
>  	pcm = hdac_hdmi_get_pcm(hdev, port);
>  
>  	if (!port->eld.monitor_present || !port->eld.eld_valid) {
> -
>  		dev_err(&hdev->dev, "%s: disconnect for pin:port %d:%d\n",
>  						__func__, pin->nid, port->id);
> -
> -		/*
> -		 * PCMs are not registered during device probe, so don't
> -		 * report jack here. It will be done in usermode mux
> -		 * control select.
> -		 */
> -		if (pcm)
> -			hdac_hdmi_jack_report(pcm, port, false);
> -
> +		hdac_hdmi_jack_report(port, false);
>  		mutex_unlock(&hdmi->pin_mutex);
>  		return;
>  	}
>  
>  	if (port->eld.monitor_present && port->eld.eld_valid) {
> -		if (pcm)
> -			hdac_hdmi_jack_report(pcm, port, true);
> -
> +		hdac_hdmi_jack_report(port, true);
>  		print_hex_dump_debug("ELD: ", DUMP_PREFIX_OFFSET, 16, 1,
>  			  port->eld.eld_buffer, port->eld.eld_size, false);
>  
> @@ -1650,6 +1646,30 @@ static int create_fill_jack_kcontrols(struct snd_soc_card *card,
>  	return snd_soc_add_card_controls(card, kc, i);
>  }
>  
> +static void hdac_hdmi_present_sense_all_pins(struct hdac_device *hdev,
> +			struct hdac_hdmi_priv *hdmi, bool detect_pin_caps)
> +{
> +	int i;
> +	struct hdac_hdmi_pin *pin;
> +
> +	list_for_each_entry(pin, &hdmi->pin_list, head) {
> +		if (detect_pin_caps) {
> +
> +			if (hdac_hdmi_get_port_len(hdev, pin->nid)  == 0)
> +				pin->mst_capable = false;
> +			else
> +				pin->mst_capable = true;
> +		}
> +
> +		for (i = 0; i < pin->num_ports; i++) {
> +			if (!pin->mst_capable && i > 0)
> +				continue;
> +
> +			hdac_hdmi_present_sense(pin, &pin->ports[i]);
> +		}
> +	}
> +}
> +
>  int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
>  			struct snd_soc_dapm_context *dapm)
>  {
> @@ -1659,6 +1679,7 @@ int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
>  	struct snd_soc_dapm_widget *widgets;
>  	struct snd_soc_dapm_route *route;
>  	char w_name[NAME_SIZE];
> +	char jack_name[NAME_SIZE];
>  	int i = 0, j, ret;
>  
>  	widgets = devm_kcalloc(dapm->dev, hdmi->num_ports,
> @@ -1687,6 +1708,30 @@ int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
>  			pin->ports[j].jack_pin = widgets[i].name;
>  			pin->ports[j].dapm = dapm;
>  
> +			/*
> +			 * Create pin-port jack. Each port (device entry) of
> +			 * the pin has a corresponding jack
> +			 */
> +			snprintf(jack_name, sizeof(jack_name),
> +				 "HDMI/DP, pin:port=%d:%d Jack",
> +				  pin->nid, pin->ports[j].id);
> +			ret = snd_soc_card_jack_new(dapm->card, jack_name,
> +						    SND_JACK_AVOUT,
> +						    &(pin->ports[j].jack),
> +						    NULL, 0);
> +			if (ret)
> +				return ret;
> +
> +			/* create the jack kctl */
> +			ret = snd_jack_add_new_kctl(pin->ports[j].jack.jack,
> +						    jack_name, SND_JACK_AVOUT);
> +			/*
> +			 * It's not a critical issue if driver fails to
> +			 * create jack kctl.
> +			 */
> +			if (ret)
> +				dev_warn(&hdev->dev, "failed creating Jack kctl\n");
> +
>  			/* add to route from Jack widget to output */
>  			hdac_hdmi_fill_route(&route[i], pin->ports[j].jack_pin,
>  					NULL, pin->ports[j].output_pin, NULL);
> @@ -1695,6 +1740,9 @@ int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
>  		}
>  	}
>  
> +	/* now jack is ready, let's update the status */
> +	hdac_hdmi_present_sense_all_pins(hdev, hdmi, true);
> +
>  	/* Add Route from Jack widget to the output widget */
>  	ret = snd_soc_dapm_new_controls(dapm, widgets, hdmi->num_ports);
>  	if (ret < 0)
> @@ -1744,8 +1792,6 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device,
>  		return -ENOMEM;
>  	pcm->pcm_id = device;
>  	pcm->cvt = hdmi->dai_map[dai->id].cvt;
> -	pcm->jack_event = 0;
> -	pcm->jack = jack;
>  	mutex_init(&pcm->lock);
>  	INIT_LIST_HEAD(&pcm->port_list);
>  	snd_pcm = hdac_hdmi_get_pcm_from_id(dai->component->card, device);
> @@ -1765,30 +1811,6 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device,
>  }
>  EXPORT_SYMBOL_GPL(hdac_hdmi_jack_init);
>  
> -static void hdac_hdmi_present_sense_all_pins(struct hdac_device *hdev,
> -			struct hdac_hdmi_priv *hdmi, bool detect_pin_caps)
> -{
> -	int i;
> -	struct hdac_hdmi_pin *pin;
> -
> -	list_for_each_entry(pin, &hdmi->pin_list, head) {
> -		if (detect_pin_caps) {
> -
> -			if (hdac_hdmi_get_port_len(hdev, pin->nid)  == 0)
> -				pin->mst_capable = false;
> -			else
> -				pin->mst_capable = true;
> -		}
> -
> -		for (i = 0; i < pin->num_ports; i++) {
> -			if (!pin->mst_capable && i > 0)
> -				continue;
> -
> -			hdac_hdmi_present_sense(pin, &pin->ports[i]);
> -		}
> -	}
> -}
> -
>  static int hdmi_codec_probe(struct snd_soc_component *component)
>  {
>  	struct hdac_hdmi_priv *hdmi = snd_soc_component_get_drvdata(component);
> @@ -1823,7 +1845,6 @@ static int hdmi_codec_probe(struct snd_soc_component *component)
>  		return ret;
>  	}
>  
> -	hdac_hdmi_present_sense_all_pins(hdev, hdmi, true);
>  	/* Imp: Store the card pointer in hda_codec */
>  	hdmi->card = dapm->card->snd_card;
>  
> diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c
> index 5cadb7f..c69cfa9 100644
> --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c
> +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
> @@ -573,14 +573,12 @@ static const struct x86_cpu_id glk_ids[] = {
>  	{}
>  };
>  
> -#define NAME_SIZE	32
>  static int bxt_card_late_probe(struct snd_soc_card *card)
>  {
>  	struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card);
>  	struct bxt_hdmi_pcm *pcm;
>  	struct snd_soc_component *component = NULL;
>  	int err, i = 0;
> -	char jack_name[NAME_SIZE];
>  
>  	if (x86_match_cpu(glk_ids))
>  		snd_soc_dapm_add_routes(&card->dapm, gemini_map,
> @@ -591,14 +589,6 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
>  
>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>  		component = pcm->codec_dai->component;
> -		snprintf(jack_name, sizeof(jack_name),
> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> -		err = snd_soc_card_jack_new(card, jack_name,
> -					SND_JACK_AVOUT, &broxton_hdmi[i],
> -					NULL, 0);
> -
> -		if (err)
> -			return err;
>  
>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>  						&broxton_hdmi[i]);
> diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c
> index e91057f..d1372891 100644
> --- a/sound/soc/intel/boards/bxt_rt298.c
> +++ b/sound/soc/intel/boards/bxt_rt298.c
> @@ -507,25 +507,15 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
>  	},
>  };
>  
> -#define NAME_SIZE	32
>  static int bxt_card_late_probe(struct snd_soc_card *card)
>  {
>  	struct bxt_rt286_private *ctx = snd_soc_card_get_drvdata(card);
>  	struct bxt_hdmi_pcm *pcm;
>  	struct snd_soc_component *component = NULL;
>  	int err, i = 0;
> -	char jack_name[NAME_SIZE];
>  
>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>  		component = pcm->codec_dai->component;
> -		snprintf(jack_name, sizeof(jack_name),
> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> -		err = snd_soc_card_jack_new(card, jack_name,
> -					SND_JACK_AVOUT, &broxton_hdmi[i],
> -					NULL, 0);
> -
> -		if (err)
> -			return err;
>  
>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>  						&broxton_hdmi[i]);
> diff --git a/sound/soc/intel/boards/glk_rt5682_max98357a.c b/sound/soc/intel/boards/glk_rt5682_max98357a.c
> index d17126f..2a35974 100644
> --- a/sound/soc/intel/boards/glk_rt5682_max98357a.c
> +++ b/sound/soc/intel/boards/glk_rt5682_max98357a.c
> @@ -29,7 +29,6 @@
>  #define MAXIM_DEV0_NAME "MX98357A:00"
>  #define DUAL_CHANNEL 2
>  #define QUAD_CHANNEL 4
> -#define NAME_SIZE 32
>  
>  static struct snd_soc_jack geminilake_hdmi[3];
>  
> @@ -523,21 +522,12 @@ static int glk_card_late_probe(struct snd_soc_card *card)
>  {
>  	struct glk_card_private *ctx = snd_soc_card_get_drvdata(card);
>  	struct snd_soc_component *component = NULL;
> -	char jack_name[NAME_SIZE];
>  	struct glk_hdmi_pcm *pcm;
>  	int err = 0;
>  	int i = 0;
>  
>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>  		component = pcm->codec_dai->component;
> -		snprintf(jack_name, sizeof(jack_name),
> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> -		err = snd_soc_card_jack_new(card, jack_name,
> -					SND_JACK_AVOUT, &geminilake_hdmi[i],
> -					NULL, 0);
> -
> -		if (err)
> -			return err;
>  
>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>  						&geminilake_hdmi[i]);
> diff --git a/sound/soc/intel/boards/kbl_da7219_max98357a.c b/sound/soc/intel/boards/kbl_da7219_max98357a.c
> index 07491a0..f293307 100644
> --- a/sound/soc/intel/boards/kbl_da7219_max98357a.c
> +++ b/sound/soc/intel/boards/kbl_da7219_max98357a.c
> @@ -519,25 +519,15 @@ static struct snd_soc_dai_link kabylake_dais[] = {
>  	},
>  };
>  
> -#define NAME_SIZE	32
>  static int kabylake_card_late_probe(struct snd_soc_card *card)
>  {
>  	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
>  	struct kbl_hdmi_pcm *pcm;
>  	struct snd_soc_component *component = NULL;
>  	int err, i = 0;
> -	char jack_name[NAME_SIZE];
>  
>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>  		component = pcm->codec_dai->component;
> -		snprintf(jack_name, sizeof(jack_name),
> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> -		err = snd_soc_card_jack_new(card, jack_name,
> -					SND_JACK_AVOUT, &skylake_hdmi[i],
> -					NULL, 0);
> -
> -		if (err)
> -			return err;
>  
>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>  				&skylake_hdmi[i]);
> diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c b/sound/soc/intel/boards/kbl_da7219_max98927.c
> index f72a7bf..84d3609 100644
> --- a/sound/soc/intel/boards/kbl_da7219_max98927.c
> +++ b/sound/soc/intel/boards/kbl_da7219_max98927.c
> @@ -34,7 +34,6 @@
>  
>  #define DUAL_CHANNEL	2
>  #define QUAD_CHANNEL	4
> -#define NAME_SIZE	32
>  
>  static struct snd_soc_card *kabylake_audio_card;
>  static struct snd_soc_jack kabylake_hdmi[3];
> @@ -952,18 +951,9 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
>  	struct kbl_hdmi_pcm *pcm;
>  	struct snd_soc_component *component = NULL;
>  	int err, i = 0;
> -	char jack_name[NAME_SIZE];
>  
>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>  		component = pcm->codec_dai->component;
> -		snprintf(jack_name, sizeof(jack_name),
> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> -		err = snd_soc_card_jack_new(card, jack_name,
> -					SND_JACK_AVOUT, &kabylake_hdmi[i],
> -					NULL, 0);
> -
> -		if (err)
> -			return err;
>  
>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>  						&kabylake_hdmi[i]);
> diff --git a/sound/soc/intel/boards/kbl_rt5660.c b/sound/soc/intel/boards/kbl_rt5660.c
> index 3255e00..06411bf 100644
> --- a/sound/soc/intel/boards/kbl_rt5660.c
> +++ b/sound/soc/intel/boards/kbl_rt5660.c
> @@ -447,25 +447,15 @@ static struct snd_soc_dai_link kabylake_rt5660_dais[] = {
>  };
>  
>  
> -#define NAME_SIZE	32
>  static int kabylake_card_late_probe(struct snd_soc_card *card)
>  {
>  	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
>  	struct kbl_hdmi_pcm *pcm;
>  	struct snd_soc_component *component = NULL;
>  	int err, i = 0;
> -	char jack_name[NAME_SIZE];
>  
>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>  		component = pcm->codec_dai->component;
> -		snprintf(jack_name, sizeof(jack_name),
> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> -		err = snd_soc_card_jack_new(card, jack_name,
> -					SND_JACK_AVOUT, &skylake_hdmi[i],
> -					NULL, 0);
> -
> -		if (err)
> -			return err;
>  
>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>  				&skylake_hdmi[i]);
> diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c
> index d714752..9c43c6c 100644
> --- a/sound/soc/intel/boards/kbl_rt5663_max98927.c
> +++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c
> @@ -898,25 +898,15 @@ static struct snd_soc_dai_link kabylake_5663_dais[] = {
>  	},
>  };
>  
> -#define NAME_SIZE	32
>  static int kabylake_card_late_probe(struct snd_soc_card *card)
>  {
>  	struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(card);
>  	struct kbl_hdmi_pcm *pcm;
>  	struct snd_soc_component *component = NULL;
>  	int err, i = 0;
> -	char jack_name[NAME_SIZE];
>  
>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>  		component = pcm->codec_dai->component;
> -		snprintf(jack_name, sizeof(jack_name),
> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> -		err = snd_soc_card_jack_new(card, jack_name,
> -					SND_JACK_AVOUT, &skylake_hdmi[i],
> -					NULL, 0);
> -
> -		if (err)
> -			return err;
>  
>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>  						&skylake_hdmi[i]);
> diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
> index 879f142..8fe4007 100644
> --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
> +++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
> @@ -40,7 +40,6 @@
>  #define RT5663_DEV_NAME "i2c-10EC5663:00"
>  #define RT5514_AIF1_BCLK_FREQ (48000 * 8 * 16)
>  #define RT5514_AIF1_SYSCLK_FREQ 12288000
> -#define NAME_SIZE 32
>  
>  #define DMIC_CH(p) p->list[p->count-1]
>  
> @@ -600,18 +599,10 @@ static int kabylake_card_late_probe(struct snd_soc_card *card)
>  	struct kbl_hdmi_pcm *pcm;
>  	struct snd_soc_component *component = NULL;
>  	int err, i = 0;
> -	char jack_name[NAME_SIZE];
>  
>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>  		component = pcm->codec_dai->component;
> -		snprintf(jack_name, sizeof(jack_name),
> -			"HDMI/DP,pcm=%d Jack", pcm->device);
> -		err = snd_soc_card_jack_new(card, jack_name,
> -				SND_JACK_AVOUT, &ctx->kabylake_hdmi[i],
> -				NULL, 0);
>  
> -		if (err)
> -			return err;
>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>  						&ctx->kabylake_hdmi[i]);
>  		if (err < 0)
> diff --git a/sound/soc/intel/boards/skl_hda_dsp_common.c b/sound/soc/intel/boards/skl_hda_dsp_common.c
> index 8b68f41..0f57fc2 100644
> --- a/sound/soc/intel/boards/skl_hda_dsp_common.c
> +++ b/sound/soc/intel/boards/skl_hda_dsp_common.c
> @@ -118,19 +118,10 @@ int skl_hda_hdmi_jack_init(struct snd_soc_card *card)
>  	struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card);
>  	struct snd_soc_component *component = NULL;
>  	struct skl_hda_hdmi_pcm *pcm;
> -	char jack_name[NAME_SIZE];
>  	int err;
>  
>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>  		component = pcm->codec_dai->component;
> -		snprintf(jack_name, sizeof(jack_name),
> -			 "HDMI/DP, pcm=%d Jack", pcm->device);
> -		err = snd_soc_card_jack_new(card, jack_name,
> -					    SND_JACK_AVOUT, &pcm->hdmi_jack,
> -					    NULL, 0);
> -
> -		if (err)
> -			return err;
>  
>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>  					  &pcm->hdmi_jack);
> diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
> index 0922106..aca426f 100644
> --- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
> +++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
> @@ -587,26 +587,15 @@ static struct snd_soc_dai_link skylake_dais[] = {
>  	},
>  };
>  
> -#define NAME_SIZE	32
>  static int skylake_card_late_probe(struct snd_soc_card *card)
>  {
>  	struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(card);
>  	struct skl_hdmi_pcm *pcm;
>  	struct snd_soc_component *component = NULL;
>  	int err, i = 0;
> -	char jack_name[NAME_SIZE];
>  
>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>  		component = pcm->codec_dai->component;
> -		snprintf(jack_name, sizeof(jack_name),
> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> -		err = snd_soc_card_jack_new(card, jack_name,
> -					SND_JACK_AVOUT,
> -					&skylake_hdmi[i],
> -					NULL, 0);
> -
> -		if (err)
> -			return err;
>  
>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>  						&skylake_hdmi[i]);
> diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
> index 8433c52..788a837 100644
> --- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
> +++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
> @@ -638,26 +638,15 @@ static struct snd_soc_dai_link skylake_dais[] = {
>  	},
>  };
>  
> -#define NAME_SIZE	32
>  static int skylake_card_late_probe(struct snd_soc_card *card)
>  {
>  	struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(card);
>  	struct skl_hdmi_pcm *pcm;
>  	struct snd_soc_component *component = NULL;
>  	int err, i = 0;
> -	char jack_name[NAME_SIZE];
>  
>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>  		component = pcm->codec_dai->component;
> -		snprintf(jack_name, sizeof(jack_name),
> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> -		err = snd_soc_card_jack_new(card, jack_name,
> -					SND_JACK_AVOUT,
> -					&skylake_hdmi[i],
> -					NULL, 0);
> -
> -		if (err)
> -			return err;
>  
>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>  						&skylake_hdmi[i]);
> diff --git a/sound/soc/intel/boards/skl_rt286.c b/sound/soc/intel/boards/skl_rt286.c
> index 0e1818d..5d245f5 100644
> --- a/sound/soc/intel/boards/skl_rt286.c
> +++ b/sound/soc/intel/boards/skl_rt286.c
> @@ -473,25 +473,15 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
>  	},
>  };
>  
> -#define NAME_SIZE	32
>  static int skylake_card_late_probe(struct snd_soc_card *card)
>  {
>  	struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(card);
>  	struct skl_hdmi_pcm *pcm;
>  	struct snd_soc_component *component = NULL;
>  	int err, i = 0;
> -	char jack_name[NAME_SIZE];
>  
>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>  		component = pcm->codec_dai->component;
> -		snprintf(jack_name, sizeof(jack_name),
> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> -		err = snd_soc_card_jack_new(card, jack_name,
> -					SND_JACK_AVOUT, &skylake_hdmi[i],
> -					NULL, 0);
> -
> -		if (err)
> -			return err;
>  
>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>  						&skylake_hdmi[i]);
> diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c
> index f28fb98..660e4a6 100644
> --- a/sound/soc/intel/boards/sof_rt5682.c
> +++ b/sound/soc/intel/boards/sof_rt5682.c
> @@ -22,8 +22,6 @@
>  #include "../../codecs/rt5682.h"
>  #include "../../codecs/hdac_hdmi.h"
>  
> -#define NAME_SIZE 32
> -
>  #define SOF_RT5682_SSP_CODEC(quirk)		((quirk) & GENMASK(2, 0))
>  #define SOF_RT5682_SSP_CODEC_MASK			(GENMASK(2, 0))
>  #define SOF_RT5682_MCLK_EN			BIT(3)
> @@ -216,7 +214,6 @@ static int sof_card_late_probe(struct snd_soc_card *card)
>  {
>  	struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
>  	struct snd_soc_component *component = NULL;
> -	char jack_name[NAME_SIZE];
>  	struct sof_hdmi_pcm *pcm;
>  	int err = 0;
>  	int i = 0;
> @@ -227,14 +224,6 @@ static int sof_card_late_probe(struct snd_soc_card *card)
>  
>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>  		component = pcm->codec_dai->component;
> -		snprintf(jack_name, sizeof(jack_name),
> -			 "HDMI/DP, pcm=%d Jack", pcm->device);
> -		err = snd_soc_card_jack_new(card, jack_name,
> -					    SND_JACK_AVOUT, &sof_hdmi[i],
> -					    NULL, 0);
> -
> -		if (err)
> -			return err;
>  
>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>  					  &sof_hdmi[i]);
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks
  2019-05-30  7:13   ` Takashi Iwai
@ 2019-05-30 15:00     ` Yang, Libin
  2019-05-30 15:22       ` Takashi Iwai
  0 siblings, 1 reply; 15+ messages in thread
From: Yang, Libin @ 2019-05-30 15:00 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, broonie, pierre-louis.bossart

Hi Takashi,

>-----Original Message-----
>From: Takashi Iwai [mailto:tiwai@suse.de]
>Sent: Thursday, May 30, 2019 3:13 PM
>To: Yang, Libin <libin.yang@intel.com>
>Cc: alsa-devel@alsa-project.org; broonie@kernel.org; pierre-
>louis.bossart@linux.intel.com
>Subject: Re: [alsa-devel] [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks
>
>On Mon, 27 May 2019 11:07:26 +0200,
>libin.yang@intel.com wrote:
>>
>> From: Libin Yang <libin.yang@intel.com>
>>
>> This patch does the following actions:
>> 1) move snd_soc_card_jack_new() from machine driver to codec driver.
>>    This is because the jack information is more lated to the codec
>>    Also this patch calls snd_jack_add_new_kctl() to export the jack kctl
>>    to userspace.
>>
>> 2) jack is bound to pcm in origal code. The patch binds jack to pin-port.
>>    This mean each pin-port (3x3) has a jack. pin-port is used for DP-MST
>>    mode. The port means device entry for DP-MST in hdac_hdmi
>>    As hdac_hdmi allows user to map the pin-port to a pcm manually, the jack
>>    is bound to pcm is not accurate.
>>    However, PA assumes jack is bound to PCM for the legacy mode.
>>    For example, for ubuntu, in
>>    /usr/share/pulseaudio/alsa-mixer/paths/hdmi-output-x.conf uses
>>    "Jack HDMI/DP,pcm=n" to find which jack event is used.
>>    This main issue is: pcm number is fixed (3, 7, 8, 9, 10) for hdmi in
>>    legacy mode. But it is not always the same for ASoC hdmi audio.
>
>The question is what brings this change practically.  On the legacy driver, as
>the jack is bound with the PCM, user-space (typically PA) who receives a jack
>connection event opens simply the corresponding PCM substream.  Now, for
>ASoC:
>  1. Which PCM substream?
>  2. How to set up the routing?
>
>I assume the 1 doens't matter, any substream, unlike the legacy case.
>But how is 2 done automatically?

For the legacy HDA, there are 2 mode (dynamic pcm assignment (DPMST) and 
static pcm assignment (NON-DPMST)).
1) For static pcm assignment, pcm is always statically mapped to pin. 
For example, pcm1 <=> pin 1; pcm <=> pin 2 and so on. So it is the same
to bind jack to pcm or to pin.
2) For dynamic pcm assignment, in generic_hdmi_build_jack(), the jack
is bound to PCM when it is created (spec->pcm_rec[pcm_idx].jack). We will
find the jack by pcm_idx. And when monitor is connected to a pin, 
update_eld() will be called. In update_eld(), it will call 
hdmi_attach_hda_pcm() to find a pcm to bind to the pin. So it can find a 
jack (from the pcm) and report its status to userspace.

So in a word for legacy HDA, it can always find a PCM (no matter in static 
mode or in dynamic mode) when the monitor is connected to a pin. This
means it can always update the status of to userspace that the pcm 
status is changed.

However, in hdac_hdmi, there is no such dynamic pcm assignment. And it
is not statically assignment of pcm to pin. PCM is statically bound to cvt.
hdac_hdmi allows user to assign a cvt to a pin with alsamixer ( in function
hdac_hdmi_set_pin_port_mux(), so this function maps the pin to the pcm).
As user may assign NONE pcm to a pin in alsamixer, this means a pin can
be assigned none of pcms. So if we mapped jack to pcm, we may not find 
any jack for the pin when a monitor is connected to the pin. This means
driver can't notify userspace of the monitor connection.
As you know, PA will use the monitor connection status to decide whether
to user it or not. So this is the problem. The root cause is pcm is bound to
cvt. And pin may be not bound to any pcm (This is the difference from the
legacy hda).

In my patch, as jack is bound to pin-port, so it can always notify userspace
that a monitor is connected. We can use configuration in /usr/share/alsa/
ucm or /usr/share/pulseaudio to configure the amixer to assign a pcm
to the pin (monitor). And userspace can playback on the monitor now.

Regards,
Libin

>
>
>thanks,
>
>Takashi
>
>>
>> Signed-off-by: Libin Yang <libin.yang@intel.com>
>> ---
>>  sound/soc/codecs/hdac_hdmi.c                       | 127 ++++++++++++---------
>>  sound/soc/intel/boards/bxt_da7219_max98357a.c      |  10 --
>>  sound/soc/intel/boards/bxt_rt298.c                 |  10 --
>>  sound/soc/intel/boards/glk_rt5682_max98357a.c      |  10 --
>>  sound/soc/intel/boards/kbl_da7219_max98357a.c      |  10 --
>>  sound/soc/intel/boards/kbl_da7219_max98927.c       |  10 --
>>  sound/soc/intel/boards/kbl_rt5660.c                |  10 --
>>  sound/soc/intel/boards/kbl_rt5663_max98927.c       |  10 --
>>  .../soc/intel/boards/kbl_rt5663_rt5514_max98927.c  |   9 --
>>  sound/soc/intel/boards/skl_hda_dsp_common.c        |   9 --
>>  sound/soc/intel/boards/skl_nau88l25_max98357a.c    |  11 --
>>  sound/soc/intel/boards/skl_nau88l25_ssm4567.c      |  11 --
>>  sound/soc/intel/boards/skl_rt286.c                 |  10 --
>>  sound/soc/intel/boards/sof_rt5682.c                |  11 --
>>  14 files changed, 74 insertions(+), 184 deletions(-)
>>
>> diff --git a/sound/soc/codecs/hdac_hdmi.c
>> b/sound/soc/codecs/hdac_hdmi.c index 90c2ee3..ed267fa 100644
>> --- a/sound/soc/codecs/hdac_hdmi.c
>> +++ b/sound/soc/codecs/hdac_hdmi.c
>> @@ -4,6 +4,7 @@
>>   *  Copyright (C) 2014-2015 Intel Corp
>>   *  Author: Samreen Nilofer <samreen.nilofer@intel.com>
>>   *	    Subhransu S. Prusty <subhransu.s.prusty@intel.com>
>> + *	    Libin Yang <libin.yang@intel.com>
>>   *
>~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>~~~~~~~~~
>>   *
>>   *  This program is free software; you can redistribute it and/or
>> modify @@ -30,6 +31,7 @@  #include <sound/hda_i915.h>  #include
>> <sound/pcm_drm_eld.h>  #include <sound/hda_chmap.h>
>> +#include <sound/hda_codec.h>
>>  #include "../../hda/local.h"
>>  #include "hdac_hdmi.h"
>>
>> @@ -95,6 +97,8 @@ struct hdac_hdmi_port {
>>  	int num_mux_nids;
>>  	hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
>>  	struct hdac_hdmi_eld eld;
>> +	struct snd_soc_jack jack;
>> +	int jack_event;
>>  	const char *jack_pin;
>>  	struct snd_soc_dapm_context *dapm;
>>  	const char *output_pin;
>> @@ -105,14 +109,12 @@ struct hdac_hdmi_pcm {
>>  	int pcm_id;
>>  	struct list_head port_list;
>>  	struct hdac_hdmi_cvt *cvt;
>> -	struct snd_soc_jack *jack;
>>  	int stream_tag;
>>  	int channels;
>>  	int format;
>>  	bool chmap_set;
>>  	unsigned char chmap[8]; /* ALSA API channel-map */
>>  	struct mutex lock;
>> -	int jack_event;
>>  };
>>
>>  struct hdac_hdmi_dai_port_map {
>> @@ -166,8 +168,7 @@ hdac_hdmi_get_pcm_from_cvt(struct
>hdac_hdmi_priv *hdmi,
>>  	return pcm;
>>  }
>>
>> -static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
>> -		struct hdac_hdmi_port *port, bool is_connect)
>> +static void hdac_hdmi_jack_report(struct hdac_hdmi_port *port, bool
>> +is_connect)
>>  {
>>  	struct hdac_device *hdev = port->pin->hdev;
>>
>> @@ -176,19 +177,25 @@ static void hdac_hdmi_jack_report(struct
>hdac_hdmi_pcm *pcm,
>>  	else
>>  		snd_soc_dapm_disable_pin(port->dapm, port->jack_pin);
>>
>> +	/* if jack is not ready, skip reporting jack status */
>> +	if (!port->jack.jack) {
>> +		snd_soc_dapm_sync(port->dapm);
>> +		return;
>> +	}
>> +
>>  	if (is_connect) {
>> -		if (pcm->jack_event == 0) {
>> +		if (port->jack_event == 0) {
>>  			dev_dbg(&hdev->dev,
>> -					"jack report for pcm=%d\n",
>> -					pcm->pcm_id);
>> -			snd_soc_jack_report(pcm->jack, SND_JACK_AVOUT,
>> -						SND_JACK_AVOUT);
>> +				"jack report for pin:port = %d:%d\n",
>> +				port->id, port->pin->nid);
>> +			snd_soc_jack_report(&port->jack, SND_JACK_AVOUT,
>> +					    SND_JACK_AVOUT);
>>  		}
>> -		pcm->jack_event = 1;
>> +		port->jack_event = 1;
>>  	} else {
>> -		if (pcm->jack_event == 1)
>> -			snd_soc_jack_report(pcm->jack, 0, SND_JACK_AVOUT);
>> -		pcm->jack_event = 0;
>> +		if (port->jack_event == 1)
>> +			snd_soc_jack_report(&port->jack, 0,
>SND_JACK_AVOUT);
>> +		port->jack_event = 0;
>>  	}
>>
>>  	snd_soc_dapm_sync(port->dapm);
>> @@ -1235,26 +1242,15 @@ static void hdac_hdmi_present_sense(struct
>hdac_hdmi_pin *pin,
>>  	pcm = hdac_hdmi_get_pcm(hdev, port);
>>
>>  	if (!port->eld.monitor_present || !port->eld.eld_valid) {
>> -
>>  		dev_err(&hdev->dev, "%s: disconnect for pin:port %d:%d\n",
>>  						__func__, pin->nid, port->id);
>> -
>> -		/*
>> -		 * PCMs are not registered during device probe, so don't
>> -		 * report jack here. It will be done in usermode mux
>> -		 * control select.
>> -		 */
>> -		if (pcm)
>> -			hdac_hdmi_jack_report(pcm, port, false);
>> -
>> +		hdac_hdmi_jack_report(port, false);
>>  		mutex_unlock(&hdmi->pin_mutex);
>>  		return;
>>  	}
>>
>>  	if (port->eld.monitor_present && port->eld.eld_valid) {
>> -		if (pcm)
>> -			hdac_hdmi_jack_report(pcm, port, true);
>> -
>> +		hdac_hdmi_jack_report(port, true);
>>  		print_hex_dump_debug("ELD: ", DUMP_PREFIX_OFFSET, 16, 1,
>>  			  port->eld.eld_buffer, port->eld.eld_size, false);
>>
>> @@ -1650,6 +1646,30 @@ static int create_fill_jack_kcontrols(struct
>snd_soc_card *card,
>>  	return snd_soc_add_card_controls(card, kc, i);  }
>>
>> +static void hdac_hdmi_present_sense_all_pins(struct hdac_device *hdev,
>> +			struct hdac_hdmi_priv *hdmi, bool detect_pin_caps) {
>> +	int i;
>> +	struct hdac_hdmi_pin *pin;
>> +
>> +	list_for_each_entry(pin, &hdmi->pin_list, head) {
>> +		if (detect_pin_caps) {
>> +
>> +			if (hdac_hdmi_get_port_len(hdev, pin->nid)  == 0)
>> +				pin->mst_capable = false;
>> +			else
>> +				pin->mst_capable = true;
>> +		}
>> +
>> +		for (i = 0; i < pin->num_ports; i++) {
>> +			if (!pin->mst_capable && i > 0)
>> +				continue;
>> +
>> +			hdac_hdmi_present_sense(pin, &pin->ports[i]);
>> +		}
>> +	}
>> +}
>> +
>>  int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
>>  			struct snd_soc_dapm_context *dapm)  { @@ -1659,6
>+1679,7 @@ int
>> hdac_hdmi_jack_port_init(struct snd_soc_component *component,
>>  	struct snd_soc_dapm_widget *widgets;
>>  	struct snd_soc_dapm_route *route;
>>  	char w_name[NAME_SIZE];
>> +	char jack_name[NAME_SIZE];
>>  	int i = 0, j, ret;
>>
>>  	widgets = devm_kcalloc(dapm->dev, hdmi->num_ports, @@ -1687,6
>> +1708,30 @@ int hdac_hdmi_jack_port_init(struct snd_soc_component
>*component,
>>  			pin->ports[j].jack_pin = widgets[i].name;
>>  			pin->ports[j].dapm = dapm;
>>
>> +			/*
>> +			 * Create pin-port jack. Each port (device entry) of
>> +			 * the pin has a corresponding jack
>> +			 */
>> +			snprintf(jack_name, sizeof(jack_name),
>> +				 "HDMI/DP, pin:port=%d:%d Jack",
>> +				  pin->nid, pin->ports[j].id);
>> +			ret = snd_soc_card_jack_new(dapm->card, jack_name,
>> +						    SND_JACK_AVOUT,
>> +						    &(pin->ports[j].jack),
>> +						    NULL, 0);
>> +			if (ret)
>> +				return ret;
>> +
>> +			/* create the jack kctl */
>> +			ret = snd_jack_add_new_kctl(pin->ports[j].jack.jack,
>> +						    jack_name,
>SND_JACK_AVOUT);
>> +			/*
>> +			 * It's not a critical issue if driver fails to
>> +			 * create jack kctl.
>> +			 */
>> +			if (ret)
>> +				dev_warn(&hdev->dev, "failed creating Jack
>kctl\n");
>> +
>>  			/* add to route from Jack widget to output */
>>  			hdac_hdmi_fill_route(&route[i], pin->ports[j].jack_pin,
>>  					NULL, pin->ports[j].output_pin, NULL);
>@@ -1695,6 +1740,9 @@ int
>> hdac_hdmi_jack_port_init(struct snd_soc_component *component,
>>  		}
>>  	}
>>
>> +	/* now jack is ready, let's update the status */
>> +	hdac_hdmi_present_sense_all_pins(hdev, hdmi, true);
>> +
>>  	/* Add Route from Jack widget to the output widget */
>>  	ret = snd_soc_dapm_new_controls(dapm, widgets, hdmi-
>>num_ports);
>>  	if (ret < 0)
>> @@ -1744,8 +1792,6 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai,
>int device,
>>  		return -ENOMEM;
>>  	pcm->pcm_id = device;
>>  	pcm->cvt = hdmi->dai_map[dai->id].cvt;
>> -	pcm->jack_event = 0;
>> -	pcm->jack = jack;
>>  	mutex_init(&pcm->lock);
>>  	INIT_LIST_HEAD(&pcm->port_list);
>>  	snd_pcm = hdac_hdmi_get_pcm_from_id(dai->component->card,
>device);
>> @@ -1765,30 +1811,6 @@ int hdac_hdmi_jack_init(struct snd_soc_dai
>> *dai, int device,  }  EXPORT_SYMBOL_GPL(hdac_hdmi_jack_init);
>>
>> -static void hdac_hdmi_present_sense_all_pins(struct hdac_device *hdev,
>> -			struct hdac_hdmi_priv *hdmi, bool detect_pin_caps)
>> -{
>> -	int i;
>> -	struct hdac_hdmi_pin *pin;
>> -
>> -	list_for_each_entry(pin, &hdmi->pin_list, head) {
>> -		if (detect_pin_caps) {
>> -
>> -			if (hdac_hdmi_get_port_len(hdev, pin->nid)  == 0)
>> -				pin->mst_capable = false;
>> -			else
>> -				pin->mst_capable = true;
>> -		}
>> -
>> -		for (i = 0; i < pin->num_ports; i++) {
>> -			if (!pin->mst_capable && i > 0)
>> -				continue;
>> -
>> -			hdac_hdmi_present_sense(pin, &pin->ports[i]);
>> -		}
>> -	}
>> -}
>> -
>>  static int hdmi_codec_probe(struct snd_soc_component *component)  {
>>  	struct hdac_hdmi_priv *hdmi =
>> snd_soc_component_get_drvdata(component);
>> @@ -1823,7 +1845,6 @@ static int hdmi_codec_probe(struct
>snd_soc_component *component)
>>  		return ret;
>>  	}
>>
>> -	hdac_hdmi_present_sense_all_pins(hdev, hdmi, true);
>>  	/* Imp: Store the card pointer in hda_codec */
>>  	hdmi->card = dapm->card->snd_card;
>>
>> diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c
>> b/sound/soc/intel/boards/bxt_da7219_max98357a.c
>> index 5cadb7f..c69cfa9 100644
>> --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c
>> +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
>> @@ -573,14 +573,12 @@ static const struct x86_cpu_id glk_ids[] = {
>>  	{}
>>  };
>>
>> -#define NAME_SIZE	32
>>  static int bxt_card_late_probe(struct snd_soc_card *card)  {
>>  	struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card);
>>  	struct bxt_hdmi_pcm *pcm;
>>  	struct snd_soc_component *component = NULL;
>>  	int err, i = 0;
>> -	char jack_name[NAME_SIZE];
>>
>>  	if (x86_match_cpu(glk_ids))
>>  		snd_soc_dapm_add_routes(&card->dapm, gemini_map, @@
>-591,14 +589,6
>> @@ static int bxt_card_late_probe(struct snd_soc_card *card)
>>
>>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>  		component = pcm->codec_dai->component;
>> -		snprintf(jack_name, sizeof(jack_name),
>> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> -		err = snd_soc_card_jack_new(card, jack_name,
>> -					SND_JACK_AVOUT, &broxton_hdmi[i],
>> -					NULL, 0);
>> -
>> -		if (err)
>> -			return err;
>>
>>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>  						&broxton_hdmi[i]);
>> diff --git a/sound/soc/intel/boards/bxt_rt298.c
>> b/sound/soc/intel/boards/bxt_rt298.c
>> index e91057f..d1372891 100644
>> --- a/sound/soc/intel/boards/bxt_rt298.c
>> +++ b/sound/soc/intel/boards/bxt_rt298.c
>> @@ -507,25 +507,15 @@ static struct snd_soc_dai_link broxton_rt298_dais[]
>= {
>>  	},
>>  };
>>
>> -#define NAME_SIZE	32
>>  static int bxt_card_late_probe(struct snd_soc_card *card)  {
>>  	struct bxt_rt286_private *ctx = snd_soc_card_get_drvdata(card);
>>  	struct bxt_hdmi_pcm *pcm;
>>  	struct snd_soc_component *component = NULL;
>>  	int err, i = 0;
>> -	char jack_name[NAME_SIZE];
>>
>>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>  		component = pcm->codec_dai->component;
>> -		snprintf(jack_name, sizeof(jack_name),
>> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> -		err = snd_soc_card_jack_new(card, jack_name,
>> -					SND_JACK_AVOUT, &broxton_hdmi[i],
>> -					NULL, 0);
>> -
>> -		if (err)
>> -			return err;
>>
>>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>  						&broxton_hdmi[i]);
>> diff --git a/sound/soc/intel/boards/glk_rt5682_max98357a.c
>> b/sound/soc/intel/boards/glk_rt5682_max98357a.c
>> index d17126f..2a35974 100644
>> --- a/sound/soc/intel/boards/glk_rt5682_max98357a.c
>> +++ b/sound/soc/intel/boards/glk_rt5682_max98357a.c
>> @@ -29,7 +29,6 @@
>>  #define MAXIM_DEV0_NAME "MX98357A:00"
>>  #define DUAL_CHANNEL 2
>>  #define QUAD_CHANNEL 4
>> -#define NAME_SIZE 32
>>
>>  static struct snd_soc_jack geminilake_hdmi[3];
>>
>> @@ -523,21 +522,12 @@ static int glk_card_late_probe(struct
>> snd_soc_card *card)  {
>>  	struct glk_card_private *ctx = snd_soc_card_get_drvdata(card);
>>  	struct snd_soc_component *component = NULL;
>> -	char jack_name[NAME_SIZE];
>>  	struct glk_hdmi_pcm *pcm;
>>  	int err = 0;
>>  	int i = 0;
>>
>>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>  		component = pcm->codec_dai->component;
>> -		snprintf(jack_name, sizeof(jack_name),
>> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> -		err = snd_soc_card_jack_new(card, jack_name,
>> -					SND_JACK_AVOUT,
>&geminilake_hdmi[i],
>> -					NULL, 0);
>> -
>> -		if (err)
>> -			return err;
>>
>>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>  						&geminilake_hdmi[i]);
>> diff --git a/sound/soc/intel/boards/kbl_da7219_max98357a.c
>> b/sound/soc/intel/boards/kbl_da7219_max98357a.c
>> index 07491a0..f293307 100644
>> --- a/sound/soc/intel/boards/kbl_da7219_max98357a.c
>> +++ b/sound/soc/intel/boards/kbl_da7219_max98357a.c
>> @@ -519,25 +519,15 @@ static struct snd_soc_dai_link kabylake_dais[] = {
>>  	},
>>  };
>>
>> -#define NAME_SIZE	32
>>  static int kabylake_card_late_probe(struct snd_soc_card *card)  {
>>  	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
>>  	struct kbl_hdmi_pcm *pcm;
>>  	struct snd_soc_component *component = NULL;
>>  	int err, i = 0;
>> -	char jack_name[NAME_SIZE];
>>
>>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>  		component = pcm->codec_dai->component;
>> -		snprintf(jack_name, sizeof(jack_name),
>> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> -		err = snd_soc_card_jack_new(card, jack_name,
>> -					SND_JACK_AVOUT, &skylake_hdmi[i],
>> -					NULL, 0);
>> -
>> -		if (err)
>> -			return err;
>>
>>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>  				&skylake_hdmi[i]);
>> diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c
>> b/sound/soc/intel/boards/kbl_da7219_max98927.c
>> index f72a7bf..84d3609 100644
>> --- a/sound/soc/intel/boards/kbl_da7219_max98927.c
>> +++ b/sound/soc/intel/boards/kbl_da7219_max98927.c
>> @@ -34,7 +34,6 @@
>>
>>  #define DUAL_CHANNEL	2
>>  #define QUAD_CHANNEL	4
>> -#define NAME_SIZE	32
>>
>>  static struct snd_soc_card *kabylake_audio_card;  static struct
>> snd_soc_jack kabylake_hdmi[3]; @@ -952,18 +951,9 @@ static int
>> kabylake_card_late_probe(struct snd_soc_card *card)
>>  	struct kbl_hdmi_pcm *pcm;
>>  	struct snd_soc_component *component = NULL;
>>  	int err, i = 0;
>> -	char jack_name[NAME_SIZE];
>>
>>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>  		component = pcm->codec_dai->component;
>> -		snprintf(jack_name, sizeof(jack_name),
>> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> -		err = snd_soc_card_jack_new(card, jack_name,
>> -					SND_JACK_AVOUT, &kabylake_hdmi[i],
>> -					NULL, 0);
>> -
>> -		if (err)
>> -			return err;
>>
>>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>  						&kabylake_hdmi[i]);
>> diff --git a/sound/soc/intel/boards/kbl_rt5660.c
>> b/sound/soc/intel/boards/kbl_rt5660.c
>> index 3255e00..06411bf 100644
>> --- a/sound/soc/intel/boards/kbl_rt5660.c
>> +++ b/sound/soc/intel/boards/kbl_rt5660.c
>> @@ -447,25 +447,15 @@ static struct snd_soc_dai_link
>> kabylake_rt5660_dais[] = {  };
>>
>>
>> -#define NAME_SIZE	32
>>  static int kabylake_card_late_probe(struct snd_soc_card *card)  {
>>  	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
>>  	struct kbl_hdmi_pcm *pcm;
>>  	struct snd_soc_component *component = NULL;
>>  	int err, i = 0;
>> -	char jack_name[NAME_SIZE];
>>
>>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>  		component = pcm->codec_dai->component;
>> -		snprintf(jack_name, sizeof(jack_name),
>> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> -		err = snd_soc_card_jack_new(card, jack_name,
>> -					SND_JACK_AVOUT, &skylake_hdmi[i],
>> -					NULL, 0);
>> -
>> -		if (err)
>> -			return err;
>>
>>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>  				&skylake_hdmi[i]);
>> diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c
>> b/sound/soc/intel/boards/kbl_rt5663_max98927.c
>> index d714752..9c43c6c 100644
>> --- a/sound/soc/intel/boards/kbl_rt5663_max98927.c
>> +++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c
>> @@ -898,25 +898,15 @@ static struct snd_soc_dai_link
>kabylake_5663_dais[] = {
>>  	},
>>  };
>>
>> -#define NAME_SIZE	32
>>  static int kabylake_card_late_probe(struct snd_soc_card *card)  {
>>  	struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(card);
>>  	struct kbl_hdmi_pcm *pcm;
>>  	struct snd_soc_component *component = NULL;
>>  	int err, i = 0;
>> -	char jack_name[NAME_SIZE];
>>
>>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>  		component = pcm->codec_dai->component;
>> -		snprintf(jack_name, sizeof(jack_name),
>> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> -		err = snd_soc_card_jack_new(card, jack_name,
>> -					SND_JACK_AVOUT, &skylake_hdmi[i],
>> -					NULL, 0);
>> -
>> -		if (err)
>> -			return err;
>>
>>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>  						&skylake_hdmi[i]);
>> diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
>> b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
>> index 879f142..8fe4007 100644
>> --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
>> +++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
>> @@ -40,7 +40,6 @@
>>  #define RT5663_DEV_NAME "i2c-10EC5663:00"
>>  #define RT5514_AIF1_BCLK_FREQ (48000 * 8 * 16)  #define
>> RT5514_AIF1_SYSCLK_FREQ 12288000 -#define NAME_SIZE 32
>>
>>  #define DMIC_CH(p) p->list[p->count-1]
>>
>> @@ -600,18 +599,10 @@ static int kabylake_card_late_probe(struct
>snd_soc_card *card)
>>  	struct kbl_hdmi_pcm *pcm;
>>  	struct snd_soc_component *component = NULL;
>>  	int err, i = 0;
>> -	char jack_name[NAME_SIZE];
>>
>>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>  		component = pcm->codec_dai->component;
>> -		snprintf(jack_name, sizeof(jack_name),
>> -			"HDMI/DP,pcm=%d Jack", pcm->device);
>> -		err = snd_soc_card_jack_new(card, jack_name,
>> -				SND_JACK_AVOUT, &ctx->kabylake_hdmi[i],
>> -				NULL, 0);
>>
>> -		if (err)
>> -			return err;
>>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>  						&ctx->kabylake_hdmi[i]);
>>  		if (err < 0)
>> diff --git a/sound/soc/intel/boards/skl_hda_dsp_common.c
>> b/sound/soc/intel/boards/skl_hda_dsp_common.c
>> index 8b68f41..0f57fc2 100644
>> --- a/sound/soc/intel/boards/skl_hda_dsp_common.c
>> +++ b/sound/soc/intel/boards/skl_hda_dsp_common.c
>> @@ -118,19 +118,10 @@ int skl_hda_hdmi_jack_init(struct snd_soc_card
>*card)
>>  	struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card);
>>  	struct snd_soc_component *component = NULL;
>>  	struct skl_hda_hdmi_pcm *pcm;
>> -	char jack_name[NAME_SIZE];
>>  	int err;
>>
>>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>  		component = pcm->codec_dai->component;
>> -		snprintf(jack_name, sizeof(jack_name),
>> -			 "HDMI/DP, pcm=%d Jack", pcm->device);
>> -		err = snd_soc_card_jack_new(card, jack_name,
>> -					    SND_JACK_AVOUT, &pcm-
>>hdmi_jack,
>> -					    NULL, 0);
>> -
>> -		if (err)
>> -			return err;
>>
>>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>  					  &pcm->hdmi_jack);
>> diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
>> b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
>> index 0922106..aca426f 100644
>> --- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
>> +++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
>> @@ -587,26 +587,15 @@ static struct snd_soc_dai_link skylake_dais[] = {
>>  	},
>>  };
>>
>> -#define NAME_SIZE	32
>>  static int skylake_card_late_probe(struct snd_soc_card *card)  {
>>  	struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(card);
>>  	struct skl_hdmi_pcm *pcm;
>>  	struct snd_soc_component *component = NULL;
>>  	int err, i = 0;
>> -	char jack_name[NAME_SIZE];
>>
>>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>  		component = pcm->codec_dai->component;
>> -		snprintf(jack_name, sizeof(jack_name),
>> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> -		err = snd_soc_card_jack_new(card, jack_name,
>> -					SND_JACK_AVOUT,
>> -					&skylake_hdmi[i],
>> -					NULL, 0);
>> -
>> -		if (err)
>> -			return err;
>>
>>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>  						&skylake_hdmi[i]);
>> diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
>> b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
>> index 8433c52..788a837 100644
>> --- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
>> +++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
>> @@ -638,26 +638,15 @@ static struct snd_soc_dai_link skylake_dais[] = {
>>  	},
>>  };
>>
>> -#define NAME_SIZE	32
>>  static int skylake_card_late_probe(struct snd_soc_card *card)  {
>>  	struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(card);
>>  	struct skl_hdmi_pcm *pcm;
>>  	struct snd_soc_component *component = NULL;
>>  	int err, i = 0;
>> -	char jack_name[NAME_SIZE];
>>
>>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>  		component = pcm->codec_dai->component;
>> -		snprintf(jack_name, sizeof(jack_name),
>> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> -		err = snd_soc_card_jack_new(card, jack_name,
>> -					SND_JACK_AVOUT,
>> -					&skylake_hdmi[i],
>> -					NULL, 0);
>> -
>> -		if (err)
>> -			return err;
>>
>>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>  						&skylake_hdmi[i]);
>> diff --git a/sound/soc/intel/boards/skl_rt286.c
>> b/sound/soc/intel/boards/skl_rt286.c
>> index 0e1818d..5d245f5 100644
>> --- a/sound/soc/intel/boards/skl_rt286.c
>> +++ b/sound/soc/intel/boards/skl_rt286.c
>> @@ -473,25 +473,15 @@ static struct snd_soc_dai_link skylake_rt286_dais[]
>= {
>>  	},
>>  };
>>
>> -#define NAME_SIZE	32
>>  static int skylake_card_late_probe(struct snd_soc_card *card)  {
>>  	struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(card);
>>  	struct skl_hdmi_pcm *pcm;
>>  	struct snd_soc_component *component = NULL;
>>  	int err, i = 0;
>> -	char jack_name[NAME_SIZE];
>>
>>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>  		component = pcm->codec_dai->component;
>> -		snprintf(jack_name, sizeof(jack_name),
>> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> -		err = snd_soc_card_jack_new(card, jack_name,
>> -					SND_JACK_AVOUT, &skylake_hdmi[i],
>> -					NULL, 0);
>> -
>> -		if (err)
>> -			return err;
>>
>>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>  						&skylake_hdmi[i]);
>> diff --git a/sound/soc/intel/boards/sof_rt5682.c
>> b/sound/soc/intel/boards/sof_rt5682.c
>> index f28fb98..660e4a6 100644
>> --- a/sound/soc/intel/boards/sof_rt5682.c
>> +++ b/sound/soc/intel/boards/sof_rt5682.c
>> @@ -22,8 +22,6 @@
>>  #include "../../codecs/rt5682.h"
>>  #include "../../codecs/hdac_hdmi.h"
>>
>> -#define NAME_SIZE 32
>> -
>>  #define SOF_RT5682_SSP_CODEC(quirk)		((quirk) & GENMASK(2,
>0))
>>  #define SOF_RT5682_SSP_CODEC_MASK			(GENMASK(2,
>0))
>>  #define SOF_RT5682_MCLK_EN			BIT(3)
>> @@ -216,7 +214,6 @@ static int sof_card_late_probe(struct snd_soc_card
>> *card)  {
>>  	struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
>>  	struct snd_soc_component *component = NULL;
>> -	char jack_name[NAME_SIZE];
>>  	struct sof_hdmi_pcm *pcm;
>>  	int err = 0;
>>  	int i = 0;
>> @@ -227,14 +224,6 @@ static int sof_card_late_probe(struct
>> snd_soc_card *card)
>>
>>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>  		component = pcm->codec_dai->component;
>> -		snprintf(jack_name, sizeof(jack_name),
>> -			 "HDMI/DP, pcm=%d Jack", pcm->device);
>> -		err = snd_soc_card_jack_new(card, jack_name,
>> -					    SND_JACK_AVOUT, &sof_hdmi[i],
>> -					    NULL, 0);
>> -
>> -		if (err)
>> -			return err;
>>
>>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>  					  &sof_hdmi[i]);
>> --
>> 2.7.4
>>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks
  2019-05-30 15:00     ` Yang, Libin
@ 2019-05-30 15:22       ` Takashi Iwai
  2019-05-31  2:27         ` Yang, Libin
  0 siblings, 1 reply; 15+ messages in thread
From: Takashi Iwai @ 2019-05-30 15:22 UTC (permalink / raw)
  To: Yang, Libin; +Cc: alsa-devel, broonie, pierre-louis.bossart

On Thu, 30 May 2019 17:00:24 +0200,
Yang, Libin wrote:
> 
> Hi Takashi,
> 
> >-----Original Message-----
> >From: Takashi Iwai [mailto:tiwai@suse.de]
> >Sent: Thursday, May 30, 2019 3:13 PM
> >To: Yang, Libin <libin.yang@intel.com>
> >Cc: alsa-devel@alsa-project.org; broonie@kernel.org; pierre-
> >louis.bossart@linux.intel.com
> >Subject: Re: [alsa-devel] [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks
> >
> >On Mon, 27 May 2019 11:07:26 +0200,
> >libin.yang@intel.com wrote:
> >>
> >> From: Libin Yang <libin.yang@intel.com>
> >>
> >> This patch does the following actions:
> >> 1) move snd_soc_card_jack_new() from machine driver to codec driver.
> >>    This is because the jack information is more lated to the codec
> >>    Also this patch calls snd_jack_add_new_kctl() to export the jack kctl
> >>    to userspace.
> >>
> >> 2) jack is bound to pcm in origal code. The patch binds jack to pin-port.
> >>    This mean each pin-port (3x3) has a jack. pin-port is used for DP-MST
> >>    mode. The port means device entry for DP-MST in hdac_hdmi
> >>    As hdac_hdmi allows user to map the pin-port to a pcm manually, the jack
> >>    is bound to pcm is not accurate.
> >>    However, PA assumes jack is bound to PCM for the legacy mode.
> >>    For example, for ubuntu, in
> >>    /usr/share/pulseaudio/alsa-mixer/paths/hdmi-output-x.conf uses
> >>    "Jack HDMI/DP,pcm=n" to find which jack event is used.
> >>    This main issue is: pcm number is fixed (3, 7, 8, 9, 10) for hdmi in
> >>    legacy mode. But it is not always the same for ASoC hdmi audio.
> >
> >The question is what brings this change practically.  On the legacy driver, as
> >the jack is bound with the PCM, user-space (typically PA) who receives a jack
> >connection event opens simply the corresponding PCM substream.  Now, for
> >ASoC:
> >  1. Which PCM substream?
> >  2. How to set up the routing?
> >
> >I assume the 1 doens't matter, any substream, unlike the legacy case.
> >But how is 2 done automatically?
> 
> For the legacy HDA, there are 2 mode (dynamic pcm assignment (DPMST) and 
> static pcm assignment (NON-DPMST)).
> 1) For static pcm assignment, pcm is always statically mapped to pin. 
> For example, pcm1 <=> pin 1; pcm <=> pin 2 and so on. So it is the same
> to bind jack to pcm or to pin.
> 2) For dynamic pcm assignment, in generic_hdmi_build_jack(), the jack
> is bound to PCM when it is created (spec->pcm_rec[pcm_idx].jack). We will
> find the jack by pcm_idx. And when monitor is connected to a pin, 
> update_eld() will be called. In update_eld(), it will call 
> hdmi_attach_hda_pcm() to find a pcm to bind to the pin. So it can find a 
> jack (from the pcm) and report its status to userspace.
> 
> So in a word for legacy HDA, it can always find a PCM (no matter in static 
> mode or in dynamic mode) when the monitor is connected to a pin. This
> means it can always update the status of to userspace that the pcm 
> status is changed.

Right, that's why the jack control has a pcm suffix.  It is bound with
the PCM stream in the end, so user-space can simply open it.

> However, in hdac_hdmi, there is no such dynamic pcm assignment. And it
> is not statically assignment of pcm to pin. PCM is statically bound to cvt.
> hdac_hdmi allows user to assign a cvt to a pin with alsamixer ( in function
> hdac_hdmi_set_pin_port_mux(), so this function maps the pin to the pcm).
> As user may assign NONE pcm to a pin in alsamixer, this means a pin can
> be assigned none of pcms. So if we mapped jack to pcm, we may not find 
> any jack for the pin when a monitor is connected to the pin. This means
> driver can't notify userspace of the monitor connection.
> As you know, PA will use the monitor connection status to decide whether
> to user it or not. So this is the problem. The root cause is pcm is bound to
> cvt. And pin may be not bound to any pcm (This is the difference from the
> legacy hda).
> 
> In my patch, as jack is bound to pin-port, so it can always notify userspace
> that a monitor is connected. We can use configuration in /usr/share/alsa/
> ucm or /usr/share/pulseaudio to configure the amixer to assign a pcm
> to the pin (monitor). And userspace can playback on the monitor now.

Then please prepare the UCM stuff at first and make sure that
everything works with the proposed change.  The kernel changes can be
merged once after all things get ready.


thanks,

Takashi

> 
> Regards,
> Libin
> 
> >
> >
> >thanks,
> >
> >Takashi
> >
> >>
> >> Signed-off-by: Libin Yang <libin.yang@intel.com>
> >> ---
> >>  sound/soc/codecs/hdac_hdmi.c                       | 127 ++++++++++++---------
> >>  sound/soc/intel/boards/bxt_da7219_max98357a.c      |  10 --
> >>  sound/soc/intel/boards/bxt_rt298.c                 |  10 --
> >>  sound/soc/intel/boards/glk_rt5682_max98357a.c      |  10 --
> >>  sound/soc/intel/boards/kbl_da7219_max98357a.c      |  10 --
> >>  sound/soc/intel/boards/kbl_da7219_max98927.c       |  10 --
> >>  sound/soc/intel/boards/kbl_rt5660.c                |  10 --
> >>  sound/soc/intel/boards/kbl_rt5663_max98927.c       |  10 --
> >>  .../soc/intel/boards/kbl_rt5663_rt5514_max98927.c  |   9 --
> >>  sound/soc/intel/boards/skl_hda_dsp_common.c        |   9 --
> >>  sound/soc/intel/boards/skl_nau88l25_max98357a.c    |  11 --
> >>  sound/soc/intel/boards/skl_nau88l25_ssm4567.c      |  11 --
> >>  sound/soc/intel/boards/skl_rt286.c                 |  10 --
> >>  sound/soc/intel/boards/sof_rt5682.c                |  11 --
> >>  14 files changed, 74 insertions(+), 184 deletions(-)
> >>
> >> diff --git a/sound/soc/codecs/hdac_hdmi.c
> >> b/sound/soc/codecs/hdac_hdmi.c index 90c2ee3..ed267fa 100644
> >> --- a/sound/soc/codecs/hdac_hdmi.c
> >> +++ b/sound/soc/codecs/hdac_hdmi.c
> >> @@ -4,6 +4,7 @@
> >>   *  Copyright (C) 2014-2015 Intel Corp
> >>   *  Author: Samreen Nilofer <samreen.nilofer@intel.com>
> >>   *	    Subhransu S. Prusty <subhransu.s.prusty@intel.com>
> >> + *	    Libin Yang <libin.yang@intel.com>
> >>   *
> >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >~~~~~~~~~
> >>   *
> >>   *  This program is free software; you can redistribute it and/or
> >> modify @@ -30,6 +31,7 @@  #include <sound/hda_i915.h>  #include
> >> <sound/pcm_drm_eld.h>  #include <sound/hda_chmap.h>
> >> +#include <sound/hda_codec.h>
> >>  #include "../../hda/local.h"
> >>  #include "hdac_hdmi.h"
> >>
> >> @@ -95,6 +97,8 @@ struct hdac_hdmi_port {
> >>  	int num_mux_nids;
> >>  	hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
> >>  	struct hdac_hdmi_eld eld;
> >> +	struct snd_soc_jack jack;
> >> +	int jack_event;
> >>  	const char *jack_pin;
> >>  	struct snd_soc_dapm_context *dapm;
> >>  	const char *output_pin;
> >> @@ -105,14 +109,12 @@ struct hdac_hdmi_pcm {
> >>  	int pcm_id;
> >>  	struct list_head port_list;
> >>  	struct hdac_hdmi_cvt *cvt;
> >> -	struct snd_soc_jack *jack;
> >>  	int stream_tag;
> >>  	int channels;
> >>  	int format;
> >>  	bool chmap_set;
> >>  	unsigned char chmap[8]; /* ALSA API channel-map */
> >>  	struct mutex lock;
> >> -	int jack_event;
> >>  };
> >>
> >>  struct hdac_hdmi_dai_port_map {
> >> @@ -166,8 +168,7 @@ hdac_hdmi_get_pcm_from_cvt(struct
> >hdac_hdmi_priv *hdmi,
> >>  	return pcm;
> >>  }
> >>
> >> -static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
> >> -		struct hdac_hdmi_port *port, bool is_connect)
> >> +static void hdac_hdmi_jack_report(struct hdac_hdmi_port *port, bool
> >> +is_connect)
> >>  {
> >>  	struct hdac_device *hdev = port->pin->hdev;
> >>
> >> @@ -176,19 +177,25 @@ static void hdac_hdmi_jack_report(struct
> >hdac_hdmi_pcm *pcm,
> >>  	else
> >>  		snd_soc_dapm_disable_pin(port->dapm, port->jack_pin);
> >>
> >> +	/* if jack is not ready, skip reporting jack status */
> >> +	if (!port->jack.jack) {
> >> +		snd_soc_dapm_sync(port->dapm);
> >> +		return;
> >> +	}
> >> +
> >>  	if (is_connect) {
> >> -		if (pcm->jack_event == 0) {
> >> +		if (port->jack_event == 0) {
> >>  			dev_dbg(&hdev->dev,
> >> -					"jack report for pcm=%d\n",
> >> -					pcm->pcm_id);
> >> -			snd_soc_jack_report(pcm->jack, SND_JACK_AVOUT,
> >> -						SND_JACK_AVOUT);
> >> +				"jack report for pin:port = %d:%d\n",
> >> +				port->id, port->pin->nid);
> >> +			snd_soc_jack_report(&port->jack, SND_JACK_AVOUT,
> >> +					    SND_JACK_AVOUT);
> >>  		}
> >> -		pcm->jack_event = 1;
> >> +		port->jack_event = 1;
> >>  	} else {
> >> -		if (pcm->jack_event == 1)
> >> -			snd_soc_jack_report(pcm->jack, 0, SND_JACK_AVOUT);
> >> -		pcm->jack_event = 0;
> >> +		if (port->jack_event == 1)
> >> +			snd_soc_jack_report(&port->jack, 0,
> >SND_JACK_AVOUT);
> >> +		port->jack_event = 0;
> >>  	}
> >>
> >>  	snd_soc_dapm_sync(port->dapm);
> >> @@ -1235,26 +1242,15 @@ static void hdac_hdmi_present_sense(struct
> >hdac_hdmi_pin *pin,
> >>  	pcm = hdac_hdmi_get_pcm(hdev, port);
> >>
> >>  	if (!port->eld.monitor_present || !port->eld.eld_valid) {
> >> -
> >>  		dev_err(&hdev->dev, "%s: disconnect for pin:port %d:%d\n",
> >>  						__func__, pin->nid, port->id);
> >> -
> >> -		/*
> >> -		 * PCMs are not registered during device probe, so don't
> >> -		 * report jack here. It will be done in usermode mux
> >> -		 * control select.
> >> -		 */
> >> -		if (pcm)
> >> -			hdac_hdmi_jack_report(pcm, port, false);
> >> -
> >> +		hdac_hdmi_jack_report(port, false);
> >>  		mutex_unlock(&hdmi->pin_mutex);
> >>  		return;
> >>  	}
> >>
> >>  	if (port->eld.monitor_present && port->eld.eld_valid) {
> >> -		if (pcm)
> >> -			hdac_hdmi_jack_report(pcm, port, true);
> >> -
> >> +		hdac_hdmi_jack_report(port, true);
> >>  		print_hex_dump_debug("ELD: ", DUMP_PREFIX_OFFSET, 16, 1,
> >>  			  port->eld.eld_buffer, port->eld.eld_size, false);
> >>
> >> @@ -1650,6 +1646,30 @@ static int create_fill_jack_kcontrols(struct
> >snd_soc_card *card,
> >>  	return snd_soc_add_card_controls(card, kc, i);  }
> >>
> >> +static void hdac_hdmi_present_sense_all_pins(struct hdac_device *hdev,
> >> +			struct hdac_hdmi_priv *hdmi, bool detect_pin_caps) {
> >> +	int i;
> >> +	struct hdac_hdmi_pin *pin;
> >> +
> >> +	list_for_each_entry(pin, &hdmi->pin_list, head) {
> >> +		if (detect_pin_caps) {
> >> +
> >> +			if (hdac_hdmi_get_port_len(hdev, pin->nid)  == 0)
> >> +				pin->mst_capable = false;
> >> +			else
> >> +				pin->mst_capable = true;
> >> +		}
> >> +
> >> +		for (i = 0; i < pin->num_ports; i++) {
> >> +			if (!pin->mst_capable && i > 0)
> >> +				continue;
> >> +
> >> +			hdac_hdmi_present_sense(pin, &pin->ports[i]);
> >> +		}
> >> +	}
> >> +}
> >> +
> >>  int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
> >>  			struct snd_soc_dapm_context *dapm)  { @@ -1659,6
> >+1679,7 @@ int
> >> hdac_hdmi_jack_port_init(struct snd_soc_component *component,
> >>  	struct snd_soc_dapm_widget *widgets;
> >>  	struct snd_soc_dapm_route *route;
> >>  	char w_name[NAME_SIZE];
> >> +	char jack_name[NAME_SIZE];
> >>  	int i = 0, j, ret;
> >>
> >>  	widgets = devm_kcalloc(dapm->dev, hdmi->num_ports, @@ -1687,6
> >> +1708,30 @@ int hdac_hdmi_jack_port_init(struct snd_soc_component
> >*component,
> >>  			pin->ports[j].jack_pin = widgets[i].name;
> >>  			pin->ports[j].dapm = dapm;
> >>
> >> +			/*
> >> +			 * Create pin-port jack. Each port (device entry) of
> >> +			 * the pin has a corresponding jack
> >> +			 */
> >> +			snprintf(jack_name, sizeof(jack_name),
> >> +				 "HDMI/DP, pin:port=%d:%d Jack",
> >> +				  pin->nid, pin->ports[j].id);
> >> +			ret = snd_soc_card_jack_new(dapm->card, jack_name,
> >> +						    SND_JACK_AVOUT,
> >> +						    &(pin->ports[j].jack),
> >> +						    NULL, 0);
> >> +			if (ret)
> >> +				return ret;
> >> +
> >> +			/* create the jack kctl */
> >> +			ret = snd_jack_add_new_kctl(pin->ports[j].jack.jack,
> >> +						    jack_name,
> >SND_JACK_AVOUT);
> >> +			/*
> >> +			 * It's not a critical issue if driver fails to
> >> +			 * create jack kctl.
> >> +			 */
> >> +			if (ret)
> >> +				dev_warn(&hdev->dev, "failed creating Jack
> >kctl\n");
> >> +
> >>  			/* add to route from Jack widget to output */
> >>  			hdac_hdmi_fill_route(&route[i], pin->ports[j].jack_pin,
> >>  					NULL, pin->ports[j].output_pin, NULL);
> >@@ -1695,6 +1740,9 @@ int
> >> hdac_hdmi_jack_port_init(struct snd_soc_component *component,
> >>  		}
> >>  	}
> >>
> >> +	/* now jack is ready, let's update the status */
> >> +	hdac_hdmi_present_sense_all_pins(hdev, hdmi, true);
> >> +
> >>  	/* Add Route from Jack widget to the output widget */
> >>  	ret = snd_soc_dapm_new_controls(dapm, widgets, hdmi-
> >>num_ports);
> >>  	if (ret < 0)
> >> @@ -1744,8 +1792,6 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai,
> >int device,
> >>  		return -ENOMEM;
> >>  	pcm->pcm_id = device;
> >>  	pcm->cvt = hdmi->dai_map[dai->id].cvt;
> >> -	pcm->jack_event = 0;
> >> -	pcm->jack = jack;
> >>  	mutex_init(&pcm->lock);
> >>  	INIT_LIST_HEAD(&pcm->port_list);
> >>  	snd_pcm = hdac_hdmi_get_pcm_from_id(dai->component->card,
> >device);
> >> @@ -1765,30 +1811,6 @@ int hdac_hdmi_jack_init(struct snd_soc_dai
> >> *dai, int device,  }  EXPORT_SYMBOL_GPL(hdac_hdmi_jack_init);
> >>
> >> -static void hdac_hdmi_present_sense_all_pins(struct hdac_device *hdev,
> >> -			struct hdac_hdmi_priv *hdmi, bool detect_pin_caps)
> >> -{
> >> -	int i;
> >> -	struct hdac_hdmi_pin *pin;
> >> -
> >> -	list_for_each_entry(pin, &hdmi->pin_list, head) {
> >> -		if (detect_pin_caps) {
> >> -
> >> -			if (hdac_hdmi_get_port_len(hdev, pin->nid)  == 0)
> >> -				pin->mst_capable = false;
> >> -			else
> >> -				pin->mst_capable = true;
> >> -		}
> >> -
> >> -		for (i = 0; i < pin->num_ports; i++) {
> >> -			if (!pin->mst_capable && i > 0)
> >> -				continue;
> >> -
> >> -			hdac_hdmi_present_sense(pin, &pin->ports[i]);
> >> -		}
> >> -	}
> >> -}
> >> -
> >>  static int hdmi_codec_probe(struct snd_soc_component *component)  {
> >>  	struct hdac_hdmi_priv *hdmi =
> >> snd_soc_component_get_drvdata(component);
> >> @@ -1823,7 +1845,6 @@ static int hdmi_codec_probe(struct
> >snd_soc_component *component)
> >>  		return ret;
> >>  	}
> >>
> >> -	hdac_hdmi_present_sense_all_pins(hdev, hdmi, true);
> >>  	/* Imp: Store the card pointer in hda_codec */
> >>  	hdmi->card = dapm->card->snd_card;
> >>
> >> diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c
> >> b/sound/soc/intel/boards/bxt_da7219_max98357a.c
> >> index 5cadb7f..c69cfa9 100644
> >> --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c
> >> +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
> >> @@ -573,14 +573,12 @@ static const struct x86_cpu_id glk_ids[] = {
> >>  	{}
> >>  };
> >>
> >> -#define NAME_SIZE	32
> >>  static int bxt_card_late_probe(struct snd_soc_card *card)  {
> >>  	struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card);
> >>  	struct bxt_hdmi_pcm *pcm;
> >>  	struct snd_soc_component *component = NULL;
> >>  	int err, i = 0;
> >> -	char jack_name[NAME_SIZE];
> >>
> >>  	if (x86_match_cpu(glk_ids))
> >>  		snd_soc_dapm_add_routes(&card->dapm, gemini_map, @@
> >-591,14 +589,6
> >> @@ static int bxt_card_late_probe(struct snd_soc_card *card)
> >>
> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
> >>  		component = pcm->codec_dai->component;
> >> -		snprintf(jack_name, sizeof(jack_name),
> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> >> -		err = snd_soc_card_jack_new(card, jack_name,
> >> -					SND_JACK_AVOUT, &broxton_hdmi[i],
> >> -					NULL, 0);
> >> -
> >> -		if (err)
> >> -			return err;
> >>
> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
> >>  						&broxton_hdmi[i]);
> >> diff --git a/sound/soc/intel/boards/bxt_rt298.c
> >> b/sound/soc/intel/boards/bxt_rt298.c
> >> index e91057f..d1372891 100644
> >> --- a/sound/soc/intel/boards/bxt_rt298.c
> >> +++ b/sound/soc/intel/boards/bxt_rt298.c
> >> @@ -507,25 +507,15 @@ static struct snd_soc_dai_link broxton_rt298_dais[]
> >= {
> >>  	},
> >>  };
> >>
> >> -#define NAME_SIZE	32
> >>  static int bxt_card_late_probe(struct snd_soc_card *card)  {
> >>  	struct bxt_rt286_private *ctx = snd_soc_card_get_drvdata(card);
> >>  	struct bxt_hdmi_pcm *pcm;
> >>  	struct snd_soc_component *component = NULL;
> >>  	int err, i = 0;
> >> -	char jack_name[NAME_SIZE];
> >>
> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
> >>  		component = pcm->codec_dai->component;
> >> -		snprintf(jack_name, sizeof(jack_name),
> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> >> -		err = snd_soc_card_jack_new(card, jack_name,
> >> -					SND_JACK_AVOUT, &broxton_hdmi[i],
> >> -					NULL, 0);
> >> -
> >> -		if (err)
> >> -			return err;
> >>
> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
> >>  						&broxton_hdmi[i]);
> >> diff --git a/sound/soc/intel/boards/glk_rt5682_max98357a.c
> >> b/sound/soc/intel/boards/glk_rt5682_max98357a.c
> >> index d17126f..2a35974 100644
> >> --- a/sound/soc/intel/boards/glk_rt5682_max98357a.c
> >> +++ b/sound/soc/intel/boards/glk_rt5682_max98357a.c
> >> @@ -29,7 +29,6 @@
> >>  #define MAXIM_DEV0_NAME "MX98357A:00"
> >>  #define DUAL_CHANNEL 2
> >>  #define QUAD_CHANNEL 4
> >> -#define NAME_SIZE 32
> >>
> >>  static struct snd_soc_jack geminilake_hdmi[3];
> >>
> >> @@ -523,21 +522,12 @@ static int glk_card_late_probe(struct
> >> snd_soc_card *card)  {
> >>  	struct glk_card_private *ctx = snd_soc_card_get_drvdata(card);
> >>  	struct snd_soc_component *component = NULL;
> >> -	char jack_name[NAME_SIZE];
> >>  	struct glk_hdmi_pcm *pcm;
> >>  	int err = 0;
> >>  	int i = 0;
> >>
> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
> >>  		component = pcm->codec_dai->component;
> >> -		snprintf(jack_name, sizeof(jack_name),
> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> >> -		err = snd_soc_card_jack_new(card, jack_name,
> >> -					SND_JACK_AVOUT,
> >&geminilake_hdmi[i],
> >> -					NULL, 0);
> >> -
> >> -		if (err)
> >> -			return err;
> >>
> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
> >>  						&geminilake_hdmi[i]);
> >> diff --git a/sound/soc/intel/boards/kbl_da7219_max98357a.c
> >> b/sound/soc/intel/boards/kbl_da7219_max98357a.c
> >> index 07491a0..f293307 100644
> >> --- a/sound/soc/intel/boards/kbl_da7219_max98357a.c
> >> +++ b/sound/soc/intel/boards/kbl_da7219_max98357a.c
> >> @@ -519,25 +519,15 @@ static struct snd_soc_dai_link kabylake_dais[] = {
> >>  	},
> >>  };
> >>
> >> -#define NAME_SIZE	32
> >>  static int kabylake_card_late_probe(struct snd_soc_card *card)  {
> >>  	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
> >>  	struct kbl_hdmi_pcm *pcm;
> >>  	struct snd_soc_component *component = NULL;
> >>  	int err, i = 0;
> >> -	char jack_name[NAME_SIZE];
> >>
> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
> >>  		component = pcm->codec_dai->component;
> >> -		snprintf(jack_name, sizeof(jack_name),
> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> >> -		err = snd_soc_card_jack_new(card, jack_name,
> >> -					SND_JACK_AVOUT, &skylake_hdmi[i],
> >> -					NULL, 0);
> >> -
> >> -		if (err)
> >> -			return err;
> >>
> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
> >>  				&skylake_hdmi[i]);
> >> diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c
> >> b/sound/soc/intel/boards/kbl_da7219_max98927.c
> >> index f72a7bf..84d3609 100644
> >> --- a/sound/soc/intel/boards/kbl_da7219_max98927.c
> >> +++ b/sound/soc/intel/boards/kbl_da7219_max98927.c
> >> @@ -34,7 +34,6 @@
> >>
> >>  #define DUAL_CHANNEL	2
> >>  #define QUAD_CHANNEL	4
> >> -#define NAME_SIZE	32
> >>
> >>  static struct snd_soc_card *kabylake_audio_card;  static struct
> >> snd_soc_jack kabylake_hdmi[3]; @@ -952,18 +951,9 @@ static int
> >> kabylake_card_late_probe(struct snd_soc_card *card)
> >>  	struct kbl_hdmi_pcm *pcm;
> >>  	struct snd_soc_component *component = NULL;
> >>  	int err, i = 0;
> >> -	char jack_name[NAME_SIZE];
> >>
> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
> >>  		component = pcm->codec_dai->component;
> >> -		snprintf(jack_name, sizeof(jack_name),
> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> >> -		err = snd_soc_card_jack_new(card, jack_name,
> >> -					SND_JACK_AVOUT, &kabylake_hdmi[i],
> >> -					NULL, 0);
> >> -
> >> -		if (err)
> >> -			return err;
> >>
> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
> >>  						&kabylake_hdmi[i]);
> >> diff --git a/sound/soc/intel/boards/kbl_rt5660.c
> >> b/sound/soc/intel/boards/kbl_rt5660.c
> >> index 3255e00..06411bf 100644
> >> --- a/sound/soc/intel/boards/kbl_rt5660.c
> >> +++ b/sound/soc/intel/boards/kbl_rt5660.c
> >> @@ -447,25 +447,15 @@ static struct snd_soc_dai_link
> >> kabylake_rt5660_dais[] = {  };
> >>
> >>
> >> -#define NAME_SIZE	32
> >>  static int kabylake_card_late_probe(struct snd_soc_card *card)  {
> >>  	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
> >>  	struct kbl_hdmi_pcm *pcm;
> >>  	struct snd_soc_component *component = NULL;
> >>  	int err, i = 0;
> >> -	char jack_name[NAME_SIZE];
> >>
> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
> >>  		component = pcm->codec_dai->component;
> >> -		snprintf(jack_name, sizeof(jack_name),
> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> >> -		err = snd_soc_card_jack_new(card, jack_name,
> >> -					SND_JACK_AVOUT, &skylake_hdmi[i],
> >> -					NULL, 0);
> >> -
> >> -		if (err)
> >> -			return err;
> >>
> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
> >>  				&skylake_hdmi[i]);
> >> diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c
> >> b/sound/soc/intel/boards/kbl_rt5663_max98927.c
> >> index d714752..9c43c6c 100644
> >> --- a/sound/soc/intel/boards/kbl_rt5663_max98927.c
> >> +++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c
> >> @@ -898,25 +898,15 @@ static struct snd_soc_dai_link
> >kabylake_5663_dais[] = {
> >>  	},
> >>  };
> >>
> >> -#define NAME_SIZE	32
> >>  static int kabylake_card_late_probe(struct snd_soc_card *card)  {
> >>  	struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(card);
> >>  	struct kbl_hdmi_pcm *pcm;
> >>  	struct snd_soc_component *component = NULL;
> >>  	int err, i = 0;
> >> -	char jack_name[NAME_SIZE];
> >>
> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
> >>  		component = pcm->codec_dai->component;
> >> -		snprintf(jack_name, sizeof(jack_name),
> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> >> -		err = snd_soc_card_jack_new(card, jack_name,
> >> -					SND_JACK_AVOUT, &skylake_hdmi[i],
> >> -					NULL, 0);
> >> -
> >> -		if (err)
> >> -			return err;
> >>
> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
> >>  						&skylake_hdmi[i]);
> >> diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
> >> b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
> >> index 879f142..8fe4007 100644
> >> --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
> >> +++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
> >> @@ -40,7 +40,6 @@
> >>  #define RT5663_DEV_NAME "i2c-10EC5663:00"
> >>  #define RT5514_AIF1_BCLK_FREQ (48000 * 8 * 16)  #define
> >> RT5514_AIF1_SYSCLK_FREQ 12288000 -#define NAME_SIZE 32
> >>
> >>  #define DMIC_CH(p) p->list[p->count-1]
> >>
> >> @@ -600,18 +599,10 @@ static int kabylake_card_late_probe(struct
> >snd_soc_card *card)
> >>  	struct kbl_hdmi_pcm *pcm;
> >>  	struct snd_soc_component *component = NULL;
> >>  	int err, i = 0;
> >> -	char jack_name[NAME_SIZE];
> >>
> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
> >>  		component = pcm->codec_dai->component;
> >> -		snprintf(jack_name, sizeof(jack_name),
> >> -			"HDMI/DP,pcm=%d Jack", pcm->device);
> >> -		err = snd_soc_card_jack_new(card, jack_name,
> >> -				SND_JACK_AVOUT, &ctx->kabylake_hdmi[i],
> >> -				NULL, 0);
> >>
> >> -		if (err)
> >> -			return err;
> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
> >>  						&ctx->kabylake_hdmi[i]);
> >>  		if (err < 0)
> >> diff --git a/sound/soc/intel/boards/skl_hda_dsp_common.c
> >> b/sound/soc/intel/boards/skl_hda_dsp_common.c
> >> index 8b68f41..0f57fc2 100644
> >> --- a/sound/soc/intel/boards/skl_hda_dsp_common.c
> >> +++ b/sound/soc/intel/boards/skl_hda_dsp_common.c
> >> @@ -118,19 +118,10 @@ int skl_hda_hdmi_jack_init(struct snd_soc_card
> >*card)
> >>  	struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card);
> >>  	struct snd_soc_component *component = NULL;
> >>  	struct skl_hda_hdmi_pcm *pcm;
> >> -	char jack_name[NAME_SIZE];
> >>  	int err;
> >>
> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
> >>  		component = pcm->codec_dai->component;
> >> -		snprintf(jack_name, sizeof(jack_name),
> >> -			 "HDMI/DP, pcm=%d Jack", pcm->device);
> >> -		err = snd_soc_card_jack_new(card, jack_name,
> >> -					    SND_JACK_AVOUT, &pcm-
> >>hdmi_jack,
> >> -					    NULL, 0);
> >> -
> >> -		if (err)
> >> -			return err;
> >>
> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
> >>  					  &pcm->hdmi_jack);
> >> diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
> >> b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
> >> index 0922106..aca426f 100644
> >> --- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
> >> +++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
> >> @@ -587,26 +587,15 @@ static struct snd_soc_dai_link skylake_dais[] = {
> >>  	},
> >>  };
> >>
> >> -#define NAME_SIZE	32
> >>  static int skylake_card_late_probe(struct snd_soc_card *card)  {
> >>  	struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(card);
> >>  	struct skl_hdmi_pcm *pcm;
> >>  	struct snd_soc_component *component = NULL;
> >>  	int err, i = 0;
> >> -	char jack_name[NAME_SIZE];
> >>
> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
> >>  		component = pcm->codec_dai->component;
> >> -		snprintf(jack_name, sizeof(jack_name),
> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> >> -		err = snd_soc_card_jack_new(card, jack_name,
> >> -					SND_JACK_AVOUT,
> >> -					&skylake_hdmi[i],
> >> -					NULL, 0);
> >> -
> >> -		if (err)
> >> -			return err;
> >>
> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
> >>  						&skylake_hdmi[i]);
> >> diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
> >> b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
> >> index 8433c52..788a837 100644
> >> --- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
> >> +++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
> >> @@ -638,26 +638,15 @@ static struct snd_soc_dai_link skylake_dais[] = {
> >>  	},
> >>  };
> >>
> >> -#define NAME_SIZE	32
> >>  static int skylake_card_late_probe(struct snd_soc_card *card)  {
> >>  	struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(card);
> >>  	struct skl_hdmi_pcm *pcm;
> >>  	struct snd_soc_component *component = NULL;
> >>  	int err, i = 0;
> >> -	char jack_name[NAME_SIZE];
> >>
> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
> >>  		component = pcm->codec_dai->component;
> >> -		snprintf(jack_name, sizeof(jack_name),
> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> >> -		err = snd_soc_card_jack_new(card, jack_name,
> >> -					SND_JACK_AVOUT,
> >> -					&skylake_hdmi[i],
> >> -					NULL, 0);
> >> -
> >> -		if (err)
> >> -			return err;
> >>
> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
> >>  						&skylake_hdmi[i]);
> >> diff --git a/sound/soc/intel/boards/skl_rt286.c
> >> b/sound/soc/intel/boards/skl_rt286.c
> >> index 0e1818d..5d245f5 100644
> >> --- a/sound/soc/intel/boards/skl_rt286.c
> >> +++ b/sound/soc/intel/boards/skl_rt286.c
> >> @@ -473,25 +473,15 @@ static struct snd_soc_dai_link skylake_rt286_dais[]
> >= {
> >>  	},
> >>  };
> >>
> >> -#define NAME_SIZE	32
> >>  static int skylake_card_late_probe(struct snd_soc_card *card)  {
> >>  	struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(card);
> >>  	struct skl_hdmi_pcm *pcm;
> >>  	struct snd_soc_component *component = NULL;
> >>  	int err, i = 0;
> >> -	char jack_name[NAME_SIZE];
> >>
> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
> >>  		component = pcm->codec_dai->component;
> >> -		snprintf(jack_name, sizeof(jack_name),
> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
> >> -		err = snd_soc_card_jack_new(card, jack_name,
> >> -					SND_JACK_AVOUT, &skylake_hdmi[i],
> >> -					NULL, 0);
> >> -
> >> -		if (err)
> >> -			return err;
> >>
> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
> >>  						&skylake_hdmi[i]);
> >> diff --git a/sound/soc/intel/boards/sof_rt5682.c
> >> b/sound/soc/intel/boards/sof_rt5682.c
> >> index f28fb98..660e4a6 100644
> >> --- a/sound/soc/intel/boards/sof_rt5682.c
> >> +++ b/sound/soc/intel/boards/sof_rt5682.c
> >> @@ -22,8 +22,6 @@
> >>  #include "../../codecs/rt5682.h"
> >>  #include "../../codecs/hdac_hdmi.h"
> >>
> >> -#define NAME_SIZE 32
> >> -
> >>  #define SOF_RT5682_SSP_CODEC(quirk)		((quirk) & GENMASK(2,
> >0))
> >>  #define SOF_RT5682_SSP_CODEC_MASK			(GENMASK(2,
> >0))
> >>  #define SOF_RT5682_MCLK_EN			BIT(3)
> >> @@ -216,7 +214,6 @@ static int sof_card_late_probe(struct snd_soc_card
> >> *card)  {
> >>  	struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
> >>  	struct snd_soc_component *component = NULL;
> >> -	char jack_name[NAME_SIZE];
> >>  	struct sof_hdmi_pcm *pcm;
> >>  	int err = 0;
> >>  	int i = 0;
> >> @@ -227,14 +224,6 @@ static int sof_card_late_probe(struct
> >> snd_soc_card *card)
> >>
> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
> >>  		component = pcm->codec_dai->component;
> >> -		snprintf(jack_name, sizeof(jack_name),
> >> -			 "HDMI/DP, pcm=%d Jack", pcm->device);
> >> -		err = snd_soc_card_jack_new(card, jack_name,
> >> -					    SND_JACK_AVOUT, &sof_hdmi[i],
> >> -					    NULL, 0);
> >> -
> >> -		if (err)
> >> -			return err;
> >>
> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
> >>  					  &sof_hdmi[i]);
> >> --
> >> 2.7.4
> >>
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks
  2019-05-30 15:22       ` Takashi Iwai
@ 2019-05-31  2:27         ` Yang, Libin
  2019-06-14  8:04           ` Yang, Libin
  0 siblings, 1 reply; 15+ messages in thread
From: Yang, Libin @ 2019-05-31  2:27 UTC (permalink / raw)
  To: Takashi Iwai; +Cc: alsa-devel, broonie, pierre-louis.bossart

Hi Takashi,

>
>On Thu, 30 May 2019 17:00:24 +0200,
>Yang, Libin wrote:
>>
>> Hi Takashi,
>>
>> >-----Original Message-----
>> >From: Takashi Iwai [mailto:tiwai@suse.de]
>> >Sent: Thursday, May 30, 2019 3:13 PM
>> >To: Yang, Libin <libin.yang@intel.com>
>> >Cc: alsa-devel@alsa-project.org; broonie@kernel.org; pierre-
>> >louis.bossart@linux.intel.com
>> >Subject: Re: [alsa-devel] [RFC PATCH 3/4] ASoC: hdac_hdmi: refine
>> >hdmi jacks
>> >
>> >On Mon, 27 May 2019 11:07:26 +0200,
>> >libin.yang@intel.com wrote:
>> >>
>> >> From: Libin Yang <libin.yang@intel.com>
>> >>
>> >> This patch does the following actions:
>> >> 1) move snd_soc_card_jack_new() from machine driver to codec driver.
>> >>    This is because the jack information is more lated to the codec
>> >>    Also this patch calls snd_jack_add_new_kctl() to export the jack kctl
>> >>    to userspace.
>> >>
>> >> 2) jack is bound to pcm in origal code. The patch binds jack to pin-port.
>> >>    This mean each pin-port (3x3) has a jack. pin-port is used for DP-MST
>> >>    mode. The port means device entry for DP-MST in hdac_hdmi
>> >>    As hdac_hdmi allows user to map the pin-port to a pcm manually, the
>jack
>> >>    is bound to pcm is not accurate.
>> >>    However, PA assumes jack is bound to PCM for the legacy mode.
>> >>    For example, for ubuntu, in
>> >>    /usr/share/pulseaudio/alsa-mixer/paths/hdmi-output-x.conf uses
>> >>    "Jack HDMI/DP,pcm=n" to find which jack event is used.
>> >>    This main issue is: pcm number is fixed (3, 7, 8, 9, 10) for hdmi in
>> >>    legacy mode. But it is not always the same for ASoC hdmi audio.
>> >
>> >The question is what brings this change practically.  On the legacy
>> >driver, as the jack is bound with the PCM, user-space (typically PA)
>> >who receives a jack connection event opens simply the corresponding
>> >PCM substream.  Now, for
>> >ASoC:
>> >  1. Which PCM substream?
>> >  2. How to set up the routing?
>> >
>> >I assume the 1 doens't matter, any substream, unlike the legacy case.
>> >But how is 2 done automatically?
>>
>> For the legacy HDA, there are 2 mode (dynamic pcm assignment (DPMST)
>> and static pcm assignment (NON-DPMST)).
>> 1) For static pcm assignment, pcm is always statically mapped to pin.
>> For example, pcm1 <=> pin 1; pcm <=> pin 2 and so on. So it is the
>> same to bind jack to pcm or to pin.
>> 2) For dynamic pcm assignment, in generic_hdmi_build_jack(), the jack
>> is bound to PCM when it is created (spec->pcm_rec[pcm_idx].jack). We
>> will find the jack by pcm_idx. And when monitor is connected to a pin,
>> update_eld() will be called. In update_eld(), it will call
>> hdmi_attach_hda_pcm() to find a pcm to bind to the pin. So it can find
>> a jack (from the pcm) and report its status to userspace.
>>
>> So in a word for legacy HDA, it can always find a PCM (no matter in
>> static mode or in dynamic mode) when the monitor is connected to a
>> pin. This means it can always update the status of to userspace that
>> the pcm status is changed.
>
>Right, that's why the jack control has a pcm suffix.  It is bound with the PCM
>stream in the end, so user-space can simply open it.
>
>> However, in hdac_hdmi, there is no such dynamic pcm assignment. And it
>> is not statically assignment of pcm to pin. PCM is statically bound to cvt.
>> hdac_hdmi allows user to assign a cvt to a pin with alsamixer ( in
>> function hdac_hdmi_set_pin_port_mux(), so this function maps the pin to
>the pcm).
>> As user may assign NONE pcm to a pin in alsamixer, this means a pin
>> can be assigned none of pcms. So if we mapped jack to pcm, we may not
>> find any jack for the pin when a monitor is connected to the pin. This
>> means driver can't notify userspace of the monitor connection.
>> As you know, PA will use the monitor connection status to decide
>> whether to user it or not. So this is the problem. The root cause is
>> pcm is bound to cvt. And pin may be not bound to any pcm (This is the
>> difference from the legacy hda).
>>
>> In my patch, as jack is bound to pin-port, so it can always notify
>> userspace that a monitor is connected. We can use configuration in
>> /usr/share/alsa/ ucm or /usr/share/pulseaudio to configure the amixer
>> to assign a pcm to the pin (monitor). And userspace can playback on the
>monitor now.
>
>Then please prepare the UCM stuff at first and make sure that everything
>works with the proposed change.  The kernel changes can be merged once
>after all things get ready.

OK. I will prepare the UCM and PA configurations to check it works well and
the purpose is patch should be compatible with the old drivers. 

Regards,
Libin

>
>
>thanks,
>
>Takashi
>
>>
>> Regards,
>> Libin
>>
>> >
>> >
>> >thanks,
>> >
>> >Takashi
>> >
>> >>
>> >> Signed-off-by: Libin Yang <libin.yang@intel.com>
>> >> ---
>> >>  sound/soc/codecs/hdac_hdmi.c                       | 127 ++++++++++++---------
>> >>  sound/soc/intel/boards/bxt_da7219_max98357a.c      |  10 --
>> >>  sound/soc/intel/boards/bxt_rt298.c                 |  10 --
>> >>  sound/soc/intel/boards/glk_rt5682_max98357a.c      |  10 --
>> >>  sound/soc/intel/boards/kbl_da7219_max98357a.c      |  10 --
>> >>  sound/soc/intel/boards/kbl_da7219_max98927.c       |  10 --
>> >>  sound/soc/intel/boards/kbl_rt5660.c                |  10 --
>> >>  sound/soc/intel/boards/kbl_rt5663_max98927.c       |  10 --
>> >>  .../soc/intel/boards/kbl_rt5663_rt5514_max98927.c  |   9 --
>> >>  sound/soc/intel/boards/skl_hda_dsp_common.c        |   9 --
>> >>  sound/soc/intel/boards/skl_nau88l25_max98357a.c    |  11 --
>> >>  sound/soc/intel/boards/skl_nau88l25_ssm4567.c      |  11 --
>> >>  sound/soc/intel/boards/skl_rt286.c                 |  10 --
>> >>  sound/soc/intel/boards/sof_rt5682.c                |  11 --
>> >>  14 files changed, 74 insertions(+), 184 deletions(-)
>> >>
>> >> diff --git a/sound/soc/codecs/hdac_hdmi.c
>> >> b/sound/soc/codecs/hdac_hdmi.c index 90c2ee3..ed267fa 100644
>> >> --- a/sound/soc/codecs/hdac_hdmi.c
>> >> +++ b/sound/soc/codecs/hdac_hdmi.c
>> >> @@ -4,6 +4,7 @@
>> >>   *  Copyright (C) 2014-2015 Intel Corp
>> >>   *  Author: Samreen Nilofer <samreen.nilofer@intel.com>
>> >>   *	    Subhransu S. Prusty <subhransu.s.prusty@intel.com>
>> >> + *	    Libin Yang <libin.yang@intel.com>
>> >>   *
>> >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>~~~
>> >~~~~~~~~~
>> >>   *
>> >>   *  This program is free software; you can redistribute it and/or
>> >> modify @@ -30,6 +31,7 @@  #include <sound/hda_i915.h>  #include
>> >> <sound/pcm_drm_eld.h>  #include <sound/hda_chmap.h>
>> >> +#include <sound/hda_codec.h>
>> >>  #include "../../hda/local.h"
>> >>  #include "hdac_hdmi.h"
>> >>
>> >> @@ -95,6 +97,8 @@ struct hdac_hdmi_port {
>> >>  	int num_mux_nids;
>> >>  	hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
>> >>  	struct hdac_hdmi_eld eld;
>> >> +	struct snd_soc_jack jack;
>> >> +	int jack_event;
>> >>  	const char *jack_pin;
>> >>  	struct snd_soc_dapm_context *dapm;
>> >>  	const char *output_pin;
>> >> @@ -105,14 +109,12 @@ struct hdac_hdmi_pcm {
>> >>  	int pcm_id;
>> >>  	struct list_head port_list;
>> >>  	struct hdac_hdmi_cvt *cvt;
>> >> -	struct snd_soc_jack *jack;
>> >>  	int stream_tag;
>> >>  	int channels;
>> >>  	int format;
>> >>  	bool chmap_set;
>> >>  	unsigned char chmap[8]; /* ALSA API channel-map */
>> >>  	struct mutex lock;
>> >> -	int jack_event;
>> >>  };
>> >>
>> >>  struct hdac_hdmi_dai_port_map {
>> >> @@ -166,8 +168,7 @@ hdac_hdmi_get_pcm_from_cvt(struct
>> >hdac_hdmi_priv *hdmi,
>> >>  	return pcm;
>> >>  }
>> >>
>> >> -static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
>> >> -		struct hdac_hdmi_port *port, bool is_connect)
>> >> +static void hdac_hdmi_jack_report(struct hdac_hdmi_port *port,
>> >> +bool
>> >> +is_connect)
>> >>  {
>> >>  	struct hdac_device *hdev = port->pin->hdev;
>> >>
>> >> @@ -176,19 +177,25 @@ static void hdac_hdmi_jack_report(struct
>> >hdac_hdmi_pcm *pcm,
>> >>  	else
>> >>  		snd_soc_dapm_disable_pin(port->dapm, port->jack_pin);
>> >>
>> >> +	/* if jack is not ready, skip reporting jack status */
>> >> +	if (!port->jack.jack) {
>> >> +		snd_soc_dapm_sync(port->dapm);
>> >> +		return;
>> >> +	}
>> >> +
>> >>  	if (is_connect) {
>> >> -		if (pcm->jack_event == 0) {
>> >> +		if (port->jack_event == 0) {
>> >>  			dev_dbg(&hdev->dev,
>> >> -					"jack report for pcm=%d\n",
>> >> -					pcm->pcm_id);
>> >> -			snd_soc_jack_report(pcm->jack, SND_JACK_AVOUT,
>> >> -						SND_JACK_AVOUT);
>> >> +				"jack report for pin:port = %d:%d\n",
>> >> +				port->id, port->pin->nid);
>> >> +			snd_soc_jack_report(&port->jack, SND_JACK_AVOUT,
>> >> +					    SND_JACK_AVOUT);
>> >>  		}
>> >> -		pcm->jack_event = 1;
>> >> +		port->jack_event = 1;
>> >>  	} else {
>> >> -		if (pcm->jack_event == 1)
>> >> -			snd_soc_jack_report(pcm->jack, 0, SND_JACK_AVOUT);
>> >> -		pcm->jack_event = 0;
>> >> +		if (port->jack_event == 1)
>> >> +			snd_soc_jack_report(&port->jack, 0,
>> >SND_JACK_AVOUT);
>> >> +		port->jack_event = 0;
>> >>  	}
>> >>
>> >>  	snd_soc_dapm_sync(port->dapm);
>> >> @@ -1235,26 +1242,15 @@ static void hdac_hdmi_present_sense(struct
>> >hdac_hdmi_pin *pin,
>> >>  	pcm = hdac_hdmi_get_pcm(hdev, port);
>> >>
>> >>  	if (!port->eld.monitor_present || !port->eld.eld_valid) {
>> >> -
>> >>  		dev_err(&hdev->dev, "%s: disconnect for pin:port %d:%d\n",
>> >>  						__func__, pin->nid, port->id);
>> >> -
>> >> -		/*
>> >> -		 * PCMs are not registered during device probe, so don't
>> >> -		 * report jack here. It will be done in usermode mux
>> >> -		 * control select.
>> >> -		 */
>> >> -		if (pcm)
>> >> -			hdac_hdmi_jack_report(pcm, port, false);
>> >> -
>> >> +		hdac_hdmi_jack_report(port, false);
>> >>  		mutex_unlock(&hdmi->pin_mutex);
>> >>  		return;
>> >>  	}
>> >>
>> >>  	if (port->eld.monitor_present && port->eld.eld_valid) {
>> >> -		if (pcm)
>> >> -			hdac_hdmi_jack_report(pcm, port, true);
>> >> -
>> >> +		hdac_hdmi_jack_report(port, true);
>> >>  		print_hex_dump_debug("ELD: ", DUMP_PREFIX_OFFSET, 16, 1,
>> >>  			  port->eld.eld_buffer, port->eld.eld_size, false);
>> >>
>> >> @@ -1650,6 +1646,30 @@ static int create_fill_jack_kcontrols(struct
>> >snd_soc_card *card,
>> >>  	return snd_soc_add_card_controls(card, kc, i);  }
>> >>
>> >> +static void hdac_hdmi_present_sense_all_pins(struct hdac_device
>*hdev,
>> >> +			struct hdac_hdmi_priv *hdmi, bool detect_pin_caps) {
>> >> +	int i;
>> >> +	struct hdac_hdmi_pin *pin;
>> >> +
>> >> +	list_for_each_entry(pin, &hdmi->pin_list, head) {
>> >> +		if (detect_pin_caps) {
>> >> +
>> >> +			if (hdac_hdmi_get_port_len(hdev, pin->nid)  == 0)
>> >> +				pin->mst_capable = false;
>> >> +			else
>> >> +				pin->mst_capable = true;
>> >> +		}
>> >> +
>> >> +		for (i = 0; i < pin->num_ports; i++) {
>> >> +			if (!pin->mst_capable && i > 0)
>> >> +				continue;
>> >> +
>> >> +			hdac_hdmi_present_sense(pin, &pin->ports[i]);
>> >> +		}
>> >> +	}
>> >> +}
>> >> +
>> >>  int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
>> >>  			struct snd_soc_dapm_context *dapm)  { @@ -1659,6
>> >+1679,7 @@ int
>> >> hdac_hdmi_jack_port_init(struct snd_soc_component *component,
>> >>  	struct snd_soc_dapm_widget *widgets;
>> >>  	struct snd_soc_dapm_route *route;
>> >>  	char w_name[NAME_SIZE];
>> >> +	char jack_name[NAME_SIZE];
>> >>  	int i = 0, j, ret;
>> >>
>> >>  	widgets = devm_kcalloc(dapm->dev, hdmi->num_ports, @@ -1687,6
>> >> +1708,30 @@ int hdac_hdmi_jack_port_init(struct snd_soc_component
>> >*component,
>> >>  			pin->ports[j].jack_pin = widgets[i].name;
>> >>  			pin->ports[j].dapm = dapm;
>> >>
>> >> +			/*
>> >> +			 * Create pin-port jack. Each port (device entry) of
>> >> +			 * the pin has a corresponding jack
>> >> +			 */
>> >> +			snprintf(jack_name, sizeof(jack_name),
>> >> +				 "HDMI/DP, pin:port=%d:%d Jack",
>> >> +				  pin->nid, pin->ports[j].id);
>> >> +			ret = snd_soc_card_jack_new(dapm->card, jack_name,
>> >> +						    SND_JACK_AVOUT,
>> >> +						    &(pin->ports[j].jack),
>> >> +						    NULL, 0);
>> >> +			if (ret)
>> >> +				return ret;
>> >> +
>> >> +			/* create the jack kctl */
>> >> +			ret = snd_jack_add_new_kctl(pin->ports[j].jack.jack,
>> >> +						    jack_name,
>> >SND_JACK_AVOUT);
>> >> +			/*
>> >> +			 * It's not a critical issue if driver fails to
>> >> +			 * create jack kctl.
>> >> +			 */
>> >> +			if (ret)
>> >> +				dev_warn(&hdev->dev, "failed creating Jack
>> >kctl\n");
>> >> +
>> >>  			/* add to route from Jack widget to output */
>> >>  			hdac_hdmi_fill_route(&route[i], pin->ports[j].jack_pin,
>> >>  					NULL, pin->ports[j].output_pin, NULL);
>> >@@ -1695,6 +1740,9 @@ int
>> >> hdac_hdmi_jack_port_init(struct snd_soc_component *component,
>> >>  		}
>> >>  	}
>> >>
>> >> +	/* now jack is ready, let's update the status */
>> >> +	hdac_hdmi_present_sense_all_pins(hdev, hdmi, true);
>> >> +
>> >>  	/* Add Route from Jack widget to the output widget */
>> >>  	ret = snd_soc_dapm_new_controls(dapm, widgets, hdmi- num_ports);
>> >>  	if (ret < 0)
>> >> @@ -1744,8 +1792,6 @@ int hdac_hdmi_jack_init(struct snd_soc_dai
>> >>*dai,
>> >int device,
>> >>  		return -ENOMEM;
>> >>  	pcm->pcm_id = device;
>> >>  	pcm->cvt = hdmi->dai_map[dai->id].cvt;
>> >> -	pcm->jack_event = 0;
>> >> -	pcm->jack = jack;
>> >>  	mutex_init(&pcm->lock);
>> >>  	INIT_LIST_HEAD(&pcm->port_list);
>> >>  	snd_pcm = hdac_hdmi_get_pcm_from_id(dai->component->card,
>> >device);
>> >> @@ -1765,30 +1811,6 @@ int hdac_hdmi_jack_init(struct snd_soc_dai
>> >> *dai, int device,  }  EXPORT_SYMBOL_GPL(hdac_hdmi_jack_init);
>> >>
>> >> -static void hdac_hdmi_present_sense_all_pins(struct hdac_device *hdev,
>> >> -			struct hdac_hdmi_priv *hdmi, bool detect_pin_caps)
>> >> -{
>> >> -	int i;
>> >> -	struct hdac_hdmi_pin *pin;
>> >> -
>> >> -	list_for_each_entry(pin, &hdmi->pin_list, head) {
>> >> -		if (detect_pin_caps) {
>> >> -
>> >> -			if (hdac_hdmi_get_port_len(hdev, pin->nid)  == 0)
>> >> -				pin->mst_capable = false;
>> >> -			else
>> >> -				pin->mst_capable = true;
>> >> -		}
>> >> -
>> >> -		for (i = 0; i < pin->num_ports; i++) {
>> >> -			if (!pin->mst_capable && i > 0)
>> >> -				continue;
>> >> -
>> >> -			hdac_hdmi_present_sense(pin, &pin->ports[i]);
>> >> -		}
>> >> -	}
>> >> -}
>> >> -
>> >>  static int hdmi_codec_probe(struct snd_soc_component *component)  {
>> >>  	struct hdac_hdmi_priv *hdmi =
>> >> snd_soc_component_get_drvdata(component);
>> >> @@ -1823,7 +1845,6 @@ static int hdmi_codec_probe(struct
>> >snd_soc_component *component)
>> >>  		return ret;
>> >>  	}
>> >>
>> >> -	hdac_hdmi_present_sense_all_pins(hdev, hdmi, true);
>> >>  	/* Imp: Store the card pointer in hda_codec */
>> >>  	hdmi->card = dapm->card->snd_card;
>> >>
>> >> diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c
>> >> b/sound/soc/intel/boards/bxt_da7219_max98357a.c
>> >> index 5cadb7f..c69cfa9 100644
>> >> --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c
>> >> +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
>> >> @@ -573,14 +573,12 @@ static const struct x86_cpu_id glk_ids[] = {
>> >>  	{}
>> >>  };
>> >>
>> >> -#define NAME_SIZE	32
>> >>  static int bxt_card_late_probe(struct snd_soc_card *card)  {
>> >>  	struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card);
>> >>  	struct bxt_hdmi_pcm *pcm;
>> >>  	struct snd_soc_component *component = NULL;
>> >>  	int err, i = 0;
>> >> -	char jack_name[NAME_SIZE];
>> >>
>> >>  	if (x86_match_cpu(glk_ids))
>> >>  		snd_soc_dapm_add_routes(&card->dapm, gemini_map, @@
>> >-591,14 +589,6
>> >> @@ static int bxt_card_late_probe(struct snd_soc_card *card)
>> >>
>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>> >>  		component = pcm->codec_dai->component;
>> >> -		snprintf(jack_name, sizeof(jack_name),
>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>> >> -					SND_JACK_AVOUT, &broxton_hdmi[i],
>> >> -					NULL, 0);
>> >> -
>> >> -		if (err)
>> >> -			return err;
>> >>
>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>> >>  						&broxton_hdmi[i]);
>> >> diff --git a/sound/soc/intel/boards/bxt_rt298.c
>> >> b/sound/soc/intel/boards/bxt_rt298.c
>> >> index e91057f..d1372891 100644
>> >> --- a/sound/soc/intel/boards/bxt_rt298.c
>> >> +++ b/sound/soc/intel/boards/bxt_rt298.c
>> >> @@ -507,25 +507,15 @@ static struct snd_soc_dai_link
>> >> broxton_rt298_dais[]
>> >= {
>> >>  	},
>> >>  };
>> >>
>> >> -#define NAME_SIZE	32
>> >>  static int bxt_card_late_probe(struct snd_soc_card *card)  {
>> >>  	struct bxt_rt286_private *ctx = snd_soc_card_get_drvdata(card);
>> >>  	struct bxt_hdmi_pcm *pcm;
>> >>  	struct snd_soc_component *component = NULL;
>> >>  	int err, i = 0;
>> >> -	char jack_name[NAME_SIZE];
>> >>
>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>> >>  		component = pcm->codec_dai->component;
>> >> -		snprintf(jack_name, sizeof(jack_name),
>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>> >> -					SND_JACK_AVOUT, &broxton_hdmi[i],
>> >> -					NULL, 0);
>> >> -
>> >> -		if (err)
>> >> -			return err;
>> >>
>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>> >>  						&broxton_hdmi[i]);
>> >> diff --git a/sound/soc/intel/boards/glk_rt5682_max98357a.c
>> >> b/sound/soc/intel/boards/glk_rt5682_max98357a.c
>> >> index d17126f..2a35974 100644
>> >> --- a/sound/soc/intel/boards/glk_rt5682_max98357a.c
>> >> +++ b/sound/soc/intel/boards/glk_rt5682_max98357a.c
>> >> @@ -29,7 +29,6 @@
>> >>  #define MAXIM_DEV0_NAME "MX98357A:00"
>> >>  #define DUAL_CHANNEL 2
>> >>  #define QUAD_CHANNEL 4
>> >> -#define NAME_SIZE 32
>> >>
>> >>  static struct snd_soc_jack geminilake_hdmi[3];
>> >>
>> >> @@ -523,21 +522,12 @@ static int glk_card_late_probe(struct
>> >> snd_soc_card *card)  {
>> >>  	struct glk_card_private *ctx = snd_soc_card_get_drvdata(card);
>> >>  	struct snd_soc_component *component = NULL;
>> >> -	char jack_name[NAME_SIZE];
>> >>  	struct glk_hdmi_pcm *pcm;
>> >>  	int err = 0;
>> >>  	int i = 0;
>> >>
>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>> >>  		component = pcm->codec_dai->component;
>> >> -		snprintf(jack_name, sizeof(jack_name),
>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>> >> -					SND_JACK_AVOUT,
>> >&geminilake_hdmi[i],
>> >> -					NULL, 0);
>> >> -
>> >> -		if (err)
>> >> -			return err;
>> >>
>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>> >>  						&geminilake_hdmi[i]);
>> >> diff --git a/sound/soc/intel/boards/kbl_da7219_max98357a.c
>> >> b/sound/soc/intel/boards/kbl_da7219_max98357a.c
>> >> index 07491a0..f293307 100644
>> >> --- a/sound/soc/intel/boards/kbl_da7219_max98357a.c
>> >> +++ b/sound/soc/intel/boards/kbl_da7219_max98357a.c
>> >> @@ -519,25 +519,15 @@ static struct snd_soc_dai_link kabylake_dais[] =
>{
>> >>  	},
>> >>  };
>> >>
>> >> -#define NAME_SIZE	32
>> >>  static int kabylake_card_late_probe(struct snd_soc_card *card)  {
>> >>  	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
>> >>  	struct kbl_hdmi_pcm *pcm;
>> >>  	struct snd_soc_component *component = NULL;
>> >>  	int err, i = 0;
>> >> -	char jack_name[NAME_SIZE];
>> >>
>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>> >>  		component = pcm->codec_dai->component;
>> >> -		snprintf(jack_name, sizeof(jack_name),
>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>> >> -					SND_JACK_AVOUT, &skylake_hdmi[i],
>> >> -					NULL, 0);
>> >> -
>> >> -		if (err)
>> >> -			return err;
>> >>
>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>> >>  				&skylake_hdmi[i]);
>> >> diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c
>> >> b/sound/soc/intel/boards/kbl_da7219_max98927.c
>> >> index f72a7bf..84d3609 100644
>> >> --- a/sound/soc/intel/boards/kbl_da7219_max98927.c
>> >> +++ b/sound/soc/intel/boards/kbl_da7219_max98927.c
>> >> @@ -34,7 +34,6 @@
>> >>
>> >>  #define DUAL_CHANNEL	2
>> >>  #define QUAD_CHANNEL	4
>> >> -#define NAME_SIZE	32
>> >>
>> >>  static struct snd_soc_card *kabylake_audio_card;  static struct
>> >> snd_soc_jack kabylake_hdmi[3]; @@ -952,18 +951,9 @@ static int
>> >> kabylake_card_late_probe(struct snd_soc_card *card)
>> >>  	struct kbl_hdmi_pcm *pcm;
>> >>  	struct snd_soc_component *component = NULL;
>> >>  	int err, i = 0;
>> >> -	char jack_name[NAME_SIZE];
>> >>
>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>> >>  		component = pcm->codec_dai->component;
>> >> -		snprintf(jack_name, sizeof(jack_name),
>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>> >> -					SND_JACK_AVOUT, &kabylake_hdmi[i],
>> >> -					NULL, 0);
>> >> -
>> >> -		if (err)
>> >> -			return err;
>> >>
>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>> >>  						&kabylake_hdmi[i]);
>> >> diff --git a/sound/soc/intel/boards/kbl_rt5660.c
>> >> b/sound/soc/intel/boards/kbl_rt5660.c
>> >> index 3255e00..06411bf 100644
>> >> --- a/sound/soc/intel/boards/kbl_rt5660.c
>> >> +++ b/sound/soc/intel/boards/kbl_rt5660.c
>> >> @@ -447,25 +447,15 @@ static struct snd_soc_dai_link
>> >> kabylake_rt5660_dais[] = {  };
>> >>
>> >>
>> >> -#define NAME_SIZE	32
>> >>  static int kabylake_card_late_probe(struct snd_soc_card *card)  {
>> >>  	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
>> >>  	struct kbl_hdmi_pcm *pcm;
>> >>  	struct snd_soc_component *component = NULL;
>> >>  	int err, i = 0;
>> >> -	char jack_name[NAME_SIZE];
>> >>
>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>> >>  		component = pcm->codec_dai->component;
>> >> -		snprintf(jack_name, sizeof(jack_name),
>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>> >> -					SND_JACK_AVOUT, &skylake_hdmi[i],
>> >> -					NULL, 0);
>> >> -
>> >> -		if (err)
>> >> -			return err;
>> >>
>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>> >>  				&skylake_hdmi[i]);
>> >> diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c
>> >> b/sound/soc/intel/boards/kbl_rt5663_max98927.c
>> >> index d714752..9c43c6c 100644
>> >> --- a/sound/soc/intel/boards/kbl_rt5663_max98927.c
>> >> +++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c
>> >> @@ -898,25 +898,15 @@ static struct snd_soc_dai_link
>> >kabylake_5663_dais[] = {
>> >>  	},
>> >>  };
>> >>
>> >> -#define NAME_SIZE	32
>> >>  static int kabylake_card_late_probe(struct snd_soc_card *card)  {
>> >>  	struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(card);
>> >>  	struct kbl_hdmi_pcm *pcm;
>> >>  	struct snd_soc_component *component = NULL;
>> >>  	int err, i = 0;
>> >> -	char jack_name[NAME_SIZE];
>> >>
>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>> >>  		component = pcm->codec_dai->component;
>> >> -		snprintf(jack_name, sizeof(jack_name),
>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>> >> -					SND_JACK_AVOUT, &skylake_hdmi[i],
>> >> -					NULL, 0);
>> >> -
>> >> -		if (err)
>> >> -			return err;
>> >>
>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>> >>  						&skylake_hdmi[i]);
>> >> diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
>> >> b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
>> >> index 879f142..8fe4007 100644
>> >> --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
>> >> +++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
>> >> @@ -40,7 +40,6 @@
>> >>  #define RT5663_DEV_NAME "i2c-10EC5663:00"
>> >>  #define RT5514_AIF1_BCLK_FREQ (48000 * 8 * 16)  #define
>> >> RT5514_AIF1_SYSCLK_FREQ 12288000 -#define NAME_SIZE 32
>> >>
>> >>  #define DMIC_CH(p) p->list[p->count-1]
>> >>
>> >> @@ -600,18 +599,10 @@ static int kabylake_card_late_probe(struct
>> >snd_soc_card *card)
>> >>  	struct kbl_hdmi_pcm *pcm;
>> >>  	struct snd_soc_component *component = NULL;
>> >>  	int err, i = 0;
>> >> -	char jack_name[NAME_SIZE];
>> >>
>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>> >>  		component = pcm->codec_dai->component;
>> >> -		snprintf(jack_name, sizeof(jack_name),
>> >> -			"HDMI/DP,pcm=%d Jack", pcm->device);
>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>> >> -				SND_JACK_AVOUT, &ctx->kabylake_hdmi[i],
>> >> -				NULL, 0);
>> >>
>> >> -		if (err)
>> >> -			return err;
>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>> >>  						&ctx->kabylake_hdmi[i]);
>> >>  		if (err < 0)
>> >> diff --git a/sound/soc/intel/boards/skl_hda_dsp_common.c
>> >> b/sound/soc/intel/boards/skl_hda_dsp_common.c
>> >> index 8b68f41..0f57fc2 100644
>> >> --- a/sound/soc/intel/boards/skl_hda_dsp_common.c
>> >> +++ b/sound/soc/intel/boards/skl_hda_dsp_common.c
>> >> @@ -118,19 +118,10 @@ int skl_hda_hdmi_jack_init(struct
>> >> snd_soc_card
>> >*card)
>> >>  	struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card);
>> >>  	struct snd_soc_component *component = NULL;
>> >>  	struct skl_hda_hdmi_pcm *pcm;
>> >> -	char jack_name[NAME_SIZE];
>> >>  	int err;
>> >>
>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>> >>  		component = pcm->codec_dai->component;
>> >> -		snprintf(jack_name, sizeof(jack_name),
>> >> -			 "HDMI/DP, pcm=%d Jack", pcm->device);
>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>> >> -					    SND_JACK_AVOUT, &pcm-
>> >>hdmi_jack,
>> >> -					    NULL, 0);
>> >> -
>> >> -		if (err)
>> >> -			return err;
>> >>
>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>> >>  					  &pcm->hdmi_jack);
>> >> diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
>> >> b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
>> >> index 0922106..aca426f 100644
>> >> --- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
>> >> +++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
>> >> @@ -587,26 +587,15 @@ static struct snd_soc_dai_link skylake_dais[] = {
>> >>  	},
>> >>  };
>> >>
>> >> -#define NAME_SIZE	32
>> >>  static int skylake_card_late_probe(struct snd_soc_card *card)  {
>> >>  	struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(card);
>> >>  	struct skl_hdmi_pcm *pcm;
>> >>  	struct snd_soc_component *component = NULL;
>> >>  	int err, i = 0;
>> >> -	char jack_name[NAME_SIZE];
>> >>
>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>> >>  		component = pcm->codec_dai->component;
>> >> -		snprintf(jack_name, sizeof(jack_name),
>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>> >> -					SND_JACK_AVOUT,
>> >> -					&skylake_hdmi[i],
>> >> -					NULL, 0);
>> >> -
>> >> -		if (err)
>> >> -			return err;
>> >>
>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>> >>  						&skylake_hdmi[i]);
>> >> diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
>> >> b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
>> >> index 8433c52..788a837 100644
>> >> --- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
>> >> +++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
>> >> @@ -638,26 +638,15 @@ static struct snd_soc_dai_link skylake_dais[] = {
>> >>  	},
>> >>  };
>> >>
>> >> -#define NAME_SIZE	32
>> >>  static int skylake_card_late_probe(struct snd_soc_card *card)  {
>> >>  	struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(card);
>> >>  	struct skl_hdmi_pcm *pcm;
>> >>  	struct snd_soc_component *component = NULL;
>> >>  	int err, i = 0;
>> >> -	char jack_name[NAME_SIZE];
>> >>
>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>> >>  		component = pcm->codec_dai->component;
>> >> -		snprintf(jack_name, sizeof(jack_name),
>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>> >> -					SND_JACK_AVOUT,
>> >> -					&skylake_hdmi[i],
>> >> -					NULL, 0);
>> >> -
>> >> -		if (err)
>> >> -			return err;
>> >>
>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>> >>  						&skylake_hdmi[i]);
>> >> diff --git a/sound/soc/intel/boards/skl_rt286.c
>> >> b/sound/soc/intel/boards/skl_rt286.c
>> >> index 0e1818d..5d245f5 100644
>> >> --- a/sound/soc/intel/boards/skl_rt286.c
>> >> +++ b/sound/soc/intel/boards/skl_rt286.c
>> >> @@ -473,25 +473,15 @@ static struct snd_soc_dai_link
>> >> skylake_rt286_dais[]
>> >= {
>> >>  	},
>> >>  };
>> >>
>> >> -#define NAME_SIZE	32
>> >>  static int skylake_card_late_probe(struct snd_soc_card *card)  {
>> >>  	struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(card);
>> >>  	struct skl_hdmi_pcm *pcm;
>> >>  	struct snd_soc_component *component = NULL;
>> >>  	int err, i = 0;
>> >> -	char jack_name[NAME_SIZE];
>> >>
>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>> >>  		component = pcm->codec_dai->component;
>> >> -		snprintf(jack_name, sizeof(jack_name),
>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>> >> -					SND_JACK_AVOUT, &skylake_hdmi[i],
>> >> -					NULL, 0);
>> >> -
>> >> -		if (err)
>> >> -			return err;
>> >>
>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>> >>  						&skylake_hdmi[i]);
>> >> diff --git a/sound/soc/intel/boards/sof_rt5682.c
>> >> b/sound/soc/intel/boards/sof_rt5682.c
>> >> index f28fb98..660e4a6 100644
>> >> --- a/sound/soc/intel/boards/sof_rt5682.c
>> >> +++ b/sound/soc/intel/boards/sof_rt5682.c
>> >> @@ -22,8 +22,6 @@
>> >>  #include "../../codecs/rt5682.h"
>> >>  #include "../../codecs/hdac_hdmi.h"
>> >>
>> >> -#define NAME_SIZE 32
>> >> -
>> >>  #define SOF_RT5682_SSP_CODEC(quirk)		((quirk) & GENMASK(2,
>> >0))
>> >>  #define SOF_RT5682_SSP_CODEC_MASK			(GENMASK(2,
>> >0))
>> >>  #define SOF_RT5682_MCLK_EN			BIT(3)
>> >> @@ -216,7 +214,6 @@ static int sof_card_late_probe(struct
>> >> snd_soc_card
>> >> *card)  {
>> >>  	struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
>> >>  	struct snd_soc_component *component = NULL;
>> >> -	char jack_name[NAME_SIZE];
>> >>  	struct sof_hdmi_pcm *pcm;
>> >>  	int err = 0;
>> >>  	int i = 0;
>> >> @@ -227,14 +224,6 @@ static int sof_card_late_probe(struct
>> >> snd_soc_card *card)
>> >>
>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>> >>  		component = pcm->codec_dai->component;
>> >> -		snprintf(jack_name, sizeof(jack_name),
>> >> -			 "HDMI/DP, pcm=%d Jack", pcm->device);
>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>> >> -					    SND_JACK_AVOUT, &sof_hdmi[i],
>> >> -					    NULL, 0);
>> >> -
>> >> -		if (err)
>> >> -			return err;
>> >>
>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>> >>  					  &sof_hdmi[i]);
>> >> --
>> >> 2.7.4
>> >>
>>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks
  2019-05-31  2:27         ` Yang, Libin
@ 2019-06-14  8:04           ` Yang, Libin
  2019-06-25  6:02             ` Yang, Libin
  0 siblings, 1 reply; 15+ messages in thread
From: Yang, Libin @ 2019-06-14  8:04 UTC (permalink / raw)
  To: 'Takashi Iwai'
  Cc: 'alsa-devel@alsa-project.org',
	'broonie@kernel.org',
	'pierre-louis.bossart@linux.intel.com'

[-- Attachment #1: Type: text/plain, Size: 33110 bytes --]

Hi Takashi,

Sorry for a long delay for the hdmi jacks. I was busy on another critical issue
last 2 weeks. I have worked out the UCM configuration files. Please check the 
attachment. It is a long file, so I use the attachment instead of the patch mode.
Based on my test, it works well. Could you please help review if the configuration
file is OK or not. I will do more test on the meantime, including DPMST and
NON-DPMST.

Regards,
Libin


>-----Original Message-----
>From: Yang, Libin
>Sent: Friday, May 31, 2019 10:27 AM
>To: Takashi Iwai <tiwai@suse.de>
>Cc: alsa-devel@alsa-project.org; broonie@kernel.org; pierre-
>louis.bossart@linux.intel.com
>Subject: RE: [alsa-devel] [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks
>
>Hi Takashi,
>
>>
>>On Thu, 30 May 2019 17:00:24 +0200,
>>Yang, Libin wrote:
>>>
>>> Hi Takashi,
>>>
>>> >-----Original Message-----
>>> >From: Takashi Iwai [mailto:tiwai@suse.de]
>>> >Sent: Thursday, May 30, 2019 3:13 PM
>>> >To: Yang, Libin <libin.yang@intel.com>
>>> >Cc: alsa-devel@alsa-project.org; broonie@kernel.org; pierre-
>>> >louis.bossart@linux.intel.com
>>> >Subject: Re: [alsa-devel] [RFC PATCH 3/4] ASoC: hdac_hdmi: refine
>>> >hdmi jacks
>>> >
>>> >On Mon, 27 May 2019 11:07:26 +0200,
>>> >libin.yang@intel.com wrote:
>>> >>
>>> >> From: Libin Yang <libin.yang@intel.com>
>>> >>
>>> >> This patch does the following actions:
>>> >> 1) move snd_soc_card_jack_new() from machine driver to codec driver.
>>> >>    This is because the jack information is more lated to the codec
>>> >>    Also this patch calls snd_jack_add_new_kctl() to export the jack kctl
>>> >>    to userspace.
>>> >>
>>> >> 2) jack is bound to pcm in origal code. The patch binds jack to pin-port.
>>> >>    This mean each pin-port (3x3) has a jack. pin-port is used for DP-MST
>>> >>    mode. The port means device entry for DP-MST in hdac_hdmi
>>> >>    As hdac_hdmi allows user to map the pin-port to a pcm manually,
>>> >> the
>>jack
>>> >>    is bound to pcm is not accurate.
>>> >>    However, PA assumes jack is bound to PCM for the legacy mode.
>>> >>    For example, for ubuntu, in
>>> >>    /usr/share/pulseaudio/alsa-mixer/paths/hdmi-output-x.conf uses
>>> >>    "Jack HDMI/DP,pcm=n" to find which jack event is used.
>>> >>    This main issue is: pcm number is fixed (3, 7, 8, 9, 10) for hdmi in
>>> >>    legacy mode. But it is not always the same for ASoC hdmi audio.
>>> >
>>> >The question is what brings this change practically.  On the legacy
>>> >driver, as the jack is bound with the PCM, user-space (typically PA)
>>> >who receives a jack connection event opens simply the corresponding
>>> >PCM substream.  Now, for
>>> >ASoC:
>>> >  1. Which PCM substream?
>>> >  2. How to set up the routing?
>>> >
>>> >I assume the 1 doens't matter, any substream, unlike the legacy case.
>>> >But how is 2 done automatically?
>>>
>>> For the legacy HDA, there are 2 mode (dynamic pcm assignment (DPMST)
>>> and static pcm assignment (NON-DPMST)).
>>> 1) For static pcm assignment, pcm is always statically mapped to pin.
>>> For example, pcm1 <=> pin 1; pcm <=> pin 2 and so on. So it is the
>>> same to bind jack to pcm or to pin.
>>> 2) For dynamic pcm assignment, in generic_hdmi_build_jack(), the jack
>>> is bound to PCM when it is created (spec->pcm_rec[pcm_idx].jack). We
>>> will find the jack by pcm_idx. And when monitor is connected to a
>>> pin,
>>> update_eld() will be called. In update_eld(), it will call
>>> hdmi_attach_hda_pcm() to find a pcm to bind to the pin. So it can
>>> find a jack (from the pcm) and report its status to userspace.
>>>
>>> So in a word for legacy HDA, it can always find a PCM (no matter in
>>> static mode or in dynamic mode) when the monitor is connected to a
>>> pin. This means it can always update the status of to userspace that
>>> the pcm status is changed.
>>
>>Right, that's why the jack control has a pcm suffix.  It is bound with
>>the PCM stream in the end, so user-space can simply open it.
>>
>>> However, in hdac_hdmi, there is no such dynamic pcm assignment. And
>>> it is not statically assignment of pcm to pin. PCM is statically bound to cvt.
>>> hdac_hdmi allows user to assign a cvt to a pin with alsamixer ( in
>>> function hdac_hdmi_set_pin_port_mux(), so this function maps the pin
>>> to
>>the pcm).
>>> As user may assign NONE pcm to a pin in alsamixer, this means a pin
>>> can be assigned none of pcms. So if we mapped jack to pcm, we may not
>>> find any jack for the pin when a monitor is connected to the pin.
>>> This means driver can't notify userspace of the monitor connection.
>>> As you know, PA will use the monitor connection status to decide
>>> whether to user it or not. So this is the problem. The root cause is
>>> pcm is bound to cvt. And pin may be not bound to any pcm (This is the
>>> difference from the legacy hda).
>>>
>>> In my patch, as jack is bound to pin-port, so it can always notify
>>> userspace that a monitor is connected. We can use configuration in
>>> /usr/share/alsa/ ucm or /usr/share/pulseaudio to configure the amixer
>>> to assign a pcm to the pin (monitor). And userspace can playback on
>>> the
>>monitor now.
>>
>>Then please prepare the UCM stuff at first and make sure that
>>everything works with the proposed change.  The kernel changes can be
>>merged once after all things get ready.
>
>OK. I will prepare the UCM and PA configurations to check it works well and
>the purpose is patch should be compatible with the old drivers.
>
>Regards,
>Libin
>
>>
>>
>>thanks,
>>
>>Takashi
>>
>>>
>>> Regards,
>>> Libin
>>>
>>> >
>>> >
>>> >thanks,
>>> >
>>> >Takashi
>>> >
>>> >>
>>> >> Signed-off-by: Libin Yang <libin.yang@intel.com>
>>> >> ---
>>> >>  sound/soc/codecs/hdac_hdmi.c                       | 127 ++++++++++++---------
>>> >>  sound/soc/intel/boards/bxt_da7219_max98357a.c      |  10 --
>>> >>  sound/soc/intel/boards/bxt_rt298.c                 |  10 --
>>> >>  sound/soc/intel/boards/glk_rt5682_max98357a.c      |  10 --
>>> >>  sound/soc/intel/boards/kbl_da7219_max98357a.c      |  10 --
>>> >>  sound/soc/intel/boards/kbl_da7219_max98927.c       |  10 --
>>> >>  sound/soc/intel/boards/kbl_rt5660.c                |  10 --
>>> >>  sound/soc/intel/boards/kbl_rt5663_max98927.c       |  10 --
>>> >>  .../soc/intel/boards/kbl_rt5663_rt5514_max98927.c  |   9 --
>>> >>  sound/soc/intel/boards/skl_hda_dsp_common.c        |   9 --
>>> >>  sound/soc/intel/boards/skl_nau88l25_max98357a.c    |  11 --
>>> >>  sound/soc/intel/boards/skl_nau88l25_ssm4567.c      |  11 --
>>> >>  sound/soc/intel/boards/skl_rt286.c                 |  10 --
>>> >>  sound/soc/intel/boards/sof_rt5682.c                |  11 --
>>> >>  14 files changed, 74 insertions(+), 184 deletions(-)
>>> >>
>>> >> diff --git a/sound/soc/codecs/hdac_hdmi.c
>>> >> b/sound/soc/codecs/hdac_hdmi.c index 90c2ee3..ed267fa 100644
>>> >> --- a/sound/soc/codecs/hdac_hdmi.c
>>> >> +++ b/sound/soc/codecs/hdac_hdmi.c
>>> >> @@ -4,6 +4,7 @@
>>> >>   *  Copyright (C) 2014-2015 Intel Corp
>>> >>   *  Author: Samreen Nilofer <samreen.nilofer@intel.com>
>>> >>   *	    Subhransu S. Prusty <subhransu.s.prusty@intel.com>
>>> >> + *	    Libin Yang <libin.yang@intel.com>
>>> >>   *
>>> >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>~
>>~~~
>>> >~~~~~~~~~
>>> >>   *
>>> >>   *  This program is free software; you can redistribute it and/or
>>> >> modify @@ -30,6 +31,7 @@  #include <sound/hda_i915.h>  #include
>>> >> <sound/pcm_drm_eld.h>  #include <sound/hda_chmap.h>
>>> >> +#include <sound/hda_codec.h>
>>> >>  #include "../../hda/local.h"
>>> >>  #include "hdac_hdmi.h"
>>> >>
>>> >> @@ -95,6 +97,8 @@ struct hdac_hdmi_port {
>>> >>  	int num_mux_nids;
>>> >>  	hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
>>> >>  	struct hdac_hdmi_eld eld;
>>> >> +	struct snd_soc_jack jack;
>>> >> +	int jack_event;
>>> >>  	const char *jack_pin;
>>> >>  	struct snd_soc_dapm_context *dapm;
>>> >>  	const char *output_pin;
>>> >> @@ -105,14 +109,12 @@ struct hdac_hdmi_pcm {
>>> >>  	int pcm_id;
>>> >>  	struct list_head port_list;
>>> >>  	struct hdac_hdmi_cvt *cvt;
>>> >> -	struct snd_soc_jack *jack;
>>> >>  	int stream_tag;
>>> >>  	int channels;
>>> >>  	int format;
>>> >>  	bool chmap_set;
>>> >>  	unsigned char chmap[8]; /* ALSA API channel-map */
>>> >>  	struct mutex lock;
>>> >> -	int jack_event;
>>> >>  };
>>> >>
>>> >>  struct hdac_hdmi_dai_port_map {
>>> >> @@ -166,8 +168,7 @@ hdac_hdmi_get_pcm_from_cvt(struct
>>> >hdac_hdmi_priv *hdmi,
>>> >>  	return pcm;
>>> >>  }
>>> >>
>>> >> -static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
>>> >> -		struct hdac_hdmi_port *port, bool is_connect)
>>> >> +static void hdac_hdmi_jack_report(struct hdac_hdmi_port *port,
>>> >> +bool
>>> >> +is_connect)
>>> >>  {
>>> >>  	struct hdac_device *hdev = port->pin->hdev;
>>> >>
>>> >> @@ -176,19 +177,25 @@ static void hdac_hdmi_jack_report(struct
>>> >hdac_hdmi_pcm *pcm,
>>> >>  	else
>>> >>  		snd_soc_dapm_disable_pin(port->dapm, port->jack_pin);
>>> >>
>>> >> +	/* if jack is not ready, skip reporting jack status */
>>> >> +	if (!port->jack.jack) {
>>> >> +		snd_soc_dapm_sync(port->dapm);
>>> >> +		return;
>>> >> +	}
>>> >> +
>>> >>  	if (is_connect) {
>>> >> -		if (pcm->jack_event == 0) {
>>> >> +		if (port->jack_event == 0) {
>>> >>  			dev_dbg(&hdev->dev,
>>> >> -					"jack report for pcm=%d\n",
>>> >> -					pcm->pcm_id);
>>> >> -			snd_soc_jack_report(pcm->jack, SND_JACK_AVOUT,
>>> >> -						SND_JACK_AVOUT);
>>> >> +				"jack report for pin:port = %d:%d\n",
>>> >> +				port->id, port->pin->nid);
>>> >> +			snd_soc_jack_report(&port->jack, SND_JACK_AVOUT,
>>> >> +					    SND_JACK_AVOUT);
>>> >>  		}
>>> >> -		pcm->jack_event = 1;
>>> >> +		port->jack_event = 1;
>>> >>  	} else {
>>> >> -		if (pcm->jack_event == 1)
>>> >> -			snd_soc_jack_report(pcm->jack, 0, SND_JACK_AVOUT);
>>> >> -		pcm->jack_event = 0;
>>> >> +		if (port->jack_event == 1)
>>> >> +			snd_soc_jack_report(&port->jack, 0,
>>> >SND_JACK_AVOUT);
>>> >> +		port->jack_event = 0;
>>> >>  	}
>>> >>
>>> >>  	snd_soc_dapm_sync(port->dapm);
>>> >> @@ -1235,26 +1242,15 @@ static void
>hdac_hdmi_present_sense(struct
>>> >hdac_hdmi_pin *pin,
>>> >>  	pcm = hdac_hdmi_get_pcm(hdev, port);
>>> >>
>>> >>  	if (!port->eld.monitor_present || !port->eld.eld_valid) {
>>> >> -
>>> >>  		dev_err(&hdev->dev, "%s: disconnect for pin:port %d:%d\n",
>>> >>  						__func__, pin->nid, port->id);
>>> >> -
>>> >> -		/*
>>> >> -		 * PCMs are not registered during device probe, so don't
>>> >> -		 * report jack here. It will be done in usermode mux
>>> >> -		 * control select.
>>> >> -		 */
>>> >> -		if (pcm)
>>> >> -			hdac_hdmi_jack_report(pcm, port, false);
>>> >> -
>>> >> +		hdac_hdmi_jack_report(port, false);
>>> >>  		mutex_unlock(&hdmi->pin_mutex);
>>> >>  		return;
>>> >>  	}
>>> >>
>>> >>  	if (port->eld.monitor_present && port->eld.eld_valid) {
>>> >> -		if (pcm)
>>> >> -			hdac_hdmi_jack_report(pcm, port, true);
>>> >> -
>>> >> +		hdac_hdmi_jack_report(port, true);
>>> >>  		print_hex_dump_debug("ELD: ", DUMP_PREFIX_OFFSET, 16, 1,
>>> >>  			  port->eld.eld_buffer, port->eld.eld_size, false);
>>> >>
>>> >> @@ -1650,6 +1646,30 @@ static int
>>> >> create_fill_jack_kcontrols(struct
>>> >snd_soc_card *card,
>>> >>  	return snd_soc_add_card_controls(card, kc, i);  }
>>> >>
>>> >> +static void hdac_hdmi_present_sense_all_pins(struct hdac_device
>>*hdev,
>>> >> +			struct hdac_hdmi_priv *hdmi, bool detect_pin_caps) {
>>> >> +	int i;
>>> >> +	struct hdac_hdmi_pin *pin;
>>> >> +
>>> >> +	list_for_each_entry(pin, &hdmi->pin_list, head) {
>>> >> +		if (detect_pin_caps) {
>>> >> +
>>> >> +			if (hdac_hdmi_get_port_len(hdev, pin->nid)  == 0)
>>> >> +				pin->mst_capable = false;
>>> >> +			else
>>> >> +				pin->mst_capable = true;
>>> >> +		}
>>> >> +
>>> >> +		for (i = 0; i < pin->num_ports; i++) {
>>> >> +			if (!pin->mst_capable && i > 0)
>>> >> +				continue;
>>> >> +
>>> >> +			hdac_hdmi_present_sense(pin, &pin->ports[i]);
>>> >> +		}
>>> >> +	}
>>> >> +}
>>> >> +
>>> >>  int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
>>> >>  			struct snd_soc_dapm_context *dapm)  { @@ -1659,6
>>> >+1679,7 @@ int
>>> >> hdac_hdmi_jack_port_init(struct snd_soc_component *component,
>>> >>  	struct snd_soc_dapm_widget *widgets;
>>> >>  	struct snd_soc_dapm_route *route;
>>> >>  	char w_name[NAME_SIZE];
>>> >> +	char jack_name[NAME_SIZE];
>>> >>  	int i = 0, j, ret;
>>> >>
>>> >>  	widgets = devm_kcalloc(dapm->dev, hdmi->num_ports, @@ -1687,6
>>> >> +1708,30 @@ int hdac_hdmi_jack_port_init(struct snd_soc_component
>>> >*component,
>>> >>  			pin->ports[j].jack_pin = widgets[i].name;
>>> >>  			pin->ports[j].dapm = dapm;
>>> >>
>>> >> +			/*
>>> >> +			 * Create pin-port jack. Each port (device entry) of
>>> >> +			 * the pin has a corresponding jack
>>> >> +			 */
>>> >> +			snprintf(jack_name, sizeof(jack_name),
>>> >> +				 "HDMI/DP, pin:port=%d:%d Jack",
>>> >> +				  pin->nid, pin->ports[j].id);
>>> >> +			ret = snd_soc_card_jack_new(dapm->card, jack_name,
>>> >> +						    SND_JACK_AVOUT,
>>> >> +						    &(pin->ports[j].jack),
>>> >> +						    NULL, 0);
>>> >> +			if (ret)
>>> >> +				return ret;
>>> >> +
>>> >> +			/* create the jack kctl */
>>> >> +			ret = snd_jack_add_new_kctl(pin->ports[j].jack.jack,
>>> >> +						    jack_name,
>>> >SND_JACK_AVOUT);
>>> >> +			/*
>>> >> +			 * It's not a critical issue if driver fails to
>>> >> +			 * create jack kctl.
>>> >> +			 */
>>> >> +			if (ret)
>>> >> +				dev_warn(&hdev->dev, "failed creating Jack
>>> >kctl\n");
>>> >> +
>>> >>  			/* add to route from Jack widget to output */
>>> >>  			hdac_hdmi_fill_route(&route[i], pin->ports[j].jack_pin,
>>> >>  					NULL, pin->ports[j].output_pin, NULL);
>>> >@@ -1695,6 +1740,9 @@ int
>>> >> hdac_hdmi_jack_port_init(struct snd_soc_component *component,
>>> >>  		}
>>> >>  	}
>>> >>
>>> >> +	/* now jack is ready, let's update the status */
>>> >> +	hdac_hdmi_present_sense_all_pins(hdev, hdmi, true);
>>> >> +
>>> >>  	/* Add Route from Jack widget to the output widget */
>>> >>  	ret = snd_soc_dapm_new_controls(dapm, widgets, hdmi- num_ports);
>>> >>  	if (ret < 0)
>>> >> @@ -1744,8 +1792,6 @@ int hdac_hdmi_jack_init(struct snd_soc_dai
>>> >>*dai,
>>> >int device,
>>> >>  		return -ENOMEM;
>>> >>  	pcm->pcm_id = device;
>>> >>  	pcm->cvt = hdmi->dai_map[dai->id].cvt;
>>> >> -	pcm->jack_event = 0;
>>> >> -	pcm->jack = jack;
>>> >>  	mutex_init(&pcm->lock);
>>> >>  	INIT_LIST_HEAD(&pcm->port_list);
>>> >>  	snd_pcm = hdac_hdmi_get_pcm_from_id(dai->component->card,
>>> >device);
>>> >> @@ -1765,30 +1811,6 @@ int hdac_hdmi_jack_init(struct snd_soc_dai
>>> >> *dai, int device,  }  EXPORT_SYMBOL_GPL(hdac_hdmi_jack_init);
>>> >>
>>> >> -static void hdac_hdmi_present_sense_all_pins(struct hdac_device
>*hdev,
>>> >> -			struct hdac_hdmi_priv *hdmi, bool detect_pin_caps)
>>> >> -{
>>> >> -	int i;
>>> >> -	struct hdac_hdmi_pin *pin;
>>> >> -
>>> >> -	list_for_each_entry(pin, &hdmi->pin_list, head) {
>>> >> -		if (detect_pin_caps) {
>>> >> -
>>> >> -			if (hdac_hdmi_get_port_len(hdev, pin->nid)  == 0)
>>> >> -				pin->mst_capable = false;
>>> >> -			else
>>> >> -				pin->mst_capable = true;
>>> >> -		}
>>> >> -
>>> >> -		for (i = 0; i < pin->num_ports; i++) {
>>> >> -			if (!pin->mst_capable && i > 0)
>>> >> -				continue;
>>> >> -
>>> >> -			hdac_hdmi_present_sense(pin, &pin->ports[i]);
>>> >> -		}
>>> >> -	}
>>> >> -}
>>> >> -
>>> >>  static int hdmi_codec_probe(struct snd_soc_component *component)
>{
>>> >>  	struct hdac_hdmi_priv *hdmi =
>>> >> snd_soc_component_get_drvdata(component);
>>> >> @@ -1823,7 +1845,6 @@ static int hdmi_codec_probe(struct
>>> >snd_soc_component *component)
>>> >>  		return ret;
>>> >>  	}
>>> >>
>>> >> -	hdac_hdmi_present_sense_all_pins(hdev, hdmi, true);
>>> >>  	/* Imp: Store the card pointer in hda_codec */
>>> >>  	hdmi->card = dapm->card->snd_card;
>>> >>
>>> >> diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c
>>> >> b/sound/soc/intel/boards/bxt_da7219_max98357a.c
>>> >> index 5cadb7f..c69cfa9 100644
>>> >> --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c
>>> >> +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
>>> >> @@ -573,14 +573,12 @@ static const struct x86_cpu_id glk_ids[] = {
>>> >>  	{}
>>> >>  };
>>> >>
>>> >> -#define NAME_SIZE	32
>>> >>  static int bxt_card_late_probe(struct snd_soc_card *card)  {
>>> >>  	struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card);
>>> >>  	struct bxt_hdmi_pcm *pcm;
>>> >>  	struct snd_soc_component *component = NULL;
>>> >>  	int err, i = 0;
>>> >> -	char jack_name[NAME_SIZE];
>>> >>
>>> >>  	if (x86_match_cpu(glk_ids))
>>> >>  		snd_soc_dapm_add_routes(&card->dapm, gemini_map, @@
>>> >-591,14 +589,6
>>> >> @@ static int bxt_card_late_probe(struct snd_soc_card *card)
>>> >>
>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>> >>  		component = pcm->codec_dai->component;
>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>> >> -					SND_JACK_AVOUT, &broxton_hdmi[i],
>>> >> -					NULL, 0);
>>> >> -
>>> >> -		if (err)
>>> >> -			return err;
>>> >>
>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>> >>  						&broxton_hdmi[i]);
>>> >> diff --git a/sound/soc/intel/boards/bxt_rt298.c
>>> >> b/sound/soc/intel/boards/bxt_rt298.c
>>> >> index e91057f..d1372891 100644
>>> >> --- a/sound/soc/intel/boards/bxt_rt298.c
>>> >> +++ b/sound/soc/intel/boards/bxt_rt298.c
>>> >> @@ -507,25 +507,15 @@ static struct snd_soc_dai_link
>>> >> broxton_rt298_dais[]
>>> >= {
>>> >>  	},
>>> >>  };
>>> >>
>>> >> -#define NAME_SIZE	32
>>> >>  static int bxt_card_late_probe(struct snd_soc_card *card)  {
>>> >>  	struct bxt_rt286_private *ctx = snd_soc_card_get_drvdata(card);
>>> >>  	struct bxt_hdmi_pcm *pcm;
>>> >>  	struct snd_soc_component *component = NULL;
>>> >>  	int err, i = 0;
>>> >> -	char jack_name[NAME_SIZE];
>>> >>
>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>> >>  		component = pcm->codec_dai->component;
>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>> >> -					SND_JACK_AVOUT, &broxton_hdmi[i],
>>> >> -					NULL, 0);
>>> >> -
>>> >> -		if (err)
>>> >> -			return err;
>>> >>
>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>> >>  						&broxton_hdmi[i]);
>>> >> diff --git a/sound/soc/intel/boards/glk_rt5682_max98357a.c
>>> >> b/sound/soc/intel/boards/glk_rt5682_max98357a.c
>>> >> index d17126f..2a35974 100644
>>> >> --- a/sound/soc/intel/boards/glk_rt5682_max98357a.c
>>> >> +++ b/sound/soc/intel/boards/glk_rt5682_max98357a.c
>>> >> @@ -29,7 +29,6 @@
>>> >>  #define MAXIM_DEV0_NAME "MX98357A:00"
>>> >>  #define DUAL_CHANNEL 2
>>> >>  #define QUAD_CHANNEL 4
>>> >> -#define NAME_SIZE 32
>>> >>
>>> >>  static struct snd_soc_jack geminilake_hdmi[3];
>>> >>
>>> >> @@ -523,21 +522,12 @@ static int glk_card_late_probe(struct
>>> >> snd_soc_card *card)  {
>>> >>  	struct glk_card_private *ctx = snd_soc_card_get_drvdata(card);
>>> >>  	struct snd_soc_component *component = NULL;
>>> >> -	char jack_name[NAME_SIZE];
>>> >>  	struct glk_hdmi_pcm *pcm;
>>> >>  	int err = 0;
>>> >>  	int i = 0;
>>> >>
>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>> >>  		component = pcm->codec_dai->component;
>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>> >> -					SND_JACK_AVOUT,
>>> >&geminilake_hdmi[i],
>>> >> -					NULL, 0);
>>> >> -
>>> >> -		if (err)
>>> >> -			return err;
>>> >>
>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>> >>  						&geminilake_hdmi[i]);
>>> >> diff --git a/sound/soc/intel/boards/kbl_da7219_max98357a.c
>>> >> b/sound/soc/intel/boards/kbl_da7219_max98357a.c
>>> >> index 07491a0..f293307 100644
>>> >> --- a/sound/soc/intel/boards/kbl_da7219_max98357a.c
>>> >> +++ b/sound/soc/intel/boards/kbl_da7219_max98357a.c
>>> >> @@ -519,25 +519,15 @@ static struct snd_soc_dai_link
>>> >> kabylake_dais[] =
>>{
>>> >>  	},
>>> >>  };
>>> >>
>>> >> -#define NAME_SIZE	32
>>> >>  static int kabylake_card_late_probe(struct snd_soc_card *card)  {
>>> >>  	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
>>> >>  	struct kbl_hdmi_pcm *pcm;
>>> >>  	struct snd_soc_component *component = NULL;
>>> >>  	int err, i = 0;
>>> >> -	char jack_name[NAME_SIZE];
>>> >>
>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>> >>  		component = pcm->codec_dai->component;
>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>> >> -					SND_JACK_AVOUT, &skylake_hdmi[i],
>>> >> -					NULL, 0);
>>> >> -
>>> >> -		if (err)
>>> >> -			return err;
>>> >>
>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>> >>  				&skylake_hdmi[i]);
>>> >> diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c
>>> >> b/sound/soc/intel/boards/kbl_da7219_max98927.c
>>> >> index f72a7bf..84d3609 100644
>>> >> --- a/sound/soc/intel/boards/kbl_da7219_max98927.c
>>> >> +++ b/sound/soc/intel/boards/kbl_da7219_max98927.c
>>> >> @@ -34,7 +34,6 @@
>>> >>
>>> >>  #define DUAL_CHANNEL	2
>>> >>  #define QUAD_CHANNEL	4
>>> >> -#define NAME_SIZE	32
>>> >>
>>> >>  static struct snd_soc_card *kabylake_audio_card;  static struct
>>> >> snd_soc_jack kabylake_hdmi[3]; @@ -952,18 +951,9 @@ static int
>>> >> kabylake_card_late_probe(struct snd_soc_card *card)
>>> >>  	struct kbl_hdmi_pcm *pcm;
>>> >>  	struct snd_soc_component *component = NULL;
>>> >>  	int err, i = 0;
>>> >> -	char jack_name[NAME_SIZE];
>>> >>
>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>> >>  		component = pcm->codec_dai->component;
>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>> >> -					SND_JACK_AVOUT, &kabylake_hdmi[i],
>>> >> -					NULL, 0);
>>> >> -
>>> >> -		if (err)
>>> >> -			return err;
>>> >>
>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>> >>  						&kabylake_hdmi[i]);
>>> >> diff --git a/sound/soc/intel/boards/kbl_rt5660.c
>>> >> b/sound/soc/intel/boards/kbl_rt5660.c
>>> >> index 3255e00..06411bf 100644
>>> >> --- a/sound/soc/intel/boards/kbl_rt5660.c
>>> >> +++ b/sound/soc/intel/boards/kbl_rt5660.c
>>> >> @@ -447,25 +447,15 @@ static struct snd_soc_dai_link
>>> >> kabylake_rt5660_dais[] = {  };
>>> >>
>>> >>
>>> >> -#define NAME_SIZE	32
>>> >>  static int kabylake_card_late_probe(struct snd_soc_card *card)  {
>>> >>  	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
>>> >>  	struct kbl_hdmi_pcm *pcm;
>>> >>  	struct snd_soc_component *component = NULL;
>>> >>  	int err, i = 0;
>>> >> -	char jack_name[NAME_SIZE];
>>> >>
>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>> >>  		component = pcm->codec_dai->component;
>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>> >> -					SND_JACK_AVOUT, &skylake_hdmi[i],
>>> >> -					NULL, 0);
>>> >> -
>>> >> -		if (err)
>>> >> -			return err;
>>> >>
>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>> >>  				&skylake_hdmi[i]);
>>> >> diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c
>>> >> b/sound/soc/intel/boards/kbl_rt5663_max98927.c
>>> >> index d714752..9c43c6c 100644
>>> >> --- a/sound/soc/intel/boards/kbl_rt5663_max98927.c
>>> >> +++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c
>>> >> @@ -898,25 +898,15 @@ static struct snd_soc_dai_link
>>> >kabylake_5663_dais[] = {
>>> >>  	},
>>> >>  };
>>> >>
>>> >> -#define NAME_SIZE	32
>>> >>  static int kabylake_card_late_probe(struct snd_soc_card *card)  {
>>> >>  	struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(card);
>>> >>  	struct kbl_hdmi_pcm *pcm;
>>> >>  	struct snd_soc_component *component = NULL;
>>> >>  	int err, i = 0;
>>> >> -	char jack_name[NAME_SIZE];
>>> >>
>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>> >>  		component = pcm->codec_dai->component;
>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>> >> -					SND_JACK_AVOUT, &skylake_hdmi[i],
>>> >> -					NULL, 0);
>>> >> -
>>> >> -		if (err)
>>> >> -			return err;
>>> >>
>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>> >>  						&skylake_hdmi[i]);
>>> >> diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
>>> >> b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
>>> >> index 879f142..8fe4007 100644
>>> >> --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
>>> >> +++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
>>> >> @@ -40,7 +40,6 @@
>>> >>  #define RT5663_DEV_NAME "i2c-10EC5663:00"
>>> >>  #define RT5514_AIF1_BCLK_FREQ (48000 * 8 * 16)  #define
>>> >> RT5514_AIF1_SYSCLK_FREQ 12288000 -#define NAME_SIZE 32
>>> >>
>>> >>  #define DMIC_CH(p) p->list[p->count-1]
>>> >>
>>> >> @@ -600,18 +599,10 @@ static int kabylake_card_late_probe(struct
>>> >snd_soc_card *card)
>>> >>  	struct kbl_hdmi_pcm *pcm;
>>> >>  	struct snd_soc_component *component = NULL;
>>> >>  	int err, i = 0;
>>> >> -	char jack_name[NAME_SIZE];
>>> >>
>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>> >>  		component = pcm->codec_dai->component;
>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>> >> -			"HDMI/DP,pcm=%d Jack", pcm->device);
>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>> >> -				SND_JACK_AVOUT, &ctx->kabylake_hdmi[i],
>>> >> -				NULL, 0);
>>> >>
>>> >> -		if (err)
>>> >> -			return err;
>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>> >>  						&ctx->kabylake_hdmi[i]);
>>> >>  		if (err < 0)
>>> >> diff --git a/sound/soc/intel/boards/skl_hda_dsp_common.c
>>> >> b/sound/soc/intel/boards/skl_hda_dsp_common.c
>>> >> index 8b68f41..0f57fc2 100644
>>> >> --- a/sound/soc/intel/boards/skl_hda_dsp_common.c
>>> >> +++ b/sound/soc/intel/boards/skl_hda_dsp_common.c
>>> >> @@ -118,19 +118,10 @@ int skl_hda_hdmi_jack_init(struct
>>> >> snd_soc_card
>>> >*card)
>>> >>  	struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card);
>>> >>  	struct snd_soc_component *component = NULL;
>>> >>  	struct skl_hda_hdmi_pcm *pcm;
>>> >> -	char jack_name[NAME_SIZE];
>>> >>  	int err;
>>> >>
>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>> >>  		component = pcm->codec_dai->component;
>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>> >> -			 "HDMI/DP, pcm=%d Jack", pcm->device);
>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>> >> -					    SND_JACK_AVOUT, &pcm-
>>> >>hdmi_jack,
>>> >> -					    NULL, 0);
>>> >> -
>>> >> -		if (err)
>>> >> -			return err;
>>> >>
>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>> >>  					  &pcm->hdmi_jack);
>>> >> diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
>>> >> b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
>>> >> index 0922106..aca426f 100644
>>> >> --- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
>>> >> +++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
>>> >> @@ -587,26 +587,15 @@ static struct snd_soc_dai_link skylake_dais[] =
>{
>>> >>  	},
>>> >>  };
>>> >>
>>> >> -#define NAME_SIZE	32
>>> >>  static int skylake_card_late_probe(struct snd_soc_card *card)  {
>>> >>  	struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(card);
>>> >>  	struct skl_hdmi_pcm *pcm;
>>> >>  	struct snd_soc_component *component = NULL;
>>> >>  	int err, i = 0;
>>> >> -	char jack_name[NAME_SIZE];
>>> >>
>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>> >>  		component = pcm->codec_dai->component;
>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>> >> -					SND_JACK_AVOUT,
>>> >> -					&skylake_hdmi[i],
>>> >> -					NULL, 0);
>>> >> -
>>> >> -		if (err)
>>> >> -			return err;
>>> >>
>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>> >>  						&skylake_hdmi[i]);
>>> >> diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
>>> >> b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
>>> >> index 8433c52..788a837 100644
>>> >> --- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
>>> >> +++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
>>> >> @@ -638,26 +638,15 @@ static struct snd_soc_dai_link skylake_dais[] =
>{
>>> >>  	},
>>> >>  };
>>> >>
>>> >> -#define NAME_SIZE	32
>>> >>  static int skylake_card_late_probe(struct snd_soc_card *card)  {
>>> >>  	struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(card);
>>> >>  	struct skl_hdmi_pcm *pcm;
>>> >>  	struct snd_soc_component *component = NULL;
>>> >>  	int err, i = 0;
>>> >> -	char jack_name[NAME_SIZE];
>>> >>
>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>> >>  		component = pcm->codec_dai->component;
>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>> >> -					SND_JACK_AVOUT,
>>> >> -					&skylake_hdmi[i],
>>> >> -					NULL, 0);
>>> >> -
>>> >> -		if (err)
>>> >> -			return err;
>>> >>
>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>> >>  						&skylake_hdmi[i]);
>>> >> diff --git a/sound/soc/intel/boards/skl_rt286.c
>>> >> b/sound/soc/intel/boards/skl_rt286.c
>>> >> index 0e1818d..5d245f5 100644
>>> >> --- a/sound/soc/intel/boards/skl_rt286.c
>>> >> +++ b/sound/soc/intel/boards/skl_rt286.c
>>> >> @@ -473,25 +473,15 @@ static struct snd_soc_dai_link
>>> >> skylake_rt286_dais[]
>>> >= {
>>> >>  	},
>>> >>  };
>>> >>
>>> >> -#define NAME_SIZE	32
>>> >>  static int skylake_card_late_probe(struct snd_soc_card *card)  {
>>> >>  	struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(card);
>>> >>  	struct skl_hdmi_pcm *pcm;
>>> >>  	struct snd_soc_component *component = NULL;
>>> >>  	int err, i = 0;
>>> >> -	char jack_name[NAME_SIZE];
>>> >>
>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>> >>  		component = pcm->codec_dai->component;
>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>> >> -					SND_JACK_AVOUT, &skylake_hdmi[i],
>>> >> -					NULL, 0);
>>> >> -
>>> >> -		if (err)
>>> >> -			return err;
>>> >>
>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>> >>  						&skylake_hdmi[i]);
>>> >> diff --git a/sound/soc/intel/boards/sof_rt5682.c
>>> >> b/sound/soc/intel/boards/sof_rt5682.c
>>> >> index f28fb98..660e4a6 100644
>>> >> --- a/sound/soc/intel/boards/sof_rt5682.c
>>> >> +++ b/sound/soc/intel/boards/sof_rt5682.c
>>> >> @@ -22,8 +22,6 @@
>>> >>  #include "../../codecs/rt5682.h"
>>> >>  #include "../../codecs/hdac_hdmi.h"
>>> >>
>>> >> -#define NAME_SIZE 32
>>> >> -
>>> >>  #define SOF_RT5682_SSP_CODEC(quirk)		((quirk) & GENMASK(2,
>>> >0))
>>> >>  #define SOF_RT5682_SSP_CODEC_MASK			(GENMASK(2,
>>> >0))
>>> >>  #define SOF_RT5682_MCLK_EN			BIT(3)
>>> >> @@ -216,7 +214,6 @@ static int sof_card_late_probe(struct
>>> >> snd_soc_card
>>> >> *card)  {
>>> >>  	struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
>>> >>  	struct snd_soc_component *component = NULL;
>>> >> -	char jack_name[NAME_SIZE];
>>> >>  	struct sof_hdmi_pcm *pcm;
>>> >>  	int err = 0;
>>> >>  	int i = 0;
>>> >> @@ -227,14 +224,6 @@ static int sof_card_late_probe(struct
>>> >> snd_soc_card *card)
>>> >>
>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>> >>  		component = pcm->codec_dai->component;
>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>> >> -			 "HDMI/DP, pcm=%d Jack", pcm->device);
>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>> >> -					    SND_JACK_AVOUT, &sof_hdmi[i],
>>> >> -					    NULL, 0);
>>> >> -
>>> >> -		if (err)
>>> >> -			return err;
>>> >>
>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>> >>  					  &sof_hdmi[i]);
>>> >> --
>>> >> 2.7.4
>>> >>
>>>

[-- Attachment #2: HiFi --]
[-- Type: application/octet-stream, Size: 6270 bytes --]

# Use case Configuration for skl-hda-card

SectionVerb {

	EnableSequence [
		cdev "hw:0"
		cset "name='Pin5-Port0 Mux' 1"
		cset "name='Pin5-Port1 Mux' 2"
		cset "name='Pin5-Port2 Mux' 3"
		cset "name='Pin6-Port0 Mux' 2"
		cset "name='Pin6-Port1 Mux' 3"
		cset "name='Pin6-Port2 Mux' 1"
		cset "name='Pin7-Port0 Mux' 3"
		cset "name='Pin7-Port1 Mux' 2"
		cset "name='Pin7-Port2 Mux' 1"
		cset "name='hif5-0 Jack Switch' on"
		cset "name='hif5-1 Jack Switch' on"
		cset "name='hif5-2 Jack Switch' on"
		cset "name='hif6-0 Jack Switch' on"
		cset "name='hif6-1 Jack Switch' on"
		cset "name='hif6-2 Jack Switch' on"
		cset "name='hif7-0 Jack Switch' on"
		cset "name='hif7-1 Jack Switch' on"
		cset "name='hif7-2 Jack Switch' on"
	]

	DisableSequence [
	]

        Value {
        }
}


SectionDevice."HDMI1" {
        Comment "HDMI1/DP1 Output"

        ConflictingDevice [
		"DPMST2-3"
		"DPMST3-3"
                # "Headset"
        ]

        EnableSequence [
                cdev "hw:0"
                cset "name='hif5-0 Jack Switch' on"
		cset "name='Pin5-Port0 Mux' 1"
        ]

        DisableSequence [
                cdev "hw:0"
		cset "name='Pin5-Port0 Mux' 0"
		cset "name='hif5-0 Jack Switch' off"
        ]

        Value {
                PlaybackPCM "hw:0,1"
                PlaybackChannels "2"
		JackControl "HDMI/DP, pin:port=5:0 Jack"
		# JackHWMute "Headset"
        }
}

SectionDevice."DPMST1-2" {
        Comment "DPMST1-2 Output"

        ConflictingDevice [
                # "Headset"
		"HDMI2"
		"DPMST3-2"
        ]

        EnableSequence [
                cdev "hw:0"
                cset "name='hif5-1 Jack Switch' on"
		cset "name='Pin5-Port1 Mux' 2"
        ]

        DisableSequence [
                cdev "hw:0"
		cset "name='Pin5-Port1 Mux' 0"
		cset "name='hif5-1 Jack Switch' off"
        ]

        Value {
                PlaybackPCM "hw:0,2"
                PlaybackChannels "2"
		JackControl "HDMI/DP, pin:port=5:1 Jack"
		# JackHWMute "Headset"
        }
}

SectionDevice."DPMST1-3" {
        Comment "DPMST1-3 Output"

        ConflictingDevice [
                # "Headset"
		"DPMST2-2"
		"HDMI3"
        ]

        EnableSequence [
                cdev "hw:0"
                cset "name='hif5-2 Jack Switch' on"
		cset "name='Pin5-Port2 Mux' 3"
        ]

        DisableSequence [
                cdev "hw:0"
		cset "name='Pin5-Port2 Mux' 0"
		cset "name='hif5-2 Jack Switch' off"
        ]

        Value {
                PlaybackPCM "hw:0,3"
                PlaybackChannels "2"
		JackControl "HDMI/DP, pin:port=5:2 Jack"
		# JackHWMute "Headset"
        }
}


SectionDevice."HDMI2" {
        Comment "HDMI2/DP2 Output"

        ConflictingDevice [
                # "Headset"
		"DPMST1-2"
		"DPMST3-2"
        ]

        EnableSequence [
                cdev "hw:0"
                cset "name='hif6-0 Jack Switch' on"
		cset "name='Pin6-Port0 Mux' 2"
        ]

        DisableSequence [
                cdev "hw:0"
		cset "name='Pin6-Port0 Mux' 0"
		cset "name='hif6-0 Jack Switch' off"
        ]

        Value {
                PlaybackPCM "hw:0,2"
                PlaybackChannels "2"
		JackControl "HDMI/DP, pin:port=6:0 Jack"
		# JackHWMute "Headset"
        }
}

SectionDevice."DPMST2-2" {
        Comment "DPMST2-2 Output"

        ConflictingDevice [
                # "Headset"
		"DPMST1-3"
		"HDMI3"
        ]

        EnableSequence [
                cdev "hw:0"
                cset "name='hif6-1 Jack Switch' on"
		cset "name='Pin6-Port1 Mux' 3"
        ]

        DisableSequence [
                cdev "hw:0"
		cset "name='Pin6-Port1 Mux' 0"
		cset "name='hif6-1 Jack Switch' off"
        ]

        Value {
                PlaybackPCM "hw:0,3"
                PlaybackChannels "2"
		JackControl "HDMI/DP, pin:port=6:1 Jack"
		# JackHWMute "Headset"
        }
}

SectionDevice."DPMST2-3" {
        Comment "DPMST2-3 Output"

        ConflictingDevice [
                # "Headset"
		"HDMI1"
		"DPMST3-3"
        ]

        EnableSequence [
                cdev "hw:0"
                cset "name='hif6-2 Jack Switch' on"
		cset "name='Pin6-Port2 Mux' 3"
        ]

        DisableSequence [
                cdev "hw:0"
		cset "name='Pin6-Port2 Mux' 0"
		cset "name='hif6-2 Jack Switch' off"
        ]

        Value {
                PlaybackPCM "hw:0,1"
                PlaybackChannels "2"
		JackControl "HDMI/DP, pin:port=6:2 Jack"
		# JackHWMute "Headset"
        }
}

SectionDevice."HDMI3" {
        Comment "HDMI3/DP3 Output"

        ConflictingDevice [
                # "Headset"
		"DPMST1-3"
		"DPMST2-2"
        ]

        EnableSequence [
                cdev "hw:0"
                cset "name='hif7-0 Jack Switch' on"
		cset "name='Pin7-Port0 Mux' 3"
        ]

        DisableSequence [
                cdev "hw:0"
		cset "name='Pin7-Port0 Mux' 0"
		cset "name='hif7-0 Jack Switch' off"
        ]

        Value {
                PlaybackPCM "hw:0,3"
                PlaybackChannels "2"
		JackControl "HDMI/DP, pin:port=7:0 Jack"
		# JackHWMute "Headset"
        }
}

SectionDevice."DPMST3-2" {
        Comment "DPMST3-2 Output"

        ConflictingDevice [
                # "Headset"
		"DPMST1-2"
		"HDMI2"
        ]

        EnableSequence [
                cdev "hw:0"
                cset "name='hif7-1 Jack Switch' on"
		cset "name='Pin7-Port1 Mux' 2"
        ]

        DisableSequence [
                cdev "hw:0"
		cset "name='Pin7-Port1 Mux' 0"
		cset "name='hif7-1 Jack Switch' off"
        ]

        Value {
                PlaybackPCM "hw:0,2"
                PlaybackChannels "2"
		JackControl "HDMI/DP, pin:port=7:1 Jack"
		# JackHWMute "Headset"
        }
}

SectionDevice."DPMST3-3" {
        Comment "DPMST3-3 Output"

        ConflictingDevice [
                # "Headset"
		"HDMI1"
		"DPMST2-3"
        ]

        EnableSequence [
                cdev "hw:0"
                cset "name='hif7-2 Jack Switch' on"
		cset "name='Pin7-Port2 Mux' 1"
        ]

        DisableSequence [
                cdev "hw:0"
		cset "name='Pin7-Port2 Mux' 0"
		cset "name='hif7-2 Jack Switch' off"
        ]

        Value {
                PlaybackPCM "hw:0,1"
                PlaybackChannels "2"
		JackControl "HDMI/DP, pin:port=7:2 Jack"
		# JackHWMute "Headset"
        }
}

[-- Attachment #3: Type: text/plain, Size: 0 bytes --]



^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks
  2019-06-14  8:04           ` Yang, Libin
@ 2019-06-25  6:02             ` Yang, Libin
  2019-06-25 11:05               ` Takashi Iwai
  0 siblings, 1 reply; 15+ messages in thread
From: Yang, Libin @ 2019-06-25  6:02 UTC (permalink / raw)
  To: 'Takashi Iwai'
  Cc: 'Hui Wang', 'alsa-devel@alsa-project.org',
	'broonie@kernel.org',
	'pierre-louis.bossart@linux.intel.com'

>
>Sorry for a long delay for the hdmi jacks. I was busy on another critical issue
>last 2 weeks. I have worked out the UCM configuration files. Please check the
>attachment. It is a long file, so I use the attachment instead of the patch mode.
>Based on my test, it works well. Could you please help review if the
>configuration file is OK or not. I will do more test on the meantime, including
>DPMST and NON-DPMST.

With some more tests on the new hdmi jack with UCM configuration, I found
that the kernel patch can always notify the jack hotplug event to userspace
correctly. However, the userspace can't set the amixer correctly based on
the UCM configurations sometimes.

Here is the details:
There are 3 PCMs on Intel platforms. Let's call them pcm1, pcm2, pcm3.
And there are 3 pins (pin5, pin6, pin7). For DPMST, and each pin has 3 ports:
port0, port1, port2.

For non-DPMST, we can set pin5 <=> pcm1, pin6 <=> pcm2, pin7 <=> pcm3.
This can always work.

For DPMST, as there are 9 ports using 3 pcms. So we should assign
1 pcm to 3 ports. For example, pin5-port0, pin6-port1 and pin7-port2
are using pcm1;  pin5-port1, pin6-port2 and pin7-port0 are using
pcm2; pin5-port2; pin6-port3 and pin7-port1 are using pcm3.
In this setting, we should setting the ConflictingDevice in UCM.
For example, pin5-port0 is conflicting with pin6-port1 and pin7-port2.
Hui and I found if we set one device conflicting with 2 devices, the
amixer setting will be wrong and it will not following UCM configuration
setting when we are hotplugging the monitors.
Hui and I thought this may be the alsa-lib or pulseaudio issue.
Do you have some ideas that if we can fix the issue of 3 devices
are conflicting? Thanks.

Regards,
Libin

>
>Regards,
>Libin
>
>
>>-----Original Message-----
>>From: Yang, Libin
>>Sent: Friday, May 31, 2019 10:27 AM
>>To: Takashi Iwai <tiwai@suse.de>
>>Cc: alsa-devel@alsa-project.org; broonie@kernel.org; pierre-
>>louis.bossart@linux.intel.com
>>Subject: RE: [alsa-devel] [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi
>>jacks
>>
>>Hi Takashi,
>>
>>>
>>>On Thu, 30 May 2019 17:00:24 +0200,
>>>Yang, Libin wrote:
>>>>
>>>> Hi Takashi,
>>>>
>>>> >-----Original Message-----
>>>> >From: Takashi Iwai [mailto:tiwai@suse.de]
>>>> >Sent: Thursday, May 30, 2019 3:13 PM
>>>> >To: Yang, Libin <libin.yang@intel.com>
>>>> >Cc: alsa-devel@alsa-project.org; broonie@kernel.org; pierre-
>>>> >louis.bossart@linux.intel.com
>>>> >Subject: Re: [alsa-devel] [RFC PATCH 3/4] ASoC: hdac_hdmi: refine
>>>> >hdmi jacks
>>>> >
>>>> >On Mon, 27 May 2019 11:07:26 +0200, libin.yang@intel.com wrote:
>>>> >>
>>>> >> From: Libin Yang <libin.yang@intel.com>
>>>> >>
>>>> >> This patch does the following actions:
>>>> >> 1) move snd_soc_card_jack_new() from machine driver to codec driver.
>>>> >>    This is because the jack information is more lated to the codec
>>>> >>    Also this patch calls snd_jack_add_new_kctl() to export the jack kctl
>>>> >>    to userspace.
>>>> >>
>>>> >> 2) jack is bound to pcm in origal code. The patch binds jack to pin-port.
>>>> >>    This mean each pin-port (3x3) has a jack. pin-port is used for DP-MST
>>>> >>    mode. The port means device entry for DP-MST in hdac_hdmi
>>>> >>    As hdac_hdmi allows user to map the pin-port to a pcm
>>>> >> manually, the
>>>jack
>>>> >>    is bound to pcm is not accurate.
>>>> >>    However, PA assumes jack is bound to PCM for the legacy mode.
>>>> >>    For example, for ubuntu, in
>>>> >>    /usr/share/pulseaudio/alsa-mixer/paths/hdmi-output-x.conf uses
>>>> >>    "Jack HDMI/DP,pcm=n" to find which jack event is used.
>>>> >>    This main issue is: pcm number is fixed (3, 7, 8, 9, 10) for hdmi in
>>>> >>    legacy mode. But it is not always the same for ASoC hdmi audio.
>>>> >
>>>> >The question is what brings this change practically.  On the legacy
>>>> >driver, as the jack is bound with the PCM, user-space (typically
>>>> >PA) who receives a jack connection event opens simply the
>>>> >corresponding PCM substream.  Now, for
>>>> >ASoC:
>>>> >  1. Which PCM substream?
>>>> >  2. How to set up the routing?
>>>> >
>>>> >I assume the 1 doens't matter, any substream, unlike the legacy case.
>>>> >But how is 2 done automatically?
>>>>
>>>> For the legacy HDA, there are 2 mode (dynamic pcm assignment (DPMST)
>>>> and static pcm assignment (NON-DPMST)).
>>>> 1) For static pcm assignment, pcm is always statically mapped to pin.
>>>> For example, pcm1 <=> pin 1; pcm <=> pin 2 and so on. So it is the
>>>> same to bind jack to pcm or to pin.
>>>> 2) For dynamic pcm assignment, in generic_hdmi_build_jack(), the
>>>> jack is bound to PCM when it is created
>>>> (spec->pcm_rec[pcm_idx].jack). We will find the jack by pcm_idx. And
>>>> when monitor is connected to a pin,
>>>> update_eld() will be called. In update_eld(), it will call
>>>> hdmi_attach_hda_pcm() to find a pcm to bind to the pin. So it can
>>>> find a jack (from the pcm) and report its status to userspace.
>>>>
>>>> So in a word for legacy HDA, it can always find a PCM (no matter in
>>>> static mode or in dynamic mode) when the monitor is connected to a
>>>> pin. This means it can always update the status of to userspace that
>>>> the pcm status is changed.
>>>
>>>Right, that's why the jack control has a pcm suffix.  It is bound with
>>>the PCM stream in the end, so user-space can simply open it.
>>>
>>>> However, in hdac_hdmi, there is no such dynamic pcm assignment. And
>>>> it is not statically assignment of pcm to pin. PCM is statically bound to cvt.
>>>> hdac_hdmi allows user to assign a cvt to a pin with alsamixer ( in
>>>> function hdac_hdmi_set_pin_port_mux(), so this function maps the pin
>>>> to
>>>the pcm).
>>>> As user may assign NONE pcm to a pin in alsamixer, this means a pin
>>>> can be assigned none of pcms. So if we mapped jack to pcm, we may
>>>> not find any jack for the pin when a monitor is connected to the pin.
>>>> This means driver can't notify userspace of the monitor connection.
>>>> As you know, PA will use the monitor connection status to decide
>>>> whether to user it or not. So this is the problem. The root cause is
>>>> pcm is bound to cvt. And pin may be not bound to any pcm (This is
>>>> the difference from the legacy hda).
>>>>
>>>> In my patch, as jack is bound to pin-port, so it can always notify
>>>> userspace that a monitor is connected. We can use configuration in
>>>> /usr/share/alsa/ ucm or /usr/share/pulseaudio to configure the
>>>> amixer to assign a pcm to the pin (monitor). And userspace can
>>>> playback on the
>>>monitor now.
>>>
>>>Then please prepare the UCM stuff at first and make sure that
>>>everything works with the proposed change.  The kernel changes can be
>>>merged once after all things get ready.
>>
>>OK. I will prepare the UCM and PA configurations to check it works well
>>and the purpose is patch should be compatible with the old drivers.
>>
>>Regards,
>>Libin
>>
>>>
>>>
>>>thanks,
>>>
>>>Takashi
>>>
>>>>
>>>> Regards,
>>>> Libin
>>>>
>>>> >
>>>> >
>>>> >thanks,
>>>> >
>>>> >Takashi
>>>> >
>>>> >>
>>>> >> Signed-off-by: Libin Yang <libin.yang@intel.com>
>>>> >> ---
>>>> >>  sound/soc/codecs/hdac_hdmi.c                       | 127 ++++++++++++-------
>--
>>>> >>  sound/soc/intel/boards/bxt_da7219_max98357a.c      |  10 --
>>>> >>  sound/soc/intel/boards/bxt_rt298.c                 |  10 --
>>>> >>  sound/soc/intel/boards/glk_rt5682_max98357a.c      |  10 --
>>>> >>  sound/soc/intel/boards/kbl_da7219_max98357a.c      |  10 --
>>>> >>  sound/soc/intel/boards/kbl_da7219_max98927.c       |  10 --
>>>> >>  sound/soc/intel/boards/kbl_rt5660.c                |  10 --
>>>> >>  sound/soc/intel/boards/kbl_rt5663_max98927.c       |  10 --
>>>> >>  .../soc/intel/boards/kbl_rt5663_rt5514_max98927.c  |   9 --
>>>> >>  sound/soc/intel/boards/skl_hda_dsp_common.c        |   9 --
>>>> >>  sound/soc/intel/boards/skl_nau88l25_max98357a.c    |  11 --
>>>> >>  sound/soc/intel/boards/skl_nau88l25_ssm4567.c      |  11 --
>>>> >>  sound/soc/intel/boards/skl_rt286.c                 |  10 --
>>>> >>  sound/soc/intel/boards/sof_rt5682.c                |  11 --
>>>> >>  14 files changed, 74 insertions(+), 184 deletions(-)
>>>> >>
>>>> >> diff --git a/sound/soc/codecs/hdac_hdmi.c
>>>> >> b/sound/soc/codecs/hdac_hdmi.c index 90c2ee3..ed267fa 100644
>>>> >> --- a/sound/soc/codecs/hdac_hdmi.c
>>>> >> +++ b/sound/soc/codecs/hdac_hdmi.c
>>>> >> @@ -4,6 +4,7 @@
>>>> >>   *  Copyright (C) 2014-2015 Intel Corp
>>>> >>   *  Author: Samreen Nilofer <samreen.nilofer@intel.com>
>>>> >>   *	    Subhransu S. Prusty <subhransu.s.prusty@intel.com>
>>>> >> + *	    Libin Yang <libin.yang@intel.com>
>>>> >>   *
>>>> >~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>~
>>~
>>>~~~
>>>> >~~~~~~~~~
>>>> >>   *
>>>> >>   *  This program is free software; you can redistribute it
>>>> >> and/or modify @@ -30,6 +31,7 @@  #include <sound/hda_i915.h>
>>>> >> #include <sound/pcm_drm_eld.h>  #include <sound/hda_chmap.h>
>>>> >> +#include <sound/hda_codec.h>
>>>> >>  #include "../../hda/local.h"
>>>> >>  #include "hdac_hdmi.h"
>>>> >>
>>>> >> @@ -95,6 +97,8 @@ struct hdac_hdmi_port {
>>>> >>  	int num_mux_nids;
>>>> >>  	hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
>>>> >>  	struct hdac_hdmi_eld eld;
>>>> >> +	struct snd_soc_jack jack;
>>>> >> +	int jack_event;
>>>> >>  	const char *jack_pin;
>>>> >>  	struct snd_soc_dapm_context *dapm;
>>>> >>  	const char *output_pin;
>>>> >> @@ -105,14 +109,12 @@ struct hdac_hdmi_pcm {
>>>> >>  	int pcm_id;
>>>> >>  	struct list_head port_list;
>>>> >>  	struct hdac_hdmi_cvt *cvt;
>>>> >> -	struct snd_soc_jack *jack;
>>>> >>  	int stream_tag;
>>>> >>  	int channels;
>>>> >>  	int format;
>>>> >>  	bool chmap_set;
>>>> >>  	unsigned char chmap[8]; /* ALSA API channel-map */
>>>> >>  	struct mutex lock;
>>>> >> -	int jack_event;
>>>> >>  };
>>>> >>
>>>> >>  struct hdac_hdmi_dai_port_map {
>>>> >> @@ -166,8 +168,7 @@ hdac_hdmi_get_pcm_from_cvt(struct
>>>> >hdac_hdmi_priv *hdmi,
>>>> >>  	return pcm;
>>>> >>  }
>>>> >>
>>>> >> -static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
>>>> >> -		struct hdac_hdmi_port *port, bool is_connect)
>>>> >> +static void hdac_hdmi_jack_report(struct hdac_hdmi_port *port,
>>>> >> +bool
>>>> >> +is_connect)
>>>> >>  {
>>>> >>  	struct hdac_device *hdev = port->pin->hdev;
>>>> >>
>>>> >> @@ -176,19 +177,25 @@ static void hdac_hdmi_jack_report(struct
>>>> >hdac_hdmi_pcm *pcm,
>>>> >>  	else
>>>> >>  		snd_soc_dapm_disable_pin(port->dapm, port->jack_pin);
>>>> >>
>>>> >> +	/* if jack is not ready, skip reporting jack status */
>>>> >> +	if (!port->jack.jack) {
>>>> >> +		snd_soc_dapm_sync(port->dapm);
>>>> >> +		return;
>>>> >> +	}
>>>> >> +
>>>> >>  	if (is_connect) {
>>>> >> -		if (pcm->jack_event == 0) {
>>>> >> +		if (port->jack_event == 0) {
>>>> >>  			dev_dbg(&hdev->dev,
>>>> >> -					"jack report for pcm=%d\n",
>>>> >> -					pcm->pcm_id);
>>>> >> -			snd_soc_jack_report(pcm->jack,
>SND_JACK_AVOUT,
>>>> >> -						SND_JACK_AVOUT);
>>>> >> +				"jack report for pin:port = %d:%d\n",
>>>> >> +				port->id, port->pin->nid);
>>>> >> +			snd_soc_jack_report(&port->jack,
>SND_JACK_AVOUT,
>>>> >> +					    SND_JACK_AVOUT);
>>>> >>  		}
>>>> >> -		pcm->jack_event = 1;
>>>> >> +		port->jack_event = 1;
>>>> >>  	} else {
>>>> >> -		if (pcm->jack_event == 1)
>>>> >> -			snd_soc_jack_report(pcm->jack, 0,
>SND_JACK_AVOUT);
>>>> >> -		pcm->jack_event = 0;
>>>> >> +		if (port->jack_event == 1)
>>>> >> +			snd_soc_jack_report(&port->jack, 0,
>>>> >SND_JACK_AVOUT);
>>>> >> +		port->jack_event = 0;
>>>> >>  	}
>>>> >>
>>>> >>  	snd_soc_dapm_sync(port->dapm);
>>>> >> @@ -1235,26 +1242,15 @@ static void
>>hdac_hdmi_present_sense(struct
>>>> >hdac_hdmi_pin *pin,
>>>> >>  	pcm = hdac_hdmi_get_pcm(hdev, port);
>>>> >>
>>>> >>  	if (!port->eld.monitor_present || !port->eld.eld_valid) {
>>>> >> -
>>>> >>  		dev_err(&hdev->dev, "%s: disconnect for pin:port %d:%d\n",
>>>> >>  						__func__, pin->nid, port->id);
>>>> >> -
>>>> >> -		/*
>>>> >> -		 * PCMs are not registered during device probe, so
>don't
>>>> >> -		 * report jack here. It will be done in usermode mux
>>>> >> -		 * control select.
>>>> >> -		 */
>>>> >> -		if (pcm)
>>>> >> -			hdac_hdmi_jack_report(pcm, port, false);
>>>> >> -
>>>> >> +		hdac_hdmi_jack_report(port, false);
>>>> >>  		mutex_unlock(&hdmi->pin_mutex);
>>>> >>  		return;
>>>> >>  	}
>>>> >>
>>>> >>  	if (port->eld.monitor_present && port->eld.eld_valid) {
>>>> >> -		if (pcm)
>>>> >> -			hdac_hdmi_jack_report(pcm, port, true);
>>>> >> -
>>>> >> +		hdac_hdmi_jack_report(port, true);
>>>> >>  		print_hex_dump_debug("ELD: ", DUMP_PREFIX_OFFSET, 16, 1,
>>>> >>  			  port->eld.eld_buffer, port->eld.eld_size, false);
>>>> >>
>>>> >> @@ -1650,6 +1646,30 @@ static int
>>>> >> create_fill_jack_kcontrols(struct
>>>> >snd_soc_card *card,
>>>> >>  	return snd_soc_add_card_controls(card, kc, i);  }
>>>> >>
>>>> >> +static void hdac_hdmi_present_sense_all_pins(struct hdac_device
>>>*hdev,
>>>> >> +			struct hdac_hdmi_priv *hdmi, bool
>detect_pin_caps) {
>>>> >> +	int i;
>>>> >> +	struct hdac_hdmi_pin *pin;
>>>> >> +
>>>> >> +	list_for_each_entry(pin, &hdmi->pin_list, head) {
>>>> >> +		if (detect_pin_caps) {
>>>> >> +
>>>> >> +			if (hdac_hdmi_get_port_len(hdev, pin->nid)
>== 0)
>>>> >> +				pin->mst_capable = false;
>>>> >> +			else
>>>> >> +				pin->mst_capable = true;
>>>> >> +		}
>>>> >> +
>>>> >> +		for (i = 0; i < pin->num_ports; i++) {
>>>> >> +			if (!pin->mst_capable && i > 0)
>>>> >> +				continue;
>>>> >> +
>>>> >> +			hdac_hdmi_present_sense(pin, &pin-
>>ports[i]);
>>>> >> +		}
>>>> >> +	}
>>>> >> +}
>>>> >> +
>>>> >>  int hdac_hdmi_jack_port_init(struct snd_soc_component *component,
>>>> >>  			struct snd_soc_dapm_context *dapm)  { @@ -1659,6
>>>> >+1679,7 @@ int
>>>> >> hdac_hdmi_jack_port_init(struct snd_soc_component *component,
>>>> >>  	struct snd_soc_dapm_widget *widgets;
>>>> >>  	struct snd_soc_dapm_route *route;
>>>> >>  	char w_name[NAME_SIZE];
>>>> >> +	char jack_name[NAME_SIZE];
>>>> >>  	int i = 0, j, ret;
>>>> >>
>>>> >>  	widgets = devm_kcalloc(dapm->dev, hdmi->num_ports, @@ -1687,6
>>>> >> +1708,30 @@ int hdac_hdmi_jack_port_init(struct
>snd_soc_component
>>>> >*component,
>>>> >>  			pin->ports[j].jack_pin = widgets[i].name;
>>>> >>  			pin->ports[j].dapm = dapm;
>>>> >>
>>>> >> +			/*
>>>> >> +			 * Create pin-port jack. Each port (device entry)
>of
>>>> >> +			 * the pin has a corresponding jack
>>>> >> +			 */
>>>> >> +			snprintf(jack_name, sizeof(jack_name),
>>>> >> +				 "HDMI/DP, pin:port=%d:%d Jack",
>>>> >> +				  pin->nid, pin->ports[j].id);
>>>> >> +			ret = snd_soc_card_jack_new(dapm->card,
>jack_name,
>>>> >> +						    SND_JACK_AVOUT,
>>>> >> +						    &(pin->ports[j].jack),
>>>> >> +						    NULL, 0);
>>>> >> +			if (ret)
>>>> >> +				return ret;
>>>> >> +
>>>> >> +			/* create the jack kctl */
>>>> >> +			ret = snd_jack_add_new_kctl(pin-
>>ports[j].jack.jack,
>>>> >> +						    jack_name,
>>>> >SND_JACK_AVOUT);
>>>> >> +			/*
>>>> >> +			 * It's not a critical issue if driver fails to
>>>> >> +			 * create jack kctl.
>>>> >> +			 */
>>>> >> +			if (ret)
>>>> >> +				dev_warn(&hdev->dev, "failed
>creating Jack
>>>> >kctl\n");
>>>> >> +
>>>> >>  			/* add to route from Jack widget to output */
>>>> >>  			hdac_hdmi_fill_route(&route[i], pin->ports[j].jack_pin,
>>>> >>  					NULL, pin->ports[j].output_pin, NULL);
>>>> >@@ -1695,6 +1740,9 @@ int
>>>> >> hdac_hdmi_jack_port_init(struct snd_soc_component *component,
>>>> >>  		}
>>>> >>  	}
>>>> >>
>>>> >> +	/* now jack is ready, let's update the status */
>>>> >> +	hdac_hdmi_present_sense_all_pins(hdev, hdmi, true);
>>>> >> +
>>>> >>  	/* Add Route from Jack widget to the output widget */
>>>> >>  	ret = snd_soc_dapm_new_controls(dapm, widgets, hdmi- num_ports);
>>>> >>  	if (ret < 0)
>>>> >> @@ -1744,8 +1792,6 @@ int hdac_hdmi_jack_init(struct snd_soc_dai
>>>> >>*dai,
>>>> >int device,
>>>> >>  		return -ENOMEM;
>>>> >>  	pcm->pcm_id = device;
>>>> >>  	pcm->cvt = hdmi->dai_map[dai->id].cvt;
>>>> >> -	pcm->jack_event = 0;
>>>> >> -	pcm->jack = jack;
>>>> >>  	mutex_init(&pcm->lock);
>>>> >>  	INIT_LIST_HEAD(&pcm->port_list);
>>>> >>  	snd_pcm = hdac_hdmi_get_pcm_from_id(dai->component->card,
>>>> >device);
>>>> >> @@ -1765,30 +1811,6 @@ int hdac_hdmi_jack_init(struct snd_soc_dai
>>>> >> *dai, int device,  }  EXPORT_SYMBOL_GPL(hdac_hdmi_jack_init);
>>>> >>
>>>> >> -static void hdac_hdmi_present_sense_all_pins(struct hdac_device
>>*hdev,
>>>> >> -			struct hdac_hdmi_priv *hdmi, bool
>detect_pin_caps)
>>>> >> -{
>>>> >> -	int i;
>>>> >> -	struct hdac_hdmi_pin *pin;
>>>> >> -
>>>> >> -	list_for_each_entry(pin, &hdmi->pin_list, head) {
>>>> >> -		if (detect_pin_caps) {
>>>> >> -
>>>> >> -			if (hdac_hdmi_get_port_len(hdev, pin->nid)
>== 0)
>>>> >> -				pin->mst_capable = false;
>>>> >> -			else
>>>> >> -				pin->mst_capable = true;
>>>> >> -		}
>>>> >> -
>>>> >> -		for (i = 0; i < pin->num_ports; i++) {
>>>> >> -			if (!pin->mst_capable && i > 0)
>>>> >> -				continue;
>>>> >> -
>>>> >> -			hdac_hdmi_present_sense(pin, &pin-
>>ports[i]);
>>>> >> -		}
>>>> >> -	}
>>>> >> -}
>>>> >> -
>>>> >>  static int hdmi_codec_probe(struct snd_soc_component *component)
>>{
>>>> >>  	struct hdac_hdmi_priv *hdmi =
>>>> >> snd_soc_component_get_drvdata(component);
>>>> >> @@ -1823,7 +1845,6 @@ static int hdmi_codec_probe(struct
>>>> >snd_soc_component *component)
>>>> >>  		return ret;
>>>> >>  	}
>>>> >>
>>>> >> -	hdac_hdmi_present_sense_all_pins(hdev, hdmi, true);
>>>> >>  	/* Imp: Store the card pointer in hda_codec */
>>>> >>  	hdmi->card = dapm->card->snd_card;
>>>> >>
>>>> >> diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c
>>>> >> b/sound/soc/intel/boards/bxt_da7219_max98357a.c
>>>> >> index 5cadb7f..c69cfa9 100644
>>>> >> --- a/sound/soc/intel/boards/bxt_da7219_max98357a.c
>>>> >> +++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
>>>> >> @@ -573,14 +573,12 @@ static const struct x86_cpu_id glk_ids[] = {
>>>> >>  	{}
>>>> >>  };
>>>> >>
>>>> >> -#define NAME_SIZE	32
>>>> >>  static int bxt_card_late_probe(struct snd_soc_card *card)  {
>>>> >>  	struct bxt_card_private *ctx = snd_soc_card_get_drvdata(card);
>>>> >>  	struct bxt_hdmi_pcm *pcm;
>>>> >>  	struct snd_soc_component *component = NULL;
>>>> >>  	int err, i = 0;
>>>> >> -	char jack_name[NAME_SIZE];
>>>> >>
>>>> >>  	if (x86_match_cpu(glk_ids))
>>>> >>  		snd_soc_dapm_add_routes(&card->dapm, gemini_map, @@
>>>> >-591,14 +589,6
>>>> >> @@ static int bxt_card_late_probe(struct snd_soc_card *card)
>>>> >>
>>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>>> >>  		component = pcm->codec_dai->component;
>>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>>> >> -					SND_JACK_AVOUT,
>&broxton_hdmi[i],
>>>> >> -					NULL, 0);
>>>> >> -
>>>> >> -		if (err)
>>>> >> -			return err;
>>>> >>
>>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>>> >>  						&broxton_hdmi[i]);
>>>> >> diff --git a/sound/soc/intel/boards/bxt_rt298.c
>>>> >> b/sound/soc/intel/boards/bxt_rt298.c
>>>> >> index e91057f..d1372891 100644
>>>> >> --- a/sound/soc/intel/boards/bxt_rt298.c
>>>> >> +++ b/sound/soc/intel/boards/bxt_rt298.c
>>>> >> @@ -507,25 +507,15 @@ static struct snd_soc_dai_link
>>>> >> broxton_rt298_dais[]
>>>> >= {
>>>> >>  	},
>>>> >>  };
>>>> >>
>>>> >> -#define NAME_SIZE	32
>>>> >>  static int bxt_card_late_probe(struct snd_soc_card *card)  {
>>>> >>  	struct bxt_rt286_private *ctx = snd_soc_card_get_drvdata(card);
>>>> >>  	struct bxt_hdmi_pcm *pcm;
>>>> >>  	struct snd_soc_component *component = NULL;
>>>> >>  	int err, i = 0;
>>>> >> -	char jack_name[NAME_SIZE];
>>>> >>
>>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>>> >>  		component = pcm->codec_dai->component;
>>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>>> >> -					SND_JACK_AVOUT,
>&broxton_hdmi[i],
>>>> >> -					NULL, 0);
>>>> >> -
>>>> >> -		if (err)
>>>> >> -			return err;
>>>> >>
>>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>>> >>  						&broxton_hdmi[i]);
>>>> >> diff --git a/sound/soc/intel/boards/glk_rt5682_max98357a.c
>>>> >> b/sound/soc/intel/boards/glk_rt5682_max98357a.c
>>>> >> index d17126f..2a35974 100644
>>>> >> --- a/sound/soc/intel/boards/glk_rt5682_max98357a.c
>>>> >> +++ b/sound/soc/intel/boards/glk_rt5682_max98357a.c
>>>> >> @@ -29,7 +29,6 @@
>>>> >>  #define MAXIM_DEV0_NAME "MX98357A:00"
>>>> >>  #define DUAL_CHANNEL 2
>>>> >>  #define QUAD_CHANNEL 4
>>>> >> -#define NAME_SIZE 32
>>>> >>
>>>> >>  static struct snd_soc_jack geminilake_hdmi[3];
>>>> >>
>>>> >> @@ -523,21 +522,12 @@ static int glk_card_late_probe(struct
>>>> >> snd_soc_card *card)  {
>>>> >>  	struct glk_card_private *ctx = snd_soc_card_get_drvdata(card);
>>>> >>  	struct snd_soc_component *component = NULL;
>>>> >> -	char jack_name[NAME_SIZE];
>>>> >>  	struct glk_hdmi_pcm *pcm;
>>>> >>  	int err = 0;
>>>> >>  	int i = 0;
>>>> >>
>>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>>> >>  		component = pcm->codec_dai->component;
>>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>>> >> -					SND_JACK_AVOUT,
>>>> >&geminilake_hdmi[i],
>>>> >> -					NULL, 0);
>>>> >> -
>>>> >> -		if (err)
>>>> >> -			return err;
>>>> >>
>>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>>> >>  						&geminilake_hdmi[i]);
>>>> >> diff --git a/sound/soc/intel/boards/kbl_da7219_max98357a.c
>>>> >> b/sound/soc/intel/boards/kbl_da7219_max98357a.c
>>>> >> index 07491a0..f293307 100644
>>>> >> --- a/sound/soc/intel/boards/kbl_da7219_max98357a.c
>>>> >> +++ b/sound/soc/intel/boards/kbl_da7219_max98357a.c
>>>> >> @@ -519,25 +519,15 @@ static struct snd_soc_dai_link
>>>> >> kabylake_dais[] =
>>>{
>>>> >>  	},
>>>> >>  };
>>>> >>
>>>> >> -#define NAME_SIZE	32
>>>> >>  static int kabylake_card_late_probe(struct snd_soc_card *card)  {
>>>> >>  	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
>>>> >>  	struct kbl_hdmi_pcm *pcm;
>>>> >>  	struct snd_soc_component *component = NULL;
>>>> >>  	int err, i = 0;
>>>> >> -	char jack_name[NAME_SIZE];
>>>> >>
>>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>>> >>  		component = pcm->codec_dai->component;
>>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>>> >> -					SND_JACK_AVOUT,
>&skylake_hdmi[i],
>>>> >> -					NULL, 0);
>>>> >> -
>>>> >> -		if (err)
>>>> >> -			return err;
>>>> >>
>>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>>> >>  				&skylake_hdmi[i]);
>>>> >> diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c
>>>> >> b/sound/soc/intel/boards/kbl_da7219_max98927.c
>>>> >> index f72a7bf..84d3609 100644
>>>> >> --- a/sound/soc/intel/boards/kbl_da7219_max98927.c
>>>> >> +++ b/sound/soc/intel/boards/kbl_da7219_max98927.c
>>>> >> @@ -34,7 +34,6 @@
>>>> >>
>>>> >>  #define DUAL_CHANNEL	2
>>>> >>  #define QUAD_CHANNEL	4
>>>> >> -#define NAME_SIZE	32
>>>> >>
>>>> >>  static struct snd_soc_card *kabylake_audio_card;  static struct
>>>> >> snd_soc_jack kabylake_hdmi[3]; @@ -952,18 +951,9 @@ static int
>>>> >> kabylake_card_late_probe(struct snd_soc_card *card)
>>>> >>  	struct kbl_hdmi_pcm *pcm;
>>>> >>  	struct snd_soc_component *component = NULL;
>>>> >>  	int err, i = 0;
>>>> >> -	char jack_name[NAME_SIZE];
>>>> >>
>>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>>> >>  		component = pcm->codec_dai->component;
>>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>>> >> -					SND_JACK_AVOUT,
>&kabylake_hdmi[i],
>>>> >> -					NULL, 0);
>>>> >> -
>>>> >> -		if (err)
>>>> >> -			return err;
>>>> >>
>>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>>> >>  						&kabylake_hdmi[i]);
>>>> >> diff --git a/sound/soc/intel/boards/kbl_rt5660.c
>>>> >> b/sound/soc/intel/boards/kbl_rt5660.c
>>>> >> index 3255e00..06411bf 100644
>>>> >> --- a/sound/soc/intel/boards/kbl_rt5660.c
>>>> >> +++ b/sound/soc/intel/boards/kbl_rt5660.c
>>>> >> @@ -447,25 +447,15 @@ static struct snd_soc_dai_link
>>>> >> kabylake_rt5660_dais[] = {  };
>>>> >>
>>>> >>
>>>> >> -#define NAME_SIZE	32
>>>> >>  static int kabylake_card_late_probe(struct snd_soc_card *card)  {
>>>> >>  	struct kbl_codec_private *ctx = snd_soc_card_get_drvdata(card);
>>>> >>  	struct kbl_hdmi_pcm *pcm;
>>>> >>  	struct snd_soc_component *component = NULL;
>>>> >>  	int err, i = 0;
>>>> >> -	char jack_name[NAME_SIZE];
>>>> >>
>>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>>> >>  		component = pcm->codec_dai->component;
>>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>>> >> -					SND_JACK_AVOUT,
>&skylake_hdmi[i],
>>>> >> -					NULL, 0);
>>>> >> -
>>>> >> -		if (err)
>>>> >> -			return err;
>>>> >>
>>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>>> >>  				&skylake_hdmi[i]);
>>>> >> diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c
>>>> >> b/sound/soc/intel/boards/kbl_rt5663_max98927.c
>>>> >> index d714752..9c43c6c 100644
>>>> >> --- a/sound/soc/intel/boards/kbl_rt5663_max98927.c
>>>> >> +++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c
>>>> >> @@ -898,25 +898,15 @@ static struct snd_soc_dai_link
>>>> >kabylake_5663_dais[] = {
>>>> >>  	},
>>>> >>  };
>>>> >>
>>>> >> -#define NAME_SIZE	32
>>>> >>  static int kabylake_card_late_probe(struct snd_soc_card *card)  {
>>>> >>  	struct kbl_rt5663_private *ctx = snd_soc_card_get_drvdata(card);
>>>> >>  	struct kbl_hdmi_pcm *pcm;
>>>> >>  	struct snd_soc_component *component = NULL;
>>>> >>  	int err, i = 0;
>>>> >> -	char jack_name[NAME_SIZE];
>>>> >>
>>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>>> >>  		component = pcm->codec_dai->component;
>>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>>> >> -					SND_JACK_AVOUT,
>&skylake_hdmi[i],
>>>> >> -					NULL, 0);
>>>> >> -
>>>> >> -		if (err)
>>>> >> -			return err;
>>>> >>
>>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>>> >>  						&skylake_hdmi[i]);
>>>> >> diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
>>>> >> b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
>>>> >> index 879f142..8fe4007 100644
>>>> >> --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
>>>> >> +++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c
>>>> >> @@ -40,7 +40,6 @@
>>>> >>  #define RT5663_DEV_NAME "i2c-10EC5663:00"
>>>> >>  #define RT5514_AIF1_BCLK_FREQ (48000 * 8 * 16)  #define
>>>> >> RT5514_AIF1_SYSCLK_FREQ 12288000 -#define NAME_SIZE 32
>>>> >>
>>>> >>  #define DMIC_CH(p) p->list[p->count-1]
>>>> >>
>>>> >> @@ -600,18 +599,10 @@ static int kabylake_card_late_probe(struct
>>>> >snd_soc_card *card)
>>>> >>  	struct kbl_hdmi_pcm *pcm;
>>>> >>  	struct snd_soc_component *component = NULL;
>>>> >>  	int err, i = 0;
>>>> >> -	char jack_name[NAME_SIZE];
>>>> >>
>>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>>> >>  		component = pcm->codec_dai->component;
>>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>>> >> -			"HDMI/DP,pcm=%d Jack", pcm->device);
>>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>>> >> -				SND_JACK_AVOUT, &ctx-
>>kabylake_hdmi[i],
>>>> >> -				NULL, 0);
>>>> >>
>>>> >> -		if (err)
>>>> >> -			return err;
>>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>>> >>  						&ctx->kabylake_hdmi[i]);
>>>> >>  		if (err < 0)
>>>> >> diff --git a/sound/soc/intel/boards/skl_hda_dsp_common.c
>>>> >> b/sound/soc/intel/boards/skl_hda_dsp_common.c
>>>> >> index 8b68f41..0f57fc2 100644
>>>> >> --- a/sound/soc/intel/boards/skl_hda_dsp_common.c
>>>> >> +++ b/sound/soc/intel/boards/skl_hda_dsp_common.c
>>>> >> @@ -118,19 +118,10 @@ int skl_hda_hdmi_jack_init(struct
>>>> >> snd_soc_card
>>>> >*card)
>>>> >>  	struct skl_hda_private *ctx = snd_soc_card_get_drvdata(card);
>>>> >>  	struct snd_soc_component *component = NULL;
>>>> >>  	struct skl_hda_hdmi_pcm *pcm;
>>>> >> -	char jack_name[NAME_SIZE];
>>>> >>  	int err;
>>>> >>
>>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>>> >>  		component = pcm->codec_dai->component;
>>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>>> >> -			 "HDMI/DP, pcm=%d Jack", pcm->device);
>>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>>> >> -					    SND_JACK_AVOUT, &pcm-
>>>> >>hdmi_jack,
>>>> >> -					    NULL, 0);
>>>> >> -
>>>> >> -		if (err)
>>>> >> -			return err;
>>>> >>
>>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>>> >>  					  &pcm->hdmi_jack);
>>>> >> diff --git a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
>>>> >> b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
>>>> >> index 0922106..aca426f 100644
>>>> >> --- a/sound/soc/intel/boards/skl_nau88l25_max98357a.c
>>>> >> +++ b/sound/soc/intel/boards/skl_nau88l25_max98357a.c
>>>> >> @@ -587,26 +587,15 @@ static struct snd_soc_dai_link
>>>> >> skylake_dais[] =
>>{
>>>> >>  	},
>>>> >>  };
>>>> >>
>>>> >> -#define NAME_SIZE	32
>>>> >>  static int skylake_card_late_probe(struct snd_soc_card *card)  {
>>>> >>  	struct skl_nau8825_private *ctx = snd_soc_card_get_drvdata(card);
>>>> >>  	struct skl_hdmi_pcm *pcm;
>>>> >>  	struct snd_soc_component *component = NULL;
>>>> >>  	int err, i = 0;
>>>> >> -	char jack_name[NAME_SIZE];
>>>> >>
>>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>>> >>  		component = pcm->codec_dai->component;
>>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>>> >> -					SND_JACK_AVOUT,
>>>> >> -					&skylake_hdmi[i],
>>>> >> -					NULL, 0);
>>>> >> -
>>>> >> -		if (err)
>>>> >> -			return err;
>>>> >>
>>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>>> >>  						&skylake_hdmi[i]);
>>>> >> diff --git a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
>>>> >> b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
>>>> >> index 8433c52..788a837 100644
>>>> >> --- a/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
>>>> >> +++ b/sound/soc/intel/boards/skl_nau88l25_ssm4567.c
>>>> >> @@ -638,26 +638,15 @@ static struct snd_soc_dai_link
>>>> >> skylake_dais[] =
>>{
>>>> >>  	},
>>>> >>  };
>>>> >>
>>>> >> -#define NAME_SIZE	32
>>>> >>  static int skylake_card_late_probe(struct snd_soc_card *card)  {
>>>> >>  	struct skl_nau88125_private *ctx = snd_soc_card_get_drvdata(card);
>>>> >>  	struct skl_hdmi_pcm *pcm;
>>>> >>  	struct snd_soc_component *component = NULL;
>>>> >>  	int err, i = 0;
>>>> >> -	char jack_name[NAME_SIZE];
>>>> >>
>>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>>> >>  		component = pcm->codec_dai->component;
>>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>>> >> -					SND_JACK_AVOUT,
>>>> >> -					&skylake_hdmi[i],
>>>> >> -					NULL, 0);
>>>> >> -
>>>> >> -		if (err)
>>>> >> -			return err;
>>>> >>
>>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>>> >>  						&skylake_hdmi[i]);
>>>> >> diff --git a/sound/soc/intel/boards/skl_rt286.c
>>>> >> b/sound/soc/intel/boards/skl_rt286.c
>>>> >> index 0e1818d..5d245f5 100644
>>>> >> --- a/sound/soc/intel/boards/skl_rt286.c
>>>> >> +++ b/sound/soc/intel/boards/skl_rt286.c
>>>> >> @@ -473,25 +473,15 @@ static struct snd_soc_dai_link
>>>> >> skylake_rt286_dais[]
>>>> >= {
>>>> >>  	},
>>>> >>  };
>>>> >>
>>>> >> -#define NAME_SIZE	32
>>>> >>  static int skylake_card_late_probe(struct snd_soc_card *card)  {
>>>> >>  	struct skl_rt286_private *ctx = snd_soc_card_get_drvdata(card);
>>>> >>  	struct skl_hdmi_pcm *pcm;
>>>> >>  	struct snd_soc_component *component = NULL;
>>>> >>  	int err, i = 0;
>>>> >> -	char jack_name[NAME_SIZE];
>>>> >>
>>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>>> >>  		component = pcm->codec_dai->component;
>>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>>> >> -			"HDMI/DP, pcm=%d Jack", pcm->device);
>>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>>> >> -					SND_JACK_AVOUT,
>&skylake_hdmi[i],
>>>> >> -					NULL, 0);
>>>> >> -
>>>> >> -		if (err)
>>>> >> -			return err;
>>>> >>
>>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>>> >>  						&skylake_hdmi[i]);
>>>> >> diff --git a/sound/soc/intel/boards/sof_rt5682.c
>>>> >> b/sound/soc/intel/boards/sof_rt5682.c
>>>> >> index f28fb98..660e4a6 100644
>>>> >> --- a/sound/soc/intel/boards/sof_rt5682.c
>>>> >> +++ b/sound/soc/intel/boards/sof_rt5682.c
>>>> >> @@ -22,8 +22,6 @@
>>>> >>  #include "../../codecs/rt5682.h"
>>>> >>  #include "../../codecs/hdac_hdmi.h"
>>>> >>
>>>> >> -#define NAME_SIZE 32
>>>> >> -
>>>> >>  #define SOF_RT5682_SSP_CODEC(quirk)		((quirk) &
>GENMASK(2,
>>>> >0))
>>>> >>  #define SOF_RT5682_SSP_CODEC_MASK
>	(GENMASK(2,
>>>> >0))
>>>> >>  #define SOF_RT5682_MCLK_EN			BIT(3)
>>>> >> @@ -216,7 +214,6 @@ static int sof_card_late_probe(struct
>>>> >> snd_soc_card
>>>> >> *card)  {
>>>> >>  	struct sof_card_private *ctx = snd_soc_card_get_drvdata(card);
>>>> >>  	struct snd_soc_component *component = NULL;
>>>> >> -	char jack_name[NAME_SIZE];
>>>> >>  	struct sof_hdmi_pcm *pcm;
>>>> >>  	int err = 0;
>>>> >>  	int i = 0;
>>>> >> @@ -227,14 +224,6 @@ static int sof_card_late_probe(struct
>>>> >> snd_soc_card *card)
>>>> >>
>>>> >>  	list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
>>>> >>  		component = pcm->codec_dai->component;
>>>> >> -		snprintf(jack_name, sizeof(jack_name),
>>>> >> -			 "HDMI/DP, pcm=%d Jack", pcm->device);
>>>> >> -		err = snd_soc_card_jack_new(card, jack_name,
>>>> >> -					    SND_JACK_AVOUT,
>&sof_hdmi[i],
>>>> >> -					    NULL, 0);
>>>> >> -
>>>> >> -		if (err)
>>>> >> -			return err;
>>>> >>
>>>> >>  		err = hdac_hdmi_jack_init(pcm->codec_dai, pcm->device,
>>>> >>  					  &sof_hdmi[i]);
>>>> >> --
>>>> >> 2.7.4
>>>> >>
>>>>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks
  2019-06-25  6:02             ` Yang, Libin
@ 2019-06-25 11:05               ` Takashi Iwai
  2019-06-25 11:41                 ` Hui Wang
  2019-06-27  1:46                 ` Yang, Libin
  0 siblings, 2 replies; 15+ messages in thread
From: Takashi Iwai @ 2019-06-25 11:05 UTC (permalink / raw)
  To: Yang, Libin
  Cc: 'Hui Wang', 'alsa-devel@alsa-project.org',
	'broonie@kernel.org',
	'pierre-louis.bossart@linux.intel.com'

On Tue, 25 Jun 2019 08:02:45 +0200,
Yang, Libin wrote:
> 
> >
> >Sorry for a long delay for the hdmi jacks. I was busy on another critical issue
> >last 2 weeks. I have worked out the UCM configuration files. Please check the
> >attachment. It is a long file, so I use the attachment instead of the patch mode.
> >Based on my test, it works well. Could you please help review if the
> >configuration file is OK or not. I will do more test on the meantime, including
> >DPMST and NON-DPMST.
> 
> With some more tests on the new hdmi jack with UCM configuration, I found
> that the kernel patch can always notify the jack hotplug event to userspace
> correctly. However, the userspace can't set the amixer correctly based on
> the UCM configurations sometimes.
> 
> Here is the details:
> There are 3 PCMs on Intel platforms. Let's call them pcm1, pcm2, pcm3.
> And there are 3 pins (pin5, pin6, pin7). For DPMST, and each pin has 3 ports:
> port0, port1, port2.
> 
> For non-DPMST, we can set pin5 <=> pcm1, pin6 <=> pcm2, pin7 <=> pcm3.
> This can always work.
> 
> For DPMST, as there are 9 ports using 3 pcms. So we should assign
> 1 pcm to 3 ports. For example, pin5-port0, pin6-port1 and pin7-port2
> are using pcm1;  pin5-port1, pin6-port2 and pin7-port0 are using
> pcm2; pin5-port2; pin6-port3 and pin7-port1 are using pcm3.
> In this setting, we should setting the ConflictingDevice in UCM.
> For example, pin5-port0 is conflicting with pin6-port1 and pin7-port2.
> Hui and I found if we set one device conflicting with 2 devices, the
> amixer setting will be wrong and it will not following UCM configuration
> setting when we are hotplugging the monitors.

How wrong would it behave?  Only one of them is done?

> Hui and I thought this may be the alsa-lib or pulseaudio issue.

You can try alsaucm directly without PA, too.
But in general the conflicting device management is done in PA, so I'd
begin with tracking the PA UCM code at first.


thanks,

Takashi

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks
  2019-06-25 11:05               ` Takashi Iwai
@ 2019-06-25 11:41                 ` Hui Wang
  2019-06-27  6:38                   ` Takashi Iwai
  2019-06-27  1:46                 ` Yang, Libin
  1 sibling, 1 reply; 15+ messages in thread
From: Hui Wang @ 2019-06-25 11:41 UTC (permalink / raw)
  To: Takashi Iwai, Yang, Libin
  Cc: 'alsa-devel@alsa-project.org',
	'broonie@kernel.org',
	'pierre-louis.bossart@linux.intel.com'


On 2019/6/25 下午7:05, Takashi Iwai wrote:
> On Tue, 25 Jun 2019 08:02:45 +0200,
> Yang, Libin wrote:
>>> Sorry for a long delay for the hdmi jacks. I was busy on another critical issue
>>> last 2 weeks. I have worked out the UCM configuration files. Please check the
>>> attachment. It is a long file, so I use the attachment instead of the patch mode.
>>> Based on my test, it works well. Could you please help review if the
>>> configuration file is OK or not. I will do more test on the meantime, including
>>> DPMST and NON-DPMST.
>> With some more tests on the new hdmi jack with UCM configuration, I found
>> that the kernel patch can always notify the jack hotplug event to userspace
>> correctly. However, the userspace can't set the amixer correctly based on
>> the UCM configurations sometimes.
>>
>> Here is the details:
>> There are 3 PCMs on Intel platforms. Let's call them pcm1, pcm2, pcm3.
>> And there are 3 pins (pin5, pin6, pin7). For DPMST, and each pin has 3 ports:
>> port0, port1, port2.
>>
>> For non-DPMST, we can set pin5 <=> pcm1, pin6 <=> pcm2, pin7 <=> pcm3.
>> This can always work.
>>
>> For DPMST, as there are 9 ports using 3 pcms. So we should assign
>> 1 pcm to 3 ports. For example, pin5-port0, pin6-port1 and pin7-port2
>> are using pcm1;  pin5-port1, pin6-port2 and pin7-port0 are using
>> pcm2; pin5-port2; pin6-port3 and pin7-port1 are using pcm3.
>> In this setting, we should setting the ConflictingDevice in UCM.
>> For example, pin5-port0 is conflicting with pin6-port1 and pin7-port2.
>> Hui and I found if we set one device conflicting with 2 devices, the
>> amixer setting will be wrong and it will not following UCM configuration
>> setting when we are hotplugging the monitors.
> How wrong would it behave?  Only one of them is done?

Yes, only the 1st conflicting device is handled.

for example:

pin5-port0 has two conflicting devices: pin6-port1 and pin7-port2,

When pin5-port0 is active in the pulseaudio, I can see the 
pin6-port1.DisableSequece and pin7-port2.DisableSequence are called 
according to pulseaudio's log, but it looks like the commands only in 
the 1st device (pin6-port1.DisableSequence) are executed.

To call conflicting devices' disablesequence, the pulseaudio will call 
snd_use_case_set(ucm->ucm_mgr, "_disdev", dev_name) twice, but only the 
1st time calling takes effect.


>
>> Hui and I thought this may be the alsa-lib or pulseaudio issue.
> You can try alsaucm directly without PA, too.
> But in general the conflicting device management is done in PA, so I'd
> begin with tracking the PA UCM code at first.
>
>
> thanks,
>
> Takashi
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel@alsa-project.org
> https://mailman.alsa-project.org/mailman/listinfo/alsa-devel
>
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks
  2019-06-25 11:05               ` Takashi Iwai
  2019-06-25 11:41                 ` Hui Wang
@ 2019-06-27  1:46                 ` Yang, Libin
  1 sibling, 0 replies; 15+ messages in thread
From: Yang, Libin @ 2019-06-27  1:46 UTC (permalink / raw)
  To: Takashi Iwai
  Cc: 'Hui Wang', 'alsa-devel@alsa-project.org',
	'broonie@kernel.org',
	'pierre-louis.bossart@linux.intel.com'

Hi Takashi,

>-----Original Message-----
>From: Takashi Iwai [mailto:tiwai@suse.de]
>Sent: Tuesday, June 25, 2019 7:06 PM
>To: Yang, Libin <libin.yang@intel.com>
>Cc: 'alsa-devel@alsa-project.org' <alsa-devel@alsa-project.org>;
>'broonie@kernel.org' <broonie@kernel.org>; 'pierre-
>louis.bossart@linux.intel.com' <pierre-louis.bossart@linux.intel.com>; 'Hui
>Wang' <hui.wang@canonical.com>
>Subject: Re: [alsa-devel] [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks
>
>On Tue, 25 Jun 2019 08:02:45 +0200,
>Yang, Libin wrote:
>>
>> >
>> >Sorry for a long delay for the hdmi jacks. I was busy on another
>> >critical issue last 2 weeks. I have worked out the UCM configuration
>> >files. Please check the attachment. It is a long file, so I use the attachment
>instead of the patch mode.
>> >Based on my test, it works well. Could you please help review if the
>> >configuration file is OK or not. I will do more test on the meantime,
>> >including DPMST and NON-DPMST.
>>
>> With some more tests on the new hdmi jack with UCM configuration, I
>> found that the kernel patch can always notify the jack hotplug event
>> to userspace correctly. However, the userspace can't set the amixer
>> correctly based on the UCM configurations sometimes.
>>
>> Here is the details:
>> There are 3 PCMs on Intel platforms. Let's call them pcm1, pcm2, pcm3.
>> And there are 3 pins (pin5, pin6, pin7). For DPMST, and each pin has 3 ports:
>> port0, port1, port2.
>>
>> For non-DPMST, we can set pin5 <=> pcm1, pin6 <=> pcm2, pin7 <=> pcm3.
>> This can always work.
>>
>> For DPMST, as there are 9 ports using 3 pcms. So we should assign
>> 1 pcm to 3 ports. For example, pin5-port0, pin6-port1 and pin7-port2
>> are using pcm1;  pin5-port1, pin6-port2 and pin7-port0 are using pcm2;
>> pin5-port2; pin6-port3 and pin7-port1 are using pcm3.
>> In this setting, we should setting the ConflictingDevice in UCM.
>> For example, pin5-port0 is conflicting with pin6-port1 and pin7-port2.
>> Hui and I found if we set one device conflicting with 2 devices, the
>> amixer setting will be wrong and it will not following UCM
>> configuration setting when we are hotplugging the monitors.
>
>How wrong would it behave?  Only one of them is done?
>
>> Hui and I thought this may be the alsa-lib or pulseaudio issue.
>
>You can try alsaucm directly without PA, too.
>But in general the conflicting device management is done in PA, so I'd begin
>with tracking the PA UCM code at first.

Sorry for delay reply. I take annual leave these days. 
The behavior is like Hui's description. Thanks for the suggestion. I will
try alsaucm firstly for the debug.

Regards,
Libin

>
>
>thanks,
>
>Takashi

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks
  2019-06-25 11:41                 ` Hui Wang
@ 2019-06-27  6:38                   ` Takashi Iwai
  0 siblings, 0 replies; 15+ messages in thread
From: Takashi Iwai @ 2019-06-27  6:38 UTC (permalink / raw)
  To: Hui Wang
  Cc: Yang, Libin, 'alsa-devel@alsa-project.org',
	'broonie@kernel.org',
	'pierre-louis.bossart@linux.intel.com'

On Tue, 25 Jun 2019 13:41:58 +0200,
Hui Wang wrote:
> 
> 
> On 2019/6/25 下午7:05, Takashi Iwai wrote:
> > On Tue, 25 Jun 2019 08:02:45 +0200,
> > Yang, Libin wrote:
> >>> Sorry for a long delay for the hdmi jacks. I was busy on another critical issue
> >>> last 2 weeks. I have worked out the UCM configuration files. Please check the
> >>> attachment. It is a long file, so I use the attachment instead of the patch mode.
> >>> Based on my test, it works well. Could you please help review if the
> >>> configuration file is OK or not. I will do more test on the meantime, including
> >>> DPMST and NON-DPMST.
> >> With some more tests on the new hdmi jack with UCM configuration, I found
> >> that the kernel patch can always notify the jack hotplug event to userspace
> >> correctly. However, the userspace can't set the amixer correctly based on
> >> the UCM configurations sometimes.
> >>
> >> Here is the details:
> >> There are 3 PCMs on Intel platforms. Let's call them pcm1, pcm2, pcm3.
> >> And there are 3 pins (pin5, pin6, pin7). For DPMST, and each pin has 3 ports:
> >> port0, port1, port2.
> >>
> >> For non-DPMST, we can set pin5 <=> pcm1, pin6 <=> pcm2, pin7 <=> pcm3.
> >> This can always work.
> >>
> >> For DPMST, as there are 9 ports using 3 pcms. So we should assign
> >> 1 pcm to 3 ports. For example, pin5-port0, pin6-port1 and pin7-port2
> >> are using pcm1;  pin5-port1, pin6-port2 and pin7-port0 are using
> >> pcm2; pin5-port2; pin6-port3 and pin7-port1 are using pcm3.
> >> In this setting, we should setting the ConflictingDevice in UCM.
> >> For example, pin5-port0 is conflicting with pin6-port1 and pin7-port2.
> >> Hui and I found if we set one device conflicting with 2 devices, the
> >> amixer setting will be wrong and it will not following UCM configuration
> >> setting when we are hotplugging the monitors.
> > How wrong would it behave?  Only one of them is done?
> 
> Yes, only the 1st conflicting device is handled.
> 
> for example:
> 
> pin5-port0 has two conflicting devices: pin6-port1 and pin7-port2,
> 
> When pin5-port0 is active in the pulseaudio, I can see the
> pin6-port1.DisableSequece and pin7-port2.DisableSequence are called
> according to pulseaudio's log, but it looks like the commands only in
> the 1st device (pin6-port1.DisableSequence) are executed.
> 
> To call conflicting devices' disablesequence, the pulseaudio will call
> snd_use_case_set(ucm->ucm_mgr, "_disdev", dev_name) twice, but only
> the 1st time calling takes effect.

If you reached at that point, you can continue tracking in alsa-lib :)
If it's some weird behavior in set_device(), it must be either the
list management failure in UCM or execute_sequence() misses
something.


thanks,

Takashi
_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2019-06-27  6:38 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-27  9:07 [RFC PATCH 0/4] ASoC: hdac_hdmi: refine the hdac_hdmi jacks libin.yang
2019-05-27  9:07 ` [RFC PATCH 1/4] ASoC: hdac_hdmi: amixer kctl setting should not impact on jack status libin.yang
2019-05-27  9:07 ` [RFC PATCH 2/4] ASoC: hdac_hdmi: jack_event represents the status libin.yang
2019-05-27  9:07 ` [RFC PATCH 3/4] ASoC: hdac_hdmi: refine hdmi jacks libin.yang
2019-05-30  7:13   ` Takashi Iwai
2019-05-30 15:00     ` Yang, Libin
2019-05-30 15:22       ` Takashi Iwai
2019-05-31  2:27         ` Yang, Libin
2019-06-14  8:04           ` Yang, Libin
2019-06-25  6:02             ` Yang, Libin
2019-06-25 11:05               ` Takashi Iwai
2019-06-25 11:41                 ` Hui Wang
2019-06-27  6:38                   ` Takashi Iwai
2019-06-27  1:46                 ` Yang, Libin
2019-05-27  9:07 ` [RFC PATCH 4/4] ASoC: hdac_hdmi: fix some coding style issue libin.yang

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.