aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Henningsson <david.henningsson@canonical.com>2010-09-30 04:12:50 -0400
committerTakashi Iwai <tiwai@suse.de>2010-09-30 08:16:11 -0400
commit4cb36310848fd17766aa72afd1f2873f54b4e055 (patch)
treebdd58b3ab4085de265086417d0dbcc53a31eeb45
parentc123e5e437a0e61e364c1cbad3ef9a7384975fb2 (diff)
ALSA: HDA: Add position_fix=3 module option, and refactor related code
What was previously known as via_dmapos_patch, and hard-coded to be used for VIA and ATI controllers, is now configurable through a module option. The background is that some VIA controllers seem to prefer via_dmapos_patch to be turned off. Signed-off-by: David Henningsson <david.henningsson@canonical.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--Documentation/sound/alsa/HD-Audio.txt8
-rw-r--r--sound/pci/hda/hda_intel.c41
2 files changed, 24 insertions, 25 deletions
diff --git a/Documentation/sound/alsa/HD-Audio.txt b/Documentation/sound/alsa/HD-Audio.txt
index 278cc2122ea0..c82beb007634 100644
--- a/Documentation/sound/alsa/HD-Audio.txt
+++ b/Documentation/sound/alsa/HD-Audio.txt
@@ -57,9 +57,11 @@ dead. However, this detection isn't perfect on some devices. In such
57a case, you can change the default method via `position_fix` option. 57a case, you can change the default method via `position_fix` option.
58 58
59`position_fix=1` means to use LPIB method explicitly. 59`position_fix=1` means to use LPIB method explicitly.
60`position_fix=2` means to use the position-buffer. 0 is the default 60`position_fix=2` means to use the position-buffer.
61value, the automatic check and fallback to LPIB as described in the 61`position_fix=3` means to use a combination of both methods, needed
62above. If you get a problem of repeated sounds, this option might 62for some VIA and ATI controllers. 0 is the default value for all other
63controllers, the automatic check and fallback to LPIB as described in
64the above. If you get a problem of repeated sounds, this option might
63help. 65help.
64 66
65In addition to that, every controller is known to be broken regarding 67In addition to that, every controller is known to be broken regarding
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index ec07e4700e3b..38b063eb80e9 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -78,8 +78,8 @@ MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
78module_param_array(model, charp, NULL, 0444); 78module_param_array(model, charp, NULL, 0444);
79MODULE_PARM_DESC(model, "Use the given board model."); 79MODULE_PARM_DESC(model, "Use the given board model.");
80module_param_array(position_fix, int, NULL, 0444); 80module_param_array(position_fix, int, NULL, 0444);
81MODULE_PARM_DESC(position_fix, "Fix DMA pointer " 81MODULE_PARM_DESC(position_fix, "DMA pointer read method."
82 "(0 = auto, 1 = none, 2 = POSBUF)."); 82 "(0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO).");
83module_param_array(bdl_pos_adj, int, NULL, 0644); 83module_param_array(bdl_pos_adj, int, NULL, 0644);
84MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); 84MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset.");
85module_param_array(probe_mask, int, NULL, 0444); 85module_param_array(probe_mask, int, NULL, 0444);
@@ -305,6 +305,7 @@ enum {
305 POS_FIX_AUTO, 305 POS_FIX_AUTO,
306 POS_FIX_LPIB, 306 POS_FIX_LPIB,
307 POS_FIX_POSBUF, 307 POS_FIX_POSBUF,
308 POS_FIX_VIACOMBO,
308}; 309};
309 310
310/* Defines for ATI HD Audio support in SB450 south bridge */ 311/* Defines for ATI HD Audio support in SB450 south bridge */
@@ -433,7 +434,6 @@ struct azx {
433 unsigned int polling_mode :1; 434 unsigned int polling_mode :1;
434 unsigned int msi :1; 435 unsigned int msi :1;
435 unsigned int irq_pending_warned :1; 436 unsigned int irq_pending_warned :1;
436 unsigned int via_dmapos_patch :1; /* enable DMA-position fix for VIA */
437 unsigned int probing :1; /* codec probing phase */ 437 unsigned int probing :1; /* codec probing phase */
438 438
439 /* for debugging */ 439 /* for debugging */
@@ -1309,11 +1309,8 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev)
1309 azx_sd_writel(azx_dev, SD_BDLPU, upper_32_bits(azx_dev->bdl.addr)); 1309 azx_sd_writel(azx_dev, SD_BDLPU, upper_32_bits(azx_dev->bdl.addr));
1310 1310
1311 /* enable the position buffer */ 1311 /* enable the position buffer */
1312 if (chip->position_fix[0] == POS_FIX_POSBUF || 1312 if (chip->position_fix[0] != POS_FIX_LPIB ||
1313 chip->position_fix[0] == POS_FIX_AUTO || 1313 chip->position_fix[1] != POS_FIX_LPIB) {
1314 chip->position_fix[1] == POS_FIX_POSBUF ||
1315 chip->position_fix[1] == POS_FIX_AUTO ||
1316 chip->via_dmapos_patch) {
1317 if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) 1314 if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE))
1318 azx_writel(chip, DPLBASE, 1315 azx_writel(chip, DPLBASE,
1319 (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE); 1316 (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE);
@@ -1852,20 +1849,21 @@ static unsigned int azx_get_position(struct azx *chip,
1852 struct azx_dev *azx_dev) 1849 struct azx_dev *azx_dev)
1853{ 1850{
1854 unsigned int pos; 1851 unsigned int pos;
1852 int stream = azx_dev->substream->stream;
1855 1853
1856 if (chip->via_dmapos_patch) 1854 switch (chip->position_fix[stream]) {
1855 case POS_FIX_LPIB:
1856 /* read LPIB */
1857 pos = azx_sd_readl(azx_dev, SD_LPIB);
1858 break;
1859 case POS_FIX_VIACOMBO:
1857 pos = azx_via_get_position(chip, azx_dev); 1860 pos = azx_via_get_position(chip, azx_dev);
1858 else { 1861 break;
1859 int stream = azx_dev->substream->stream; 1862 default:
1860 if (chip->position_fix[stream] == POS_FIX_POSBUF || 1863 /* use the position buffer */
1861 chip->position_fix[stream] == POS_FIX_AUTO) { 1864 pos = le32_to_cpu(*azx_dev->posbuf);
1862 /* use the position buffer */
1863 pos = le32_to_cpu(*azx_dev->posbuf);
1864 } else {
1865 /* read LPIB */
1866 pos = azx_sd_readl(azx_dev, SD_LPIB);
1867 }
1868 } 1865 }
1866
1869 if (pos >= azx_dev->bufsize) 1867 if (pos >= azx_dev->bufsize)
1870 pos = 0; 1868 pos = 0;
1871 return pos; 1869 return pos;
@@ -2313,6 +2311,7 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
2313 switch (fix) { 2311 switch (fix) {
2314 case POS_FIX_LPIB: 2312 case POS_FIX_LPIB:
2315 case POS_FIX_POSBUF: 2313 case POS_FIX_POSBUF:
2314 case POS_FIX_VIACOMBO:
2316 return fix; 2315 return fix;
2317 } 2316 }
2318 2317
@@ -2320,11 +2319,9 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
2320 switch (chip->driver_type) { 2319 switch (chip->driver_type) {
2321 case AZX_DRIVER_VIA: 2320 case AZX_DRIVER_VIA:
2322 case AZX_DRIVER_ATI: 2321 case AZX_DRIVER_ATI:
2323 chip->via_dmapos_patch = 1;
2324 /* Use link position directly, avoid any transfer problem. */ 2322 /* Use link position directly, avoid any transfer problem. */
2325 return POS_FIX_LPIB; 2323 return POS_FIX_VIACOMBO;
2326 } 2324 }
2327 chip->via_dmapos_patch = 0;
2328 2325
2329 q = snd_pci_quirk_lookup(chip->pci, position_fix_list); 2326 q = snd_pci_quirk_lookup(chip->pci, position_fix_list);
2330 if (q) { 2327 if (q) {