diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-07-06 08:28:39 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-07-07 03:31:18 -0400 |
commit | 343a04be376a3733514e4eca7a8c8adb2493ea23 (patch) | |
tree | 77879829dd357b899fc7a2cb940b37e39c889d7e | |
parent | 97aaab7b493d9e22a9c0a125a501920354e67846 (diff) |
ALSA: hda - Code consolidation for ALC88x and ALC662 auto-parsers
Use the same common code for auto-parsing the output paths and their
initializations, based on the existing ALC662 code, which is smarter
than the old ALC880/2 code.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 428 |
1 files changed, 75 insertions, 353 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 236200963b02..a0ed9e524d84 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -5325,46 +5325,6 @@ static int add_control_with_pfx(struct alc_spec *spec, int type, | |||
5325 | #define alc880_idx_to_selector(nid) ((nid) + 0x10) | 5325 | #define alc880_idx_to_selector(nid) ((nid) + 0x10) |
5326 | #define ALC880_PIN_CD_NID 0x1c | 5326 | #define ALC880_PIN_CD_NID 0x1c |
5327 | 5327 | ||
5328 | /* fill in the dac_nids table from the parsed pin configuration */ | ||
5329 | static int alc880_auto_fill_dac_nids(struct hda_codec *codec) | ||
5330 | { | ||
5331 | struct alc_spec *spec = codec->spec; | ||
5332 | const struct auto_pin_cfg *cfg = &spec->autocfg; | ||
5333 | hda_nid_t nid; | ||
5334 | int assigned[4]; | ||
5335 | int i, j; | ||
5336 | |||
5337 | memset(assigned, 0, sizeof(assigned)); | ||
5338 | spec->multiout.dac_nids = spec->private_dac_nids; | ||
5339 | |||
5340 | /* check the pins hardwired to audio widget */ | ||
5341 | for (i = 0; i < cfg->line_outs; i++) { | ||
5342 | nid = cfg->line_out_pins[i]; | ||
5343 | if (alc880_is_fixed_pin(nid)) { | ||
5344 | int idx = alc880_fixed_pin_idx(nid); | ||
5345 | spec->private_dac_nids[i] = alc880_idx_to_dac(idx); | ||
5346 | assigned[idx] = 1; | ||
5347 | } | ||
5348 | } | ||
5349 | /* left pins can be connect to any audio widget */ | ||
5350 | for (i = 0; i < cfg->line_outs; i++) { | ||
5351 | nid = cfg->line_out_pins[i]; | ||
5352 | if (alc880_is_fixed_pin(nid)) | ||
5353 | continue; | ||
5354 | /* search for an empty channel */ | ||
5355 | for (j = 0; j < cfg->line_outs; j++) { | ||
5356 | if (!assigned[j]) { | ||
5357 | spec->private_dac_nids[i] = | ||
5358 | alc880_idx_to_dac(j); | ||
5359 | assigned[j] = 1; | ||
5360 | break; | ||
5361 | } | ||
5362 | } | ||
5363 | } | ||
5364 | spec->multiout.num_dacs = cfg->line_outs; | ||
5365 | return 0; | ||
5366 | } | ||
5367 | |||
5368 | static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, | 5328 | static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, |
5369 | bool can_be_master, int *index) | 5329 | bool can_be_master, int *index) |
5370 | { | 5330 | { |
@@ -5397,106 +5357,6 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, | |||
5397 | return chname[ch]; | 5357 | return chname[ch]; |
5398 | } | 5358 | } |
5399 | 5359 | ||
5400 | /* add playback controls from the parsed DAC table */ | ||
5401 | static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, | ||
5402 | const struct auto_pin_cfg *cfg) | ||
5403 | { | ||
5404 | hda_nid_t nid; | ||
5405 | int i, err, noutputs; | ||
5406 | |||
5407 | noutputs = cfg->line_outs; | ||
5408 | if (spec->multi_ios > 0) | ||
5409 | noutputs += spec->multi_ios; | ||
5410 | |||
5411 | for (i = 0; i < noutputs; i++) { | ||
5412 | const char *name; | ||
5413 | int index; | ||
5414 | if (!spec->multiout.dac_nids[i]) | ||
5415 | continue; | ||
5416 | nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); | ||
5417 | name = alc_get_line_out_pfx(spec, i, false, &index); | ||
5418 | if (!name) { | ||
5419 | /* Center/LFE */ | ||
5420 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, | ||
5421 | "Center", | ||
5422 | HDA_COMPOSE_AMP_VAL(nid, 1, 0, | ||
5423 | HDA_OUTPUT)); | ||
5424 | if (err < 0) | ||
5425 | return err; | ||
5426 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, | ||
5427 | "LFE", | ||
5428 | HDA_COMPOSE_AMP_VAL(nid, 2, 0, | ||
5429 | HDA_OUTPUT)); | ||
5430 | if (err < 0) | ||
5431 | return err; | ||
5432 | err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, | ||
5433 | "Center", | ||
5434 | HDA_COMPOSE_AMP_VAL(nid, 1, 2, | ||
5435 | HDA_INPUT)); | ||
5436 | if (err < 0) | ||
5437 | return err; | ||
5438 | err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, | ||
5439 | "LFE", | ||
5440 | HDA_COMPOSE_AMP_VAL(nid, 2, 2, | ||
5441 | HDA_INPUT)); | ||
5442 | if (err < 0) | ||
5443 | return err; | ||
5444 | } else { | ||
5445 | err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, | ||
5446 | name, index, | ||
5447 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, | ||
5448 | HDA_OUTPUT)); | ||
5449 | if (err < 0) | ||
5450 | return err; | ||
5451 | err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, | ||
5452 | name, index, | ||
5453 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, | ||
5454 | HDA_INPUT)); | ||
5455 | if (err < 0) | ||
5456 | return err; | ||
5457 | } | ||
5458 | } | ||
5459 | return 0; | ||
5460 | } | ||
5461 | |||
5462 | /* add playback controls for speaker and HP outputs */ | ||
5463 | static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, | ||
5464 | const char *pfx) | ||
5465 | { | ||
5466 | hda_nid_t nid; | ||
5467 | int err; | ||
5468 | |||
5469 | if (!pin) | ||
5470 | return 0; | ||
5471 | |||
5472 | if (alc880_is_fixed_pin(pin)) { | ||
5473 | nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); | ||
5474 | /* specify the DAC as the extra output */ | ||
5475 | if (!spec->multiout.hp_nid) | ||
5476 | spec->multiout.hp_nid = nid; | ||
5477 | else | ||
5478 | spec->multiout.extra_out_nid[0] = nid; | ||
5479 | /* control HP volume/switch on the output mixer amp */ | ||
5480 | nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); | ||
5481 | err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, | ||
5482 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); | ||
5483 | if (err < 0) | ||
5484 | return err; | ||
5485 | err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx, | ||
5486 | HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); | ||
5487 | if (err < 0) | ||
5488 | return err; | ||
5489 | } else if (alc880_is_multi_pin(pin)) { | ||
5490 | /* set manual connection */ | ||
5491 | /* we have only a switch on HP-out PIN */ | ||
5492 | err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, | ||
5493 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); | ||
5494 | if (err < 0) | ||
5495 | return err; | ||
5496 | } | ||
5497 | return 0; | ||
5498 | } | ||
5499 | |||
5500 | /* create input playback/capture controls for the given pin */ | 5360 | /* create input playback/capture controls for the given pin */ |
5501 | static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, | 5361 | static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, |
5502 | const char *ctlname, int ctlidx, | 5362 | const char *ctlname, int ctlidx, |
@@ -5569,6 +5429,14 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec, | |||
5569 | return 0; | 5429 | return 0; |
5570 | } | 5430 | } |
5571 | 5431 | ||
5432 | static int alc_auto_fill_dac_nids(struct hda_codec *codec); | ||
5433 | static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, | ||
5434 | const struct auto_pin_cfg *cfg); | ||
5435 | static int alc_auto_create_hp_out(struct hda_codec *codec); | ||
5436 | static int alc_auto_create_speaker_out(struct hda_codec *codec); | ||
5437 | static void alc_auto_init_multi_out(struct hda_codec *codec); | ||
5438 | static void alc_auto_init_extra_out(struct hda_codec *codec); | ||
5439 | |||
5572 | static int alc880_auto_create_input_ctls(struct hda_codec *codec, | 5440 | static int alc880_auto_create_input_ctls(struct hda_codec *codec, |
5573 | const struct auto_pin_cfg *cfg) | 5441 | const struct auto_pin_cfg *cfg) |
5574 | { | 5442 | { |
@@ -5585,21 +5453,6 @@ static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, | |||
5585 | AMP_OUT_UNMUTE); | 5453 | AMP_OUT_UNMUTE); |
5586 | } | 5454 | } |
5587 | 5455 | ||
5588 | static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, | ||
5589 | hda_nid_t nid, int pin_type, | ||
5590 | int dac_idx) | ||
5591 | { | ||
5592 | alc_set_pin_output(codec, nid, pin_type); | ||
5593 | /* need the manual connection? */ | ||
5594 | if (alc880_is_multi_pin(nid)) { | ||
5595 | struct alc_spec *spec = codec->spec; | ||
5596 | int idx = alc880_multi_pin_idx(nid); | ||
5597 | snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, | ||
5598 | AC_VERB_SET_CONNECT_SEL, | ||
5599 | alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); | ||
5600 | } | ||
5601 | } | ||
5602 | |||
5603 | static int get_pin_type(int line_out_type) | 5456 | static int get_pin_type(int line_out_type) |
5604 | { | 5457 | { |
5605 | if (line_out_type == AUTO_PIN_HP_OUT) | 5458 | if (line_out_type == AUTO_PIN_HP_OUT) |
@@ -5608,63 +5461,6 @@ static int get_pin_type(int line_out_type) | |||
5608 | return PIN_OUT; | 5461 | return PIN_OUT; |
5609 | } | 5462 | } |
5610 | 5463 | ||
5611 | static void alc880_auto_init_dac(struct hda_codec *codec, hda_nid_t dac) | ||
5612 | { | ||
5613 | hda_nid_t nid, mix; | ||
5614 | |||
5615 | if (!dac) | ||
5616 | return; | ||
5617 | mix = alc880_idx_to_mixer(alc880_dac_to_idx(dac)); | ||
5618 | if (query_amp_caps(codec, dac, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS) | ||
5619 | nid = dac; | ||
5620 | else if (query_amp_caps(codec, mix, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS) | ||
5621 | nid = mix; | ||
5622 | else | ||
5623 | nid = 0; | ||
5624 | if (nid) | ||
5625 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
5626 | AMP_OUT_ZERO); | ||
5627 | if (query_amp_caps(codec, mix, HDA_INPUT) & AC_AMPCAP_MUTE) { | ||
5628 | snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
5629 | AMP_IN_UNMUTE(0)); | ||
5630 | snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
5631 | AMP_IN_UNMUTE(1)); | ||
5632 | } | ||
5633 | } | ||
5634 | |||
5635 | static void alc880_auto_init_multi_out(struct hda_codec *codec) | ||
5636 | { | ||
5637 | struct alc_spec *spec = codec->spec; | ||
5638 | int i; | ||
5639 | |||
5640 | for (i = 0; i < spec->autocfg.line_outs; i++) { | ||
5641 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | ||
5642 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | ||
5643 | alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); | ||
5644 | } | ||
5645 | /* mute DACs */ | ||
5646 | for (i = 0; i < spec->multiout.num_dacs; i++) | ||
5647 | alc880_auto_init_dac(codec, spec->multiout.dac_nids[i]); | ||
5648 | } | ||
5649 | |||
5650 | static void alc880_auto_init_extra_out(struct hda_codec *codec) | ||
5651 | { | ||
5652 | struct alc_spec *spec = codec->spec; | ||
5653 | hda_nid_t pin; | ||
5654 | int i; | ||
5655 | |||
5656 | pin = spec->autocfg.speaker_pins[0]; | ||
5657 | if (pin) /* connect to front */ | ||
5658 | alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); | ||
5659 | pin = spec->autocfg.hp_pins[0]; | ||
5660 | if (pin) /* connect to front */ | ||
5661 | alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); | ||
5662 | /* mute DACs */ | ||
5663 | alc880_auto_init_dac(codec, spec->multiout.hp_nid); | ||
5664 | for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) | ||
5665 | alc880_auto_init_dac(codec, spec->multiout.extra_out_nid[i]); | ||
5666 | } | ||
5667 | |||
5668 | static void alc880_auto_init_analog_input(struct hda_codec *codec) | 5464 | static void alc880_auto_init_analog_input(struct hda_codec *codec) |
5669 | { | 5465 | { |
5670 | struct alc_spec *spec = codec->spec; | 5466 | struct alc_spec *spec = codec->spec; |
@@ -5734,22 +5530,19 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
5734 | if (!spec->autocfg.line_outs) | 5530 | if (!spec->autocfg.line_outs) |
5735 | return 0; /* can't find valid BIOS pin config */ | 5531 | return 0; /* can't find valid BIOS pin config */ |
5736 | 5532 | ||
5737 | err = alc880_auto_fill_dac_nids(codec); | 5533 | err = alc_auto_fill_dac_nids(codec); |
5738 | if (err < 0) | 5534 | if (err < 0) |
5739 | return err; | 5535 | return err; |
5740 | err = alc_auto_add_multi_channel_mode(codec, alc880_auto_fill_dac_nids); | 5536 | err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids); |
5741 | if (err < 0) | 5537 | if (err < 0) |
5742 | return err; | 5538 | return err; |
5743 | err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); | 5539 | err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg); |
5744 | if (err < 0) | 5540 | if (err < 0) |
5745 | return err; | 5541 | return err; |
5746 | err = alc880_auto_create_extra_out(spec, | 5542 | err = alc_auto_create_hp_out(codec); |
5747 | spec->autocfg.speaker_pins[0], | ||
5748 | "Speaker"); | ||
5749 | if (err < 0) | 5543 | if (err < 0) |
5750 | return err; | 5544 | return err; |
5751 | err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], | 5545 | err = alc_auto_create_speaker_out(codec); |
5752 | "Headphone"); | ||
5753 | if (err < 0) | 5546 | if (err < 0) |
5754 | return err; | 5547 | return err; |
5755 | err = alc880_auto_create_input_ctls(codec, &spec->autocfg); | 5548 | err = alc880_auto_create_input_ctls(codec, &spec->autocfg); |
@@ -5775,8 +5568,8 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
5775 | static void alc880_auto_init(struct hda_codec *codec) | 5568 | static void alc880_auto_init(struct hda_codec *codec) |
5776 | { | 5569 | { |
5777 | struct alc_spec *spec = codec->spec; | 5570 | struct alc_spec *spec = codec->spec; |
5778 | alc880_auto_init_multi_out(codec); | 5571 | alc_auto_init_multi_out(codec); |
5779 | alc880_auto_init_extra_out(codec); | 5572 | alc_auto_init_extra_out(codec); |
5780 | alc880_auto_init_analog_input(codec); | 5573 | alc880_auto_init_analog_input(codec); |
5781 | alc880_auto_init_input_src(codec); | 5574 | alc880_auto_init_input_src(codec); |
5782 | alc_auto_init_digital(codec); | 5575 | alc_auto_init_digital(codec); |
@@ -10990,82 +10783,6 @@ static int alc882_auto_create_input_ctls(struct hda_codec *codec, | |||
10990 | return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22); | 10783 | return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22); |
10991 | } | 10784 | } |
10992 | 10785 | ||
10993 | static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, | ||
10994 | hda_nid_t nid, int pin_type, | ||
10995 | hda_nid_t dac) | ||
10996 | { | ||
10997 | int idx; | ||
10998 | |||
10999 | /* set as output */ | ||
11000 | alc_set_pin_output(codec, nid, pin_type); | ||
11001 | |||
11002 | if (snd_hda_get_conn_list(codec, nid, NULL) < 2) | ||
11003 | return; | ||
11004 | |||
11005 | if (dac == 0x25) | ||
11006 | idx = 4; | ||
11007 | else if (dac >= 0x02 && dac <= 0x05) | ||
11008 | idx = dac - 2; | ||
11009 | else | ||
11010 | return; | ||
11011 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); | ||
11012 | } | ||
11013 | |||
11014 | #define alc882_auto_init_dac alc880_auto_init_dac | ||
11015 | |||
11016 | static void alc882_auto_init_multi_out(struct hda_codec *codec) | ||
11017 | { | ||
11018 | struct alc_spec *spec = codec->spec; | ||
11019 | int i; | ||
11020 | |||
11021 | for (i = 0; i <= HDA_SIDE; i++) { | ||
11022 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | ||
11023 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | ||
11024 | if (nid) | ||
11025 | alc882_auto_set_output_and_unmute(codec, nid, pin_type, | ||
11026 | spec->multiout.dac_nids[i]); | ||
11027 | } | ||
11028 | /* mute DACs */ | ||
11029 | for (i = 0; i < spec->multiout.num_dacs; i++) | ||
11030 | alc882_auto_init_dac(codec, spec->multiout.dac_nids[i]); | ||
11031 | } | ||
11032 | |||
11033 | static void alc882_auto_init_hp_out(struct hda_codec *codec) | ||
11034 | { | ||
11035 | struct alc_spec *spec = codec->spec; | ||
11036 | hda_nid_t pin, dac; | ||
11037 | int i; | ||
11038 | |||
11039 | if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) { | ||
11040 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { | ||
11041 | pin = spec->autocfg.hp_pins[i]; | ||
11042 | if (!pin) | ||
11043 | break; | ||
11044 | dac = spec->multiout.hp_nid; | ||
11045 | if (!dac) | ||
11046 | dac = spec->multiout.dac_nids[0]; /* to front */ | ||
11047 | alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac); | ||
11048 | } | ||
11049 | } | ||
11050 | |||
11051 | if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) { | ||
11052 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { | ||
11053 | pin = spec->autocfg.speaker_pins[i]; | ||
11054 | if (!pin) | ||
11055 | break; | ||
11056 | dac = spec->multiout.extra_out_nid[0]; | ||
11057 | if (!dac) | ||
11058 | dac = spec->multiout.dac_nids[0]; /* to front */ | ||
11059 | alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac); | ||
11060 | } | ||
11061 | } | ||
11062 | |||
11063 | /* mute DACs */ | ||
11064 | alc882_auto_init_dac(codec, spec->multiout.hp_nid); | ||
11065 | for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) | ||
11066 | alc882_auto_init_dac(codec, spec->multiout.extra_out_nid[i]); | ||
11067 | } | ||
11068 | |||
11069 | #define alc882_auto_init_analog_input alc880_auto_init_analog_input | 10786 | #define alc882_auto_init_analog_input alc880_auto_init_analog_input |
11070 | 10787 | ||
11071 | static void alc882_auto_init_input_src(struct hda_codec *codec) | 10788 | static void alc882_auto_init_input_src(struct hda_codec *codec) |
@@ -11177,22 +10894,19 @@ static int alc882_parse_auto_config(struct hda_codec *codec) | |||
11177 | if (!spec->autocfg.line_outs) | 10894 | if (!spec->autocfg.line_outs) |
11178 | return 0; /* can't find valid BIOS pin config */ | 10895 | return 0; /* can't find valid BIOS pin config */ |
11179 | 10896 | ||
11180 | err = alc880_auto_fill_dac_nids(codec); | 10897 | err = alc_auto_fill_dac_nids(codec); |
11181 | if (err < 0) | 10898 | if (err < 0) |
11182 | return err; | 10899 | return err; |
11183 | err = alc_auto_add_multi_channel_mode(codec, alc880_auto_fill_dac_nids); | 10900 | err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids); |
11184 | if (err < 0) | 10901 | if (err < 0) |
11185 | return err; | 10902 | return err; |
11186 | err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); | 10903 | err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg); |
11187 | if (err < 0) | 10904 | if (err < 0) |
11188 | return err; | 10905 | return err; |
11189 | err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], | 10906 | err = alc_auto_create_hp_out(codec); |
11190 | "Headphone"); | ||
11191 | if (err < 0) | 10907 | if (err < 0) |
11192 | return err; | 10908 | return err; |
11193 | err = alc880_auto_create_extra_out(spec, | 10909 | err = alc_auto_create_speaker_out(codec); |
11194 | spec->autocfg.speaker_pins[0], | ||
11195 | "Speaker"); | ||
11196 | if (err < 0) | 10910 | if (err < 0) |
11197 | return err; | 10911 | return err; |
11198 | err = alc882_auto_create_input_ctls(codec, &spec->autocfg); | 10912 | err = alc882_auto_create_input_ctls(codec, &spec->autocfg); |
@@ -11206,10 +10920,6 @@ static int alc882_parse_auto_config(struct hda_codec *codec) | |||
11206 | if (spec->kctls.list) | 10920 | if (spec->kctls.list) |
11207 | add_mixer(spec, spec->kctls.list); | 10921 | add_mixer(spec, spec->kctls.list); |
11208 | 10922 | ||
11209 | /* if ADC 0x07 is available, initialize it, too */ | ||
11210 | if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN) | ||
11211 | add_verb(spec, alc882_adc1_init_verbs); | ||
11212 | |||
11213 | spec->num_mux_defs = 1; | 10923 | spec->num_mux_defs = 1; |
11214 | spec->input_mux = &spec->private_imux[0]; | 10924 | spec->input_mux = &spec->private_imux[0]; |
11215 | 10925 | ||
@@ -11226,8 +10936,8 @@ static int alc882_parse_auto_config(struct hda_codec *codec) | |||
11226 | static void alc882_auto_init(struct hda_codec *codec) | 10936 | static void alc882_auto_init(struct hda_codec *codec) |
11227 | { | 10937 | { |
11228 | struct alc_spec *spec = codec->spec; | 10938 | struct alc_spec *spec = codec->spec; |
11229 | alc882_auto_init_multi_out(codec); | 10939 | alc_auto_init_multi_out(codec); |
11230 | alc882_auto_init_hp_out(codec); | 10940 | alc_auto_init_extra_out(codec); |
11231 | alc882_auto_init_analog_input(codec); | 10941 | alc882_auto_init_analog_input(codec); |
11232 | alc882_auto_init_input_src(codec); | 10942 | alc882_auto_init_input_src(codec); |
11233 | alc_auto_init_digital(codec); | 10943 | alc_auto_init_digital(codec); |
@@ -12586,8 +12296,6 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
12586 | return 1; | 12296 | return 1; |
12587 | } | 12297 | } |
12588 | 12298 | ||
12589 | #define alc262_auto_init_multi_out alc882_auto_init_multi_out | ||
12590 | #define alc262_auto_init_hp_out alc882_auto_init_hp_out | ||
12591 | #define alc262_auto_init_analog_input alc882_auto_init_analog_input | 12299 | #define alc262_auto_init_analog_input alc882_auto_init_analog_input |
12592 | #define alc262_auto_init_input_src alc882_auto_init_input_src | 12300 | #define alc262_auto_init_input_src alc882_auto_init_input_src |
12593 | 12301 | ||
@@ -12596,8 +12304,8 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
12596 | static void alc262_auto_init(struct hda_codec *codec) | 12304 | static void alc262_auto_init(struct hda_codec *codec) |
12597 | { | 12305 | { |
12598 | struct alc_spec *spec = codec->spec; | 12306 | struct alc_spec *spec = codec->spec; |
12599 | alc262_auto_init_multi_out(codec); | 12307 | alc_auto_init_multi_out(codec); |
12600 | alc262_auto_init_hp_out(codec); | 12308 | alc_auto_init_extra_out(codec); |
12601 | alc262_auto_init_analog_input(codec); | 12309 | alc262_auto_init_analog_input(codec); |
12602 | alc262_auto_init_input_src(codec); | 12310 | alc262_auto_init_input_src(codec); |
12603 | alc_auto_init_digital(codec); | 12311 | alc_auto_init_digital(codec); |
@@ -16970,8 +16678,6 @@ static int alc861vd_auto_create_input_ctls(struct hda_codec *codec, | |||
16970 | } | 16678 | } |
16971 | 16679 | ||
16972 | 16680 | ||
16973 | #define alc861vd_auto_init_multi_out alc882_auto_init_multi_out | ||
16974 | #define alc861vd_auto_init_hp_out alc882_auto_init_hp_out | ||
16975 | #define alc861vd_auto_init_analog_input alc882_auto_init_analog_input | 16681 | #define alc861vd_auto_init_analog_input alc882_auto_init_analog_input |
16976 | #define alc861vd_auto_init_input_src alc882_auto_init_input_src | 16682 | #define alc861vd_auto_init_input_src alc882_auto_init_input_src |
16977 | 16683 | ||
@@ -17110,10 +16816,10 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) | |||
17110 | if (!spec->autocfg.line_outs) | 16816 | if (!spec->autocfg.line_outs) |
17111 | return 0; /* can't find valid BIOS pin config */ | 16817 | return 0; /* can't find valid BIOS pin config */ |
17112 | 16818 | ||
17113 | err = alc880_auto_fill_dac_nids(codec); | 16819 | err = alc_auto_fill_dac_nids(codec); |
17114 | if (err < 0) | 16820 | if (err < 0) |
17115 | return err; | 16821 | return err; |
17116 | err = alc_auto_add_multi_channel_mode(codec, alc880_auto_fill_dac_nids); | 16822 | err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids); |
17117 | if (err < 0) | 16823 | if (err < 0) |
17118 | return err; | 16824 | return err; |
17119 | err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); | 16825 | err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); |
@@ -17156,8 +16862,8 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) | |||
17156 | static void alc861vd_auto_init(struct hda_codec *codec) | 16862 | static void alc861vd_auto_init(struct hda_codec *codec) |
17157 | { | 16863 | { |
17158 | struct alc_spec *spec = codec->spec; | 16864 | struct alc_spec *spec = codec->spec; |
17159 | alc861vd_auto_init_multi_out(codec); | 16865 | alc_auto_init_multi_out(codec); |
17160 | alc861vd_auto_init_hp_out(codec); | 16866 | alc_auto_init_extra_out(codec); |
17161 | alc861vd_auto_init_analog_input(codec); | 16867 | alc861vd_auto_init_analog_input(codec); |
17162 | alc861vd_auto_init_input_src(codec); | 16868 | alc861vd_auto_init_input_src(codec); |
17163 | alc_auto_init_digital(codec); | 16869 | alc_auto_init_digital(codec); |
@@ -18795,7 +18501,7 @@ static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) | |||
18795 | } | 18501 | } |
18796 | 18502 | ||
18797 | /* fill in the dac_nids table from the parsed pin configuration */ | 18503 | /* fill in the dac_nids table from the parsed pin configuration */ |
18798 | static int alc662_auto_fill_dac_nids(struct hda_codec *codec) | 18504 | static int alc_auto_fill_dac_nids(struct hda_codec *codec) |
18799 | { | 18505 | { |
18800 | struct alc_spec *spec = codec->spec; | 18506 | struct alc_spec *spec = codec->spec; |
18801 | const struct auto_pin_cfg *cfg = &spec->autocfg; | 18507 | const struct auto_pin_cfg *cfg = &spec->autocfg; |
@@ -18855,7 +18561,7 @@ static int alc662_auto_fill_dac_nids(struct hda_codec *codec) | |||
18855 | return 0; | 18561 | return 0; |
18856 | } | 18562 | } |
18857 | 18563 | ||
18858 | static int alc662_add_vol_ctl(struct hda_codec *codec, | 18564 | static int alc_auto_add_vol_ctl(struct hda_codec *codec, |
18859 | const char *pfx, int cidx, | 18565 | const char *pfx, int cidx, |
18860 | hda_nid_t nid, unsigned int chs) | 18566 | hda_nid_t nid, unsigned int chs) |
18861 | { | 18567 | { |
@@ -18863,13 +18569,13 @@ static int alc662_add_vol_ctl(struct hda_codec *codec, | |||
18863 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | 18569 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); |
18864 | } | 18570 | } |
18865 | 18571 | ||
18866 | #define alc662_add_stereo_vol(codec, pfx, cidx, nid) \ | 18572 | #define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \ |
18867 | alc662_add_vol_ctl(codec, pfx, cidx, nid, 3) | 18573 | alc_auto_add_vol_ctl(codec, pfx, cidx, nid, 3) |
18868 | 18574 | ||
18869 | /* create a mute-switch for the given mixer widget; | 18575 | /* create a mute-switch for the given mixer widget; |
18870 | * if it has multiple sources (e.g. DAC and loopback), create a bind-mute | 18576 | * if it has multiple sources (e.g. DAC and loopback), create a bind-mute |
18871 | */ | 18577 | */ |
18872 | static int alc662_add_sw_ctl(struct hda_codec *codec, | 18578 | static int alc_auto_add_sw_ctl(struct hda_codec *codec, |
18873 | const char *pfx, int cidx, | 18579 | const char *pfx, int cidx, |
18874 | hda_nid_t nid, unsigned int chs) | 18580 | hda_nid_t nid, unsigned int chs) |
18875 | { | 18581 | { |
@@ -18885,11 +18591,11 @@ static int alc662_add_sw_ctl(struct hda_codec *codec, | |||
18885 | return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val); | 18591 | return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val); |
18886 | } | 18592 | } |
18887 | 18593 | ||
18888 | #define alc662_add_stereo_sw(codec, pfx, cidx, nid) \ | 18594 | #define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \ |
18889 | alc662_add_sw_ctl(codec, pfx, cidx, nid, 3) | 18595 | alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3) |
18890 | 18596 | ||
18891 | /* add playback controls from the parsed DAC table */ | 18597 | /* add playback controls from the parsed DAC table */ |
18892 | static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, | 18598 | static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, |
18893 | const struct auto_pin_cfg *cfg) | 18599 | const struct auto_pin_cfg *cfg) |
18894 | { | 18600 | { |
18895 | struct alc_spec *spec = codec->spec; | 18601 | struct alc_spec *spec = codec->spec; |
@@ -18916,23 +18622,23 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
18916 | name = alc_get_line_out_pfx(spec, i, true, &index); | 18622 | name = alc_get_line_out_pfx(spec, i, true, &index); |
18917 | if (!name) { | 18623 | if (!name) { |
18918 | /* Center/LFE */ | 18624 | /* Center/LFE */ |
18919 | err = alc662_add_vol_ctl(codec, "Center", 0, nid, 1); | 18625 | err = alc_auto_add_vol_ctl(codec, "Center", 0, nid, 1); |
18920 | if (err < 0) | 18626 | if (err < 0) |
18921 | return err; | 18627 | return err; |
18922 | err = alc662_add_vol_ctl(codec, "LFE", 0, nid, 2); | 18628 | err = alc_auto_add_vol_ctl(codec, "LFE", 0, nid, 2); |
18923 | if (err < 0) | 18629 | if (err < 0) |
18924 | return err; | 18630 | return err; |
18925 | err = alc662_add_sw_ctl(codec, "Center", 0, mix, 1); | 18631 | err = alc_auto_add_sw_ctl(codec, "Center", 0, mix, 1); |
18926 | if (err < 0) | 18632 | if (err < 0) |
18927 | return err; | 18633 | return err; |
18928 | err = alc662_add_sw_ctl(codec, "LFE", 0, mix, 2); | 18634 | err = alc_auto_add_sw_ctl(codec, "LFE", 0, mix, 2); |
18929 | if (err < 0) | 18635 | if (err < 0) |
18930 | return err; | 18636 | return err; |
18931 | } else { | 18637 | } else { |
18932 | err = alc662_add_stereo_vol(codec, name, index, nid); | 18638 | err = alc_auto_add_stereo_vol(codec, name, index, nid); |
18933 | if (err < 0) | 18639 | if (err < 0) |
18934 | return err; | 18640 | return err; |
18935 | err = alc662_add_stereo_sw(codec, name, index, mix); | 18641 | err = alc_auto_add_stereo_sw(codec, name, index, mix); |
18936 | if (err < 0) | 18642 | if (err < 0) |
18937 | return err; | 18643 | return err; |
18938 | } | 18644 | } |
@@ -18941,7 +18647,7 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
18941 | } | 18647 | } |
18942 | 18648 | ||
18943 | /* add playback controls for speaker and HP outputs */ | 18649 | /* add playback controls for speaker and HP outputs */ |
18944 | static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | 18650 | static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, |
18945 | hda_nid_t dac, const char *pfx) | 18651 | hda_nid_t dac, const char *pfx) |
18946 | { | 18652 | { |
18947 | struct alc_spec *spec = codec->spec; | 18653 | struct alc_spec *spec = codec->spec; |
@@ -18962,25 +18668,41 @@ static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | |||
18962 | mix = alc_auto_dac_to_mix(codec, pin, dac); | 18668 | mix = alc_auto_dac_to_mix(codec, pin, dac); |
18963 | if (!mix) | 18669 | if (!mix) |
18964 | return 0; | 18670 | return 0; |
18965 | err = alc662_add_stereo_vol(codec, pfx, 0, dac); | 18671 | err = alc_auto_add_stereo_vol(codec, pfx, 0, dac); |
18966 | if (err < 0) | 18672 | if (err < 0) |
18967 | return err; | 18673 | return err; |
18968 | err = alc662_add_stereo_sw(codec, pfx, 0, mix); | 18674 | err = alc_auto_add_stereo_sw(codec, pfx, 0, mix); |
18969 | if (err < 0) | 18675 | if (err < 0) |
18970 | return err; | 18676 | return err; |
18971 | return 0; | 18677 | return 0; |
18972 | } | 18678 | } |
18973 | 18679 | ||
18680 | static int alc_auto_create_hp_out(struct hda_codec *codec) | ||
18681 | { | ||
18682 | struct alc_spec *spec = codec->spec; | ||
18683 | return alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0], | ||
18684 | spec->multiout.hp_nid, | ||
18685 | "Headphone"); | ||
18686 | } | ||
18687 | |||
18688 | static int alc_auto_create_speaker_out(struct hda_codec *codec) | ||
18689 | { | ||
18690 | struct alc_spec *spec = codec->spec; | ||
18691 | return alc_auto_create_extra_out(codec, spec->autocfg.speaker_pins[0], | ||
18692 | spec->multiout.extra_out_nid[0], | ||
18693 | "Speaker"); | ||
18694 | } | ||
18695 | |||
18974 | /* create playback/capture controls for input pins */ | 18696 | /* create playback/capture controls for input pins */ |
18975 | #define alc662_auto_create_input_ctls \ | 18697 | #define alc662_auto_create_input_ctls \ |
18976 | alc882_auto_create_input_ctls | 18698 | alc882_auto_create_input_ctls |
18977 | 18699 | ||
18978 | static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, | 18700 | static void alc_auto_set_output_and_unmute(struct hda_codec *codec, |
18979 | hda_nid_t nid, int pin_type, | 18701 | hda_nid_t nid, int pin_type, |
18980 | hda_nid_t dac) | 18702 | hda_nid_t dac) |
18981 | { | 18703 | { |
18982 | int i, num; | 18704 | int i, num; |
18983 | hda_nid_t mix; | 18705 | hda_nid_t mix = 0; |
18984 | hda_nid_t srcs[HDA_MAX_CONNECTIONS]; | 18706 | hda_nid_t srcs[HDA_MAX_CONNECTIONS]; |
18985 | 18707 | ||
18986 | alc_set_pin_output(codec, nid, pin_type); | 18708 | alc_set_pin_output(codec, nid, pin_type); |
@@ -19014,7 +18736,7 @@ static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, | |||
19014 | AMP_OUT_ZERO); | 18736 | AMP_OUT_ZERO); |
19015 | } | 18737 | } |
19016 | 18738 | ||
19017 | static void alc662_auto_init_multi_out(struct hda_codec *codec) | 18739 | static void alc_auto_init_multi_out(struct hda_codec *codec) |
19018 | { | 18740 | { |
19019 | struct alc_spec *spec = codec->spec; | 18741 | struct alc_spec *spec = codec->spec; |
19020 | int pin_type = get_pin_type(spec->autocfg.line_out_type); | 18742 | int pin_type = get_pin_type(spec->autocfg.line_out_type); |
@@ -19023,23 +18745,23 @@ static void alc662_auto_init_multi_out(struct hda_codec *codec) | |||
19023 | for (i = 0; i <= HDA_SIDE; i++) { | 18745 | for (i = 0; i <= HDA_SIDE; i++) { |
19024 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; | 18746 | hda_nid_t nid = spec->autocfg.line_out_pins[i]; |
19025 | if (nid) | 18747 | if (nid) |
19026 | alc662_auto_set_output_and_unmute(codec, nid, pin_type, | 18748 | alc_auto_set_output_and_unmute(codec, nid, pin_type, |
19027 | spec->multiout.dac_nids[i]); | 18749 | spec->multiout.dac_nids[i]); |
19028 | } | 18750 | } |
19029 | } | 18751 | } |
19030 | 18752 | ||
19031 | static void alc662_auto_init_hp_out(struct hda_codec *codec) | 18753 | static void alc_auto_init_extra_out(struct hda_codec *codec) |
19032 | { | 18754 | { |
19033 | struct alc_spec *spec = codec->spec; | 18755 | struct alc_spec *spec = codec->spec; |
19034 | hda_nid_t pin; | 18756 | hda_nid_t pin; |
19035 | 18757 | ||
19036 | pin = spec->autocfg.hp_pins[0]; | 18758 | pin = spec->autocfg.hp_pins[0]; |
19037 | if (pin) | 18759 | if (pin) |
19038 | alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, | 18760 | alc_auto_set_output_and_unmute(codec, pin, PIN_HP, |
19039 | spec->multiout.hp_nid); | 18761 | spec->multiout.hp_nid); |
19040 | pin = spec->autocfg.speaker_pins[0]; | 18762 | pin = spec->autocfg.speaker_pins[0]; |
19041 | if (pin) | 18763 | if (pin) |
19042 | alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, | 18764 | alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, |
19043 | spec->multiout.extra_out_nid[0]); | 18765 | spec->multiout.extra_out_nid[0]); |
19044 | } | 18766 | } |
19045 | 18767 | ||
@@ -19226,22 +18948,22 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
19226 | if (!spec->autocfg.line_outs) | 18948 | if (!spec->autocfg.line_outs) |
19227 | return 0; /* can't find valid BIOS pin config */ | 18949 | return 0; /* can't find valid BIOS pin config */ |
19228 | 18950 | ||
19229 | err = alc662_auto_fill_dac_nids(codec); | 18951 | err = alc_auto_fill_dac_nids(codec); |
19230 | if (err < 0) | 18952 | if (err < 0) |
19231 | return err; | 18953 | return err; |
19232 | err = alc_auto_add_multi_channel_mode(codec, alc662_auto_fill_dac_nids); | 18954 | err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids); |
19233 | if (err < 0) | 18955 | if (err < 0) |
19234 | return err; | 18956 | return err; |
19235 | err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg); | 18957 | err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg); |
19236 | if (err < 0) | 18958 | if (err < 0) |
19237 | return err; | 18959 | return err; |
19238 | err = alc662_auto_create_extra_out(codec, | 18960 | err = alc_auto_create_extra_out(codec, |
19239 | spec->autocfg.speaker_pins[0], | 18961 | spec->autocfg.speaker_pins[0], |
19240 | spec->multiout.extra_out_nid[0], | 18962 | spec->multiout.extra_out_nid[0], |
19241 | "Speaker"); | 18963 | "Speaker"); |
19242 | if (err < 0) | 18964 | if (err < 0) |
19243 | return err; | 18965 | return err; |
19244 | err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0], | 18966 | err = alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0], |
19245 | spec->multiout.hp_nid, | 18967 | spec->multiout.hp_nid, |
19246 | "Headphone"); | 18968 | "Headphone"); |
19247 | if (err < 0) | 18969 | if (err < 0) |
@@ -19277,8 +18999,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
19277 | static void alc662_auto_init(struct hda_codec *codec) | 18999 | static void alc662_auto_init(struct hda_codec *codec) |
19278 | { | 19000 | { |
19279 | struct alc_spec *spec = codec->spec; | 19001 | struct alc_spec *spec = codec->spec; |
19280 | alc662_auto_init_multi_out(codec); | 19002 | alc_auto_init_multi_out(codec); |
19281 | alc662_auto_init_hp_out(codec); | 19003 | alc_auto_init_extra_out(codec); |
19282 | alc662_auto_init_analog_input(codec); | 19004 | alc662_auto_init_analog_input(codec); |
19283 | alc662_auto_init_input_src(codec); | 19005 | alc662_auto_init_input_src(codec); |
19284 | alc_auto_init_digital(codec); | 19006 | alc_auto_init_digital(codec); |