AC97之DMA(s3c6410)

本文详细介绍了在S3C6410平台上,AC97如何利用DMA进行音频数据传输。在设备打开时,通过`s3c24xx_pcm_open`分配私有数据并设置硬件参数。`s3c24xx_pcm_hw_params`中根据流类型配置DMA通道,并预先分配DMA缓冲区,确保播放和录音过程中高效稳定的音频数据流动。此外,还讨论了内存映射、缓冲区管理及触发操作的相关细节。
摘要由CSDN通过智能技术生成

AC97之DMA(S3C6410)

在AC97的s3c-pcm.c文件中即platform驱动中,提供了ac97的DMA的使用。现在按照下面的过程一一讲述。
在设备打开时会调用s3c24xx_pcm_open,其参数为打开的子流数据
static const struct snd_pcm_hardware s3c24xx_pcm_hardware = {
 .info   = SNDRV_PCM_INFO_INTERLEAVED |
        SNDRV_PCM_INFO_BLOCK_TRANSFER |
        SNDRV_PCM_INFO_MMAP |
        SNDRV_PCM_INFO_MMAP_VALID,
 .formats  = SNDRV_PCM_FMTBIT_S16_LE |
        SNDRV_PCM_FMTBIT_U16_LE |
        SNDRV_PCM_FMTBIT_U8 |
        SNDRV_PCM_FMTBIT_S24_LE |
        SNDRV_PCM_FMTBIT_S8,
 .channels_min  = 2,
 .channels_max  = 2,
 .buffer_bytes_max = 128*1024,
 .period_bytes_min = PAGE_SIZE,
 .period_bytes_max = PAGE_SIZE*2,
 .periods_min  = 2,
 .periods_max  = 128,
 .fifo_size  = 32,
};

struct s3c24xx_runtime_data {
 spinlock_t lock;
 int state;
 unsigned int dma_loaded;
 unsigned int dma_limit;
 unsigned int dma_period;
 dma_addr_t dma_start;
 dma_addr_t dma_pos;
 dma_addr_t dma_end;
 struct s3c24xx_pcm_dma_params *params;
};
static int s3c24xx_pcm_open(struct snd_pcm_substream *substream)
{
 struct snd_pcm_runtime *runtime = substream->runtime;
 struct s3c24xx_runtime_data *prtd;

 s3cdbg("Entered %s/n", __FUNCTION__);

 snd_soc_set_runtime_hwparams(substream, &s3c24xx_pcm_hardware); 设置运行硬件参数

 prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL);
 if (prtd == NULL)
  return -ENOMEM;

 spin_lock_init(&prtd->lock);

 runtime->private_data = prtd;    将DMA的信息保存在运行的私有数据中
 return 0;
}

/**
 * snd_soc_set_runtime_hwparams - set the runtime hardware parameters
 * @substream: the pcm substream
 * @hw: the hardware parameters
 *
 * Sets the substream runtime hardware parameters.
 */
int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,const struct snd_pcm_hardware *hw)
{
 struct snd_pcm_runtime *runtime = substream->runtime;
 runtime->hw.info = hw->info;
 runtime->hw.formats = hw->formats;
 runtime->hw.period_bytes_min = hw->period_bytes_min;
 runtime->hw.period_bytes_max = hw->period_bytes_max;
 runtime->hw.periods_min = hw->periods_min;
 runtime->hw.periods_max = hw->periods_max;
 runtime->hw.buffer_bytes_max = hw->buffer_bytes_max;
 runtime->hw.fifo_size = hw->fifo_size;
 return 0;
}

static struct s3c2410_dma_client s3c6400_dma_client_out = {
 .name = "AC97 PCM Stereo out"
};

static struct s3c24xx_pcm_dma_params s3c6400_ac97_pcm_stereo_out = {
 .client  = &s3c6400_dma_client_out,
 .channel = DMACH_AC97_PCM_OUT,
 .dma_addr = S3C6400_PA_AC97 + S3C_AC97_PCM_DATA,
 .dma_size = 4,
};

#ifdef CONFIG_SOUND_WM9713_INPUT_STREAM_MIC
static struct s3c2410_dma_client s3c6400_dma_client_micin = {
 .name = "AC97 Mic Mono in"
};

static struct s3c24xx_pcm_dma_params s3c6400_ac97_mic_mono_in = {
 .client  = &s3c6400_dma_client_micin,
 .channel = DMACH_AC97_MIC

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值