aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/intel8x0.c
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2008-08-29 05:29:39 -0400
committerJaroslav Kysela <perex@perex.cz>2008-08-29 06:23:41 -0400
commit2b3b5485aa96d18b0025dfb2bc92c824dc81a780 (patch)
treea917a3cdc1dd01a97afbae6dd668cdd42e217afc /sound/pci/intel8x0.c
parentd886e87cb82b0f6636476c1104bb84d7c8dc87d9 (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.c44
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.");
83module_param(id, charp, 0444); 83module_param(id, charp, 0444);
84MODULE_PARM_DESC(id, "ID string for Intel i8x0 soundcard."); 84MODULE_PARM_DESC(id, "ID string for Intel i8x0 soundcard.");
85module_param(ac97_clock, int, 0444); 85module_param(ac97_clock, int, 0444);
86MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect)."); 86MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = whitelist + auto-detect, 1 = force autodetect).");
87module_param(ac97_quirk, charp, 0444); 87module_param(ac97_quirk, charp, 0444);
88MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); 88MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
89module_param(buggy_semaphore, bool, 0444); 89module_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
2695struct intel8x0_clock_list {
2696 unsigned short subvendor;
2697 unsigned short subdevice;
2698 unsigned int rate;
2699};
2700
2701static 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
2709static 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
2696static void snd_intel8x0_proc_read(struct snd_info_entry * entry, 2728static 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);