diff options
author | Takashi Iwai <tiwai@suse.de> | 2010-07-30 04:48:14 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-07-30 04:48:14 -0400 |
commit | 757899aceebc33d9f86bbc481be7b7bf861e89ac (patch) | |
tree | ba07222b92186c8092a228fd0c2ce1630f917765 /sound/pci/hda/patch_realtek.c | |
parent | ce503f38bdb59c9175a9076215a3ba579fad4e64 (diff) |
ALSA: hda - Share digital I/O parser in patch_realtek.c
Make a helper function to parse the digital I/Os of all Realtek codecs
to simplify the code and to ensure the setups.
Also, initialize digital I/O pins properly in init callbacks. Some BIOS
seem to leave pins uninitialized.
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 | 140 |
1 files changed, 78 insertions, 62 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cf9f20805173..442adef38c5b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -1541,6 +1541,63 @@ static int alc_read_coef_idx(struct hda_codec *codec, | |||
1541 | return val; | 1541 | return val; |
1542 | } | 1542 | } |
1543 | 1543 | ||
1544 | /* set right pin controls for digital I/O */ | ||
1545 | static void alc_auto_init_digital(struct hda_codec *codec) | ||
1546 | { | ||
1547 | struct alc_spec *spec = codec->spec; | ||
1548 | int i; | ||
1549 | hda_nid_t pin; | ||
1550 | |||
1551 | for (i = 0; i < spec->autocfg.dig_outs; i++) { | ||
1552 | pin = spec->autocfg.dig_out_pins[i]; | ||
1553 | if (pin) { | ||
1554 | snd_hda_codec_write(codec, pin, 0, | ||
1555 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
1556 | PIN_OUT); | ||
1557 | } | ||
1558 | } | ||
1559 | pin = spec->autocfg.dig_in_pin; | ||
1560 | if (pin) | ||
1561 | snd_hda_codec_write(codec, pin, 0, | ||
1562 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
1563 | PIN_IN); | ||
1564 | } | ||
1565 | |||
1566 | /* parse digital I/Os and set up NIDs in BIOS auto-parse mode */ | ||
1567 | static void alc_auto_parse_digital(struct hda_codec *codec) | ||
1568 | { | ||
1569 | struct alc_spec *spec = codec->spec; | ||
1570 | int i, err; | ||
1571 | hda_nid_t dig_nid; | ||
1572 | |||
1573 | /* support multiple SPDIFs; the secondary is set up as a slave */ | ||
1574 | for (i = 0; i < spec->autocfg.dig_outs; i++) { | ||
1575 | err = snd_hda_get_connections(codec, | ||
1576 | spec->autocfg.dig_out_pins[i], | ||
1577 | &dig_nid, 1); | ||
1578 | if (err < 0) | ||
1579 | continue; | ||
1580 | if (!i) { | ||
1581 | spec->multiout.dig_out_nid = dig_nid; | ||
1582 | spec->dig_out_type = spec->autocfg.dig_out_type[0]; | ||
1583 | } else { | ||
1584 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; | ||
1585 | if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) | ||
1586 | break; | ||
1587 | spec->slave_dig_outs[i - 1] = dig_nid; | ||
1588 | } | ||
1589 | } | ||
1590 | |||
1591 | if (spec->autocfg.dig_in_pin) { | ||
1592 | hda_nid_t dig_nid; | ||
1593 | err = snd_hda_get_connections(codec, | ||
1594 | spec->autocfg.dig_in_pin, | ||
1595 | &dig_nid, 1); | ||
1596 | if (err > 0) | ||
1597 | spec->dig_in_nid = dig_nid; | ||
1598 | } | ||
1599 | } | ||
1600 | |||
1544 | /* | 1601 | /* |
1545 | * ALC888 | 1602 | * ALC888 |
1546 | */ | 1603 | */ |
@@ -5013,7 +5070,7 @@ static void alc880_auto_init_input_src(struct hda_codec *codec) | |||
5013 | static int alc880_parse_auto_config(struct hda_codec *codec) | 5070 | static int alc880_parse_auto_config(struct hda_codec *codec) |
5014 | { | 5071 | { |
5015 | struct alc_spec *spec = codec->spec; | 5072 | struct alc_spec *spec = codec->spec; |
5016 | int i, err; | 5073 | int err; |
5017 | static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; | 5074 | static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; |
5018 | 5075 | ||
5019 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 5076 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
@@ -5044,25 +5101,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
5044 | 5101 | ||
5045 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 5102 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
5046 | 5103 | ||
5047 | /* check multiple SPDIF-out (for recent codecs) */ | 5104 | alc_auto_parse_digital(codec); |
5048 | for (i = 0; i < spec->autocfg.dig_outs; i++) { | ||
5049 | hda_nid_t dig_nid; | ||
5050 | err = snd_hda_get_connections(codec, | ||
5051 | spec->autocfg.dig_out_pins[i], | ||
5052 | &dig_nid, 1); | ||
5053 | if (err < 0) | ||
5054 | continue; | ||
5055 | if (!i) | ||
5056 | spec->multiout.dig_out_nid = dig_nid; | ||
5057 | else { | ||
5058 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; | ||
5059 | if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) | ||
5060 | break; | ||
5061 | spec->slave_dig_outs[i - 1] = dig_nid; | ||
5062 | } | ||
5063 | } | ||
5064 | if (spec->autocfg.dig_in_pin) | ||
5065 | spec->dig_in_nid = ALC880_DIGIN_NID; | ||
5066 | 5105 | ||
5067 | if (spec->kctls.list) | 5106 | if (spec->kctls.list) |
5068 | add_mixer(spec, spec->kctls.list); | 5107 | add_mixer(spec, spec->kctls.list); |
@@ -5085,6 +5124,7 @@ static void alc880_auto_init(struct hda_codec *codec) | |||
5085 | alc880_auto_init_extra_out(codec); | 5124 | alc880_auto_init_extra_out(codec); |
5086 | alc880_auto_init_analog_input(codec); | 5125 | alc880_auto_init_analog_input(codec); |
5087 | alc880_auto_init_input_src(codec); | 5126 | alc880_auto_init_input_src(codec); |
5127 | alc_auto_init_digital(codec); | ||
5088 | if (spec->unsol_event) | 5128 | if (spec->unsol_event) |
5089 | alc_inithook(codec); | 5129 | alc_inithook(codec); |
5090 | } | 5130 | } |
@@ -6724,6 +6764,7 @@ static void alc260_auto_init(struct hda_codec *codec) | |||
6724 | alc260_auto_init_multi_out(codec); | 6764 | alc260_auto_init_multi_out(codec); |
6725 | alc260_auto_init_analog_input(codec); | 6765 | alc260_auto_init_analog_input(codec); |
6726 | alc260_auto_init_input_src(codec); | 6766 | alc260_auto_init_input_src(codec); |
6767 | alc_auto_init_digital(codec); | ||
6727 | if (spec->unsol_event) | 6768 | if (spec->unsol_event) |
6728 | alc_inithook(codec); | 6769 | alc_inithook(codec); |
6729 | } | 6770 | } |
@@ -10546,7 +10587,7 @@ static int alc882_parse_auto_config(struct hda_codec *codec) | |||
10546 | { | 10587 | { |
10547 | struct alc_spec *spec = codec->spec; | 10588 | struct alc_spec *spec = codec->spec; |
10548 | static hda_nid_t alc882_ignore[] = { 0x1d, 0 }; | 10589 | static hda_nid_t alc882_ignore[] = { 0x1d, 0 }; |
10549 | int i, err; | 10590 | int err; |
10550 | 10591 | ||
10551 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 10592 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
10552 | alc882_ignore); | 10593 | alc882_ignore); |
@@ -10576,25 +10617,7 @@ static int alc882_parse_auto_config(struct hda_codec *codec) | |||
10576 | 10617 | ||
10577 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 10618 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
10578 | 10619 | ||
10579 | /* check multiple SPDIF-out (for recent codecs) */ | 10620 | alc_auto_parse_digital(codec); |
10580 | for (i = 0; i < spec->autocfg.dig_outs; i++) { | ||
10581 | hda_nid_t dig_nid; | ||
10582 | err = snd_hda_get_connections(codec, | ||
10583 | spec->autocfg.dig_out_pins[i], | ||
10584 | &dig_nid, 1); | ||
10585 | if (err < 0) | ||
10586 | continue; | ||
10587 | if (!i) | ||
10588 | spec->multiout.dig_out_nid = dig_nid; | ||
10589 | else { | ||
10590 | spec->multiout.slave_dig_outs = spec->slave_dig_outs; | ||
10591 | if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1) | ||
10592 | break; | ||
10593 | spec->slave_dig_outs[i - 1] = dig_nid; | ||
10594 | } | ||
10595 | } | ||
10596 | if (spec->autocfg.dig_in_pin) | ||
10597 | spec->dig_in_nid = ALC880_DIGIN_NID; | ||
10598 | 10621 | ||
10599 | if (spec->kctls.list) | 10622 | if (spec->kctls.list) |
10600 | add_mixer(spec, spec->kctls.list); | 10623 | add_mixer(spec, spec->kctls.list); |
@@ -10624,6 +10647,7 @@ static void alc882_auto_init(struct hda_codec *codec) | |||
10624 | alc882_auto_init_hp_out(codec); | 10647 | alc882_auto_init_hp_out(codec); |
10625 | alc882_auto_init_analog_input(codec); | 10648 | alc882_auto_init_analog_input(codec); |
10626 | alc882_auto_init_input_src(codec); | 10649 | alc882_auto_init_input_src(codec); |
10650 | alc_auto_init_digital(codec); | ||
10627 | if (spec->unsol_event) | 10651 | if (spec->unsol_event) |
10628 | alc_inithook(codec); | 10652 | alc_inithook(codec); |
10629 | } | 10653 | } |
@@ -12154,12 +12178,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
12154 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 12178 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
12155 | 12179 | ||
12156 | dig_only: | 12180 | dig_only: |
12157 | if (spec->autocfg.dig_outs) { | 12181 | alc_auto_parse_digital(codec); |
12158 | spec->multiout.dig_out_nid = ALC262_DIGOUT_NID; | ||
12159 | spec->dig_out_type = spec->autocfg.dig_out_type[0]; | ||
12160 | } | ||
12161 | if (spec->autocfg.dig_in_pin) | ||
12162 | spec->dig_in_nid = ALC262_DIGIN_NID; | ||
12163 | 12182 | ||
12164 | if (spec->kctls.list) | 12183 | if (spec->kctls.list) |
12165 | add_mixer(spec, spec->kctls.list); | 12184 | add_mixer(spec, spec->kctls.list); |
@@ -12191,6 +12210,7 @@ static void alc262_auto_init(struct hda_codec *codec) | |||
12191 | alc262_auto_init_hp_out(codec); | 12210 | alc262_auto_init_hp_out(codec); |
12192 | alc262_auto_init_analog_input(codec); | 12211 | alc262_auto_init_analog_input(codec); |
12193 | alc262_auto_init_input_src(codec); | 12212 | alc262_auto_init_input_src(codec); |
12213 | alc_auto_init_digital(codec); | ||
12194 | if (spec->unsol_event) | 12214 | if (spec->unsol_event) |
12195 | alc_inithook(codec); | 12215 | alc_inithook(codec); |
12196 | } | 12216 | } |
@@ -13327,10 +13347,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec) | |||
13327 | 13347 | ||
13328 | dig_only: | 13348 | dig_only: |
13329 | /* digital only support output */ | 13349 | /* digital only support output */ |
13330 | if (spec->autocfg.dig_outs) { | 13350 | alc_auto_parse_digital(codec); |
13331 | spec->multiout.dig_out_nid = ALC268_DIGOUT_NID; | ||
13332 | spec->dig_out_type = spec->autocfg.dig_out_type[0]; | ||
13333 | } | ||
13334 | if (spec->kctls.list) | 13351 | if (spec->kctls.list) |
13335 | add_mixer(spec, spec->kctls.list); | 13352 | add_mixer(spec, spec->kctls.list); |
13336 | 13353 | ||
@@ -13360,6 +13377,7 @@ static void alc268_auto_init(struct hda_codec *codec) | |||
13360 | alc268_auto_init_hp_out(codec); | 13377 | alc268_auto_init_hp_out(codec); |
13361 | alc268_auto_init_mono_speaker_out(codec); | 13378 | alc268_auto_init_mono_speaker_out(codec); |
13362 | alc268_auto_init_analog_input(codec); | 13379 | alc268_auto_init_analog_input(codec); |
13380 | alc_auto_init_digital(codec); | ||
13363 | if (spec->unsol_event) | 13381 | if (spec->unsol_event) |
13364 | alc_inithook(codec); | 13382 | alc_inithook(codec); |
13365 | } | 13383 | } |
@@ -14305,8 +14323,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
14305 | 14323 | ||
14306 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 14324 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
14307 | 14325 | ||
14308 | if (spec->autocfg.dig_outs) | 14326 | alc_auto_parse_digital(codec); |
14309 | spec->multiout.dig_out_nid = ALC269_DIGOUT_NID; | ||
14310 | 14327 | ||
14311 | if (spec->kctls.list) | 14328 | if (spec->kctls.list) |
14312 | add_mixer(spec, spec->kctls.list); | 14329 | add_mixer(spec, spec->kctls.list); |
@@ -14354,6 +14371,7 @@ static void alc269_auto_init(struct hda_codec *codec) | |||
14354 | alc269_auto_init_multi_out(codec); | 14371 | alc269_auto_init_multi_out(codec); |
14355 | alc269_auto_init_hp_out(codec); | 14372 | alc269_auto_init_hp_out(codec); |
14356 | alc269_auto_init_analog_input(codec); | 14373 | alc269_auto_init_analog_input(codec); |
14374 | alc_auto_init_digital(codec); | ||
14357 | if (spec->unsol_event) | 14375 | if (spec->unsol_event) |
14358 | alc_inithook(codec); | 14376 | alc_inithook(codec); |
14359 | } | 14377 | } |
@@ -15515,8 +15533,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
15515 | 15533 | ||
15516 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 15534 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
15517 | 15535 | ||
15518 | if (spec->autocfg.dig_outs) | 15536 | alc_auto_parse_digital(codec); |
15519 | spec->multiout.dig_out_nid = ALC861_DIGOUT_NID; | ||
15520 | 15537 | ||
15521 | if (spec->kctls.list) | 15538 | if (spec->kctls.list) |
15522 | add_mixer(spec, spec->kctls.list); | 15539 | add_mixer(spec, spec->kctls.list); |
@@ -15542,6 +15559,7 @@ static void alc861_auto_init(struct hda_codec *codec) | |||
15542 | alc861_auto_init_multi_out(codec); | 15559 | alc861_auto_init_multi_out(codec); |
15543 | alc861_auto_init_hp_out(codec); | 15560 | alc861_auto_init_hp_out(codec); |
15544 | alc861_auto_init_analog_input(codec); | 15561 | alc861_auto_init_analog_input(codec); |
15562 | alc_auto_init_digital(codec); | ||
15545 | if (spec->unsol_event) | 15563 | if (spec->unsol_event) |
15546 | alc_inithook(codec); | 15564 | alc_inithook(codec); |
15547 | } | 15565 | } |
@@ -16646,8 +16664,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) | |||
16646 | 16664 | ||
16647 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 16665 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
16648 | 16666 | ||
16649 | if (spec->autocfg.dig_outs) | 16667 | alc_auto_parse_digital(codec); |
16650 | spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID; | ||
16651 | 16668 | ||
16652 | if (spec->kctls.list) | 16669 | if (spec->kctls.list) |
16653 | add_mixer(spec, spec->kctls.list); | 16670 | add_mixer(spec, spec->kctls.list); |
@@ -16674,6 +16691,7 @@ static void alc861vd_auto_init(struct hda_codec *codec) | |||
16674 | alc861vd_auto_init_hp_out(codec); | 16691 | alc861vd_auto_init_hp_out(codec); |
16675 | alc861vd_auto_init_analog_input(codec); | 16692 | alc861vd_auto_init_analog_input(codec); |
16676 | alc861vd_auto_init_input_src(codec); | 16693 | alc861vd_auto_init_input_src(codec); |
16694 | alc_auto_init_digital(codec); | ||
16677 | if (spec->unsol_event) | 16695 | if (spec->unsol_event) |
16678 | alc_inithook(codec); | 16696 | alc_inithook(codec); |
16679 | } | 16697 | } |
@@ -18761,8 +18779,7 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
18761 | 18779 | ||
18762 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 18780 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
18763 | 18781 | ||
18764 | if (spec->autocfg.dig_outs) | 18782 | alc_auto_parse_digital(codec); |
18765 | spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; | ||
18766 | 18783 | ||
18767 | if (spec->kctls.list) | 18784 | if (spec->kctls.list) |
18768 | add_mixer(spec, spec->kctls.list); | 18785 | add_mixer(spec, spec->kctls.list); |
@@ -18799,6 +18816,7 @@ static void alc662_auto_init(struct hda_codec *codec) | |||
18799 | alc662_auto_init_hp_out(codec); | 18816 | alc662_auto_init_hp_out(codec); |
18800 | alc662_auto_init_analog_input(codec); | 18817 | alc662_auto_init_analog_input(codec); |
18801 | alc662_auto_init_input_src(codec); | 18818 | alc662_auto_init_input_src(codec); |
18819 | alc_auto_init_digital(codec); | ||
18802 | if (spec->unsol_event) | 18820 | if (spec->unsol_event) |
18803 | alc_inithook(codec); | 18821 | alc_inithook(codec); |
18804 | } | 18822 | } |
@@ -19124,10 +19142,7 @@ static int alc680_parse_auto_config(struct hda_codec *codec) | |||
19124 | 19142 | ||
19125 | dig_only: | 19143 | dig_only: |
19126 | /* digital only support output */ | 19144 | /* digital only support output */ |
19127 | if (spec->autocfg.dig_outs) { | 19145 | alc_auto_parse_digital(codec); |
19128 | spec->multiout.dig_out_nid = ALC680_DIGOUT_NID; | ||
19129 | spec->dig_out_type = spec->autocfg.dig_out_type[0]; | ||
19130 | } | ||
19131 | if (spec->kctls.list) | 19146 | if (spec->kctls.list) |
19132 | add_mixer(spec, spec->kctls.list); | 19147 | add_mixer(spec, spec->kctls.list); |
19133 | 19148 | ||
@@ -19151,6 +19166,7 @@ static void alc680_auto_init(struct hda_codec *codec) | |||
19151 | alc680_auto_init_multi_out(codec); | 19166 | alc680_auto_init_multi_out(codec); |
19152 | alc680_auto_init_hp_out(codec); | 19167 | alc680_auto_init_hp_out(codec); |
19153 | alc680_auto_init_analog_input(codec); | 19168 | alc680_auto_init_analog_input(codec); |
19169 | alc_auto_init_digital(codec); | ||
19154 | if (spec->unsol_event) | 19170 | if (spec->unsol_event) |
19155 | alc_inithook(codec); | 19171 | alc_inithook(codec); |
19156 | } | 19172 | } |