diff options
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 76 |
1 files changed, 52 insertions, 24 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 5cc3d07f715..be6982289c0 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -177,7 +177,8 @@ MODULE_DESCRIPTION("Intel HDA driver"); | |||
177 | #define ICH6_REG_INTCTL 0x20 | 177 | #define ICH6_REG_INTCTL 0x20 |
178 | #define ICH6_REG_INTSTS 0x24 | 178 | #define ICH6_REG_INTSTS 0x24 |
179 | #define ICH6_REG_WALLCLK 0x30 /* 24Mhz source */ | 179 | #define ICH6_REG_WALLCLK 0x30 /* 24Mhz source */ |
180 | #define ICH6_REG_SYNC 0x34 | 180 | #define ICH6_REG_OLD_SSYNC 0x34 /* SSYNC for old ICH */ |
181 | #define ICH6_REG_SSYNC 0x38 | ||
181 | #define ICH6_REG_CORBLBASE 0x40 | 182 | #define ICH6_REG_CORBLBASE 0x40 |
182 | #define ICH6_REG_CORBUBASE 0x44 | 183 | #define ICH6_REG_CORBUBASE 0x44 |
183 | #define ICH6_REG_CORBWP 0x48 | 184 | #define ICH6_REG_CORBWP 0x48 |
@@ -479,6 +480,7 @@ enum { | |||
479 | #define AZX_DCAPS_POSFIX_VIA (1 << 17) /* Use VIACOMBO as default */ | 480 | #define AZX_DCAPS_POSFIX_VIA (1 << 17) /* Use VIACOMBO as default */ |
480 | #define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ | 481 | #define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ |
481 | #define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ | 482 | #define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ |
483 | #define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ | ||
482 | 484 | ||
483 | /* quirks for ATI SB / AMD Hudson */ | 485 | /* quirks for ATI SB / AMD Hudson */ |
484 | #define AZX_DCAPS_PRESET_ATI_SB \ | 486 | #define AZX_DCAPS_PRESET_ATI_SB \ |
@@ -1706,13 +1708,16 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) | |||
1706 | struct snd_pcm_runtime *runtime = substream->runtime; | 1708 | struct snd_pcm_runtime *runtime = substream->runtime; |
1707 | unsigned int bufsize, period_bytes, format_val, stream_tag; | 1709 | unsigned int bufsize, period_bytes, format_val, stream_tag; |
1708 | int err; | 1710 | int err; |
1711 | struct hda_spdif_out *spdif = | ||
1712 | snd_hda_spdif_out_of_nid(apcm->codec, hinfo->nid); | ||
1713 | unsigned short ctls = spdif ? spdif->ctls : 0; | ||
1709 | 1714 | ||
1710 | azx_stream_reset(chip, azx_dev); | 1715 | azx_stream_reset(chip, azx_dev); |
1711 | format_val = snd_hda_calc_stream_format(runtime->rate, | 1716 | format_val = snd_hda_calc_stream_format(runtime->rate, |
1712 | runtime->channels, | 1717 | runtime->channels, |
1713 | runtime->format, | 1718 | runtime->format, |
1714 | hinfo->maxbps, | 1719 | hinfo->maxbps, |
1715 | apcm->codec->spdif_ctls); | 1720 | ctls); |
1716 | if (!format_val) { | 1721 | if (!format_val) { |
1717 | snd_printk(KERN_ERR SFX | 1722 | snd_printk(KERN_ERR SFX |
1718 | "invalid format_val, rate=%d, ch=%d, format=%d\n", | 1723 | "invalid format_val, rate=%d, ch=%d, format=%d\n", |
@@ -1792,7 +1797,11 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
1792 | spin_lock(&chip->reg_lock); | 1797 | spin_lock(&chip->reg_lock); |
1793 | if (nsync > 1) { | 1798 | if (nsync > 1) { |
1794 | /* first, set SYNC bits of corresponding streams */ | 1799 | /* first, set SYNC bits of corresponding streams */ |
1795 | azx_writel(chip, SYNC, azx_readl(chip, SYNC) | sbits); | 1800 | if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC) |
1801 | azx_writel(chip, OLD_SSYNC, | ||
1802 | azx_readl(chip, OLD_SSYNC) | sbits); | ||
1803 | else | ||
1804 | azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) | sbits); | ||
1796 | } | 1805 | } |
1797 | snd_pcm_group_for_each_entry(s, substream) { | 1806 | snd_pcm_group_for_each_entry(s, substream) { |
1798 | if (s->pcm->card != substream->pcm->card) | 1807 | if (s->pcm->card != substream->pcm->card) |
@@ -1848,7 +1857,11 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
1848 | if (nsync > 1) { | 1857 | if (nsync > 1) { |
1849 | spin_lock(&chip->reg_lock); | 1858 | spin_lock(&chip->reg_lock); |
1850 | /* reset SYNC bits */ | 1859 | /* reset SYNC bits */ |
1851 | azx_writel(chip, SYNC, azx_readl(chip, SYNC) & ~sbits); | 1860 | if (chip->driver_caps & AZX_DCAPS_OLD_SSYNC) |
1861 | azx_writel(chip, OLD_SSYNC, | ||
1862 | azx_readl(chip, OLD_SSYNC) & ~sbits); | ||
1863 | else | ||
1864 | azx_writel(chip, SSYNC, azx_readl(chip, SSYNC) & ~sbits); | ||
1852 | spin_unlock(&chip->reg_lock); | 1865 | spin_unlock(&chip->reg_lock); |
1853 | } | 1866 | } |
1854 | return 0; | 1867 | return 0; |
@@ -1863,7 +1876,7 @@ static unsigned int azx_via_get_position(struct azx *chip, | |||
1863 | unsigned int fifo_size; | 1876 | unsigned int fifo_size; |
1864 | 1877 | ||
1865 | link_pos = azx_sd_readl(azx_dev, SD_LPIB); | 1878 | link_pos = azx_sd_readl(azx_dev, SD_LPIB); |
1866 | if (azx_dev->index >= 4) { | 1879 | if (azx_dev->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
1867 | /* Playback, no problem using link position */ | 1880 | /* Playback, no problem using link position */ |
1868 | return link_pos; | 1881 | return link_pos; |
1869 | } | 1882 | } |
@@ -1927,6 +1940,17 @@ static unsigned int azx_get_position(struct azx *chip, | |||
1927 | default: | 1940 | default: |
1928 | /* use the position buffer */ | 1941 | /* use the position buffer */ |
1929 | pos = le32_to_cpu(*azx_dev->posbuf); | 1942 | pos = le32_to_cpu(*azx_dev->posbuf); |
1943 | if (chip->position_fix[stream] == POS_FIX_AUTO) { | ||
1944 | if (!pos || pos == (u32)-1) { | ||
1945 | printk(KERN_WARNING | ||
1946 | "hda-intel: Invalid position buffer, " | ||
1947 | "using LPIB read method instead.\n"); | ||
1948 | chip->position_fix[stream] = POS_FIX_LPIB; | ||
1949 | pos = azx_sd_readl(azx_dev, SD_LPIB); | ||
1950 | } else | ||
1951 | chip->position_fix[stream] = POS_FIX_POSBUF; | ||
1952 | } | ||
1953 | break; | ||
1930 | } | 1954 | } |
1931 | 1955 | ||
1932 | if (pos >= azx_dev->bufsize) | 1956 | if (pos >= azx_dev->bufsize) |
@@ -1964,16 +1988,6 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) | |||
1964 | 1988 | ||
1965 | stream = azx_dev->substream->stream; | 1989 | stream = azx_dev->substream->stream; |
1966 | pos = azx_get_position(chip, azx_dev); | 1990 | pos = azx_get_position(chip, azx_dev); |
1967 | if (chip->position_fix[stream] == POS_FIX_AUTO) { | ||
1968 | if (!pos) { | ||
1969 | printk(KERN_WARNING | ||
1970 | "hda-intel: Invalid position buffer, " | ||
1971 | "using LPIB read method instead.\n"); | ||
1972 | chip->position_fix[stream] = POS_FIX_LPIB; | ||
1973 | pos = azx_get_position(chip, azx_dev); | ||
1974 | } else | ||
1975 | chip->position_fix[stream] = POS_FIX_POSBUF; | ||
1976 | } | ||
1977 | 1991 | ||
1978 | if (WARN_ONCE(!azx_dev->period_bytes, | 1992 | if (WARN_ONCE(!azx_dev->period_bytes, |
1979 | "hda-intel: zero azx_dev->period_bytes")) | 1993 | "hda-intel: zero azx_dev->period_bytes")) |
@@ -2061,6 +2075,8 @@ static void azx_pcm_free(struct snd_pcm *pcm) | |||
2061 | } | 2075 | } |
2062 | } | 2076 | } |
2063 | 2077 | ||
2078 | #define MAX_PREALLOC_SIZE (32 * 1024 * 1024) | ||
2079 | |||
2064 | static int | 2080 | static int |
2065 | azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, | 2081 | azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, |
2066 | struct hda_pcm *cpcm) | 2082 | struct hda_pcm *cpcm) |
@@ -2069,6 +2085,7 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, | |||
2069 | struct snd_pcm *pcm; | 2085 | struct snd_pcm *pcm; |
2070 | struct azx_pcm *apcm; | 2086 | struct azx_pcm *apcm; |
2071 | int pcm_dev = cpcm->device; | 2087 | int pcm_dev = cpcm->device; |
2088 | unsigned int size; | ||
2072 | int s, err; | 2089 | int s, err; |
2073 | 2090 | ||
2074 | if (pcm_dev >= HDA_MAX_PCMS) { | 2091 | if (pcm_dev >= HDA_MAX_PCMS) { |
@@ -2104,9 +2121,12 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, | |||
2104 | snd_pcm_set_ops(pcm, s, &azx_pcm_ops); | 2121 | snd_pcm_set_ops(pcm, s, &azx_pcm_ops); |
2105 | } | 2122 | } |
2106 | /* buffer pre-allocation */ | 2123 | /* buffer pre-allocation */ |
2124 | size = CONFIG_SND_HDA_PREALLOC_SIZE * 1024; | ||
2125 | if (size > MAX_PREALLOC_SIZE) | ||
2126 | size = MAX_PREALLOC_SIZE; | ||
2107 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, | 2127 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, |
2108 | snd_dma_pci_data(chip->pci), | 2128 | snd_dma_pci_data(chip->pci), |
2109 | 1024 * 64, 32 * 1024 * 1024); | 2129 | size, MAX_PREALLOC_SIZE); |
2110 | return 0; | 2130 | return 0; |
2111 | } | 2131 | } |
2112 | 2132 | ||
@@ -2347,28 +2367,20 @@ static int azx_dev_free(struct snd_device *device) | |||
2347 | * white/black-listing for position_fix | 2367 | * white/black-listing for position_fix |
2348 | */ | 2368 | */ |
2349 | static struct snd_pci_quirk position_fix_list[] __devinitdata = { | 2369 | static struct snd_pci_quirk position_fix_list[] __devinitdata = { |
2350 | SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB), | ||
2351 | SND_PCI_QUIRK(0x1025, 0x026f, "Acer Aspire 5538", POS_FIX_LPIB), | ||
2352 | SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), | 2370 | SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), |
2353 | SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), | 2371 | SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), |
2354 | SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), | ||
2355 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell Inspiron 1120", POS_FIX_LPIB), | ||
2356 | SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), | 2372 | SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), |
2357 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), | 2373 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), |
2358 | SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), | 2374 | SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), |
2359 | SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB), | 2375 | SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB), |
2360 | SND_PCI_QUIRK(0x1043, 0x8410, "ASUS", POS_FIX_LPIB), | ||
2361 | SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), | 2376 | SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), |
2362 | SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), | 2377 | SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), |
2363 | SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba A100-259", POS_FIX_LPIB), | ||
2364 | SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB), | 2378 | SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB), |
2365 | SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), | 2379 | SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), |
2366 | SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), | 2380 | SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), |
2367 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB), | ||
2368 | SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB), | 2381 | SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB), |
2369 | SND_PCI_QUIRK(0x1849, 0x0888, "775Dual-VSTA", POS_FIX_LPIB), | 2382 | SND_PCI_QUIRK(0x1849, 0x0888, "775Dual-VSTA", POS_FIX_LPIB), |
2370 | SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB), | 2383 | SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB), |
2371 | SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB), | ||
2372 | {} | 2384 | {} |
2373 | }; | 2385 | }; |
2374 | 2386 | ||
@@ -2815,6 +2827,22 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
2815 | /* SCH */ | 2827 | /* SCH */ |
2816 | { PCI_DEVICE(0x8086, 0x811b), | 2828 | { PCI_DEVICE(0x8086, 0x811b), |
2817 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP }, | 2829 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP }, |
2830 | { PCI_DEVICE(0x8086, 0x2668), | ||
2831 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH6 */ | ||
2832 | { PCI_DEVICE(0x8086, 0x27d8), | ||
2833 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH7 */ | ||
2834 | { PCI_DEVICE(0x8086, 0x269a), | ||
2835 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ESB2 */ | ||
2836 | { PCI_DEVICE(0x8086, 0x284b), | ||
2837 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH8 */ | ||
2838 | { PCI_DEVICE(0x8086, 0x293e), | ||
2839 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH9 */ | ||
2840 | { PCI_DEVICE(0x8086, 0x293f), | ||
2841 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH9 */ | ||
2842 | { PCI_DEVICE(0x8086, 0x3a3e), | ||
2843 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH10 */ | ||
2844 | { PCI_DEVICE(0x8086, 0x3a6e), | ||
2845 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC }, /* ICH10 */ | ||
2818 | /* Generic Intel */ | 2846 | /* Generic Intel */ |
2819 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), | 2847 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), |
2820 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 2848 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |