Beispiel #1
0
PUBLIC int drv_reset(void) {
	int i;
	Dprint(("drv_reset():\n"));

	sb16_outb(DSP_RESET, 1);
	for(i = 0; i < 1000; i++); /* wait a while */
	sb16_outb(DSP_RESET, 0);

	for(i = 0; i < 1000 && !(sb16_inb(DSP_DATA_AVL) & 0x80); i++); 	
	
	if(sb16_inb(DSP_READ) != 0xAA) return EIO; /* No SoundBlaster */

	return OK;
}
Beispiel #2
0
/*===========================================================================*
 *				dsp_reset
 *===========================================================================*/
PRIVATE int dsp_reset()
{
	int i;

	sb16_outb(DSP_RESET, 1);
	for(i = 0; i < 1000; i++); /* wait a while */
	sb16_outb(DSP_RESET, 0);

	for(i = 0; i < 1000 && !(sb16_inb(DSP_DATA_AVL) & 0x80); i++); 	
	
	if(sb16_inb(DSP_READ) != 0xAA) return EIO; /* No SoundBlaster */

	DmaBusy = -1;

	return OK;
}
Beispiel #3
0
/*=========================================================================*
 *				mixer_get				  
 *=========================================================================*/
PRIVATE int mixer_get(int reg)
{
	int i;

	sb16_outb(MIXER_REG, reg);
	for(i = 0; i < 100; i++);
	return sb16_inb(MIXER_DATA) & 0xff;
}  
Beispiel #4
0
/*===========================================================================*
 *				dsp_init
 *===========================================================================*/
PRIVATE int dsp_init()
{
	int i, s;

	if(dsp_reset () != OK) { 
		dprint("sb16: No SoundBlaster card detected\n");
		return -1;
	}

	DspVersion[0] = DspVersion[1] = 0;
	dsp_command(DSP_GET_VERSION);	/* Get DSP version bytes */

	for(i = 1000; i; i--) {
		if(sb16_inb(DSP_DATA_AVL) & 0x80) {		
			if(DspVersion[0] == 0) {
				DspVersion[0] = sb16_inb(DSP_READ);
			} else {
				DspVersion[1] = sb16_inb(DSP_READ);
				break;
			}
		}
	}

	if(DspVersion[0] < 4) {
		dprint("sb16: No SoundBlaster 16 compatible card detected\n");
		return -1;
	} 
	
	dprint("sb16: SoundBlaster DSP version %d.%d detected\n", DspVersion[0], DspVersion[1]);

	/* set SB to use our IRQ and DMA channels */
	mixer_set(MIXER_SET_IRQ, (1 << (SB_IRQ / 2 - 1)));
	mixer_set(MIXER_SET_DMA, (1 << SB_DMA_8 | 1 << SB_DMA_16)); 

	/* register interrupt vector and enable irq */
	if ((s=sys_irqsetpolicy(SB_IRQ, IRQ_REENABLE, &irq_hook_id )) != OK)
  		panic("Couldn't set IRQ policy: %d", s);
	if ((s=sys_irqenable(&irq_hook_id)) != OK)
  		panic("Couldn't enable IRQ: %d", s);

	DspAvail = 1;
	return OK;
}
Beispiel #5
0
PUBLIC int drv_init_hw(void) {
	int i;
	int DspVersion[2];
	Dprint(("drv_init_hw():\n"));

	if(drv_reset () != OK) { 
		Dprint(("sb16: No SoundBlaster card detected\n"));
		return -1;
	}

	DspVersion[0] = DspVersion[1] = 0;
	dsp_command(DSP_GET_VERSION);	/* Get DSP version bytes */

	for(i = 1000; i; i--) {
		if(sb16_inb(DSP_DATA_AVL) & 0x80) {		
			if(DspVersion[0] == 0) {
				DspVersion[0] = sb16_inb(DSP_READ);
			} else {
				DspVersion[1] = sb16_inb(DSP_READ);
				break;
			}
		}
	}

	if(DspVersion[0] < 4) {
		Dprint(("sb16: No SoundBlaster 16 compatible card detected\n"));
		return -1;
	} 
	
	Dprint(("sb16: SoundBlaster DSP version %d.%d detected!\n", DspVersion[0], DspVersion[1]));

	/* set SB to use our IRQ and DMA channels */
	mixer_set(MIXER_SET_IRQ, (1 << (SB_IRQ / 2 - 1)));
	mixer_set(MIXER_SET_DMA, (1 << SB_DMA_8 | 1 << SB_DMA_16));

	DspFragmentSize = sub_dev[AUDIO].DmaSize / sub_dev[AUDIO].NrOfDmaFragments;

	return OK;
}
Beispiel #6
0
/*===========================================================================*
 *				dsp_command
 *===========================================================================*/
PRIVATE int dsp_command(int value)
{
	int i;

	for (i = 0; i < SB_TIMEOUT; i++) {
		if((sb16_inb(DSP_STATUS) & 0x80) == 0) {
			sb16_outb(DSP_COMMAND, value);
			return OK;
		}
	}

	dprint("sb16: SoundBlaster: DSP Command(%x) timeout\n", value);
	return -1;
}
Beispiel #7
0
/*===========================================================================*
 *				dsp_hardware_msg
 *===========================================================================*/
PRIVATE void dsp_hardware_msg()
{	
	dprint("Interrupt: ");
	if(DmaBusy >= 0) { /* Dma transfer was actually busy */
		dprint("Finished playing dma[%d]; ", DmaBusy);
		DmaBusy = (DmaBusy + 1) % DMA_NR_OF_BUFFERS;
		if(DmaBusy == DmaFillNext) { /* Dma buffer empty, stop Dma transfer */

			dsp_command((DspBits == 8 ? DSP_CMD_DMA8HALT : DSP_CMD_DMA16HALT));
			dprint("No more work...!\n");
			DmaBusy = -1;

		} else if(BufReadNext >= 0) { /* Data in second buffer, copy one fragment to Dma buffer */
			
			/* Acknowledge the interrupt on the DSP */
			sb16_inb((DspBits == 8 ? DSP_DATA_AVL : DSP_DATA16_AVL));

			memcpy(DmaPtr + DmaFillNext * DspFragmentSize, Buffer + BufReadNext * DspFragmentSize, DspFragmentSize);
			dprint("copy buf[%d] -> dma[%d]; ", BufReadNext, DmaFillNext);
			BufReadNext = (BufReadNext + 1) % DSP_NR_OF_BUFFERS;
			DmaFillNext = (DmaFillNext + 1) % DMA_NR_OF_BUFFERS;
			if(BufReadNext == BufFillNext) {
				BufReadNext = -1;
			} 
			dprint("Starting dma[%d]\n", DmaBusy);
			
			return;

		} else { /* Second buffer empty, still data in Dma buffer, continue playback */
			dprint("Starting dma[%d]\n", DmaBusy);
		}
	}

	/* Acknowledge the interrupt on the DSP */
	sb16_inb((DspBits == 8 ? DSP_DATA_AVL : DSP_DATA16_AVL));
}