diff options
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 74 |
1 files changed, 53 insertions, 21 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index e340792f6cb3..ff8ad46cc50e 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -60,10 +60,14 @@ static int bdl_pos_adj[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; | |||
60 | static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; | 60 | static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; |
61 | static int probe_only[SNDRV_CARDS]; | 61 | static int probe_only[SNDRV_CARDS]; |
62 | static int single_cmd; | 62 | static int single_cmd; |
63 | static int enable_msi; | 63 | static int enable_msi = -1; |
64 | #ifdef CONFIG_SND_HDA_PATCH_LOADER | 64 | #ifdef CONFIG_SND_HDA_PATCH_LOADER |
65 | static char *patch[SNDRV_CARDS]; | 65 | static char *patch[SNDRV_CARDS]; |
66 | #endif | 66 | #endif |
67 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
68 | static int beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = | ||
69 | CONFIG_SND_HDA_INPUT_BEEP_MODE}; | ||
70 | #endif | ||
67 | 71 | ||
68 | module_param_array(index, int, NULL, 0444); | 72 | module_param_array(index, int, NULL, 0444); |
69 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); | 73 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); |
@@ -91,6 +95,11 @@ MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); | |||
91 | module_param_array(patch, charp, NULL, 0444); | 95 | module_param_array(patch, charp, NULL, 0444); |
92 | MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface."); | 96 | MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface."); |
93 | #endif | 97 | #endif |
98 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
99 | module_param_array(beep_mode, int, NULL, 0444); | ||
100 | MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " | ||
101 | "(0=off, 1=on, 2=mute switch on/off) (default=1)."); | ||
102 | #endif | ||
94 | 103 | ||
95 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 104 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
96 | static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT; | 105 | static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT; |
@@ -404,6 +413,7 @@ struct azx { | |||
404 | unsigned short codec_mask; | 413 | unsigned short codec_mask; |
405 | int codec_probe_mask; /* copied from probe_mask option */ | 414 | int codec_probe_mask; /* copied from probe_mask option */ |
406 | struct hda_bus *bus; | 415 | struct hda_bus *bus; |
416 | unsigned int beep_mode; | ||
407 | 417 | ||
408 | /* CORB/RIRB */ | 418 | /* CORB/RIRB */ |
409 | struct azx_rb corb; | 419 | struct azx_rb corb; |
@@ -677,6 +687,14 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus, | |||
677 | } | 687 | } |
678 | } | 688 | } |
679 | 689 | ||
690 | if (!chip->polling_mode) { | ||
691 | snd_printk(KERN_WARNING SFX "azx_get_response timeout, " | ||
692 | "switching to polling mode: last cmd=0x%08x\n", | ||
693 | chip->last_cmd[addr]); | ||
694 | chip->polling_mode = 1; | ||
695 | goto again; | ||
696 | } | ||
697 | |||
680 | if (chip->msi) { | 698 | if (chip->msi) { |
681 | snd_printk(KERN_WARNING SFX "No response from codec, " | 699 | snd_printk(KERN_WARNING SFX "No response from codec, " |
682 | "disabling MSI: last cmd=0x%08x\n", | 700 | "disabling MSI: last cmd=0x%08x\n", |
@@ -692,14 +710,6 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus, | |||
692 | goto again; | 710 | goto again; |
693 | } | 711 | } |
694 | 712 | ||
695 | if (!chip->polling_mode) { | ||
696 | snd_printk(KERN_WARNING SFX "azx_get_response timeout, " | ||
697 | "switching to polling mode: last cmd=0x%08x\n", | ||
698 | chip->last_cmd[addr]); | ||
699 | chip->polling_mode = 1; | ||
700 | goto again; | ||
701 | } | ||
702 | |||
703 | if (chip->probing) { | 713 | if (chip->probing) { |
704 | /* If this critical timeout happens during the codec probing | 714 | /* If this critical timeout happens during the codec probing |
705 | * phase, this is likely an access to a non-existing codec | 715 | * phase, this is likely an access to a non-existing codec |
@@ -722,9 +732,10 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus, | |||
722 | chip->last_cmd[addr]); | 732 | chip->last_cmd[addr]); |
723 | chip->single_cmd = 1; | 733 | chip->single_cmd = 1; |
724 | bus->response_reset = 0; | 734 | bus->response_reset = 0; |
725 | /* re-initialize CORB/RIRB */ | 735 | /* release CORB/RIRB */ |
726 | azx_free_cmd_io(chip); | 736 | azx_free_cmd_io(chip); |
727 | azx_init_cmd_io(chip); | 737 | /* disable unsolicited responses */ |
738 | azx_writel(chip, GCTL, azx_readl(chip, GCTL) & ~ICH6_GCTL_UNSOL); | ||
728 | return -1; | 739 | return -1; |
729 | } | 740 | } |
730 | 741 | ||
@@ -865,7 +876,9 @@ static int azx_reset(struct azx *chip) | |||
865 | } | 876 | } |
866 | 877 | ||
867 | /* Accept unsolicited responses */ | 878 | /* Accept unsolicited responses */ |
868 | azx_writel(chip, GCTL, azx_readl(chip, GCTL) | ICH6_GCTL_UNSOL); | 879 | if (!chip->single_cmd) |
880 | azx_writel(chip, GCTL, azx_readl(chip, GCTL) | | ||
881 | ICH6_GCTL_UNSOL); | ||
869 | 882 | ||
870 | /* detect codecs */ | 883 | /* detect codecs */ |
871 | if (!chip->codec_mask) { | 884 | if (!chip->codec_mask) { |
@@ -980,7 +993,8 @@ static void azx_init_chip(struct azx *chip) | |||
980 | azx_int_enable(chip); | 993 | azx_int_enable(chip); |
981 | 994 | ||
982 | /* initialize the codec command I/O */ | 995 | /* initialize the codec command I/O */ |
983 | azx_init_cmd_io(chip); | 996 | if (!chip->single_cmd) |
997 | azx_init_cmd_io(chip); | ||
984 | 998 | ||
985 | /* program the position buffer */ | 999 | /* program the position buffer */ |
986 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); | 1000 | azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr); |
@@ -1400,6 +1414,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) | |||
1400 | err = snd_hda_codec_new(chip->bus, c, &codec); | 1414 | err = snd_hda_codec_new(chip->bus, c, &codec); |
1401 | if (err < 0) | 1415 | if (err < 0) |
1402 | continue; | 1416 | continue; |
1417 | codec->beep_mode = chip->beep_mode; | ||
1403 | codecs++; | 1418 | codecs++; |
1404 | } | 1419 | } |
1405 | } | 1420 | } |
@@ -2067,7 +2082,8 @@ static void azx_power_notify(struct hda_bus *bus) | |||
2067 | } | 2082 | } |
2068 | if (power_on) | 2083 | if (power_on) |
2069 | azx_init_chip(chip); | 2084 | azx_init_chip(chip); |
2070 | else if (chip->running && power_save_controller) | 2085 | else if (chip->running && power_save_controller && |
2086 | !bus->power_keep_link_on) | ||
2071 | azx_stop_chip(chip); | 2087 | azx_stop_chip(chip); |
2072 | } | 2088 | } |
2073 | #endif /* CONFIG_SND_HDA_POWER_SAVE */ | 2089 | #endif /* CONFIG_SND_HDA_POWER_SAVE */ |
@@ -2150,6 +2166,7 @@ static int azx_resume(struct pci_dev *pci) | |||
2150 | static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf) | 2166 | static int azx_halt(struct notifier_block *nb, unsigned long event, void *buf) |
2151 | { | 2167 | { |
2152 | struct azx *chip = container_of(nb, struct azx, reboot_notifier); | 2168 | struct azx *chip = container_of(nb, struct azx, reboot_notifier); |
2169 | snd_hda_bus_reboot_notify(chip->bus); | ||
2153 | azx_stop_chip(chip); | 2170 | azx_stop_chip(chip); |
2154 | return NOTIFY_OK; | 2171 | return NOTIFY_OK; |
2155 | } | 2172 | } |
@@ -2217,7 +2234,9 @@ static int azx_dev_free(struct snd_device *device) | |||
2217 | static struct snd_pci_quirk position_fix_list[] __devinitdata = { | 2234 | static struct snd_pci_quirk position_fix_list[] __devinitdata = { |
2218 | SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), | 2235 | SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), |
2219 | SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), | 2236 | SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), |
2237 | SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), | ||
2220 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), | 2238 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), |
2239 | SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), | ||
2221 | {} | 2240 | {} |
2222 | }; | 2241 | }; |
2223 | 2242 | ||
@@ -2300,11 +2319,10 @@ static void __devinit check_probe_mask(struct azx *chip, int dev) | |||
2300 | } | 2319 | } |
2301 | 2320 | ||
2302 | /* | 2321 | /* |
2303 | * white-list for enable_msi | 2322 | * white/black-list for enable_msi |
2304 | */ | 2323 | */ |
2305 | static struct snd_pci_quirk msi_white_list[] __devinitdata = { | 2324 | static struct snd_pci_quirk msi_black_list[] __devinitdata = { |
2306 | SND_PCI_QUIRK(0x103c, 0x30f7, "HP Pavilion dv4t-1300", 1), | 2325 | SND_PCI_QUIRK(0x1043, 0x81f2, "ASUS", 0), /* Athlon64 X2 + nvidia */ |
2307 | SND_PCI_QUIRK(0x103c, 0x3607, "HP Compa CQ40", 1), | ||
2308 | {} | 2326 | {} |
2309 | }; | 2327 | }; |
2310 | 2328 | ||
@@ -2312,10 +2330,12 @@ static void __devinit check_msi(struct azx *chip) | |||
2312 | { | 2330 | { |
2313 | const struct snd_pci_quirk *q; | 2331 | const struct snd_pci_quirk *q; |
2314 | 2332 | ||
2315 | chip->msi = enable_msi; | 2333 | if (enable_msi >= 0) { |
2316 | if (chip->msi) | 2334 | chip->msi = !!enable_msi; |
2317 | return; | 2335 | return; |
2318 | q = snd_pci_quirk_lookup(chip->pci, msi_white_list); | 2336 | } |
2337 | chip->msi = 1; /* enable MSI as default */ | ||
2338 | q = snd_pci_quirk_lookup(chip->pci, msi_black_list); | ||
2319 | if (q) { | 2339 | if (q) { |
2320 | printk(KERN_INFO | 2340 | printk(KERN_INFO |
2321 | "hda_intel: msi for device %04x:%04x set to %d\n", | 2341 | "hda_intel: msi for device %04x:%04x set to %d\n", |
@@ -2432,6 +2452,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2432 | } | 2452 | } |
2433 | } | 2453 | } |
2434 | 2454 | ||
2455 | /* disable 64bit DMA address for Teradici */ | ||
2456 | /* it does not work with device 6549:1200 subsys e4a2:040b */ | ||
2457 | if (chip->driver_type == AZX_DRIVER_TERA) | ||
2458 | gcap &= ~ICH6_GCAP_64OK; | ||
2459 | |||
2435 | /* allow 64bit DMA address if supported by H/W */ | 2460 | /* allow 64bit DMA address if supported by H/W */ |
2436 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) | 2461 | if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) |
2437 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); | 2462 | pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); |
@@ -2574,6 +2599,10 @@ static int __devinit azx_probe(struct pci_dev *pci, | |||
2574 | goto out_free; | 2599 | goto out_free; |
2575 | card->private_data = chip; | 2600 | card->private_data = chip; |
2576 | 2601 | ||
2602 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
2603 | chip->beep_mode = beep_mode[dev]; | ||
2604 | #endif | ||
2605 | |||
2577 | /* create codec instances */ | 2606 | /* create codec instances */ |
2578 | err = azx_codec_create(chip, model[dev]); | 2607 | err = azx_codec_create(chip, model[dev]); |
2579 | if (err < 0) | 2608 | if (err < 0) |
@@ -2685,6 +2714,9 @@ static struct pci_device_id azx_ids[] = { | |||
2685 | { PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA }, | 2714 | { PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA }, |
2686 | { PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA }, | 2715 | { PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA }, |
2687 | { PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA }, | 2716 | { PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA }, |
2717 | { PCI_DEVICE(0x10de, 0x0be2), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2718 | { PCI_DEVICE(0x10de, 0x0be3), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2719 | { PCI_DEVICE(0x10de, 0x0be4), .driver_data = AZX_DRIVER_NVIDIA }, | ||
2688 | { PCI_DEVICE(0x10de, 0x0d94), .driver_data = AZX_DRIVER_NVIDIA }, | 2720 | { PCI_DEVICE(0x10de, 0x0d94), .driver_data = AZX_DRIVER_NVIDIA }, |
2689 | { PCI_DEVICE(0x10de, 0x0d95), .driver_data = AZX_DRIVER_NVIDIA }, | 2721 | { PCI_DEVICE(0x10de, 0x0d95), .driver_data = AZX_DRIVER_NVIDIA }, |
2690 | { PCI_DEVICE(0x10de, 0x0d96), .driver_data = AZX_DRIVER_NVIDIA }, | 2722 | { PCI_DEVICE(0x10de, 0x0d96), .driver_data = AZX_DRIVER_NVIDIA }, |