]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - sound/pci/hda/patch_hdmi.c
ALSA: hda - Restrict PCM parameters per ELD information over HDMI
[net-next-2.6.git] / sound / pci / hda / patch_hdmi.c
index 522e0748ee99f841cf6458823bd8228013bbd83c..2bc0f07cf33fe4f67720fc3c9487a817b3e77823 100644 (file)
@@ -46,6 +46,7 @@ struct hdmi_spec {
         * export one pcm per pipe
         */
        struct hda_pcm  pcm_rec[MAX_HDMI_CVTS];
+       struct hda_pcm_stream codec_pcm_pars[MAX_HDMI_CVTS];
 
        /*
         * nvhdmi specific
@@ -765,6 +766,47 @@ static int hdmi_setup_stream(struct hda_codec *codec, hda_nid_t nid,
        return 0;
 }
 
+/*
+ * HDA PCM callbacks
+ */
+static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
+                        struct hda_codec *codec,
+                        struct snd_pcm_substream *substream)
+{
+       struct hdmi_spec *spec = codec->spec;
+       struct hdmi_eld *eld;
+       struct hda_pcm_stream *codec_pars;
+       unsigned int idx;
+
+       for (idx = 0; idx < spec->num_cvts; idx++)
+               if (hinfo->nid == spec->cvt[idx])
+                       break;
+       if (snd_BUG_ON(idx >= spec->num_cvts) ||
+           snd_BUG_ON(idx >= spec->num_pins))
+               return -EINVAL;
+
+       /* save the PCM info the codec provides */
+       codec_pars = &spec->codec_pcm_pars[idx];
+       if (!codec_pars->rates)
+               *codec_pars = *hinfo;
+
+       eld = &spec->sink_eld[idx];
+       if (eld->sad_count > 0) {
+               hdmi_eld_update_pcm_info(eld, hinfo, codec_pars);
+               if (hinfo->channels_min > hinfo->channels_max ||
+                   !hinfo->rates || !hinfo->formats)
+                       return -ENODEV;
+       } else {
+               /* fallback to the codec default */
+               hinfo->channels_min = codec_pars->channels_min;
+               hinfo->channels_max = codec_pars->channels_max;
+               hinfo->rates = codec_pars->rates;
+               hinfo->formats = codec_pars->formats;
+               hinfo->maxbps = codec_pars->maxbps;
+       }
+       return 0;
+}
+
 /*
  * HDA/HDMI auto parsing
  */