aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ac97
diff options
context:
space:
mode:
authorJohn L. Utz III <john.utz@dmx.com>2008-08-28 10:04:40 -0400
committerJaroslav Kysela <perex@perex.cz>2008-08-29 04:06:18 -0400
commit9e285e1a58bcf957cde9c0c559a1b9b0f708bb2f (patch)
treeec48890aaa0e07a7ece119153b2c5fbbcfe29897 /sound/pci/ac97
parentac68c16a44df6dd9edfde31917ae304526f60398 (diff)
ALSA: ac97 - vt1618 7.1 Audio Support
1. Implement 7.1 Output for vt1618 codec. 2. Fix typos in comments from my previous 1617a patch. Signed-off-by: John L. Utz III <john.utz@dmx.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/pci/ac97')
-rw-r--r--sound/pci/ac97/ac97_codec.c2
-rw-r--r--sound/pci/ac97/ac97_patch.c198
2 files changed, 197 insertions, 3 deletions
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c
index d0023e99bdf9..6704acbca8c0 100644
--- a/sound/pci/ac97/ac97_codec.c
+++ b/sound/pci/ac97/ac97_codec.c
@@ -168,7 +168,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = {
168{ 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL }, 168{ 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL },
169{ 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF 169{ 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF
170{ 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL }, // modified VT1616 with S/PDIF 170{ 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL }, // modified VT1616 with S/PDIF
171{ 0x56494182, 0xffffffff, "VIA1618", NULL, NULL }, 171{ 0x56494182, 0xffffffff, "VIA1618", patch_vt1618, NULL },
172{ 0x57454301, 0xffffffff, "W83971D", NULL, NULL }, 172{ 0x57454301, 0xffffffff, "W83971D", NULL, NULL },
173{ 0x574d4c00, 0xffffffff, "WM9701,WM9701A", NULL, NULL }, 173{ 0x574d4c00, 0xffffffff, "WM9701,WM9701A", NULL, NULL },
174{ 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL}, 174{ 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL},
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index bb028f8f9a2e..d0cab1d38789 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -3465,7 +3465,7 @@ static int patch_vt1616(struct snd_ac97 * ac97)
3465 3465
3466/* 3466/*
3467 * unfortunately, the vt1617a stashes the twiddlers required for 3467 * unfortunately, the vt1617a stashes the twiddlers required for
3468 * nooding the i/o jacks on 2 different regs. * thameans that we cant 3468 * noodling the i/o jacks on 2 different regs. that means that we can't
3469 * use the easy way provided by AC97_ENUM_DOUBLE() we have to write 3469 * use the easy way provided by AC97_ENUM_DOUBLE() we have to write
3470 * are own funcs. 3470 * are own funcs.
3471 * 3471 *
@@ -3498,7 +3498,7 @@ static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol,
3498 3498
3499 pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */ 3499 pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */
3500 3500
3501 /* grab our desirec bits, then mash them together in a manner 3501 /* grab our desired bits, then mash them together in a manner
3502 * consistent with Table 6 on page 17 in the 1617a docs */ 3502 * consistent with Table 6 on page 17 in the 1617a docs */
3503 3503
3504 usSM51 = snd_ac97_read(pac97, 0x7a) >> 14; 3504 usSM51 = snd_ac97_read(pac97, 0x7a) >> 14;
@@ -3576,6 +3576,200 @@ int patch_vt1617a(struct snd_ac97 * ac97)
3576 return err; 3576 return err;
3577} 3577}
3578 3578
3579/* VIA VT1618 8 CHANNEL AC97 CODEC
3580 *
3581 * VIA implements 'Smart 5.1' completely differently on the 1618 than
3582 * it does on the 1617a. awesome! They seem to have sourced this
3583 * particular revision of the technology from somebody else, it's
3584 * called Universal Audio Jack and it shows up on some other folk's chips
3585 * as well.
3586 *
3587 * ordering in this list reflects vt1618 docs for Reg 60h and
3588 * the block diagram, DACs are as follows:
3589 *
3590 * OUT_O -> Front,
3591 * OUT_1 -> Surround,
3592 * OUT_2 -> C/LFE
3593 *
3594 * Unlike the 1617a, each OUT has a consistent set of mappings
3595 * for all bitpatterns other than 00:
3596 *
3597 * 01 Unmixed Output
3598 * 10 Line In
3599 * 11 Mic In
3600 *
3601 * Special Case of 00:
3602 *
3603 * OUT_0 Mixed Output
3604 * OUT_1 Reserved
3605 * OUT_2 Reserved
3606 *
3607 * I have no idea what the hell Reserved does, but on an MSI
3608 * CN700T, i have to set it to get 5.1 output - YMMV, bad
3609 * shit may happen.
3610 *
3611 * If other chips use Universal Audio Jack, then this code might be applicable
3612 * to them.
3613 */
3614
3615struct vt1618_uaj_item {
3616 unsigned short mask;
3617 unsigned short shift;
3618 const char *items[4];
3619};
3620
3621/* This list reflects the vt1618 docs for Vendor Defined Register 0x60. */
3622
3623static struct vt1618_uaj_item vt1618_uaj[3] = {
3624 {
3625 /* speaker jack */
3626 .mask = 0x03,
3627 .shift = 0,
3628 .items = {
3629 "Speaker Out", "DAC Unmixed Out", "Line In", "Mic In"
3630 }
3631 },
3632 {
3633 /* line jack */
3634 .mask = 0x0c,
3635 .shift = 2,
3636 .items = {
3637 "Surround Out", "DAC Unmixed Out", "Line In", "Mic In"
3638 }
3639 },
3640 {
3641 /* mic jack */
3642 .mask = 0x30,
3643 .shift = 4,
3644 .items = {
3645 "Center LFE Out", "DAC Unmixed Out", "Line In", "Mic In"
3646 },
3647 },
3648};
3649
3650static int snd_ac97_vt1618_UAJ_info(struct snd_kcontrol *kcontrol,
3651 struct snd_ctl_elem_info *uinfo)
3652{
3653 return ac97_enum_text_info(kcontrol, uinfo,
3654 vt1618_uaj[kcontrol->private_value].items,
3655 4);
3656}
3657
3658/* All of the vt1618 Universal Audio Jack twiddlers are on
3659 * Vendor Defined Register 0x60, page 0. The bits, and thus
3660 * the mask, are the only thing that changes
3661 */
3662static int snd_ac97_vt1618_UAJ_get(struct snd_kcontrol *kcontrol,
3663 struct snd_ctl_elem_value *ucontrol)
3664{
3665 unsigned short datpag, uaj;
3666 struct snd_ac97 *pac97 = snd_kcontrol_chip(kcontrol);
3667
3668 mutex_lock(&pac97->page_mutex);
3669
3670 datpag = snd_ac97_read(pac97, AC97_INT_PAGING) & AC97_PAGE_MASK;
3671 snd_ac97_update_bits(pac97, AC97_INT_PAGING, AC97_PAGE_MASK, 0);
3672
3673 uaj = snd_ac97_read(pac97, 0x60) &
3674 vt1618_uaj[kcontrol->private_value].mask;
3675
3676 snd_ac97_update_bits(pac97, AC97_INT_PAGING, AC97_PAGE_MASK, datpag);
3677 mutex_unlock(&pac97->page_mutex);
3678
3679 ucontrol->value.enumerated.item[0] = uaj >>
3680 vt1618_uaj[kcontrol->private_value].shift;
3681
3682 return 0;
3683}
3684
3685static int snd_ac97_vt1618_UAJ_put(struct snd_kcontrol *kcontrol,
3686 struct snd_ctl_elem_value *ucontrol)
3687{
3688 return ac97_update_bits_page(snd_kcontrol_chip(kcontrol), 0x60,
3689 vt1618_uaj[kcontrol->private_value].mask,
3690 ucontrol->value.enumerated.item[0]<<
3691 vt1618_uaj[kcontrol->private_value].shift,
3692 0);
3693}
3694
3695/* config aux in jack - not found on 3 jack motherboards or soundcards */
3696
3697static int snd_ac97_vt1618_aux_info(struct snd_kcontrol *kcontrol,
3698 struct snd_ctl_elem_info *uinfo)
3699{
3700 static const char *txt_aux[] = {"Aux In", "Back Surr Out"};
3701
3702 return ac97_enum_text_info(kcontrol, uinfo, txt_aux, 2);
3703}
3704
3705static int snd_ac97_vt1618_aux_get(struct snd_kcontrol *kcontrol,
3706 struct snd_ctl_elem_value *ucontrol)
3707{
3708 ucontrol->value.enumerated.item[0] =
3709 (snd_ac97_read(snd_kcontrol_chip(kcontrol), 0x5c) & 0x0008)>>3;
3710 return 0;
3711}
3712
3713static int snd_ac97_vt1618_aux_put(struct snd_kcontrol *kcontrol,
3714 struct snd_ctl_elem_value *ucontrol)
3715{
3716 /* toggle surround rear dac power */
3717
3718 snd_ac97_update_bits(snd_kcontrol_chip(kcontrol), 0x5c, 0x0008,
3719 ucontrol->value.enumerated.item[0] << 3);
3720
3721 /* toggle aux in surround rear out jack */
3722
3723 return snd_ac97_update_bits(snd_kcontrol_chip(kcontrol), 0x76, 0x0008,
3724 ucontrol->value.enumerated.item[0] << 3);
3725}
3726
3727static const struct snd_kcontrol_new snd_ac97_controls_vt1618[] = {
3728 AC97_SINGLE("Exchange Center/LFE", 0x5a, 8, 1, 0),
3729 AC97_SINGLE("DC Offset", 0x5a, 10, 1, 0),
3730 AC97_SINGLE("Soft Mute", 0x5c, 0, 1, 1),
3731 AC97_SINGLE("Headphone Amp", 0x5c, 5, 1, 1),
3732 AC97_DOUBLE("Back Surr Volume", 0x5e, 8, 0, 31, 1),
3733 AC97_SINGLE("Back Surr Switch", 0x5e, 15, 1, 1),
3734 {
3735 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3736 .name = "Speaker Jack Mode",
3737 .info = snd_ac97_vt1618_UAJ_info,
3738 .get = snd_ac97_vt1618_UAJ_get,
3739 .put = snd_ac97_vt1618_UAJ_put,
3740 .private_value = 0
3741 },
3742 {
3743 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3744 .name = "Line Jack Mode",
3745 .info = snd_ac97_vt1618_UAJ_info,
3746 .get = snd_ac97_vt1618_UAJ_get,
3747 .put = snd_ac97_vt1618_UAJ_put,
3748 .private_value = 1
3749 },
3750 {
3751 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3752 .name = "Mic Jack Mode",
3753 .info = snd_ac97_vt1618_UAJ_info,
3754 .get = snd_ac97_vt1618_UAJ_get,
3755 .put = snd_ac97_vt1618_UAJ_put,
3756 .private_value = 2
3757 },
3758 {
3759 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3760 .name = "Aux Jack Mode",
3761 .info = snd_ac97_vt1618_aux_info,
3762 .get = snd_ac97_vt1618_aux_get,
3763 .put = snd_ac97_vt1618_aux_put,
3764 }
3765};
3766
3767int patch_vt1618(struct snd_ac97 *ac97)
3768{
3769 return patch_build_controls(ac97, snd_ac97_controls_vt1618,
3770 ARRAY_SIZE(snd_ac97_controls_vt1618));
3771}
3772
3579/* 3773/*
3580 */ 3774 */
3581static void it2646_update_jacks(struct snd_ac97 *ac97) 3775static void it2646_update_jacks(struct snd_ac97 *ac97)