Path: blob/master/sound/soc/mediatek/mt8189/mt8189-nau8825.c
122943 views
// SPDX-License-Identifier: GPL-2.01/*2* mt8189-nau8825.c -- mt8189 nau8825 ALSA SoC machine driver3*4* Copyright (c) 2025 MediaTek Inc.5* Author: Darren Ye <[email protected]>6*/78#include <linux/input.h>9#include <linux/module.h>10#include <linux/of_device.h>11#include <linux/pm_runtime.h>1213#include <sound/soc.h>14#include <sound/jack.h>15#include <sound/pcm_params.h>1617#include "mt8189-afe-common.h"1819#include "../common/mtk-soc-card.h"20#include "../common/mtk-soundcard-driver.h"21#include "../common/mtk-afe-platform-driver.h"2223#include "../../codecs/cs35l41.h"24#include "../../codecs/nau8825.h"25#include "../../codecs/rt5682s.h"26#include "../../codecs/rt5682.h"2728#define NAU8825_HS_PRESENT BIT(0)29#define RT5682S_HS_PRESENT BIT(1)30#define RT5650_HS_PRESENT BIT(2)31#define RT5682I_HS_PRESENT BIT(3)32#define ES8326_HS_PRESENT BIT(4)3334/*35* Nau88l2536*/37#define NAU8825_CODEC_DAI "nau8825-hifi"3839/*40* Rt5682s41*/42#define RT5682S_CODEC_DAI "rt5682s-aif1"4344/*45* Rt565046*/47#define RT5650_CODEC_DAI "rt5645-aif1"4849/*50* Rt5682i51*/52#define RT5682I_CODEC_DAI "rt5682-aif1"5354/*55* Cs35l4156*/57#define CS35L41_CODEC_DAI "cs35l41-pcm"58#define CS35L41_DEV0_NAME "cs35l41.7-0040"59#define CS35L41_DEV1_NAME "cs35l41.7-0042"6061/*62* ES832663*/64#define ES8326_CODEC_DAI "ES8326 HiFi"6566enum mt8189_jacks {67MT8189_JACK_HEADSET,68MT8189_JACK_DP,69MT8189_JACK_HDMI,70MT8189_JACK_MAX,71};7273static struct snd_soc_jack_pin mt8189_dp_jack_pins[] = {74{75.pin = "DP",76.mask = SND_JACK_LINEOUT,77},78};7980static struct snd_soc_jack_pin mt8189_hdmi_jack_pins[] = {81{82.pin = "HDMI",83.mask = SND_JACK_LINEOUT,84},85};8687static struct snd_soc_jack_pin mt8189_headset_jack_pins[] = {88{89.pin = "Headphone Jack",90.mask = SND_JACK_HEADPHONE,91},92{93.pin = "Headset Mic",94.mask = SND_JACK_MICROPHONE,95},96};9798static const struct snd_kcontrol_new mt8189_dumb_spk_controls[] = {99SOC_DAPM_PIN_SWITCH("Ext Spk"),100};101102static const struct snd_soc_dapm_widget mt8189_dumb_spk_widgets[] = {103SND_SOC_DAPM_SPK("Ext Spk", NULL),104};105106static const struct snd_soc_dapm_widget mt8189_headset_widgets[] = {107SND_SOC_DAPM_HP("Headphone Jack", NULL),108SND_SOC_DAPM_MIC("Headset Mic", NULL),109};110111static const struct snd_kcontrol_new mt8189_headset_controls[] = {112SOC_DAPM_PIN_SWITCH("Headphone Jack"),113SOC_DAPM_PIN_SWITCH("Headset Mic"),114};115116static const struct snd_soc_dapm_widget mt8189_nau8825_card_widgets[] = {117SND_SOC_DAPM_SINK("DP"),118};119120static int mt8189_common_i2s_startup(struct snd_pcm_substream *substream)121{122static const unsigned int rates[] = {12348000,124};125static const struct snd_pcm_hw_constraint_list constraints_rates = {126.count = ARRAY_SIZE(rates),127.list = rates,128};129130return snd_pcm_hw_constraint_list(substream->runtime, 0,131SNDRV_PCM_HW_PARAM_RATE,132&constraints_rates);133}134135static int mt8189_common_i2s_hw_params(struct snd_pcm_substream *substream,136struct snd_pcm_hw_params *params)137{138struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);139unsigned int rate = params_rate(params);140unsigned int mclk_fs_ratio = 128;141unsigned int mclk_fs = rate * mclk_fs_ratio;142struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);143144return snd_soc_dai_set_sysclk(cpu_dai,1450, mclk_fs, SND_SOC_CLOCK_OUT);146}147148static const struct snd_soc_ops mt8189_common_i2s_ops = {149.startup = mt8189_common_i2s_startup,150.hw_params = mt8189_common_i2s_hw_params,151};152153static int mt8189_dptx_hw_params(struct snd_pcm_substream *substream,154struct snd_pcm_hw_params *params)155{156struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);157unsigned int rate = params_rate(params);158unsigned int mclk_fs_ratio = 256;159unsigned int mclk_fs = rate * mclk_fs_ratio;160struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0);161162return snd_soc_dai_set_sysclk(dai, 0, mclk_fs, SND_SOC_CLOCK_OUT);163}164165static const struct snd_soc_ops mt8189_dptx_ops = {166.hw_params = mt8189_dptx_hw_params,167};168169static int mt8189_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,170struct snd_pcm_hw_params *params)171{172dev_dbg(rtd->dev, "%s(), fix format to 32bit\n", __func__);173174/* fix BE i2s format to 32bit, clean param mask first */175snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),1760, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);177178params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);179180return 0;181}182183static const struct snd_soc_ops mt8189_pcm_ops = {184.startup = mt8189_common_i2s_startup,185};186187static int mt8189_nau8825_hw_params(struct snd_pcm_substream *substream,188struct snd_pcm_hw_params *params)189{190struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);191struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);192unsigned int rate = params_rate(params);193unsigned int bit_width = params_width(params);194int clk_freq, ret;195196clk_freq = rate * 2 * bit_width;197dev_dbg(codec_dai->dev, "clk_freq %d, rate: %d, bit_width: %d\n",198clk_freq, rate, bit_width);199200/* Configure clock for codec */201ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_BLK, 0,202SND_SOC_CLOCK_IN);203if (ret < 0) {204dev_err(codec_dai->dev, "can't set BCLK clock %d\n", ret);205return ret;206}207208/* Configure pll for codec */209ret = snd_soc_dai_set_pll(codec_dai, 0, 0, clk_freq,210rate * 256);211if (ret < 0) {212dev_err(codec_dai->dev, "can't set BCLK: %d\n", ret);213return ret;214}215216return 0;217}218219static const struct snd_soc_ops mt8189_nau8825_ops = {220.startup = mt8189_common_i2s_startup,221.hw_params = mt8189_nau8825_hw_params,222};223224static int mt8189_rtxxxx_i2s_hw_params(struct snd_pcm_substream *substream,225struct snd_pcm_hw_params *params)226{227struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);228struct snd_soc_card *card = rtd->card;229struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);230struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);231unsigned int rate = params_rate(params);232int bitwidth;233int ret;234235bitwidth = snd_pcm_format_width(params_format(params));236if (bitwidth < 0) {237dev_err(card->dev, "invalid bit width: %d\n", bitwidth);238return bitwidth;239}240241ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth);242if (ret) {243dev_err(card->dev, "failed to set tdm slot\n");244return ret;245}246247ret = snd_soc_dai_set_pll(codec_dai, 0, 1, rate * 32, rate * 512);248if (ret) {249dev_err(card->dev, "failed to set pll\n");250return ret;251}252253ret = snd_soc_dai_set_sysclk(codec_dai, 1, rate * 512, SND_SOC_CLOCK_IN);254if (ret) {255dev_err(card->dev, "failed to set sysclk\n");256return ret;257}258259return snd_soc_dai_set_sysclk(cpu_dai, 0, rate * 512,260SND_SOC_CLOCK_OUT);261}262263static const struct snd_soc_ops mt8189_rtxxxx_i2s_ops = {264.startup = mt8189_common_i2s_startup,265.hw_params = mt8189_rtxxxx_i2s_hw_params,266};267268static int mt8189_cs35l41_i2s_hw_params(struct snd_pcm_substream *substream,269struct snd_pcm_hw_params *params)270{271struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);272unsigned int rate = params_rate(params);273unsigned int mclk_fs = rate * 128;274struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);275struct snd_soc_dai *codec_dai;276int clk_freq = rate * 32;277int rx_slot[] = {0, 1};278int i, ret;279280for_each_rtd_codec_dais(rtd, i, codec_dai) {281ret = snd_soc_component_set_sysclk(codec_dai->component,282CS35L41_CLKID_SCLK, 0,283clk_freq, SND_SOC_CLOCK_IN);284if (ret < 0) {285dev_err(codec_dai->dev, "set component sysclk fail: %d\n",286ret);287return ret;288}289290ret = snd_soc_dai_set_sysclk(codec_dai, CS35L41_CLKID_SCLK,291clk_freq, SND_SOC_CLOCK_IN);292if (ret < 0) {293dev_err(codec_dai->dev, "set sysclk fail: %d\n",294ret);295return ret;296}297298ret = snd_soc_dai_set_channel_map(codec_dai, 0, NULL,2991, &rx_slot[i]);300if (ret < 0) {301dev_err(codec_dai->dev, "set channel map fail: %d\n",302ret);303return ret;304}305}306307return snd_soc_dai_set_sysclk(cpu_dai,3080, mclk_fs, SND_SOC_CLOCK_OUT);309}310311static const struct snd_soc_ops mt8189_cs35l41_i2s_ops = {312.startup = mt8189_common_i2s_startup,313.hw_params = mt8189_cs35l41_i2s_hw_params,314};315316static int mt8189_es8326_hw_params(struct snd_pcm_substream *substream,317struct snd_pcm_hw_params *params)318{319struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);320struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);321struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);322unsigned int rate = params_rate(params);323int ret;324325/* Configure MCLK for codec */326ret = snd_soc_dai_set_sysclk(codec_dai, 0, rate * 256, SND_SOC_CLOCK_IN);327if (ret < 0) {328dev_err(codec_dai->dev, "can't set MCLK %d\n", ret);329return ret;330}331332/* Configure MCLK for cpu */333return snd_soc_dai_set_sysclk(cpu_dai, 0, rate * 256, SND_SOC_CLOCK_OUT);334}335336static const struct snd_soc_ops mt8189_es8326_ops = {337.startup = mt8189_common_i2s_startup,338.hw_params = mt8189_es8326_hw_params,339};340341static int mt8189_dumb_amp_init(struct snd_soc_pcm_runtime *rtd)342{343struct snd_soc_card *card = rtd->card;344struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);345int ret;346347ret = snd_soc_dapm_new_controls(dapm, mt8189_dumb_spk_widgets,348ARRAY_SIZE(mt8189_dumb_spk_widgets));349if (ret) {350dev_err(rtd->dev, "unable to add Dumb Speaker dapm, ret %d\n", ret);351return ret;352}353354ret = snd_soc_add_card_controls(card, mt8189_dumb_spk_controls,355ARRAY_SIZE(mt8189_dumb_spk_controls));356if (ret) {357dev_err(rtd->dev, "unable to add Dumb card controls, ret %d\n", ret);358return ret;359}360361return 0;362}363364static int mt8189_dptx_codec_init(struct snd_soc_pcm_runtime *rtd)365{366struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card);367struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8189_JACK_DP];368struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;369int ret;370371ret = snd_soc_card_jack_new_pins(rtd->card, "DP Jack", SND_JACK_LINEOUT,372jack, mt8189_dp_jack_pins,373ARRAY_SIZE(mt8189_dp_jack_pins));374if (ret) {375dev_err(rtd->dev, "%s, new jack failed: %d\n", __func__, ret);376return ret;377}378379ret = snd_soc_component_set_jack(component, jack, NULL);380if (ret) {381dev_err(rtd->dev, "%s, set jack failed on %s (ret=%d)\n",382__func__, component->name, ret);383return ret;384}385386return 0;387}388389static int mt8189_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd)390{391struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card);392struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8189_JACK_HDMI];393struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;394int ret;395396ret = snd_soc_card_jack_new_pins(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,397jack, mt8189_hdmi_jack_pins,398ARRAY_SIZE(mt8189_hdmi_jack_pins));399if (ret) {400dev_err(rtd->dev, "%s, new jack failed: %d\n", __func__, ret);401return ret;402}403404ret = snd_soc_component_set_jack(component, jack, NULL);405if (ret) {406dev_err(rtd->dev, "%s, set jack failed on %s (ret=%d)\n",407__func__, component->name, ret);408return ret;409}410411return 0;412}413414static int mt8189_headset_codec_init(struct snd_soc_pcm_runtime *rtd)415{416struct snd_soc_card *card = rtd->card;417struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);418struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8189_JACK_HEADSET];419struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;420struct mtk_platform_card_data *card_data = soc_card_data->card_data;421struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);422int ret;423int type;424425ret = snd_soc_dapm_new_controls(dapm, mt8189_headset_widgets,426ARRAY_SIZE(mt8189_headset_widgets));427if (ret) {428dev_err(rtd->dev, "unable to add nau8825 card widget, ret %d\n", ret);429return ret;430}431432ret = snd_soc_add_card_controls(card, mt8189_headset_controls,433ARRAY_SIZE(mt8189_headset_controls));434if (ret) {435dev_err(rtd->dev, "unable to add nau8825 card controls, ret %d\n", ret);436return ret;437}438439ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",440SND_JACK_HEADSET | SND_JACK_BTN_0 |441SND_JACK_BTN_1 | SND_JACK_BTN_2 |442SND_JACK_BTN_3,443jack,444mt8189_headset_jack_pins,445ARRAY_SIZE(mt8189_headset_jack_pins));446if (ret) {447dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);448return ret;449}450451if (card_data->flags & ES8326_HS_PRESENT) {452snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);453snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP);454snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);455snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);456} else {457snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);458snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);459snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);460snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);461}462463type = SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3;464ret = snd_soc_component_set_jack(component, jack, (void *)&type);465if (ret) {466dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);467return ret;468}469470return 0;471};472473static void mt8189_headset_codec_exit(struct snd_soc_pcm_runtime *rtd)474{475struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;476477snd_soc_component_set_jack(component, NULL, NULL);478}479480/* FE */481SND_SOC_DAILINK_DEFS(playback0,482DAILINK_COMP_ARRAY(COMP_CPU("DL0")),483DAILINK_COMP_ARRAY(COMP_DUMMY()),484DAILINK_COMP_ARRAY(COMP_EMPTY()));485SND_SOC_DAILINK_DEFS(playback1,486DAILINK_COMP_ARRAY(COMP_CPU("DL1")),487DAILINK_COMP_ARRAY(COMP_DUMMY()),488DAILINK_COMP_ARRAY(COMP_EMPTY()));489SND_SOC_DAILINK_DEFS(playback2,490DAILINK_COMP_ARRAY(COMP_CPU("DL2")),491DAILINK_COMP_ARRAY(COMP_DUMMY()),492DAILINK_COMP_ARRAY(COMP_EMPTY()));493SND_SOC_DAILINK_DEFS(playback3,494DAILINK_COMP_ARRAY(COMP_CPU("DL3")),495DAILINK_COMP_ARRAY(COMP_DUMMY()),496DAILINK_COMP_ARRAY(COMP_EMPTY()));497SND_SOC_DAILINK_DEFS(playback4,498DAILINK_COMP_ARRAY(COMP_CPU("DL4")),499DAILINK_COMP_ARRAY(COMP_DUMMY()),500DAILINK_COMP_ARRAY(COMP_EMPTY()));501SND_SOC_DAILINK_DEFS(playback5,502DAILINK_COMP_ARRAY(COMP_CPU("DL5")),503DAILINK_COMP_ARRAY(COMP_DUMMY()),504DAILINK_COMP_ARRAY(COMP_EMPTY()));505SND_SOC_DAILINK_DEFS(playback6,506DAILINK_COMP_ARRAY(COMP_CPU("DL6")),507DAILINK_COMP_ARRAY(COMP_DUMMY()),508DAILINK_COMP_ARRAY(COMP_EMPTY()));509SND_SOC_DAILINK_DEFS(playback7,510DAILINK_COMP_ARRAY(COMP_CPU("DL7")),511DAILINK_COMP_ARRAY(COMP_DUMMY()),512DAILINK_COMP_ARRAY(COMP_EMPTY()));513SND_SOC_DAILINK_DEFS(playback8,514DAILINK_COMP_ARRAY(COMP_CPU("DL8")),515DAILINK_COMP_ARRAY(COMP_DUMMY()),516DAILINK_COMP_ARRAY(COMP_EMPTY()));517SND_SOC_DAILINK_DEFS(playback23,518DAILINK_COMP_ARRAY(COMP_CPU("DL23")),519DAILINK_COMP_ARRAY(COMP_DUMMY()),520DAILINK_COMP_ARRAY(COMP_EMPTY()));521SND_SOC_DAILINK_DEFS(playback24,522DAILINK_COMP_ARRAY(COMP_CPU("DL24")),523DAILINK_COMP_ARRAY(COMP_DUMMY()),524DAILINK_COMP_ARRAY(COMP_EMPTY()));525SND_SOC_DAILINK_DEFS(playback25,526DAILINK_COMP_ARRAY(COMP_CPU("DL25")),527DAILINK_COMP_ARRAY(COMP_DUMMY()),528DAILINK_COMP_ARRAY(COMP_EMPTY()));529SND_SOC_DAILINK_DEFS(playback_24ch,530DAILINK_COMP_ARRAY(COMP_CPU("DL_24CH")),531DAILINK_COMP_ARRAY(COMP_DUMMY()),532DAILINK_COMP_ARRAY(COMP_EMPTY()));533SND_SOC_DAILINK_DEFS(capture0,534DAILINK_COMP_ARRAY(COMP_CPU("UL0")),535DAILINK_COMP_ARRAY(COMP_DUMMY()),536DAILINK_COMP_ARRAY(COMP_EMPTY()));537SND_SOC_DAILINK_DEFS(capture1,538DAILINK_COMP_ARRAY(COMP_CPU("UL1")),539DAILINK_COMP_ARRAY(COMP_DUMMY()),540DAILINK_COMP_ARRAY(COMP_EMPTY()));541SND_SOC_DAILINK_DEFS(capture2,542DAILINK_COMP_ARRAY(COMP_CPU("UL2")),543DAILINK_COMP_ARRAY(COMP_DUMMY()),544DAILINK_COMP_ARRAY(COMP_EMPTY()));545SND_SOC_DAILINK_DEFS(capture3,546DAILINK_COMP_ARRAY(COMP_CPU("UL3")),547DAILINK_COMP_ARRAY(COMP_DUMMY()),548DAILINK_COMP_ARRAY(COMP_EMPTY()));549SND_SOC_DAILINK_DEFS(capture4,550DAILINK_COMP_ARRAY(COMP_CPU("UL4")),551DAILINK_COMP_ARRAY(COMP_DUMMY()),552DAILINK_COMP_ARRAY(COMP_EMPTY()));553SND_SOC_DAILINK_DEFS(capture5,554DAILINK_COMP_ARRAY(COMP_CPU("UL5")),555DAILINK_COMP_ARRAY(COMP_DUMMY()),556DAILINK_COMP_ARRAY(COMP_EMPTY()));557SND_SOC_DAILINK_DEFS(capture6,558DAILINK_COMP_ARRAY(COMP_CPU("UL6")),559DAILINK_COMP_ARRAY(COMP_DUMMY()),560DAILINK_COMP_ARRAY(COMP_EMPTY()));561SND_SOC_DAILINK_DEFS(capture7,562DAILINK_COMP_ARRAY(COMP_CPU("UL7")),563DAILINK_COMP_ARRAY(COMP_DUMMY()),564DAILINK_COMP_ARRAY(COMP_EMPTY()));565SND_SOC_DAILINK_DEFS(capture8,566DAILINK_COMP_ARRAY(COMP_CPU("UL8")),567DAILINK_COMP_ARRAY(COMP_DUMMY()),568DAILINK_COMP_ARRAY(COMP_EMPTY()));569SND_SOC_DAILINK_DEFS(capture9,570DAILINK_COMP_ARRAY(COMP_CPU("UL9")),571DAILINK_COMP_ARRAY(COMP_DUMMY()),572DAILINK_COMP_ARRAY(COMP_EMPTY()));573SND_SOC_DAILINK_DEFS(capture10,574DAILINK_COMP_ARRAY(COMP_CPU("UL10")),575DAILINK_COMP_ARRAY(COMP_DUMMY()),576DAILINK_COMP_ARRAY(COMP_EMPTY()));577SND_SOC_DAILINK_DEFS(capture24,578DAILINK_COMP_ARRAY(COMP_CPU("UL24")),579DAILINK_COMP_ARRAY(COMP_DUMMY()),580DAILINK_COMP_ARRAY(COMP_EMPTY()));581SND_SOC_DAILINK_DEFS(capture25,582DAILINK_COMP_ARRAY(COMP_CPU("UL25")),583DAILINK_COMP_ARRAY(COMP_DUMMY()),584DAILINK_COMP_ARRAY(COMP_EMPTY()));585SND_SOC_DAILINK_DEFS(capture_cm0,586DAILINK_COMP_ARRAY(COMP_CPU("UL_CM0")),587DAILINK_COMP_ARRAY(COMP_DUMMY()),588DAILINK_COMP_ARRAY(COMP_EMPTY()));589SND_SOC_DAILINK_DEFS(capture_cm1,590DAILINK_COMP_ARRAY(COMP_CPU("UL_CM1")),591DAILINK_COMP_ARRAY(COMP_DUMMY()),592DAILINK_COMP_ARRAY(COMP_EMPTY()));593SND_SOC_DAILINK_DEFS(capture_etdm_in0,594DAILINK_COMP_ARRAY(COMP_CPU("UL_ETDM_IN0")),595DAILINK_COMP_ARRAY(COMP_DUMMY()),596DAILINK_COMP_ARRAY(COMP_EMPTY()));597SND_SOC_DAILINK_DEFS(capture_etdm_in1,598DAILINK_COMP_ARRAY(COMP_CPU("UL_ETDM_IN1")),599DAILINK_COMP_ARRAY(COMP_DUMMY()),600DAILINK_COMP_ARRAY(COMP_EMPTY()));601SND_SOC_DAILINK_DEFS(playback_hdmi,602DAILINK_COMP_ARRAY(COMP_CPU("HDMI")),603DAILINK_COMP_ARRAY(COMP_DUMMY()),604DAILINK_COMP_ARRAY(COMP_EMPTY()));605/* BE */606SND_SOC_DAILINK_DEFS(ap_dmic,607DAILINK_COMP_ARRAY(COMP_CPU("AP_DMIC")),608DAILINK_COMP_ARRAY(COMP_DUMMY()),609DAILINK_COMP_ARRAY(COMP_EMPTY()));610SND_SOC_DAILINK_DEFS(ap_dmic_ch34,611DAILINK_COMP_ARRAY(COMP_CPU("AP_DMIC_CH34")),612DAILINK_COMP_ARRAY(COMP_DUMMY()),613DAILINK_COMP_ARRAY(COMP_EMPTY()));614SND_SOC_DAILINK_DEFS(i2sin0,615DAILINK_COMP_ARRAY(COMP_CPU("I2SIN0")),616DAILINK_COMP_ARRAY(COMP_DUMMY()),617DAILINK_COMP_ARRAY(COMP_EMPTY()));618SND_SOC_DAILINK_DEFS(i2sin1,619DAILINK_COMP_ARRAY(COMP_CPU("I2SIN1")),620DAILINK_COMP_ARRAY(COMP_DUMMY()),621DAILINK_COMP_ARRAY(COMP_EMPTY()));622SND_SOC_DAILINK_DEFS(i2sout0,623DAILINK_COMP_ARRAY(COMP_CPU("I2SOUT0")),624DAILINK_COMP_ARRAY(COMP_DUMMY()),625DAILINK_COMP_ARRAY(COMP_EMPTY()));626SND_SOC_DAILINK_DEFS(i2sout1,627DAILINK_COMP_ARRAY(COMP_CPU("I2SOUT1")),628DAILINK_COMP_ARRAY(COMP_DUMMY()),629DAILINK_COMP_ARRAY(COMP_EMPTY()));630SND_SOC_DAILINK_DEFS(pcm0,631DAILINK_COMP_ARRAY(COMP_CPU("PCM 0")),632DAILINK_COMP_ARRAY(COMP_DUMMY()),633DAILINK_COMP_ARRAY(COMP_EMPTY()));634SND_SOC_DAILINK_DEFS(tdm_dptx,635DAILINK_COMP_ARRAY(COMP_CPU("TDM_DPTX")),636DAILINK_COMP_ARRAY(COMP_DUMMY()),637DAILINK_COMP_ARRAY(COMP_EMPTY()));638639static struct snd_soc_dai_link mt8189_nau8825_dai_links[] = {640/* Front End DAI links */641{642.name = "DL0_FE",643.stream_name = "DL0 Playback",644.trigger = {SND_SOC_DPCM_TRIGGER_PRE,645SND_SOC_DPCM_TRIGGER_PRE},646.dynamic = 1,647.playback_only = 1,648.dpcm_merged_format = 1,649SND_SOC_DAILINK_REG(playback0),650},651{652.name = "DL1_FE",653.stream_name = "DL1 Playback",654.trigger = {SND_SOC_DPCM_TRIGGER_PRE,655SND_SOC_DPCM_TRIGGER_PRE},656.dynamic = 1,657.playback_only = 1,658.dpcm_merged_format = 1,659SND_SOC_DAILINK_REG(playback1),660},661{662.name = "UL0_FE",663.stream_name = "UL0 Capture",664.trigger = {SND_SOC_DPCM_TRIGGER_PRE,665SND_SOC_DPCM_TRIGGER_PRE},666.dynamic = 1,667.capture_only = 1,668.dpcm_merged_format = 1,669SND_SOC_DAILINK_REG(capture0),670},671{672.name = "UL1_FE",673.stream_name = "UL1 Capture",674.trigger = {SND_SOC_DPCM_TRIGGER_PRE,675SND_SOC_DPCM_TRIGGER_PRE},676.dynamic = 1,677.capture_only = 1,678.dpcm_merged_format = 1,679SND_SOC_DAILINK_REG(capture1),680},681{682.name = "UL2_FE",683.stream_name = "UL2 Capture",684.trigger = {SND_SOC_DPCM_TRIGGER_PRE,685SND_SOC_DPCM_TRIGGER_PRE},686.dynamic = 1,687.capture_only = 1,688.dpcm_merged_format = 1,689SND_SOC_DAILINK_REG(capture2),690},691{692.name = "HDMI_FE",693.stream_name = "HDMI Playback",694.trigger = {SND_SOC_DPCM_TRIGGER_PRE,695SND_SOC_DPCM_TRIGGER_PRE},696.dynamic = 1,697.playback_only = 1,698SND_SOC_DAILINK_REG(playback_hdmi),699},700{701.name = "DL2_FE",702.stream_name = "DL2 Playback",703.trigger = {SND_SOC_DPCM_TRIGGER_PRE,704SND_SOC_DPCM_TRIGGER_PRE},705.dynamic = 1,706.playback_only = 1,707SND_SOC_DAILINK_REG(playback2),708},709{710.name = "DL3_FE",711.stream_name = "DL3 Playback",712.trigger = {SND_SOC_DPCM_TRIGGER_PRE,713SND_SOC_DPCM_TRIGGER_PRE},714.dynamic = 1,715.playback_only = 1,716SND_SOC_DAILINK_REG(playback3),717},718{719.name = "DL4_FE",720.stream_name = "DL4 Playback",721.trigger = {SND_SOC_DPCM_TRIGGER_PRE,722SND_SOC_DPCM_TRIGGER_PRE},723.dynamic = 1,724.playback_only = 1,725SND_SOC_DAILINK_REG(playback4),726},727{728.name = "DL5_FE",729.stream_name = "DL5 Playback",730.trigger = {SND_SOC_DPCM_TRIGGER_PRE,731SND_SOC_DPCM_TRIGGER_PRE},732.dynamic = 1,733.playback_only = 1,734SND_SOC_DAILINK_REG(playback5),735},736{737.name = "DL6_FE",738.stream_name = "DL6 Playback",739.trigger = {SND_SOC_DPCM_TRIGGER_PRE,740SND_SOC_DPCM_TRIGGER_PRE},741.dynamic = 1,742.playback_only = 1,743SND_SOC_DAILINK_REG(playback6),744},745{746.name = "DL7_FE",747.stream_name = "DL7 Playback",748.trigger = {SND_SOC_DPCM_TRIGGER_PRE,749SND_SOC_DPCM_TRIGGER_PRE},750.dynamic = 1,751.playback_only = 1,752SND_SOC_DAILINK_REG(playback7),753},754{755.name = "DL8 FE",756.stream_name = "DL8 Playback",757.trigger = {SND_SOC_DPCM_TRIGGER_PRE,758SND_SOC_DPCM_TRIGGER_PRE},759.dynamic = 1,760.playback_only = 1,761SND_SOC_DAILINK_REG(playback8),762},763{764.name = "DL23 FE",765.stream_name = "DL23 Playback",766.trigger = {SND_SOC_DPCM_TRIGGER_PRE,767SND_SOC_DPCM_TRIGGER_PRE},768.dynamic = 1,769.playback_only = 1,770SND_SOC_DAILINK_REG(playback23),771},772{773.name = "DL24 FE",774.stream_name = "DL24 Playback",775.trigger = {SND_SOC_DPCM_TRIGGER_PRE,776SND_SOC_DPCM_TRIGGER_PRE},777.dynamic = 1,778.playback_only = 1,779SND_SOC_DAILINK_REG(playback24),780},781{782.name = "DL25 FE",783.stream_name = "DL25 Playback",784.trigger = {SND_SOC_DPCM_TRIGGER_PRE,785SND_SOC_DPCM_TRIGGER_PRE},786.dynamic = 1,787.playback_only = 1,788SND_SOC_DAILINK_REG(playback25),789},790{791.name = "DL_24CH_FE",792.stream_name = "DL_24CH Playback",793.trigger = {SND_SOC_DPCM_TRIGGER_PRE,794SND_SOC_DPCM_TRIGGER_PRE},795.dynamic = 1,796.playback_only = 1,797SND_SOC_DAILINK_REG(playback_24ch),798},799{800.name = "UL9_FE",801.stream_name = "UL9 Capture",802.trigger = {SND_SOC_DPCM_TRIGGER_PRE,803SND_SOC_DPCM_TRIGGER_PRE},804.dynamic = 1,805.capture_only = 1,806SND_SOC_DAILINK_REG(capture9),807},808{809.name = "UL3_FE",810.stream_name = "UL3 Capture",811.trigger = {SND_SOC_DPCM_TRIGGER_PRE,812SND_SOC_DPCM_TRIGGER_PRE},813.dynamic = 1,814.capture_only = 1,815SND_SOC_DAILINK_REG(capture3),816},817{818.name = "UL7_FE",819.stream_name = "UL7 Capture",820.trigger = {SND_SOC_DPCM_TRIGGER_PRE,821SND_SOC_DPCM_TRIGGER_PRE},822.dynamic = 1,823.capture_only = 1,824SND_SOC_DAILINK_REG(capture7),825},826{827.name = "UL4_FE",828.stream_name = "UL4 Capture",829.trigger = {SND_SOC_DPCM_TRIGGER_PRE,830SND_SOC_DPCM_TRIGGER_PRE},831.dynamic = 1,832.capture_only = 1,833SND_SOC_DAILINK_REG(capture4),834},835{836.name = "UL5_FE",837.stream_name = "UL5 Capture",838.trigger = {SND_SOC_DPCM_TRIGGER_PRE,839SND_SOC_DPCM_TRIGGER_PRE},840.dynamic = 1,841.capture_only = 1,842SND_SOC_DAILINK_REG(capture5),843},844{845.name = "UL_CM0_FE",846.stream_name = "UL_CM0 Capture",847.trigger = {SND_SOC_DPCM_TRIGGER_PRE,848SND_SOC_DPCM_TRIGGER_PRE},849.dynamic = 1,850.capture_only = 1,851SND_SOC_DAILINK_REG(capture_cm0),852},853{854.name = "UL_CM1_FE",855.stream_name = "UL_CM1 Capture",856.trigger = {SND_SOC_DPCM_TRIGGER_PRE,857SND_SOC_DPCM_TRIGGER_PRE},858.dynamic = 1,859.capture_only = 1,860SND_SOC_DAILINK_REG(capture_cm1),861},862{863.name = "UL10_FE",864.stream_name = "UL10 Capture",865.trigger = {SND_SOC_DPCM_TRIGGER_PRE,866SND_SOC_DPCM_TRIGGER_PRE},867.dynamic = 1,868.capture_only = 1,869SND_SOC_DAILINK_REG(capture10),870},871{872.name = "UL6_FE",873.stream_name = "UL6 Capture",874.trigger = {SND_SOC_DPCM_TRIGGER_PRE,875SND_SOC_DPCM_TRIGGER_PRE},876.dynamic = 1,877.capture_only = 1,878SND_SOC_DAILINK_REG(capture6),879},880{881.name = "UL25_FE",882.stream_name = "UL25 Capture",883.trigger = {SND_SOC_DPCM_TRIGGER_PRE,884SND_SOC_DPCM_TRIGGER_PRE},885.dynamic = 1,886.capture_only = 1,887SND_SOC_DAILINK_REG(capture25),888},889{890.name = "UL8_FE",891.stream_name = "UL8 Capture_Mono_1",892.trigger = {SND_SOC_DPCM_TRIGGER_PRE,893SND_SOC_DPCM_TRIGGER_PRE},894.dynamic = 1,895.capture_only = 1,896SND_SOC_DAILINK_REG(capture8),897},898{899.name = "UL24_FE",900.stream_name = "UL24 Capture_Mono_2",901.trigger = {SND_SOC_DPCM_TRIGGER_PRE,902SND_SOC_DPCM_TRIGGER_PRE},903.dynamic = 1,904.capture_only = 1,905SND_SOC_DAILINK_REG(capture24),906},907{908.name = "UL_ETDM_In0_FE",909.stream_name = "UL_ETDM_In0 Capture",910.trigger = {SND_SOC_DPCM_TRIGGER_PRE,911SND_SOC_DPCM_TRIGGER_PRE},912.dynamic = 1,913.capture_only = 1,914SND_SOC_DAILINK_REG(capture_etdm_in0),915},916{917.name = "UL_ETDM_In1_FE",918.stream_name = "UL_ETDM_In1 Capture",919.trigger = {SND_SOC_DPCM_TRIGGER_PRE,920SND_SOC_DPCM_TRIGGER_PRE},921.dynamic = 1,922.capture_only = 1,923SND_SOC_DAILINK_REG(capture_etdm_in1),924},925/* Back End DAI links */926{927.name = "I2SIN0_BE",928.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC929| SND_SOC_DAIFMT_GATED,930.ops = &mt8189_common_i2s_ops,931.no_pcm = 1,932.capture_only = 1,933.ignore_suspend = 1,934SND_SOC_DAILINK_REG(i2sin0),935},936{937.name = "I2SIN1_BE",938.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC939| SND_SOC_DAIFMT_GATED,940.ops = &mt8189_common_i2s_ops,941.no_pcm = 1,942.capture_only = 1,943.ignore_suspend = 1,944SND_SOC_DAILINK_REG(i2sin1),945},946{947.name = "I2SOUT0_BE",948.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC949| SND_SOC_DAIFMT_GATED,950.ops = &mt8189_common_i2s_ops,951.no_pcm = 1,952.playback_only = 1,953.ignore_suspend = 1,954SND_SOC_DAILINK_REG(i2sout0),955},956{957.name = "I2SOUT1_BE",958.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC959| SND_SOC_DAIFMT_GATED,960.ops = &mt8189_common_i2s_ops,961.no_pcm = 1,962.playback_only = 1,963.ignore_suspend = 1,964SND_SOC_DAILINK_REG(i2sout1),965},966{967.name = "AP_DMIC_BE",968.no_pcm = 1,969.capture_only = 1,970.ignore_suspend = 1,971SND_SOC_DAILINK_REG(ap_dmic),972},973{974.name = "AP_DMIC_CH34_BE",975.no_pcm = 1,976.capture_only = 1,977.ignore_suspend = 1,978SND_SOC_DAILINK_REG(ap_dmic_ch34),979},980{981.name = "TDM_DPTX_BE",982.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC983| SND_SOC_DAIFMT_GATED,984.ops = &mt8189_dptx_ops,985.be_hw_params_fixup = mt8189_dptx_hw_params_fixup,986.no_pcm = 1,987.playback_only = 1,988.ignore_suspend = 1,989SND_SOC_DAILINK_REG(tdm_dptx),990},991{992.name = "PCM_0_BE",993.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC994| SND_SOC_DAIFMT_GATED,995.no_pcm = 1,996.ops = &mt8189_pcm_ops,997.playback_only = 1,998.ignore_suspend = 1,999SND_SOC_DAILINK_REG(pcm0),1000},1001};10021003static struct snd_soc_codec_conf mt8189_cs35l41_codec_conf[] = {1004{1005.dlc = COMP_CODEC_CONF(CS35L41_DEV0_NAME),1006.name_prefix = "Right",1007},1008{1009.dlc = COMP_CODEC_CONF(CS35L41_DEV1_NAME),1010.name_prefix = "Left",1011},1012};10131014static int mt8189_nau8825_soc_card_probe(struct mtk_soc_card_data *soc_card_data, bool legacy)1015{1016struct snd_soc_card *card = soc_card_data->card_data->card;1017struct snd_soc_dai_link *dai_link;1018bool init_nau8825 = false;1019bool init_rt5682s = false;1020bool init_rt5650 = false;1021bool init_rt5682i = false;1022bool init_es8326 = false;1023bool init_dumb = false;1024int i;10251026for_each_card_prelinks(card, i, dai_link) {1027if (strcmp(dai_link->name, "TDM_DPTX_BE") == 0) {1028if (dai_link->num_codecs &&1029strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))1030dai_link->init = mt8189_dptx_codec_init;1031} else if (strcmp(dai_link->name, "PCM_0_BE") == 0) {1032if (dai_link->num_codecs &&1033strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))1034dai_link->init = mt8189_hdmi_codec_init;1035} else if (strcmp(dai_link->name, "I2SOUT0_BE") == 0 ||1036strcmp(dai_link->name, "I2SIN0_BE") == 0) {1037if (!strcmp(dai_link->codecs->dai_name, NAU8825_CODEC_DAI)) {1038dai_link->ops = &mt8189_nau8825_ops;1039if (!init_nau8825) {1040dai_link->init = mt8189_headset_codec_init;1041dai_link->exit = mt8189_headset_codec_exit;1042init_nau8825 = true;1043}1044} else if (!strcmp(dai_link->codecs->dai_name, RT5682S_CODEC_DAI)) {1045dai_link->ops = &mt8189_rtxxxx_i2s_ops;1046if (!init_rt5682s) {1047dai_link->init = mt8189_headset_codec_init;1048dai_link->exit = mt8189_headset_codec_exit;1049init_rt5682s = true;1050}1051} else if (!strcmp(dai_link->codecs->dai_name, RT5650_CODEC_DAI)) {1052dai_link->ops = &mt8189_rtxxxx_i2s_ops;1053if (!init_rt5650) {1054dai_link->init = mt8189_headset_codec_init;1055dai_link->exit = mt8189_headset_codec_exit;1056init_rt5650 = true;1057}1058} else if (!strcmp(dai_link->codecs->dai_name, RT5682I_CODEC_DAI)) {1059dai_link->ops = &mt8189_rtxxxx_i2s_ops;1060if (!init_rt5682i) {1061dai_link->init = mt8189_headset_codec_init;1062dai_link->exit = mt8189_headset_codec_exit;1063init_rt5682i = true;1064}1065} else if (!strcmp(dai_link->codecs->dai_name, ES8326_CODEC_DAI)) {1066dai_link->ops = &mt8189_es8326_ops;1067if (!init_es8326) {1068dai_link->init = mt8189_headset_codec_init;1069dai_link->exit = mt8189_headset_codec_exit;1070init_es8326 = true;1071}1072} else {1073if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) {1074if (!init_dumb) {1075dai_link->init = mt8189_dumb_amp_init;1076init_dumb = true;1077}1078}1079}1080} else if (strcmp(dai_link->name, "I2SOUT1_BE") == 0) {1081if (!strcmp(dai_link->codecs->dai_name, CS35L41_CODEC_DAI)) {1082dai_link->ops = &mt8189_cs35l41_i2s_ops;1083card->num_configs = ARRAY_SIZE(mt8189_cs35l41_codec_conf);1084card->codec_conf = mt8189_cs35l41_codec_conf;1085}1086}1087}10881089return 0;1090}10911092static struct snd_soc_card mt8189_nau8825_soc_card = {1093.owner = THIS_MODULE,1094.dai_link = mt8189_nau8825_dai_links,1095.num_links = ARRAY_SIZE(mt8189_nau8825_dai_links),1096.dapm_widgets = mt8189_nau8825_card_widgets,1097.num_dapm_widgets = ARRAY_SIZE(mt8189_nau8825_card_widgets),1098};10991100static const struct mtk_soundcard_pdata mt8189_nau8825_card = {1101.card_name = "mt8189_nau8825",1102.card_data = &(struct mtk_platform_card_data) {1103.card = &mt8189_nau8825_soc_card,1104.num_jacks = MT8189_JACK_MAX,1105.flags = NAU8825_HS_PRESENT1106},1107.sof_priv = NULL,1108.soc_probe = mt8189_nau8825_soc_card_probe,1109};11101111static const struct mtk_soundcard_pdata mt8189_rt5650_card = {1112.card_name = "mt8189_rt5650",1113.card_data = &(struct mtk_platform_card_data) {1114.card = &mt8189_nau8825_soc_card,1115.num_jacks = MT8189_JACK_MAX,1116.flags = RT5650_HS_PRESENT1117},1118.sof_priv = NULL,1119.soc_probe = mt8189_nau8825_soc_card_probe,1120};11211122static const struct mtk_soundcard_pdata mt8189_rt5682s_card = {1123.card_name = "mt8189_rt5682s",1124.card_data = &(struct mtk_platform_card_data) {1125.card = &mt8189_nau8825_soc_card,1126.num_jacks = MT8189_JACK_MAX,1127.flags = RT5682S_HS_PRESENT1128},1129.sof_priv = NULL,1130.soc_probe = mt8189_nau8825_soc_card_probe,1131};11321133static const struct mtk_soundcard_pdata mt8189_rt5682i_card = {1134.card_name = "mt8189_rt5682i",1135.card_data = &(struct mtk_platform_card_data) {1136.card = &mt8189_nau8825_soc_card,1137.num_jacks = MT8189_JACK_MAX,1138.flags = RT5682I_HS_PRESENT1139},1140.sof_priv = NULL,1141.soc_probe = mt8189_nau8825_soc_card_probe,1142};11431144static const struct mtk_soundcard_pdata mt8188_es8326_card = {1145.card_name = "mt8188_es8326",1146.card_data = &(struct mtk_platform_card_data) {1147.card = &mt8189_nau8825_soc_card,1148.num_jacks = MT8189_JACK_MAX,1149.flags = ES8326_HS_PRESENT1150},1151.sof_priv = NULL,1152.soc_probe = mt8189_nau8825_soc_card_probe,1153};11541155static const struct of_device_id mt8189_nau8825_dt_match[] = {1156{.compatible = "mediatek,mt8189-nau8825", .data = &mt8189_nau8825_card,},1157{.compatible = "mediatek,mt8189-rt5650", .data = &mt8189_rt5650_card,},1158{.compatible = "mediatek,mt8189-rt5682s", .data = &mt8189_rt5682s_card,},1159{.compatible = "mediatek,mt8189-rt5682i", .data = &mt8189_rt5682i_card,},1160{.compatible = "mediatek,mt8189-es8326", .data = &mt8188_es8326_card,},1161{}1162};1163MODULE_DEVICE_TABLE(of, mt8189_nau8825_dt_match);11641165static struct platform_driver mt8189_nau8825_driver = {1166.driver = {1167.name = "mt8189-nau8825",1168.of_match_table = mt8189_nau8825_dt_match,1169.pm = &snd_soc_pm_ops,1170},1171.probe = mtk_soundcard_common_probe,1172};1173module_platform_driver(mt8189_nau8825_driver);11741175/* Module information */1176MODULE_DESCRIPTION("MT8189 NAU8825 ALSA SoC machine driver");1177MODULE_AUTHOR("Darren Ye <[email protected]>");1178MODULE_AUTHOR("Cyril Chao <[email protected]>");1179MODULE_LICENSE("GPL");118011811182