summaryrefslogtreecommitdiff
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
authorMengdong Lin <mengdong.lin@intel.com>2013-08-26 21:35:21 -0400
committerTakashi Iwai <tiwai@suse.de>2013-08-27 12:15:09 +0200
commitf1aa06847506d5b88f5eb41fae6a24a7128097e7 (patch)
treecac7c3bd3fa0cc6a945f2393ab678b263f65b99c /sound/pci/hda/hda_codec.c
parent68538bf2bce557c3b5fe8c59b034d45352500db1 (diff)
ALSA: hda - add flags and routines to get devices selection info for DP1.2 MST
This patch adds flags and routines to get device list & selection info on a pin. To support Display Port 1.2 multi-stream transport (MST) over single DP port, a pin can support multiple devices. Please refer to HD-A spec Document Change Notificaton HDA040-A. A display audio codec can set flag "dp_mst" in its patch, indicating its pins can support MST. But at runtime, a pin may not be multi-streaming capable and report the device list is empty, depending on Gfx driver configuration. Signed-off-by: Mengdong Lin <mengdong.lin@intel.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index fdbb09a9b9e5..5b6c4e3c92ca 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -666,6 +666,64 @@ int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
}
EXPORT_SYMBOL_HDA(snd_hda_get_conn_index);
+
+/* return DEVLIST_LEN parameter of the given widget */
+static unsigned int get_num_devices(struct hda_codec *codec, hda_nid_t nid)
+{
+ unsigned int wcaps = get_wcaps(codec, nid);
+ unsigned int parm;
+
+ if (!codec->dp_mst || !(wcaps & AC_WCAP_DIGITAL) ||
+ get_wcaps_type(wcaps) != AC_WID_PIN)
+ return 0;
+
+ parm = snd_hda_param_read(codec, nid, AC_PAR_DEVLIST_LEN);
+ if (parm == -1 && codec->bus->rirb_error)
+ parm = 0;
+ return parm & AC_DEV_LIST_LEN_MASK;
+}
+
+/**
+ * snd_hda_get_devices - copy device list without cache
+ * @codec: the HDA codec
+ * @nid: NID of the pin to parse
+ * @dev_list: device list array
+ * @max_devices: max. number of devices to store
+ *
+ * Copy the device list. This info is dynamic and so not cached.
+ * Currently called only from hda_proc.c, so not exported.
+ */
+int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
+ u8 *dev_list, int max_devices)
+{
+ unsigned int parm;
+ int i, dev_len, devices;
+
+ parm = get_num_devices(codec, nid);
+ if (!parm) /* not multi-stream capable */
+ return 0;
+
+ dev_len = parm + 1;
+ dev_len = dev_len < max_devices ? dev_len : max_devices;
+
+ devices = 0;
+ while (devices < dev_len) {
+ parm = snd_hda_codec_read(codec, nid, 0,
+ AC_VERB_GET_DEVICE_LIST, devices);
+ if (parm == -1 && codec->bus->rirb_error)
+ break;
+
+ for (i = 0; i < 8; i++) {
+ dev_list[devices] = (u8)parm;
+ parm >>= 4;
+ devices++;
+ if (devices >= dev_len)
+ break;
+ }
+ }
+ return devices;
+}
+
/**
* snd_hda_queue_unsol_event - add an unsolicited event to queue
* @bus: the BUS