aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_via.c
diff options
context:
space:
mode:
authorLydia Wang <lydiawang@viatech.com.cn>2011-03-23 05:56:05 -0400
committerTakashi Iwai <tiwai@suse.de>2011-03-23 06:49:33 -0400
commitbc92df7fe55e49c616a003b0b77e7badf2736429 (patch)
tree60b1a5c1d4af61f0a8319fc6cb07fcc35efe31f9 /sound/pci/hda/patch_via.c
parent3e95b9aba50deeee69afce87d2bcd94c4cd1d95e (diff)
ALSA: hda - VIA: Add support for VT1705
Add support for VT1705 codec, which is similiar with VT1708S except it has 6 channels output. Signed-off-by: Lydia Wang <lydiawang@viatech.com.cn> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_via.c')
-rw-r--r--sound/pci/hda/patch_via.c100
1 files changed, 87 insertions, 13 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 23cb44086b27..b7650a3dea03 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -3181,7 +3181,8 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
3181 int imux_is_smixer; 3181 int imux_is_smixer;
3182 unsigned int parm; 3182 unsigned int parm;
3183 int is_8ch = 0; 3183 int is_8ch = 0;
3184 if (spec->codec_type != VT1708B_4CH) 3184 if ((spec->codec_type != VT1708B_4CH) &&
3185 (codec->vendor_id != 0x11064397))
3185 is_8ch = 1; 3186 is_8ch = 1;
3186 3187
3187 /* SW0 (17h) = stereo mixer */ 3188 /* SW0 (17h) = stereo mixer */
@@ -3220,6 +3221,16 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
3220 AC_VERB_SET_POWER_STATE, parm); 3221 AC_VERB_SET_POWER_STATE, parm);
3221 snd_hda_codec_write(codec, 0x24, 0, 3222 snd_hda_codec_write(codec, 0x24, 0,
3222 AC_VERB_SET_POWER_STATE, parm); 3223 AC_VERB_SET_POWER_STATE, parm);
3224 } else if (codec->vendor_id == 0x11064397) {
3225 /* PW7(23h), SW2(27h), AOW2(25h) */
3226 parm = AC_PWRST_D3;
3227 set_pin_power_state(codec, 0x23, &parm);
3228 if (spec->smart51_enabled)
3229 set_pin_power_state(codec, 0x1a, &parm);
3230 snd_hda_codec_write(codec, 0x27, 0,
3231 AC_VERB_SET_POWER_STATE, parm);
3232 snd_hda_codec_write(codec, 0x25, 0,
3233 AC_VERB_SET_POWER_STATE, parm);
3223 } 3234 }
3224 3235
3225 /* PW 3/4/7 (1ch/1dh/23h) */ 3236 /* PW 3/4/7 (1ch/1dh/23h) */
@@ -3239,7 +3250,9 @@ static void set_widgets_power_state_vt1708B(struct hda_codec *codec)
3239 AC_VERB_SET_POWER_STATE, parm); 3250 AC_VERB_SET_POWER_STATE, parm);
3240 snd_hda_codec_write(codec, 0x27, 0, 3251 snd_hda_codec_write(codec, 0x27, 0,
3241 AC_VERB_SET_POWER_STATE, parm); 3252 AC_VERB_SET_POWER_STATE, parm);
3242 } 3253 } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode)
3254 snd_hda_codec_write(codec, 0x25, 0,
3255 AC_VERB_SET_POWER_STATE, parm);
3243} 3256}
3244 3257
3245static int patch_vt1708S(struct hda_codec *codec); 3258static int patch_vt1708S(struct hda_codec *codec);
@@ -3414,6 +3427,18 @@ static struct hda_verb vt1708S_uniwill_init_verbs[] = {
3414 { } 3427 { }
3415}; 3428};
3416 3429
3430static struct hda_verb vt1705_uniwill_init_verbs[] = {
3431 {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE,
3432 AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT},
3433 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3434 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3435 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3436 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3437 {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3438 {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT},
3439 { }
3440};
3441
3417static struct hda_pcm_stream vt1708S_pcm_analog_playback = { 3442static struct hda_pcm_stream vt1708S_pcm_analog_playback = {
3418 .substreams = 2, 3443 .substreams = 2,
3419 .channels_min = 2, 3444 .channels_min = 2,
@@ -3427,6 +3452,19 @@ static struct hda_pcm_stream vt1708S_pcm_analog_playback = {
3427 }, 3452 },
3428}; 3453};
3429 3454
3455static struct hda_pcm_stream vt1705_pcm_analog_playback = {
3456 .substreams = 2,
3457 .channels_min = 2,
3458 .channels_max = 6,
3459 .nid = 0x10, /* NID to query formats and rates */
3460 .ops = {
3461 .open = via_playback_pcm_open,
3462 .prepare = via_playback_multi_pcm_prepare,
3463 .cleanup = via_playback_multi_pcm_cleanup,
3464 .close = via_pcm_open_close
3465 },
3466};
3467
3430static struct hda_pcm_stream vt1708S_pcm_analog_capture = { 3468static struct hda_pcm_stream vt1708S_pcm_analog_capture = {
3431 .substreams = 2, 3469 .substreams = 2,
3432 .channels_min = 2, 3470 .channels_min = 2,
@@ -3473,7 +3511,10 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
3473 spec->multiout.dac_nids[i] = 0x10; 3511 spec->multiout.dac_nids[i] = 0x10;
3474 break; 3512 break;
3475 case AUTO_SEQ_CENLFE: 3513 case AUTO_SEQ_CENLFE:
3476 spec->multiout.dac_nids[i] = 0x24; 3514 if (spec->codec->vendor_id == 0x11064397)
3515 spec->multiout.dac_nids[i] = 0x25;
3516 else
3517 spec->multiout.dac_nids[i] = 0x24;
3477 break; 3518 break;
3478 case AUTO_SEQ_SURROUND: 3519 case AUTO_SEQ_SURROUND:
3479 spec->multiout.dac_nids[i] = 0x11; 3520 spec->multiout.dac_nids[i] = 0x11;
@@ -3489,22 +3530,28 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec,
3489 if (cfg->line_outs == 1) { 3530 if (cfg->line_outs == 1) {
3490 spec->multiout.num_dacs = 3; 3531 spec->multiout.num_dacs = 3;
3491 spec->multiout.dac_nids[AUTO_SEQ_SURROUND] = 0x11; 3532 spec->multiout.dac_nids[AUTO_SEQ_SURROUND] = 0x11;
3492 spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24; 3533 if (spec->codec->vendor_id == 0x11064397)
3534 spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x25;
3535 else
3536 spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24;
3493 } 3537 }
3494 3538
3495 return 0; 3539 return 0;
3496} 3540}
3497 3541
3498/* add playback controls from the parsed DAC table */ 3542/* add playback controls from the parsed DAC table */
3499static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec, 3543static int vt1708S_auto_create_multi_out_ctls(struct hda_codec *codec,
3500 const struct auto_pin_cfg *cfg) 3544 const struct auto_pin_cfg *cfg)
3501{ 3545{
3546 struct via_spec *spec = codec->spec;
3502 char name[32]; 3547 char name[32];
3503 static const char * const chname[4] = { 3548 static const char * const chname[4] = {
3504 "Front", "Surround", "C/LFE", "Side" 3549 "Front", "Surround", "C/LFE", "Side"
3505 }; 3550 };
3506 hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25}; 3551 hda_nid_t nid_vols[2][4] = { {0x10, 0x11, 0x24, 0x25},
3507 hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27}; 3552 {0x10, 0x11, 0x25, 0} };
3553 hda_nid_t nid_mutes[2][4] = { {0x1C, 0x18, 0x26, 0x27},
3554 {0x1C, 0x18, 0x27, 0} };
3508 hda_nid_t nid, nid_vol, nid_mute; 3555 hda_nid_t nid, nid_vol, nid_mute;
3509 int i, err; 3556 int i, err;
3510 3557
@@ -3515,8 +3562,15 @@ static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec,
3515 if (!nid && i > AUTO_SEQ_CENLFE) 3562 if (!nid && i > AUTO_SEQ_CENLFE)
3516 continue; 3563 continue;
3517 3564
3518 nid_vol = nid_vols[i]; 3565 if (codec->vendor_id == 0x11064397) {
3519 nid_mute = nid_mutes[i]; 3566 nid_vol = nid_vols[1][i];
3567 nid_mute = nid_mutes[1][i];
3568 } else {
3569 nid_vol = nid_vols[0][i];
3570 nid_mute = nid_mutes[0][i];
3571 }
3572 if (!nid_vol && !nid_mute)
3573 continue;
3520 3574
3521 if (i == AUTO_SEQ_CENLFE) { 3575 if (i == AUTO_SEQ_CENLFE) {
3522 /* Center/LFE */ 3576 /* Center/LFE */
@@ -3670,7 +3724,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
3670 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) 3724 if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0])
3671 return 0; /* can't find valid BIOS pin config */ 3725 return 0; /* can't find valid BIOS pin config */
3672 3726
3673 err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg); 3727 err = vt1708S_auto_create_multi_out_ctls(codec, &spec->autocfg);
3674 if (err < 0) 3728 if (err < 0)
3675 return err; 3729 return err;
3676 err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); 3730 err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]);
@@ -3737,17 +3791,29 @@ static int patch_vt1708S(struct hda_codec *codec)
3737 } 3791 }
3738 3792
3739 spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs; 3793 spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs;
3740 spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs; 3794 if (codec->vendor_id == 0x11064397)
3795 spec->init_verbs[spec->num_iverbs++] =
3796 vt1705_uniwill_init_verbs;
3797 else
3798 spec->init_verbs[spec->num_iverbs++] =
3799 vt1708S_uniwill_init_verbs;
3741 3800
3742 if (codec->vendor_id == 0x11060440) 3801 if (codec->vendor_id == 0x11060440)
3743 spec->stream_name_analog = "VT1818S Analog"; 3802 spec->stream_name_analog = "VT1818S Analog";
3803 else if (codec->vendor_id == 0x11064397)
3804 spec->stream_name_analog = "VT1705 Analog";
3744 else 3805 else
3745 spec->stream_name_analog = "VT1708S Analog"; 3806 spec->stream_name_analog = "VT1708S Analog";
3746 spec->stream_analog_playback = &vt1708S_pcm_analog_playback; 3807 if (codec->vendor_id == 0x11064397)
3808 spec->stream_analog_playback = &vt1705_pcm_analog_playback;
3809 else
3810 spec->stream_analog_playback = &vt1708S_pcm_analog_playback;
3747 spec->stream_analog_capture = &vt1708S_pcm_analog_capture; 3811 spec->stream_analog_capture = &vt1708S_pcm_analog_capture;
3748 3812
3749 if (codec->vendor_id == 0x11060440) 3813 if (codec->vendor_id == 0x11060440)
3750 spec->stream_name_digital = "VT1818S Digital"; 3814 spec->stream_name_digital = "VT1818S Digital";
3815 else if (codec->vendor_id == 0x11064397)
3816 spec->stream_name_digital = "VT1705 Digital";
3751 else 3817 else
3752 spec->stream_name_digital = "VT1708S Digital"; 3818 spec->stream_name_digital = "VT1708S Digital";
3753 spec->stream_digital_playback = &vt1708S_pcm_digital_playback; 3819 spec->stream_digital_playback = &vt1708S_pcm_digital_playback;
@@ -3785,6 +3851,14 @@ static int patch_vt1708S(struct hda_codec *codec)
3785 spec->stream_name_analog = "VT1818S Analog"; 3851 spec->stream_name_analog = "VT1818S Analog";
3786 spec->stream_name_digital = "VT1818S Digital"; 3852 spec->stream_name_digital = "VT1818S Digital";
3787 } 3853 }
3854 /* correct names for VT1705 */
3855 if (codec->vendor_id == 0x11064397) {
3856 kfree(codec->chip_name);
3857 codec->chip_name = kstrdup("VT1705", GFP_KERNEL);
3858 snprintf(codec->bus->card->mixername,
3859 sizeof(codec->bus->card->mixername),
3860 "%s %s", codec->vendor_name, codec->chip_name);
3861 }
3788 spec->set_widgets_power_state = set_widgets_power_state_vt1708B; 3862 spec->set_widgets_power_state = set_widgets_power_state_vt1708B;
3789 return 0; 3863 return 0;
3790} 3864}
@@ -6003,7 +6077,7 @@ static struct hda_codec_preset snd_hda_preset_via[] = {
6003 .patch = patch_vt1708S}, 6077 .patch = patch_vt1708S},
6004 { .id = 0x11063397, .name = "VT1708S", 6078 { .id = 0x11063397, .name = "VT1708S",
6005 .patch = patch_vt1708S}, 6079 .patch = patch_vt1708S},
6006 { .id = 0x11064397, .name = "VT1708S", 6080 { .id = 0x11064397, .name = "VT1705",
6007 .patch = patch_vt1708S}, 6081 .patch = patch_vt1708S},
6008 { .id = 0x11065397, .name = "VT1708S", 6082 { .id = 0x11065397, .name = "VT1708S",
6009 .patch = patch_vt1708S}, 6083 .patch = patch_vt1708S},