Commit f1aa0684 authored by Mengdong Lin's avatar Mengdong Lin Committed by Takashi Iwai

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: default avatarMengdong Lin <mengdong.lin@intel.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 68538bf2
...@@ -666,6 +666,64 @@ int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux, ...@@ -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); 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 * snd_hda_queue_unsol_event - add an unsolicited event to queue
* @bus: the BUS * @bus: the BUS
......
...@@ -94,6 +94,8 @@ enum { ...@@ -94,6 +94,8 @@ enum {
#define AC_VERB_GET_HDMI_DIP_XMIT 0x0f32 #define AC_VERB_GET_HDMI_DIP_XMIT 0x0f32
#define AC_VERB_GET_HDMI_CP_CTRL 0x0f33 #define AC_VERB_GET_HDMI_CP_CTRL 0x0f33
#define AC_VERB_GET_HDMI_CHAN_SLOT 0x0f34 #define AC_VERB_GET_HDMI_CHAN_SLOT 0x0f34
#define AC_VERB_GET_DEVICE_SEL 0xf35
#define AC_VERB_GET_DEVICE_LIST 0xf36
/* /*
* SET verbs * SET verbs
...@@ -133,6 +135,7 @@ enum { ...@@ -133,6 +135,7 @@ enum {
#define AC_VERB_SET_HDMI_DIP_XMIT 0x732 #define AC_VERB_SET_HDMI_DIP_XMIT 0x732
#define AC_VERB_SET_HDMI_CP_CTRL 0x733 #define AC_VERB_SET_HDMI_CP_CTRL 0x733
#define AC_VERB_SET_HDMI_CHAN_SLOT 0x734 #define AC_VERB_SET_HDMI_CHAN_SLOT 0x734
#define AC_VERB_SET_DEVICE_SEL 0x735
/* /*
* Parameter IDs * Parameter IDs
...@@ -154,6 +157,7 @@ enum { ...@@ -154,6 +157,7 @@ enum {
#define AC_PAR_GPIO_CAP 0x11 #define AC_PAR_GPIO_CAP 0x11
#define AC_PAR_AMP_OUT_CAP 0x12 #define AC_PAR_AMP_OUT_CAP 0x12
#define AC_PAR_VOL_KNB_CAP 0x13 #define AC_PAR_VOL_KNB_CAP 0x13
#define AC_PAR_DEVLIST_LEN 0x15
#define AC_PAR_HDMI_LPCM_CAP 0x20 #define AC_PAR_HDMI_LPCM_CAP 0x20
/* /*
...@@ -352,6 +356,10 @@ enum { ...@@ -352,6 +356,10 @@ enum {
#define AC_LPCMCAP_44K (1<<30) /* 44.1kHz support */ #define AC_LPCMCAP_44K (1<<30) /* 44.1kHz support */
#define AC_LPCMCAP_44K_MS (1<<31) /* 44.1kHz-multiplies support */ #define AC_LPCMCAP_44K_MS (1<<31) /* 44.1kHz-multiplies support */
/* Display pin's device list length */
#define AC_DEV_LIST_LEN_MASK 0x3f
#define AC_MAX_DEV_LIST_LEN 64
/* /*
* Control Parameters * Control Parameters
*/ */
...@@ -460,6 +468,11 @@ enum { ...@@ -460,6 +468,11 @@ enum {
#define AC_DEFCFG_PORT_CONN (0x3<<30) #define AC_DEFCFG_PORT_CONN (0x3<<30)
#define AC_DEFCFG_PORT_CONN_SHIFT 30 #define AC_DEFCFG_PORT_CONN_SHIFT 30
/* Display pin's device list entry */
#define AC_DE_PD (1<<0)
#define AC_DE_ELDV (1<<1)
#define AC_DE_IA (1<<2)
/* device device types (0x0-0xf) */ /* device device types (0x0-0xf) */
enum { enum {
AC_JACK_LINE_OUT, AC_JACK_LINE_OUT,
...@@ -885,6 +898,7 @@ struct hda_codec { ...@@ -885,6 +898,7 @@ struct hda_codec {
unsigned int pcm_format_first:1; /* PCM format must be set first */ unsigned int pcm_format_first:1; /* PCM format must be set first */
unsigned int epss:1; /* supporting EPSS? */ unsigned int epss:1; /* supporting EPSS? */
unsigned int cached_write:1; /* write only to caches */ unsigned int cached_write:1; /* write only to caches */
unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */
#ifdef CONFIG_PM #ifdef CONFIG_PM
unsigned int power_on :1; /* current (global) power-state */ unsigned int power_on :1; /* current (global) power-state */
unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */ 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,6 +986,8 @@ int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int nums,
const hda_nid_t *list); const hda_nid_t *list);
int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux, int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
hda_nid_t nid, int recursive); hda_nid_t nid, int recursive);
int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
u8 *dev_list, int max_devices);
int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
u32 *ratesp, u64 *formatsp, unsigned int *bpsp); u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment