⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sb_dsp.c

📁 LINUX1.0内核源代码,学习LINUX编程的一定要看。
💻 C
📖 第 1 页 / 共 2 页
字号:
    dsp_speaker (OFF);  sb_irq_mode = IMODE_INPUT;  DMAbuf_start_dma (dev, buf, count, DMA_MODE_READ);  if (sound_dsp_dmachan[dev] > 3)    count >>= 1;  count--;  if (sb_dsp_highspeed)    {      DISABLE_INTR (flags);      if (sb_dsp_command (0x48))	/* High speed size */	{	  sb_dsp_command ((unsigned char)(count & 0xff));	  sb_dsp_command ((unsigned char)((count >> 8) & 0xff));	  sb_dsp_command (0x99);	/* High speed 8 bit ADC */	}      else	printk ("SB Error: Unable to start (high speed) ADC\n");      RESTORE_INTR (flags);    }  else    {      DISABLE_INTR (flags);      if (sb_dsp_command (0x24))	/* 8-bit ADC (DMA) */	{	  sb_dsp_command ((unsigned char)(count & 0xff));	  sb_dsp_command ((unsigned char)((count >> 8) & 0xff));	}      else	printk ("SB Error: Unable to start ADC\n");      RESTORE_INTR (flags);    }  sb_intr_active = 1;}static voiddsp_cleanup (void){  sb_intr_active = 0;}static intsb_dsp_prepare_for_input (int dev, int bsize, int bcount){  dsp_cleanup ();  dsp_speaker (OFF);  if (major == 3)	/* SB Pro */  {    if (dsp_stereo)       sb_dsp_command(0xa8);    else       sb_dsp_command(0xa0);    dsp_speed (dsp_current_speed);/* Speed must be recalculated if #channels				   * changes */  }  return 0;}static intsb_dsp_prepare_for_output (int dev, int bsize, int bcount){  dsp_cleanup ();  dsp_speaker (ON);#ifndef EXCLUDE_SBPRO  if (major == 3)	/* SB Pro */  {    sb_mixer_set_stereo(dsp_stereo);    dsp_speed (dsp_current_speed);/* Speed must be recalculated if #channels				   * changes */  }#endif  return 0;}static voidsb_dsp_halt_xfer (int dev){}static intverify_irq (void){#if 0  DEFINE_WAIT_QUEUE(testq, testf);  irq_ok = 0;  if (sb_get_irq () == -1)    {      printk ("*** SB Error: Irq %d already in use\n", sbc_irq);      return 0;    }  sb_irq_mode = IMODE_INIT;  sb_dsp_command (0xf2);		/* This should cause immediate interrupt */  DO_SLEEP(testq, testf, HZ / 5);  sb_free_irq();  if (!irq_ok)    {      printk ("SB Warning: IRQ%d test not passed!", sbc_irq);      irq_ok = 1;    }#else  irq_ok = 1;#endif  return irq_ok;}static intsb_dsp_open (int dev, int mode){  int             retval;  if (!sb_dsp_ok)    {      printk ("SB Error: SoundBlaster board not installed\n");      return RET_ERROR (ENXIO);    }  if (sb_intr_active || (sb_midi_busy && sb_midi_mode == UART_MIDI))    {      printk ("SB: PCM not possible during MIDI input\n");      return RET_ERROR (EBUSY);    }  if (!irq_verified)    {  	verify_irq();  	irq_verified = 1;    }  else    if (!irq_ok)       printk("SB Warning: Incorrect IRQ setting %d\n",  	      sbc_irq);  retval = sb_get_irq ();  if (retval)    return retval;  if (!DMAbuf_open_dma (dev))    {      sb_free_irq ();      printk ("SB: DMA Busy\n");      return RET_ERROR (EBUSY);    }  sb_irq_mode = IMODE_NONE;  sb_dsp_busy = 1;  return 0;}static voidsb_dsp_close (int dev){  DMAbuf_close_dma (dev);  sb_free_irq ();  dsp_cleanup ();  dsp_speaker (OFF);  sb_dsp_busy = 0;  sb_dsp_highspeed = 0;}static intsb_dsp_ioctl (int dev, unsigned int cmd, unsigned int arg, int local){  switch (cmd)    {    case SOUND_PCM_WRITE_RATE:      if (local)	return dsp_speed (arg);      return IOCTL_OUT (arg, dsp_speed (IOCTL_IN (arg)));      break;    case SOUND_PCM_READ_RATE:      if (local)	return dsp_current_speed;      return IOCTL_OUT (arg, dsp_current_speed);      break;    case SOUND_PCM_WRITE_CHANNELS:      if (local)         return dsp_set_stereo (arg - 1) + 1;      return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg) - 1) + 1);      break;    case SOUND_PCM_READ_CHANNELS:      if (local)	return dsp_stereo + 1;      return IOCTL_OUT (arg, dsp_stereo + 1);      break;    case SNDCTL_DSP_STEREO:      if (local)	return dsp_set_stereo (arg);      return IOCTL_OUT (arg, dsp_set_stereo (IOCTL_IN (arg)));      break;    case SOUND_PCM_WRITE_BITS:    case SOUND_PCM_READ_BITS:      if (local)	return 8;      return IOCTL_OUT (arg, 8);/* Only 8 bits/sample supported */      break;    case SOUND_PCM_WRITE_FILTER:    case SOUND_PCM_READ_FILTER:      return RET_ERROR (EINVAL);      break;    default:      return RET_ERROR (EINVAL);    }  return RET_ERROR (EINVAL);}static voidsb_dsp_reset (int dev){  unsigned long   flags;  DISABLE_INTR (flags);  sb_reset_dsp ();  dsp_cleanup ();  RESTORE_INTR (flags);}#endifintsb_dsp_detect (struct address_info *hw_config){  sbc_base = hw_config->io_base;  sbc_irq = hw_config->irq;  if (sb_dsp_ok)    return 0;			/* Already initialized */  if (!sb_reset_dsp ())    return 0;  return 1;			/* Detected */}#ifndef EXCLUDE_AUDIOstatic struct audio_operations sb_dsp_operations ={  "SoundBlaster",  sb_dsp_open,  sb_dsp_close,  sb_dsp_output_block,  sb_dsp_start_input,  sb_dsp_ioctl,  sb_dsp_prepare_for_input,  sb_dsp_prepare_for_output,  sb_dsp_reset,  sb_dsp_halt_xfer,  NULL,				/* has_output_drained */  NULL				/* copy_from_user */};#endiflongsb_dsp_init (long mem_start, struct address_info *hw_config){  int             i;  major = minor = 0;  sb_dsp_command (0xe1);		/* Get version */  for (i = 1000; i; i--)    {      if (INB (DSP_DATA_AVAIL) & 0x80)	{			/* wait for Data Ready */	  if (major == 0)	    major = INB (DSP_READ);	  else	    {	      minor = INB (DSP_READ);	      break;	    }	}    }      if (major == 2 || major == 3)	sb_duplex_midi = 1;      if (major == 4)	sb16 = 1;      if (major >= 3)	sb_dsp_model = 2;#ifndef EXCLUDE_SBPRO      if (major >= 3)         sb_mixer_init(major);#endif#ifndef EXCLUDE_YM3812      if (major > 3 || (major == 3 && minor > 0))	/* SB Pro2 or later */	{	  enable_opl3_mode (OPL3_LEFT, OPL3_RIGHT, OPL3_BOTH);	}#endif    if (major >= 3)      {#ifndef SCO      	sprintf (sb_dsp_operations.name, "SoundBlaster Pro %d.%d", major, minor);#endif      }    else      {#ifndef SCO    	sprintf (sb_dsp_operations.name, "SoundBlaster %d.%d", major, minor);#endif      }  printk (" <%s>", sb_dsp_operations.name);#ifndef EXCLUDE_AUDIO#  if !defined(EXCLUDE_SB16) && !defined(EXCLUDE_SBPRO)  if (!sb16)	/* There is a better driver for SB16	*/#  endif  if (num_dspdevs < MAX_DSP_DEV)    {      dsp_devs[my_dev = num_dspdevs++] = &sb_dsp_operations;      sound_buffcounts[my_dev] = DSP_BUFFCOUNT;      sound_buffsizes[my_dev] = DSP_BUFFSIZE;      sound_dsp_dmachan[my_dev] = hw_config->dma;      sound_dma_automode[my_dev] = 0;    }  else    printk ("SB: Too many DSP devices available\n");#endif#ifndef EXCLUDE_MIDI  if (!midi_disabled && !sb16)	/* Midi don't work in the SB emulation mode				 * of PAS, SB16 has better midi interface */	sb_midi_init(major);#endif  sb_dsp_ok = 1;  return mem_start;}voidsb_dsp_disable_midi (void){  midi_disabled = 1;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -