diff options
author | Lydia Wang <lydiawang@viatech.com.cn> | 2011-03-23 05:56:05 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-03-23 06:49:33 -0400 |
commit | bc92df7fe55e49c616a003b0b77e7badf2736429 (patch) | |
tree | 60b1a5c1d4af61f0a8319fc6cb07fcc35efe31f9 /sound/pci/hda/patch_via.c | |
parent | 3e95b9aba50deeee69afce87d2bcd94c4cd1d95e (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.c | 100 |
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 | ||
3245 | static int patch_vt1708S(struct hda_codec *codec); | 3258 | static 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 | ||
3430 | static 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 | |||
3417 | static struct hda_pcm_stream vt1708S_pcm_analog_playback = { | 3442 | static 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 | ||
3455 | static 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 | |||
3430 | static struct hda_pcm_stream vt1708S_pcm_analog_capture = { | 3468 | static 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 */ |
3499 | static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec, | 3543 | static 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}, |