aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2010-07-30 04:48:14 -0400
committerTakashi Iwai <tiwai@suse.de>2010-07-30 04:48:14 -0400
commit757899aceebc33d9f86bbc481be7b7bf861e89ac (patch)
treeba07222b92186c8092a228fd0c2ce1630f917765 /sound/pci/hda/patch_realtek.c
parentce503f38bdb59c9175a9076215a3ba579fad4e64 (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.c140
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 */
1545static 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 */
1567static 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)
5013static int alc880_parse_auto_config(struct hda_codec *codec) 5070static 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}