diff options
| author | Jaroslav Kysela <perex@suse.cz> | 2003-09-25 18:33:24 +0200 |
|---|---|---|
| committer | Jaroslav Kysela <perex@suse.cz> | 2003-09-25 18:33:24 +0200 |
| commit | 5e63ebcadb132db401edd24bfa477eadd295132c (patch) | |
| tree | cf8df27e66e0ddd1cbe687a4a724845ca2887a99 | |
| parent | 87c672989fff161e9e25b4d08f0fea564f43a7cb (diff) | |
ALSA CVS update
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().
| -rw-r--r-- | include/sound/ac97_codec.h | 1 | ||||
| -rw-r--r-- | sound/pci/ac97/ac97_codec.c | 32 | ||||
| -rw-r--r-- | sound/pci/ac97/ac97_patch.c | 20 |
3 files changed, 43 insertions, 10 deletions
diff --git a/include/sound/ac97_codec.h b/include/sound/ac97_codec.h index a86629953fb5..94e88a0159f3 100644 --- a/include/sound/ac97_codec.h +++ b/include/sound/ac97_codec.h @@ -217,6 +217,7 @@ #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 */ diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index c1efd5dddf56..780bff32137e 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -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)) { diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index b88863496c29..cb00b376df2e 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -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 */ |
