5. 创建声卡

news2024/9/19 10:34:48

 代码位置 sound/soc/generic/simple-card.c

static int asoc_simple_card_probe(struct platform_device *pdev)
{
    ...

    ret = devm_snd_soc_register_card(dev, card);
 
    ...
}

 asoc_simple_card_probe -> devm_snd_soc_register_card -> snd_soc_register_card

int snd_soc_register_card(struct snd_soc_card *card)
{
    int i, ret;
    struct snd_soc_pcm_runtime *rtd;

    if (!card->name || !card->dev)
        return -EINVAL;

    for (i = 0; i < card->num_links; i++) {
        struct snd_soc_dai_link *link = &card->dai_link[i];

        ret = soc_init_dai_link(card, link);
        if (ret) {
            dev_err(card->dev, "ASoC: failed to init link %s\n",
                link->name);
            return ret;
        }
    }
    ...
}

soc_init_dai_link执行后,会出现下面红框内的链接

 继续分析

asoc_simple_card_probe -> devm_snd_soc_register_card -> snd_soc_register_card -> snd_soc_instantiate_card -> soc_bind_dai_link

int snd_soc_register_card(struct snd_soc_card *card)
{
       ...
    dev_set_drvdata(card->dev, card);
    snd_soc_initialize_card_lists(card);
    INIT_LIST_HEAD(&card->dai_link_list);
    card->num_dai_links = 0;

    INIT_LIST_HEAD(&card->rtd_list);
    card->num_rtd = 0;

    INIT_LIST_HEAD(&card->dapm_dirty);
    INIT_LIST_HEAD(&card->dobj_list);
    card->instantiated = 0;
    mutex_init(&card->mutex);
    mutex_init(&card->dapm_mutex);

    ret = snd_soc_instantiate_card(card);
       ...
    }
}

static int snd_soc_instantiate_card(struct snd_soc_card *card)
{
    struct snd_soc_pcm_runtime *rtd;
    struct snd_soc_dai_link *dai_link;
    int ret, i, order;

    mutex_lock(&client_mutex);
    mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT);

    /* check whether any platform is ignore machine FE and using topology */
    soc_check_tplg_fes(card);

    /* bind DAIs */
    for (i = 0; i < card->num_links; i++) {
        ret = soc_bind_dai_link(card, &card->dai_link[i]);
        if (ret != 0)
            goto base_error;
    }
    
    ...
}

static int soc_bind_dai_link(struct snd_soc_card *card,
    struct snd_soc_dai_link *dai_link)
{
    struct snd_soc_pcm_runtime *rtd;
    struct snd_soc_dai_link_component *codecs = dai_link->codecs;
    struct snd_soc_dai_link_component cpu_dai_component;
    struct snd_soc_component *component;
    struct snd_soc_dai **codec_dais;
    struct device_node *platform_of_node;
    const char *platform_name;
    int i;

    if (dai_link->ignore)
        return 0;

    dev_dbg(card->dev, "ASoC: binding %s\n", dai_link->name);

    if (soc_is_dai_link_bound(card, dai_link)) {
        dev_dbg(card->dev, "ASoC: dai link %s already bound\n",
            dai_link->name);
        return 0;
    }

    /* 创建rtd */
    rtd = soc_new_pcm_runtime(card, dai_link);
    if (!rtd)
        return -ENOMEM;

    cpu_dai_component.name = dai_link->cpu_name;
    cpu_dai_component.of_node = dai_link->cpu_of_node;
    cpu_dai_component.dai_name = dai_link->cpu_dai_name;
    rtd->cpu_dai = snd_soc_find_dai(&cpu_dai_component);
    if (!rtd->cpu_dai) {
        dev_info(card->dev, "ASoC: CPU DAI %s not registered\n",
             dai_link->cpu_dai_name);
        goto _err_defer;
    }
    
    /* 关联cpu */
    snd_soc_rtdcom_add(rtd, rtd->cpu_dai->component);
    rtd->num_codecs = dai_link->num_codecs;

    /* Find CODEC from registered CODECs */
    codec_dais = rtd->codec_dais;
    for (i = 0; i < rtd->num_codecs; i++) {
        codec_dais[i] = snd_soc_find_dai(&codecs[i]);
        if (!codec_dais[i]) {
            dev_err(card->dev, "ASoC: CODEC DAI %s not registered\n",
                codecs[i].dai_name);
            goto _err_defer;
        }
        snd_soc_rtdcom_add(rtd, codec_dais[i]->component);
    }

    /* Single codec links expect codec and codec_dai in runtime data */
    rtd->codec_dai = codec_dais[0];

    /* if there's no platform we match on the empty platform */
    platform_name = dai_link->platform_name;
    if (!platform_name && !dai_link->platform_of_node)
        platform_name = "snd-soc-dummy";

    /* find one from the set of registered platforms */
    list_for_each_entry(component, &component_list, list) {
        platform_of_node = component->dev->of_node;
        if (!platform_of_node && component->dev->parent->of_node)
            platform_of_node = component->dev->parent->of_node;

        if (dai_link->platform_of_node) {
            if (platform_of_node != dai_link->platform_of_node)
                continue;
        } else {
            if (strcmp(component->name, platform_name))
                continue;
        }
        /* 关联codec*/
        snd_soc_rtdcom_add(rtd, component);
    }

    soc_add_pcm_runtime(card, rtd);
    return 0;

_err_defer:
    soc_free_pcm_runtime(rtd);
    return  -EPROBE_DEFER;
}

asoc_simple_card_probe -> devm_snd_soc_register_card -> snd_soc_register_card -> snd_soc_instantiate_card -> snd_soc_add_dai_link

 

static int snd_soc_instantiate_card(struct snd_soc_card *card)
{
    /* add predefined DAI links to the list */
    for (i = 0; i < card->num_links; i++) 
        snd_soc_add_dai_link(card, card->dai_link+i);
    ...
}

主要是将dai_link挂载到card的dai_link上面,上图已经连接

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/715437.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MS1825 SDK 移植指南

1. 概述 MS1825 SDK 支持以下 Macrosilicon 芯片&#xff0c;按照芯片功能组合的不同&#xff0c; SDK 中相关 API 和类型的定义有所 不同&#xff0c;请在该文档 API 和类型说明时特别关注&#xff1a; MS1825 SDK 的作用是帮助用户建立基于 MS1825 的视频输入输…

力扣 17. 电话号码的字母组合

题目来源&#xff1a;https://leetcode.cn/problems/letter-combinations-of-a-phone-number/description/ C题解&#xff1a; 递归法。 确定回溯函数参数&#xff1a;首先需要一个字符串s来收集叶子节点的结果&#xff0c;一个字符串数组result保存起来&#xff0c;定义为全局…

78-基于stm32单片机电压电流检测LCD1602显示(程序+原理图+元件清单全套资料)...

资料编号&#xff1a;078 功能介绍&#xff1a;采用stm32单片机作为主控CPU&#xff0c;采用精密电阻分压将高电压分压后接入STM32单片机ADC接口&#xff0c;采用ADC可以采集出当前的电压值&#xff0c;通过功率电阻来测量电路中的电流&#xff0c;通过串联电路电流相同的原理&…

正则表达式 教程与简介 | 一看就懂!!!(一)

目录 一、正则表达式 - 教程 二、 正则表达式的模式 &#xff08;一&#xff09;字面值字符 &#xff08;二&#xff09;特殊字符 &#xff08;三&#xff09;字符类 &#xff08;四&#xff09;元字符 &#xff08;五&#xff09;量词 &#xff08;六&#xff09;边界…

如何进行小红书笔记关键词布局,热词分析!

坐拥2.6亿活跃用户&#xff0c;小红书已经成为品牌宣推、种草的重要平台之一。那么品牌进入平台&#xff0c;如何进行小红书笔记关键词布局&#xff0c;热词分析&#xff01; 一、 如何确定关键词 想要做好小红书关键词布局&#xff0c;首先要明确如何确定关键词。 1、当我们要…

shell判断程序是否运行,守护进程

一、需求 服务部署在linux上&#xff0c;要求服务器上的服务可以一直保持正常运行 二、问题 在linux上部署的微服务&#xff0c;不知道什么原因过一段时间就自己停掉了&#xff0c;无法启动。 三、解决办法 添加angle守护进程&#xff0c;通过定时执行脚本来判断程序是否运行…

为什么对ChatGPT、ChatGLM这样的大语言模型说“你是某某领域专家”,它的回答会有效得多?(一)...

“ 太长不看总结版&#xff1a;LLM大模型的本质在于计算某个词汇后面应该跟着哪些词汇的概率。当问题给定了特定的限定范围后&#xff0c;它能够找到一条相对明确的计算路径&#xff0c;从一系列概率分布中挑选出所需的答案。否则&#xff0c;它会根据最常见且最高概率的组合方…

浑元太极马老师和小薇-UMLChina建模知识竞赛第4赛季第7轮[更新]

DDD领域驱动设计批评文集 欢迎加入“软件方法建模师”群 《软件方法》各章合集 参考潘加宇在《软件方法》和UMLChina公众号文章中发表的内容作答。在本文下留言回答。 第7轮一直无人得分&#xff0c;再次更换题目。 因有的题目之前已经出过&#xff0c;本轮需要最先答对全…

聊天室(二)__ unipush 推送如何实现?

你想搞个自己的聊天室 app 吗&#xff1f;好多前端同学会好奇聊天室app的推送是怎么搞的&#xff1f;今天就以前端同学使用最多的 uniapp 开发的 app 推送为例&#xff0c;悄悄告诉大家推送是如何实现的&#xff01; 项目技术栈&#xff1a; 项目基于 vue3 的 uniapp 推送基于…

从小白到大神之路之学习运维第51天---第三阶段----redis高可用集群数据库的安装部署

第三阶段基础 时 间&#xff1a;2023年7月3日 参加人&#xff1a;全班人员 内 容&#xff1a; 生产级redis cluster部署 目录 一、环境配置&#xff1a;【两台服务器】 二、redis多实例配置&#xff1a; 三、构建redis cluster集群 四、生产集群部署 五、集群故障切…

Makefile:1: *** 遗漏分隔符 (null)。 停止。解决方法

在使用ubuntu时&#xff0c;make命令后&#xff0c;直接弹出了个错误。。。。。。 Makefile: n n表示出问题的行数&#xff0c;仔细检查代码的内容&#xff0c;主要问题可能是该有的空格是否添加或者使用$引入的参数是否存在等 我的问题是这个 ifneq 后面的空格没有加 耐心查…

论文浅尝 | 大语言模型综述

笔记整理&#xff1a;刘康为、方润楠&#xff0c;浙江大学硕士&#xff0c;研究方向为自然语言处理 链接&#xff1a;https://arxiv.org/abs/2303.18223 一、介绍 在当前机遇和挑战的背景下&#xff0c;对大语言模型的研究和开发需要更多的关注。为了让读者对大语言模型有一个基…

C++实现打包工具代码框架(附源码)

C++常用功能源码系列 文章目录 C++常用功能源码系列前言一、打包工具二、packtool框架前言 本文是C/C++常用功能代码封装专栏的导航贴。部分来源于实战项目中的部分功能提炼,希望能够达到你在自己的项目中拿来就用的效果,这样更好的服务于工作实践。 专栏介绍:专栏讲本人近…

windows10安装wsl2,centos内核

windows10安装wsl2&#xff0c;centos内核 检查系统环境 必须运行 Windows 10 版本 2004 及更高版本&#xff08;内部版本 19041 及更高版本&#xff09;或 Windows 11 才能使用以下命令。 一、开启WSL2特性 【控制面板】>>【程序】>>【程序和功能】>>【启…

apple pencil平替笔哪个好用?适用于绘画的电容笔推荐

由于ipad的版本一直在升级&#xff0c;其功能也在增加&#xff0c;其功能已经达到了与手提电脑相媲美的程度。而且随着科技的发展&#xff0c;ipad也不仅仅是一个娱乐的工具&#xff0c;更是一个可以用来学习、画画、工作的强大工具。想要提高生产力&#xff0c;那么电容笔就是…

mysql 8.0版本更换用户密码

1、首先 cmd 进入命令行 mysql -uroot -p 2、查询版本号 select version(); 3、看一下数据库 show databases; 4、使用mysql即可 5、进行查询 user、host select user,host from user; 6、修改root的密码 alter user root% identified by 1234; 7、刷新权限 flush privi…

Kubernetes 服务发布方式(蓝绿发布、灰度发布和滚动发布)

目录 一、三种常用的项目发布方式1.1 蓝绿发布1.2 灰度发布&#xff08;金丝雀发布&#xff09;1.3 滚动发布 二、金丝雀的方式升级发布实验三、总结 一、三种常用的项目发布方式 应用程序升级面临最大挑战是新旧业务切换&#xff0c;将软件从测试的最后阶段带到生产环境&…

Windows服务器——部署WSUS服务与综合测试

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​ 目录 前言 本章结构&#xff1a; 一.WSUS概述 1.WSUS概述 2.WSUS的特点 3.WSUS常见部署…

fastboot连接@设备识别问题

文章目录 fastboot模式(MIUI)界面变换fastboot链接电脑设备识别问题连接部件的兼容性 fastboot模式(MIUI)界面变换 老设备新设备 fastboot链接电脑设备识别问题 通常一根普通的数据线和PC就能够识别处于fastboot(bootloader)模式下的android设备 扫描已连接的bootloader模式…

软件设计模式与体系结构-设计模式-结构型软件设计模式-外观模式

目录 三、外观模式概念外观模式分析实例一&#xff1a;实例二&#xff1a;图形绘制外观模式讨论一个系统有多个外观类&#xff1f;不要试图通过外观类为子系统增加新行为外观模式与迪米特法则抽象外观类的引入 &#xff08;因为违背开闭原则&#xff09;使用外观模式的目的适配…