*** ad1848.c.orig	Thu Nov 14 05:14:52 1996
--- ad1848.c	Sat Apr  3 01:18:16 1999
***************
*** 48,53 ****
--- 48,55 ----
  #define IMODE_INIT		3
  #define IMODE_MIDI		4
  
+ #define WSN
+ 
  typedef struct
    {
      int             base;
***************
*** 109,120 ****
  static void     ad1848_reset (int dev);
  static void     ad1848_halt (int dev);
  
  static int
  ad_read (ad1848_info * devc, int reg)
  {
    unsigned long   flags;
    int             x;
!   int             timeout = 100;
  
    while (timeout > 0 && INB (devc->base) == 0x80)	/*Are we initializing */
      timeout--;
--- 111,128 ----
  static void     ad1848_reset (int dev);
  static void     ad1848_halt (int dev);
  
+ #ifdef WSN
+ static int      wsn_init(void);
+ 
+ static int 	wsn_chk_io = 0x51e1;
+ #endif
+ 
  static int
  ad_read (ad1848_info * devc, int reg)
  {
    unsigned long   flags;
    int             x;
!   int             timeout = 10000;
  
    while (timeout > 0 && INB (devc->base) == 0x80)	/*Are we initializing */
      timeout--;
***************
*** 132,138 ****
  ad_write (ad1848_info * devc, int reg, int data)
  {
    unsigned long   flags;
!   int             timeout = 100;
  
    while (timeout > 0 && INB (devc->base) == 0x80)	/*Are we initializing */
      timeout--;
--- 140,146 ----
  ad_write (ad1848_info * devc, int reg, int data)
  {
    unsigned long   flags;
!   int             timeout = 10000;
  
    while (timeout > 0 && INB (devc->base) == 0x80)	/*Are we initializing */
      timeout--;
***************
*** 509,515 ****
    ad1848_info    *devc = NULL;
    unsigned long   flags;
  
!   DEB (printk ("ad1848_open(int mode = %X)\n", mode));
  
    if (dev < 0 || dev >= num_audiodevs)
      return RET_ERROR (ENXIO);
--- 517,523 ----
    ad1848_info    *devc = NULL;
    unsigned long   flags;
  
!   DEB (printk ("ad1848_open(int mode = %x)\n", mode));
  
    if (dev < 0 || dev >= num_audiodevs)
      return RET_ERROR (ENXIO);
***************
*** 525,530 ****
--- 533,539 ----
      }
  
    if (devc->irq)		/* Not managed by another driver */
+     {
      if ((err = snd_set_irq_handler (devc->irq, ad1848_interrupt,
  				    audio_devs[dev]->name)) < 0)
        {
***************
*** 532,537 ****
--- 541,547 ----
  	RESTORE_INTR (flags);
  	return err;
        }
+     }
  
    if (DMAbuf_open_dma (dev) < 0)
      {
***************
*** 813,819 ****
    ad_write (devc, 15, (unsigned char) (cnt & 0xff));
    ad_write (devc, 14, (unsigned char) ((cnt >> 8) & 0xff));
  
!   ad_write (devc, 9, 0x0d);	/*
  				 * Playback enable, single DMA channel mode,
  				 * auto calibration on.
  				 */
--- 823,829 ----
    ad_write (devc, 15, (unsigned char) (cnt & 0xff));
    ad_write (devc, 14, (unsigned char) ((cnt >> 8) & 0xff));
  
!   ad_write (devc, 9, ad_read(devc, 9) | 0x0d);	/*
  				 * Playback enable, single DMA channel mode,
  				 * auto calibration on.
  				 */
***************
*** 829,834 ****
--- 839,845 ----
    devc->intr_active = 1;
    INB (io_Status (devc));
    OUTB (0, io_Status (devc));	/* Clear pending interrupts */
+ 
    RESTORE_INTR (flags);
  }
  
***************
*** 877,883 ****
    ad_write (devc, count_reg + 1, (unsigned char) (cnt & 0xff));
    ad_write (devc, count_reg, (unsigned char) ((cnt >> 8) & 0xff));
  
!   ad_write (devc, 9, 0x0e);	/*
  				 * Capture enable, single DMA channel mode,
  				 * auto calibration on.
  				 */
--- 888,894 ----
    ad_write (devc, count_reg + 1, (unsigned char) (cnt & 0xff));
    ad_write (devc, count_reg, (unsigned char) ((cnt >> 8) & 0xff));
  
!   ad_write (devc, 9, ad_read(devc, 9) | 0x0e);	/*
  				 * Capture enable, single DMA channel mode,
  				 * auto calibration on.
  				 */
***************
*** 915,921 ****
    /*
     * Write to I8 starts resyncronization. Wait until it completes.
     */
!   timeout = 10000;
  #ifdef PC98
    while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80)
  #else
--- 926,932 ----
    /*
     * Write to I8 starts resyncronization. Wait until it completes.
     */
!   timeout = 100000;
  #ifdef PC98
    while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80)
  #else
***************
*** 928,934 ****
    /*
     * Write to I8 starts resyncronization. Wait until it completes.
     */
!   timeout = 10000;
    while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80)
      timeout--;
  #endif
--- 939,945 ----
    /*
     * Write to I8 starts resyncronization. Wait until it completes.
     */
!   timeout = 100000;
    while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80)
      timeout--;
  #endif
***************
*** 938,949 ****
     */
    if (devc->mode == 2)
      {
!       ad_write (devc, 28, fs);
  
        /*
           * Write to I28 starts resyncronization. Wait until it completes.
         */
!       timeout = 10000;
  #ifdef PC98
        while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80)
  #else
--- 949,960 ----
     */
    if (devc->mode == 2)
      {
!       ad_write (devc, 28, fs & 0xf0);
  
        /*
           * Write to I28 starts resyncronization. Wait until it completes.
         */
!       timeout = 100000;
  #ifdef PC98
        while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80)
  #else
***************
*** 954,965 ****
      }
  
  #ifdef PC98
!       ad_write (devc, 28, fs);
  
        /*
           * Write to I28 starts resyncronization. Wait until it completes.
         */
!       timeout = 10000;
        while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80)
  	timeout--;
  #endif
--- 965,976 ----
      }
  
  #ifdef PC98
!       ad_write (devc, 28, fs & 0xf0);
  
        /*
           * Write to I28 starts resyncronization. Wait until it completes.
         */
!       timeout = 100000;
        while (timeout > 0 && (INB (devc->base) & 0x80) == 0x80)
  	timeout--;
  #endif
***************
*** 1054,1059 ****
--- 1065,1071 ----
        return 0;
      }
  
+ 
    /*
       * Test if it's possible to change contents of the indirect registers.
       * Registers 0 and 1 are ADC volume registers. The bit 0x10 is read only
***************
*** 1187,1193 ****
    static int      init_values[] =
    {
      0xa8, 0xa8, 0x08, 0x08, 0x08, 0x08, 0x80, 0x80,
!     0x00, 0x08, 0x02, 0x00, 0x8a, 0x01, 0x00, 0x00,
  
    /* Positions 16 to 31 just for CS4231 */
      0x80, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
--- 1199,1205 ----
    static int      init_values[] =
    {
      0xa8, 0xa8, 0x08, 0x08, 0x08, 0x08, 0x80, 0x80,
!     0x00, 0x0c, 0x02, 0x00, 0x8a, 0x01, 0x00, 0x00,
  
    /* Positions 16 to 31 just for CS4231 */
      0x80, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,
***************
*** 1416,1421 ****
--- 1428,1437 ----
    InitAEDSP16_MSS (hw_config);
  #endif
  
+ #ifdef WSN
+   wsn_init();
+ #endif
+ 
    /*
       * Check if the IO port returns valid signature. The original MS Sound
       * system returns 0x04 while some cards (AudioTriX Pro for example)
***************
*** 1432,1437 ****
--- 1449,1455 ----
      mad16init (hw_config->io_base);
  #endif
  
+ #ifndef WSN
    if ((INB (hw_config->io_base + 3) & 0x3f) != 0x04 &&
        (INB (hw_config->io_base + 3) & 0x3f) != 0x00)
      {
***************
*** 1439,1444 ****
--- 1460,1466 ----
  		   hw_config->io_base, INB (hw_config->io_base + 3)));
        return 0;
      }
+ #endif
  
  #ifdef PC98
    if (hw_config->irq > 12)
***************
*** 1460,1465 ****
--- 1482,1488 ----
       * Check that DMA0 is not in use with a 8 bit board.
     */
  
+ #ifndef WSN
    if (hw_config->dma == 0 && INB (hw_config->io_base + 3) & 0x80)
      {
        printk ("MSS: Can't use DMA0 with a 8 bit card/slot\n");
***************
*** 1471,1476 ****
--- 1494,1500 ----
        printk ("MSS: Can't use IRQ%d with a 8 bit card/slot\n", hw_config->irq);
        return 0;
      }
+ #endif
  
    return ad1848_detect (hw_config->io_base + 4);
  }
***************
*** 1481,1487 ****
--- 1505,1515 ----
  #ifdef PC98
    static char     interrupt_bits[13] =
    {
+ #ifdef WSN
+     -1, -1, -1, 0x08, -1, 0x10, -1, -1, -1, -1, -1, -1, 0x20
+ #else
      -1, -1, -1, 0x08, -1, 0x10, -1, -1, -1, -1, 0x18, -1, 0x20
+ #endif
    };
  #else
    static char     interrupt_bits[12] =
***************
*** 1509,1519 ****
--- 1537,1555 ----
    if (bits == -1)
      return mem_start;
  
+ #ifdef WSN
+   if ( hw_config->irq == 12 ) {
+ 	/* WSN FM INT DISABLE */
+ 	OUTB(INB(wsn_chk_io - 1) | 0x02, wsn_chk_io - 1);
+   }
+ #endif
+   
    OUTB (bits | 0x40, config_port);
    if ((INB (version_port) & 0x40) == 0)
      printk ("[IRQ Conflict?]");
  
    OUTB (bits | dma_bits[hw_config->dma], config_port);	/* Write IRQ+DMA setup */
+   printk("%x=%x %x=%x\n",config_port,INB(config_port),version_port,INB(version_port));
  
    ad1848_init ("MS Sound System", hw_config->io_base + 4,
  	       hw_config->irq,
***************
*** 1521,1525 ****
--- 1557,1604 ----
  	       hw_config->dma);
    return mem_start;
  }
+ 
+ #ifdef WSN
+ static int
+ wsn_init(void)
+ {
+ 	unsigned char bits;
+ 	int i;
+ 
+ 	/* check wsn board */
+ 	for (i=0; i<8; i+=2) {
+ 		bits = INB(wsn_chk_io);
+ 		if ( bits == 0xc2 ) break;
+ 		wsn_chk_io+=2;
+ 	}
+ 	if ( bits != 0xc2 ) return 0;
+ 
+ 	/* WSN Mode */
+ 	bits = INB(wsn_chk_io + 0x500);
+ 	bits &= 0xae;
+ 	bits |= 0x51;
+ 	OUTB(bits, wsn_chk_io + 0x500);
+ 
+ 	/* WSN SYS ENABLE */ 
+ 	bits = INB(wsn_chk_io + 0x600);
+ 	bits &= 0xdf;
+ 	bits |= 0x50;
+ 	OUTB(bits, wsn_chk_io + 0x600);
+ 
+ 	/* WSN PCM ENABLE */
+ 	bits = INB(wsn_chk_io + 0xa00);
+ 	bits &= 0xf9;
+ 	bits |= 0x02;
+ 	OUTB(bits, wsn_chk_io + 0xa00);
+ 
+ 	/* WSN FM INT ENABLE */
+ 	bits = INB(wsn_chk_io - 1);
+ 	bits &= 0xfd;
+ 	OUTB(bits, wsn_chk_io - 1);
+ 
+ 	return 1;
+ 	
+ }
+ #endif 	/* WSN */
  
  #endif
