From mboxrd@z Thu Jan 1 00:00:00 1970 From: Takashi Iwai Subject: Re: Problems Writing a Driver for an AMD Au1000 MIPS Processor Date: Tue, 08 Jun 2004 18:03:44 +0200 Sender: alsa-devel-admin@lists.sourceforge.net Message-ID: References: <40C4A94D.3070100@rogers.com> Mime-Version: 1.0 (generated by SEMI 1.14.5 - "Awara-Onsen") Content-Type: text/plain; charset=US-ASCII Return-path: In-Reply-To: <40C4A94D.3070100@rogers.com> Errors-To: alsa-devel-admin@lists.sourceforge.net List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , List-Archive: To: charles.eidsness@rogers.com Cc: alsa-devel@lists.sourceforge.net List-Id: alsa-devel@alsa-project.org At Mon, 07 Jun 2004 13:43:41 -0400, Charles Eidsness wrote: > > I've been trying to write an ALSA driver for the AC97 port on an > embedded AMD au1000 MIPS processor but am having some difficulties. The > processor's DMA controller has two buffers which automatically toggle > back and forth once the buffer is full. My problem is that when I > playback a wave file (just using cat xxx > /dev/dsp) it sounds choppy if > I run the spin_unlock_irqrestore on every interrupt, it's only playing > back half the data. But if I run the spin_unlock_irqrestore function on > every-other interrupt and have only two periods it sounds fine. I'm > guessing I'm handling the streaming interface with the ALSA API incorrectly. just taking a quick look, at least i found that the pointer callback returns the wrong value. static snd_pcm_uframes_t snd_au1000_pointer(snd_pcm_substream_t * substream) { audio_stream_t *stream = substream->private_data; snd_pcm_runtime_t *runtime = substream->runtime; unsigned long location, flags; spin_lock_irqsave(&stream->dma_lock, flags); location = get_dma_residue(stream->dma); spin_unlock_irqrestore(&stream->dma_lock, flags); location = stream->dma_size - location; return bytes_to_frames(runtime,location); } this returns the point in the current period. the pointer callback must return the current position in the whole DMA buffer. thus, you'll need to track the current DMA position (remembering e.g. stream->cur_period), and increment it in interrupt. Then adds this offset in the above pointer callback. Takashi ------------------------------------------------------- This SF.Net email is sponsored by: GNOME Foundation Hackers Unite! GUADEC: The world's #1 Open Source Desktop Event. GNOME Users and Developers European Conference, 28-30th June in Norway http://2004/guadec.org