All of lore.kernel.org
 help / color / mirror / Atom feed
From: libin.yang@linux.intel.com
To: alsa-devel@alsa-project.org, tiwai@suse.de
Cc: libin.yang@intel.com, Libin Yang <libin.yang@linux.intel.com>,
	mengdong.lin@linux.intel.com
Subject: [PATCH] ALSA - hda: hdmi flag to stop playback when monitor is disconnected
Date: Wed, 11 Nov 2015 16:39:09 +0800	[thread overview]
Message-ID: <1447231149-88326-1-git-send-email-libin.yang@linux.intel.com> (raw)

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

Add a flag that user can decide to stop HDMI/DP playback when
the corresponding monitor is disconnected and refuse to open PCM
if there is no monitor connected.

Background:
When a monitor is disconnected and a new monitor is connected,
the parameters of the 2 monitors may be different. Audio driver
need handle this situation.

Besides, stopping playback when monitor is disconnected will
help to save the power.

Signed-off-by: Libin Yang <libin.yang@linux.intel.com>
---
 sound/pci/hda/patch_hdmi.c | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index f503a88..4f5023a 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -47,6 +47,11 @@ static bool static_hdmi_pcm;
 module_param(static_hdmi_pcm, bool, 0644);
 MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
 
+static bool hdmi_pcm_stop_on_disconnect;
+module_param(hdmi_pcm_stop_on_disconnect, bool, 0644);
+MODULE_PARM_DESC(hdmi_pcm_stop_on_disconnect,
+				 "Stop PCM when monitor is disconnected");
+
 #define is_haswell(codec)  ((codec)->core.vendor_id == 0x80862807)
 #define is_broadwell(codec)    ((codec)->core.vendor_id == 0x80862808)
 #define is_skylake(codec) ((codec)->core.vendor_id == 0x80862809)
@@ -72,6 +77,7 @@ struct hdmi_spec_per_cvt {
 
 struct hdmi_spec_per_pin {
 	hda_nid_t pin_nid;
+	int pin_idx;
 	int num_mux_nids;
 	hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
 	int mux_idx;
@@ -1456,6 +1462,9 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
 	per_pin = get_pin(spec, pin_idx);
 	eld = &per_pin->sink_eld;
 
+	if (hdmi_pcm_stop_on_disconnect && !eld->eld_valid)
+		return -ENODEV;
+
 	err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx, &mux_idx);
 	if (err < 0)
 		return err;
@@ -1529,6 +1538,28 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx)
 	return 0;
 }
 
+static void hdmi_pcm_stop(struct hdmi_spec *spec,
+					struct hdmi_spec_per_pin *per_pin)
+{
+	struct hda_codec *codec = per_pin->codec;
+	struct snd_pcm_substream *substream;
+	int pin_idx = per_pin->pin_idx;
+
+	if (!hdmi_pcm_stop_on_disconnect)
+		return;
+
+	substream = get_pcm_rec(spec, pin_idx)->pcm->streams[0].substream;
+
+	snd_pcm_stream_lock_irq(substream);
+	if (substream && substream->runtime &&
+		snd_pcm_running(substream)) {
+		codec_info(codec,
+			"HDMI: monitor disconnected, try to stop playback\n");
+		snd_pcm_stop(substream, SNDRV_PCM_STATE_DISCONNECTED);
+	}
+	snd_pcm_stream_unlock_irq(substream);
+}
+
 static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
 {
 	struct hda_jack_tbl *jack;
@@ -1586,6 +1617,8 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
 		}
 	}
 
+	if (!eld->eld_valid)
+		hdmi_pcm_stop(spec, per_pin);
 	if (pin_eld->eld_valid != eld->eld_valid)
 		eld_changed = true;
 
@@ -1680,6 +1713,7 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
 		return -ENOMEM;
 
 	per_pin->pin_nid = pin_nid;
+	per_pin->pin_idx = pin_idx;
 	per_pin->non_pcm = false;
 
 	err = hdmi_read_pin_conn(codec, pin_idx);
-- 
1.9.1

             reply	other threads:[~2015-11-11  8:40 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-11  8:39 libin.yang [this message]
2015-11-11  9:02 ` [PATCH] ALSA - hda: hdmi flag to stop playback when monitor is disconnected Takashi Iwai
2015-11-11 14:12   ` Takashi Iwai
2015-11-11 14:23     ` Yang, Libin
2015-11-11 14:41       ` Takashi Iwai
2015-11-11 14:53         ` Yang, Libin
2015-11-11 14:58           ` Takashi Iwai
2015-11-11 15:21             ` Yang, Libin
2015-11-12  7:02       ` David Henningsson
2015-11-12  7:26         ` Libin Yang
2015-11-12  7:32           ` David Henningsson
2015-11-12  7:38             ` Libin Yang
2015-11-11 14:43     ` Yang, Libin
2015-11-11 15:00       ` Takashi Iwai
2015-11-11 15:22         ` Yang, Libin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1447231149-88326-1-git-send-email-libin.yang@linux.intel.com \
    --to=libin.yang@linux.intel.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=libin.yang@intel.com \
    --cc=mengdong.lin@linux.intel.com \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.