]> git.hungrycats.org Git - linux/commitdiff
ALSA CVS update
authorJaroslav Kysela <perex@suse.cz>
Thu, 25 Sep 2003 16:33:24 +0000 (18:33 +0200)
committerJaroslav Kysela <perex@suse.cz>
Thu, 25 Sep 2003 16:33:24 +0000 (18:33 +0200)
D:2003/08/28 16:36:44
C:AC97 Codec Core
A:Takashi Iwai <tiwai@suse.de>
F:include/ac97_codec.h:1.32->1.33
F:pci/ac97/ac97_codec.c:1.102->1.103
F:pci/ac97/ac97_patch.c:1.20->1.21
L:- added the detection of revision of ALC650 chip by
L:  James Courtier-Dutton <James@superbug.demon.co.uk>
L:- fixed the patch_alc650() to refer to the detected revision.
L:- detect the availability of stereo mute bits in snd_ac97_cmute_new().

include/sound/ac97_codec.h
sound/pci/ac97/ac97_codec.c
sound/pci/ac97/ac97_patch.c

index a86629953fb5f0c2f9b46dd34aaf44d07e6af107..94e88a0159f37e7274d6588c340cf18dd2d10eaa 100644 (file)
 #define AC97_ALC650_SURR_DAC_VOL       0x64
 #define AC97_ALC650_LFE_DAC_VOL                0x66
 #define AC97_ALC650_MULTICH    0x6a
+#define AC97_ALC650_REVISION    0x6e
 #define AC97_ALC650_CLOCK      0x7a
 
 /* specific - Yamaha YMF753 */
index c1efd5dddf56eadebb0a2d2770b7164617232e6f..780bff32137e2bac2fafed0ed4fda3f2f92c654d 100644 (file)
@@ -64,7 +64,7 @@ static const ac97_codec_id_t snd_ac97_codec_id_vendors[] = {
 { 0x414b4d00, 0xffffff00, "Asahi Kasei",       NULL,   NULL },
 { 0x41445300, 0xffffff00, "Analog Devices",    NULL,   NULL },
 { 0x414c4300, 0xffffff00, "Realtek",           NULL,   NULL },
-{ 0x414c4700, 0xffffff00, "Avance Logic",      NULL,   NULL },
+{ 0x414c4700, 0xffffff00, "Realtek",           NULL,   NULL },
 { 0x434d4900, 0xffffff00, "C-Media Electronics", NULL, NULL },
 { 0x43525900, 0xffffff00, "Cirrus Logic",      NULL,   NULL },
 { 0x43585400, 0xffffff00, "Conexant",           NULL,  NULL },
@@ -109,6 +109,9 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
 { 0x414c4320, 0xfffffff0, "RL5383",            NULL,           NULL },
 { 0x414c4710, 0xfffffff0, "ALC200/200P",       NULL,           NULL },
 { 0x414c4720, 0xfffffff0, "ALC650",            patch_alc650,   NULL },
+{ 0x414c4721, 0xfffffff0, "ALC650D",           patch_alc650,   NULL },
+{ 0x414c4722, 0xfffffff0, "ALC650E",           patch_alc650,   NULL },
+{ 0x414c4723, 0xfffffff0, "ALC650F",           patch_alc650,   NULL },
 { 0x414c4730, 0xffffffff, "ALC101",            NULL,           NULL },
 { 0x414c4740, 0xfffffff0, "ALC202",            NULL,           NULL },
 { 0x414c4750, 0xfffffff0, "ALC250",            NULL,           NULL },
@@ -1125,7 +1128,19 @@ snd_kcontrol_t *snd_ac97_cnew(const snd_kcontrol_new_t *_template, ac97_t * ac97
 static int snd_ac97_cmute_new(snd_card_t *card, char *name, int reg, ac97_t *ac97)
 {
        snd_kcontrol_t *kctl;
+       int stereo = 0;
+
        if (ac97->flags & AC97_STEREO_MUTES) {
+               /* check whether both mute bits work */
+               unsigned short val, val1;
+               val = snd_ac97_read(ac97, reg);
+               val1 = val | 0x8080;
+               snd_ac97_write(ac97, reg, val1);
+               if (val1 == snd_ac97_read(ac97, reg))
+                       stereo = 1;
+               snd_ac97_write(ac97, reg, val);
+       }
+       if (stereo) {
                snd_kcontrol_new_t tmp = AC97_DOUBLE(name, reg, 15, 7, 1, 1);
                tmp.index = ac97->num;
                kctl = snd_ctl_new1(&tmp, ac97);
@@ -1622,6 +1637,7 @@ int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97)
        ac97_t *ac97;
        char name[64];
        unsigned long end_time;
+       unsigned int reg;
        static snd_device_ops_t ops = {
                .dev_free =     snd_ac97_dev_free,
        };
@@ -1665,6 +1681,20 @@ int snd_ac97_mixer(snd_card_t * card, ac97_t * _ac97, ac97_t ** rac97)
                snd_ac97_free(ac97);
                return -EIO;
        }
+       /* AC97 audio codec chip revision detection. */
+       /* Currently only Realtek ALC650 detection implemented. */
+       switch(ac97->id & 0xfffffff0) {
+       case 0x414c4720:        /* ALC650 */
+               reg = snd_ac97_read(ac97, AC97_ALC650_REVISION);
+               if (((reg & 0x3f) >= 0) && ((reg & 0x3f) < 3))
+                       ac97->id = 0x414c4720;          /* Old version */
+               else if (((reg & 0x3f) >= 3) && ((reg & 0x3f) < 0x10))
+                       ac97->id = 0x414c4721;          /* D version */
+               else if ((reg&0x30) == 0x10)
+                       ac97->id = 0x414c4722;          /* E version */
+               else if ((reg&0x30) == 0x20)
+                       ac97->id = 0x414c4723;          /* F version */
+        }
        
        /* test for AC'97 */
        if (! (ac97->scaps & AC97_SCAP_AUDIO)) {
index b88863496c29c7f5de5fa736162db6180d213919..cb00b376df2e7c54d5a290ddbbe64863b05567bd 100644 (file)
@@ -897,20 +897,22 @@ static struct snd_ac97_build_ops patch_alc650_ops = {
 
 int patch_alc650(ac97_t * ac97)
 {
-       unsigned short val;
+       unsigned short val, reg;
        int spdif = 0;
 
-       /* FIXME: set the below 1 if we can detect the chip rev.E correctly.
-        *        this is used for switching mic and center/lfe, which needs
-        *        resetting GPIO0 level on the older revision.
-        */
        ac97->build_ops = &patch_alc650_ops;
-       ac97->spec.dev_flags = 0;
+
+       /* revision E or F */
+       /* FIXME: what about revision D ? */
+       ac97->spec.dev_flags = (ac97->id == 0x414c4722 ||
+                               ac97->id == 0x414c4723);
 
        /* check spdif (should be only on rev.E) */
-       val = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
-       if (val & AC97_EA_SPCV)
-               spdif = 1;
+       if (ac97->spec.dev_flags) {
+               val = snd_ac97_read(ac97, AC97_EXTENDED_STATUS);
+               if (val & AC97_EA_SPCV)
+                       spdif = 1;
+       }
 
        if (spdif) {
                /* enable spdif in */