Subject: port-i386/2045: ad1848 cannot record
To: None <gnats-bugs@NetBSD.ORG>
From: jason <jason@jlbaker.async.csuohio.edu>
List: netbsd-bugs
Date: 02/07/1996 17:10:53
>Number:         2045
>Category:       port-i386
>Synopsis:       ad1848 cannot record
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    gnats-admin (GNATS administrator)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Feb  7 18:50:44 1996
>Last-Modified:
>Originator:     jason baker
>Organization:
	
>Release:        pre-1.1, but problem still in current
>Environment:
	i386 with pss soundcard
System: NetBSD jlbaker.async.csuohio.edu 1.0A NetBSD 1.0A (HASSAN) #24: Tue Feb 6 20:00:36 EST 1996 jason@jlbaker.async.csuohio.edu:/usr/src/sys/arch/i386/compile/HASSAN i386


>Description:
	The autoconfig code in pss.c will not complain when an invalid
irq >= 12 is configured for the ad1848 soundport.  The autoconfig code
in ad1848.c tries to set the auto calibration bit in the wrong
register.  This selects an invalid sample rate and prevents some of
the later register initialization from taking place, thus recording is
not possible on a card with one dma channel.
>How-To-Repeat:
	find a machine with a wss sound card and try to record with it.
>Fix:
*** ad1848.c	1996/02/06 22:04:25	1.1
--- ad1848.c	1996/02/07 21:59:48
***************
*** 118,126 ****
      0x19,		/* Left DAC output Control */
      0x19,		/* Right DAC output Control */
      			/* Clock and Data Format */
!     CLOCK_XTAL1|FMT_PCM8|AUTO_CAL_ENABLE,
      			/* Interface Config */
!     SINGLE_DMA,
      INTERRUPT_ENABLE,	/* Pin control */
      0x00,		/* Test and Init */
      0xca,		/* Misc control */
--- 118,126 ----
      0x19,		/* Left DAC output Control */
      0x19,		/* Right DAC output Control */
      			/* Clock and Data Format */
!     CLOCK_XTAL1|FMT_PCM8,
      			/* Interface Config */
!     SINGLE_DMA|AUTO_CAL_ENABLE,
      INTERRUPT_ENABLE,	/* Pin control */
      0x00,		/* Test and Init */
      0xca,		/* Misc control */
***************
*** 237,260 ****
  
  #ifdef AUDIO_DEBUG
  void
! ad1848_dump_regs(sc)
!     struct ad1848_softc *sc;
  {
!     int i;
!     u_char r;
!     
!     printf("ad1848 status=%x", inb(sc->sc_iobase+AD1848_STATUS));
!     printf(" regs: ");
!     for (i = 0; i < 16; i++) {
! 	r = ad_read(sc, i);
! 	printf("%x ", r);
      }
!     if (sc->mode == 2)
! 	    for (i = 16; i < 32; i++) {
! 		    r = ad_read(sc, i);
! 		    printf("%x ", r);
! 	    }
!     printf("\n");
  }
  #endif
  
--- 237,314 ----
  
  #ifdef AUDIO_DEBUG
  void
! ad1848_dump_regs (sc)
!      struct ad1848_softc *sc;
  {
!   u_char reg;
! 
! #define DUMP(x) if (reg & x) printf (#x ", "); else printf ("not " #x ", ")
! #define DUMP_T(x) if (reg & x) printf (#x ", ")
! #define DUMP_NIL(x) if (!(reg & x)) printf ("not " #x ", ")
! 
!   reg = inb (sc->sc_iobase + AD1848_IADDR);
!   printf ("index reg (0x%x): ", reg);
!   DUMP_T(SP_IN_INIT);
!   DUMP_T(MODE_CHANGE_ENABLE);
!   DUMP_T(TRANSFER_DISABLE);
!   printf ("\n");
!   
!   reg = inb (sc->sc_iobase + AD1848_STATUS);
!   printf ("status reg (0x%x): ", reg);
!   DUMP(INTERRUPT_STATUS);
!   DUMP(PLAYBACK_READY);
!   DUMP(SAMPLE_ERROR);
!   DUMP(CAPTURE_READY);
!   printf ("\n");
! 
!   printf ("mixer regs: ")
!   for (i=0, i < SP_CLOCK_AND_DATA_FORMAT; i++)
!     printf ("0x%x, " ad_read (sc, i));
! 
!   printf ("\nclock and data = 0x%x\n",
! 	  ad_read (sc, SP_CLOCK_AND_DATA_FORMAT));
! 
!   reg = ad_read (sc, SP_INTERFACE_CONFIG);
!   printf ("interface config (0x%x): ", reg);
!   DUMP_T(PLAYBACK_ENABLE);
!   DUMP_T(CAPTURE_ENABLE);
!   DUMP(SINGLE_DMA);
!   DUMP(AUTO_CAL_ENABLE);
!   DUMP_T(PLAYBACK_PIO_ENABLE);
!   DUMP_T(CAPTURE_PIO_ENABLE);
!   printf ("\n");
! 
!   reg = ad_read (sc, SP_PIN_CONTROL);
!   printf ("pin control (0x%x): ", reg);
!   DUMP(INTERRUPT_ENABLE);
!   printf ("\n");
! 
!   reg = ad_read (sc, SP_TEST_AND_INIT);
!   printf ("test and init (0x%x): ", reg);
!   DUMP_T(~OVERRANGE_LEFT_MASK);
!   DUMP_T(~OVERRANGE_RIGHT_MASK);
!   DUMP(DATA_REQUEST_STATUS);
!   DUMP_T(PLAYBACK_UNDERRUN);
!   DUMP_T(CAPTURE_OVERRUN);
!   printf ("\n");
! 
!   printf ("digital mix = 0x%x\n",
! 	  ad_read (sc, SP_DIGITIAL_MIX));
! 
!   reg = (ad_read (sc, SP_UPPER_BASE_COUNT) << 8)
!       + ad_read (sc, SP_LOWER_BASE_COUNT);
!   printf ("base count = 0x%x\n", reg);
! 
!   if (sc->mode == 2)
!     for (i = 16; i < 32; i++) {
!       r = ad_read(sc, i);
!       printf("%x ", r);
      }
!   printf("\n");
! 
! #undef DUMP
! #undef DUMP_T
! #undef DUMP_NIL
  }
  #endif
  
***************
*** 489,494 ****
--- 543,549 ----
  		    if (ad1848_init_values[i] != 0)
  			    ad_write(sc, i, ad1848_init_values[i]);
      }
+ 
      ad1848_reset(sc);
  
      /* Set default encoding (ULAW) */
***************
*** 1301,1314 ****
      DPRINTF(("ad1848_reset\n"));
      
      /* Clear the PEN and CEN bits */
! #if 0
      r = ad_read(sc, SP_INTERFACE_CONFIG);
      r &= ~(CAPTURE_ENABLE|PLAYBACK_ENABLE);
      ad_write(sc, SP_INTERFACE_CONFIG, r);
! #else
!     ad_write(sc, SP_INTERFACE_CONFIG, 0);
! #endif
      if (sc->mode == 2) {
  	    outb(sc->sc_iobase+AD1848_IADDR, CS_IRQ_STATUS);
  	    outb(sc->sc_iobase+AD1848_IDATA, 0);
      }
--- 1356,1370 ----
      DPRINTF(("ad1848_reset\n"));
      
      /* Clear the PEN and CEN bits */
! /*    printf ("\n");
!     ad1848_dump_regs(sc);*/
      r = ad_read(sc, SP_INTERFACE_CONFIG);
      r &= ~(CAPTURE_ENABLE|PLAYBACK_ENABLE);
      ad_write(sc, SP_INTERFACE_CONFIG, r);
! /*    ad1848_dump_regs(sc);*/
      if (sc->mode == 2) {
+       	    r = ad_read (sc, SP_INTERFACE_CONFIG);
+ 	    ad_write (sc, SP_INTERFACE_CONFIG, r & ~SINGLE_DMA);
  	    outb(sc->sc_iobase+AD1848_IADDR, CS_IRQ_STATUS);
  	    outb(sc->sc_iobase+AD1848_IDATA, 0);
      }
*** ../ic/ad1848reg.h	1996/02/06 20:35:15	1.1
--- ../ic/ad1848reg.h	1996/02/06 21:24:45
***************
*** 104,110 ****
  #define CAPTURE_READY		0x20
  #define CAPTURE_LEFT		0x40
  /* cpright is not left */
! #define CAPTURE_UPPER		0x08
  /* cplower is not upper */
  
  /* Input & Output regs bits */
--- 104,110 ----
  #define CAPTURE_READY		0x20
  #define CAPTURE_LEFT		0x40
  /* cpright is not left */
! #define CAPTURE_UPPER		0x80
  /* cplower is not upper */
  
  /* Input & Output regs bits */
*** pss.c	1995/10/07 15:47:35	1.3
--- pss.c	1996/02/04 20:00:50
***************
*** 226,235 ****
  
  
  /* Interrupt translation for WSS config */
! static u_char wss_interrupt_bits[12] = {
      0xff, 0xff, 0xff, 0xff,
      0xff, 0xff, 0xff, 0x08,
!     0xff, 0x10, 0x18, 0x20
  };
  /* ditto for WSS DMA channel */
  static u_char wss_dma_bits[4] = {1, 2, 0, 3};
--- 226,236 ----
  
  
  /* Interrupt translation for WSS config */
! static u_char wss_interrupt_bits[16] = {
      0xff, 0xff, 0xff, 0xff,
      0xff, 0xff, 0xff, 0x08,
!     0xff, 0x10, 0x18, 0x20,
!     0xff, 0xff, 0xff, 0xff
  };
  /* ditto for WSS DMA channel */
  static u_char wss_dma_bits[4] = {1, 2, 0, 3};

>Audit-Trail:
>Unformatted: