diff options
author | Jaroslav Kysela <perex@perex.cz> | 2008-08-29 05:29:39 -0400 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-08-29 06:23:41 -0400 |
commit | 2b3b5485aa96d18b0025dfb2bc92c824dc81a780 (patch) | |
tree | a917a3cdc1dd01a97afbae6dd668cdd42e217afc /sound/pci/intel8x0.c | |
parent | d886e87cb82b0f6636476c1104bb84d7c8dc87d9 (diff) |
ALSA: intel8x0: implement ac97_clock whitelist
The AC97 clock detection is not accurate in some cases. This patch adds
an initial whitelist for audio devices gathered from RedHat's bugzilla:
https://bugzilla.redhat.com/show_bug.cgi?id=441087
As a side effect, white-listing might speedup kernel booting (AC97 clock
measuring code is not activated).
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/pci/intel8x0.c')
-rw-r--r-- | sound/pci/intel8x0.c | 44 |
1 files changed, 41 insertions, 3 deletions
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 73ad58995366..c8f514896841 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -83,7 +83,7 @@ MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard."); | |||
83 | module_param(id, charp, 0444); | 83 | module_param(id, charp, 0444); |
84 | MODULE_PARM_DESC(id, "ID string for Intel i8x0 soundcard."); | 84 | MODULE_PARM_DESC(id, "ID string for Intel i8x0 soundcard."); |
85 | module_param(ac97_clock, int, 0444); | 85 | module_param(ac97_clock, int, 0444); |
86 | MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect)."); | 86 | MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = whitelist + auto-detect, 1 = force autodetect)."); |
87 | module_param(ac97_quirk, charp, 0444); | 87 | module_param(ac97_quirk, charp, 0444); |
88 | MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); | 88 | MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); |
89 | module_param(buggy_semaphore, bool, 0444); | 89 | module_param(buggy_semaphore, bool, 0444); |
@@ -2692,6 +2692,38 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) | |||
2692 | snd_ac97_update_power(chip->ac97[0], AC97_PCM_FRONT_DAC_RATE, 0); | 2692 | snd_ac97_update_power(chip->ac97[0], AC97_PCM_FRONT_DAC_RATE, 0); |
2693 | } | 2693 | } |
2694 | 2694 | ||
2695 | struct intel8x0_clock_list { | ||
2696 | unsigned short subvendor; | ||
2697 | unsigned short subdevice; | ||
2698 | unsigned int rate; | ||
2699 | }; | ||
2700 | |||
2701 | static struct intel8x0_clock_list intel8x0_clock_list[] __devinitdata = { | ||
2702 | { 0x0e11, 0x008a, 41000 }, /* Analog Devices AD1885 */ | ||
2703 | { 0x1028, 0x00be, 44100 }, /* Analog Devices AD1885 */ | ||
2704 | { 0x1028, 0x0177, 48000 }, /* Analog Devices AD1980 */ | ||
2705 | { 0x1043, 0x80f3, 48000 }, /* Analog Devices AD1985 */ | ||
2706 | { 0x0000, 0x0000, 00000 } /* terminator */ | ||
2707 | }; | ||
2708 | |||
2709 | static int __devinit intel8x0_in_clock_list(struct intel8x0 *chip) | ||
2710 | { | ||
2711 | struct pci_dev *pci = chip->pci; | ||
2712 | struct intel8x0_clock_list *wl; | ||
2713 | |||
2714 | for (wl = intel8x0_clock_list; wl->subvendor; wl++) { | ||
2715 | if (wl->subvendor == pci->subsystem_vendor && | ||
2716 | wl->subdevice == pci->subsystem_device) { | ||
2717 | printk(KERN_INFO "intel8x0: white list rate for %04x:%04x is %i\n", | ||
2718 | pci->subsystem_vendor, | ||
2719 | pci->subsystem_device, wl->rate); | ||
2720 | chip->ac97_bus->clock = wl->rate; | ||
2721 | return 1; | ||
2722 | } | ||
2723 | } | ||
2724 | return 0; | ||
2725 | } | ||
2726 | |||
2695 | #ifdef CONFIG_PROC_FS | 2727 | #ifdef CONFIG_PROC_FS |
2696 | static void snd_intel8x0_proc_read(struct snd_info_entry * entry, | 2728 | static void snd_intel8x0_proc_read(struct snd_info_entry * entry, |
2697 | struct snd_info_buffer *buffer) | 2729 | struct snd_info_buffer *buffer) |
@@ -3087,8 +3119,14 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci, | |||
3087 | "%s with %s at irq %i", card->shortname, | 3119 | "%s with %s at irq %i", card->shortname, |
3088 | snd_ac97_get_short_name(chip->ac97[0]), chip->irq); | 3120 | snd_ac97_get_short_name(chip->ac97[0]), chip->irq); |
3089 | 3121 | ||
3090 | if (! ac97_clock) | 3122 | if (ac97_clock == 0 || ac97_clock == 1) { |
3091 | intel8x0_measure_ac97_clock(chip); | 3123 | if (ac97_clock == 0) { |
3124 | if (intel8x0_in_clock_list(chip) == 0) | ||
3125 | intel8x0_measure_ac97_clock(chip); | ||
3126 | } else { | ||
3127 | intel8x0_measure_ac97_clock(chip); | ||
3128 | } | ||
3129 | } | ||
3092 | 3130 | ||
3093 | if ((err = snd_card_register(card)) < 0) { | 3131 | if ((err = snd_card_register(card)) < 0) { |
3094 | snd_card_free(card); | 3132 | snd_card_free(card); |