aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-07-08 09:16:55 -0400
committerTakashi Iwai <tiwai@suse.de>2011-07-08 09:16:55 -0400
commit72dcd8e76bd2b5d9846c3103ec020e1b550cdaac (patch)
treef376ace699ad0d90ec6d01f3a3b6c68fa1d02c82
parent44c0240052892911d9ebcb2bbc2a5cfc3176077c (diff)
ALSA: hda - Merge ALC861 auto-parser code
Merge more auto-parser code in patch_realtek.c, now for ALC861. The topology of this codec is pretty simple, and can be parsed well by the current starndard parser. Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/patch_realtek.c195
1 files changed, 8 insertions, 187 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index db9df5759103..b9e0c73cbd76 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -5364,176 +5364,6 @@ static int patch_alc269(struct hda_codec *codec)
5364 * ALC861 5364 * ALC861
5365 */ 5365 */
5366 5366
5367static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
5368{
5369 struct alc_spec *spec = codec->spec;
5370 hda_nid_t mix, srcs[5];
5371 int i, num;
5372
5373 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
5374 return 0;
5375 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
5376 if (num < 0)
5377 return 0;
5378 for (i = 0; i < num; i++) {
5379 unsigned int type;
5380 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
5381 if (type != AC_WID_AUD_OUT)
5382 continue;
5383 if (!found_in_nid_list(srcs[i], spec->multiout.dac_nids,
5384 spec->multiout.num_dacs))
5385 return srcs[i];
5386 }
5387 return 0;
5388}
5389
5390/* fill in the dac_nids table from the parsed pin configuration */
5391static int alc861_auto_fill_dac_nids(struct hda_codec *codec)
5392{
5393 struct alc_spec *spec = codec->spec;
5394 const struct auto_pin_cfg *cfg = &spec->autocfg;
5395 int i;
5396 hda_nid_t nid, dac;
5397
5398 spec->multiout.dac_nids = spec->private_dac_nids;
5399 for (i = 0; i < cfg->line_outs; i++) {
5400 nid = cfg->line_out_pins[i];
5401 dac = alc861_look_for_dac(codec, nid);
5402 if (!dac)
5403 continue;
5404 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
5405 }
5406 return 0;
5407}
5408
5409static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
5410 hda_nid_t nid, int idx, unsigned int chs)
5411{
5412 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
5413 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
5414}
5415
5416#define alc861_create_out_sw(codec, pfx, nid, chs) \
5417 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
5418
5419/* add playback controls from the parsed DAC table */
5420static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
5421 const struct auto_pin_cfg *cfg)
5422{
5423 struct alc_spec *spec = codec->spec;
5424 hda_nid_t nid;
5425 int i, err, noutputs;
5426
5427 noutputs = cfg->line_outs;
5428 if (spec->multi_ios > 0)
5429 noutputs += spec->multi_ios;
5430
5431 for (i = 0; i < noutputs; i++) {
5432 const char *name;
5433 int index;
5434 nid = spec->multiout.dac_nids[i];
5435 if (!nid)
5436 continue;
5437 name = alc_get_line_out_pfx(spec, i, true, &index);
5438 if (!name) {
5439 /* Center/LFE */
5440 err = alc861_create_out_sw(codec, "Center", nid, 1);
5441 if (err < 0)
5442 return err;
5443 err = alc861_create_out_sw(codec, "LFE", nid, 2);
5444 if (err < 0)
5445 return err;
5446 } else {
5447 err = __alc861_create_out_sw(codec, name, nid, index, 3);
5448 if (err < 0)
5449 return err;
5450 }
5451 }
5452 return 0;
5453}
5454
5455static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
5456{
5457 struct alc_spec *spec = codec->spec;
5458 int err;
5459 hda_nid_t nid;
5460
5461 if (!pin)
5462 return 0;
5463
5464 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
5465 nid = alc861_look_for_dac(codec, pin);
5466 if (nid) {
5467 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
5468 if (err < 0)
5469 return err;
5470 spec->multiout.hp_nid = nid;
5471 }
5472 }
5473 return 0;
5474}
5475
5476static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
5477 hda_nid_t nid,
5478 int pin_type, hda_nid_t dac)
5479{
5480 hda_nid_t mix, srcs[5];
5481 int i, num;
5482
5483 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5484 pin_type);
5485 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5486 AMP_OUT_UNMUTE);
5487 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
5488 return;
5489 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
5490 if (num < 0)
5491 return;
5492 for (i = 0; i < num; i++) {
5493 unsigned int mute;
5494 if (srcs[i] == dac || srcs[i] == 0x15)
5495 mute = AMP_IN_UNMUTE(i);
5496 else
5497 mute = AMP_IN_MUTE(i);
5498 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5499 mute);
5500 }
5501}
5502
5503static void alc861_auto_init_multi_out(struct hda_codec *codec)
5504{
5505 struct alc_spec *spec = codec->spec;
5506 int i;
5507
5508 for (i = 0; i < spec->autocfg.line_outs + spec->multi_ios; i++) {
5509 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5510 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5511 if (nid)
5512 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
5513 spec->multiout.dac_nids[i]);
5514 }
5515}
5516
5517static void alc861_auto_init_hp_out(struct hda_codec *codec)
5518{
5519 struct alc_spec *spec = codec->spec;
5520
5521 if (spec->autocfg.hp_outs)
5522 alc861_auto_set_output_and_unmute(codec,
5523 spec->autocfg.hp_pins[0],
5524 PIN_HP,
5525 spec->multiout.hp_nid);
5526 if (spec->autocfg.speaker_outs)
5527 alc861_auto_set_output_and_unmute(codec,
5528 spec->autocfg.speaker_pins[0],
5529 PIN_OUT,
5530 spec->multiout.dac_nids[0]);
5531}
5532
5533/* parse the BIOS configuration and set up the alc_spec */
5534/* return 1 if successful, 0 if the proper config is not found,
5535 * or a negative error code
5536 */
5537static int alc861_parse_auto_config(struct hda_codec *codec) 5367static int alc861_parse_auto_config(struct hda_codec *codec)
5538{ 5368{
5539 struct alc_spec *spec = codec->spec; 5369 struct alc_spec *spec = codec->spec;
@@ -5547,16 +5377,19 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
5547 if (!spec->autocfg.line_outs) 5377 if (!spec->autocfg.line_outs)
5548 return 0; /* can't find valid BIOS pin config */ 5378 return 0; /* can't find valid BIOS pin config */
5549 5379
5550 err = alc861_auto_fill_dac_nids(codec); 5380 err = alc_auto_fill_dac_nids(codec);
5551 if (err < 0) 5381 if (err < 0)
5552 return err; 5382 return err;
5553 err = alc_auto_add_multi_channel_mode(codec, alc861_auto_fill_dac_nids); 5383 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
5384 if (err < 0)
5385 return err;
5386 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
5554 if (err < 0) 5387 if (err < 0)
5555 return err; 5388 return err;
5556 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg); 5389 err = alc_auto_create_hp_out(codec);
5557 if (err < 0) 5390 if (err < 0)
5558 return err; 5391 return err;
5559 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]); 5392 err = alc_auto_create_speaker_out(codec);
5560 if (err < 0) 5393 if (err < 0)
5561 return err; 5394 return err;
5562 err = alc_auto_create_input_ctls(codec); 5395 err = alc_auto_create_input_ctls(codec);
@@ -5580,18 +5413,6 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
5580 return 1; 5413 return 1;
5581} 5414}
5582 5415
5583/* additional initialization for auto-configuration model */
5584static void alc861_auto_init(struct hda_codec *codec)
5585{
5586 struct alc_spec *spec = codec->spec;
5587 alc861_auto_init_multi_out(codec);
5588 alc861_auto_init_hp_out(codec);
5589 alc_auto_init_analog_input(codec);
5590 alc_auto_init_digital(codec);
5591 if (spec->unsol_event)
5592 alc_inithook(codec);
5593}
5594
5595#ifdef CONFIG_SND_HDA_POWER_SAVE 5416#ifdef CONFIG_SND_HDA_POWER_SAVE
5596static const struct hda_amp_list alc861_loopbacks[] = { 5417static const struct hda_amp_list alc861_loopbacks[] = {
5597 { 0x15, HDA_INPUT, 0 }, 5418 { 0x15, HDA_INPUT, 0 },
@@ -5700,7 +5521,7 @@ static int patch_alc861(struct hda_codec *codec)
5700 5521
5701 codec->patch_ops = alc_patch_ops; 5522 codec->patch_ops = alc_patch_ops;
5702 if (board_config == ALC_MODEL_AUTO) { 5523 if (board_config == ALC_MODEL_AUTO) {
5703 spec->init_hook = alc861_auto_init; 5524 spec->init_hook = alc_auto_init_std;
5704#ifdef CONFIG_SND_HDA_POWER_SAVE 5525#ifdef CONFIG_SND_HDA_POWER_SAVE
5705 spec->power_hook = alc_power_eapd; 5526 spec->power_hook = alc_power_eapd;
5706#endif 5527#endif