int pcm_idx; /* which pcm is attached. -1 means no pcm is attached */
        int repoll_count;
        bool setup; /* the stream has been set up by prepare callback */
+       bool silent_stream;
        int channels; /* current number of channels */
        bool non_pcm;
        bool chmap_set;         /* channel-map override by ALSA API? */
        else
                per_pin = get_pin(spec, pin_idx);
 
+       if (per_pin && per_pin->silent_stream) {
+               cvt_idx = cvt_nid_to_cvt_index(codec, per_pin->cvt_nid);
+               if (cvt_id)
+                       *cvt_id = cvt_idx;
+               return 0;
+       }
+
        /* Dynamically assign converter to stream */
        for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) {
                per_cvt = get_cvt(spec, cvt_idx);
        snd_hda_power_down_pm(codec);
 }
 
+#define I915_SILENT_RATE               48000
+#define I915_SILENT_CHANNELS           2
+#define I915_SILENT_FORMAT             SNDRV_PCM_FORMAT_S16_LE
+#define I915_SILENT_FORMAT_BITS        16
+#define I915_SILENT_FMT_MASK           0xf
+
 static void silent_stream_enable(struct hda_codec *codec,
-                               struct hdmi_spec_per_pin *per_pin)
+                                struct hdmi_spec_per_pin *per_pin)
 {
-       unsigned int newval, oldval;
-
-       codec_dbg(codec, "hdmi: enabling silent stream for NID %d\n",
-                       per_pin->pin_nid);
+       struct hdmi_spec *spec = codec->spec;
+       struct hdmi_spec_per_cvt *per_cvt;
+       int cvt_idx, pin_idx, err;
+       unsigned int format;
 
        mutex_lock(&per_pin->lock);
 
-       if (!per_pin->channels)
-               per_pin->channels = 2;
+       if (per_pin->setup) {
+               codec_dbg(codec, "hdmi: PCM already open, no silent stream\n");
+               goto unlock_out;
+       }
 
-       oldval = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
-                       AC_VERB_GET_CONV, 0);
-       newval = (oldval & 0xF0) | 0xF;
-       snd_hda_codec_write(codec, per_pin->pin_nid, 0,
-                       AC_VERB_SET_CHANNEL_STREAMID, newval);
+       pin_idx = pin_id_to_pin_index(codec, per_pin->pin_nid, per_pin->dev_id);
+       err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx);
+       if (err) {
+               codec_err(codec, "hdmi: no free converter to enable silent mode\n");
+               goto unlock_out;
+       }
+
+       per_cvt = get_cvt(spec, cvt_idx);
+       per_cvt->assigned = 1;
+       per_pin->cvt_nid = per_cvt->cvt_nid;
+       per_pin->silent_stream = true;
 
+       codec_dbg(codec, "hdmi: enabling silent stream pin-NID=0x%x cvt-NID=0x%x\n",
+                 per_pin->pin_nid, per_cvt->cvt_nid);
+
+       snd_hda_set_dev_select(codec, per_pin->pin_nid, per_pin->dev_id);
+       snd_hda_codec_write_cache(codec, per_pin->pin_nid, 0,
+                                 AC_VERB_SET_CONNECT_SEL,
+                                 per_pin->mux_idx);
+
+       /* configure unused pins to choose other converters */
+       pin_cvt_fixup(codec, per_pin, 0);
+
+       snd_hdac_sync_audio_rate(&codec->core, per_pin->pin_nid,
+                                per_pin->dev_id, I915_SILENT_RATE);
+
+       /* trigger silent stream generation in hw */
+       format = snd_hdac_calc_stream_format(I915_SILENT_RATE, I915_SILENT_CHANNELS,
+                                            I915_SILENT_FORMAT, I915_SILENT_FORMAT_BITS, 0);
+       snd_hda_codec_setup_stream(codec, per_pin->cvt_nid,
+                                  I915_SILENT_FMT_MASK, I915_SILENT_FMT_MASK, format);
+       usleep_range(100, 200);
+       snd_hda_codec_setup_stream(codec, per_pin->cvt_nid, I915_SILENT_FMT_MASK, 0, format);
+
+       per_pin->channels = I915_SILENT_CHANNELS;
        hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);
 
+ unlock_out:
        mutex_unlock(&per_pin->lock);
 }
 
+static void silent_stream_disable(struct hda_codec *codec,
+                                 struct hdmi_spec_per_pin *per_pin)
+{
+       struct hdmi_spec *spec = codec->spec;
+       struct hdmi_spec_per_cvt *per_cvt;
+       int cvt_idx;
+
+       mutex_lock(&per_pin->lock);
+       if (!per_pin->silent_stream)
+               goto unlock_out;
+
+       codec_dbg(codec, "HDMI: disable silent stream on pin-NID=0x%x cvt-NID=0x%x\n",
+                 per_pin->pin_nid, per_pin->cvt_nid);
+
+       cvt_idx = cvt_nid_to_cvt_index(codec, per_pin->cvt_nid);
+       if (cvt_idx >= 0 && cvt_idx < spec->num_cvts) {
+               per_cvt = get_cvt(spec, cvt_idx);
+               per_cvt->assigned = 0;
+       }
+
+       per_pin->cvt_nid = 0;
+       per_pin->silent_stream = false;
+
+ unlock_out:
+       mutex_unlock(&spec->pcm_lock);
+}
+
 /* update ELD and jack state via audio component */
 static void sync_eld_via_acomp(struct hda_codec *codec,
                               struct hdmi_spec_per_pin *per_pin)
                                pm_ret);
                        silent_stream_enable(codec, per_pin);
                } else if (monitor_prev && !monitor_next) {
+                       silent_stream_disable(codec, per_pin);
                        pm_ret = snd_hda_power_down_pm(codec);
                        if (pm_ret < 0)
                                codec_err(codec,