Path: blob/master/sound/soc/mediatek/mt8189/mt8189-nau8825.c
38237 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;344int ret;345346ret = snd_soc_dapm_new_controls(&card->dapm, mt8189_dumb_spk_widgets,347ARRAY_SIZE(mt8189_dumb_spk_widgets));348if (ret) {349dev_err(rtd->dev, "unable to add Dumb Speaker dapm, ret %d\n", ret);350return ret;351}352353ret = snd_soc_add_card_controls(card, mt8189_dumb_spk_controls,354ARRAY_SIZE(mt8189_dumb_spk_controls));355if (ret) {356dev_err(rtd->dev, "unable to add Dumb card controls, ret %d\n", ret);357return ret;358}359360return 0;361}362363static int mt8189_dptx_codec_init(struct snd_soc_pcm_runtime *rtd)364{365struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card);366struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8189_JACK_DP];367struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;368int ret;369370ret = snd_soc_card_jack_new_pins(rtd->card, "DP Jack", SND_JACK_LINEOUT,371jack, mt8189_dp_jack_pins,372ARRAY_SIZE(mt8189_dp_jack_pins));373if (ret) {374dev_err(rtd->dev, "%s, new jack failed: %d\n", __func__, ret);375return ret;376}377378ret = snd_soc_component_set_jack(component, jack, NULL);379if (ret) {380dev_err(rtd->dev, "%s, set jack failed on %s (ret=%d)\n",381__func__, component->name, ret);382return ret;383}384385return 0;386}387388static int mt8189_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd)389{390struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card);391struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8189_JACK_HDMI];392struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;393int ret;394395ret = snd_soc_card_jack_new_pins(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,396jack, mt8189_hdmi_jack_pins,397ARRAY_SIZE(mt8189_hdmi_jack_pins));398if (ret) {399dev_err(rtd->dev, "%s, new jack failed: %d\n", __func__, ret);400return ret;401}402403ret = snd_soc_component_set_jack(component, jack, NULL);404if (ret) {405dev_err(rtd->dev, "%s, set jack failed on %s (ret=%d)\n",406__func__, component->name, ret);407return ret;408}409410return 0;411}412413static int mt8189_headset_codec_init(struct snd_soc_pcm_runtime *rtd)414{415struct snd_soc_card *card = rtd->card;416struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);417struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8189_JACK_HEADSET];418struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;419struct mtk_platform_card_data *card_data = soc_card_data->card_data;420int ret;421int type;422423ret = snd_soc_dapm_new_controls(&card->dapm, mt8189_headset_widgets,424ARRAY_SIZE(mt8189_headset_widgets));425if (ret) {426dev_err(rtd->dev, "unable to add nau8825 card widget, ret %d\n", ret);427return ret;428}429430ret = snd_soc_add_card_controls(card, mt8189_headset_controls,431ARRAY_SIZE(mt8189_headset_controls));432if (ret) {433dev_err(rtd->dev, "unable to add nau8825 card controls, ret %d\n", ret);434return ret;435}436437ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",438SND_JACK_HEADSET | SND_JACK_BTN_0 |439SND_JACK_BTN_1 | SND_JACK_BTN_2 |440SND_JACK_BTN_3,441jack,442mt8189_headset_jack_pins,443ARRAY_SIZE(mt8189_headset_jack_pins));444if (ret) {445dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);446return ret;447}448449if (card_data->flags & ES8326_HS_PRESENT) {450snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);451snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP);452snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);453snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);454} else {455snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);456snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);457snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);458snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);459}460461type = SND_JACK_HEADSET | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | SND_JACK_BTN_3;462ret = snd_soc_component_set_jack(component, jack, (void *)&type);463if (ret) {464dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);465return ret;466}467468return 0;469};470471static void mt8189_headset_codec_exit(struct snd_soc_pcm_runtime *rtd)472{473struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;474475snd_soc_component_set_jack(component, NULL, NULL);476}477478/* FE */479SND_SOC_DAILINK_DEFS(playback0,480DAILINK_COMP_ARRAY(COMP_CPU("DL0")),481DAILINK_COMP_ARRAY(COMP_DUMMY()),482DAILINK_COMP_ARRAY(COMP_EMPTY()));483SND_SOC_DAILINK_DEFS(playback1,484DAILINK_COMP_ARRAY(COMP_CPU("DL1")),485DAILINK_COMP_ARRAY(COMP_DUMMY()),486DAILINK_COMP_ARRAY(COMP_EMPTY()));487SND_SOC_DAILINK_DEFS(playback2,488DAILINK_COMP_ARRAY(COMP_CPU("DL2")),489DAILINK_COMP_ARRAY(COMP_DUMMY()),490DAILINK_COMP_ARRAY(COMP_EMPTY()));491SND_SOC_DAILINK_DEFS(playback3,492DAILINK_COMP_ARRAY(COMP_CPU("DL3")),493DAILINK_COMP_ARRAY(COMP_DUMMY()),494DAILINK_COMP_ARRAY(COMP_EMPTY()));495SND_SOC_DAILINK_DEFS(playback4,496DAILINK_COMP_ARRAY(COMP_CPU("DL4")),497DAILINK_COMP_ARRAY(COMP_DUMMY()),498DAILINK_COMP_ARRAY(COMP_EMPTY()));499SND_SOC_DAILINK_DEFS(playback5,500DAILINK_COMP_ARRAY(COMP_CPU("DL5")),501DAILINK_COMP_ARRAY(COMP_DUMMY()),502DAILINK_COMP_ARRAY(COMP_EMPTY()));503SND_SOC_DAILINK_DEFS(playback6,504DAILINK_COMP_ARRAY(COMP_CPU("DL6")),505DAILINK_COMP_ARRAY(COMP_DUMMY()),506DAILINK_COMP_ARRAY(COMP_EMPTY()));507SND_SOC_DAILINK_DEFS(playback7,508DAILINK_COMP_ARRAY(COMP_CPU("DL7")),509DAILINK_COMP_ARRAY(COMP_DUMMY()),510DAILINK_COMP_ARRAY(COMP_EMPTY()));511SND_SOC_DAILINK_DEFS(playback8,512DAILINK_COMP_ARRAY(COMP_CPU("DL8")),513DAILINK_COMP_ARRAY(COMP_DUMMY()),514DAILINK_COMP_ARRAY(COMP_EMPTY()));515SND_SOC_DAILINK_DEFS(playback23,516DAILINK_COMP_ARRAY(COMP_CPU("DL23")),517DAILINK_COMP_ARRAY(COMP_DUMMY()),518DAILINK_COMP_ARRAY(COMP_EMPTY()));519SND_SOC_DAILINK_DEFS(playback24,520DAILINK_COMP_ARRAY(COMP_CPU("DL24")),521DAILINK_COMP_ARRAY(COMP_DUMMY()),522DAILINK_COMP_ARRAY(COMP_EMPTY()));523SND_SOC_DAILINK_DEFS(playback25,524DAILINK_COMP_ARRAY(COMP_CPU("DL25")),525DAILINK_COMP_ARRAY(COMP_DUMMY()),526DAILINK_COMP_ARRAY(COMP_EMPTY()));527SND_SOC_DAILINK_DEFS(playback_24ch,528DAILINK_COMP_ARRAY(COMP_CPU("DL_24CH")),529DAILINK_COMP_ARRAY(COMP_DUMMY()),530DAILINK_COMP_ARRAY(COMP_EMPTY()));531SND_SOC_DAILINK_DEFS(capture0,532DAILINK_COMP_ARRAY(COMP_CPU("UL0")),533DAILINK_COMP_ARRAY(COMP_DUMMY()),534DAILINK_COMP_ARRAY(COMP_EMPTY()));535SND_SOC_DAILINK_DEFS(capture1,536DAILINK_COMP_ARRAY(COMP_CPU("UL1")),537DAILINK_COMP_ARRAY(COMP_DUMMY()),538DAILINK_COMP_ARRAY(COMP_EMPTY()));539SND_SOC_DAILINK_DEFS(capture2,540DAILINK_COMP_ARRAY(COMP_CPU("UL2")),541DAILINK_COMP_ARRAY(COMP_DUMMY()),542DAILINK_COMP_ARRAY(COMP_EMPTY()));543SND_SOC_DAILINK_DEFS(capture3,544DAILINK_COMP_ARRAY(COMP_CPU("UL3")),545DAILINK_COMP_ARRAY(COMP_DUMMY()),546DAILINK_COMP_ARRAY(COMP_EMPTY()));547SND_SOC_DAILINK_DEFS(capture4,548DAILINK_COMP_ARRAY(COMP_CPU("UL4")),549DAILINK_COMP_ARRAY(COMP_DUMMY()),550DAILINK_COMP_ARRAY(COMP_EMPTY()));551SND_SOC_DAILINK_DEFS(capture5,552DAILINK_COMP_ARRAY(COMP_CPU("UL5")),553DAILINK_COMP_ARRAY(COMP_DUMMY()),554DAILINK_COMP_ARRAY(COMP_EMPTY()));555SND_SOC_DAILINK_DEFS(capture6,556DAILINK_COMP_ARRAY(COMP_CPU("UL6")),557DAILINK_COMP_ARRAY(COMP_DUMMY()),558DAILINK_COMP_ARRAY(COMP_EMPTY()));559SND_SOC_DAILINK_DEFS(capture7,560DAILINK_COMP_ARRAY(COMP_CPU("UL7")),561DAILINK_COMP_ARRAY(COMP_DUMMY()),562DAILINK_COMP_ARRAY(COMP_EMPTY()));563SND_SOC_DAILINK_DEFS(capture8,564DAILINK_COMP_ARRAY(COMP_CPU("UL8")),565DAILINK_COMP_ARRAY(COMP_DUMMY()),566DAILINK_COMP_ARRAY(COMP_EMPTY()));567SND_SOC_DAILINK_DEFS(capture9,568DAILINK_COMP_ARRAY(COMP_CPU("UL9")),569DAILINK_COMP_ARRAY(COMP_DUMMY()),570DAILINK_COMP_ARRAY(COMP_EMPTY()));571SND_SOC_DAILINK_DEFS(capture10,572DAILINK_COMP_ARRAY(COMP_CPU("UL10")),573DAILINK_COMP_ARRAY(COMP_DUMMY()),574DAILINK_COMP_ARRAY(COMP_EMPTY()));575SND_SOC_DAILINK_DEFS(capture24,576DAILINK_COMP_ARRAY(COMP_CPU("UL24")),577DAILINK_COMP_ARRAY(COMP_DUMMY()),578DAILINK_COMP_ARRAY(COMP_EMPTY()));579SND_SOC_DAILINK_DEFS(capture25,580DAILINK_COMP_ARRAY(COMP_CPU("UL25")),581DAILINK_COMP_ARRAY(COMP_DUMMY()),582DAILINK_COMP_ARRAY(COMP_EMPTY()));583SND_SOC_DAILINK_DEFS(capture_cm0,584DAILINK_COMP_ARRAY(COMP_CPU("UL_CM0")),585DAILINK_COMP_ARRAY(COMP_DUMMY()),586DAILINK_COMP_ARRAY(COMP_EMPTY()));587SND_SOC_DAILINK_DEFS(capture_cm1,588DAILINK_COMP_ARRAY(COMP_CPU("UL_CM1")),589DAILINK_COMP_ARRAY(COMP_DUMMY()),590DAILINK_COMP_ARRAY(COMP_EMPTY()));591SND_SOC_DAILINK_DEFS(capture_etdm_in0,592DAILINK_COMP_ARRAY(COMP_CPU("UL_ETDM_IN0")),593DAILINK_COMP_ARRAY(COMP_DUMMY()),594DAILINK_COMP_ARRAY(COMP_EMPTY()));595SND_SOC_DAILINK_DEFS(capture_etdm_in1,596DAILINK_COMP_ARRAY(COMP_CPU("UL_ETDM_IN1")),597DAILINK_COMP_ARRAY(COMP_DUMMY()),598DAILINK_COMP_ARRAY(COMP_EMPTY()));599SND_SOC_DAILINK_DEFS(playback_hdmi,600DAILINK_COMP_ARRAY(COMP_CPU("HDMI")),601DAILINK_COMP_ARRAY(COMP_DUMMY()),602DAILINK_COMP_ARRAY(COMP_EMPTY()));603/* BE */604SND_SOC_DAILINK_DEFS(ap_dmic,605DAILINK_COMP_ARRAY(COMP_CPU("AP_DMIC")),606DAILINK_COMP_ARRAY(COMP_DUMMY()),607DAILINK_COMP_ARRAY(COMP_EMPTY()));608SND_SOC_DAILINK_DEFS(ap_dmic_ch34,609DAILINK_COMP_ARRAY(COMP_CPU("AP_DMIC_CH34")),610DAILINK_COMP_ARRAY(COMP_DUMMY()),611DAILINK_COMP_ARRAY(COMP_EMPTY()));612SND_SOC_DAILINK_DEFS(i2sin0,613DAILINK_COMP_ARRAY(COMP_CPU("I2SIN0")),614DAILINK_COMP_ARRAY(COMP_DUMMY()),615DAILINK_COMP_ARRAY(COMP_EMPTY()));616SND_SOC_DAILINK_DEFS(i2sin1,617DAILINK_COMP_ARRAY(COMP_CPU("I2SIN1")),618DAILINK_COMP_ARRAY(COMP_DUMMY()),619DAILINK_COMP_ARRAY(COMP_EMPTY()));620SND_SOC_DAILINK_DEFS(i2sout0,621DAILINK_COMP_ARRAY(COMP_CPU("I2SOUT0")),622DAILINK_COMP_ARRAY(COMP_DUMMY()),623DAILINK_COMP_ARRAY(COMP_EMPTY()));624SND_SOC_DAILINK_DEFS(i2sout1,625DAILINK_COMP_ARRAY(COMP_CPU("I2SOUT1")),626DAILINK_COMP_ARRAY(COMP_DUMMY()),627DAILINK_COMP_ARRAY(COMP_EMPTY()));628SND_SOC_DAILINK_DEFS(pcm0,629DAILINK_COMP_ARRAY(COMP_CPU("PCM 0")),630DAILINK_COMP_ARRAY(COMP_DUMMY()),631DAILINK_COMP_ARRAY(COMP_EMPTY()));632SND_SOC_DAILINK_DEFS(tdm_dptx,633DAILINK_COMP_ARRAY(COMP_CPU("TDM_DPTX")),634DAILINK_COMP_ARRAY(COMP_DUMMY()),635DAILINK_COMP_ARRAY(COMP_EMPTY()));636637static struct snd_soc_dai_link mt8189_nau8825_dai_links[] = {638/* Front End DAI links */639{640.name = "DL0_FE",641.stream_name = "DL0 Playback",642.trigger = {SND_SOC_DPCM_TRIGGER_PRE,643SND_SOC_DPCM_TRIGGER_PRE},644.dynamic = 1,645.playback_only = 1,646.dpcm_merged_format = 1,647SND_SOC_DAILINK_REG(playback0),648},649{650.name = "DL1_FE",651.stream_name = "DL1 Playback",652.trigger = {SND_SOC_DPCM_TRIGGER_PRE,653SND_SOC_DPCM_TRIGGER_PRE},654.dynamic = 1,655.playback_only = 1,656.dpcm_merged_format = 1,657SND_SOC_DAILINK_REG(playback1),658},659{660.name = "UL0_FE",661.stream_name = "UL0 Capture",662.trigger = {SND_SOC_DPCM_TRIGGER_PRE,663SND_SOC_DPCM_TRIGGER_PRE},664.dynamic = 1,665.capture_only = 1,666.dpcm_merged_format = 1,667SND_SOC_DAILINK_REG(capture0),668},669{670.name = "UL1_FE",671.stream_name = "UL1 Capture",672.trigger = {SND_SOC_DPCM_TRIGGER_PRE,673SND_SOC_DPCM_TRIGGER_PRE},674.dynamic = 1,675.capture_only = 1,676.dpcm_merged_format = 1,677SND_SOC_DAILINK_REG(capture1),678},679{680.name = "UL2_FE",681.stream_name = "UL2 Capture",682.trigger = {SND_SOC_DPCM_TRIGGER_PRE,683SND_SOC_DPCM_TRIGGER_PRE},684.dynamic = 1,685.capture_only = 1,686.dpcm_merged_format = 1,687SND_SOC_DAILINK_REG(capture2),688},689{690.name = "HDMI_FE",691.stream_name = "HDMI Playback",692.trigger = {SND_SOC_DPCM_TRIGGER_PRE,693SND_SOC_DPCM_TRIGGER_PRE},694.dynamic = 1,695.playback_only = 1,696SND_SOC_DAILINK_REG(playback_hdmi),697},698{699.name = "DL2_FE",700.stream_name = "DL2 Playback",701.trigger = {SND_SOC_DPCM_TRIGGER_PRE,702SND_SOC_DPCM_TRIGGER_PRE},703.dynamic = 1,704.playback_only = 1,705SND_SOC_DAILINK_REG(playback2),706},707{708.name = "DL3_FE",709.stream_name = "DL3 Playback",710.trigger = {SND_SOC_DPCM_TRIGGER_PRE,711SND_SOC_DPCM_TRIGGER_PRE},712.dynamic = 1,713.playback_only = 1,714SND_SOC_DAILINK_REG(playback3),715},716{717.name = "DL4_FE",718.stream_name = "DL4 Playback",719.trigger = {SND_SOC_DPCM_TRIGGER_PRE,720SND_SOC_DPCM_TRIGGER_PRE},721.dynamic = 1,722.playback_only = 1,723SND_SOC_DAILINK_REG(playback4),724},725{726.name = "DL5_FE",727.stream_name = "DL5 Playback",728.trigger = {SND_SOC_DPCM_TRIGGER_PRE,729SND_SOC_DPCM_TRIGGER_PRE},730.dynamic = 1,731.playback_only = 1,732SND_SOC_DAILINK_REG(playback5),733},734{735.name = "DL6_FE",736.stream_name = "DL6 Playback",737.trigger = {SND_SOC_DPCM_TRIGGER_PRE,738SND_SOC_DPCM_TRIGGER_PRE},739.dynamic = 1,740.playback_only = 1,741SND_SOC_DAILINK_REG(playback6),742},743{744.name = "DL7_FE",745.stream_name = "DL7 Playback",746.trigger = {SND_SOC_DPCM_TRIGGER_PRE,747SND_SOC_DPCM_TRIGGER_PRE},748.dynamic = 1,749.playback_only = 1,750SND_SOC_DAILINK_REG(playback7),751},752{753.name = "DL8 FE",754.stream_name = "DL8 Playback",755.trigger = {SND_SOC_DPCM_TRIGGER_PRE,756SND_SOC_DPCM_TRIGGER_PRE},757.dynamic = 1,758.playback_only = 1,759SND_SOC_DAILINK_REG(playback8),760},761{762.name = "DL23 FE",763.stream_name = "DL23 Playback",764.trigger = {SND_SOC_DPCM_TRIGGER_PRE,765SND_SOC_DPCM_TRIGGER_PRE},766.dynamic = 1,767.playback_only = 1,768SND_SOC_DAILINK_REG(playback23),769},770{771.name = "DL24 FE",772.stream_name = "DL24 Playback",773.trigger = {SND_SOC_DPCM_TRIGGER_PRE,774SND_SOC_DPCM_TRIGGER_PRE},775.dynamic = 1,776.playback_only = 1,777SND_SOC_DAILINK_REG(playback24),778},779{780.name = "DL25 FE",781.stream_name = "DL25 Playback",782.trigger = {SND_SOC_DPCM_TRIGGER_PRE,783SND_SOC_DPCM_TRIGGER_PRE},784.dynamic = 1,785.playback_only = 1,786SND_SOC_DAILINK_REG(playback25),787},788{789.name = "DL_24CH_FE",790.stream_name = "DL_24CH Playback",791.trigger = {SND_SOC_DPCM_TRIGGER_PRE,792SND_SOC_DPCM_TRIGGER_PRE},793.dynamic = 1,794.playback_only = 1,795SND_SOC_DAILINK_REG(playback_24ch),796},797{798.name = "UL9_FE",799.stream_name = "UL9 Capture",800.trigger = {SND_SOC_DPCM_TRIGGER_PRE,801SND_SOC_DPCM_TRIGGER_PRE},802.dynamic = 1,803.capture_only = 1,804SND_SOC_DAILINK_REG(capture9),805},806{807.name = "UL3_FE",808.stream_name = "UL3 Capture",809.trigger = {SND_SOC_DPCM_TRIGGER_PRE,810SND_SOC_DPCM_TRIGGER_PRE},811.dynamic = 1,812.capture_only = 1,813SND_SOC_DAILINK_REG(capture3),814},815{816.name = "UL7_FE",817.stream_name = "UL7 Capture",818.trigger = {SND_SOC_DPCM_TRIGGER_PRE,819SND_SOC_DPCM_TRIGGER_PRE},820.dynamic = 1,821.capture_only = 1,822SND_SOC_DAILINK_REG(capture7),823},824{825.name = "UL4_FE",826.stream_name = "UL4 Capture",827.trigger = {SND_SOC_DPCM_TRIGGER_PRE,828SND_SOC_DPCM_TRIGGER_PRE},829.dynamic = 1,830.capture_only = 1,831SND_SOC_DAILINK_REG(capture4),832},833{834.name = "UL5_FE",835.stream_name = "UL5 Capture",836.trigger = {SND_SOC_DPCM_TRIGGER_PRE,837SND_SOC_DPCM_TRIGGER_PRE},838.dynamic = 1,839.capture_only = 1,840SND_SOC_DAILINK_REG(capture5),841},842{843.name = "UL_CM0_FE",844.stream_name = "UL_CM0 Capture",845.trigger = {SND_SOC_DPCM_TRIGGER_PRE,846SND_SOC_DPCM_TRIGGER_PRE},847.dynamic = 1,848.capture_only = 1,849SND_SOC_DAILINK_REG(capture_cm0),850},851{852.name = "UL_CM1_FE",853.stream_name = "UL_CM1 Capture",854.trigger = {SND_SOC_DPCM_TRIGGER_PRE,855SND_SOC_DPCM_TRIGGER_PRE},856.dynamic = 1,857.capture_only = 1,858SND_SOC_DAILINK_REG(capture_cm1),859},860{861.name = "UL10_FE",862.stream_name = "UL10 Capture",863.trigger = {SND_SOC_DPCM_TRIGGER_PRE,864SND_SOC_DPCM_TRIGGER_PRE},865.dynamic = 1,866.capture_only = 1,867SND_SOC_DAILINK_REG(capture10),868},869{870.name = "UL6_FE",871.stream_name = "UL6 Capture",872.trigger = {SND_SOC_DPCM_TRIGGER_PRE,873SND_SOC_DPCM_TRIGGER_PRE},874.dynamic = 1,875.capture_only = 1,876SND_SOC_DAILINK_REG(capture6),877},878{879.name = "UL25_FE",880.stream_name = "UL25 Capture",881.trigger = {SND_SOC_DPCM_TRIGGER_PRE,882SND_SOC_DPCM_TRIGGER_PRE},883.dynamic = 1,884.capture_only = 1,885SND_SOC_DAILINK_REG(capture25),886},887{888.name = "UL8_FE",889.stream_name = "UL8 Capture_Mono_1",890.trigger = {SND_SOC_DPCM_TRIGGER_PRE,891SND_SOC_DPCM_TRIGGER_PRE},892.dynamic = 1,893.capture_only = 1,894SND_SOC_DAILINK_REG(capture8),895},896{897.name = "UL24_FE",898.stream_name = "UL24 Capture_Mono_2",899.trigger = {SND_SOC_DPCM_TRIGGER_PRE,900SND_SOC_DPCM_TRIGGER_PRE},901.dynamic = 1,902.capture_only = 1,903SND_SOC_DAILINK_REG(capture24),904},905{906.name = "UL_ETDM_In0_FE",907.stream_name = "UL_ETDM_In0 Capture",908.trigger = {SND_SOC_DPCM_TRIGGER_PRE,909SND_SOC_DPCM_TRIGGER_PRE},910.dynamic = 1,911.capture_only = 1,912SND_SOC_DAILINK_REG(capture_etdm_in0),913},914{915.name = "UL_ETDM_In1_FE",916.stream_name = "UL_ETDM_In1 Capture",917.trigger = {SND_SOC_DPCM_TRIGGER_PRE,918SND_SOC_DPCM_TRIGGER_PRE},919.dynamic = 1,920.capture_only = 1,921SND_SOC_DAILINK_REG(capture_etdm_in1),922},923/* Back End DAI links */924{925.name = "I2SIN0_BE",926.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC927| SND_SOC_DAIFMT_GATED,928.ops = &mt8189_common_i2s_ops,929.no_pcm = 1,930.capture_only = 1,931.ignore_suspend = 1,932SND_SOC_DAILINK_REG(i2sin0),933},934{935.name = "I2SIN1_BE",936.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC937| SND_SOC_DAIFMT_GATED,938.ops = &mt8189_common_i2s_ops,939.no_pcm = 1,940.capture_only = 1,941.ignore_suspend = 1,942SND_SOC_DAILINK_REG(i2sin1),943},944{945.name = "I2SOUT0_BE",946.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC947| SND_SOC_DAIFMT_GATED,948.ops = &mt8189_common_i2s_ops,949.no_pcm = 1,950.playback_only = 1,951.ignore_suspend = 1,952SND_SOC_DAILINK_REG(i2sout0),953},954{955.name = "I2SOUT1_BE",956.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC957| SND_SOC_DAIFMT_GATED,958.ops = &mt8189_common_i2s_ops,959.no_pcm = 1,960.playback_only = 1,961.ignore_suspend = 1,962SND_SOC_DAILINK_REG(i2sout1),963},964{965.name = "AP_DMIC_BE",966.no_pcm = 1,967.capture_only = 1,968.ignore_suspend = 1,969SND_SOC_DAILINK_REG(ap_dmic),970},971{972.name = "AP_DMIC_CH34_BE",973.no_pcm = 1,974.capture_only = 1,975.ignore_suspend = 1,976SND_SOC_DAILINK_REG(ap_dmic_ch34),977},978{979.name = "TDM_DPTX_BE",980.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC981| SND_SOC_DAIFMT_GATED,982.ops = &mt8189_dptx_ops,983.be_hw_params_fixup = mt8189_dptx_hw_params_fixup,984.no_pcm = 1,985.playback_only = 1,986.ignore_suspend = 1,987SND_SOC_DAILINK_REG(tdm_dptx),988},989{990.name = "PCM_0_BE",991.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBC_CFC992| SND_SOC_DAIFMT_GATED,993.no_pcm = 1,994.ops = &mt8189_pcm_ops,995.playback_only = 1,996.ignore_suspend = 1,997SND_SOC_DAILINK_REG(pcm0),998},999};10001001static struct snd_soc_codec_conf mt8189_cs35l41_codec_conf[] = {1002{1003.dlc = COMP_CODEC_CONF(CS35L41_DEV0_NAME),1004.name_prefix = "Right",1005},1006{1007.dlc = COMP_CODEC_CONF(CS35L41_DEV1_NAME),1008.name_prefix = "Left",1009},1010};10111012static int mt8189_nau8825_soc_card_probe(struct mtk_soc_card_data *soc_card_data, bool legacy)1013{1014struct snd_soc_card *card = soc_card_data->card_data->card;1015struct snd_soc_dai_link *dai_link;1016bool init_nau8825 = false;1017bool init_rt5682s = false;1018bool init_rt5650 = false;1019bool init_rt5682i = false;1020bool init_es8326 = false;1021bool init_dumb = false;1022int i;10231024for_each_card_prelinks(card, i, dai_link) {1025if (strcmp(dai_link->name, "TDM_DPTX_BE") == 0) {1026if (dai_link->num_codecs &&1027strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))1028dai_link->init = mt8189_dptx_codec_init;1029} else if (strcmp(dai_link->name, "PCM_0_BE") == 0) {1030if (dai_link->num_codecs &&1031strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai"))1032dai_link->init = mt8189_hdmi_codec_init;1033} else if (strcmp(dai_link->name, "I2SOUT0_BE") == 0 ||1034strcmp(dai_link->name, "I2SIN0_BE") == 0) {1035if (!strcmp(dai_link->codecs->dai_name, NAU8825_CODEC_DAI)) {1036dai_link->ops = &mt8189_nau8825_ops;1037if (!init_nau8825) {1038dai_link->init = mt8189_headset_codec_init;1039dai_link->exit = mt8189_headset_codec_exit;1040init_nau8825 = true;1041}1042} else if (!strcmp(dai_link->codecs->dai_name, RT5682S_CODEC_DAI)) {1043dai_link->ops = &mt8189_rtxxxx_i2s_ops;1044if (!init_rt5682s) {1045dai_link->init = mt8189_headset_codec_init;1046dai_link->exit = mt8189_headset_codec_exit;1047init_rt5682s = true;1048}1049} else if (!strcmp(dai_link->codecs->dai_name, RT5650_CODEC_DAI)) {1050dai_link->ops = &mt8189_rtxxxx_i2s_ops;1051if (!init_rt5650) {1052dai_link->init = mt8189_headset_codec_init;1053dai_link->exit = mt8189_headset_codec_exit;1054init_rt5650 = true;1055}1056} else if (!strcmp(dai_link->codecs->dai_name, RT5682I_CODEC_DAI)) {1057dai_link->ops = &mt8189_rtxxxx_i2s_ops;1058if (!init_rt5682i) {1059dai_link->init = mt8189_headset_codec_init;1060dai_link->exit = mt8189_headset_codec_exit;1061init_rt5682i = true;1062}1063} else if (!strcmp(dai_link->codecs->dai_name, ES8326_CODEC_DAI)) {1064dai_link->ops = &mt8189_es8326_ops;1065if (!init_es8326) {1066dai_link->init = mt8189_headset_codec_init;1067dai_link->exit = mt8189_headset_codec_exit;1068init_es8326 = true;1069}1070} else {1071if (strcmp(dai_link->codecs->dai_name, "snd-soc-dummy-dai")) {1072if (!init_dumb) {1073dai_link->init = mt8189_dumb_amp_init;1074init_dumb = true;1075}1076}1077}1078} else if (strcmp(dai_link->name, "I2SOUT1_BE") == 0) {1079if (!strcmp(dai_link->codecs->dai_name, CS35L41_CODEC_DAI)) {1080dai_link->ops = &mt8189_cs35l41_i2s_ops;1081card->num_configs = ARRAY_SIZE(mt8189_cs35l41_codec_conf);1082card->codec_conf = mt8189_cs35l41_codec_conf;1083}1084}1085}10861087return 0;1088}10891090static struct snd_soc_card mt8189_nau8825_soc_card = {1091.owner = THIS_MODULE,1092.dai_link = mt8189_nau8825_dai_links,1093.num_links = ARRAY_SIZE(mt8189_nau8825_dai_links),1094.dapm_widgets = mt8189_nau8825_card_widgets,1095.num_dapm_widgets = ARRAY_SIZE(mt8189_nau8825_card_widgets),1096};10971098static const struct mtk_soundcard_pdata mt8189_nau8825_card = {1099.card_name = "mt8189_nau8825",1100.card_data = &(struct mtk_platform_card_data) {1101.card = &mt8189_nau8825_soc_card,1102.num_jacks = MT8189_JACK_MAX,1103.flags = NAU8825_HS_PRESENT1104},1105.sof_priv = NULL,1106.soc_probe = mt8189_nau8825_soc_card_probe,1107};11081109static const struct mtk_soundcard_pdata mt8189_rt5650_card = {1110.card_name = "mt8189_rt5650",1111.card_data = &(struct mtk_platform_card_data) {1112.card = &mt8189_nau8825_soc_card,1113.num_jacks = MT8189_JACK_MAX,1114.flags = RT5650_HS_PRESENT1115},1116.sof_priv = NULL,1117.soc_probe = mt8189_nau8825_soc_card_probe,1118};11191120static const struct mtk_soundcard_pdata mt8189_rt5682s_card = {1121.card_name = "mt8189_rt5682s",1122.card_data = &(struct mtk_platform_card_data) {1123.card = &mt8189_nau8825_soc_card,1124.num_jacks = MT8189_JACK_MAX,1125.flags = RT5682S_HS_PRESENT1126},1127.sof_priv = NULL,1128.soc_probe = mt8189_nau8825_soc_card_probe,1129};11301131static const struct mtk_soundcard_pdata mt8189_rt5682i_card = {1132.card_name = "mt8189_rt5682i",1133.card_data = &(struct mtk_platform_card_data) {1134.card = &mt8189_nau8825_soc_card,1135.num_jacks = MT8189_JACK_MAX,1136.flags = RT5682I_HS_PRESENT1137},1138.sof_priv = NULL,1139.soc_probe = mt8189_nau8825_soc_card_probe,1140};11411142static const struct mtk_soundcard_pdata mt8188_es8326_card = {1143.card_name = "mt8188_es8326",1144.card_data = &(struct mtk_platform_card_data) {1145.card = &mt8189_nau8825_soc_card,1146.num_jacks = MT8189_JACK_MAX,1147.flags = ES8326_HS_PRESENT1148},1149.sof_priv = NULL,1150.soc_probe = mt8189_nau8825_soc_card_probe,1151};11521153static const struct of_device_id mt8189_nau8825_dt_match[] = {1154{.compatible = "mediatek,mt8189-nau8825", .data = &mt8189_nau8825_card,},1155{.compatible = "mediatek,mt8189-rt5650", .data = &mt8189_rt5650_card,},1156{.compatible = "mediatek,mt8189-rt5682s", .data = &mt8189_rt5682s_card,},1157{.compatible = "mediatek,mt8189-rt5682i", .data = &mt8189_rt5682i_card,},1158{.compatible = "mediatek,mt8189-es8326", .data = &mt8188_es8326_card,},1159{}1160};1161MODULE_DEVICE_TABLE(of, mt8189_nau8825_dt_match);11621163static struct platform_driver mt8189_nau8825_driver = {1164.driver = {1165.name = "mt8189-nau8825",1166.of_match_table = mt8189_nau8825_dt_match,1167.pm = &snd_soc_pm_ops,1168},1169.probe = mtk_soundcard_common_probe,1170};1171module_platform_driver(mt8189_nau8825_driver);11721173/* Module information */1174MODULE_DESCRIPTION("MT8189 NAU8825 ALSA SoC machine driver");1175MODULE_AUTHOR("Darren Ye <[email protected]>");1176MODULE_AUTHOR("Cyril Chao <[email protected]>");1177MODULE_LICENSE("GPL");117811791180