Skip to content

Commit 46d26ca

Browse files
committed
ASoC: mediatek: mt8195: add sof to machine driver
Add SOF platform driver and use connection table to connect sof platform driver and normal platform driver. Use no_ignore_machine in sof device descriptor and set as 1 to keep and reuse original platform driver. Signed-off-by: YC Hung <yc.hung@mediatek.com>
1 parent c836c0d commit 46d26ca

File tree

1 file changed

+260
-0
lines changed

1 file changed

+260
-0
lines changed

sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c

Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,21 @@
2525
#define RT5682_CODEC_DAI "rt5682-aif1"
2626
#define RT5682_DEV0_NAME "rt5682.2-001a"
2727

28+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195)
29+
#include <sound/soc-acpi.h>
30+
#define SOF_DMA_DL2 "SOF_DMA_DL2"
31+
#define SOF_DMA_DL3 "SOF_DMA_DL3"
32+
#define SOF_DMA_UL4 "SOF_DMA_UL4"
33+
#define SOF_DMA_UL5 "SOF_DMA_UL5"
34+
35+
struct sof_conn_stream {
36+
const char *normal_link;
37+
const char *sof_link;
38+
const char *sof_dma;
39+
int stream_dir;
40+
};
41+
#endif
42+
2843
struct mt8195_mt6359_rt1019_rt5682_priv {
2944
struct snd_soc_jack headset_jack;
3045
struct snd_soc_jack dp_jack;
@@ -36,6 +51,12 @@ static const struct snd_soc_dapm_widget
3651
SND_SOC_DAPM_SPK("Speakers", NULL),
3752
SND_SOC_DAPM_HP("Headphone Jack", NULL),
3853
SND_SOC_DAPM_MIC("Headset Mic", NULL),
54+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195)
55+
SND_SOC_DAPM_MIXER(SOF_DMA_DL2, SND_SOC_NOPM, 0, 0, NULL, 0),
56+
SND_SOC_DAPM_MIXER(SOF_DMA_DL3, SND_SOC_NOPM, 0, 0, NULL, 0),
57+
SND_SOC_DAPM_MIXER(SOF_DMA_UL4, SND_SOC_NOPM, 0, 0, NULL, 0),
58+
SND_SOC_DAPM_MIXER(SOF_DMA_UL5, SND_SOC_NOPM, 0, 0, NULL, 0),
59+
#endif
3960
};
4061

4162
static const struct snd_soc_dapm_route mt8195_mt6359_rt1019_rt5682_routes[] = {
@@ -45,6 +66,18 @@ static const struct snd_soc_dapm_route mt8195_mt6359_rt1019_rt5682_routes[] = {
4566
{ "Headphone Jack", NULL, "HPOL" },
4667
{ "Headphone Jack", NULL, "HPOR" },
4768
{ "IN1P", NULL, "Headset Mic" },
69+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195)
70+
/* SOF Uplink */
71+
{SOF_DMA_UL4, NULL, "O034"},
72+
{SOF_DMA_UL4, NULL, "O035"},
73+
{SOF_DMA_UL5, NULL, "O036"},
74+
{SOF_DMA_UL5, NULL, "O037"},
75+
/* SOF Downlink */
76+
{"I070", NULL, SOF_DMA_DL2},
77+
{"I071", NULL, SOF_DMA_DL2},
78+
{"I020", NULL, SOF_DMA_DL3},
79+
{"I021", NULL, SOF_DMA_DL3},
80+
#endif
4881
};
4982

5083
static const struct snd_kcontrol_new mt8195_mt6359_rt1019_rt5682_controls[] = {
@@ -556,6 +589,12 @@ enum {
556589
DAI_LINK_PCM1_BE,
557590
DAI_LINK_UL_SRC1_BE,
558591
DAI_LINK_UL_SRC2_BE,
592+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195)
593+
DAI_LINK_SOF_DL2_BE,
594+
DAI_LINK_SOF_DL3_BE,
595+
DAI_LINK_SOF_UL4_BE,
596+
DAI_LINK_SOF_UL5_BE,
597+
#endif
559598
};
560599

561600
/* FE */
@@ -698,6 +737,171 @@ SND_SOC_DAILINK_DEFS(UL_SRC2_BE,
698737
"mt6359-snd-codec-aif2")),
699738
DAILINK_COMP_ARRAY(COMP_EMPTY()));
700739

740+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195)
741+
SND_SOC_DAILINK_DEFS(AFE_SOF_DL2,
742+
DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL2")),
743+
DAILINK_COMP_ARRAY(COMP_DUMMY()),
744+
DAILINK_COMP_ARRAY(COMP_PLATFORM("10803000.adsp")));
745+
746+
SND_SOC_DAILINK_DEFS(AFE_SOF_DL3,
747+
DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL3")),
748+
DAILINK_COMP_ARRAY(COMP_DUMMY()),
749+
DAILINK_COMP_ARRAY(COMP_PLATFORM("10803000.adsp")));
750+
751+
SND_SOC_DAILINK_DEFS(AFE_SOF_UL4,
752+
DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL4")),
753+
DAILINK_COMP_ARRAY(COMP_DUMMY()),
754+
DAILINK_COMP_ARRAY(COMP_PLATFORM("10803000.adsp")));
755+
756+
SND_SOC_DAILINK_DEFS(AFE_SOF_UL5,
757+
DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL5")),
758+
DAILINK_COMP_ARRAY(COMP_DUMMY()),
759+
DAILINK_COMP_ARRAY(COMP_PLATFORM("10803000.adsp")));
760+
761+
static const struct sof_conn_stream g_sof_conn_streams[] = {
762+
{ "ETDM2_OUT_BE", "AFE_SOF_DL2", SOF_DMA_DL2, SNDRV_PCM_STREAM_PLAYBACK},
763+
{ "ETDM1_OUT_BE", "AFE_SOF_DL3", SOF_DMA_DL3, SNDRV_PCM_STREAM_PLAYBACK},
764+
{ "UL_SRC1_BE", "AFE_SOF_UL4", SOF_DMA_UL4, SNDRV_PCM_STREAM_CAPTURE},
765+
{ "ETDM2_IN_BE", "AFE_SOF_UL5", SOF_DMA_UL5, SNDRV_PCM_STREAM_CAPTURE},
766+
};
767+
768+
/* fixup the BE DAI link to match any values from topology */
769+
static int mt8195_dai_link_fixup(struct snd_soc_pcm_runtime *rtd,
770+
struct snd_pcm_hw_params *params)
771+
{
772+
int i, j, ret = 0;
773+
struct snd_soc_card *card = rtd->card;
774+
struct snd_soc_dai_link *sof_dai_link;
775+
struct snd_soc_pcm_runtime *runtime;
776+
struct snd_soc_dai *cpu_dai;
777+
778+
for (i = 0; i < ARRAY_SIZE(g_sof_conn_streams); i++) {
779+
const struct sof_conn_stream *conn = &g_sof_conn_streams[i];
780+
781+
sof_dai_link = NULL;
782+
783+
if (strcmp(rtd->dai_link->name, conn->normal_link))
784+
continue;
785+
786+
for_each_card_rtds(card, runtime) {
787+
if (strcmp(runtime->dai_link->name, conn->sof_link))
788+
continue;
789+
790+
for_each_rtd_cpu_dais(runtime, j, cpu_dai) {
791+
if (cpu_dai->stream_active[conn->stream_dir] > 0) {
792+
sof_dai_link = runtime->dai_link;
793+
break;
794+
}
795+
}
796+
break;
797+
}
798+
799+
if (sof_dai_link && sof_dai_link->be_hw_params_fixup) {
800+
ret = sof_dai_link->be_hw_params_fixup(runtime, params);
801+
if (!strcmp(rtd->dai_link->name, "ETDM2_IN_BE") ||
802+
!strcmp(rtd->dai_link->name, "ETDM1_OUT_BE")) {
803+
mt8195_etdm_hw_params_fixup(runtime, params);
804+
}
805+
break;
806+
}
807+
}
808+
809+
return ret;
810+
}
811+
812+
static int mt8195_mt6359_rt1019_rt5682_card_late_probe(struct snd_soc_card *card)
813+
{
814+
struct snd_soc_pcm_runtime *runtime;
815+
struct snd_soc_component *sof_comp;
816+
int i;
817+
818+
/* 1. find sof component */
819+
for_each_card_rtds(card, runtime) {
820+
for (i = 0; i < runtime->num_components; i++) {
821+
if (!runtime->components[i]->driver->name)
822+
continue;
823+
if (!strcmp(runtime->components[i]->driver->name, "sof-audio-component")) {
824+
sof_comp = runtime->components[i];
825+
break;
826+
}
827+
}
828+
}
829+
830+
if (!sof_comp) {
831+
dev_info(card->dev, " probe without component\n");
832+
return 0;
833+
}
834+
/* 2. add route path and fixup callback */
835+
for (i = 0; i < ARRAY_SIZE(g_sof_conn_streams); i++) {
836+
const struct sof_conn_stream *conn = &g_sof_conn_streams[i];
837+
struct snd_soc_pcm_runtime *sof_rtd = NULL;
838+
struct snd_soc_pcm_runtime *normal_rtd = NULL;
839+
struct snd_soc_pcm_runtime *rtd;
840+
841+
for_each_card_rtds(card, rtd) {
842+
if (!strcmp(rtd->dai_link->stream_name, conn->sof_link)) {
843+
sof_rtd = rtd;
844+
continue;
845+
}
846+
if (!strcmp(rtd->dai_link->name, conn->normal_link)) {
847+
normal_rtd = rtd;
848+
continue;
849+
}
850+
if (normal_rtd && sof_rtd)
851+
break;
852+
}
853+
if (normal_rtd && sof_rtd) {
854+
int j;
855+
struct snd_soc_dai *cpu_dai;
856+
857+
for_each_rtd_cpu_dais(sof_rtd, j, cpu_dai) {
858+
struct snd_soc_dapm_route route;
859+
struct snd_soc_dapm_path *p = NULL;
860+
struct snd_soc_dapm_widget *play_widget =
861+
cpu_dai->playback_widget;
862+
struct snd_soc_dapm_widget *cap_widget =
863+
cpu_dai->capture_widget;
864+
memset(&route, 0, sizeof(route));
865+
if (conn->stream_dir == SNDRV_PCM_STREAM_CAPTURE &&
866+
cap_widget) {
867+
snd_soc_dapm_widget_for_each_sink_path(cap_widget, p) {
868+
route.source = conn->sof_dma;
869+
route.sink = p->sink->name;
870+
snd_soc_dapm_add_routes(&card->dapm, &route, 1);
871+
}
872+
} else if (conn->stream_dir == SNDRV_PCM_STREAM_PLAYBACK &&
873+
play_widget){
874+
snd_soc_dapm_widget_for_each_source_path(play_widget, p) {
875+
route.source = p->source->name;
876+
route.sink = conn->sof_dma;
877+
snd_soc_dapm_add_routes(&card->dapm, &route, 1);
878+
}
879+
} else {
880+
dev_err(cpu_dai->dev, "stream dir and widget not pair\n");
881+
}
882+
}
883+
normal_rtd->dai_link->be_hw_params_fixup = mt8195_dai_link_fixup;
884+
sof_rtd->dai_link->be_hw_params_fixup =
885+
sof_comp->driver->be_hw_params_fixup;
886+
}
887+
}
888+
889+
return 0;
890+
}
891+
892+
static int mt8195_mt6359_rt1019_rt5682_card_probe(struct snd_soc_card *card)
893+
{
894+
int i;
895+
struct snd_soc_dai_link *dai_link;
896+
897+
for_each_card_prelinks(card, i, dai_link) {
898+
if (dai_link->no_pcm && !dai_link->stream_name && dai_link->name)
899+
dai_link->stream_name = dai_link->name;
900+
}
901+
return 0;
902+
}
903+
#endif
904+
701905
static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = {
702906
/* FE */
703907
[DAI_LINK_DL2_FE] = {
@@ -977,6 +1181,33 @@ static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = {
9771181
.dpcm_capture = 1,
9781182
SND_SOC_DAILINK_REG(UL_SRC2_BE),
9791183
},
1184+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195)
1185+
/* SOF BE */
1186+
[DAI_LINK_SOF_DL2_BE] = {
1187+
.name = "AFE_SOF_DL2",
1188+
.no_pcm = 1,
1189+
.dpcm_playback = 1,
1190+
SND_SOC_DAILINK_REG(AFE_SOF_DL2),
1191+
},
1192+
[DAI_LINK_SOF_DL3_BE] = {
1193+
.name = "AFE_SOF_DL3",
1194+
.no_pcm = 1,
1195+
.dpcm_playback = 1,
1196+
SND_SOC_DAILINK_REG(AFE_SOF_DL3),
1197+
},
1198+
[DAI_LINK_SOF_UL4_BE] = {
1199+
.name = "AFE_SOF_UL4",
1200+
.no_pcm = 1,
1201+
.dpcm_capture = 1,
1202+
SND_SOC_DAILINK_REG(AFE_SOF_UL4),
1203+
},
1204+
[DAI_LINK_SOF_UL5_BE] = {
1205+
.name = "AFE_SOF_UL5",
1206+
.no_pcm = 1,
1207+
.dpcm_capture = 1,
1208+
SND_SOC_DAILINK_REG(AFE_SOF_UL5),
1209+
},
1210+
#endif
9801211
};
9811212

9821213
static struct snd_soc_card mt8195_mt6359_rt1019_rt5682_soc_card = {
@@ -990,6 +1221,10 @@ static struct snd_soc_card mt8195_mt6359_rt1019_rt5682_soc_card = {
9901221
.num_dapm_widgets = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_widgets),
9911222
.dapm_routes = mt8195_mt6359_rt1019_rt5682_routes,
9921223
.num_dapm_routes = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_routes),
1224+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195)
1225+
.late_probe = mt8195_mt6359_rt1019_rt5682_card_late_probe,
1226+
.probe = mt8195_mt6359_rt1019_rt5682_card_probe,
1227+
#endif
9931228
};
9941229

9951230
static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev)
@@ -998,12 +1233,25 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev)
9981233
struct device_node *platform_node;
9991234
struct snd_soc_dai_link *dai_link;
10001235
struct mt8195_mt6359_rt1019_rt5682_priv *priv = NULL;
1236+
1237+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195)
1238+
struct device_node *machine_node;
1239+
struct snd_soc_acpi_mach *mach;
1240+
#endif
1241+
10011242
int ret, i;
10021243

10031244
card->dev = &pdev->dev;
10041245

1246+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195)
1247+
mach = pdev->dev.platform_data;
1248+
machine_node = mach->pdata;
1249+
platform_node = of_parse_phandle(machine_node, "mediatek,platform", 0);
1250+
#else
10051251
platform_node = of_parse_phandle(pdev->dev.of_node,
10061252
"mediatek,platform", 0);
1253+
#endif
1254+
10071255
if (!platform_node) {
10081256
dev_dbg(&pdev->dev, "Property 'platform' missing or invalid\n");
10091257
return -EINVAL;
@@ -1014,9 +1262,15 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev)
10141262
dai_link->platforms->of_node = platform_node;
10151263

10161264
if (strcmp(dai_link->name, "DPTX_BE") == 0) {
1265+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195)
1266+
dai_link->codecs->of_node =
1267+
of_parse_phandle(machine_node,
1268+
"mediatek,dptx-codec", 0);
1269+
#else
10171270
dai_link->codecs->of_node =
10181271
of_parse_phandle(pdev->dev.of_node,
10191272
"mediatek,dptx-codec", 0);
1273+
#endif
10201274
if (!dai_link->codecs->of_node) {
10211275
dev_err(&pdev->dev, "Property 'dptx-codec' missing or invalid\n");
10221276
return -EINVAL;
@@ -1028,9 +1282,15 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev)
10281282
}
10291283

10301284
if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) {
1285+
#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195)
1286+
dai_link->codecs->of_node =
1287+
of_parse_phandle(machine_node,
1288+
"mediatek,hdmi-codec", 0);
1289+
#else
10311290
dai_link->codecs->of_node =
10321291
of_parse_phandle(pdev->dev.of_node,
10331292
"mediatek,hdmi-codec", 0);
1293+
#endif
10341294
if (!dai_link->codecs->of_node) {
10351295
dev_err(&pdev->dev, "Property 'hdmi-codec' missing or invalid\n");
10361296
return -EINVAL;

0 commit comments

Comments
 (0)