*** 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