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

📄 vidc_audio.c

📁 arm平台上的uclinux系统全部源代码
💻 C
字号:
/* * sound/vidc_audio.c * * Audio routines for the VIDC * * Copyright (C) 1997 Russell King */#include <linux/config.h>#include "sound_config.h"#include "vidc.h"/* * VIDC sound * * When using SERIAL SOUND mode (external DAC), the number of physical * channels is fixed at 2.  Therefore, the sample rate = vidc sample rate. */#if defined(CONFIG_VIDC)static int vidc_adev;static int  vidc_audio_volume;static int  vidc_audio_rate;static char vidc_audio_bits;static char vidc_audio_channels;extern void vidc_update_filler (int bits, int channels);int vidc_audio_get_volume (void){  return vidc_audio_volume;}int vidc_audio_set_volume (int newvol){  vidc_audio_volume = newvol;  return vidc_audio_volume;}static int vidc_audio_set_bits (int bits){  switch (bits) {  case AFMT_QUERY:	break;  case AFMT_U8:  case AFMT_S8:  case AFMT_S16_LE:	vidc_audio_bits = bits;	vidc_update_filler (vidc_audio_bits, vidc_audio_channels);	break;  default:	vidc_audio_bits = AFMT_S16_LE;	vidc_update_filler (vidc_audio_bits, vidc_audio_channels);	break;  }  return vidc_audio_bits;}static int vidc_audio_set_rate (int rate){  if (rate) {    int newsize, new2size;    vidc_audio_rate = ((500000 / rate) + 1) >> 1;    if (vidc_audio_rate < 3)      vidc_audio_rate = 3;    if (vidc_audio_rate > 255)      vidc_audio_rate = 255;    outl ((vidc_audio_rate - 2) | 0xb0000000, IO_VIDC_BASE);    outl (0xb1000003, IO_VIDC_BASE);    newsize = (10000 / vidc_audio_rate) & ~3;    if (newsize< 208)      newsize = 208;    if (newsize > 4096)      newsize = 4096;    for (new2size = 128; new2size < newsize; new2size <<= 1);    if (new2size - newsize > newsize - (new2size >> 1))      new2size >>= 1;    dma_bufsize = new2size;  }  return 250000 / vidc_audio_rate;}static int vidc_audio_set_channels (int channels){  switch (channels) {  case 0: break;  case 1:  case 2:    vidc_audio_channels = channels;    vidc_update_filler (vidc_audio_bits, vidc_audio_channels);    break;  default:    vidc_audio_channels = 2;    vidc_update_filler (vidc_audio_bits, vidc_audio_channels);    break;  }  return vidc_audio_channels;}/* * Open the device * * dev	- device * mode	- mode to open device (logical OR of OPEN_READ and OPEN_WRITE) * * Called when opening the DMAbuf		(dmabuf.c:259) */static intvidc_audio_open (int dev, int mode){  if (vidc_busy)    return -EBUSY;  if (mode & OPEN_READ && !mode & OPEN_WRITE) {    printk ("VIDCsound: This audio device doesn't have recording capability\n");    return -EIO;  }  vidc_busy = 1;  return 0;}/* * Close the device * * dev	- device * * Called when closing the DMAbuf		(dmabuf.c:477) *	after halt_xfer */static voidvidc_audio_close (int dev){  vidc_busy = 0;}static intvidc_audio_ioctl (int dev, unsigned int cmd, caddr_t arg, int local){  int ret;  switch (cmd) {  case SOUND_PCM_WRITE_RATE:    if (local)      ret = vidc_audio_set_rate ((int) arg);    else      ret = vidc_audio_set_rate (get_user ((int *)arg));    break;  case SOUND_PCM_READ_RATE:    ret = vidc_audio_set_rate (0);    break;  case SNDCTL_DSP_STEREO:    if (local)      ret = vidc_audio_set_channels ((int) arg + 1) - 1;    else      ret = vidc_audio_set_channels (get_user ((int *)arg) + 1) - 1;    break;  case SOUND_PCM_WRITE_CHANNELS:    if (local)      ret = vidc_audio_set_channels ((int) arg);    else      ret = vidc_audio_set_channels (get_user ((int *)arg));    break;  case SOUND_PCM_READ_CHANNELS:    ret = vidc_audio_set_channels (0);    break;  case SNDCTL_DSP_SETFMT:    if (local)      ret = vidc_audio_set_bits ((int) arg);    else      ret = vidc_audio_set_bits (get_user ((int *)arg));    break;  case SOUND_PCM_READ_BITS:    ret = vidc_audio_set_bits (0);    break;  case SOUND_PCM_WRITE_FILTER:  case SOUND_PCM_READ_FILTER:    ret = -EINVAL;    break;  default:    ret = -EINVAL;    break;  }  if (local)    return ret;  else    return snd_ioctl_return ((int *)arg, ret);}/* * Output a block via DMA to sound device * * dev		- device number * buf		- physical address of buffer * total_count	- total byte count in buffer * intrflag	- set if this has been called from an interrupt (via DMAbuf_outputintr) * restart_dma	- set if DMA needs to be re-initialised * * Called when: *  1. Starting output					(dmabuf.c:1327) *  2.							(dmabuf.c:1504) *  3. A new buffer needs to be sent to the device	(dmabuf.c:1579) */static voidvidc_audio_dma_interrupt (void){  DMAbuf_outputintr (vidc_adev, 1);}static voidvidc_audio_output_block (int dev, unsigned long buf, int total_count,			 int intrflag, int restart_dma){  dma_start = (unsigned long)bus_to_virt(buf);  dma_count = total_count;  if (restart_dma && !intrflag) {    dma_interrupt = vidc_audio_dma_interrupt;    vidc_sound_dma_irq (0, NULL, NULL);    outb (0x30, IOMD_SD0CR);  }}static voidvidc_audio_start_input (int dev, unsigned long buf, int count,			int intrflag, int restart_dma){}static intvidc_audio_prepare_for_input (int dev, int bsize, int bcount){  return -EINVAL;}/* * Prepare for outputting samples to `dev' * * Each buffer that will be passed will be `bsize' bytes long, * with a total of `bcount' buffers. * * Called when: *  1. A trigger enables audio output			(dmabuf.c:978) *  2. We get a write buffer without dma_mode setup	(dmabuf.c:1152) *  3. We restart a transfer				(dmabuf.c:1324) */static intvidc_audio_prepare_for_output (int dev, int bsize, int bcount){  return 0;}static voidvidc_audio_reset (int dev){}/* * Halt a DMA transfer to `dev' * * Called when: *  1. We close the DMAbuf					(dmabuf.c:476) *  2. We run out of output buffers to output to the device.	(dmabuf.c:1456) *  3. We run out of output buffers and we're closing down.	(dmabuf.c:1546) *  4. We run out of input buffers in AUTOMODE.			(dmabuf.c:1651) */static voidvidc_audio_halt_xfer (int dev){  dma_count = 0;}static intvidc_audio_local_qlen (int dev){  return dma_count != 0;}static struct audio_driver vidc_audio_driver = {  vidc_audio_open,			/* open			*/  vidc_audio_close,			/* close		*/  vidc_audio_output_block,		/* output_block		*/  vidc_audio_start_input,		/* start_input		*/  vidc_audio_ioctl,			/* ioctl		*/  vidc_audio_prepare_for_input,		/* prepare_for_input	*/  vidc_audio_prepare_for_output,	/* prepare_for_output	*/  vidc_audio_reset,			/* reset		*/  vidc_audio_halt_xfer,			/* halt_xfer		*/  vidc_audio_local_qlen,		/*+local_qlen		*/  NULL,					/*+copy_from_user	*/  NULL,					/*+halt_input		*/  NULL,					/*+halt_output		*/  NULL,					/*+trigger		*/  NULL,					/*+set_speed		*/  NULL,					/*+set_bits		*/  NULL,					/*+set_channels		*/};static struct audio_operations vidc_audio_operations = {  "VIDCsound",  0,  AFMT_U8 | AFMT_S16_LE,  NULL,  &vidc_audio_driver};void vidc_audio_init (struct address_info *hw_config){  vidc_audio_volume = 100 | (100 << 8);  if (num_audiodevs < MAX_AUDIO_DEV) {    audio_devs[vidc_adev = num_audiodevs++] = &vidc_audio_operations;    audio_devs[vidc_adev]->dmachan1 = hw_config->dma;    /* size of the total DMA buffer */    audio_devs[vidc_adev]->buffsize = DSP_BUFFSIZE;    audio_devs[vidc_adev]->min_fragment = 10; /* 1024 bytes => 64 buffers */    audio_devs[vidc_adev]->mixer_dev = num_mixers;    audio_devs[vidc_adev]->flags |= 0;  } else    printk ("VIDCsound: Too many PCM devices available\n");}#endif

⌨️ 快捷键说明

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