diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-16 12:10:31 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-16 12:10:31 -0700 |
commit | 661adc423d70203a56723701aaf255e16950dfdb (patch) | |
tree | 72a62c9016667cba8a63ab3f038c69df3692a085 /sound/pci/intel8x0.c | |
parent | 15bdb5652689d51cc0316de61774d2732472d9e1 (diff) | |
parent | 3b13b5ce8c1b52379aff80666d31d4354354b2d4 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6:
ALSA: ctxfi - Fix deadlock with xfi-timer
ALSA: intel8x0 - Fix PCM position craziness
ALSA: usb-audio - rework quirk for TerraTec Aureon USB 5.1 MkII
ASoC: magician: fix PXA SSP clock polarity
ASoC: Instantiate any forgotten DAPM widgets
ASoC: Revert duplicated code in SSM2602 driver
ALSA: hda - Add quirk for Acer Aspire 6935G
ALSA: ctxfi - Replace atc lock to mutex
ASoC: Remove odd bit clock ratios for WM8903
Diffstat (limited to 'sound/pci/intel8x0.c')
-rw-r--r-- | sound/pci/intel8x0.c | 24 |
1 files changed, 12 insertions, 12 deletions
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 173bebf9f51..8aa5687f392 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -356,8 +356,6 @@ struct ichdev { unsigned int position; unsigned int pos_shift; unsigned int last_pos; - unsigned long last_pos_jiffies; - unsigned int jiffy_to_bytes; int frags; int lvi; int lvi_frag; @@ -844,7 +842,6 @@ static int snd_intel8x0_pcm_trigger(struct snd_pcm_substream *substream, int cmd case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: val = ICH_IOCE | ICH_STARTBM; ichdev->last_pos = ichdev->position; - ichdev->last_pos_jiffies = jiffies; break; case SNDRV_PCM_TRIGGER_SUSPEND: ichdev->suspended = 1; @@ -1048,7 +1045,6 @@ static int snd_intel8x0_pcm_prepare(struct snd_pcm_substream *substream) ichdev->pos_shift = (runtime->sample_bits > 16) ? 2 : 1; } snd_intel8x0_setup_periods(chip, ichdev); - ichdev->jiffy_to_bytes = (runtime->rate * 4 * ichdev->pos_shift) / HZ; return 0; } @@ -1073,19 +1069,23 @@ static snd_pcm_uframes_t snd_intel8x0_pcm_pointer(struct snd_pcm_substream *subs ptr1 == igetword(chip, ichdev->reg_offset + ichdev->roff_picb)) break; } while (timeout--); + ptr = ichdev->last_pos; if (ptr1 != 0) { ptr1 <<= ichdev->pos_shift; ptr = ichdev->fragsize1 - ptr1; ptr += position; - ichdev->last_pos = ptr; - ichdev->last_pos_jiffies = jiffies; - } else { - ptr1 = jiffies - ichdev->last_pos_jiffies; - if (ptr1) - ptr1 -= 1; - ptr = ichdev->last_pos + ptr1 * ichdev->jiffy_to_bytes; - ptr %= ichdev->size; + if (ptr < ichdev->last_pos) { + unsigned int pos_base, last_base; + pos_base = position / ichdev->fragsize1; + last_base = ichdev->last_pos / ichdev->fragsize1; + /* another sanity check; ptr1 can go back to full + * before the base position is updated + */ + if (pos_base == last_base) + ptr = ichdev->last_pos; + } } + ichdev->last_pos = ptr; spin_unlock(&chip->reg_lock); if (ptr >= ichdev->size) return 0; |