Skip to content

Commit 13800f3

Browse files
libinyangdanvet
authored andcommitted
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 <[email protected]> Signed-off-by: Libin Yang <[email protected]> Signed-off-by: Daniel Vetter <[email protected]> Link: http://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent 3486977 commit 13800f3

File tree

2 files changed

+71
-4
lines changed

2 files changed

+71
-4
lines changed

sound/pci/hda/hda_codec.c

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -311,9 +311,15 @@ int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
311311
}
312312
EXPORT_SYMBOL_GPL(snd_hda_get_conn_index);
313313

314-
315-
/* return DEVLIST_LEN parameter of the given widget */
316-
static unsigned int get_num_devices(struct hda_codec *codec, hda_nid_t nid)
314+
/**
315+
* snd_hda_get_num_devices - get DEVLIST_LEN parameter of the given widget
316+
* @codec: the HDA codec
317+
* @nid: NID of the pin to parse
318+
*
319+
* Get the device entry number on the given widget. This is a feature of
320+
* DP MST audio. Each pin can have several device entries in it.
321+
*/
322+
unsigned int snd_hda_get_num_devices(struct hda_codec *codec, hda_nid_t nid)
317323
{
318324
unsigned int wcaps = get_wcaps(codec, nid);
319325
unsigned int parm;
@@ -327,6 +333,7 @@ static unsigned int get_num_devices(struct hda_codec *codec, hda_nid_t nid)
327333
parm = 0;
328334
return parm & AC_DEV_LIST_LEN_MASK;
329335
}
336+
EXPORT_SYMBOL_GPL(snd_hda_get_num_devices);
330337

331338
/**
332339
* 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,
344351
unsigned int parm;
345352
int i, dev_len, devices;
346353

347-
parm = get_num_devices(codec, nid);
354+
parm = snd_hda_get_num_devices(codec, nid);
348355
if (!parm) /* not multi-stream capable */
349356
return 0;
350357

@@ -368,6 +375,63 @@ int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
368375
return devices;
369376
}
370377

378+
/**
379+
* snd_hda_get_dev_select - get device entry select on the pin
380+
* @codec: the HDA codec
381+
* @nid: NID of the pin to get device entry select
382+
*
383+
* Get the devcie entry select on the pin. Return the device entry
384+
* id selected on the pin. Return 0 means the first device entry
385+
* is selected or MST is not supported.
386+
*/
387+
int snd_hda_get_dev_select(struct hda_codec *codec, hda_nid_t nid)
388+
{
389+
/* not support dp_mst will always return 0, using first dev_entry */
390+
if (!codec->dp_mst)
391+
return 0;
392+
393+
return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DEVICE_SEL, 0);
394+
}
395+
EXPORT_SYMBOL_GPL(snd_hda_get_dev_select);
396+
397+
/**
398+
* snd_hda_set_dev_select - set device entry select on the pin
399+
* @codec: the HDA codec
400+
* @nid: NID of the pin to set device entry select
401+
* @dev_id: device entry id to be set
402+
*
403+
* Set the device entry select on the pin nid.
404+
*/
405+
int snd_hda_set_dev_select(struct hda_codec *codec, hda_nid_t nid, int dev_id)
406+
{
407+
int ret, num_devices;
408+
409+
/* not support dp_mst will always return 0, using first dev_entry */
410+
if (!codec->dp_mst)
411+
return 0;
412+
413+
/* AC_PAR_DEVLIST_LEN is 0 based. */
414+
num_devices = snd_hda_get_num_devices(codec, nid) + 1;
415+
/* If Device List Length is 0 (num_device = 1),
416+
* the pin is not multi stream capable.
417+
* Do nothing in this case.
418+
*/
419+
if (num_devices == 1)
420+
return 0;
421+
422+
/* Behavior of setting index being equal to or greater than
423+
* Device List Length is not predictable
424+
*/
425+
if (num_devices <= dev_id)
426+
return -EINVAL;
427+
428+
ret = snd_hda_codec_write(codec, nid, 0,
429+
AC_VERB_SET_DEVICE_SEL, dev_id);
430+
431+
return ret;
432+
}
433+
EXPORT_SYMBOL_GPL(snd_hda_set_dev_select);
434+
371435
/*
372436
* read widget caps for each widget and store in cache
373437
*/

sound/pci/hda/hda_codec.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,11 @@ int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int nums,
347347
const hda_nid_t *list);
348348
int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
349349
hda_nid_t nid, int recursive);
350+
unsigned int snd_hda_get_num_devices(struct hda_codec *codec, hda_nid_t nid);
350351
int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
351352
u8 *dev_list, int max_devices);
353+
int snd_hda_get_dev_select(struct hda_codec *codec, hda_nid_t nid);
354+
int snd_hda_set_dev_select(struct hda_codec *codec, hda_nid_t nid, int dev_id);
352355

353356
struct hda_verb {
354357
hda_nid_t nid;

0 commit comments

Comments
 (0)