diff options
author | Takashi Iwai <tiwai@suse.de> | 2006-03-21 05:24:42 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-03-22 04:40:14 -0500 |
commit | 82bc955f6379135e6ce35ff90c7ac411fd412c4c (patch) | |
tree | 314610afb5a469ac6a5a9f4d5e947436bb2c0538 /sound/pci/hda/patch_realtek.c | |
parent | 19739fef0203d2f3eecc9c4b1ef25b57d85f2b30 (diff) |
[ALSA] hda-codec - Fix BIOS auto-configuration
Modules: HDA Codec driver,HDA generic driver
- Fix autoconfig speaker/hp detection
Now it allows multiple speaker pins (e.g. Dell laptops have such config)
- Use speaker or hp pins if no line-outs are available
This fixes the silence output on recent Dell laptops with STAC9200
(ALSA bug#1843)
- Fix analog/realtek/sigmatel autoconfig parser
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 47 |
1 files changed, 14 insertions, 33 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 1607a1fab568..de145d102d9f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -2431,14 +2431,11 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, | |||
2431 | 2431 | ||
2432 | if (alc880_is_fixed_pin(pin)) { | 2432 | if (alc880_is_fixed_pin(pin)) { |
2433 | nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); | 2433 | nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); |
2434 | if (! spec->multiout.dac_nids[0]) { | 2434 | /* specify the DAC as the extra output */ |
2435 | /* use this as the primary output */ | 2435 | if (! spec->multiout.hp_nid) |
2436 | spec->multiout.dac_nids[0] = nid; | ||
2437 | if (! spec->multiout.num_dacs) | ||
2438 | spec->multiout.num_dacs = 1; | ||
2439 | } else | ||
2440 | /* specify the DAC as the extra output */ | ||
2441 | spec->multiout.hp_nid = nid; | 2436 | spec->multiout.hp_nid = nid; |
2437 | else | ||
2438 | spec->multiout.extra_out_nid[0] = nid; | ||
2442 | /* control HP volume/switch on the output mixer amp */ | 2439 | /* control HP volume/switch on the output mixer amp */ |
2443 | nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); | 2440 | nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); |
2444 | sprintf(name, "%s Playback Volume", pfx); | 2441 | sprintf(name, "%s Playback Volume", pfx); |
@@ -2451,12 +2448,6 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, | |||
2451 | return err; | 2448 | return err; |
2452 | } else if (alc880_is_multi_pin(pin)) { | 2449 | } else if (alc880_is_multi_pin(pin)) { |
2453 | /* set manual connection */ | 2450 | /* set manual connection */ |
2454 | if (! spec->multiout.dac_nids[0]) { | ||
2455 | /* use this as the primary output */ | ||
2456 | spec->multiout.dac_nids[0] = alc880_idx_to_dac(alc880_multi_pin_idx(pin)); | ||
2457 | if (! spec->multiout.num_dacs) | ||
2458 | spec->multiout.num_dacs = 1; | ||
2459 | } | ||
2460 | /* we have only a switch on HP-out PIN */ | 2451 | /* we have only a switch on HP-out PIN */ |
2461 | sprintf(name, "%s Playback Switch", pfx); | 2452 | sprintf(name, "%s Playback Switch", pfx); |
2462 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, | 2453 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, |
@@ -2540,7 +2531,7 @@ static void alc880_auto_init_extra_out(struct hda_codec *codec) | |||
2540 | struct alc_spec *spec = codec->spec; | 2531 | struct alc_spec *spec = codec->spec; |
2541 | hda_nid_t pin; | 2532 | hda_nid_t pin; |
2542 | 2533 | ||
2543 | pin = spec->autocfg.speaker_pin; | 2534 | pin = spec->autocfg.speaker_pins[0]; |
2544 | if (pin) /* connect to front */ | 2535 | if (pin) /* connect to front */ |
2545 | alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); | 2536 | alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); |
2546 | pin = spec->autocfg.hp_pin; | 2537 | pin = spec->autocfg.hp_pin; |
@@ -2576,15 +2567,15 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
2576 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 2567 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
2577 | alc880_ignore)) < 0) | 2568 | alc880_ignore)) < 0) |
2578 | return err; | 2569 | return err; |
2579 | if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin && | 2570 | if (! spec->autocfg.line_outs) |
2580 | ! spec->autocfg.hp_pin) | ||
2581 | return 0; /* can't find valid BIOS pin config */ | 2571 | return 0; /* can't find valid BIOS pin config */ |
2582 | 2572 | ||
2583 | if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || | 2573 | if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || |
2584 | (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || | 2574 | (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || |
2585 | (err = alc880_auto_create_extra_out(spec, spec->autocfg.speaker_pin, | 2575 | (err = alc880_auto_create_extra_out(spec, |
2576 | spec->autocfg.speaker_pins[0], | ||
2586 | "Speaker")) < 0 || | 2577 | "Speaker")) < 0 || |
2587 | (err = alc880_auto_create_extra_out(spec, spec->autocfg.speaker_pin, | 2578 | (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pin, |
2588 | "Headphone")) < 0 || | 2579 | "Headphone")) < 0 || |
2589 | (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) | 2580 | (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) |
2590 | return err; | 2581 | return err; |
@@ -3445,7 +3436,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
3445 | return err; | 3436 | return err; |
3446 | } | 3437 | } |
3447 | 3438 | ||
3448 | nid = cfg->speaker_pin; | 3439 | nid = cfg->speaker_pins[0]; |
3449 | if (nid) { | 3440 | if (nid) { |
3450 | err = alc260_add_playback_controls(spec, nid, "Speaker"); | 3441 | err = alc260_add_playback_controls(spec, nid, "Speaker"); |
3451 | if (err < 0) | 3442 | if (err < 0) |
@@ -3518,7 +3509,7 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) | |||
3518 | if (nid) | 3509 | if (nid) |
3519 | alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); | 3510 | alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); |
3520 | 3511 | ||
3521 | nid = spec->autocfg.speaker_pin; | 3512 | nid = spec->autocfg.speaker_pins[0]; |
3522 | if (nid) | 3513 | if (nid) |
3523 | alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); | 3514 | alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); |
3524 | 3515 | ||
@@ -4602,7 +4593,7 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct | |||
4602 | return err; | 4593 | return err; |
4603 | } | 4594 | } |
4604 | 4595 | ||
4605 | nid = cfg->speaker_pin; | 4596 | nid = cfg->speaker_pins[0]; |
4606 | if (nid) { | 4597 | if (nid) { |
4607 | if (nid == 0x16) { | 4598 | if (nid == 0x16) { |
4608 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume", | 4599 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume", |
@@ -4612,10 +4603,6 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct | |||
4612 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) | 4603 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) |
4613 | return err; | 4604 | return err; |
4614 | } else { | 4605 | } else { |
4615 | if (! cfg->line_out_pins[0]) | ||
4616 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume", | ||
4617 | HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0) | ||
4618 | return err; | ||
4619 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch", | 4606 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch", |
4620 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 4607 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) |
4621 | return err; | 4608 | return err; |
@@ -4632,10 +4619,6 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct | |||
4632 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) | 4619 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) |
4633 | return err; | 4620 | return err; |
4634 | } else { | 4621 | } else { |
4635 | if (! cfg->line_out_pins[0]) | ||
4636 | if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume", | ||
4637 | HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0) | ||
4638 | return err; | ||
4639 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", | 4622 | if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", |
4640 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) | 4623 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) |
4641 | return err; | 4624 | return err; |
@@ -4729,8 +4712,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
4729 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 4712 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
4730 | alc262_ignore)) < 0) | 4713 | alc262_ignore)) < 0) |
4731 | return err; | 4714 | return err; |
4732 | if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin && | 4715 | if (! spec->autocfg.line_outs) |
4733 | ! spec->autocfg.hp_pin) | ||
4734 | return 0; /* can't find valid BIOS pin config */ | 4716 | return 0; /* can't find valid BIOS pin config */ |
4735 | if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || | 4717 | if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || |
4736 | (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) | 4718 | (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) |
@@ -5404,8 +5386,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
5404 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 5386 | if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
5405 | alc861_ignore)) < 0) | 5387 | alc861_ignore)) < 0) |
5406 | return err; | 5388 | return err; |
5407 | if (! spec->autocfg.line_outs && ! spec->autocfg.speaker_pin && | 5389 | if (! spec->autocfg.line_outs) |
5408 | ! spec->autocfg.hp_pin) | ||
5409 | return 0; /* can't find valid BIOS pin config */ | 5390 | return 0; /* can't find valid BIOS pin config */ |
5410 | 5391 | ||
5411 | if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || | 5392 | if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || |