linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Several problems with i810_audio driver
@ 2001-07-28  0:48 Taylan Akdogan
  0 siblings, 0 replies; only message in thread
From: Taylan Akdogan @ 2001-07-28  0:48 UTC (permalink / raw)
  To: Alan Cox; +Cc: linux-kernel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1757 bytes --]

Hello Alan,

I assumed you are the maintainer of i810_audio driver. I had
three problems with it. I think, I solved one of them. I'm
talking about integrated sound card on Intel 850GBAL motherboard.
It's a 82801BA (ICH2) based AD1881A chip.

The first problem is that it's locked to 48kHz when it's included
into the kernel. It works fine when loaded as module. This is
fine, as I can live with it as module.

The second and third problem is somewhat related. When I play
something and stop playing without closing the /dev/dsp device
(say because of heavy system load), if DAC drains during this
pause, it won't continue to play anymore. The test program is
attached, which is going to fail with 2.4.7 (it was also failing
with 2.4.2).

The reason for this, I believe, is that when it receives DCH (DMA
controller is Halted) interrupt, it doesn't change dmabuf->ready
flag. A one line patch for this fix (?) is also attached. It
needs to be checked, because I'm not sure if I should lock
anything before changing it. However, the test program, and my
real application works fine with this patch.

On the other hand, the third problem... When one try to play very
very short, say less then fragsize (I tried just 8 bytes),
sample, after such pause/drain sequence, it doesn't resume to
play. I didn't track down this problem, because it's not as
disturbing as the previous one. However, it should be noted.

Best regards,
Taylan

PS: Please CC your reply to me, because of the know reason...

---=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=---
Taylan Akdogan              Massachusetts Institute of Technology
akdogan@mit.edu                             Department of Physics
---=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=---


[-- Attachment #2: i810_audio.c patch to 2.4.7 --]
[-- Type: TEXT/PLAIN, Size: 809 bytes --]

diff -urN linux-orj/drivers/sound/i810_audio.c linux/drivers/sound/i810_audio.c
--- linux-orj/drivers/sound/i810_audio.c	Tue Jul  3 10:59:51 2001
+++ linux/drivers/sound/i810_audio.c	Fri Jul 27 20:10:33 2001
@@ -109,6 +109,7 @@
 
 //#define DEBUG
 //#define DEBUG2
+//#define DEBUG_INTERRUPTS
 
 #define ADC_RUNNING	1
 #define DAC_RUNNING	2
@@ -983,7 +984,7 @@
 		{
 			i810_update_ptr(state);
 #ifdef DEBUG_INTERRUPTS
-			printk("COMP%d ",x);
+			printk("COMP ");
 #endif
 		}
 		if(status & DMA_INT_LVI)
@@ -1005,6 +1006,9 @@
 				outb(inb(port+OFF_CR) | 1, port+OFF_CR);
 			} else {
 				wake_up(&dmabuf->wait);
+				// When DCH (DMA Controller is Halted)
+				// It's not ready anymore!!!
+				dmabuf->ready = 0;
 #ifdef DEBUG_INTERRUPTS
 				printk("DCH - STOP ");
 #endif

[-- Attachment #3: Test program for bugs --]
[-- Type: TEXT/PLAIN, Size: 1668 bytes --]

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <math.h>
#include <sys/soundcard.h>

int main(int argn, char *arg[]) {
  int i;
  int16_t sample1[48000*2*2];
  int16_t sample2[48000*2*2];
  u_int8_t *ptr1, *ptr2;
  int ret, out, req;
  int fd;
  int tmp;

  ptr1 = (u_int8_t *)sample1;
  ptr2 = (u_int8_t *)sample2;

  fd = open("/dev/dsp", O_WRONLY | O_NONBLOCK);
  tmp=0;     ioctl(fd, SNDCTL_DSP_RESET,      &tmp);
  tmp=2;     ioctl(fd, SNDCTL_DSP_STEREO,     &tmp);
  tmp=16;    ioctl(fd, SNDCTL_DSP_SAMPLESIZE, &tmp);
  tmp=48000; ioctl(fd, SNDCTL_DSP_SPEED,      &tmp);

  usleep(500000);

  for (i=0;i<48000*2;i++) {
    sample1[i*2  ]=20000.0*sin(2.0*M_PI*440.0*((double)i)/48000.0);
    sample1[i*2+1]=20000.0*sin(2.0*M_PI*445.0*((double)i)/48000.0);
  }

  for (i=0;i<48000*2;i++) {
    sample2[i*2  ]=20000.0*sin(2.0*M_PI*660.0*((double)i)/48000.0);
    sample2[i*2+1]=20000.0*sin(2.0*M_PI*665.0*((double)i)/48000.0);
  }

  // play the first tone
  out = 0; req = 48000*2*2*2;
  while (out!=req) {
    ret = write(fd, ptr1+out, req-out);
    if (ret!=-1) out += ret;
    usleep(10);
  }
 
  // wait for dac drain 
  do ioctl(fd, SNDCTL_DSP_GETODELAY, &tmp); while (tmp>0);

  // Wait more to be certain that it's drained
  usleep(500000);

  // Try to play the second tone
  out = 0; req = 48000*2*2*2;
  while (out!=req) {
    ret = write(fd, ptr2+out, req-out);
    if (ret!=-1) out += ret;
    usleep(10);
  }

  do ioctl(fd, SNDCTL_DSP_GETODELAY, &tmp); while (tmp>0);

  usleep(500000);

  close(fd);
  return 0;
}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2001-07-28  0:47 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-07-28  0:48 Several problems with i810_audio driver Taylan Akdogan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).