/* helper function to get the number of specific codec */ staticunsignedint get_num_codecs(constchar *hid)
{ struct acpi_device *adev; unsignedint dev_num = 0;
staticint rt1011_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params)
{ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai *codec_dai; int srate, i, ret = 0;
srate = params_rate(params);
for_each_rtd_codec_dais(rtd, i, codec_dai) { /* 100 Fs to drive 24 bit data */
ret = snd_soc_dai_set_pll(codec_dai, 0, RT1011_PLL1_S_BCLK,
100 * srate, 256 * srate); if (ret < 0) {
dev_err(codec_dai->dev, "fail to set pll, ret %d\n",
ret); return ret;
}
ret = snd_soc_dai_set_sysclk(codec_dai, RT1011_FS_SYS_PRE_S_PLL1,
256 * srate, SND_SOC_CLOCK_IN); if (ret < 0) {
dev_err(codec_dai->dev, "fail to set sysclk, ret %d\n",
ret); return ret;
}
if (i >= ARRAY_SIZE(rt1011_tdm_mask)) {
dev_err(codec_dai->dev, "invalid codec index %d\n",
i); return -ENODEV;
}
ret = snd_soc_dai_set_tdm_slot(codec_dai, rt1011_tdm_mask[i].tx,
rt1011_tdm_mask[i].rx, 4,
params_width(params)); if (ret < 0) {
dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n",
ret); return ret;
}
}
switch (num_codecs) { case 2: if (!soc_intel_is_cml()) {
ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets,
ARRAY_SIZE(realtek_2spk_widgets)); if (ret) {
dev_err(rtd->dev, "fail to add rt1011 widgets, ret %d\n",
ret); return ret;
}
ret = snd_soc_add_card_controls(card, realtek_2spk_kcontrols,
ARRAY_SIZE(realtek_2spk_kcontrols)); if (ret) {
dev_err(rtd->dev, "fail to add rt1011 kcontrols, ret %d\n",
ret); return ret;
}
ret = snd_soc_dapm_add_routes(&card->dapm, speaker_map_lr,
ARRAY_SIZE(speaker_map_lr)); if (ret) {
dev_err(rtd->dev, "fail to add rt1011 routes, ret %d\n",
ret); return ret;
}
break;
}
/* * register speaker widgets "WL Ext Spk" and "WR Ext Spk" to * keep backward compatible with cml devices
*/
fallthrough; case 4:
ret = snd_soc_dapm_new_controls(&card->dapm, realtek_4spk_widgets,
num_codecs); if (ret) {
dev_err(rtd->dev, "fail to add rt1011 widgets, ret %d\n",
ret); return ret;
}
ret = snd_soc_add_card_controls(card, realtek_4spk_kcontrols,
num_codecs); if (ret) {
dev_err(rtd->dev, "fail to add rt1011 controls, ret %d\n",
ret); return ret;
}
ret = snd_soc_dapm_add_routes(&card->dapm, rt1011_4spk_routes,
num_codecs); if (ret) {
dev_err(rtd->dev, "fail to add rt1011 routes, ret %d\n",
ret); return ret;
} break; default:
dev_err(rtd->dev, "rt1011: invalid num_codecs %d\n", num_codecs); return -EINVAL;
}
switch (num_codecs) { case 2: if (soc_intel_is_cml()) { /* * use name prefix 'WL' and 'WR' for speaker widgets to * keep backward compatible with cml devices
*/
card->codec_conf = rt1011_4spk_codec_confs;
} else {
card->codec_conf = rt1011_2spk_codec_confs;
}
/* * rt1015: i2c mode driver for ALC1015 and ALC1015Q * rt1015p: auto-mode driver for ALC1015, ALC1015Q, and ALC1015Q-VB * * For stereo output, there are always two amplifiers on the board. * However, the ACPI implements only one device instance (UID=0) if they * are sharing the same enable pin. This is the case of rt1015p.
*/ staticconststruct snd_soc_dapm_route rt1015p_dapm_routes[] = { /* speaker */
{ "Left Spk", NULL, "Speaker" },
{ "Right Spk", NULL, "Speaker" },
};
ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets,
ARRAY_SIZE(realtek_2spk_widgets)); if (ret) {
dev_err(rtd->dev, "fail to add rt1015p widgets, ret %d\n", ret); return ret;
}
ret = snd_soc_add_card_controls(card, realtek_2spk_kcontrols,
ARRAY_SIZE(realtek_2spk_kcontrols)); if (ret) {
dev_err(rtd->dev, "fail to add rt1015p kcontrols, ret %d\n", ret); return ret;
}
ret = snd_soc_dapm_add_routes(&card->dapm, rt1015p_dapm_routes,
ARRAY_SIZE(rt1015p_dapm_routes)); if (ret)
dev_err(rtd->dev, "Speaker map addition failed: %d\n", ret); return ret;
}
staticint rt1015_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params)
{ struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_dai_link *dai_link = rtd->dai_link; struct snd_soc_dai *codec_dai; int i, clk_freq; int ret = 0;
clk_freq = sof_dai_get_bclk(rtd);
if (clk_freq <= 0) {
dev_err(rtd->dev, "fail to get bclk freq, ret %d\n", clk_freq); return -EINVAL;
}
for_each_rtd_codec_dais(rtd, i, codec_dai) {
ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK,
clk_freq,
params_rate(params) * 256); if (ret) {
dev_err(codec_dai->dev, "fail to set pll, ret %d\n",
ret); return ret;
}
ret = snd_soc_dai_set_sysclk(codec_dai, RT1015_SCLK_S_PLL,
params_rate(params) * 256,
SND_SOC_CLOCK_IN); if (ret) {
dev_err(codec_dai->dev, "fail to set sysclk, ret %d\n",
ret); return ret;
}
switch (dai_link->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_DSP_A: case SND_SOC_DAIFMT_DSP_B: /* 4-slot TDM */
ret = snd_soc_dai_set_tdm_slot(codec_dai,
rt1015_tdm_mask[i].tx,
rt1015_tdm_mask[i].rx,
4,
params_width(params)); if (ret < 0) {
dev_err(codec_dai->dev, "fail to set tdm slot, ret %d\n",
ret); return ret;
} break; default:
dev_dbg(codec_dai->dev, "codec is in I2S mode\n"); break;
}
}
switch (num_codecs) { case 2:
ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets,
ARRAY_SIZE(realtek_2spk_widgets)); if (ret) {
dev_err(rtd->dev, "fail to add rt1015 widgets, ret %d\n",
ret); return ret;
}
ret = snd_soc_add_card_controls(card, realtek_2spk_kcontrols,
ARRAY_SIZE(realtek_2spk_kcontrols)); if (ret) {
dev_err(rtd->dev, "fail to add rt1015 kcontrols, ret %d\n",
ret); return ret;
}
ret = snd_soc_dapm_add_routes(&rtd->card->dapm, speaker_map_lr,
ARRAY_SIZE(speaker_map_lr)); if (ret) {
dev_err(rtd->dev, "fail to add rt1015 routes, ret %d\n",
ret); return ret;
} break; default:
dev_err(rtd->dev, "rt1015: invalid num_codecs %d\n", num_codecs); return -EINVAL;
}
ret = snd_soc_dapm_new_controls(&card->dapm, rt1308_dapm_widgets,
ARRAY_SIZE(rt1308_dapm_widgets)); if (ret) {
dev_err(rtd->dev, "fail to add dapm controls, ret %d\n", ret); return ret;
}
ret = snd_soc_add_card_controls(card, rt1308_kcontrols,
ARRAY_SIZE(rt1308_kcontrols)); if (ret) {
dev_err(rtd->dev, "fail to add card controls, ret %d\n", ret); return ret;
}
ret = snd_soc_dapm_add_routes(&card->dapm, rt1308_dapm_routes,
ARRAY_SIZE(rt1308_dapm_routes));
if (ret)
dev_err(rtd->dev, "fail to add dapm routes, ret %d\n", ret);
clk_id = RT1308_PLL_S_MCLK; /* get the tplg configured mclk. */
clk_freq = sof_dai_get_mclk(rtd);
pll_out = params_rate(params) * 512;
/* Set rt1308 pll */
ret = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, pll_out); if (ret < 0) {
dev_err(card->dev, "Failed to set RT1308 PLL: %d\n", ret); return ret;
}
/* Set rt1308 sysclk */
ret = snd_soc_dai_set_sysclk(codec_dai, RT1308_FS_SYS_S_PLL, pll_out,
SND_SOC_CLOCK_IN); if (ret < 0)
dev_err(card->dev, "Failed to set RT1308 SYSCLK: %d\n", ret);
ret = snd_soc_dapm_new_controls(&card->dapm, realtek_2spk_widgets,
ARRAY_SIZE(realtek_2spk_widgets)); if (ret) {
dev_err(rtd->dev, "fail to add rt1019p widgets, ret %d\n", ret); return ret;
}
ret = snd_soc_add_card_controls(card, realtek_2spk_kcontrols,
ARRAY_SIZE(realtek_2spk_kcontrols)); if (ret) {
dev_err(rtd->dev, "fail to add rt1019p kcontrols, ret %d\n", 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.