edison intel sst audio驱动注册流程

一. device 部分注册流程

  1. arch/x86/platform/intel-mid/Board.c
    struct devs_id __initconst device_ids[] = {
    ... ...
    	{"mrfld_sst", SFI_DEV_TYPE_IPC, 1, &mrfld_sst_audio_platform_data,
    						&ipc_device_handler},
    

  2. arch/x86/platform/intel-mid/device_libs/Platform_mrfld_audio.c
    void *mrfld_sst_audio_platform_data(void *info)
    {
    	struct platform_device *pdev;
    	int ret;
    
    	ret = add_sst_platform_device();
    	if (ret < 0) {
    		pr_err("%s failed to sst_platform device\n", __func__);
    		return NULL;
    	}
    
    	if(!audio_codec || !strcmp(audio_codec, "dummy")) {
    		pdev = platform_device_register_simple("merr_dpcm_dummy",
    					0, NULL, 0);
    		if (!pdev) {
    			pr_err("failed to register merr_dpcm_dummy platform device\n");
    			return NULL;
    		}
    	} else if (!strcmp(audio_codec, "wm8958")) {
    


  3. arch/x86/platform/intel-mid/device_libs/Platform_sst_audio.c
    int add_sst_platform_device(void)
    {
    	struct platform_device *pdev = NULL;
    	int ret;
    
    	populate_platform_data();
    
    	pdev = platform_device_alloc("sst-platform", -1);
    	if (!pdev) {
    		pr_err("failed to allocate audio platform device\n");
    		return -EINVAL;
    	}
    
    	ret = platform_device_add_data(pdev, &sst_platform_pdata,
    					sizeof(sst_platform_pdata));
    	if (ret) {
    		pr_err("failed to add sst platform data\n");
    		platform_device_put(pdev);
    		return  -EINVAL;
    	}
    	ret = platform_device_add(pdev);
    	if (ret) {
    		pr_err("failed to add audio platform device\n");
    		platform_device_put(pdev);
    		return  -EINVAL;
    	}
    	return ret;
    }
    

    // 注册device "sst-platform"    和 "merr_dpcm_dummy" 完成。

二.  驱动匹配:   //  匹配  "sst-platform"  流程

  1. sound/soc/intel/pcm.c
    static struct platform_driver sst_platform_driver = {
    	.driver		= {
    		.name		= "sst-platform“,
    		.owner		= THIS_MODULE,
    	},
    	.probe		= sst_platform_probe,
    	.remove		= sst_platform_remove,
    };
    
    module_platform_driver(sst_platform_driver);
    

  2. sound/soc/intel/pcm.c
    static int sst_platform_probe(struct platform_device *pdev)
    {
    	struct sst_data *sst;
    	int ret;
    	struct sst_platform_data *pdata = pdev->dev.platform_data;
    
    	pr_debug("sst_platform_probe called\n");
    	sst = devm_kzalloc(&pdev->dev, sizeof(*sst), GFP_KERNEL);
    	if (sst == NULL) {
    		pr_err("kzalloc failed\n");
    		return -ENOMEM;
    	}
    
    	sst_pdev = &pdev->dev;
    	sst->pdata = pdata;
    	mutex_init(&sst->lock);
    	dev_set_drvdata(&pdev->dev, sst);
    
    	ret = snd_soc_register_platform(&pdev->dev,
    					 &sst_soc_platform_drv);
    	if (ret) {
    		pr_err("registering soc platform failed\n");
    		return ret;
    	}
    	ret = snd_soc_register_component(&pdev->dev, &pcm_component,
    				sst_platform_dai, ARRAY_SIZE(sst_platform_dai));
    	if (ret) {
    		pr_err("registering cpu dais failed\n");
    		snd_soc_unregister_platform(&pdev->dev);
    	}
    
    	return ret;
    }
    

  3. sound/soc/intel/pcm.c
    static struct snd_soc_platform_driver sst_soc_platform_drv  = {
    	.probe		= sst_soc_probe,
    	.remove		= sst_soc_remove,
    	.ops		= &sst_platform_ops,
    	.compr_ops	= &sst_platform_compr_ops,
    	.pcm_new	= sst_pcm_new,
    	.pcm_free	= sst_pcm_free,
    	.read		= sst_soc_read,
    	.write		= sst_soc_write,
    };

  4. sound/soc/intel/pcm.c
    static int sst_soc_probe(struct snd_soc_platform *platform)
    {
    	struct sst_data *ctx = snd_soc_platform_get_drvdata(platform);
    	struct soft_platform_id spid;
    	int ret = 0;
    
    	memcpy(&spid, ctx->pdata->spid, sizeof(spid));
    	pr_err("Enter:%s\n", __func__);
    
    #if IS_BUILTIN(CONFIG_SST_MRFLD_DPCM)
        ret = sst_dsp_init_v2_dpcm(platform);
    #else
        ret = sst_dsp_init(platform);
    #endif
    //    if (ret)
    //        return ret;
    //    ret = snd_soc_register_effect(platform->card, &effects_ops);
    
    	return ret;
    }

  5. sound/soc/intel/platform-libs/Controls_v2_dpcm.c
    int sst_dsp_init_v2_dpcm(struct snd_soc_platform *platform)
    {
    	int i, ret = 0;
    	struct sst_data *sst = snd_soc_platform_get_drvdata(platform);
    
    	sst->byte_stream = devm_kzalloc(platform->dev,
    					SST_MAX_BIN_BYTES, GFP_KERNEL);
    	if (!sst->byte_stream) {
    		pr_err("%s: kzalloc failed\n", __func__);
    		return -ENOMEM;
    	}
    	sst->widget = devm_kzalloc(platform->dev,
    				   SST_NUM_WIDGETS * sizeof(*sst->widget),
    				   GFP_KERNEL);
    	if (!sst->widget) {
    		pr_err("%s: kzalloc failed\n", __func__);
    		return -ENOMEM;
    	}
    
    	snd_soc_dapm_new_controls(&platform->dapm, sst_dapm_widgets,
    			ARRAY_SIZE(sst_dapm_widgets));
    	snd_soc_dapm_add_routes(&platform->dapm, intercon,
    			ARRAY_SIZE(intercon));
    	snd_soc_dapm_new_widgets(&platform->dapm);
    
    	for (i = 0; i < SST_NUM_GAINS; i++) {
    		sst_gains[i].mute = SST_GAIN_MUTE_DEFAULT;
    		sst_gains[i].l_gain = SST_GAIN_VOLUME_DEFAULT;
    		sst_gains[i].r_gain = SST_GAIN_VOLUME_DEFAULT;
    		sst_gains[i].ramp_duration = SST_GAIN_RAMP_DURATION_DEFAULT;
    	}
    
    	snd_soc_add_platform_controls(platform, sst_gain_controls,
    			ARRAY_SIZE(sst_gain_controls));
    
    	snd_soc_add_platform_controls(platform, sst_algo_controls,
    			ARRAY_SIZE(sst_algo_controls));
    	snd_soc_add_platform_controls(platform, sst_slot_controls,
    			ARRAY_SIZE(sst_slot_controls));
    	snd_soc_add_platform_controls(platform, sst_mux_controls,
    			ARRAY_SIZE(sst_mux_controls));
    
    	/* initialize the names of the probe points */
    	for (i = 0; i < SST_NUM_PROBE_CONNECTION_PTS; i++)
    		sst_probe_enum_texts[i] = sst_probes[i].name;
    
    	snd_soc_add_platform_controls(platform, sst_probe_controls,
    			ARRAY_SIZE(sst_probe_controls));
    
    	ret = sst_map_modules_to_pipe(platform);
    
    	return ret;
    }
    

    // 继续向下执行驱动代码。

三.  驱动匹配: //  匹配 “merr_dpcm_dummy”  流程

  1. sound/soc/intel/board/merr_dpcm_dummy.c
    static struct platform_driver snd_merr_dpcm_drv = {
    	.driver = {
    			.owner = THIS_MODULE,
    			.name = "merr_dpcm_dummy",
    			.pm = &snd_merr_dpcm_mc_pm_ops,
    	},
    	.probe = snd_merr_dpcm_probe,
    	.remove = snd_merr_dpcm_remove,
    };
    
    module_platform_driver(snd_merr_dpcm_drv);

  2. sound/soc/intel/board/merr_dpcm_dummy.c
    static int snd_merr_dpcm_probe(struct platform_device *pdev)
    {
    	int ret_val = 0;
    	pr_debug("%s enter\n", __func__);
    
    	/* register the soc card */
    	snd_soc_card_merr.dev = &pdev->dev;
    	ret_val = snd_soc_register_card(&snd_soc_card_merr);
    	if (ret_val) {
    		pr_err("snd_soc_register_card failed %d\n", ret_val);
    		return ret_val;
    	}
    	platform_set_drvdata(pdev, &snd_soc_card_merr);
    	pr_info("%s successful\n", __func__);
    	return ret_val;
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值