diff options
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/hda_codec.c | 42 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 2 | ||||
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 16 | ||||
-rw-r--r-- | sound/pci/hda/patch_cmedia.c | 11 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 15 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 14 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 27 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 40 |
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 | */ | ||
516 | int 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 | } | ||
538 | EXPORT_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); |
906 | int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid, | 906 | int 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); |
908 | int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux, | ||
909 | hda_nid_t nid, int recursive); | ||
908 | int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, | 910 | int 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 | ||
3309 | static const hda_nid_t cx_auto_adc_nids[] = { 0x14 }; | 3309 | static 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)\ |
3312 | static 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 | ||
1198 | static 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 */ |
1212 | static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec) | 1202 | static 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 | ||
3411 | static 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 | */ | ||
417 | static 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 | ||
435 | static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, | 416 | static 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 */ | ||
2015 | static bool is_reachable_nid(struct hda_codec *codec, hda_nid_t src, | 1995 | static 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; |