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

📄 soundcard.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  int             i;  if (connect_wrapper (WRAPPER_VERSION) < 0)    {      printk ("Sound: Incompatible kernel (wrapper) version\n");      return -EINVAL;    }  /*     * "sound=" command line handling by Harald Milz.   */  i = 0;  while (i < 20 && sound[i])    ints[i + 1] = sound[i++];  ints[0] = i;  if (i)    sound_setup ("sound=", ints);  err = module_register_chrdev (sound_major, "sound", &sound_fops);  if (err)    {      printk ("sound: driver already loaded/included in kernel\n");      return err;    }  chrdev_registered = 1;  soundcard_init ();  if (sound_nblocks >= 1024)    printk ("Sound warning: Deallocation table was too small.\n");  return 0;}#ifdef MODULEvoidcleanup_module (void){  int             i;  if (MOD_IN_USE)    {      return;    }  if (chrdev_registered)    module_unregister_chrdev (sound_major, "sound");#ifdef CONFIG_SEQUENCER  sound_stop_timer ();#endif#ifdef CONFIG_LOWLEVEL_SOUND  {    extern void     sound_unload_lowlevel_drivers (void);    sound_unload_lowlevel_drivers ();  }#endif  sound_unload_drivers ();  for (i = 0; i < sound_nblocks; i++)    vfree (sound_mem_blocks[i]);  free_all_irqs ();		/* If something was left allocated by accident */  for (i = 0; i < MAX_DMA_CHANNELS; i++)    if (dma_alloc_map[i] != DMA_MAP_UNAVAIL)      {	printk ("Sound: Hmm, DMA%d was left allocated - fixed\n", i);	sound_free_dma (i);      }}#endifvoidtenmicrosec (int *osp){  int             i;  for (i = 0; i < 16; i++)    inb (0x80);}intsnd_set_irq_handler (int interrupt_level, void (*iproc) (int, void *, struct pt_regs *), char *name, int *osp){  int             retcode;  unsigned long   flags;  save_flags (flags);  cli ();  retcode = request_irq (interrupt_level, iproc, 0 /* SA_INTERRUPT */ , name, NULL);  if (retcode < 0)    {      printk ("Sound: IRQ%d already in use\n", interrupt_level);    }  else    irqs |= (1ul << interrupt_level);  restore_flags (flags);  return retcode;}voidsnd_release_irq (int vect){  if (!(irqs & (1ul << vect)))    return;  irqs &= ~(1ul << vect);  free_irq (vect, NULL);}intsound_alloc_dma (int chn, char *deviceID){  int             err;  if ((err = request_dma (chn, deviceID)) != 0)    return err;  dma_alloc_map[chn] = DMA_MAP_FREE;  return 0;}intsound_open_dma (int chn, char *deviceID){  unsigned long   flags;  if (chn < 0 || chn >= MAX_DMA_CHANNELS || chn == 4)    {      printk ("sound_open_dma: Invalid DMA channel %d\n", chn);      return 1;    }  save_flags (flags);  cli ();  if (dma_alloc_map[chn] != DMA_MAP_FREE)    {      printk ("sound_open_dma: DMA channel %d busy or not allocated\n", chn);      restore_flags (flags);      return 1;    }  dma_alloc_map[chn] = DMA_MAP_BUSY;  restore_flags (flags);  return 0;}voidsound_free_dma (int chn){  if (dma_alloc_map[chn] != DMA_MAP_FREE)    {      /* printk ("sound_free_dma: Bad access to DMA channel %d\n", chn); */      return;    }  free_dma (chn);  dma_alloc_map[chn] = DMA_MAP_UNAVAIL;}voidsound_close_dma (int chn){  unsigned long   flags;  save_flags (flags);  cli ();  if (dma_alloc_map[chn] != DMA_MAP_BUSY)    {      printk ("sound_close_dma: Bad access to DMA channel %d\n", chn);      restore_flags (flags);      return;    }  dma_alloc_map[chn] = DMA_MAP_FREE;  restore_flags (flags);}#ifdef CONFIG_SEQUENCERstatic struct timer_list seq_timer ={NULL, NULL, 0, 0, sequencer_timer};voidrequest_sound_timer (int count){  extern unsigned long seq_time;  if (count < 0)    count = jiffies + (-count);  else    count += seq_time;  ;  {    seq_timer.expires = ((count - jiffies)) + jiffies;    add_timer (&seq_timer);  };}voidsound_stop_timer (void){  del_timer (&seq_timer);;}#endif#ifdef CONFIG_AUDIO#ifdef KMALLOC_DMA_BROKENfatal_error__This_version_is_not_compatible_with_this_kernel;#endifstatic int      dma_buffsize = DSP_BUFFSIZE;intsound_alloc_dmap (int dev, struct dma_buffparms *dmap, int chan){  char           *start_addr, *end_addr;  int             i, dma_pagesize;  dmap->mapping_flags &= ~DMA_MAP_MAPPED;  if (dmap->raw_buf != NULL)    return 0;			/* Already done */  if (dma_buffsize < 4096)    dma_buffsize = 4096;  if (chan < 4)    dma_pagesize = 64 * 1024;  else    dma_pagesize = 128 * 1024;  dmap->raw_buf = NULL;  if (debugmem)    printk ("sound: buffsize[%d] = %lu\n", dev, audio_devs[dev]->buffsize);  audio_devs[dev]->buffsize = dma_buffsize;  if (audio_devs[dev]->buffsize > dma_pagesize)    audio_devs[dev]->buffsize = dma_pagesize;  start_addr = NULL;/* * Now loop until we get a free buffer. Try to get smaller buffer if * it fails. */  while (start_addr == NULL && audio_devs[dev]->buffsize > PAGE_SIZE)    {      int             sz, size;      for (sz = 0, size = PAGE_SIZE;	   size < audio_devs[dev]->buffsize;	   sz++, size <<= 1);      audio_devs[dev]->buffsize = PAGE_SIZE * (1 << sz);      if ((start_addr = (char *) __get_dma_pages (GFP_ATOMIC, sz)) == NULL)	audio_devs[dev]->buffsize /= 2;    }  if (start_addr == NULL)    {      printk ("Sound error: Couldn't allocate DMA buffer\n");      return -(ENOMEM);    }  else    {      /* make some checks */      end_addr = start_addr + audio_devs[dev]->buffsize - 1;      if (debugmem)	printk ("sound: start 0x%lx, end 0x%lx\n",		(long) start_addr, (long) end_addr);      /* now check if it fits into the same dma-pagesize */      if (((long) start_addr & ~(dma_pagesize - 1))	  != ((long) end_addr & ~(dma_pagesize - 1))	  || end_addr >= (char *) (MAX_DMA_ADDRESS))	{	  printk (		   "sound: Got invalid address 0x%lx for %ldb DMA-buffer\n",		   (long) start_addr,		   audio_devs[dev]->buffsize);	  return -(EFAULT);	}    }  dmap->raw_buf = start_addr;  dmap->raw_buf_phys = virt_to_bus (start_addr);  for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)    {      mem_map_reserve (i);    }  return 0;}voidsound_free_dmap (int dev, struct dma_buffparms *dmap){  int             sz, size, i;  unsigned long   start_addr, end_addr;  if (dmap->raw_buf == NULL)    return;  if (dmap->mapping_flags & DMA_MAP_MAPPED)    return;			/* Don't free mmapped buffer. Will use it next time */  for (sz = 0, size = PAGE_SIZE;       size < audio_devs[dev]->buffsize;       sz++, size <<= 1);  start_addr = (unsigned long) dmap->raw_buf;  end_addr = start_addr + audio_devs[dev]->buffsize;  for (i = MAP_NR (start_addr); i <= MAP_NR (end_addr); i++)    {      mem_map_unreserve (i);    }  free_pages ((unsigned long) dmap->raw_buf, sz);  dmap->raw_buf = NULL;}intsound_map_buffer (int dev, struct dma_buffparms *dmap, buffmem_desc * info){  printk ("Entered sound_map_buffer()\n");  printk ("Exited sound_map_buffer()\n");  return -(EINVAL);}#endifvoidconf_printf (char *name, struct address_info *hw_config){  if (!trace_init)    return;  printk ("<%s> at 0x%03x", name, hw_config->io_base);  if (hw_config->irq)    printk (" irq %d", (hw_config->irq > 0) ? hw_config->irq : -hw_config->irq);  if (hw_config->dma != -1 || hw_config->dma2 != -1)    {      printk (" dma %d", hw_config->dma);      if (hw_config->dma2 != -1)	printk (",%d", hw_config->dma2);    }  printk ("\n");}voidconf_printf2 (char *name, int base, int irq, int dma, int dma2){  if (!trace_init)    return;  printk ("<%s> at 0x%03x", name, base);  if (irq)    printk (" irq %d", (irq > 0) ? irq : -irq);  if (dma != -1 || dma2 != -1)    {      printk (" dma %d", dma);      if (dma2 != -1)	printk (",%d", dma2);    }  printk ("\n");}

⌨️ 快捷键说明

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