声卡注册流程(linux-5.4)
结构体介绍
先介绍声卡相关结构体
struct asoc_simple_priv {struct snd_soc_card snd_card;struct simple_dai_props {struct asoc_simple_dai *cpu_dai;struct asoc_simple_dai *codec_dai;struct snd_soc_dai_link_component cpus; /* single cpu */struct snd_soc_dai_link_component codecs; /* single codec */struct snd_soc_dai_link_component platforms;struct asoc_simple_data adata;struct snd_soc_codec_conf *codec_conf;bool mclk_fp;unsigned int mclk_fs;unsigned int cpu_pll_fs;unsigned int codec_pll_fs;} *dai_props;struct asoc_simple_jack hp_jack;struct asoc_simple_jack mic_jack;struct snd_soc_dai_link *dai_link;struct asoc_simple_dai *dais;struct snd_soc_codec_conf *codec_conf;struct gpio_desc *pa_gpio;
};struct snd_soc_card {const char *name;const char *long_name;const char *driver_name;char dmi_longname[80];char topology_shortname[32];struct device *dev;struct snd_card *snd_card;struct module *owner;struct mutex mutex;struct mutex dapm_mutex;/* Mutex for PCM operations */struct mutex pcm_mutex;enum snd_soc_pcm_subclass pcm_subclass;spinlock_t dpcm_lock;bool instantiated;bool topology_shortname_created;int (*probe)(struct snd_soc_card *card);int (*late_probe)(struct snd_soc_card *card);int (*remove)(struct snd_soc_card *card);/* the pre and post PM functions are used to do any PM work before and* after the codec and DAI's do any PM work. */int (*suspend_pre)(struct snd_soc_card *card);int (*suspend_post)(struct snd_soc_card *card);int (*resume_pre)(struct snd_soc_card *card);int (*resume_post)(struct snd_soc_card *card);/* callbacks */int (*set_bias_level)(struct snd_soc_card *,struct snd_soc_dapm_context *dapm,enum snd_soc_bias_level level);int (*set_bias_level_post)(struct snd_soc_card *,struct snd_soc_dapm_context *dapm,enum snd_soc_bias_level level);int (*add_dai_link)(struct snd_soc_card *,struct snd_soc_dai_link *link);void (*remove_dai_link)(struct snd_soc_card *,struct snd_soc_dai_link *link);long pmdown_time;/* CPU <--> Codec DAI links */struct snd_soc_dai_link *dai_link; /* predefined links only */int num_links; /* predefined links only */struct list_head dai_link_list; /* all links */struct list_head rtd_list;int num_rtd;/* optional codec specific configuration */struct snd_soc_codec_conf *codec_conf;int num_configs;/** optional auxiliary devices such as amplifiers or codecs with DAI* link unused*/struct snd_soc_aux_dev *aux_dev;int num_aux_devs;struct list_head aux_comp_list;const struct snd_kcontrol_new *controls;int num_controls;/** Card-specific routes and widgets.* Note: of_dapm_xxx for Device Tree; Otherwise for driver build-in.*/const struct snd_soc_dapm_widget *dapm_widgets;int num_dapm_widgets;const struct snd_soc_dapm_route *dapm_routes;int num_dapm_routes;const struct snd_soc_dapm_widget *of_dapm_widgets;int num_of_dapm_widgets;const struct snd_soc_dapm_route *of_dapm_routes;int num_of_dapm_routes;bool fully_routed;bool disable_route_checks;/* lists of probed devices belonging to this card */struct list_head component_dev_list;struct list_head list;struct list_head widgets;struct list_head paths;struct list_head dapm_list;struct list_head dapm_dirty;/* attached dynamic objects */struct list_head dobj_list;/* Generic DAPM context for the card */struct snd_soc_dapm_context dapm;struct snd_soc_dapm_stats dapm_stats;struct snd_soc_dapm_update *update;#ifdef CONFIG_DEBUG_FSstruct dentry *debugfs_card_root;
#endif
#ifdef CONFIG_PM_SLEEPstruct work_struct deferred_resume_work;
#endifu32 pop_time;void *drvdata;ANDROID_KABI_RESERVE(1);ANDROID_KABI_RESERVE(2);ANDROID_KABI_RESERVE(3);ANDROID_KABI_RESERVE(4);
};struct snd_card {int number; /* number of soundcard (index tosnd_cards) */char id[16]; /* id string of this card */char driver[16]; /* driver name */char shortname[32]; /* short name of this soundcard */char longname[80]; /* name of this soundcard */char irq_descr[32]; /* Interrupt description */char mixername[80]; /* mixer name */char components[128]; /* card components delimited withspace */struct module *module; /* top-level module */void *private_data; /* private data for soundcard */void (*private_free) (struct snd_card *card); /* callback for freeing ofprivate data */struct list_head devices; /* devices */struct device ctl_dev; /* control device */unsigned int last_numid; /* last used numeric ID */struct rw_semaphore controls_rwsem; /* controls list lock */rwlock_t ctl_files_rwlock; /* ctl_files list lock */int controls_count; /* count of all controls */int user_ctl_count; /* count of all user controls */struct list_head controls; /* all controls for this card */struct list_head ctl_files; /* active control files */struct snd_info_entry *proc_root; /* root for soundcard specific files */struct proc_dir_entry *proc_root_link; /* number link to real id */struct list_head files_list; /* all files associated to this card */struct snd_shutdown_f_ops *s_f_ops; /* file operations in the shutdownstate */spinlock_t files_lock; /* lock the files for this card */int shutdown; /* this card is going down */struct completion *release_completion;struct device *dev; /* device assigned to this card */struct device card_dev; /* cardX object for sysfs */const struct attribute_group *dev_groups[4]; /* assigned sysfs attr */bool registered; /* card_dev is registered? */wait_queue_head_t remove_sleep;#ifdef CONFIG_PMunsigned int power_state; /* power state */wait_queue_head_t power_sleep;
#endif#if IS_ENABLED(CONFIG_SND_MIXER_OSS)struct snd_mixer_oss *mixer_oss;int mixer_oss_change_count;
#endifANDROID_KABI_RESERVE(1);ANDROID_KABI_RESERVE(2);
};
可以看出,三个结构体的大致内容:
asoc_simple_priv:
属于该结构体的snd_soc_card
dai相关
时钟相关
耳机、麦克风拔插相关
功放相关
snd_soc_card:
snd_soc_card的基本信息
属于该结构体的snd_card
各种mutex(PCM、DAPM等)
电源管理相关的操作函数
回调函数(DAPM、DAI LINK)
DAPM、DAI LINK相关
snd_card:
声卡的基本信息
属于该声卡的control设备
proc文件系统的相关配置
sys文件系统的相关配置
流程介绍
probe()
为asoc_simple_priv分配空间并初始化 --- devm_kzalloc_priv() asoc_simple_init_priv()
判断pdev->dev的status是否为okay --- of_device_is_available()
最后跳到进行声卡注册 --- devm_snd_soc_register_card()
3.1 snd_soc_register_card() --- 初始化card里的内核链表以及mutex,
3.1.1 然后return snd_soc_bind_card()
snd_soc_bind_card()
实例化snd_soc_card --- snd_soc_instantiate_card()
snd_soc_instantiate_card()
初始化snd_soc_dai_link结构体(关于dai匹配)--- soc_init_dai_link()
初始化dapm,并把dapm->list加到card->dapm_list里面 --- snd_soc_dapm_init()
绑定dai link--- soc_bind_dai_link()
3.1 soc_new_pcm_runtime() --- 初始化rtd(该结构体与绑定codec和platform有关)
3.2 通过snd_soc_find_dai() 和 snd_soc_rtdcom_add()来拿到已经注册的codec和platform并添加到rtd
3.3 通过soc_add_pcm_runtime()将rtd添加到card绑定aux设备(耳机口),也是从component list中找到再给card --- soc_bind_aux_dev()
都完成都开始创建声卡 --- snd_card_new()
初始化dubugfs --- soc_init_card_debugfs()
初始化dapm部分 --- snd_soc_dapm_new_controls()
初始化声卡(仅一次)--- card->probe
初始化所有dai用到的component --- soc_probe_link_components()
初始化所有aux设备 --- soc_probe_aux_devices()
初始化dai links的时候可能会添加新的dais和dai links,所以还需要再进行一次1和3
初始化所有的dai link --- soc_probe_link_dais()
创建、添加PCM设备 --- soc_link_init()
连接dapm --- snd_soc_dapm_link_dai_widgets() snd_soc_dapm_connect_dai_link_widgets()
注册control设备 --- snd_soc_add_card_controls()
注册dapm的route --- snd_soc_dapm_add_routes()
注册设备树的dapm的route --- snd_soc_dapm_add_routes()
尝试设置dmi_name --- snd_soc_set_dmi_name()
设置snd_card->name --- snprintf(card->snd_card->**name, ...)
执行后部分初始化 --- card->late_probe()
注册dapm_widget --- snd_soc_dapm_new_widgets()
注册声卡 --- snd_card_register(card->snd_card)
检查所有dapm尾指针 --- dapm_mark_endpoints_dirty() snd_soc_dapm_sync()
snd_card_register()
注册声卡设备 --- device_add(&card->card_dev)
注册所属声卡的所有设备 --- snd_device_register_all()
通过 if 判断声卡是否已经注册 --- snd_cards[card->num]
设置card->id --- snd_card_set_id_no_lock()
加入到snd_cards[ ]中 --- snd_card[card->num] = card
注册card的proc文件--- snd_info_card_register()
声卡注册流程(linux-5.4)相关推荐
- ALSA框架学习笔记3:声卡注册流程(代码解析)
以Amlogic V918D为例,介绍驱动如何将设备树中的声卡节点注册为声卡设备 一.设备树中的声卡节点 /* Audio Related start */auge_sound {compatible ...
- ALSA声卡注册流程
嵌入式声卡驱动主要分为Platform Driver.Codec Driver.Machine Driver三部分,声卡驱动的注册是Machine Driver的注册进行展开.按照ALSA架构看,声卡 ...
- linux加密框架 crypto 通用算法注册接口__crypto_register_alg注册流程
函数介绍 __crypto_register_alg函数实现向加密框架注册算法(包括静态算法和动态算法)的功能,输入参数为算法说明alg,注册成功时返回算法注册用的算法幼虫larval,注册失败时返回 ...
- linux加密框架 crypto 算法crypto_register_alg的注册流程
算法注册流程 静态算法模块初始化 分组算法模块初始化 AES算法模块(aes_generic.c)的初始化接口aes_init实现向加密框架注册AES算法的功能,如下所示. aes_generic.c ...
- 基于GBT28181:SIP协议组件开发-----------第三篇SIP注册流程分析实现
原创文章,引用请保证原文完整性,尊重作者劳动,原文地址http://www.cnblogs.com/qq1269122125/p/3941172.html,qq:1269122125. 上两章节简要的 ...
- 基于GBT28181:SIP协议组件开发-----------第四篇SIP注册流程eXosip2实现(一)
原创文章,引用请保证原文完整性,尊重作者劳动,原文地址http://www.cnblogs.com/qq1269122125/p/3945294.html. 上章节讲解了利用自主开发的组件SIP组件l ...
- 【5G NR】UE注册流程
作者:柒号华仔 个人主页:欢迎访问我的主页 个人信条:星光不问赶路人,岁月不负有心人. 个人方向:专注于4G/5G领域,同时兼顾其他网络协议,编解码协议,C/C++,linux等,感兴趣的小伙伴可以关 ...
- Android安全问题 抢先接收广播 - 内因篇之广播接收器注册流程
导读:本文说明系统是如何注册动态广播以及静态广播,这里主要注意其注册的顺序 这篇文章主要是针对我前两篇文章 android安全问题 抢先开机启动 - 结果篇 android安全问题 抢先拦截短信 ...
- NR 5G AMF重定向的注册流程
AMF重定向的注册流程 当一个AMF收到Registration Request,这个AMF可能需要将此Registration Request改道发送到另外一个AMF,主要应用场景:当初始AMF不适 ...
最新文章
- JVM之JVM内存区域与内存分配(转载)
- opencv阈值化(五)
- access 查找工龄大于30_ACCESS查询操作题完整
- tmux 如何自定义背景颜色 | How does the tmux color palette work?
- ssm中spring mvc找不到控制器,报错404
- python函数调用自身后果_python 写函数在一定条件下需要调用自身时的写法说明...
- linux system更好方法,Linux将程序添加到服务的方法(通用【但最好还是用systemd】)...
- 常用牛人主页链接(计算机视觉、模式识别、机器学习相关方向,陆续更新。。。。)【转】...
- 下载OneDrive共享的数据集
- 使用argparse解析命令行参数
- Docker Networking Data Volume
- Math Type World2016安装
- 《C++Primer》14、15章
- 一盒两用!——破解电信IPTV机顶盒为普通安卓机顶盒
- Oracle 之 AIO (异步io)
- html文字浮雕效果不起作用,CSS3实现文字浮雕效果,镂刻效果,火焰文字
- Error: EBUSY: resource busy or locked, lstat ‘D:\pagefile.sys‘
- 利用“串口调试助手”等软件调试 PROTEUS 环境中 51单片机 的串行通信
- Android APP在线自动更新安装
- 机器学习-*-K均值聚类及代码实现
热门文章
- python怎么读取特定路径文件夹下的图片
- 逆天,前端请装上这个 Chrome 插件
- 2021/04/29 插件qrcodejs2将后端链接转换成二维码
- 阻挡***狙击攻略 配置安全的路由器
- 机械键盘键帽打油如何解决
- 打造视听游戏新体验:TCL T7G真高刷电视II发布
- 有三种葡萄,每种分别有a,b,c颗。有三个人,第一个人只吃第1,2种葡萄,第二个人只吃第2,3种葡萄,第三个人只吃第1,3种葡萄。
- 解决VUE自定义拖拽指令时 onmouseup 与 click事件冲突
- 归一化 (Normalization)、标准化 (Standardization)和中心化/零均值化 (Zero-centered)...
- 【12月17日更新决赛预测】用二元泊松模型预测2022年世界杯淘汰赛结果