aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
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 06:15:09 -0400
commitf1aa06847506d5b88f5eb41fae6a24a7128097e7 (patch)
treecac7c3bd3fa0cc6a945f2393ab678b263f65b99c /sound/pci
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')
-rw-r--r--sound/pci/hda/hda_codec.c58
-rw-r--r--sound/pci/hda/hda_codec.h16
2 files changed, 74 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,
666} 666}
667EXPORT_SYMBOL_HDA(snd_hda_get_conn_index); 667EXPORT_SYMBOL_HDA(snd_hda_get_conn_index);
668 668
669
670/* return DEVLIST_LEN parameter of the given widget */
671static unsigned int get_num_devices(struct hda_codec *codec, hda_nid_t nid)
672{
673 unsigned int wcaps = get_wcaps(codec, nid);
674 unsigned int parm;
675
676 if (!codec->dp_mst || !(wcaps & AC_WCAP_DIGITAL) ||
677 get_wcaps_type(wcaps) != AC_WID_PIN)
678 return 0;
679
680 parm = snd_hda_param_read(codec, nid, AC_PAR_DEVLIST_LEN);
681 if (parm == -1 && codec->bus->rirb_error)
682 parm = 0;
683 return parm & AC_DEV_LIST_LEN_MASK;
684}
685
686/**
687 * snd_hda_get_devices - copy device list without cache
688 * @codec: the HDA codec
689 * @nid: NID of the pin to parse
690 * @dev_list: device list array
691 * @max_devices: max. number of devices to store
692 *
693 * Copy the device list. This info is dynamic and so not cached.
694 * Currently called only from hda_proc.c, so not exported.
695 */
696int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
697 u8 *dev_list, int max_devices)
698{
699 unsigned int parm;
700 int i, dev_len, devices;
701
702 parm = get_num_devices(codec, nid);
703 if (!parm) /* not multi-stream capable */
704 return 0;
705
706 dev_len = parm + 1;
707 dev_len = dev_len < max_devices ? dev_len : max_devices;
708
709 devices = 0;
710 while (devices < dev_len) {
711 parm = snd_hda_codec_read(codec, nid, 0,
712 AC_VERB_GET_DEVICE_LIST, devices);
713 if (parm == -1 && codec->bus->rirb_error)
714 break;
715
716 for (i = 0; i < 8; i++) {
717 dev_list[devices] = (u8)parm;
718 parm >>= 4;
719 devices++;
720 if (devices >= dev_len)
721 break;
722 }
723 }
724 return devices;
725}
726
669/** 727/**
670 * snd_hda_queue_unsol_event - add an unsolicited event to queue 728 * snd_hda_queue_unsol_event - add an unsolicited event to queue
671 * @bus: the BUS 729 * @bus: the BUS
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 701c2e069b10..b838c70420d1 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -94,6 +94,8 @@ enum {
94#define AC_VERB_GET_HDMI_DIP_XMIT 0x0f32 94#define AC_VERB_GET_HDMI_DIP_XMIT 0x0f32
95#define AC_VERB_GET_HDMI_CP_CTRL 0x0f33 95#define AC_VERB_GET_HDMI_CP_CTRL 0x0f33
96#define AC_VERB_GET_HDMI_CHAN_SLOT 0x0f34 96#define AC_VERB_GET_HDMI_CHAN_SLOT 0x0f34
97#define AC_VERB_GET_DEVICE_SEL 0xf35
98#define AC_VERB_GET_DEVICE_LIST 0xf36
97 99
98/* 100/*
99 * SET verbs 101 * SET verbs
@@ -133,6 +135,7 @@ enum {
133#define AC_VERB_SET_HDMI_DIP_XMIT 0x732 135#define AC_VERB_SET_HDMI_DIP_XMIT 0x732
134#define AC_VERB_SET_HDMI_CP_CTRL 0x733 136#define AC_VERB_SET_HDMI_CP_CTRL 0x733
135#define AC_VERB_SET_HDMI_CHAN_SLOT 0x734 137#define AC_VERB_SET_HDMI_CHAN_SLOT 0x734
138#define AC_VERB_SET_DEVICE_SEL 0x735
136 139
137/* 140/*
138 * Parameter IDs 141 * Parameter IDs
@@ -154,6 +157,7 @@ enum {
154#define AC_PAR_GPIO_CAP 0x11 157#define AC_PAR_GPIO_CAP 0x11
155#define AC_PAR_AMP_OUT_CAP 0x12 158#define AC_PAR_AMP_OUT_CAP 0x12
156#define AC_PAR_VOL_KNB_CAP 0x13 159#define AC_PAR_VOL_KNB_CAP 0x13
160#define AC_PAR_DEVLIST_LEN 0x15
157#define AC_PAR_HDMI_LPCM_CAP 0x20 161#define AC_PAR_HDMI_LPCM_CAP 0x20
158 162
159/* 163/*
@@ -352,6 +356,10 @@ enum {
352#define AC_LPCMCAP_44K (1<<30) /* 44.1kHz support */ 356#define AC_LPCMCAP_44K (1<<30) /* 44.1kHz support */
353#define AC_LPCMCAP_44K_MS (1<<31) /* 44.1kHz-multiplies support */ 357#define AC_LPCMCAP_44K_MS (1<<31) /* 44.1kHz-multiplies support */
354 358
359/* Display pin's device list length */
360#define AC_DEV_LIST_LEN_MASK 0x3f
361#define AC_MAX_DEV_LIST_LEN 64
362
355/* 363/*
356 * Control Parameters 364 * Control Parameters
357 */ 365 */
@@ -460,6 +468,11 @@ enum {
460#define AC_DEFCFG_PORT_CONN (0x3<<30) 468#define AC_DEFCFG_PORT_CONN (0x3<<30)
461#define AC_DEFCFG_PORT_CONN_SHIFT 30 469#define AC_DEFCFG_PORT_CONN_SHIFT 30
462 470
471/* Display pin's device list entry */
472#define AC_DE_PD (1<<0)
473#define AC_DE_ELDV (1<<1)
474#define AC_DE_IA (1<<2)
475
463/* device device types (0x0-0xf) */ 476/* device device types (0x0-0xf) */
464enum { 477enum {
465 AC_JACK_LINE_OUT, 478 AC_JACK_LINE_OUT,
@@ -885,6 +898,7 @@ struct hda_codec {
885 unsigned int pcm_format_first:1; /* PCM format must be set first */ 898 unsigned int pcm_format_first:1; /* PCM format must be set first */
886 unsigned int epss:1; /* supporting EPSS? */ 899 unsigned int epss:1; /* supporting EPSS? */
887 unsigned int cached_write:1; /* write only to caches */ 900 unsigned int cached_write:1; /* write only to caches */
901 unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */
888#ifdef CONFIG_PM 902#ifdef CONFIG_PM
889 unsigned int power_on :1; /* current (global) power-state */ 903 unsigned int power_on :1; /* current (global) power-state */
890 unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */ 904 unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */
@@ -972,6 +986,8 @@ int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int nums,
972 const hda_nid_t *list); 986 const hda_nid_t *list);
973int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux, 987int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
974 hda_nid_t nid, int recursive); 988 hda_nid_t nid, int recursive);
989int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
990 u8 *dev_list, int max_devices);
975int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, 991int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
976 u32 *ratesp, u64 *formatsp, unsigned int *bpsp); 992 u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
977 993