[PATCH RESEND 0/3] ASoC: mediatek: support SOF for mt8186
From: "chunxu.li" chunxu.li@mediatek.com
In these patches, we add SOF support for mt8186 which have HiFi5 DSP inside.
Chunxu Li (3): ASoC: mediatek: mt8186: support DSP downlink ASoC: mediatek: mt8186: add SOF support on mt8186-mt6366-rt1019-rt5682s ASoC: mediatek: mt8186: add SOF support on mt8186-mt6366-da7219-max98357
sound/soc/mediatek/mt8186/mt8186-afe-pcm.c | 3 + sound/soc/mediatek/mt8186/mt8186-dai-i2s.c | 12 ++ .../mt8186/mt8186-mt6366-da7219-max98357.c | 168 ++++++++++++++++-- .../mt8186/mt8186-mt6366-rt1019-rt5682s.c | 168 ++++++++++++++++-- 4 files changed, 325 insertions(+), 26 deletions(-)
1. add DSP downlink link widget 2. add DSP to I2S route path
Signed-off-by: Chunxu Li chunxu.li@mediatek.com --- sound/soc/mediatek/mt8186/mt8186-afe-pcm.c | 3 +++ sound/soc/mediatek/mt8186/mt8186-dai-i2s.c | 12 ++++++++++++ 2 files changed, 15 insertions(+)
diff --git a/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c b/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c index eb729ab00f5a..d7e94e6a19c7 100644 --- a/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c +++ b/sound/soc/mediatek/mt8186/mt8186-afe-pcm.c @@ -1359,6 +1359,9 @@ static const struct snd_soc_dapm_widget mt8186_memif_widgets[] = { SND_SOC_DAPM_MUX("UL5_IN_MUX", SND_SOC_NOPM, 0, 0, &ul5_in_mux_control),
+ SND_SOC_DAPM_MIXER("DSP_DL1_VIRT", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("DSP_DL2_VIRT", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_INPUT("UL1_VIRTUAL_INPUT"), SND_SOC_DAPM_INPUT("UL2_VIRTUAL_INPUT"), SND_SOC_DAPM_INPUT("UL3_VIRTUAL_INPUT"), diff --git a/sound/soc/mediatek/mt8186/mt8186-dai-i2s.c b/sound/soc/mediatek/mt8186/mt8186-dai-i2s.c index d7a227169548..e553a555d168 100644 --- a/sound/soc/mediatek/mt8186/mt8186-dai-i2s.c +++ b/sound/soc/mediatek/mt8186/mt8186-dai-i2s.c @@ -658,9 +658,15 @@ static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = { {"I2S1_CH1", "DL1_CH1 Switch", "DL1"}, {"I2S1_CH2", "DL1_CH2 Switch", "DL1"},
+ {"I2S1_CH1", "DL1_CH1 Switch", "DSP_DL1_VIRT"}, + {"I2S1_CH2", "DL1_CH2 Switch", "DSP_DL1_VIRT"}, + {"I2S1_CH1", "DL2_CH1 Switch", "DL2"}, {"I2S1_CH2", "DL2_CH2 Switch", "DL2"},
+ {"I2S1_CH1", "DL2_CH1 Switch", "DSP_DL2_VIRT"}, + {"I2S1_CH2", "DL2_CH2 Switch", "DSP_DL2_VIRT"}, + {"I2S1_CH1", "DL3_CH1 Switch", "DL3"}, {"I2S1_CH2", "DL3_CH2 Switch", "DL3"},
@@ -728,9 +734,15 @@ static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = { {"I2S3_CH1", "DL1_CH1 Switch", "DL1"}, {"I2S3_CH2", "DL1_CH2 Switch", "DL1"},
+ {"I2S3_CH1", "DL1_CH1 Switch", "DSP_DL1_VIRT"}, + {"I2S3_CH2", "DL1_CH2 Switch", "DSP_DL1_VIRT"}, + {"I2S3_CH1", "DL2_CH1 Switch", "DL2"}, {"I2S3_CH2", "DL2_CH2 Switch", "DL2"},
+ {"I2S3_CH1", "DL2_CH1 Switch", "DSP_DL2_VIRT"}, + {"I2S3_CH2", "DL2_CH2 Switch", "DSP_DL2_VIRT"}, + {"I2S3_CH1", "DL3_CH1 Switch", "DL3"}, {"I2S3_CH2", "DL3_CH2 Switch", "DL3"},
1. Add widgets, routes and dai-links required by SOF
2. Only when adsp phandle could be retrieved from DTS, the SOF related part of machine driver is executed.
3. Support dai-links could be specified from DTS, so that we can disable AP side hardware controls when DSP SOF controls the same audio FE.
Signed-off-by: Chunxu Li chunxu.li@mediatek.com --- .../mt8186/mt8186-mt6366-rt1019-rt5682s.c | 168 ++++++++++++++++-- 1 file changed, 155 insertions(+), 13 deletions(-)
diff --git a/sound/soc/mediatek/mt8186/mt8186-mt6366-rt1019-rt5682s.c b/sound/soc/mediatek/mt8186/mt8186-mt6366-rt1019-rt5682s.c index 891146fd6c2b..6c41706a5621 100644 --- a/sound/soc/mediatek/mt8186/mt8186-mt6366-rt1019-rt5682s.c +++ b/sound/soc/mediatek/mt8186/mt8186-mt6366-rt1019-rt5682s.c @@ -19,6 +19,8 @@ #include "../../codecs/mt6358.h" #include "../../codecs/rt5682.h" #include "../common/mtk-afe-platform-driver.h" +#include "../common/mtk-dsp-sof-common.h" +#include "../common/mtk-soc-card.h" #include "mt8186-afe-common.h" #include "mt8186-afe-clk.h" #include "mt8186-afe-gpio.h" @@ -30,6 +32,11 @@ #define RT5682S_CODEC_DAI "rt5682s-aif1" #define RT5682S_DEV0_NAME "rt5682s.5-001a"
+#define SOF_DMA_DL1 "SOF_DMA_DL1" +#define SOF_DMA_DL2 "SOF_DMA_DL2" +#define SOF_DMA_UL1 "SOF_DMA_UL1" +#define SOF_DMA_UL2 "SOF_DMA_UL2" + struct mt8186_mt6366_rt1019_rt5682s_priv { struct snd_soc_jack headset_jack, hdmi_jack; }; @@ -51,8 +58,9 @@ static struct snd_soc_codec_conf mt8186_mt6366_rt1019_rt5682s_codec_conf[] = {
static int mt8186_rt5682s_init(struct snd_soc_pcm_runtime *rtd) { - struct mt8186_mt6366_rt1019_rt5682s_priv *priv = + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card); + struct mt8186_mt6366_rt1019_rt5682s_priv *priv = soc_card_data->mach_priv; struct snd_soc_jack *jack = &priv->headset_jack; struct snd_soc_component *cmpnt_codec = asoc_rtd_to_codec(rtd, 0)->component; @@ -130,8 +138,9 @@ static int mt8186_mt6366_rt1019_rt5682s_hdmi_init(struct snd_soc_pcm_runtime *rt { struct snd_soc_component *cmpnt_codec = asoc_rtd_to_codec(rtd, 0)->component; - struct mt8186_mt6366_rt1019_rt5682s_priv *priv = + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card); + struct mt8186_mt6366_rt1019_rt5682s_priv *priv = soc_card_data->mach_priv; int ret;
ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, &priv->hdmi_jack); @@ -177,6 +186,24 @@ static int mt8186_it6505_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return mt8186_hw_params_fixup(rtd, params, SNDRV_PCM_FORMAT_S32_LE); }
+/* fixup the BE DAI link to match any values from topology */ +static int mt8186_sof_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + int ret; + + ret = mtk_sof_dai_link_fixup(rtd, params); + + if (!strcmp(rtd->dai_link->name, "I2S0") || + !strcmp(rtd->dai_link->name, "I2S1") || + !strcmp(rtd->dai_link->name, "I2S2")) + mt8186_i2s_hw_params_fixup(rtd, params); + else if (!strcmp(rtd->dai_link->name, "I2S3")) + mt8186_it6505_i2s_hw_params_fixup(rtd, params); + + return ret; +} + static int mt8186_mt6366_rt1019_rt5682s_playback_startup(struct snd_pcm_substream *substream) { static const unsigned int rates[] = { @@ -450,6 +477,33 @@ SND_SOC_DAILINK_DEFS(hostless_src_aaudio, DAILINK_COMP_ARRAY(COMP_CPU("Hostless SRC AAudio DAI")), DAILINK_COMP_ARRAY(COMP_DUMMY()), DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(AFE_SOF_DL1, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(AFE_SOF_DL2, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL2")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(AFE_SOF_UL1, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(AFE_SOF_UL2, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL2")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +static const struct sof_conn_stream g_sof_conn_streams[] = { + { "I2S1", "AFE_SOF_DL1", SOF_DMA_DL1, SNDRV_PCM_STREAM_PLAYBACK}, + { "I2S3", "AFE_SOF_DL2", SOF_DMA_DL2, SNDRV_PCM_STREAM_PLAYBACK}, + { "Primary Codec", "AFE_SOF_UL1", SOF_DMA_UL1, SNDRV_PCM_STREAM_CAPTURE}, + { "I2S0", "AFE_SOF_UL2", SOF_DMA_UL2, SNDRV_PCM_STREAM_CAPTURE}, +}; + static struct snd_soc_dai_link mt8186_mt6366_rt1019_rt5682s_dai_links[] = { /* Front End DAI links */ { @@ -824,12 +878,41 @@ static struct snd_soc_dai_link mt8186_mt6366_rt1019_rt5682s_dai_links[] = { .ignore_suspend = 1, SND_SOC_DAILINK_REG(hostless_ul6), }, + /* SOF BE */ + { + .name = "AFE_SOF_DL1", + .no_pcm = 1, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(AFE_SOF_DL1), + }, + { + .name = "AFE_SOF_DL2", + .no_pcm = 1, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(AFE_SOF_DL2), + }, + { + .name = "AFE_SOF_UL1", + .no_pcm = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(AFE_SOF_UL1), + }, + { + .name = "AFE_SOF_UL2", + .no_pcm = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(AFE_SOF_UL2), + }, };
static const struct snd_soc_dapm_widget mt8186_mt6366_rt1019_rt5682s_widgets[] = { SND_SOC_DAPM_SPK("Speakers", NULL), SND_SOC_DAPM_OUTPUT("HDMI1"), + SND_SOC_DAPM_MIXER(SOF_DMA_DL1, SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER(SOF_DMA_DL2, SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER(SOF_DMA_UL1, SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER(SOF_DMA_UL2, SND_SOC_NOPM, 0, 0, NULL, 0), };
static const struct snd_soc_dapm_route @@ -838,6 +921,14 @@ mt8186_mt6366_rt1019_rt5682s_routes[] = { { "Speakers", NULL, "Speaker" }, /* HDMI */ { "HDMI1", NULL, "TX" }, + /* SOF Uplink */ + {SOF_DMA_UL1, NULL, "UL1_CH1"}, + {SOF_DMA_UL1, NULL, "UL1_CH2"}, + {SOF_DMA_UL2, NULL, "UL2_CH1"}, + {SOF_DMA_UL2, NULL, "UL2_CH2"}, + /* SOF Downlink */ + {"DSP_DL1_VIRT", NULL, SOF_DMA_DL1}, + {"DSP_DL2_VIRT", NULL, SOF_DMA_DL2}, };
static const struct snd_kcontrol_new @@ -865,8 +956,10 @@ static int mt8186_mt6366_rt1019_rt5682s_dev_probe(struct platform_device *pdev) { struct snd_soc_card *card; struct snd_soc_dai_link *dai_link; - struct mt8186_mt6366_rt1019_rt5682s_priv *priv; - struct device_node *platform_node, *headset_codec, *playback_codec; + struct mtk_soc_card_data *soc_card_data; + struct mt8186_mt6366_rt1019_rt5682s_priv *mach_priv; + struct device_node *platform_node, *headset_codec, *playback_codec, *adsp_node; + int sof_on = 0; int ret, i;
card = (struct snd_soc_card *)device_get_match_data(&pdev->dev); @@ -874,11 +967,60 @@ static int mt8186_mt6366_rt1019_rt5682s_dev_probe(struct platform_device *pdev) return -EINVAL; card->dev = &pdev->dev;
+ soc_card_data = devm_kzalloc(&pdev->dev, sizeof(*soc_card_data), GFP_KERNEL); + if (!soc_card_data) + return -ENOMEM; + mach_priv = devm_kzalloc(&pdev->dev, sizeof(*mach_priv), GFP_KERNEL); + if (!mach_priv) + return -ENOMEM; + + soc_card_data->mach_priv = mach_priv; + + adsp_node = of_parse_phandle(pdev->dev.of_node, "mediatek,adsp", 0); + if (adsp_node) { + struct mtk_sof_priv *sof_priv; + + sof_priv = devm_kzalloc(&pdev->dev, sizeof(*sof_priv), GFP_KERNEL); + if (!sof_priv) { + ret = -ENOMEM; + goto err_adsp_node; + } + sof_priv->conn_streams = g_sof_conn_streams; + sof_priv->num_streams = ARRAY_SIZE(g_sof_conn_streams); + sof_priv->sof_dai_link_fixup = mt8186_sof_dai_link_fixup; + soc_card_data->sof_priv = sof_priv; + card->probe = mtk_sof_card_probe; + card->late_probe = mtk_sof_card_late_probe; + if (!card->topology_shortname_created) { + snprintf(card->topology_shortname, 32, "sof-%s", card->name); + card->topology_shortname_created = true; + } + card->name = card->topology_shortname; + sof_on = 1; + } else { + dev_info(&pdev->dev, "Probe without adsp\n"); + } + + if (of_property_read_bool(pdev->dev.of_node, "mediatek,dai-link")) { + ret = mtk_sof_dailink_parse_of(card, pdev->dev.of_node, + "mediatek,dai-link", + mt8186_mt6366_rt1019_rt5682s_dai_links, + ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_dai_links)); + if (ret) { + dev_dbg(&pdev->dev, "Parse dai-link fail\n"); + goto err_adsp_node; + } + } else { + if (!sof_on) + card->num_links = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_dai_links) + - ARRAY_SIZE(g_sof_conn_streams); + } + platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0); if (!platform_node) { ret = -EINVAL; dev_err_probe(&pdev->dev, ret, "Property 'platform' missing or invalid\n"); - return ret; + goto err_platform_node; }
playback_codec = of_get_child_by_name(pdev->dev.of_node, "playback-codecs"); @@ -917,17 +1059,14 @@ static int mt8186_mt6366_rt1019_rt5682s_dev_probe(struct platform_device *pdev) goto err_probe; }
- if (!dai_link->platforms->name) - dai_link->platforms->of_node = platform_node; - } + if (!strncmp(dai_link->name, "AFE_SOF", strlen("AFE_SOF")) && sof_on) + dai_link->platforms->of_node = adsp_node;
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - ret = -ENOMEM; - goto err_probe; + if (!dai_link->platforms->name && !dai_link->platforms->of_node) + dai_link->platforms->of_node = platform_node; }
- snd_soc_card_set_drvdata(card, priv); + snd_soc_card_set_drvdata(card, soc_card_data);
ret = mt8186_afe_gpio_init(&pdev->dev); if (ret) { @@ -945,6 +1084,9 @@ static int mt8186_mt6366_rt1019_rt5682s_dev_probe(struct platform_device *pdev) of_node_put(playback_codec); err_playback_codec: of_node_put(platform_node); +err_platform_node: +err_adsp_node: + of_node_put(adsp_node);
return ret; }
1. Add widgets, routes and dai-links required by SOF
2. Only when adsp phandle could be retrieved from DTS, the SOF related part of machine driver is executed.
3. Support dai-links could be specified from DTS, so that we can disable AP side hardware controls when DSP SOF controls the same audio FE.
Signed-off-by: Chunxu Li chunxu.li@mediatek.com --- .../mt8186/mt8186-mt6366-da7219-max98357.c | 168 ++++++++++++++++-- 1 file changed, 155 insertions(+), 13 deletions(-)
diff --git a/sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-max98357.c b/sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-max98357.c index 387f25cad809..84ee5d95a9f0 100644 --- a/sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-max98357.c +++ b/sound/soc/mediatek/mt8186/mt8186-mt6366-da7219-max98357.c @@ -18,6 +18,8 @@ #include "../../codecs/da7219.h" #include "../../codecs/mt6358.h" #include "../common/mtk-afe-platform-driver.h" +#include "../common/mtk-dsp-sof-common.h" +#include "../common/mtk-soc-card.h" #include "mt8186-afe-common.h" #include "mt8186-afe-clk.h" #include "mt8186-afe-gpio.h" @@ -26,6 +28,11 @@ #define DA7219_CODEC_DAI "da7219-hifi" #define DA7219_DEV_NAME "da7219.5-001a"
+#define SOF_DMA_DL1 "SOF_DMA_DL1" +#define SOF_DMA_DL2 "SOF_DMA_DL2" +#define SOF_DMA_UL1 "SOF_DMA_UL1" +#define SOF_DMA_UL2 "SOF_DMA_UL2" + struct mt8186_mt6366_da7219_max98357_priv { struct snd_soc_jack headset_jack, hdmi_jack; }; @@ -47,8 +54,9 @@ static struct snd_soc_codec_conf mt8186_mt6366_da7219_max98357_codec_conf[] = {
static int mt8186_da7219_init(struct snd_soc_pcm_runtime *rtd) { - struct mt8186_mt6366_da7219_max98357_priv *priv = + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card); + struct mt8186_mt6366_da7219_max98357_priv *priv = soc_card_data->mach_priv; struct snd_soc_jack *jack = &priv->headset_jack; struct snd_soc_component *cmpnt_codec = asoc_rtd_to_codec(rtd, 0)->component; @@ -154,8 +162,9 @@ static int mt8186_mt6366_da7219_max98357_hdmi_init(struct snd_soc_pcm_runtime *r { struct snd_soc_component *cmpnt_codec = asoc_rtd_to_codec(rtd, 0)->component; - struct mt8186_mt6366_da7219_max98357_priv *priv = + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card); + struct mt8186_mt6366_da7219_max98357_priv *priv = soc_card_data->mach_priv; int ret;
ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, &priv->hdmi_jack); @@ -201,6 +210,24 @@ static int mt8186_anx7625_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return mt8186_hw_params_fixup(rtd, params, SNDRV_PCM_FORMAT_S24_LE); }
+/* fixup the BE DAI link to match any values from topology */ +static int mt8186_sof_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + int ret; + + ret = mtk_sof_dai_link_fixup(rtd, params); + + if (!strcmp(rtd->dai_link->name, "I2S0") || + !strcmp(rtd->dai_link->name, "I2S1") || + !strcmp(rtd->dai_link->name, "I2S2")) + mt8186_i2s_hw_params_fixup(rtd, params); + else if (!strcmp(rtd->dai_link->name, "I2S3")) + mt8186_anx7625_i2s_hw_params_fixup(rtd, params); + + return ret; +} + static int mt8186_mt6366_da7219_max98357_playback_startup(struct snd_pcm_substream *substream) { static const unsigned int rates[] = { @@ -474,6 +501,33 @@ SND_SOC_DAILINK_DEFS(hostless_src_aaudio, DAILINK_COMP_ARRAY(COMP_CPU("Hostless SRC AAudio DAI")), DAILINK_COMP_ARRAY(COMP_DUMMY()), DAILINK_COMP_ARRAY(COMP_EMPTY())); +SND_SOC_DAILINK_DEFS(AFE_SOF_DL1, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(AFE_SOF_DL2, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL2")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(AFE_SOF_UL1, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(AFE_SOF_UL2, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL2")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +static const struct sof_conn_stream g_sof_conn_streams[] = { + { "I2S1", "AFE_SOF_DL1", SOF_DMA_DL1, SNDRV_PCM_STREAM_PLAYBACK}, + { "I2S3", "AFE_SOF_DL2", SOF_DMA_DL2, SNDRV_PCM_STREAM_PLAYBACK}, + { "Primary Codec", "AFE_SOF_UL1", SOF_DMA_UL1, SNDRV_PCM_STREAM_CAPTURE}, + { "I2S0", "AFE_SOF_UL2", SOF_DMA_UL2, SNDRV_PCM_STREAM_CAPTURE}, +}; + static struct snd_soc_dai_link mt8186_mt6366_da7219_max98357_dai_links[] = { /* Front End DAI links */ { @@ -848,12 +902,41 @@ static struct snd_soc_dai_link mt8186_mt6366_da7219_max98357_dai_links[] = { .ignore_suspend = 1, SND_SOC_DAILINK_REG(hostless_ul6), }, + /* SOF BE */ + { + .name = "AFE_SOF_DL1", + .no_pcm = 1, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(AFE_SOF_DL1), + }, + { + .name = "AFE_SOF_DL2", + .no_pcm = 1, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(AFE_SOF_DL2), + }, + { + .name = "AFE_SOF_UL1", + .no_pcm = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(AFE_SOF_UL1), + }, + { + .name = "AFE_SOF_UL2", + .no_pcm = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(AFE_SOF_UL2), + }, };
static const struct snd_soc_dapm_widget mt8186_mt6366_da7219_max98357_widgets[] = { SND_SOC_DAPM_SPK("Speakers", NULL), SND_SOC_DAPM_OUTPUT("HDMI1"), + SND_SOC_DAPM_MIXER(SOF_DMA_DL1, SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER(SOF_DMA_DL2, SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER(SOF_DMA_UL1, SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER(SOF_DMA_UL2, SND_SOC_NOPM, 0, 0, NULL, 0), };
static const struct snd_soc_dapm_route @@ -862,6 +945,14 @@ mt8186_mt6366_da7219_max98357_routes[] = { { "Speakers", NULL, "Speaker"}, /* HDMI */ { "HDMI1", NULL, "TX"}, + /* SOF Uplink */ + {SOF_DMA_UL1, NULL, "UL1_CH1"}, + {SOF_DMA_UL1, NULL, "UL1_CH2"}, + {SOF_DMA_UL2, NULL, "UL2_CH1"}, + {SOF_DMA_UL2, NULL, "UL2_CH2"}, + /* SOF Downlink */ + {"DSP_DL1_VIRT", NULL, SOF_DMA_DL1}, + {"DSP_DL2_VIRT", NULL, SOF_DMA_DL2}, };
static const struct snd_kcontrol_new @@ -889,8 +980,10 @@ static int mt8186_mt6366_da7219_max98357_dev_probe(struct platform_device *pdev) { struct snd_soc_card *card; struct snd_soc_dai_link *dai_link; - struct mt8186_mt6366_da7219_max98357_priv *priv; - struct device_node *platform_node, *headset_codec, *playback_codec; + struct mtk_soc_card_data *soc_card_data; + struct mt8186_mt6366_da7219_max98357_priv *mach_priv; + struct device_node *platform_node, *headset_codec, *playback_codec, *adsp_node; + int sof_on = 0; int ret, i;
card = (struct snd_soc_card *)device_get_match_data(&pdev->dev); @@ -898,11 +991,60 @@ static int mt8186_mt6366_da7219_max98357_dev_probe(struct platform_device *pdev) return -EINVAL; card->dev = &pdev->dev;
+ soc_card_data = devm_kzalloc(&pdev->dev, sizeof(*soc_card_data), GFP_KERNEL); + if (!soc_card_data) + return -ENOMEM; + mach_priv = devm_kzalloc(&pdev->dev, sizeof(*mach_priv), GFP_KERNEL); + if (!mach_priv) + return -ENOMEM; + + soc_card_data->mach_priv = mach_priv; + + adsp_node = of_parse_phandle(pdev->dev.of_node, "mediatek,adsp", 0); + if (adsp_node) { + struct mtk_sof_priv *sof_priv; + + sof_priv = devm_kzalloc(&pdev->dev, sizeof(*sof_priv), GFP_KERNEL); + if (!sof_priv) { + ret = -ENOMEM; + goto err_adsp_node; + } + sof_priv->conn_streams = g_sof_conn_streams; + sof_priv->num_streams = ARRAY_SIZE(g_sof_conn_streams); + sof_priv->sof_dai_link_fixup = mt8186_sof_dai_link_fixup; + soc_card_data->sof_priv = sof_priv; + card->probe = mtk_sof_card_probe; + card->late_probe = mtk_sof_card_late_probe; + if (!card->topology_shortname_created) { + snprintf(card->topology_shortname, 32, "sof-%s", card->name); + card->topology_shortname_created = true; + } + card->name = card->topology_shortname; + sof_on = 1; + } else { + dev_info(&pdev->dev, "Probe without adsp\n"); + } + + if (of_property_read_bool(pdev->dev.of_node, "mediatek,dai-link")) { + ret = mtk_sof_dailink_parse_of(card, pdev->dev.of_node, + "mediatek,dai-link", + mt8186_mt6366_da7219_max98357_dai_links, + ARRAY_SIZE(mt8186_mt6366_da7219_max98357_dai_links)); + if (ret) { + dev_dbg(&pdev->dev, "Parse dai-link fail\n"); + goto err_adsp_node; + } + } else { + if (!sof_on) + card->num_links = ARRAY_SIZE(mt8186_mt6366_da7219_max98357_dai_links) + - ARRAY_SIZE(g_sof_conn_streams); + } + platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0); if (!platform_node) { ret = -EINVAL; dev_err_probe(&pdev->dev, ret, "Property 'platform' missing or invalid\n"); - return ret; + goto err_platform_node; }
playback_codec = of_get_child_by_name(pdev->dev.of_node, "playback-codecs"); @@ -941,17 +1083,14 @@ static int mt8186_mt6366_da7219_max98357_dev_probe(struct platform_device *pdev) goto err_probe; }
- if (!dai_link->platforms->name) - dai_link->platforms->of_node = platform_node; - } + if (!strncmp(dai_link->name, "AFE_SOF", strlen("AFE_SOF")) && sof_on) + dai_link->platforms->of_node = adsp_node;
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) { - ret = -ENOMEM; - goto err_probe; + if (!dai_link->platforms->name && !dai_link->platforms->of_node) + dai_link->platforms->of_node = platform_node; }
- snd_soc_card_set_drvdata(card, priv); + snd_soc_card_set_drvdata(card, soc_card_data);
ret = mt8186_afe_gpio_init(&pdev->dev); if (ret) { @@ -969,6 +1108,9 @@ static int mt8186_mt6366_da7219_max98357_dev_probe(struct platform_device *pdev) of_node_put(playback_codec); err_playback_codec: of_node_put(platform_node); +err_platform_node: +err_adsp_node: + of_node_put(adsp_node);
return ret; }
On Thu, 18 Aug 2022 10:51:10 +0800, Chunxu Li wrote:
From: "chunxu.li" chunxu.li@mediatek.com
In these patches, we add SOF support for mt8186 which have HiFi5 DSP inside.
Chunxu Li (3): ASoC: mediatek: mt8186: support DSP downlink ASoC: mediatek: mt8186: add SOF support on mt8186-mt6366-rt1019-rt5682s ASoC: mediatek: mt8186: add SOF support on mt8186-mt6366-da7219-max98357
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/3] ASoC: mediatek: mt8186: support DSP downlink commit: 3c15abbed0ab99bac2e075ad38d43a7004778e91 [2/3] ASoC: mediatek: mt8186: add SOF support on mt8186-mt6366-rt1019-rt5682s commit: 4be34e1b70ac72415a55e02683cd847436424588 [3/3] ASoC: mediatek: mt8186: add SOF support on mt8186-mt6366-da7219-max98357 commit: 9398381a3904d8849691fb3ec173b48f077c185e
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (2)
-
Chunxu Li
-
Mark Brown