Skip to content

Commit bd07676

Browse files
brentlubroonie
authored andcommitted
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 <[email protected]> Reviewed-by: Péter Ujfalusi <[email protected]> Signed-off-by: Bard Liao <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 32d5f79 commit bd07676

File tree

2 files changed

+155
-0
lines changed

2 files changed

+155
-0
lines changed

sound/soc/intel/boards/sof_board_helpers.c

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,64 @@ static int dmic_init(struct snd_soc_pcm_runtime *rtd)
7070
return 0;
7171
}
7272

73+
/*
74+
* HDA External Codec DAI Link
75+
*/
76+
static const struct snd_soc_dapm_widget hda_widgets[] = {
77+
SND_SOC_DAPM_MIC("Analog In", NULL),
78+
SND_SOC_DAPM_MIC("Digital In", NULL),
79+
SND_SOC_DAPM_MIC("Alt Analog In", NULL),
80+
81+
SND_SOC_DAPM_HP("Analog Out", NULL),
82+
SND_SOC_DAPM_SPK("Digital Out", NULL),
83+
SND_SOC_DAPM_HP("Alt Analog Out", NULL),
84+
};
85+
86+
static const struct snd_soc_dapm_route hda_routes[] = {
87+
{ "Codec Input Pin1", NULL, "Analog In" },
88+
{ "Codec Input Pin2", NULL, "Digital In" },
89+
{ "Codec Input Pin3", NULL, "Alt Analog In" },
90+
91+
{ "Analog Out", NULL, "Codec Output Pin1" },
92+
{ "Digital Out", NULL, "Codec Output Pin2" },
93+
{ "Alt Analog Out", NULL, "Codec Output Pin3" },
94+
95+
/* CODEC BE connections */
96+
{ "codec0_in", NULL, "Analog CPU Capture" },
97+
{ "Analog CPU Capture", NULL, "Analog Codec Capture" },
98+
{ "codec1_in", NULL, "Digital CPU Capture" },
99+
{ "Digital CPU Capture", NULL, "Digital Codec Capture" },
100+
{ "codec2_in", NULL, "Alt Analog CPU Capture" },
101+
{ "Alt Analog CPU Capture", NULL, "Alt Analog Codec Capture" },
102+
103+
{ "Analog Codec Playback", NULL, "Analog CPU Playback" },
104+
{ "Analog CPU Playback", NULL, "codec0_out" },
105+
{ "Digital Codec Playback", NULL, "Digital CPU Playback" },
106+
{ "Digital CPU Playback", NULL, "codec1_out" },
107+
{ "Alt Analog Codec Playback", NULL, "Alt Analog CPU Playback" },
108+
{ "Alt Analog CPU Playback", NULL, "codec2_out" },
109+
};
110+
111+
static int hda_init(struct snd_soc_pcm_runtime *rtd)
112+
{
113+
struct snd_soc_card *card = rtd->card;
114+
int ret;
115+
116+
ret = snd_soc_dapm_new_controls(&card->dapm, hda_widgets,
117+
ARRAY_SIZE(hda_widgets));
118+
if (ret) {
119+
dev_err(rtd->dev, "fail to add hda widgets, ret %d\n", ret);
120+
return ret;
121+
}
122+
123+
ret = snd_soc_dapm_add_routes(&card->dapm, hda_routes,
124+
ARRAY_SIZE(hda_routes));
125+
if (ret)
126+
dev_err(rtd->dev, "fail to add hda routes, ret %d\n", ret);
127+
128+
return ret;
129+
}
130+
73131
/*
74132
* DAI Link Helpers
75133
*/
@@ -79,6 +137,11 @@ enum sof_dmic_be_type {
79137
SOF_DMIC_16K,
80138
};
81139

140+
enum sof_hda_be_type {
141+
SOF_HDA_ANALOG,
142+
SOF_HDA_DIGITAL,
143+
};
144+
82145
/* DEFAULT_LINK_ORDER: the order used in sof_rt5682 */
83146
#define DEFAULT_LINK_ORDER SOF_LINK_ORDER(SOF_LINK_CODEC, \
84147
SOF_LINK_DMIC01, \
@@ -95,6 +158,16 @@ static struct snd_soc_dai_link_component dmic_component[] = {
95158
}
96159
};
97160

161+
SND_SOC_DAILINK_DEF(hda_analog_cpus,
162+
DAILINK_COMP_ARRAY(COMP_CPU("Analog CPU DAI")));
163+
SND_SOC_DAILINK_DEF(hda_analog_codecs,
164+
DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D0", "Analog Codec DAI")));
165+
166+
SND_SOC_DAILINK_DEF(hda_digital_cpus,
167+
DAILINK_COMP_ARRAY(COMP_CPU("Digital CPU DAI")));
168+
SND_SOC_DAILINK_DEF(hda_digital_codecs,
169+
DAILINK_COMP_ARRAY(COMP_CODEC("ehdaudio0D0", "Digital Codec DAI")));
170+
98171
static struct snd_soc_dai_link_component platform_component[] = {
99172
{
100173
/* 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,
380453
return 0;
381454
}
382455

456+
static int set_hda_codec_link(struct device *dev, struct snd_soc_dai_link *link,
457+
int be_id, enum sof_hda_be_type be_type)
458+
{
459+
switch (be_type) {
460+
case SOF_HDA_ANALOG:
461+
dev_dbg(dev, "link %d: hda analog\n", be_id);
462+
463+
link->name = "Analog Playback and Capture";
464+
465+
/* cpus */
466+
link->cpus = hda_analog_cpus;
467+
link->num_cpus = ARRAY_SIZE(hda_analog_cpus);
468+
469+
/* codecs */
470+
link->codecs = hda_analog_codecs;
471+
link->num_codecs = ARRAY_SIZE(hda_analog_codecs);
472+
break;
473+
case SOF_HDA_DIGITAL:
474+
dev_dbg(dev, "link %d: hda digital\n", be_id);
475+
476+
link->name = "Digital Playback and Capture";
477+
478+
/* cpus */
479+
link->cpus = hda_digital_cpus;
480+
link->num_cpus = ARRAY_SIZE(hda_digital_cpus);
481+
482+
/* codecs */
483+
link->codecs = hda_digital_codecs;
484+
link->num_codecs = ARRAY_SIZE(hda_digital_codecs);
485+
break;
486+
default:
487+
dev_err(dev, "invalid be type %d\n", be_type);
488+
return -EINVAL;
489+
}
490+
491+
/* platforms */
492+
link->platforms = platform_component;
493+
link->num_platforms = ARRAY_SIZE(platform_component);
494+
495+
link->id = be_id;
496+
if (be_type == SOF_HDA_ANALOG)
497+
link->init = hda_init;
498+
link->no_pcm = 1;
499+
link->dpcm_capture = 1;
500+
link->dpcm_playback = 1;
501+
502+
return 0;
503+
}
504+
383505
static int calculate_num_links(struct sof_card_private *ctx)
384506
{
385507
int num_links = 0;
@@ -409,6 +531,10 @@ static int calculate_num_links(struct sof_card_private *ctx)
409531
/* HDMI-In */
410532
num_links += hweight32(ctx->ssp_mask_hdmi_in);
411533

534+
/* HDA external codec */
535+
if (ctx->hda_codec_present)
536+
num_links += 2;
537+
412538
return num_links;
413539
}
414540

@@ -566,6 +692,32 @@ int sof_intel_board_set_dai_link(struct device *dev, struct snd_soc_card *card,
566692
be_id++;
567693
}
568694
break;
695+
case SOF_LINK_HDA:
696+
/* HDA external codec */
697+
if (!ctx->hda_codec_present)
698+
continue;
699+
700+
ret = set_hda_codec_link(dev, &links[idx], be_id,
701+
SOF_HDA_ANALOG);
702+
if (ret) {
703+
dev_err(dev, "fail to set hda analog link, ret %d\n",
704+
ret);
705+
return ret;
706+
}
707+
708+
idx++;
709+
be_id++;
710+
711+
ret = set_hda_codec_link(dev, &links[idx], be_id,
712+
SOF_HDA_DIGITAL);
713+
if (ret) {
714+
dev_err(dev, "fail to set hda digital link, ret %d\n",
715+
ret);
716+
return ret;
717+
}
718+
719+
idx++;
720+
break;
569721
case SOF_LINK_NONE:
570722
/* caught here if it's not used as terminator in macro */
571723
fallthrough;

sound/soc/intel/boards/sof_board_helpers.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ enum {
5757
SOF_LINK_AMP,
5858
SOF_LINK_BT_OFFLOAD,
5959
SOF_LINK_HDMI_IN,
60+
SOF_LINK_HDA,
6061
};
6162

6263
#define SOF_LINK_ORDER_MASK (0xF)
@@ -121,6 +122,7 @@ struct sof_rt5682_private {
121122
* @ssp_bt: ssp port number of BT offload BE link
122123
* @ssp_mask_hdmi_in: ssp port mask of HDMI-IN BE link
123124
* @bt_offload_present: true to create BT offload BE link
125+
* @hda_codec_present: true to create HDA codec BE links
124126
* @codec_link: pointer to headset codec dai link
125127
* @amp_link: pointer to speaker amplifier dai link
126128
* @link_order_overwrite: custom DAI link order
@@ -144,6 +146,7 @@ struct sof_card_private {
144146
unsigned long ssp_mask_hdmi_in;
145147

146148
bool bt_offload_present;
149+
bool hda_codec_present;
147150

148151
struct snd_soc_dai_link *codec_link;
149152
struct snd_soc_dai_link *amp_link;

0 commit comments

Comments
 (0)