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

📄 soundcard.c

📁 arm平台上的uclinux系统全部源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * linux/kernel/chr_drv/sound/soundcard.c * * Soundcard driver for Linux *//* * Copyright (C) by Hannu Savolainen 1993-1996 * * USS/Lite for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) * Version 2 (June 1991). See the "COPYING" file distributed with this software * for more info. */#include <linux/config.h>#include "sound_config.h"#include <linux/major.h>int            *sound_global_osp = NULL;static int      chrdev_registered = 0;static int      sound_major = SOUND_MAJOR;static int      is_unloading = 0;/* * Table for permanently allocated memory (used when unloading the module) */caddr_t         sound_mem_blocks[1024];int             sound_nblocks = 0;static int      soundcard_configured = 0;static struct fileinfo files[SND_NDEVS];static char     dma_alloc_map[MAX_DMA_CHANNELS] ={0};#define DMA_MAP_UNAVAIL		0#define DMA_MAP_FREE		1#define DMA_MAP_BUSY		2intsnd_ioctl_return (int *addr, int value){  if (value < 0)    return value;  put_user (value, addr);  return 0;}static intsound_read (inode_handle * inode, file_handle * file, char *buf, int count){  int             dev;  dev = MINOR (inode_get_rdev (inode));  files[dev].flags = file_get_flags (file);  return sound_read_sw (dev, &files[dev], buf, count);}static intsound_write (inode_handle * inode, file_handle * file, const char *buf, int count){  int             dev;  dev = MINOR (inode_get_rdev (inode));  files[dev].flags = file_get_flags (file);  return sound_write_sw (dev, &files[dev], buf, count);}static intsound_lseek (inode_handle * inode, file_handle * file, off_t offset, int orig){  return -(EPERM);}static intsound_open (inode_handle * inode, file_handle * file){  int             dev, retval;  struct fileinfo tmp_file;  if (is_unloading)    {      printk ("Sound: Driver partially removed. Can't open device\n");      return -(EBUSY);    }  dev = MINOR (inode_get_rdev (inode));  if (!soundcard_configured && dev != SND_DEV_CTL && dev != SND_DEV_STATUS)    {      printk ("Sound Card Error: The soundcard system has not been configured\n");      return -(ENXIO);    }  tmp_file.mode = 0;  tmp_file.flags = file_get_flags (file);  if ((tmp_file.flags & O_ACCMODE) == O_RDWR)    tmp_file.mode = OPEN_READWRITE;  if ((tmp_file.flags & O_ACCMODE) == O_RDONLY)    tmp_file.mode = OPEN_READ;  if ((tmp_file.flags & O_ACCMODE) == O_WRONLY)    tmp_file.mode = OPEN_WRITE;  if ((retval = sound_open_sw (dev, &tmp_file)) < 0)    return retval;#ifdef MODULE  MOD_INC_USE_COUNT;#endif  memcpy ((char *) &files[dev], (char *) &tmp_file, sizeof (tmp_file));  return retval;}static voidsound_release (inode_handle * inode, file_handle * file){  int             dev;  dev = MINOR (inode_get_rdev (inode));  files[dev].flags = file_get_flags (file);  sound_release_sw (dev, &files[dev]);#ifdef MODULE  MOD_DEC_USE_COUNT;#endif}static intsound_ioctl (inode_handle * inode, file_handle * file,	     unsigned int cmd, unsigned long arg){  int             dev, err;  dev = MINOR (inode_get_rdev (inode));  files[dev].flags = file_get_flags (file);  if (_IOC_DIR (cmd) != _IOC_NONE)    {      /*         * Have to validate the address given by the process.       */      int             len;      len = _IOC_SIZE (cmd);      if (_IOC_DIR (cmd) & _IOC_WRITE)	{	  if ((err = verify_area (VERIFY_READ, (void *) arg, len)) < 0)	    return err;	}      if (_IOC_DIR (cmd) & _IOC_READ)	{	  if ((err = verify_area (VERIFY_WRITE, (void *) arg, len)) < 0)	    return err;	}    }  err = sound_ioctl_sw (dev, &files[dev], cmd, (caddr_t) arg);  return err;}static intsound_select (inode_handle * inode, file_handle * file, int sel_type, select_table_handle * wait){  int             dev;  dev = MINOR (inode_get_rdev (inode));  files[dev].flags = file_get_flags (file);  DEB (printk ("sound_select(dev=%d, type=0x%x)\n", dev, sel_type));  switch (dev & 0x0f)    {#ifdef CONFIG_SEQUENCER    case SND_DEV_SEQ:    case SND_DEV_SEQ2:      return sequencer_select (dev, &files[dev], sel_type, wait);      break;#endif#ifdef CONFIG_MIDI    case SND_DEV_MIDIN:      return MIDIbuf_select (dev, &files[dev], sel_type, wait);      break;#endif#ifdef CONFIG_AUDIO    case SND_DEV_DSP:    case SND_DEV_DSP16:    case SND_DEV_AUDIO:      return audio_select (dev, &files[dev], sel_type, wait);      break;#endif    default:      return 0;    }  return 0;}static intsound_mmap (inode_handle * inode, file_handle * file, vm_area_handle * vma){  int             dev, dev_class;  unsigned long   size;  struct dma_buffparms *dmap = NULL;  dev = MINOR (inode_get_rdev (inode));  files[dev].flags = file_get_flags (file);  dev_class = dev & 0x0f;  dev >>= 4;  if (dev_class != SND_DEV_DSP && dev_class != SND_DEV_DSP16 && dev_class != SND_DEV_AUDIO)    {      printk ("Sound: mmap() not supported for other than audio devices\n");      return -EINVAL;    }  if ((vma_get_flags (vma) & (VM_READ | VM_WRITE)) == (VM_READ | VM_WRITE))    {      printk ("Sound: Cannot do read/write mmap()\n");      return -EINVAL;    }  if (vma_get_flags (vma) & VM_READ)    {      dmap = audio_devs[dev]->dmap_in;    }  else if (vma_get_flags (vma) & VM_WRITE)    {      dmap = audio_devs[dev]->dmap_out;    }  else    {      printk ("Sound: Undefined mmap() access\n");      return -EINVAL;    }  if (dmap == NULL)    {      printk ("Sound: mmap() error. dmap == NULL\n");      return -EIO;    }  if (dmap->raw_buf == NULL)    {      printk ("Sound: mmap() called when raw_buf == NULL\n");      return -EIO;    }  if (dmap->mapping_flags)    {      printk ("Sound: mmap() called twice for the same DMA buffer\n");      return -EIO;    }  if (vma_get_offset (vma) != 0)    {      printk ("Sound: mmap() offset must be 0.\n");      return -EINVAL;    }  size = vma_get_end (vma) - vma_get_start (vma);  if (size != dmap->bytes_in_use)    {      printk ("Sound: mmap() size = %ld. Should be %d\n",	      size, dmap->bytes_in_use);    }  if (remap_page_range (vma_get_start (vma), (unsigned long)dmap->raw_buf,			vma_get_end (vma) - vma_get_start (vma),			vma_get_page_prot (vma)))    return -EAGAIN;  vma_set_inode (vma, inode);  inode_inc_count (inode);  dmap->mapping_flags |= DMA_MAP_MAPPED;  memset (dmap->raw_buf,	  dmap->neutral_byte,	  dmap->bytes_in_use);  return 0;}static struct file_operation_handle sound_fops ={  sound_lseek,  sound_read,  sound_write,  NULL,				/* sound_readdir */  sound_select,  sound_ioctl,  sound_mmap,  sound_open,  sound_release};voidsoundcard_init (void){#ifndef MODULE  module_register_chrdev (sound_major, "sound", &sound_fops);  chrdev_registered = 1;#endif  soundcard_configured = 1;  sndtable_init ();		/* Initialize call tables and detect cards */#ifdef CONFIG_LOWLEVEL_SOUND  {    extern void     sound_init_lowlevel_drivers (void);    sound_init_lowlevel_drivers ();  }#endif  if (sndtable_get_cardcount () == 0)    return;			/* No cards detected */#ifdef CONFIG_AUDIO  if (num_audiodevs)		/* Audio devices present */    {      DMAbuf_init ();      audio_init ();    }#endif#ifdef CONFIG_MIDI  if (num_midis)    MIDIbuf_init ();#endif#ifdef CONFIG_SEQUENCER  if (num_midis + num_synths)    sequencer_init ();#endif}static unsigned int irqs = 0;#ifdef MODULEstatic voidfree_all_irqs (void){  int             i;  for (i = 0; i < 31; i++)    if (irqs & (1ul << i))      {	printk ("Sound warning: IRQ%d was left allocated - fixed.\n", i);	snd_release_irq (i);      }  irqs = 0;}char            kernel_version[] = UTS_RELEASE;#endifstatic int      debugmem = 0;	/* switched off by default */static int      sound[20] ={0};intinit_module (void){  int             err;  int             ints[21];

⌨️ 快捷键说明

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