一. device 部分注册流程
- 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},
- 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")) {
- 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" 流程
- 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);
- 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; }
- 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, };
- 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; }
- 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” 流程
- 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);
- 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; }