4. 注册machine

news/2025/3/4 14:56:22/

数字mic系列,注册machine

 dts配置如下

    digital_mic: digital-mic {status = "okay";compatible = "simple-audio-card";simple-audio-card,format = "i2s";simple-audio-card,mclk-fs = <256>;simple-audio-card,name = "digital-mic";simple-audio-card,cpu {sound-dai = <&i2s0_8ch>;};simple-audio-card,codec {sound-dai = <&dummy_codec>;};};

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

static int asoc_simple_card_probe(struct platform_device *pdev)
{struct simple_card_data *priv;struct snd_soc_dai_link *dai_link;struct simple_dai_props *dai_props;struct device *dev = &pdev->dev;struct device_node *np = dev->of_node;struct snd_soc_card *card;int num, ret;/* Get the number of DAI links */if (np && of_get_child_by_name(np, PREFIX "dai-link"))num = of_get_child_count(np);else/* 对于dai-link*/num = 1;/* Allocate the private data and the DAI link array */priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);if (!priv)return -ENOMEM;dai_props = devm_kcalloc(dev, num, sizeof(*dai_props), GFP_KERNEL);dai_link  = devm_kcalloc(dev, num, sizeof(*dai_link), GFP_KERNEL);if (!dai_props || !dai_link)return -ENOMEM;priv->dai_props         = dai_props;priv->dai_link          = dai_link;/* Init snd_soc_card */card = simple_priv_to_card(priv);card->owner     = THIS_MODULE;card->dev       = dev;card->dai_link      = priv->dai_link;card->num_links     = num;card->probe     = asoc_simple_soc_card_probe;if (np && of_device_is_available(np)) {ret = asoc_simple_card_parse_of(priv);if (ret < 0) {if (ret != -EPROBE_DEFER)dev_err(dev, "parse error %d\n", ret);goto err;}} else {...}snd_soc_card_set_drvdata(card, priv);

asoc_simple_card_probe() -> asoc_simple_is_available()

 

static int asoc_simple_card_parse_of(struct simple_card_data *priv)
{struct device *dev = simple_priv_to_dev(priv);struct snd_soc_card *card = simple_priv_to_card(priv);struct device_node *dai_link;struct device_node *node = dev->of_node;int ret;if (!node)return -EINVAL;/* 这里会匹配 simple-audio-card,dai-link 子节点 */dai_link = of_get_child_by_name(node, PREFIX "dai-link");/* 解析 simple-audio-card,widgets 属性 */ret = asoc_simple_card_of_parse_widgets(card, PREFIX);if (ret < 0)goto card_parse_end;/* 解析 simple-audio-card,routing 属性 */ret = asoc_simple_card_of_parse_routing(card, PREFIX, 1);if (ret < 0)goto card_parse_end;/* Factor to mclk, used in hw_params() *//* 解析 simple-audio-card,mclk-fs 属性 */of_property_read_u32(node, PREFIX "mclk-fs", &priv->mclk_fs);/* Single/Muti DAI link(s) & New style of DT node *//* 不支持 跳过 */if (dai_link) {struct device_node *np = NULL;int i = 0;for_each_child_of_node(node, np) {dev_dbg(dev, "\tlink %d:\n", i);ret = asoc_simple_card_dai_link_of(np, priv,i, false);if (ret < 0) {of_node_put(np);goto card_parse_end;}i++;}} else {/* For single DAI link & old style of DT node */ret = asoc_simple_card_dai_link_of(node, priv, 0, true);if (ret < 0)goto card_parse_end;}/* label属性没有 * card->dai_link->name*/ret = asoc_simple_card_parse_card_name(card, PREFIX);if (ret < 0)goto card_parse_end;/* 没有aux-devs */ret = asoc_simple_card_parse_aux_devs(node, priv);card_parse_end:of_node_put(dai_link);return ret;
}

asoc_simple_card_probe() -> asoc_simple_is_available() -> asoc_simple_card_dai_link_of()

static int asoc_simple_card_dai_link_of(struct device_node *node,struct simple_card_data *priv,int idx,bool is_top_level_node)
{struct device *dev = simple_priv_to_dev(priv);struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);struct simple_dai_props *dai_props = simple_priv_to_props(priv, idx);struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai;struct asoc_simple_dai *codec_dai = &dai_props->codec_dai;struct device_node *cpu = NULL;struct device_node *plat = NULL;struct device_node *codec = NULL;char prop[128];char *prefix = ""; int ret, single_cpu;/* For single DAI link & old style of DT node */if (is_top_level_node)prefix = PREFIX;snprintf(prop, sizeof(prop), "%scpu", prefix);/* simple-audio-card,cpu 节点 */cpu = of_get_child_by_name(node, prop);if (!cpu) {ret = -EINVAL;dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);goto dai_link_of_err;}   snprintf(prop, sizeof(prop), "%splat", prefix);/* simple-audio-card,plat 节点 ,可以没有 */plat = of_get_child_by_name(node, prop);snprintf(prop, sizeof(prop), "%scodec", prefix);/* simple-audio-card,codec 节点 */codec = of_get_child_by_name(node, prop);if (!codec) {ret = -EINVAL;dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);goto dai_link_of_err;}   /* 获取dai_fmt  主要通过machine和codec进行判断 */ret = asoc_simple_card_parse_daifmt(dev, node, codec,prefix, &dai_link->dai_fmt);if (ret < 0)goto dai_link_of_err;of_property_read_u32(node, "mclk-fs", &dai_props->mclk_fs);/* 这里会找到platform* dai_link->cpu_of_node 会填充platform节点*/ret = asoc_simple_card_parse_cpu(cpu, dai_link,DAI, CELL, &single_cpu);if (ret < 0)goto dai_link_of_err;/* dai_link->codec_of_node 会填充codec节点 */ret = asoc_simple_card_parse_codec(codec, dai_link, DAI, CELL);if (ret < 0)goto dai_link_of_err;/* 没有platform code */ret = asoc_simple_card_parse_platform(plat, dai_link, DAI, CELL);if (ret < 0)goto dai_link_of_err;/* 不支持 */ret = asoc_simple_card_of_parse_tdm(cpu, cpu_dai);if (ret < 0)goto dai_link_of_err;/* 不支持 */ret = asoc_simple_card_of_parse_tdm(codec, codec_dai);if (ret < 0)goto dai_link_of_err;/* platform clk节点 * 查找顺序* 1. platform (simple-audio-card,cpu)节点的 clock * 2. platform (simple-audio-card,cpu)节点的 system-clock-frequency* 3. dai_link->cpu_of_node (i2s0_8ch) 节点的 clock*    这里是不是会到rcu ? 且只拿第一个时钟*/ret = asoc_simple_card_parse_clk_cpu(dev, cpu, dai_link, cpu_dai);if (ret < 0)goto dai_link_of_err;/* codec clk节点 * 查找顺序* 1. codec (simple-audio-card,codec)节点的 clock * 2. codec (simple-audio-card,codec)节点的 system-clock-frequency* 3. dai_link->codec_of_node (dummy_codec) 节点的 clock*/ret = asoc_simple_card_parse_clk_codec(dev, codec, dai_link, codec_dai);if (ret < 0)goto dai_link_of_err;/* 没有platform_of_node * platform_of_node = cpu_of_node */ret = asoc_simple_card_canonicalize_dailink(dai_link);if (ret < 0)goto dai_link_of_err;/* "ff800000.i2s-tdm-dummy_codec"* dai_link->name & dai_link->stream_name    */ret = asoc_simple_card_set_dailink_name(dev, dai_link,"%s-%s",dai_link->cpu_dai_name,dai_link->codec_dai_name);if (ret < 0)goto dai_link_of_err;dai_link->ops = &asoc_simple_card_ops;dai_link->init = asoc_simple_card_dai_init;/* dai_link->cpu_dai_name = NULL */asoc_simple_card_canonicalize_cpu(dai_link, single_cpu);dai_link_of_err:of_node_put(cpu);of_node_put(codec);return ret;
}

 

 


http://www.ppmy.cn/news/708550.html

相关文章

海康播放监控

播放h265流解决方案 文中代码&#xff1a;https://github.com/moxiefxj/video_vue 1. 视频WEB插件 视频WEB插件,下载的压缩包中含有播放监控所需要的插件、开发的demo等。在项目中具体的实现&#xff08;以vue组件实现为例&#xff09; <template><!--视频窗口展示-…

海康威视设备在Web端显示实时(回放)视频

前言 目前做的项目&#xff0c;需要Web端显示实时视频数据。本次项目使用的是海康威视的摄像头进行实时监控。 硬件&#xff1a;海康威视的摄像头 软件&#xff1a;video.js、nginx、vlc 参考&#xff1a;https://blog.csdn.net/qq_36720088/article/details/82893924?utm…

Android 集成海康威视监控 SDK,实现监控录像的查看

Android 集成海康威视监控 SDK&#xff0c;实现监控录像的查看 配置 切换Android studio 到project目录下&#xff0c;分别将jar包与armeabi包复制进去lib文件夹下&#xff1a; 设置app bulid.gradle文件 主要是添加CPU限制 只支持32位 以及添加so包的路径、添加jar包依赖&am…

vue2实现海康威视根据海康插件进行监控实时预览和回放功能,全套代码,开箱即用。

这是一套拿到手就能直接用的根据海康提供的摄像机节点实时预览和回放的全步骤代码&#xff0c;开箱即用。 前言 我的是基于vue2写的&#xff0c;vue3可以看我下一篇文章。 点击跳转至vue3关于海康视频开发文章。 很多人在开发vue项目的时候&#xff0c;不知道怎么去开发视频实…

海康威视视频监控的实现

首先商家会给我们api 大家一定要认真看不然真的不明白呜呜呜 api里面双击下载这些功能 注意&#xff1a;这些appKey的是根据密钥来的 必须认真看文档拿到这个token就是下面这个形式生成的 搞了好久终于把视频效果展示出来了 注意当我们运行index的时候是html运行 转到 Visu…

uni-app引入海康威视h5player实现视频监控的播放

uni-app引入海康威视h5player实现视频监控的播放 知识储备工具下载webplayer.htmlh5player.vue视频时效传递参数为中文webview 返回上一页在H5环境中使用window.postMessage通信&#xff0c;webview向uni-app应用发送消息uni-app中不使用webview、直接在.vue中播放视频 知识储备…

Docker镜像是什么原理?Dockerfile是什么?

Dockerfile 一、docker镜像原理 Linux文件系统有bootfs和rootfs两部分组成 bootfs&#xff1a; 包含bootloader&#xff08;引导加载程序&#xff09;和kernel&#xff08;内核&#xff09;rootfs&#xff1a; root文件系统&#xff0c;包含的就是典型Linux系统中的 /dev&…

WEB端项目中接入海康监控视频播放监控画面

需求&#xff1a; 以树形结构展示组织以及组织下的摄像头列表&#xff0c;点击单个摄像头进行预览效果图&#xff1a; 该博客基于 海康开放平台API开发 准备工作 1. APPkey、APPsecret、服务器ip地址、端口号 2. [OpenAPI 安全认证库 &#xff08;JAVA&#xff09; V1.1.3](…