diff options
-rw-r--r-- | Documentation/sound/alsa/ALSA-Configuration.txt | 6 | ||||
-rw-r--r-- | sound/pci/atiixp.c | 45 |
2 files changed, 51 insertions, 0 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index c54fd7c258d9..d853a303ffcb 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt | |||
@@ -242,6 +242,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. | |||
242 | ac97_clock - AC'97 clock (default = 48000) | 242 | ac97_clock - AC'97 clock (default = 48000) |
243 | ac97_quirk - AC'97 workaround for strange hardware | 243 | ac97_quirk - AC'97 workaround for strange hardware |
244 | See "AC97 Quirk Option" section below. | 244 | See "AC97 Quirk Option" section below. |
245 | ac97_codec - Workaround to specify which AC'97 codec | ||
246 | instead of probing. If this works for you | ||
247 | file a bug with your `lspci -vn` output. | ||
248 | -2 -- Force probing. | ||
249 | -1 -- Default behavior. | ||
250 | 0-2 -- Use the specified codec. | ||
245 | spdif_aclink - S/PDIF transfer over AC-link (default = 1) | 251 | spdif_aclink - S/PDIF transfer over AC-link (default = 1) |
246 | 252 | ||
247 | This module supports one card and autoprobe. | 253 | This module supports one card and autoprobe. |
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index 86710df71a8e..92df811d695d 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c | |||
@@ -45,6 +45,7 @@ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ | |||
45 | static int ac97_clock = 48000; | 45 | static int ac97_clock = 48000; |
46 | static char *ac97_quirk; | 46 | static char *ac97_quirk; |
47 | static int spdif_aclink = 1; | 47 | static int spdif_aclink = 1; |
48 | static int ac97_codec = -1; | ||
48 | 49 | ||
49 | module_param(index, int, 0444); | 50 | module_param(index, int, 0444); |
50 | MODULE_PARM_DESC(index, "Index value for ATI IXP controller."); | 51 | MODULE_PARM_DESC(index, "Index value for ATI IXP controller."); |
@@ -54,6 +55,8 @@ module_param(ac97_clock, int, 0444); | |||
54 | MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz)."); | 55 | MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz)."); |
55 | module_param(ac97_quirk, charp, 0444); | 56 | module_param(ac97_quirk, charp, 0444); |
56 | MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); | 57 | MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); |
58 | module_param(ac97_codec, int, 0444); | ||
59 | MODULE_PARM_DESC(ac97_codec, "Specify codec instead of probing."); | ||
57 | module_param(spdif_aclink, bool, 0444); | 60 | module_param(spdif_aclink, bool, 0444); |
58 | MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link."); | 61 | MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link."); |
59 | 62 | ||
@@ -293,6 +296,22 @@ static struct pci_device_id snd_atiixp_ids[] = { | |||
293 | 296 | ||
294 | MODULE_DEVICE_TABLE(pci, snd_atiixp_ids); | 297 | MODULE_DEVICE_TABLE(pci, snd_atiixp_ids); |
295 | 298 | ||
299 | struct atiixp_quirk { | ||
300 | unsigned short subvendor; | ||
301 | unsigned short subdevice; | ||
302 | const char *name; | ||
303 | int ac97_codec; | ||
304 | }; | ||
305 | |||
306 | static struct atiixp_quirk atiixp_quirks[] __devinitdata = { | ||
307 | { | ||
308 | .subvendor = 0x15bd, | ||
309 | .subdevice = 0x3100, | ||
310 | .name = "DFI RS482", | ||
311 | .ac97_codec = 0, | ||
312 | }, | ||
313 | { .subvendor = 0 } /* terminator */ | ||
314 | }; | ||
296 | 315 | ||
297 | /* | 316 | /* |
298 | * lowlevel functions | 317 | * lowlevel functions |
@@ -553,11 +572,37 @@ static int snd_atiixp_aclink_down(struct atiixp *chip) | |||
553 | ATI_REG_ISR_CODEC2_NOT_READY) | 572 | ATI_REG_ISR_CODEC2_NOT_READY) |
554 | #define CODEC_CHECK_BITS (ALL_CODEC_NOT_READY|ATI_REG_ISR_NEW_FRAME) | 573 | #define CODEC_CHECK_BITS (ALL_CODEC_NOT_READY|ATI_REG_ISR_NEW_FRAME) |
555 | 574 | ||
575 | static int ac97_probing_bugs(struct pci_dev *pci) | ||
576 | { | ||
577 | int i = 0; | ||
578 | |||
579 | while (atiixp_quirks[i].subvendor) { | ||
580 | if (pci->subsystem_vendor == atiixp_quirks[i].subvendor && | ||
581 | pci->subsystem_device == atiixp_quirks[i].subdevice) { | ||
582 | printk(KERN_INFO "Atiixp quirk for %s. " | ||
583 | "Forcing codec %d\n", atiixp_quirks[i].name, | ||
584 | atiixp_quirks[i].ac97_codec); | ||
585 | return atiixp_quirks[i].ac97_codec; | ||
586 | } | ||
587 | i++; | ||
588 | } | ||
589 | /* this hardware doesn't need workarounds. Probe for codec */ | ||
590 | return -1; | ||
591 | } | ||
592 | |||
556 | static int snd_atiixp_codec_detect(struct atiixp *chip) | 593 | static int snd_atiixp_codec_detect(struct atiixp *chip) |
557 | { | 594 | { |
558 | int timeout; | 595 | int timeout; |
559 | 596 | ||
560 | chip->codec_not_ready_bits = 0; | 597 | chip->codec_not_ready_bits = 0; |
598 | if (ac97_codec == -1) | ||
599 | ac97_codec = ac97_probing_bugs(chip->pci); | ||
600 | if (ac97_codec >= 0) { | ||
601 | chip->codec_not_ready_bits |= | ||
602 | CODEC_CHECK_BITS ^ (1 << (ac97_codec + 10)); | ||
603 | return 0; | ||
604 | } | ||
605 | |||
561 | atiixp_write(chip, IER, CODEC_CHECK_BITS); | 606 | atiixp_write(chip, IER, CODEC_CHECK_BITS); |
562 | /* wait for the interrupts */ | 607 | /* wait for the interrupts */ |
563 | timeout = 50; | 608 | timeout = 50; |