@@ -311,9 +311,15 @@ int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
311
311
}
312
312
EXPORT_SYMBOL_GPL (snd_hda_get_conn_index );
313
313
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 )
317
323
{
318
324
unsigned int wcaps = get_wcaps (codec , nid );
319
325
unsigned int parm ;
@@ -327,6 +333,7 @@ static unsigned int get_num_devices(struct hda_codec *codec, hda_nid_t nid)
327
333
parm = 0 ;
328
334
return parm & AC_DEV_LIST_LEN_MASK ;
329
335
}
336
+ EXPORT_SYMBOL_GPL (snd_hda_get_num_devices );
330
337
331
338
/**
332
339
* 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,
344
351
unsigned int parm ;
345
352
int i , dev_len , devices ;
346
353
347
- parm = get_num_devices (codec , nid );
354
+ parm = snd_hda_get_num_devices (codec , nid );
348
355
if (!parm ) /* not multi-stream capable */
349
356
return 0 ;
350
357
@@ -368,6 +375,63 @@ int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
368
375
return devices ;
369
376
}
370
377
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
+
371
435
/*
372
436
* read widget caps for each widget and store in cache
373
437
*/
0 commit comments