[Linux Audio Driver] Android 10 machine driver probe函数分析

[蓝牙] 1、蓝牙核心技术了解(蓝牙协议、架构、硬件和软件笔记)     声明:这篇文章是楼主beautifulzzzz学习网上关于蓝牙的相关知识的笔记,其中比较多的受益于xubin341719的蓝牙系列文章,同时还有其他网上作者的资料。由于有些文章只做参考或统计不足,如涉及版权请在下面留言~。同时我也在博客分类中新建一个蓝牙通信分类,用来研究分享蓝牙相关技术。   主要参考资料的来源:xubin341719[下面是该前辈的BT系列文章]下载连接:Blu... 阅读详情

0. 背景

平台:Qualcomm 5G SM6350、android10、kernel version: msm-4.19。

本文重点分析machine driver里面的msm_asoc_machine_probe函数,这个是machie驱动的核心代码,涉及声卡解析注册,CPU dai和codec dai绑定,麦克偏置解析配置routing、耳机麦克检测(欧-美标兼容)、MI2S主、从模式配置,以及新增的LPASS音频投票机制。

此外,msm_asoc_machine_probe函数也可以说就干了一件事:
实例化结构体snd_soc_card。

那个,兄弟们转载博客还是希望附上我的转载链接啊,不要直接copy,也是尊重人不是 -_-。
在这里插入图片描述

1. msm_asoc_machine_probe

代码位置:

./vendor/qcom/opensource/audio-kernel/asoc/kona.c

msm_asoc_machine_probe整个函数如下:

static int msm_asoc_machine_probe(struct platform_device *pdev)
{
   
   
	struct snd_soc_card *card = NULL;
	struct msm_asoc_mach_data *pdata = NULL;
	const char *mbhc_audio_jack_type = NULL;
	int ret = 0;
	uint index = 0;
	struct clk *lpass_audio_hw_vote = NULL;

	if (!pdev->dev.of_node) {
   
   
		dev_err(&pdev->dev, "%s: No platform supplied from device tree\n", __func__);
		return -EINVAL;
	}

	pdata = devm_kzalloc(&pdev->dev,
			sizeof(struct msm_asoc_mach_data), GFP_KERNEL);
	if (!pdata)
		return -ENOMEM;

	of_property_read_u32(pdev->dev.of_node,
				"qcom,lito-is-v2-enabled",
				&pdata->lito_v2_enabled);


	card = populate_snd_card_dailinks(&pdev->dev);
	if (!card) {
   
   
		dev_err(&pdev->dev, "%s: Card uninitialized\n", __func__);
		ret = -EINVAL;
		goto err;
	}

	card->dev = &pdev->dev;
	platform_set_drvdata(pdev, card);
	snd_soc_card_set_drvdata(card, pdata);

	ret = snd_soc_of_parse_card_name(card, "qcom,model");
	if (ret) {
   
   
		dev_err(&pdev->dev, "%s: parse card name failed, err:%d\n",
			__func__, ret);
		goto err;
	}


	ret = snd_soc_of_parse_audio_routing(card, "qcom,audio-routing");
	if (ret) {
   
   
		dev_err(&pdev->dev, "%s: parse audio routing failed, err:%d\n",
			__func__, ret);
		goto err;
	}


	ret = msm_populate_dai_link_component_of_node(card);
	if (ret) {
   
   
		ret = -EPROBE_DEFER;
		goto err;
	}


	ret = msm_init_aux_dev(pdev, card);
	if (ret)
		goto err;


	ret = devm_snd_soc_register_card(&pdev->dev, card);
	if (ret == -EPROBE_DEFER) {
   
   
		if (codec_reg_done)
			ret = -EINVAL;
		goto err;
	} else if (ret) {
   
   
		dev_err(&pdev->dev, "%s: snd_soc_register_card failed (%d)\n",
			__func__, ret);
		goto err;
	}
	dev_err(&pdev->dev, "%s: Sound card %s registered\n", __func__, card->name);


	kona_parse_aw87xx_mode(pdev, pdata);
	pdata->spk_ext_pa_gpio_p = of_parse_phandle(pdev->dev.of_node, 
	"qcom,msm-spk-ext-pa-gpios", 0);
	if (!pdata->spk_ext_pa_gpio_p) {
   
   
		pr_err("%s: property %s not detected in node %s\n", __func__, 
		"qcom,msm-spk-ext-pa-gpios", pdev->dev.of_node->full_name);
	}else{
   
   
		ret = msm_cdc_pinctrl_select_sleep_state(pdata->spk_ext_pa_gpio_p);
		if (ret < 0) {
   
   
			pr_err("%s: gpio set cannot be activated %s\n", __func__, "speaker_pa_gpio");
			return ret;
		}
	}

	ret = of_property_read_u32(pdev->dev.of_node, "qcom,tdm-max-slots",
				   &pdata->tdm_max_slots);
	if (ret) {
   
   
		dev_err(&pdev->dev, "%s: No DT match for tdm max slots\n",
			__func__);
	}
	if ((pdata->tdm_max_slots <= 0) || (pdata->tdm_max_slots >
	    TDM_MAX_SLOTS)) {
   
   
		pdata->tdm_max_slots = TDM_MAX_SLOTS;
		dev_err(&pdev->dev, "%s: Using default tdm max slot: %d\n",
			__func__, pdata->tdm_max_slots);
	}

	pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node,
						"qcom,hph-en1-gpio", 0);
	if (!pdata->hph_en1_gpio_p) {
   
   
		dev_dbg(&pdev->dev, "%s: property %s not detected in node %s\n",
			__func__, "qcom,hph-en1-gpio",
			pdev->dev.of_node->full_name);
	}

	pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node,
						"qcom,hph-en0-gpio", 0);
	if (!pdata->hph_en0_gpio_p) {
   
   
		dev_dbg(&pdev->dev, 
ASoC音频驱动开发实战:从Codec注册到DAPM调试 在嵌入式Linux系统中,音频子系统通过ASoC框架实现SoC与Codec的解耦。其核心原理是将音频系统拆分为Platform、Codec和Machine三层,利用DAPM实现动态电源管理,并通过kcontrol提供用户空间控制接口。这种架构显著提升了驱动复用性和可维护性,广泛应用于智能音箱、车载娱乐等场景。理解寄存器访问、DAPM widget与route配置,是解决音频驱动调试问题的关键。 阅读详情

相关推荐

Android Qcom Audio入门学习

在devictree中可以发现有其实在PIL驱动并没有发生image加载过程,真正的加载有对应的子模块处理中,adsp就是在adsp-loader.c中通过init.qcom.rc启动时 write /sys/kernel/boot_adsp/boot 1 ,之后就会subsystem_get(“adsp”)获取并加载;其他例如slpi, 要看高通不同的平台子模块的组成,有些PIL是没有load slpi模块,sensor也是adsp中,

Android驱动开发 8623

【Qualcomm高通音频】MSM8953安卓7如何配置QUIN MI2S为从模式?

1. pinctrl配置 高通平台配置一组I2S一般对应四个或者六个GPIO, QUIN MI2S对应GPIO88 GPIO91 GPIO92 GPIO93 对应代码文件为:kernel/msm-3.18/arch/arm/boot/dts/qcom/msm8953-pinctrl.dtsi pri-tlmm-lines { pri_tlmm_lines_act: pri_tl...

crow_ch的博客 3904

车载音频开发实战:从ALSA/ASoC驱动到虚拟声卡实现

音频子系统是现代嵌入式系统中连接应用与硬件的关键软件层,其核心在于管理音频数据的输入、输出与处理流程。其工作原理基于分层架构,通过硬件抽象层(HAL)和内核驱动框架(如ALSA/ASoC)实现硬件与应用的解耦,从而提供统一的音频服务接口。这一设计具有重要的技术价值,它确保了系统的可移植性与可维护性,使得上层应用无需关心底层芯片差异。在车载信息娱乐系统等对可靠性、低延迟和多音源管理有严苛要求的应用场景中,一个稳定高效的音频驱动栈至关重要。本文聚焦于车载音频开发,通过剖析ALSA与ASoC框架,并提供一个完整的

weixin_30596343的博客 345

嵌入式Linux ASoC音频驱动开发:Codec控件与DAPM通路全解析

在嵌入式Linux系统中,音频设备驱动开发往往涉及复杂的总线拓扑与电源管理约束。ASoC(ALSA System on Chip)框架通过Machine、Platform、Codec三块拆分,将芯片能力与板级接线解耦,使得Codec驱动可以独立复用。其中音频控件(kcontrol)用于暴露音量、路由等控制项,DAPM则根据音频通路动态管理电源,降低功耗并避免爆音。理解这些基础机制后,开发者可借助设备树与Machine驱动快速完成音频链路适配,并通过tinymix、debugfs等工具排查无声、噪声等问题。本

weixin_34268169的博客 783

RK3576+Android14集成RG200U-CN 5G模组全栈适配指南

5G模组集成是嵌入式Android系统开发的关键技术环节,其本质是跨层协同:从内核PCIe/USB设备枚举与电源管理,到HAL层QMI协议栈实现与RIL状态机设计,再到Framework对CarrierConfigService和信号强度解析的深度适配。随着Android 14强制启用RIL HAL v3.0、Rockchip RK3576引入独立PCIe PHY与USB 3.1 Gen2控制器,传统‘驱动移植+RIL补丁’模式已失效。本文聚焦RK3576平台与RG200U-CN模组的真实工程实践,覆盖PC

weixin_33895657的博客 423

嵌入式Linux ASoC音频驱动开发:Codec驱动、kcontrol与DAPM实战

在嵌入式Linux系统中,音频子系统通过ASoC(ALSA System on Chip)框架实现分层解耦,将音频芯片驱动(Codec)、SoC控制器驱动(Platform)和板级绑定(Machine)分离。其核心原理在于通过kcontrol控件映射用户空间与寄存器,并借助DAPM动态电源管理按需上电,从而降低功耗、提升系统稳定性。这一机制在智能音箱、车载娱乐、工业HMI等场景中至关重要。然而,开发者常因控件注册错误、DAPM路由缺失或时钟配置不当导致无声、杂音或录音失败。本文聚焦Codec驱动开发,深入拆

weixin_34174322的博客 609

SM6350 死机分析(一)

1.通过QCAP解析dump可知: 从dmesg来看不确定是串口导致的死机还是蓝牙固件导致的死机,先规避下,屏蔽串口一直打印的log。根本原因待分析。 高通这块很恶心,SPI,uart,i2c这些个总线全放在QUPV,封装了固件看不到源码,高通FAE都看不到,封装到TZ里面,美其名曰为了安全,这块的研发好像在印度。。。 可以看看RTB是哪个cpu在哪出的问题 ...

墨染天玑的博客 1096

【Qt】使用QMediaPlayer播放视频

window平台可以安装K-Lite,linux平台一般各发行版都会默认安装GSteam。播放RTSP视频时,可以使用VLC播放器搭建一个视频推流服务器,用于拉流的客户端的调试。3、如果没有添加Qt环境变量,请把关联的Qt5MultimediaWidgets.dll和Qt5Multimedia.dll放到进程路径下否则也会报ServiceMissingError错误。2、需要安装解码器,否则报 ServiceMissingError 无法找到服务的错误。1、需要在.pro工程文件中引用对应模块。

奔涌的后浪的专栏 2219

STM32F407 CanOpen主机实战:对象字典配置与多电机CIA402协议驱动详解

本文详细介绍了基于STM32F407的CanOpen主机开发实战,重点解析了对象字典的配置流程与多电机CIA402协议驱动方法。通过使用objdictedit工具配置SDO和PDO参数,并整合CanFestival协议栈,实现了对多个伺服电机的稳定同步控制。文章提供了从硬件连接到代码调试的完整指南,帮助开发者快速掌握工业现场的多轴运动控制技术。

plant的博客 529

080、多轴运动控制:插补器设计(螺旋线插补)

本文分享了螺旋线插补器设计的实战经验。针对五轴点胶机Z轴抖动问题,作者分析了螺旋线数学本质,提出基于归一化时间参数的速度规划方法,强调各轴严格同步的重要性。文章详细介绍了速度分解、加减速处理、嵌入式优化技巧(查表法、定点化),并总结了起点闭合、速度波动、数值处理等常见问题解决方案。最后给出5条实用建议:注重速度规划而非纯数学推导、预先仿真、保留调试接口、考虑机械谐振、防范编码器丢脉冲。通过优化插补周期、电子齿轮比和S形速度曲线,成功将设备良率从60%提升至95%。

m0_50546716的博客 85

winform自定义控件(gdi+)(1)———设置透明背景色

本文详细讲解了如何在winform中设置控件的背景色为透明色

qq_34059233的博客 3686

02 HCM CPI SF集成-组织集成(一)

将员工主数据和组织数据从SAP Successfactors Employee CentraI复制到SAPERP或SAP S/4HANA,SAP SF CPI HCM集成

SAP CPI 129

点云统计滤波 (python详细过程版)【2025最新版】

统计滤波python详细过程版,博客长期更新,本文最近更新时间为:2025年1月12日。

点云侠的博客 5638

Android编译系统——Android.bp语法介绍(十五)

Android.bp 是 Android 构建系统(Android Build System)中的配置文件,用于描述如何编译和打包项目中的模块。它是用 Blueprint 编写的,其语法类似于 JSON,但专为 Android 编译系统设计,提供了更高效、灵活的模块化管理。

小旭的专栏 939

[QMT和ptrade量化交易小白入门]-121、如何用K-means聚类,每月自动筛选高流动性ETF

本专栏主要是介绍QMT和ptrade的基础用法,常见函数,写策略的方法,也会分享一些量化交易的思路,大概会写200篇左右。QMT的相关资料较少,在使用过程中不断的摸索,遇到了一些问题,记录下来和大家一起沟通,共同进步。

木头大左的博客 828

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

上一篇: [Linux Audio Driver] 高通平台麦克偏置电压取值范围
下一篇: [Linux Camera Driver] 开机之后获取camera型号方法
1byte ≠ 8bit
博客等级 码龄8年 7242粉丝 170原创
评论 13
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值