if (ctx->rt5682.mclk_en) { if (ctx->rt5682.is_legacy_cpu) {
ret = clk_prepare_enable(ctx->rt5682.mclk); if (ret < 0) {
dev_err(rtd->dev, "could not configure MCLK state"); return ret;
}
}
switch (ctx->codec_type) { case CODEC_RT5650:
pll_source = RT5645_PLL1_S_MCLK; break; case CODEC_RT5682:
pll_source = RT5682_PLL1_S_MCLK; break; case CODEC_RT5682S:
pll_source = RT5682S_PLL_S_MCLK; break; default:
dev_err(rtd->dev, "invalid codec type %d\n",
ctx->codec_type); return -EINVAL;
}
/* get the tplg configured mclk. */
pll_in = sof_dai_get_mclk(rtd); if (pll_in <= 0) {
dev_err(rtd->dev, "invalid mclk freq %d\n", pll_in); return -EINVAL;
}
} else { switch (ctx->codec_type) { case CODEC_RT5650:
pll_source = RT5645_PLL1_S_BCLK1; break; case CODEC_RT5682:
pll_source = RT5682_PLL1_S_BCLK1; break; case CODEC_RT5682S:
pll_source = RT5682S_PLL_S_BCLK1; break; default:
dev_err(rtd->dev, "invalid codec type %d\n",
ctx->codec_type); return -EINVAL;
}
/* get the tplg configured bclk. */
pll_in = sof_dai_get_bclk(rtd); if (pll_in <= 0) {
dev_err(rtd->dev, "invalid bclk freq %d\n", pll_in); return -EINVAL;
}
}
pll_out = params_rate(params) * 512;
/* when MCLK is 512FS, no need to set PLL configuration additionally. */ if (pll_in == pll_out) { switch (ctx->codec_type) { case CODEC_RT5650:
clk_id = RT5645_SCLK_S_MCLK; break; case CODEC_RT5682:
clk_id = RT5682_SCLK_S_MCLK; break; case CODEC_RT5682S:
clk_id = RT5682S_SCLK_S_MCLK; break; default:
dev_err(rtd->dev, "invalid codec type %d\n",
ctx->codec_type); return -EINVAL;
}
} else { switch (ctx->codec_type) { case CODEC_RT5650:
pll_id = 0; /* not used in codec driver */
clk_id = RT5645_SCLK_S_PLL1; break; case CODEC_RT5682:
pll_id = RT5682_PLL1;
clk_id = RT5682_SCLK_S_PLL1; break; case CODEC_RT5682S: /* check plla_table and pllb_table in rt5682s.c */ switch (pll_in) { case3072000: case24576000: /* *ForMCLK=24.576MHzandsamplerate=96KHzcase,usePLL1Wedon'ttest *pll_outorparams_rate()heresincert5682sPLL2doesn'tsupport24.576MHz *input,sowehavenochoicebuttousePLL1.Besides,wewillnotusePLLat *allifpll_in==pll_out.ex,MCLK=24.576Mhzandsamplerate=48KHz
*/
pll_id = RT5682S_PLL1;
clk_id = RT5682S_SCLK_S_PLL1; break; default:
pll_id = RT5682S_PLL2;
clk_id = RT5682S_SCLK_S_PLL2; break;
} break; default:
dev_err(rtd->dev, "invalid codec type %d\n", ctx->codec_type); return -EINVAL;
}
/* Configure pll for codec */
ret = snd_soc_dai_set_pll(codec_dai, pll_id, pll_source, pll_in,
pll_out); if (ret < 0)
dev_err(rtd->dev, "snd_soc_dai_set_pll err = %d\n", ret);
}
/* Configure sysclk for codec */
ret = snd_soc_dai_set_sysclk(codec_dai, clk_id,
pll_out, SND_SOC_CLOCK_IN); if (ret < 0)
dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
staticconststruct snd_soc_dapm_route sof_map[] = { /* HP jack connectors - unknown if we have jack detection */
{ "Headphone Jack", NULL, "HPOL" },
{ "Headphone Jack", NULL, "HPOR" },
ret = snd_soc_dapm_new_controls(&card->dapm, rt5650_spk_widgets,
ARRAY_SIZE(rt5650_spk_widgets)); if (ret) {
dev_err(rtd->dev, "fail to add rt5650 spk widgets, ret %d\n",
ret); return ret;
}
ret = snd_soc_add_card_controls(card, rt5650_spk_kcontrols,
ARRAY_SIZE(rt5650_spk_kcontrols)); if (ret) {
dev_err(rtd->dev, "fail to add rt5650 spk kcontrols, ret %d\n",
ret); return ret;
}
ret = snd_soc_dapm_add_routes(&card->dapm, rt5650_spk_dapm_routes,
ARRAY_SIZE(rt5650_spk_dapm_routes)); if (ret)
dev_err(rtd->dev, "fail to add dapm routes, ret=%d\n", ret);
return ret;
}
/* sof audio machine driver for rt5682 codec */ staticstruct snd_soc_card sof_audio_card_rt5682 = {
.name = "rt5682", /* the sof- prefix is added by the core */
.owner = THIS_MODULE,
.controls = sof_controls,
.num_controls = ARRAY_SIZE(sof_controls),
.dapm_widgets = sof_widgets,
.num_dapm_widgets = ARRAY_SIZE(sof_widgets),
.dapm_routes = sof_map,
.num_dapm_routes = ARRAY_SIZE(sof_map),
.fully_routed = true,
.late_probe = sof_card_late_probe,
};
/* initialize ctx with board quirk */
ctx = sof_intel_board_get_ctx(&pdev->dev, sof_rt5682_quirk); if (!ctx) return -ENOMEM;
if (ctx->codec_type == CODEC_RT5650) {
card_name = devm_kstrdup(&pdev->dev, "rt5650", GFP_KERNEL); if (!card_name) return -ENOMEM;
sof_audio_card_rt5682.name = card_name;
/* create speaker dai link also */ if (ctx->amp_type == CODEC_NONE)
ctx->amp_type = CODEC_RT5650;
}
if (mach->mach_params.codec_mask & IDISP_CODEC_MASK)
ctx->hdmi.idisp_codec = true;
if (soc_intel_is_byt() || soc_intel_is_cht()) {
ctx->rt5682.is_legacy_cpu = true;
ctx->dmic_be_num = 0; /* HDMI is not supported by SOF on Baytrail/CherryTrail */
ctx->hdmi_num = 0;
} elseif (soc_intel_is_glk()) { /* dmic16k not support */
ctx->dmic_be_num = 1;
/* overwrite the DAI link order for GLK boards */
ctx->link_order_overwrite = GLK_LINK_ORDER;
/* backward-compatible with existing devices */ switch (ctx->amp_type) { case CODEC_MAX98357A:
card_name = devm_kstrdup(&pdev->dev, "glkrt5682max",
GFP_KERNEL); if (!card_name) return -ENOMEM;
if (sof_rt5682_quirk & SOF_RT5682_MCLK_EN) {
ctx->rt5682.mclk_en = true;
/* need to get main clock from pmc */ if (ctx->rt5682.is_legacy_cpu) {
ctx->rt5682.mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3"); if (IS_ERR(ctx->rt5682.mclk)) {
ret = PTR_ERR(ctx->rt5682.mclk);
dev_err(&pdev->dev, "Failed to get MCLK from pmc_plt_clk_3: %d\n",
ret); return ret;
}
ret = clk_prepare_enable(ctx->rt5682.mclk); if (ret < 0) {
dev_err(&pdev->dev, "could not configure MCLK state"); return ret;
}
}
}
/* update dai_link */
ret = sof_card_dai_links_create(&pdev->dev, &sof_audio_card_rt5682, ctx); if (ret) return ret;
/* update codec_conf */ switch (ctx->amp_type) { case CODEC_MAX98373:
max_98373_set_codec_conf(&sof_audio_card_rt5682); break; case CODEC_MAX98390:
max_98390_set_codec_conf(&pdev->dev, &sof_audio_card_rt5682); break; case CODEC_RT1011:
sof_rt1011_codec_conf(&pdev->dev, &sof_audio_card_rt5682); break; case CODEC_RT1015:
sof_rt1015_codec_conf(&sof_audio_card_rt5682); break; case CODEC_RT1015P:
sof_rt1015p_codec_conf(&sof_audio_card_rt5682); break; case CODEC_MAX98357A: case CODEC_MAX98360A: case CODEC_RT1019P: case CODEC_RT5650: case CODEC_NONE: /* no codec conf required */ break; default:
dev_err(&pdev->dev, "invalid amp type %d\n", ctx->amp_type); return -EINVAL;
}
sof_audio_card_rt5682.dev = &pdev->dev;
/* set platform name for each dailink */
ret = snd_soc_fixup_dai_links_platform_name(&sof_audio_card_rt5682,
mach->mach_params.platform); if (ret) return ret;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.