aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/hda_codec.c42
-rw-r--r--sound/pci/hda/hda_codec.h2
-rw-r--r--sound/pci/hda/patch_cirrus.c16
-rw-r--r--sound/pci/hda/patch_cmedia.c11
-rw-r--r--sound/pci/hda/patch_conexant.c15
-rw-r--r--sound/pci/hda/patch_realtek.c14
-rw-r--r--sound/pci/hda/patch_sigmatel.c27
-rw-r--r--sound/pci/hda/patch_via.c40
8 files changed, 59 insertions, 108 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 26c420de91c3..7f8502388a82 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -411,11 +411,8 @@ static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
411 411
412 wcaps = get_wcaps(codec, nid); 412 wcaps = get_wcaps(codec, nid);
413 if (!(wcaps & AC_WCAP_CONN_LIST) && 413 if (!(wcaps & AC_WCAP_CONN_LIST) &&
414 get_wcaps_type(wcaps) != AC_WID_VOL_KNB) { 414 get_wcaps_type(wcaps) != AC_WID_VOL_KNB)
415 snd_printk(KERN_WARNING "hda_codec: " 415 return 0;
416 "connection list not available for 0x%x\n", nid);
417 return -EINVAL;
418 }
419 416
420 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN); 417 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN);
421 if (parm & AC_CLIST_LONG) { 418 if (parm & AC_CLIST_LONG) {
@@ -506,6 +503,41 @@ static bool add_conn_list(struct snd_array *array, hda_nid_t nid)
506} 503}
507 504
508/** 505/**
506 * snd_hda_get_conn_index - get the connection index of the given NID
507 * @codec: the HDA codec
508 * @mux: NID containing the list
509 * @nid: NID to select
510 * @recursive: 1 when searching NID recursively, otherwise 0
511 *
512 * Parses the connection list of the widget @mux and checks whether the
513 * widget @nid is present. If it is, return the connection index.
514 * Otherwise it returns -1.
515 */
516int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
517 hda_nid_t nid, int recursive)
518{
519 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
520 int i, nums;
521
522 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
523 for (i = 0; i < nums; i++)
524 if (conn[i] == nid)
525 return i;
526 if (!recursive)
527 return -1;
528 if (recursive > 5) {
529 snd_printd("hda_codec: too deep connection for 0x%x\n", nid);
530 return -1;
531 }
532 recursive++;
533 for (i = 0; i < nums; i++)
534 if (snd_hda_get_conn_index(codec, conn[i], nid, recursive) >= 0)
535 return i;
536 return -1;
537}
538EXPORT_SYMBOL_HDA(snd_hda_get_conn_index);
539
540/**
509 * snd_hda_queue_unsol_event - add an unsolicited event to queue 541 * snd_hda_queue_unsol_event - add an unsolicited event to queue
510 * @bus: the BUS 542 * @bus: the BUS
511 * @res: unsolicited event (lower 32bit of RIRB entry) 543 * @res: unsolicited event (lower 32bit of RIRB entry)
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 79ef65e3ae14..10d500d2ba33 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -905,6 +905,8 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
905 hda_nid_t *conn_list, int max_conns); 905 hda_nid_t *conn_list, int max_conns);
906int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid, 906int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid,
907 const hda_nid_t **listp); 907 const hda_nid_t **listp);
908int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
909 hda_nid_t nid, int recursive);
908int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, 910int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
909 u32 *ratesp, u64 *formatsp, unsigned int *bpsp); 911 u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
910 912
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index c7b5ca28fa77..7f93739b1e33 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -346,21 +346,15 @@ static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin,
346 346
347 nid = codec->start_nid; 347 nid = codec->start_nid;
348 for (i = 0; i < codec->num_nodes; i++, nid++) { 348 for (i = 0; i < codec->num_nodes; i++, nid++) {
349 hda_nid_t pins[2];
350 unsigned int type; 349 unsigned int type;
351 int j, nums; 350 int idx;
352 type = get_wcaps_type(get_wcaps(codec, nid)); 351 type = get_wcaps_type(get_wcaps(codec, nid));
353 if (type != AC_WID_AUD_IN) 352 if (type != AC_WID_AUD_IN)
354 continue; 353 continue;
355 nums = snd_hda_get_connections(codec, nid, pins, 354 idx = snd_hda_get_conn_index(codec, nid, pin, 0);
356 ARRAY_SIZE(pins)); 355 if (idx >= 0) {
357 if (nums <= 0) 356 *idxp = idx;
358 continue; 357 return nid;
359 for (j = 0; j < nums; j++) {
360 if (pins[j] == pin) {
361 *idxp = j;
362 return nid;
363 }
364 } 358 }
365 } 359 }
366 return 0; 360 return 0;
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c
index 9eaf99b01aec..08af4847c07a 100644
--- a/sound/pci/hda/patch_cmedia.c
+++ b/sound/pci/hda/patch_cmedia.c
@@ -403,7 +403,6 @@ static int cmi9880_fill_multi_init(struct hda_codec *codec, const struct auto_pi
403 /* clear the table, only one c-media dac assumed here */ 403 /* clear the table, only one c-media dac assumed here */
404 memset(spec->multi_init, 0, sizeof(spec->multi_init)); 404 memset(spec->multi_init, 0, sizeof(spec->multi_init));
405 for (j = 0, i = 0; i < cfg->line_outs; i++) { 405 for (j = 0, i = 0; i < cfg->line_outs; i++) {
406 hda_nid_t conn[4];
407 nid = cfg->line_out_pins[i]; 406 nid = cfg->line_out_pins[i];
408 /* set as output */ 407 /* set as output */
409 spec->multi_init[j].nid = nid; 408 spec->multi_init[j].nid = nid;
@@ -416,12 +415,10 @@ static int cmi9880_fill_multi_init(struct hda_codec *codec, const struct auto_pi
416 spec->multi_init[j].verb = AC_VERB_SET_CONNECT_SEL; 415 spec->multi_init[j].verb = AC_VERB_SET_CONNECT_SEL;
417 spec->multi_init[j].param = 0; 416 spec->multi_init[j].param = 0;
418 /* find the index in connect list */ 417 /* find the index in connect list */
419 len = snd_hda_get_connections(codec, nid, conn, 4); 418 k = snd_hda_get_conn_index(codec, nid,
420 for (k = 0; k < len; k++) 419 spec->dac_nids[i], 0);
421 if (conn[k] == spec->dac_nids[i]) { 420 if (k >= 0)
422 spec->multi_init[j].param = k; 421 spec->multi_init[j].param = k;
423 break;
424 }
425 j++; 422 j++;
426 } 423 }
427 } 424 }
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 6e864276b744..40cf7f16f587 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3308,19 +3308,8 @@ static const struct hda_pcm_stream cx_auto_pcm_analog_capture = {
3308 3308
3309static const hda_nid_t cx_auto_adc_nids[] = { 0x14 }; 3309static const hda_nid_t cx_auto_adc_nids[] = { 0x14 };
3310 3310
3311/* get the connection index of @nid in the widget @mux */ 3311#define get_connection_index(codec, mux, nid)\
3312static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 3312 snd_hda_get_conn_index(codec, mux, nid, 0)
3313 hda_nid_t nid)
3314{
3315 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3316 int i, nums;
3317
3318 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3319 for (i = 0; i < nums; i++)
3320 if (conn[i] == nid)
3321 return i;
3322 return -1;
3323}
3324 3313
3325/* get an unassigned DAC from the given list. 3314/* get an unassigned DAC from the given list.
3326 * Return the nid if found and reduce the DAC list, or return zero if 3315 * Return the nid if found and reduce the DAC list, or return zero if
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index cf383ede281d..7b96dcef2c62 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1195,18 +1195,8 @@ static void alc_line_automute(struct hda_codec *codec)
1195 update_speakers(codec); 1195 update_speakers(codec);
1196} 1196}
1197 1197
1198static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 1198#define get_connection_index(codec, mux, nid) \
1199 hda_nid_t nid) 1199 snd_hda_get_conn_index(codec, mux, nid, 0)
1200{
1201 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1202 int i, nums;
1203
1204 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1205 for (i = 0; i < nums; i++)
1206 if (conn[i] == nid)
1207 return i;
1208 return -1;
1209}
1210 1200
1211/* switch the current ADC according to the jack state */ 1201/* switch the current ADC according to the jack state */
1212static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec) 1202static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 7407095cbc78..56425a53cf1b 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -3408,30 +3408,9 @@ static hda_nid_t get_connected_node(struct hda_codec *codec, hda_nid_t mux,
3408 return 0; 3408 return 0;
3409} 3409}
3410 3410
3411static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, 3411/* look for NID recursively */
3412 hda_nid_t nid) 3412#define get_connection_index(codec, mux, nid) \
3413{ 3413 snd_hda_get_conn_index(codec, mux, nid, 1)
3414 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3415 int i, nums;
3416
3417 if (!(get_wcaps(codec, mux) & AC_WCAP_CONN_LIST))
3418 return -1;
3419
3420 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3421 for (i = 0; i < nums; i++)
3422 if (conn[i] == nid)
3423 return i;
3424
3425 for (i = 0; i < nums; i++) {
3426 unsigned int wid_caps = get_wcaps(codec, conn[i]);
3427 unsigned int wid_type = get_wcaps_type(wid_caps);
3428
3429 if (wid_type != AC_WID_PIN && wid_type != AC_WID_AUD_MIX)
3430 if (get_connection_index(codec, conn[i], nid) >= 0)
3431 return i;
3432 }
3433 return -1;
3434}
3435 3414
3436/* create a volume assigned to the given pin (only if supported) */ 3415/* create a volume assigned to the given pin (only if supported) */
3437/* return 1 if the volume control is created */ 3416/* return 1 if the volume control is created */
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 997b7057a549..76142c1389d7 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -410,27 +410,8 @@ static int via_new_analog_input(struct via_spec *spec, const char *ctlname,
410 return 0; 410 return 0;
411} 411}
412 412
413/* return the index of the given widget nid as the source of mux;
414 * return -1 if not found;
415 * if num_conns is non-NULL, set the total number of connections
416 */
417static int __get_connection_index(struct hda_codec *codec, hda_nid_t mux,
418 hda_nid_t nid, int *num_conns)
419{
420 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
421 int i, nums;
422
423 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
424 if (num_conns)
425 *num_conns = nums;
426 for (i = 0; i < nums; i++)
427 if (conn[i] == nid)
428 return i;
429 return -1;
430}
431
432#define get_connection_index(codec, mux, nid) \ 413#define get_connection_index(codec, mux, nid) \
433 __get_connection_index(codec, mux, nid, NULL) 414 snd_hda_get_conn_index(codec, mux, nid, 0)
434 415
435static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, 416static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
436 unsigned int mask) 417 unsigned int mask)
@@ -2011,23 +1992,10 @@ static void add_loopback_list(struct via_spec *spec, hda_nid_t mix, int idx)
2011 spec->loopback.amplist = spec->loopback_list; 1992 spec->loopback.amplist = spec->loopback_list;
2012} 1993}
2013 1994
2014/* check whether the path from src to dst is reachable */
2015static bool is_reachable_nid(struct hda_codec *codec, hda_nid_t src, 1995static bool is_reachable_nid(struct hda_codec *codec, hda_nid_t src,
2016 hda_nid_t dst, int depth) 1996 hda_nid_t dst)
2017{ 1997{
2018 hda_nid_t conn[8]; 1998 return snd_hda_get_conn_index(codec, src, dst, 1) >= 0;
2019 int i, nums;
2020
2021 nums = snd_hda_get_connections(codec, src, conn, ARRAY_SIZE(conn));
2022 for (i = 0; i < nums; i++)
2023 if (conn[i] == dst)
2024 return true;
2025 if (++depth > MAX_NID_PATH_DEPTH)
2026 return false;
2027 for (i = 0; i < nums; i++)
2028 if (is_reachable_nid(codec, conn[i], dst, depth))
2029 return true;
2030 return false;
2031} 1999}
2032 2000
2033/* add the input-route to the given pin */ 2001/* add the input-route to the given pin */
@@ -2046,7 +2014,7 @@ static bool add_input_route(struct hda_codec *codec, hda_nid_t pin)
2046 continue; 2014 continue;
2047 spec->inputs[spec->num_inputs].mux_idx = idx; 2015 spec->inputs[spec->num_inputs].mux_idx = idx;
2048 } else { 2016 } else {
2049 if (!is_reachable_nid(codec, spec->adc_nids[c], pin, 0)) 2017 if (!is_reachable_nid(codec, spec->adc_nids[c], pin))
2050 continue; 2018 continue;
2051 } 2019 }
2052 spec->inputs[spec->num_inputs].adc_idx = c; 2020 spec->inputs[spec->num_inputs].adc_idx = c;