ALSA: hda - add DP mst verb support
Add snd_hda_get_dev_select() and snd_hda_set_dev_select() functions for DP MST audio support. Reviewed-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Libin Yang <libin.yang@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Link: http://patchwork.freedesktop.org/patch/msgid/1484208294-8637-2-git-send-email-libin.yang@intel.com
This commit is contained in:
parent
34869776c7
commit
13800f397e
|
@ -311,9 +311,15 @@ int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(snd_hda_get_conn_index);
|
EXPORT_SYMBOL_GPL(snd_hda_get_conn_index);
|
||||||
|
|
||||||
|
/**
|
||||||
/* return DEVLIST_LEN parameter of the given widget */
|
* snd_hda_get_num_devices - get DEVLIST_LEN parameter of the given widget
|
||||||
static unsigned int get_num_devices(struct hda_codec *codec, hda_nid_t nid)
|
* @codec: the HDA codec
|
||||||
|
* @nid: NID of the pin to parse
|
||||||
|
*
|
||||||
|
* Get the device entry number on the given widget. This is a feature of
|
||||||
|
* DP MST audio. Each pin can have several device entries in it.
|
||||||
|
*/
|
||||||
|
unsigned int snd_hda_get_num_devices(struct hda_codec *codec, hda_nid_t nid)
|
||||||
{
|
{
|
||||||
unsigned int wcaps = get_wcaps(codec, nid);
|
unsigned int wcaps = get_wcaps(codec, nid);
|
||||||
unsigned int parm;
|
unsigned int parm;
|
||||||
|
@ -327,6 +333,7 @@ static unsigned int get_num_devices(struct hda_codec *codec, hda_nid_t nid)
|
||||||
parm = 0;
|
parm = 0;
|
||||||
return parm & AC_DEV_LIST_LEN_MASK;
|
return parm & AC_DEV_LIST_LEN_MASK;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(snd_hda_get_num_devices);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* snd_hda_get_devices - copy device list without cache
|
* snd_hda_get_devices - copy device list without cache
|
||||||
|
@ -344,7 +351,7 @@ int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
|
||||||
unsigned int parm;
|
unsigned int parm;
|
||||||
int i, dev_len, devices;
|
int i, dev_len, devices;
|
||||||
|
|
||||||
parm = get_num_devices(codec, nid);
|
parm = snd_hda_get_num_devices(codec, nid);
|
||||||
if (!parm) /* not multi-stream capable */
|
if (!parm) /* not multi-stream capable */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -368,6 +375,63 @@ int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
|
||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* snd_hda_get_dev_select - get device entry select on the pin
|
||||||
|
* @codec: the HDA codec
|
||||||
|
* @nid: NID of the pin to get device entry select
|
||||||
|
*
|
||||||
|
* Get the devcie entry select on the pin. Return the device entry
|
||||||
|
* id selected on the pin. Return 0 means the first device entry
|
||||||
|
* is selected or MST is not supported.
|
||||||
|
*/
|
||||||
|
int snd_hda_get_dev_select(struct hda_codec *codec, hda_nid_t nid)
|
||||||
|
{
|
||||||
|
/* not support dp_mst will always return 0, using first dev_entry */
|
||||||
|
if (!codec->dp_mst)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DEVICE_SEL, 0);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(snd_hda_get_dev_select);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* snd_hda_set_dev_select - set device entry select on the pin
|
||||||
|
* @codec: the HDA codec
|
||||||
|
* @nid: NID of the pin to set device entry select
|
||||||
|
* @dev_id: device entry id to be set
|
||||||
|
*
|
||||||
|
* Set the device entry select on the pin nid.
|
||||||
|
*/
|
||||||
|
int snd_hda_set_dev_select(struct hda_codec *codec, hda_nid_t nid, int dev_id)
|
||||||
|
{
|
||||||
|
int ret, num_devices;
|
||||||
|
|
||||||
|
/* not support dp_mst will always return 0, using first dev_entry */
|
||||||
|
if (!codec->dp_mst)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* AC_PAR_DEVLIST_LEN is 0 based. */
|
||||||
|
num_devices = snd_hda_get_num_devices(codec, nid) + 1;
|
||||||
|
/* If Device List Length is 0 (num_device = 1),
|
||||||
|
* the pin is not multi stream capable.
|
||||||
|
* Do nothing in this case.
|
||||||
|
*/
|
||||||
|
if (num_devices == 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Behavior of setting index being equal to or greater than
|
||||||
|
* Device List Length is not predictable
|
||||||
|
*/
|
||||||
|
if (num_devices <= dev_id)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
ret = snd_hda_codec_write(codec, nid, 0,
|
||||||
|
AC_VERB_SET_DEVICE_SEL, dev_id);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(snd_hda_set_dev_select);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* read widget caps for each widget and store in cache
|
* read widget caps for each widget and store in cache
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -347,8 +347,11 @@ 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);
|
||||||
|
unsigned int snd_hda_get_num_devices(struct hda_codec *codec, hda_nid_t nid);
|
||||||
int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
|
int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
|
||||||
u8 *dev_list, int max_devices);
|
u8 *dev_list, int max_devices);
|
||||||
|
int snd_hda_get_dev_select(struct hda_codec *codec, hda_nid_t nid);
|
||||||
|
int snd_hda_set_dev_select(struct hda_codec *codec, hda_nid_t nid, int dev_id);
|
||||||
|
|
||||||
struct hda_verb {
|
struct hda_verb {
|
||||||
hda_nid_t nid;
|
hda_nid_t nid;
|
||||||
|
|
Loading…
Reference in a new issue