diff options
author | Dan Carpenter <error27@gmail.com> | 2006-11-20 10:35:18 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2007-02-09 03:01:38 -0500 |
commit | 14e1d357e4fed9577d349952b71ec7d81aad710c (patch) | |
tree | 64214a31f820e4f78f5d3cc2226bda88cc06d98b /sound/pci | |
parent | ddc2cec4dbec157ac7426111205d59ac28f887ee (diff) |
[ALSA] atiixp - Add a parameter ac97_quirk
Add an option to specify the AC'97 codec instead of
probing. This is a fix for bugzilla #7467.
Signed-off-by: Dan Carpenter <error27@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@suse.cz>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/atiixp.c | 45 |
1 files changed, 45 insertions, 0 deletions
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; |