赞
踩
ASoC被分为Machine,Platform和Codec3大部件,Platform驱动的主要作用是完成音频数据的管理,终究通过CPU的数字音频接口(DAI)把音频数据传送
给Codec进行处理,终究由Codec输出驱动耳机或是喇叭的音信信号。在具体实现上,ASoC有把Platform驱动分为两个部份:snd_soc_platform_driver
和snd_soc_dai_driver。其中,platform_driver负责管理音频数据,把音频数据通过dma或其他操作传送至cpu dai中,dai_driver则主要完成cpu 1侧的
dai的参数配置,同时也会通过1定的途径把必要的dma等参数与snd_soc_platform_driver进行交互。
Machine 是指某1款机器,可以是某款装备,某款开发板,又或是某款智能手机,由此可以看出Machine几近是不可重用的,每一个Machine上的硬件实
现可能都不1样,CPU不1样,Codec不1样,音频的输入、输出装备也不1样,Machine为CPU、Codec、输入输出装备提供了1个载体。
Platform 1般是指某1个SoC平台,比如pxaxxx,s3cxxxx,omapxxx等等,与音频相干的通常包括该SoC中的时钟、DMA、I2S、PCM等等,只要指定了SoC,那么我们可以认为它会有1个对应的Platform,它只与SoC相干,与
Machine无关,这样我们就能够把Platform抽象出来,使得同1款SoC不用做任何的改动,就能够用在不同的Machine中。实际上,把Platform认为是某个SoC更好理解。
Codec 字面上的意思就是编解码器,Codec里面包括了I2S接口、D/A、A/D、Mixer、PA(功放),通常包括多种输入(Mic、Line-in、I2S、PCM)和多个
输出(耳机、喇叭、听筒,Line-out),Codec和Platform 1样,是可重用的部件,同1个Codec可以被不同的Machine使用。嵌入式Codec通常通过I2C对
内部的寄存器进行控制。
Machine驱动的初始化,codec和dai的注册,都会调用snd_soc_instantiate_cards()进行1次声卡和codec,dai,platform的匹配绑定进程,这里所说的
绑定,正如Machine驱动1文中所描写,就是通过3个全局链表,按名字进行匹配,把匹配的codec,dai和platform实例赋值给声卡每对dai的snd_soc_pcm_runtime变量中。1旦绑定成功,将会使得codec和dai驱动的probe回调被调用。alsa架构的数据交互,是通过对PCM装备的操作来完成的, PCM装备分成playback和capture两个stream, 每一个stream底下有N个substream
alsa驱动最底层需要调试的有3块: DMA部份,IIS驱动部份,codec部份
IIS介绍
B)声音数据DAT 1般在CLK的上升沿进行采样,有些DAC也是可以调的。每一个声道里面可以容纳的CLK数必须多于数据的位数,多出来的时钟和数据DAC会丢弃不用,比如16bit采样的声音数据当1个声道是32个CLK且left-justify的时候,后面106个时钟的数据会被DAC丢掉,不影响的。
codec芯片介绍
cs4270的驱动要设置的参数有:
静音,传输模式,比特位长度,时钟主从模式,音量大小
cs4270驱动里面定义了snd_soc_dai_driver结构成员,里面定义了playback和capture两个substream,同时也挂了1个snd_soc_dai_ops结构体,里面全是操作函数指针。
alsa上面1层层的终究会调用到这些指针
几个典型调用流程
注册ioctl
vendor/qcom/opensource/audio-kernel/asoc/msm8952.c
|
/kernel/msm-4.9/sound/soc/soc-devres.c
kernel/msm-4.9/sound/soc/soc-core.c
|
|
|
|
/kernel/msm-4.9/sound/soc/soc-pcm.c
|
/kernel/msm-4.9/sound/core/pcm.c
|
|
|
/kernel/msm-4.9/sound/core/pcm_native.c
///
|
if (ioctl(pcm->fd, , ¶ms)) {
|
/kernel/msm-4.9/sound/core/pcm_native.c
|
2808 {
2809 switch (cmd) {
2810 case SNDRV_PCM_IOCTL_PVERSION:
2811 return put_user(SNDRV_PCM_VERSION, (int __user *)arg) ? -EFAULT : 0;
2812 case SNDRV_PCM_IOCTL_INFO:
2813 return snd_pcm_info_user(substream, arg);
2814 case SNDRV_PCM_IOCTL_TSTAMP: /* just for compatibility */
2815 return 0;
2816 case SNDRV_PCM_IOCTL_TTSTAMP:
2817 return snd_pcm_tstamp(substream, arg);
2818 case SNDRV_PCM_IOCTL_HW_REFINE:
2819 return snd_pcm_hw_refine_user(substream, arg);
2820 case SNDRV_PCM_IOCTL_HW_PARAMS:
2821 return snd_pcm_hw_params_user(substream, arg);
2822 case SNDRV_PCM_IOCTL_HW_FREE:
2823 return snd_pcm_hw_free(substream);
2824 case SNDRV_PCM_IOCTL_SW_PARAMS:
2825 return snd_pcm_sw_params_user(substream, arg);
2826 case SNDRV_PCM_IOCTL_STATUS:
2827 return snd_pcm_status_user(substream, arg, false);
2828 case SNDRV_PCM_IOCTL_STATUS_EXT:
2829 return snd_pcm_status_user(substream, arg, true);
2830 case SNDRV_PCM_IOCTL_CHANNEL_INFO:
2831 return snd_pcm_channel_info_user(substream, arg);
2832 case SNDRV_PCM_IOCTL_PREPARE:
2833 return snd_pcm_prepare(substream, file);
2834 case SNDRV_PCM_IOCTL_RESET:
2835 return snd_pcm_reset(substream);
2836 case SNDRV_PCM_IOCTL_START:
2837 return snd_pcm_action_lock_irq(&snd_pcm_action_start, substream, SNDRV_PCM_STATE_RUNNING);
2838 case SNDRV_PCM_IOCTL_LINK:
2839 return snd_pcm_link(substream, (int)(unsigned long) arg);
2840 case SNDRV_PCM_IOCTL_UNLINK:
2841 return snd_pcm_unlink(substream);
2842 case SNDRV_PCM_IOCTL_RESUME:
2843 return snd_pcm_resume(substream);
2844 case SNDRV_PCM_IOCTL_XRUN:
2845 return snd_pcm_xrun(substream);
2846 case SNDRV_PCM_IOCTL_HWSYNC:
2847 return snd_pcm_hwsync(substream);
2848 case SNDRV_PCM_IOCTL_DELAY:
2849 return snd_pcm_delay(substream, arg);
2850 case SNDRV_PCM_IOCTL_SYNC_PTR:
2851 return snd_pcm_sync_ptr(substream, arg);
2852 #ifdef CONFIG_SND_SUPPORT_OLD_API
2853 case SNDRV_PCM_IOCTL_HW_REFINE_OLD:
2854 return snd_pcm_hw_refine_old_user(substream, arg);
2855 case SNDRV_PCM_IOCTL_HW_PARAMS_OLD:
2856 return snd_pcm_hw_params_old_user(substream, arg);
2857 #endif
2858 case SNDRV_PCM_IOCTL_DRAIN:
2859 return snd_pcm_drain(substream, file);
2860 case SNDRV_PCM_IOCTL_DROP:
2861 return snd_pcm_drop(substream);
2862 case SNDRV_PCM_IOCTL_PAUSE:
2863 {
2864 int res;
2865 snd_pcm_stream_lock_irq(substream);
2866 res = snd_pcm_pause(substream, (int)(unsigned long)arg);
2867 snd_pcm_stream_unlock_irq(substream);
2868 return res;
2869 }
2870 case SNDRV_COMPRESS_GET_CAPS:
2871 case SNDRV_COMPRESS_GET_CODEC_CAPS:
2872 case SNDRV_COMPRESS_SET_PARAMS:
2873 case SNDRV_COMPRESS_GET_PARAMS:
2874 case SNDRV_COMPRESS_TSTAMP:
2875 case SNDRV_COMPRESS_DRAIN:
2876 return snd_compressed_ioctl(substream, cmd, arg);
2877 default:
2878 if (((cmd >> 8) & 0xff) == 'U')
2879 return snd_user_ioctl(substream, cmd, arg);
2880 }
2881 pcm_dbg(substream->pcm, "unknown ioctl = 0x%x\n", cmd);
2882 return -ENOTTY;
2883 }
|
|
转自:https://mp.csdn.net/editor/html/111975376
上一篇 CSS应用:过渡
下一篇 Android面试经验总结
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。