mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-09-21 12:11:49 +08:00
ASoC: Intel: board_helpers: support HDA link initialization
Add a helper function for machine drivers to initialize HDA external codec DAI link. Signed-off-by: Brent Lu <brent.lu@intel.com> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com> Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> Link: https://patch.msgid.link/20240912120308.134762-2-yung-chuan.liao@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
32d5f79aaf
commit
bd07676dda
@ -70,6 +70,64 @@ static int dmic_init(struct snd_soc_pcm_runtime *rtd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* HDA External Codec DAI Link
|
||||
*/
|
||||
static const struct snd_soc_dapm_widget hda_widgets[] = {
|
||||
SND_SOC_DAPM_MIC("Analog In", NULL),
|
||||
SND_SOC_DAPM_MIC("Digital In", NULL),
|
||||
SND_SOC_DAPM_MIC("Alt Analog In", NULL),
|
||||
|
||||
SND_SOC_DAPM_HP("Analog Out", NULL),
|
||||
SND_SOC_DAPM_SPK("Digital Out", NULL),
|
||||
SND_SOC_DAPM_HP("Alt Analog Out", NULL),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route hda_routes[] = {
|
||||
{ "Codec Input Pin1", NULL, "Analog In" },
|
||||
{ "Codec Input Pin2", NULL, "Digital In" },
|
||||
{ "Codec Input Pin3", NULL, "Alt Analog In" },
|
||||
|
||||
{ "Analog Out", NULL, "Codec Output Pin1" },
|
||||
{ "Digital Out", NULL, "Codec Output Pin2" },
|
||||
{ "Alt Analog Out", NULL, "Codec Output Pin3" },
|
||||
|
||||
/* CODEC BE connections */
|
||||
{ "codec0_in", NULL, "Analog CPU Capture" },
|
||||
{ "Analog CPU Capture", NULL, "Analog Codec Capture" },
|
||||
{ "codec1_in", NULL, "Digital CPU Capture" },
|
||||
{ "Digital CPU Capture", NULL, "Digital Codec Capture" },
|
||||
{ "codec2_in", NULL, "Alt Analog CPU Capture" },
|
||||
{ "Alt Analog CPU Capture", NULL, "Alt Analog Codec Capture" },
|
||||
|
||||
{ "Analog Codec Playback", NULL, "Analog CPU Playback" },
|
||||
{ "Analog CPU Playback", NULL, "codec0_out" },
|
||||
{ "Digital Codec Playback", NULL, "Digital CPU Playback" },
|
||||
{ "Digital CPU Playback", NULL, "codec1_out" },
|
||||
{ "Alt Analog Codec Playback", NULL, "Alt Analog CPU Playback" },
|
||||
{ "Alt Analog CPU Playback", NULL, "codec2_out" },
|
||||
};
|
||||
|
||||
static int hda_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
int ret;
|
||||
|
||||
ret = snd_soc_dapm_new_controls(&card->dapm, hda_widgets,
|
||||
ARRAY_SIZE(hda_widgets));
|
||||
if (ret) {
|
||||
dev_err(rtd->dev, "fail to add hda widgets, ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = snd_soc_dapm_add_routes(&card->dapm, hda_routes,
|
||||
ARRAY_SIZE(hda_routes));
|
||||
if (ret)
|
||||
dev_err(rtd->dev, "fail to add hda routes, ret %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* DAI Link Helpers
|
||||
*/
|
||||
@ -79,6 +137,11 @@ enum sof_dmic_be_type {
|
||||
SOF_DMIC_16K,
|
||||
};
|
||||
|
||||
enum sof_hda_be_type {
|
||||
SOF_HDA_ANALOG,
|
||||
SOF_HDA_DIGITAL,
|
||||
};
|
||||
|
||||
/* DEFAULT_LINK_ORDER: the order used in sof_rt5682 */
|
||||
#define DEFAULT_LINK_ORDER SOF_LINK_ORDER(SOF_LINK_CODEC, \
|
||||
SOF_LINK_DMIC01, \
|
||||
@ -95,6 +158,16 @@ static struct snd_soc_dai_link_component dmic_component[] = {
|
||||
}
|
||||
};
|
||||
|
||||
SND_SOC_DAILINK_DEF(hda_analog_cpus,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("Analog CPU DAI")));
|
||||
SND_SOC_DAILINK_DEF(hda_analog_codecs,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D0", "Analog Codec DAI")));
|
||||
|
||||
SND_SOC_DAILINK_DEF(hda_digital_cpus,
|
||||
DAILINK_COMP_ARRAY(COMP_CPU("Digital CPU DAI")));
|
||||
SND_SOC_DAILINK_DEF(hda_digital_codecs,
|
||||
DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D0", "Digital Codec DAI")));
|
||||
|
||||
static struct snd_soc_dai_link_component platform_component[] = {
|
||||
{
|
||||
/* name might be overridden during probe */
|
||||
@ -380,6 +453,55 @@ static int set_hdmi_in_link(struct device *dev, struct snd_soc_dai_link *link,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_hda_codec_link(struct device *dev, struct snd_soc_dai_link *link,
|
||||
int be_id, enum sof_hda_be_type be_type)
|
||||
{
|
||||
switch (be_type) {
|
||||
case SOF_HDA_ANALOG:
|
||||
dev_dbg(dev, "link %d: hda analog\n", be_id);
|
||||
|
||||
link->name = "Analog Playback and Capture";
|
||||
|
||||
/* cpus */
|
||||
link->cpus = hda_analog_cpus;
|
||||
link->num_cpus = ARRAY_SIZE(hda_analog_cpus);
|
||||
|
||||
/* codecs */
|
||||
link->codecs = hda_analog_codecs;
|
||||
link->num_codecs = ARRAY_SIZE(hda_analog_codecs);
|
||||
break;
|
||||
case SOF_HDA_DIGITAL:
|
||||
dev_dbg(dev, "link %d: hda digital\n", be_id);
|
||||
|
||||
link->name = "Digital Playback and Capture";
|
||||
|
||||
/* cpus */
|
||||
link->cpus = hda_digital_cpus;
|
||||
link->num_cpus = ARRAY_SIZE(hda_digital_cpus);
|
||||
|
||||
/* codecs */
|
||||
link->codecs = hda_digital_codecs;
|
||||
link->num_codecs = ARRAY_SIZE(hda_digital_codecs);
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "invalid be type %d\n", be_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* platforms */
|
||||
link->platforms = platform_component;
|
||||
link->num_platforms = ARRAY_SIZE(platform_component);
|
||||
|
||||
link->id = be_id;
|
||||
if (be_type == SOF_HDA_ANALOG)
|
||||
link->init = hda_init;
|
||||
link->no_pcm = 1;
|
||||
link->dpcm_capture = 1;
|
||||
link->dpcm_playback = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int calculate_num_links(struct sof_card_private *ctx)
|
||||
{
|
||||
int num_links = 0;
|
||||
@ -409,6 +531,10 @@ static int calculate_num_links(struct sof_card_private *ctx)
|
||||
/* HDMI-In */
|
||||
num_links += hweight32(ctx->ssp_mask_hdmi_in);
|
||||
|
||||
/* HDA external codec */
|
||||
if (ctx->hda_codec_present)
|
||||
num_links += 2;
|
||||
|
||||
return num_links;
|
||||
}
|
||||
|
||||
@ -566,6 +692,32 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
|
||||
be_id++;
|
||||
}
|
||||
break;
|
||||
case SOF_LINK_HDA:
|
||||
/* HDA external codec */
|
||||
if (!ctx->hda_codec_present)
|
||||
continue;
|
||||
|
||||
ret = set_hda_codec_link(dev, &links[idx], be_id,
|
||||
SOF_HDA_ANALOG);
|
||||
if (ret) {
|
||||
dev_err(dev, "fail to set hda analog link, ret %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
idx++;
|
||||
be_id++;
|
||||
|
||||
ret = set_hda_codec_link(dev, &links[idx], be_id,
|
||||
SOF_HDA_DIGITAL);
|
||||
if (ret) {
|
||||
dev_err(dev, "fail to set hda digital link, ret %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
idx++;
|
||||
break;
|
||||
case SOF_LINK_NONE:
|
||||
/* caught here if it's not used as terminator in macro */
|
||||
fallthrough;
|
||||
|
@ -57,6 +57,7 @@ enum {
|
||||
SOF_LINK_AMP,
|
||||
SOF_LINK_BT_OFFLOAD,
|
||||
SOF_LINK_HDMI_IN,
|
||||
SOF_LINK_HDA,
|
||||
};
|
||||
|
||||
#define SOF_LINK_ORDER_MASK (0xF)
|
||||
@ -121,6 +122,7 @@ struct sof_rt5682_private {
|
||||
* @ssp_bt: ssp port number of BT offload BE link
|
||||
* @ssp_mask_hdmi_in: ssp port mask of HDMI-IN BE link
|
||||
* @bt_offload_present: true to create BT offload BE link
|
||||
* @hda_codec_present: true to create HDA codec BE links
|
||||
* @codec_link: pointer to headset codec dai link
|
||||
* @amp_link: pointer to speaker amplifier dai link
|
||||
* @link_order_overwrite: custom DAI link order
|
||||
@ -144,6 +146,7 @@ struct sof_card_private {
|
||||
unsigned long ssp_mask_hdmi_in;
|
||||
|
||||
bool bt_offload_present;
|
||||
bool hda_codec_present;
|
||||
|
||||
struct snd_soc_dai_link *codec_link;
|
||||
struct snd_soc_dai_link *amp_link;
|
||||
|
Loading…
Reference in New Issue
Block a user