aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-05-13 12:36:37 -0400
committerTakashi Iwai <tiwai@suse.de>2011-05-13 13:30:58 -0400
commit5c9887e08761eecd4dafbdff354ef7c703efb201 (patch)
tree9fd0f2aea4e102bae90ebc8f2f23f32108f7dbbb /sound
parentf6100bb4b849c45caa8d6b3706756d3b8a560c92 (diff)
ALSA: hda - Parse more deep input-source routes in Conexant auto-parser
Handle not only a single-depth input-route but two-level depth routes (PIN->MUX->ADC), too. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/patch_conexant.c73
1 files changed, 52 insertions, 21 deletions
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index b575c9989f3c..655bd23e80df 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3276,15 +3276,6 @@ static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
3276 return -1; 3276 return -1;
3277} 3277}
3278 3278
3279static int has_multi_connection(struct hda_codec *codec, hda_nid_t mux)
3280{
3281 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3282 int nums;
3283
3284 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3285 return nums > 1;
3286}
3287
3288/* get an unassigned DAC from the given list. 3279/* get an unassigned DAC from the given list.
3289 * Return the nid if found and reduce the DAC list, or return zero if 3280 * Return the nid if found and reduce the DAC list, or return zero if
3290 * not found 3281 * not found
@@ -3455,6 +3446,51 @@ static int cx_auto_mux_enum_get(struct snd_kcontrol *kcontrol,
3455 return 0; 3446 return 0;
3456} 3447}
3457 3448
3449/* look for the route the given pin from mux and return the index;
3450 * if do_select is set, actually select the route.
3451 */
3452static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux,
3453 hda_nid_t pin, bool do_select, int depth)
3454{
3455 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
3456 int i, nums;
3457
3458 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
3459 for (i = 0; i < nums; i++)
3460 if (conn[i] == pin) {
3461 if (do_select)
3462 snd_hda_codec_write(codec, mux, 0,
3463 AC_VERB_SET_CONNECT_SEL, i);
3464 return i;
3465 }
3466 depth++;
3467 if (depth == 2)
3468 return -1;
3469 for (i = 0; i < nums; i++) {
3470 int ret = __select_input_connection(codec, conn[i], pin,
3471 do_select, depth);
3472 if (ret >= 0) {
3473 if (do_select)
3474 snd_hda_codec_write(codec, mux, 0,
3475 AC_VERB_SET_CONNECT_SEL, i);
3476 return ret;
3477 }
3478 }
3479 return -1;
3480}
3481
3482static void select_input_connection(struct hda_codec *codec, hda_nid_t mux,
3483 hda_nid_t pin)
3484{
3485 __select_input_connection(codec, mux, pin, true, 0);
3486}
3487
3488static int get_input_connection(struct hda_codec *codec, hda_nid_t mux,
3489 hda_nid_t pin)
3490{
3491 return __select_input_connection(codec, mux, pin, false, 0);
3492}
3493
3458static int cx_auto_mux_enum_update(struct hda_codec *codec, 3494static int cx_auto_mux_enum_update(struct hda_codec *codec,
3459 const struct hda_input_mux *imux, 3495 const struct hda_input_mux *imux,
3460 unsigned int idx) 3496 unsigned int idx)
@@ -3469,10 +3505,8 @@ static int cx_auto_mux_enum_update(struct hda_codec *codec,
3469 if (spec->cur_mux[0] == idx) 3505 if (spec->cur_mux[0] == idx)
3470 return 0; 3506 return 0;
3471 adc = spec->imux_adcs[idx]; 3507 adc = spec->imux_adcs[idx];
3472 if (has_multi_connection(codec, adc)) 3508 select_input_connection(codec, spec->imux_adcs[idx],
3473 snd_hda_codec_write(codec, adc, 0, 3509 spec->imux_pins[idx]);
3474 AC_VERB_SET_CONNECT_SEL,
3475 imux->items[idx].index);
3476 if (spec->cur_adc && spec->cur_adc != adc) { 3510 if (spec->cur_adc && spec->cur_adc != adc) {
3477 /* stream is running, let's swap the current ADC */ 3511 /* stream is running, let's swap the current ADC */
3478 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); 3512 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
@@ -3584,8 +3618,8 @@ static void cx_auto_parse_input(struct hda_codec *codec)
3584 for (i = 0; i < cfg->num_inputs; i++) { 3618 for (i = 0; i < cfg->num_inputs; i++) {
3585 for (j = 0; j < spec->num_adc_nids; j++) { 3619 for (j = 0; j < spec->num_adc_nids; j++) {
3586 hda_nid_t adc = spec->adc_nids[j]; 3620 hda_nid_t adc = spec->adc_nids[j];
3587 int idx = get_connection_index(codec, adc, 3621 int idx = get_input_connection(codec, adc,
3588 cfg->inputs[i].pin); 3622 cfg->inputs[i].pin);
3589 if (idx >= 0) { 3623 if (idx >= 0) {
3590 const char *label; 3624 const char *label;
3591 label = hda_get_autocfg_input_label(codec, cfg, i); 3625 label = hda_get_autocfg_input_label(codec, cfg, i);
@@ -3791,11 +3825,8 @@ static void cx_auto_init_input(struct hda_codec *codec)
3791 AC_USRSP_EN | CONEXANT_MIC_EVENT); 3825 AC_USRSP_EN | CONEXANT_MIC_EVENT);
3792 cx_auto_automic(codec); 3826 cx_auto_automic(codec);
3793 } else { 3827 } else {
3794 for (i = 0; i < spec->num_adc_nids; i++) { 3828 select_input_connection(codec, spec->imux_adcs[0],
3795 snd_hda_codec_write(codec, spec->adc_nids[i], 0, 3829 spec->imux_pins[0]);
3796 AC_VERB_SET_CONNECT_SEL,
3797 spec->private_imux.items[0].index);
3798 }
3799 } 3830 }
3800} 3831}
3801 3832
@@ -3924,7 +3955,7 @@ static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid,
3924 3955
3925 for (i = 0; i < spec->num_adc_nids; i++) { 3956 for (i = 0; i < spec->num_adc_nids; i++) {
3926 hda_nid_t adc_nid = spec->adc_nids[i]; 3957 hda_nid_t adc_nid = spec->adc_nids[i];
3927 int idx = get_connection_index(codec, adc_nid, nid); 3958 int idx = get_input_connection(codec, adc_nid, nid);
3928 if (idx < 0) 3959 if (idx < 0)
3929 continue; 3960 continue;
3930 return cx_auto_add_volume_idx(codec, label, pfx, 3961 return cx_auto_add_volume_idx(codec, label, pfx,