diff options
author | David Henningsson <david.henningsson@canonical.com> | 2010-09-30 04:12:50 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-09-30 08:16:11 -0400 |
commit | 4cb36310848fd17766aa72afd1f2873f54b4e055 (patch) | |
tree | bdd58b3ab4085de265086417d0dbcc53a31eeb45 | |
parent | c123e5e437a0e61e364c1cbad3ef9a7384975fb2 (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.txt | 8 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 41 |
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 | |||
57 | a case, you can change the default method via `position_fix` option. | 57 | a 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. |
61 | value, the automatic check and fallback to LPIB as described in the | 61 | `position_fix=3` means to use a combination of both methods, needed |
62 | above. If you get a problem of repeated sounds, this option might | 62 | for some VIA and ATI controllers. 0 is the default value for all other |
63 | controllers, the automatic check and fallback to LPIB as described in | ||
64 | the above. If you get a problem of repeated sounds, this option might | ||
63 | help. | 65 | help. |
64 | 66 | ||
65 | In addition to that, every controller is known to be broken regarding | 67 | In 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."); | |||
78 | module_param_array(model, charp, NULL, 0444); | 78 | module_param_array(model, charp, NULL, 0444); |
79 | MODULE_PARM_DESC(model, "Use the given board model."); | 79 | MODULE_PARM_DESC(model, "Use the given board model."); |
80 | module_param_array(position_fix, int, NULL, 0444); | 80 | module_param_array(position_fix, int, NULL, 0444); |
81 | MODULE_PARM_DESC(position_fix, "Fix DMA pointer " | 81 | MODULE_PARM_DESC(position_fix, "DMA pointer read method." |
82 | "(0 = auto, 1 = none, 2 = POSBUF)."); | 82 | "(0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO)."); |
83 | module_param_array(bdl_pos_adj, int, NULL, 0644); | 83 | module_param_array(bdl_pos_adj, int, NULL, 0644); |
84 | MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); | 84 | MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); |
85 | module_param_array(probe_mask, int, NULL, 0444); | 85 | module_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) { |