diff options
Diffstat (limited to 'sound/soc/mediatek/mt8188')
-rw-r--r-- | sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 8 | ||||
-rw-r--r-- | sound/soc/mediatek/mt8188/mt8188-dai-etdm.c | 4 | ||||
-rw-r--r-- | sound/soc/mediatek/mt8188/mt8188-mt6359.c | 362 |
3 files changed, 342 insertions, 32 deletions
diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c index 5e14655c56..46d6a55404 100644 --- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c +++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c @@ -98,7 +98,7 @@ static int mt8188_memif_fs(struct snd_pcm_substream *substream, struct mtk_base_afe_memif *memif = NULL; struct mtk_dai_memif_priv *memif_priv = NULL; int fs = mt8188_afe_fs_timing(rate); - int id = asoc_rtd_to_cpu(rtd, 0)->id; + int id = snd_soc_rtd_to_cpu(rtd, 0)->id; if (id < 0) return -EINVAL; @@ -303,7 +303,7 @@ static int mt8188_afe_fe_startup(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_pcm_runtime *runtime = substream->runtime; struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); - int id = asoc_rtd_to_cpu(rtd, 0)->id; + int id = snd_soc_rtd_to_cpu(rtd, 0)->id; int ret; ret = mtk_afe_fe_startup(substream, dai); @@ -336,7 +336,7 @@ static int mt8188_afe_fe_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); - int id = asoc_rtd_to_cpu(rtd, 0)->id; + int id = snd_soc_rtd_to_cpu(rtd, 0)->id; struct mtk_base_afe_memif *memif = &afe->memif[id]; const struct mtk_base_memif_data *data = memif->data; const struct mt8188_afe_channel_merge *cm = mt8188_afe_found_cm(dai); @@ -360,7 +360,7 @@ static int mt8188_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd, const struct mt8188_afe_channel_merge *cm = mt8188_afe_found_cm(dai); struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_pcm_runtime * const runtime = substream->runtime; - int id = asoc_rtd_to_cpu(rtd, 0)->id; + int id = snd_soc_rtd_to_cpu(rtd, 0)->id; struct mtk_base_afe_memif *memif = &afe->memif[id]; struct mtk_base_afe_irq *irqs = &afe->irqs[memif->irq_usage]; const struct mtk_base_irq_data *irq_data = irqs->irq_data; diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c index 16440dd0a8..2a48f5fd68 100644 --- a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c +++ b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c @@ -576,13 +576,13 @@ static int mtk_apll_event(struct snd_soc_dapm_widget *w, switch (event) { case SND_SOC_DAPM_PRE_PMU: - if (strcmp(w->name, APLL1_W_NAME) == 0) + if (snd_soc_dapm_widget_name_cmp(w, APLL1_W_NAME) == 0) mt8188_apll1_enable(afe); else mt8188_apll2_enable(afe); break; case SND_SOC_DAPM_POST_PMD: - if (strcmp(w->name, APLL1_W_NAME) == 0) + if (snd_soc_dapm_widget_name_cmp(w, APLL1_W_NAME) == 0) mt8188_apll1_disable(afe); else mt8188_apll2_disable(afe); diff --git a/sound/soc/mediatek/mt8188/mt8188-mt6359.c b/sound/soc/mediatek/mt8188/mt8188-mt6359.c index f7e22abb75..33d477cc2e 100644 --- a/sound/soc/mediatek/mt8188/mt8188-mt6359.c +++ b/sound/soc/mediatek/mt8188/mt8188-mt6359.c @@ -9,7 +9,7 @@ #include <linux/bitfield.h> #include <linux/input.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> #include <linux/pm_runtime.h> #include <sound/jack.h> #include <sound/pcm_params.h> @@ -17,8 +17,11 @@ #include "mt8188-afe-common.h" #include "../../codecs/nau8825.h" #include "../../codecs/mt6359.h" +#include "../../codecs/rt5682.h" #include "../common/mtk-afe-platform-driver.h" #include "../common/mtk-soundcard-driver.h" +#include "../common/mtk-dsp-sof-common.h" +#include "../common/mtk-soc-card.h" #define CKSYS_AUD_TOP_CFG 0x032c #define RG_TEST_ON BIT(0) @@ -30,7 +33,7 @@ #define TEST_MISO_DONE_2 BIT(29) #define NAU8825_HS_PRESENT BIT(0) - +#define RT5682S_HS_PRESENT BIT(1) /* * Maxim MAX98390 */ @@ -45,6 +48,13 @@ */ #define NAU8825_CODEC_DAI "nau8825-hifi" +#define SOF_DMA_DL2 "SOF_DMA_DL2" +#define SOF_DMA_DL3 "SOF_DMA_DL3" +#define SOF_DMA_UL4 "SOF_DMA_UL4" +#define SOF_DMA_UL5 "SOF_DMA_UL5" + +#define RT5682S_CODEC_DAI "rt5682s-aif1" + /* FE */ SND_SOC_DAILINK_DEFS(playback2, DAILINK_COMP_ARRAY(COMP_CPU("DL2")), @@ -176,6 +186,49 @@ SND_SOC_DAILINK_DEFS(ul_src, "dmic-hifi")), 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_DL3, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL3")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(AFE_SOF_UL4, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL4")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(AFE_SOF_UL5, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL5")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +static const struct sof_conn_stream g_sof_conn_streams[] = { + { + .sof_link = "AFE_SOF_DL2", + .sof_dma = SOF_DMA_DL2, + .stream_dir = SNDRV_PCM_STREAM_PLAYBACK + }, + { + .sof_link = "AFE_SOF_DL3", + .sof_dma = SOF_DMA_DL3, + .stream_dir = SNDRV_PCM_STREAM_PLAYBACK + }, + { + .sof_link = "AFE_SOF_UL4", + .sof_dma = SOF_DMA_UL4, + .stream_dir = SNDRV_PCM_STREAM_CAPTURE + }, + { + .sof_link = "AFE_SOF_UL5", + .sof_dma = SOF_DMA_UL5, + .stream_dir = SNDRV_PCM_STREAM_CAPTURE + }, +}; + struct mt8188_mt6359_priv { struct snd_soc_jack dp_jack; struct snd_soc_jack hdmi_jack; @@ -246,6 +299,10 @@ static const struct snd_soc_dapm_widget mt8188_mt6359_widgets[] = { SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_SINK("HDMI"), SND_SOC_DAPM_SINK("DP"), + SND_SOC_DAPM_MIXER(SOF_DMA_DL2, SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER(SOF_DMA_DL3, SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER(SOF_DMA_UL4, SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER(SOF_DMA_UL5, SND_SOC_NOPM, 0, 0, NULL, 0), /* dynamic pinctrl */ SND_SOC_DAPM_PINCTRL("ETDM_SPK_PIN", "aud_etdm_spk_on", "aud_etdm_spk_off"), @@ -266,12 +323,25 @@ static const struct snd_kcontrol_new mt8188_nau8825_controls[] = { SOC_DAPM_PIN_SWITCH("Headphone Jack"), }; +static const struct snd_soc_dapm_route mt8188_mt6359_routes[] = { + /* SOF Uplink */ + {SOF_DMA_UL4, NULL, "O034"}, + {SOF_DMA_UL4, NULL, "O035"}, + {SOF_DMA_UL5, NULL, "O036"}, + {SOF_DMA_UL5, NULL, "O037"}, + /* SOF Downlink */ + {"I070", NULL, SOF_DMA_DL2}, + {"I071", NULL, SOF_DMA_DL2}, + {"I020", NULL, SOF_DMA_DL3}, + {"I021", NULL, SOF_DMA_DL3}, +}; + static int mt8188_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_component *cmpnt_afe = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); struct snd_soc_component *cmpnt_codec = - asoc_rtd_to_codec(rtd, 0)->component; + snd_soc_rtd_to_codec(rtd, 0)->component; struct snd_soc_dapm_widget *pin_w = NULL, *w; struct mtk_base_afe *afe; struct mt8188_afe_private *afe_priv; @@ -433,7 +503,7 @@ static int mt8188_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd) static int mt8188_mt6359_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_component *cmpnt_codec = - asoc_rtd_to_codec(rtd, 0)->component; + snd_soc_rtd_to_codec(rtd, 0)->component; /* set mtkaif protocol */ mt6359_set_mtkaif_protocol(cmpnt_codec, @@ -471,8 +541,17 @@ enum { DAI_LINK_ETDM3_OUT_BE, DAI_LINK_PCM1_BE, DAI_LINK_UL_SRC_BE, + DAI_LINK_REGULAR_LAST = DAI_LINK_UL_SRC_BE, + DAI_LINK_SOF_START, + DAI_LINK_SOF_DL2_BE = DAI_LINK_SOF_START, + DAI_LINK_SOF_DL3_BE, + DAI_LINK_SOF_UL4_BE, + DAI_LINK_SOF_UL5_BE, + DAI_LINK_SOF_END = DAI_LINK_SOF_UL5_BE, }; +#define DAI_LINK_REGULAR_NUM (DAI_LINK_REGULAR_LAST + 1) + static int mt8188_dptx_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -480,7 +559,7 @@ static int mt8188_dptx_hw_params(struct snd_pcm_substream *substream, unsigned int rate = params_rate(params); unsigned int mclk_fs_ratio = 256; unsigned int mclk_fs = rate * mclk_fs_ratio; - struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0); return snd_soc_dai_set_sysclk(dai, 0, mclk_fs, SND_SOC_CLOCK_OUT); } @@ -503,8 +582,9 @@ static int mt8188_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, static int mt8188_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd) { - struct mt8188_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card); + struct mt8188_mt6359_priv *priv = soc_card_data->mach_priv; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; int ret = 0; ret = snd_soc_card_jack_new_pins(rtd->card, "HDMI Jack", @@ -528,8 +608,9 @@ static int mt8188_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd) static int mt8188_dptx_codec_init(struct snd_soc_pcm_runtime *rtd) { - struct mt8188_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card); + struct mt8188_mt6359_priv *priv = soc_card_data->mach_priv; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; int ret = 0; ret = snd_soc_card_jack_new_pins(rtd->card, "DP Jack", SND_JACK_LINEOUT, @@ -577,7 +658,7 @@ static int mt8188_max98390_hw_params(struct snd_pcm_substream *substream, { struct snd_soc_pcm_runtime *rtd = substream->private_data; unsigned int bit_width = params_width(params); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); struct snd_soc_dai *codec_dai; int i; @@ -648,8 +729,9 @@ static int mt8188_max98390_codec_init(struct snd_soc_pcm_runtime *rtd) static int mt8188_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_card *card = rtd->card; - struct mt8188_mt6359_priv *priv = snd_soc_card_get_drvdata(card); - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card); + struct mt8188_mt6359_priv *priv = soc_card_data->mach_priv; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; struct snd_soc_jack *jack = &priv->headset_jack; int ret; @@ -693,9 +775,65 @@ static int mt8188_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd) return 0; }; +static int mt8188_rt5682s_codec_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_card *card = rtd->card; + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card); + struct mt8188_mt6359_priv *priv = soc_card_data->mach_priv; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_jack *jack = &priv->headset_jack; + int ret; + + ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_nau8825_widgets, + ARRAY_SIZE(mt8188_nau8825_widgets)); + if (ret) { + dev_err(rtd->dev, "unable to add rt5682s card widget, ret %d\n", ret); + return ret; + } + + ret = snd_soc_add_card_controls(card, mt8188_nau8825_controls, + ARRAY_SIZE(mt8188_nau8825_controls)); + if (ret) { + dev_err(rtd->dev, "unable to add rt5682s card controls, ret %d\n", ret); + return ret; + } + + ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1 | SND_JACK_BTN_2 | + SND_JACK_BTN_3, + jack, + nau8825_jack_pins, + ARRAY_SIZE(nau8825_jack_pins)); + if (ret) { + dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); + return ret; + } + + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); + ret = snd_soc_component_set_jack(component, jack, NULL); + + if (ret) { + dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret); + return ret; + } + + return 0; +}; + static void mt8188_nau8825_codec_exit(struct snd_soc_pcm_runtime *rtd) { - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; + + snd_soc_component_set_jack(component, NULL, NULL); +} + +static void mt8188_rt5682s_codec_exit(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component; snd_soc_component_set_jack(component, NULL, NULL); } @@ -703,8 +841,8 @@ static void mt8188_nau8825_codec_exit(struct snd_soc_pcm_runtime *rtd) static int mt8188_nau8825_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); unsigned int rate = params_rate(params); unsigned int bit_width = params_width(params); int clk_freq, ret; @@ -733,6 +871,78 @@ static int mt8188_nau8825_hw_params(struct snd_pcm_substream *substream, static const struct snd_soc_ops mt8188_nau8825_ops = { .hw_params = mt8188_nau8825_hw_params, }; + +static int mt8188_rt5682s_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0); + unsigned int rate = params_rate(params); + int bitwidth; + int ret; + + bitwidth = snd_pcm_format_width(params_format(params)); + if (bitwidth < 0) { + dev_err(card->dev, "invalid bit width: %d\n", bitwidth); + return bitwidth; + } + + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth); + if (ret) { + dev_err(card->dev, "failed to set tdm slot\n"); + return ret; + } + + ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1, RT5682_PLL1_S_BCLK1, + rate * 32, rate * 512); + if (ret) { + dev_err(card->dev, "failed to set pll\n"); + return ret; + } + + ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1, + rate * 512, SND_SOC_CLOCK_IN); + if (ret) { + dev_err(card->dev, "failed to set sysclk\n"); + return ret; + } + + return snd_soc_dai_set_sysclk(cpu_dai, 0, rate * 128, + SND_SOC_CLOCK_OUT); +} + +static const struct snd_soc_ops mt8188_rt5682s_i2s_ops = { + .hw_params = mt8188_rt5682s_i2s_hw_params, +}; + +static int mt8188_sof_be_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_component *cmpnt_afe = NULL; + struct snd_soc_pcm_runtime *runtime; + + /* find afe component */ + for_each_card_rtds(rtd->card, runtime) { + cmpnt_afe = snd_soc_rtdcom_lookup(runtime, AFE_PCM_NAME); + if (cmpnt_afe) + break; + } + + if (cmpnt_afe && !pm_runtime_active(cmpnt_afe->dev)) { + dev_err(rtd->dev, "afe pm runtime is not active!!\n"); + return -EINVAL; + } + + return 0; +} + +static const struct snd_soc_ops mt8188_sof_be_ops = { + .hw_params = mt8188_sof_be_hw_params, +}; + static struct snd_soc_dai_link mt8188_mt6359_dai_links[] = { /* FE */ [DAI_LINK_DL2_FE] = { @@ -1003,15 +1213,46 @@ static struct snd_soc_dai_link mt8188_mt6359_dai_links[] = { .dpcm_capture = 1, SND_SOC_DAILINK_REG(ul_src), }, + + /* SOF BE */ + [DAI_LINK_SOF_DL2_BE] = { + .name = "AFE_SOF_DL2", + .no_pcm = 1, + .dpcm_playback = 1, + .ops = &mt8188_sof_be_ops, + SND_SOC_DAILINK_REG(AFE_SOF_DL2), + }, + [DAI_LINK_SOF_DL3_BE] = { + .name = "AFE_SOF_DL3", + .no_pcm = 1, + .dpcm_playback = 1, + .ops = &mt8188_sof_be_ops, + SND_SOC_DAILINK_REG(AFE_SOF_DL3), + }, + [DAI_LINK_SOF_UL4_BE] = { + .name = "AFE_SOF_UL4", + .no_pcm = 1, + .dpcm_capture = 1, + .ops = &mt8188_sof_be_ops, + SND_SOC_DAILINK_REG(AFE_SOF_UL4), + }, + [DAI_LINK_SOF_UL5_BE] = { + .name = "AFE_SOF_UL5", + .no_pcm = 1, + .dpcm_capture = 1, + .ops = &mt8188_sof_be_ops, + SND_SOC_DAILINK_REG(AFE_SOF_UL5), + }, }; static void mt8188_fixup_controls(struct snd_soc_card *card) { - struct mt8188_mt6359_priv *priv = snd_soc_card_get_drvdata(card); + struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card); + struct mt8188_mt6359_priv *priv = soc_card_data->mach_priv; struct mt8188_card_data *card_data = (struct mt8188_card_data *)priv->private_data; struct snd_kcontrol *kctl; - if (card_data->quirk & NAU8825_HS_PRESENT) { + if (card_data->quirk & (NAU8825_HS_PRESENT | RT5682S_HS_PRESENT)) { struct snd_soc_dapm_widget *w, *next_w; for_each_card_widgets_safe(card, w, next_w) { @@ -1035,6 +1276,8 @@ static struct snd_soc_card mt8188_mt6359_soc_card = { .num_links = ARRAY_SIZE(mt8188_mt6359_dai_links), .dapm_widgets = mt8188_mt6359_widgets, .num_dapm_widgets = ARRAY_SIZE(mt8188_mt6359_widgets), + .dapm_routes = mt8188_mt6359_routes, + .num_dapm_routes = ARRAY_SIZE(mt8188_mt6359_routes), .controls = mt8188_mt6359_controls, .num_controls = ARRAY_SIZE(mt8188_mt6359_controls), .fixup_controls = mt8188_fixup_controls, @@ -1044,11 +1287,14 @@ static int mt8188_mt6359_dev_probe(struct platform_device *pdev) { struct snd_soc_card *card = &mt8188_mt6359_soc_card; struct device_node *platform_node; + struct device_node *adsp_node; + struct mtk_soc_card_data *soc_card_data; struct mt8188_mt6359_priv *priv; struct mt8188_card_data *card_data; struct snd_soc_dai_link *dai_link; bool init_mt6359 = false; bool init_nau8825 = false; + bool init_rt5682s = false; bool init_max98390 = false; bool init_dumb = false; int ret, i; @@ -1064,21 +1310,64 @@ static int mt8188_mt6359_dev_probe(struct platform_device *pdev) if (!card->name) card->name = card_data->name; - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - if (of_property_read_bool(pdev->dev.of_node, "audio-routing")) { ret = snd_soc_of_parse_audio_routing(card, "audio-routing"); if (ret) return ret; } + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + soc_card_data = devm_kzalloc(&pdev->dev, sizeof(*card_data), GFP_KERNEL); + if (!soc_card_data) + return -ENOMEM; + + soc_card_data->mach_priv = 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); + 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; + } + + 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", + mt8188_mt6359_dai_links, + ARRAY_SIZE(mt8188_mt6359_dai_links)); + if (ret) { + dev_err_probe(&pdev->dev, ret, "Parse dai-link fail\n"); + goto err_adsp_node; + } + } else { + if (!adsp_node) + card->num_links = DAI_LINK_REGULAR_NUM; + } + platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0); if (!platform_node) { - ret = -EINVAL; - return dev_err_probe(&pdev->dev, ret, "Property 'platform' missing or invalid\n"); + ret = dev_err_probe(&pdev->dev, -EINVAL, + "Property 'platform' missing or invalid\n"); + goto err_adsp_node; + } ret = parse_dai_link_info(card); @@ -1086,8 +1375,12 @@ static int mt8188_mt6359_dev_probe(struct platform_device *pdev) goto err; for_each_card_prelinks(card, i, dai_link) { - if (!dai_link->platforms->name) - dai_link->platforms->of_node = platform_node; + if (!dai_link->platforms->name) { + if (!strncmp(dai_link->name, "AFE_SOF", strlen("AFE_SOF")) && adsp_node) + dai_link->platforms->of_node = adsp_node; + else + dai_link->platforms->of_node = platform_node; + } if (strcmp(dai_link->name, "DPTX_BE") == 0) { if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) @@ -1118,6 +1411,13 @@ static int mt8188_mt6359_dev_probe(struct platform_device *pdev) dai_link->exit = mt8188_nau8825_codec_exit; init_nau8825 = true; } + } else if (!strcmp(dai_link->codecs->dai_name, RT5682S_CODEC_DAI)) { + dai_link->ops = &mt8188_rt5682s_i2s_ops; + if (!init_rt5682s) { + dai_link->init = mt8188_rt5682s_codec_init; + dai_link->exit = mt8188_rt5682s_codec_exit; + init_rt5682s = true; + } } else { if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) { if (!init_dumb) { @@ -1130,7 +1430,7 @@ static int mt8188_mt6359_dev_probe(struct platform_device *pdev) } priv->private_data = card_data; - snd_soc_card_set_drvdata(card, priv); + snd_soc_card_set_drvdata(card, soc_card_data); ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) @@ -1139,6 +1439,10 @@ static int mt8188_mt6359_dev_probe(struct platform_device *pdev) err: of_node_put(platform_node); clean_card_reference(card); + +err_adsp_node: + of_node_put(adsp_node); + return ret; } @@ -1151,9 +1455,15 @@ static struct mt8188_card_data mt8188_nau8825_card = { .quirk = NAU8825_HS_PRESENT, }; +static struct mt8188_card_data mt8188_rt5682s_card = { + .name = "mt8188_rt5682s", + .quirk = RT5682S_HS_PRESENT, +}; + static const struct of_device_id mt8188_mt6359_dt_match[] = { { .compatible = "mediatek,mt8188-mt6359-evb", .data = &mt8188_evb_card, }, { .compatible = "mediatek,mt8188-nau8825", .data = &mt8188_nau8825_card, }, + { .compatible = "mediatek,mt8188-rt5682s", .data = &mt8188_rt5682s_card, }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, mt8188_mt6359_dt_match); |