Path: blob/master/sound/soc/mediatek/mt8188/mt8188-mt6359.c
54321 views
// SPDX-License-Identifier: GPL-2.01/*2* mt8188-mt6359.c -- MT8188-MT6359 ALSA SoC machine driver3*4* Copyright (c) 2022 MediaTek Inc.5* Author: Trevor Wu <[email protected]>6*/78#include <linux/bitfield.h>9#include <linux/input.h>10#include <linux/module.h>11#include <linux/of.h>12#include <linux/pm_runtime.h>13#include <sound/jack.h>14#include <sound/pcm_params.h>15#include <sound/soc.h>16#include "mt8188-afe-common.h"17#include "../../codecs/nau8825.h"18#include "../../codecs/mt6359.h"19#include "../../codecs/mt6359-accdet.h"20#include "../../codecs/rt5682.h"21#include "../common/mtk-afe-platform-driver.h"22#include "../common/mtk-soundcard-driver.h"23#include "../common/mtk-dsp-sof-common.h"24#include "../common/mtk-soc-card.h"2526#define CKSYS_AUD_TOP_CFG 0x032c27#define RG_TEST_ON BIT(0)28#define RG_TEST_TYPE BIT(2)29#define CKSYS_AUD_TOP_MON 0x033030#define TEST_MISO_COUNT_1 GENMASK(3, 0)31#define TEST_MISO_COUNT_2 GENMASK(7, 4)32#define TEST_MISO_DONE_1 BIT(28)33#define TEST_MISO_DONE_2 BIT(29)3435#define NAU8825_HS_PRESENT BIT(0)36#define RT5682S_HS_PRESENT BIT(1)37#define ES8326_HS_PRESENT BIT(2)38#define MAX98390_TWO_AMP BIT(3)39/*40* Maxim MAX9839041*/42#define MAX98390_CODEC_DAI "max98390-aif1"43#define MAX98390_DEV0_NAME "max98390.0-0038" /* rear right */44#define MAX98390_DEV1_NAME "max98390.0-0039" /* rear left */45#define MAX98390_DEV2_NAME "max98390.0-003a" /* front right */46#define MAX98390_DEV3_NAME "max98390.0-003b" /* front left */4748/*49* Nau88l2550*/51#define NAU8825_CODEC_DAI "nau8825-hifi"5253/*54* ES832655*/56#define ES8326_CODEC_DAI "ES8326 HiFi"5758#define SOF_DMA_DL2 "SOF_DMA_DL2"59#define SOF_DMA_DL3 "SOF_DMA_DL3"60#define SOF_DMA_UL4 "SOF_DMA_UL4"61#define SOF_DMA_UL5 "SOF_DMA_UL5"6263#define RT5682S_CODEC_DAI "rt5682s-aif1"6465/* FE */66SND_SOC_DAILINK_DEFS(playback2,67DAILINK_COMP_ARRAY(COMP_CPU("DL2")),68DAILINK_COMP_ARRAY(COMP_DUMMY()),69DAILINK_COMP_ARRAY(COMP_EMPTY()));7071SND_SOC_DAILINK_DEFS(playback3,72DAILINK_COMP_ARRAY(COMP_CPU("DL3")),73DAILINK_COMP_ARRAY(COMP_DUMMY()),74DAILINK_COMP_ARRAY(COMP_EMPTY()));7576SND_SOC_DAILINK_DEFS(playback6,77DAILINK_COMP_ARRAY(COMP_CPU("DL6")),78DAILINK_COMP_ARRAY(COMP_DUMMY()),79DAILINK_COMP_ARRAY(COMP_EMPTY()));8081SND_SOC_DAILINK_DEFS(playback7,82DAILINK_COMP_ARRAY(COMP_CPU("DL7")),83DAILINK_COMP_ARRAY(COMP_DUMMY()),84DAILINK_COMP_ARRAY(COMP_EMPTY()));8586SND_SOC_DAILINK_DEFS(playback8,87DAILINK_COMP_ARRAY(COMP_CPU("DL8")),88DAILINK_COMP_ARRAY(COMP_DUMMY()),89DAILINK_COMP_ARRAY(COMP_EMPTY()));9091SND_SOC_DAILINK_DEFS(playback10,92DAILINK_COMP_ARRAY(COMP_CPU("DL10")),93DAILINK_COMP_ARRAY(COMP_DUMMY()),94DAILINK_COMP_ARRAY(COMP_EMPTY()));9596SND_SOC_DAILINK_DEFS(playback11,97DAILINK_COMP_ARRAY(COMP_CPU("DL11")),98DAILINK_COMP_ARRAY(COMP_DUMMY()),99DAILINK_COMP_ARRAY(COMP_EMPTY()));100101SND_SOC_DAILINK_DEFS(capture1,102DAILINK_COMP_ARRAY(COMP_CPU("UL1")),103DAILINK_COMP_ARRAY(COMP_DUMMY()),104DAILINK_COMP_ARRAY(COMP_EMPTY()));105106SND_SOC_DAILINK_DEFS(capture2,107DAILINK_COMP_ARRAY(COMP_CPU("UL2")),108DAILINK_COMP_ARRAY(COMP_DUMMY()),109DAILINK_COMP_ARRAY(COMP_EMPTY()));110111SND_SOC_DAILINK_DEFS(capture3,112DAILINK_COMP_ARRAY(COMP_CPU("UL3")),113DAILINK_COMP_ARRAY(COMP_DUMMY()),114DAILINK_COMP_ARRAY(COMP_EMPTY()));115116SND_SOC_DAILINK_DEFS(capture4,117DAILINK_COMP_ARRAY(COMP_CPU("UL4")),118DAILINK_COMP_ARRAY(COMP_DUMMY()),119DAILINK_COMP_ARRAY(COMP_EMPTY()));120121SND_SOC_DAILINK_DEFS(capture5,122DAILINK_COMP_ARRAY(COMP_CPU("UL5")),123DAILINK_COMP_ARRAY(COMP_DUMMY()),124DAILINK_COMP_ARRAY(COMP_EMPTY()));125126SND_SOC_DAILINK_DEFS(capture6,127DAILINK_COMP_ARRAY(COMP_CPU("UL6")),128DAILINK_COMP_ARRAY(COMP_DUMMY()),129DAILINK_COMP_ARRAY(COMP_EMPTY()));130131SND_SOC_DAILINK_DEFS(capture8,132DAILINK_COMP_ARRAY(COMP_CPU("UL8")),133DAILINK_COMP_ARRAY(COMP_DUMMY()),134DAILINK_COMP_ARRAY(COMP_EMPTY()));135136SND_SOC_DAILINK_DEFS(capture9,137DAILINK_COMP_ARRAY(COMP_CPU("UL9")),138DAILINK_COMP_ARRAY(COMP_DUMMY()),139DAILINK_COMP_ARRAY(COMP_EMPTY()));140141SND_SOC_DAILINK_DEFS(capture10,142DAILINK_COMP_ARRAY(COMP_CPU("UL10")),143DAILINK_COMP_ARRAY(COMP_DUMMY()),144DAILINK_COMP_ARRAY(COMP_EMPTY()));145146/* BE */147SND_SOC_DAILINK_DEFS(dl_src,148DAILINK_COMP_ARRAY(COMP_CPU("DL_SRC")),149DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",150"mt6359-snd-codec-aif1")),151DAILINK_COMP_ARRAY(COMP_EMPTY()));152153SND_SOC_DAILINK_DEFS(DMIC_BE,154DAILINK_COMP_ARRAY(COMP_CPU("DMIC")),155DAILINK_COMP_ARRAY(COMP_DUMMY()),156DAILINK_COMP_ARRAY(COMP_EMPTY()));157158SND_SOC_DAILINK_DEFS(dptx,159DAILINK_COMP_ARRAY(COMP_CPU("DPTX")),160DAILINK_COMP_ARRAY(COMP_DUMMY()),161DAILINK_COMP_ARRAY(COMP_EMPTY()));162163SND_SOC_DAILINK_DEFS(etdm1_in,164DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_IN")),165DAILINK_COMP_ARRAY(COMP_DUMMY()),166DAILINK_COMP_ARRAY(COMP_EMPTY()));167168SND_SOC_DAILINK_DEFS(etdm2_in,169DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_IN")),170DAILINK_COMP_ARRAY(COMP_DUMMY()),171DAILINK_COMP_ARRAY(COMP_EMPTY()));172173SND_SOC_DAILINK_DEFS(etdm1_out,174DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_OUT")),175DAILINK_COMP_ARRAY(COMP_DUMMY()),176DAILINK_COMP_ARRAY(COMP_EMPTY()));177178SND_SOC_DAILINK_DEFS(etdm2_out,179DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_OUT")),180DAILINK_COMP_ARRAY(COMP_DUMMY()),181DAILINK_COMP_ARRAY(COMP_EMPTY()));182183SND_SOC_DAILINK_DEFS(etdm3_out,184DAILINK_COMP_ARRAY(COMP_CPU("ETDM3_OUT")),185DAILINK_COMP_ARRAY(COMP_DUMMY()),186DAILINK_COMP_ARRAY(COMP_EMPTY()));187188SND_SOC_DAILINK_DEFS(pcm1,189DAILINK_COMP_ARRAY(COMP_CPU("PCM1")),190DAILINK_COMP_ARRAY(COMP_DUMMY()),191DAILINK_COMP_ARRAY(COMP_EMPTY()));192193SND_SOC_DAILINK_DEFS(ul_src,194DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC")),195DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",196"mt6359-snd-codec-aif1")),197DAILINK_COMP_ARRAY(COMP_EMPTY()));198199SND_SOC_DAILINK_DEFS(AFE_SOF_DL2,200DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL2")),201DAILINK_COMP_ARRAY(COMP_DUMMY()),202DAILINK_COMP_ARRAY(COMP_EMPTY()));203204SND_SOC_DAILINK_DEFS(AFE_SOF_DL3,205DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL3")),206DAILINK_COMP_ARRAY(COMP_DUMMY()),207DAILINK_COMP_ARRAY(COMP_EMPTY()));208209SND_SOC_DAILINK_DEFS(AFE_SOF_UL4,210DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL4")),211DAILINK_COMP_ARRAY(COMP_DUMMY()),212DAILINK_COMP_ARRAY(COMP_EMPTY()));213214SND_SOC_DAILINK_DEFS(AFE_SOF_UL5,215DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL5")),216DAILINK_COMP_ARRAY(COMP_DUMMY()),217DAILINK_COMP_ARRAY(COMP_EMPTY()));218219static const struct sof_conn_stream g_sof_conn_streams[] = {220{221.sof_link = "AFE_SOF_DL2",222.sof_dma = SOF_DMA_DL2,223.stream_dir = SNDRV_PCM_STREAM_PLAYBACK224},225{226.sof_link = "AFE_SOF_DL3",227.sof_dma = SOF_DMA_DL3,228.stream_dir = SNDRV_PCM_STREAM_PLAYBACK229},230{231.sof_link = "AFE_SOF_UL4",232.sof_dma = SOF_DMA_UL4,233.stream_dir = SNDRV_PCM_STREAM_CAPTURE234},235{236.sof_link = "AFE_SOF_UL5",237.sof_dma = SOF_DMA_UL5,238.stream_dir = SNDRV_PCM_STREAM_CAPTURE239},240};241242enum mt8188_jacks {243MT8188_JACK_HEADSET,244MT8188_JACK_DP,245MT8188_JACK_HDMI,246MT8188_JACK_MAX,247};248249static struct snd_soc_jack_pin mt8188_hdmi_jack_pins[] = {250{251.pin = "HDMI",252.mask = SND_JACK_AVOUT,253},254};255256static struct snd_soc_jack_pin mt8188_dp_jack_pins[] = {257{258.pin = "DP",259.mask = SND_JACK_AVOUT,260},261};262263static struct snd_soc_jack_pin nau8825_jack_pins[] = {264{265.pin = "Headphone Jack",266.mask = SND_JACK_HEADPHONE,267},268{269.pin = "Headset Mic",270.mask = SND_JACK_MICROPHONE,271},272};273274static struct snd_soc_jack_pin mt8188_headset_jack_pins[] = {275{276.pin = "Headphone",277.mask = SND_JACK_HEADPHONE,278},279{280.pin = "Headset Mic",281.mask = SND_JACK_MICROPHONE,282},283};284285static const struct snd_kcontrol_new mt8188_dumb_spk_controls[] = {286SOC_DAPM_PIN_SWITCH("Ext Spk"),287};288289static const struct snd_soc_dapm_widget mt8188_dumb_spk_widgets[] = {290SND_SOC_DAPM_SPK("Ext Spk", NULL),291};292293static const struct snd_kcontrol_new mt8188_dual_spk_controls[] = {294SOC_DAPM_PIN_SWITCH("Left Spk"),295SOC_DAPM_PIN_SWITCH("Right Spk"),296};297298static const struct snd_soc_dapm_widget mt8188_dual_spk_widgets[] = {299SND_SOC_DAPM_SPK("Left Spk", NULL),300SND_SOC_DAPM_SPK("Right Spk", NULL),301};302303static const struct snd_kcontrol_new mt8188_rear_spk_controls[] = {304SOC_DAPM_PIN_SWITCH("Rear Left Spk"),305SOC_DAPM_PIN_SWITCH("Rear Right Spk"),306};307308static const struct snd_soc_dapm_widget mt8188_rear_spk_widgets[] = {309SND_SOC_DAPM_SPK("Rear Left Spk", NULL),310SND_SOC_DAPM_SPK("Rear Right Spk", NULL),311};312313static const struct snd_soc_dapm_widget mt8188_mt6359_widgets[] = {314SND_SOC_DAPM_HP("Headphone", NULL),315SND_SOC_DAPM_MIC("Headset Mic", NULL),316SND_SOC_DAPM_MIC("AP DMIC", NULL),317SND_SOC_DAPM_SINK("HDMI"),318SND_SOC_DAPM_SINK("DP"),319SND_SOC_DAPM_MIXER(SOF_DMA_DL2, SND_SOC_NOPM, 0, 0, NULL, 0),320SND_SOC_DAPM_MIXER(SOF_DMA_DL3, SND_SOC_NOPM, 0, 0, NULL, 0),321SND_SOC_DAPM_MIXER(SOF_DMA_UL4, SND_SOC_NOPM, 0, 0, NULL, 0),322SND_SOC_DAPM_MIXER(SOF_DMA_UL5, SND_SOC_NOPM, 0, 0, NULL, 0),323324/* dynamic pinctrl */325SND_SOC_DAPM_PINCTRL("ETDM_SPK_PIN", "aud_etdm_spk_on", "aud_etdm_spk_off"),326SND_SOC_DAPM_PINCTRL("ETDM_HP_PIN", "aud_etdm_hp_on", "aud_etdm_hp_off"),327SND_SOC_DAPM_PINCTRL("MTKAIF_PIN", "aud_mtkaif_on", "aud_mtkaif_off"),328};329330static const struct snd_kcontrol_new mt8188_mt6359_controls[] = {331SOC_DAPM_PIN_SWITCH("Headphone"),332SOC_DAPM_PIN_SWITCH("Headset Mic"),333};334335static const struct snd_soc_dapm_widget mt8188_nau8825_widgets[] = {336SND_SOC_DAPM_HP("Headphone Jack", NULL),337};338339static const struct snd_kcontrol_new mt8188_nau8825_controls[] = {340SOC_DAPM_PIN_SWITCH("Headphone Jack"),341};342343static const struct snd_soc_dapm_route mt8188_mt6359_routes[] = {344/* SOF Uplink */345{SOF_DMA_UL4, NULL, "O034"},346{SOF_DMA_UL4, NULL, "O035"},347{SOF_DMA_UL5, NULL, "O036"},348{SOF_DMA_UL5, NULL, "O037"},349/* SOF Downlink */350{"I070", NULL, SOF_DMA_DL2},351{"I071", NULL, SOF_DMA_DL2},352{"I020", NULL, SOF_DMA_DL3},353{"I021", NULL, SOF_DMA_DL3},354};355356static int mt8188_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd)357{358struct snd_soc_component *cmpnt_afe =359snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);360struct snd_soc_component *cmpnt_codec =361snd_soc_rtd_to_codec(rtd, 0)->component;362struct snd_soc_dapm_widget *pin_w = NULL, *w;363struct mtk_base_afe *afe;364struct mt8188_afe_private *afe_priv;365struct mtkaif_param *param;366int chosen_phase_1, chosen_phase_2;367int prev_cycle_1, prev_cycle_2;368u8 test_done_1, test_done_2;369int cycle_1, cycle_2;370int mtkaif_chosen_phase[MT8188_MTKAIF_MISO_NUM];371int mtkaif_phase_cycle[MT8188_MTKAIF_MISO_NUM];372int mtkaif_calibration_num_phase;373bool mtkaif_calibration_ok;374u32 monitor = 0;375int counter;376int phase;377int i;378379if (!cmpnt_afe)380return -EINVAL;381382afe = snd_soc_component_get_drvdata(cmpnt_afe);383afe_priv = afe->platform_priv;384param = &afe_priv->mtkaif_params;385386dev_dbg(afe->dev, "%s(), start\n", __func__);387388param->mtkaif_calibration_ok = false;389for (i = 0; i < MT8188_MTKAIF_MISO_NUM; i++) {390param->mtkaif_chosen_phase[i] = -1;391param->mtkaif_phase_cycle[i] = 0;392mtkaif_chosen_phase[i] = -1;393mtkaif_phase_cycle[i] = 0;394}395396if (IS_ERR(afe_priv->topckgen)) {397dev_info(afe->dev, "%s() Cannot find topckgen controller\n",398__func__);399return 0;400}401402for_each_card_widgets(rtd->card, w) {403if (!strcmp(w->name, "MTKAIF_PIN")) {404pin_w = w;405break;406}407}408409if (pin_w)410snd_soc_dapm_pinctrl_event(pin_w, NULL, SND_SOC_DAPM_PRE_PMU);411else412dev_dbg(afe->dev, "%s(), no pinmux widget, please check if default on\n", __func__);413414pm_runtime_get_sync(afe->dev);415mt6359_mtkaif_calibration_enable(cmpnt_codec);416417/* set test type to synchronizer pulse */418regmap_write(afe_priv->topckgen, CKSYS_AUD_TOP_CFG, RG_TEST_TYPE);419mtkaif_calibration_num_phase = 42; /* mt6359: 0 ~ 42 */420mtkaif_calibration_ok = true;421422for (phase = 0;423phase <= mtkaif_calibration_num_phase && mtkaif_calibration_ok;424phase++) {425mt6359_set_mtkaif_calibration_phase(cmpnt_codec,426phase, phase, phase);427428regmap_set_bits(afe_priv->topckgen, CKSYS_AUD_TOP_CFG, RG_TEST_ON);429430test_done_1 = 0;431test_done_2 = 0;432433cycle_1 = -1;434cycle_2 = -1;435436counter = 0;437while (!(test_done_1 & test_done_2)) {438regmap_read(afe_priv->topckgen,439CKSYS_AUD_TOP_MON, &monitor);440test_done_1 = FIELD_GET(TEST_MISO_DONE_1, monitor);441test_done_2 = FIELD_GET(TEST_MISO_DONE_2, monitor);442443if (test_done_1 == 1)444cycle_1 = FIELD_GET(TEST_MISO_COUNT_1, monitor);445446if (test_done_2 == 1)447cycle_2 = FIELD_GET(TEST_MISO_COUNT_2, monitor);448449/* handle if never test done */450if (++counter > 10000) {451dev_err(afe->dev, "%s(), test fail, cycle_1 %d, cycle_2 %d, monitor 0x%x\n",452__func__, cycle_1, cycle_2, monitor);453mtkaif_calibration_ok = false;454break;455}456}457458if (phase == 0) {459prev_cycle_1 = cycle_1;460prev_cycle_2 = cycle_2;461}462463if (cycle_1 != prev_cycle_1 &&464mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] < 0) {465mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] = phase - 1;466mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0] = prev_cycle_1;467}468469if (cycle_2 != prev_cycle_2 &&470mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] < 0) {471mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] = phase - 1;472mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1] = prev_cycle_2;473}474475regmap_clear_bits(afe_priv->topckgen, CKSYS_AUD_TOP_CFG, RG_TEST_ON);476477if (mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] >= 0 &&478mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] >= 0)479break;480}481482if (mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] < 0) {483mtkaif_calibration_ok = false;484chosen_phase_1 = 0;485} else {486chosen_phase_1 = mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0];487}488489if (mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] < 0) {490mtkaif_calibration_ok = false;491chosen_phase_2 = 0;492} else {493chosen_phase_2 = mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1];494}495496mt6359_set_mtkaif_calibration_phase(cmpnt_codec,497chosen_phase_1,498chosen_phase_2,4990);500501mt6359_mtkaif_calibration_disable(cmpnt_codec);502pm_runtime_put(afe->dev);503504param->mtkaif_calibration_ok = mtkaif_calibration_ok;505param->mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] = chosen_phase_1;506param->mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] = chosen_phase_2;507508for (i = 0; i < MT8188_MTKAIF_MISO_NUM; i++)509param->mtkaif_phase_cycle[i] = mtkaif_phase_cycle[i];510511if (pin_w)512snd_soc_dapm_pinctrl_event(pin_w, NULL, SND_SOC_DAPM_POST_PMD);513514dev_dbg(afe->dev, "%s(), end, calibration ok %d\n",515__func__, param->mtkaif_calibration_ok);516517return 0;518}519520static int mt8188_mt6359_accdet_init(struct snd_soc_pcm_runtime *rtd)521{522struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card);523struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8188_JACK_HEADSET];524int ret;525526if (!soc_card_data->accdet)527return 0;528529ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",530SND_JACK_HEADSET | SND_JACK_BTN_0 |531SND_JACK_BTN_1 | SND_JACK_BTN_2 |532SND_JACK_BTN_3,533jack, mt8188_headset_jack_pins,534ARRAY_SIZE(mt8188_headset_jack_pins));535if (ret) {536dev_err(rtd->dev, "Headset Jack create failed: %d\n", ret);537return ret;538}539540ret = mt6359_accdet_enable_jack_detect(soc_card_data->accdet, jack);541if (ret) {542dev_err(rtd->dev, "Headset Jack enable failed: %d\n", ret);543return ret;544}545546return 0;547}548549static int mt8188_mt6359_init(struct snd_soc_pcm_runtime *rtd)550{551struct snd_soc_component *cmpnt_codec =552snd_soc_rtd_to_codec(rtd, 0)->component;553554/* set mtkaif protocol */555mt6359_set_mtkaif_protocol(cmpnt_codec,556MT6359_MTKAIF_PROTOCOL_2_CLK_P2);557558/* mtkaif calibration */559mt8188_mt6359_mtkaif_calibration(rtd);560561mt8188_mt6359_accdet_init(rtd);562563return 0;564}565566enum {567DAI_LINK_DL2_FE,568DAI_LINK_DL3_FE,569DAI_LINK_DL6_FE,570DAI_LINK_DL7_FE,571DAI_LINK_DL8_FE,572DAI_LINK_DL10_FE,573DAI_LINK_DL11_FE,574DAI_LINK_UL1_FE,575DAI_LINK_UL2_FE,576DAI_LINK_UL3_FE,577DAI_LINK_UL4_FE,578DAI_LINK_UL5_FE,579DAI_LINK_UL6_FE,580DAI_LINK_UL8_FE,581DAI_LINK_UL9_FE,582DAI_LINK_UL10_FE,583DAI_LINK_DL_SRC_BE,584DAI_LINK_DMIC_BE,585DAI_LINK_DPTX_BE,586DAI_LINK_ETDM1_IN_BE,587DAI_LINK_ETDM2_IN_BE,588DAI_LINK_ETDM1_OUT_BE,589DAI_LINK_ETDM2_OUT_BE,590DAI_LINK_ETDM3_OUT_BE,591DAI_LINK_PCM1_BE,592DAI_LINK_UL_SRC_BE,593DAI_LINK_REGULAR_LAST = DAI_LINK_UL_SRC_BE,594DAI_LINK_SOF_START,595DAI_LINK_SOF_DL2_BE = DAI_LINK_SOF_START,596DAI_LINK_SOF_DL3_BE,597DAI_LINK_SOF_UL4_BE,598DAI_LINK_SOF_UL5_BE,599DAI_LINK_SOF_END = DAI_LINK_SOF_UL5_BE,600};601602#define DAI_LINK_REGULAR_NUM (DAI_LINK_REGULAR_LAST + 1)603604static int mt8188_dptx_hw_params(struct snd_pcm_substream *substream,605struct snd_pcm_hw_params *params)606{607struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);608unsigned int rate = params_rate(params);609unsigned int mclk_fs_ratio = 256;610unsigned int mclk_fs = rate * mclk_fs_ratio;611struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0);612613return snd_soc_dai_set_sysclk(dai, 0, mclk_fs, SND_SOC_CLOCK_OUT);614}615616static const struct snd_soc_ops mt8188_dptx_ops = {617.hw_params = mt8188_dptx_hw_params,618};619620static int mt8188_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,621struct snd_pcm_hw_params *params)622{623/* fix BE i2s format to 32bit, clean param mask first */624snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),6250, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);626627params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);628629return 0;630}631632static int mt8188_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd)633{634struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card);635struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8188_JACK_HDMI];636struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;637int ret = 0;638639ret = snd_soc_card_jack_new_pins(rtd->card, "HDMI Jack",640SND_JACK_AVOUT, jack,641mt8188_hdmi_jack_pins,642ARRAY_SIZE(mt8188_hdmi_jack_pins));643if (ret) {644dev_err(rtd->dev, "%s, new jack failed: %d\n", __func__, ret);645return ret;646}647648ret = snd_soc_component_set_jack(component, jack, NULL);649if (ret) {650dev_err(rtd->dev, "%s, set jack failed on %s (ret=%d)\n",651__func__, component->name, ret);652return ret;653}654655return 0;656}657658static int mt8188_dptx_codec_init(struct snd_soc_pcm_runtime *rtd)659{660struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card);661struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8188_JACK_DP];662struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;663int ret = 0;664665ret = snd_soc_card_jack_new_pins(rtd->card, "DP Jack", SND_JACK_AVOUT,666jack, mt8188_dp_jack_pins,667ARRAY_SIZE(mt8188_dp_jack_pins));668if (ret) {669dev_err(rtd->dev, "%s, new jack failed: %d\n", __func__, ret);670return ret;671}672673ret = snd_soc_component_set_jack(component, jack, NULL);674if (ret) {675dev_err(rtd->dev, "%s, set jack failed on %s (ret=%d)\n",676__func__, component->name, ret);677return ret;678}679680return 0;681}682683static int mt8188_dumb_amp_init(struct snd_soc_pcm_runtime *rtd)684{685struct snd_soc_card *card = rtd->card;686struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);687int ret = 0;688689ret = snd_soc_dapm_new_controls(dapm, mt8188_dumb_spk_widgets,690ARRAY_SIZE(mt8188_dumb_spk_widgets));691if (ret) {692dev_err(rtd->dev, "unable to add Dumb Speaker dapm, ret %d\n", ret);693return ret;694}695696ret = snd_soc_add_card_controls(card, mt8188_dumb_spk_controls,697ARRAY_SIZE(mt8188_dumb_spk_controls));698if (ret) {699dev_err(rtd->dev, "unable to add Dumb card controls, ret %d\n", ret);700return ret;701}702703return 0;704}705706static int mt8188_max98390_hw_params(struct snd_pcm_substream *substream,707struct snd_pcm_hw_params *params)708{709struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);710unsigned int bit_width = params_width(params);711struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);712struct snd_soc_dai *codec_dai;713int i;714715snd_soc_dai_set_tdm_slot(cpu_dai, 0xf, 0xf, 4, bit_width);716717for_each_rtd_codec_dais(rtd, i, codec_dai) {718if (!strcmp(codec_dai->component->name, MAX98390_DEV0_NAME))719snd_soc_dai_set_tdm_slot(codec_dai, 0x8, 0x3, 4, bit_width);720721if (!strcmp(codec_dai->component->name, MAX98390_DEV1_NAME))722snd_soc_dai_set_tdm_slot(codec_dai, 0x4, 0x3, 4, bit_width);723724if (!strcmp(codec_dai->component->name, MAX98390_DEV2_NAME))725snd_soc_dai_set_tdm_slot(codec_dai, 0x2, 0x3, 4, bit_width);726727if (!strcmp(codec_dai->component->name, MAX98390_DEV3_NAME))728snd_soc_dai_set_tdm_slot(codec_dai, 0x1, 0x3, 4, bit_width);729}730return 0;731}732733static const struct snd_soc_ops mt8188_max98390_ops = {734.hw_params = mt8188_max98390_hw_params,735};736737static int mt8188_max98390_codec_init(struct snd_soc_pcm_runtime *rtd)738{739struct snd_soc_card *card = rtd->card;740struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);741int ret;742743/* add regular speakers dapm route */744ret = snd_soc_dapm_new_controls(dapm, mt8188_dual_spk_widgets,745ARRAY_SIZE(mt8188_dual_spk_widgets));746if (ret) {747dev_err(rtd->dev, "unable to add Left/Right Speaker widget, ret %d\n", ret);748return ret;749}750751ret = snd_soc_add_card_controls(card, mt8188_dual_spk_controls,752ARRAY_SIZE(mt8188_dual_spk_controls));753if (ret) {754dev_err(rtd->dev, "unable to add Left/Right card controls, ret %d\n", ret);755return ret;756}757758if (rtd->dai_link->num_codecs <= 2)759return 0;760761/* add widgets/controls/dapm for rear speakers */762ret = snd_soc_dapm_new_controls(dapm, mt8188_rear_spk_widgets,763ARRAY_SIZE(mt8188_rear_spk_widgets));764if (ret) {765dev_err(rtd->dev, "unable to add Rear Speaker widget, ret %d\n", ret);766/* Don't need to add routes if widget addition failed */767return ret;768}769770ret = snd_soc_add_card_controls(card, mt8188_rear_spk_controls,771ARRAY_SIZE(mt8188_rear_spk_controls));772if (ret) {773dev_err(rtd->dev, "unable to add Rear card controls, ret %d\n", ret);774return ret;775}776777return 0;778}779780static int mt8188_headset_codec_init(struct snd_soc_pcm_runtime *rtd)781{782struct snd_soc_card *card = rtd->card;783struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);784struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card);785struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8188_JACK_HEADSET];786struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;787struct mtk_platform_card_data *card_data = soc_card_data->card_data;788int ret;789790ret = snd_soc_dapm_new_controls(dapm, mt8188_nau8825_widgets,791ARRAY_SIZE(mt8188_nau8825_widgets));792if (ret) {793dev_err(rtd->dev, "unable to add nau8825 card widget, ret %d\n", ret);794return ret;795}796797ret = snd_soc_add_card_controls(card, mt8188_nau8825_controls,798ARRAY_SIZE(mt8188_nau8825_controls));799if (ret) {800dev_err(rtd->dev, "unable to add nau8825 card controls, ret %d\n", ret);801return ret;802}803804ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",805SND_JACK_HEADSET | SND_JACK_BTN_0 |806SND_JACK_BTN_1 | SND_JACK_BTN_2 |807SND_JACK_BTN_3,808jack,809nau8825_jack_pins,810ARRAY_SIZE(nau8825_jack_pins));811if (ret) {812dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);813return ret;814}815816if (card_data->flags & ES8326_HS_PRESENT) {817snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);818snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP);819snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);820snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);821} else {822snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);823snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);824snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);825snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);826}827828ret = snd_soc_component_set_jack(component, jack, NULL);829830if (ret) {831dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);832return ret;833}834835return 0;836};837838static void mt8188_headset_codec_exit(struct snd_soc_pcm_runtime *rtd)839{840struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;841842snd_soc_component_set_jack(component, NULL, NULL);843}844845846static int mt8188_nau8825_hw_params(struct snd_pcm_substream *substream,847struct snd_pcm_hw_params *params)848{849struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);850struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);851unsigned int rate = params_rate(params);852unsigned int bit_width = params_width(params);853int clk_freq, ret;854855clk_freq = rate * 2 * bit_width;856857/* Configure clock for codec */858ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_BLK, 0,859SND_SOC_CLOCK_IN);860if (ret < 0) {861dev_err(codec_dai->dev, "can't set BCLK clock %d\n", ret);862return ret;863}864865/* Configure pll for codec */866ret = snd_soc_dai_set_pll(codec_dai, 0, 0, clk_freq,867params_rate(params) * 256);868if (ret < 0) {869dev_err(codec_dai->dev, "can't set BCLK: %d\n", ret);870return ret;871}872873return 0;874}875876static const struct snd_soc_ops mt8188_nau8825_ops = {877.hw_params = mt8188_nau8825_hw_params,878};879880static int mt8188_rt5682s_i2s_hw_params(struct snd_pcm_substream *substream,881struct snd_pcm_hw_params *params)882{883struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);884struct snd_soc_card *card = rtd->card;885struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);886struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);887unsigned int rate = params_rate(params);888int bitwidth;889int ret;890891bitwidth = snd_pcm_format_width(params_format(params));892if (bitwidth < 0) {893dev_err(card->dev, "invalid bit width: %d\n", bitwidth);894return bitwidth;895}896897ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth);898if (ret) {899dev_err(card->dev, "failed to set tdm slot\n");900return ret;901}902903ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1, RT5682_PLL1_S_BCLK1,904rate * 32, rate * 512);905if (ret) {906dev_err(card->dev, "failed to set pll\n");907return ret;908}909910ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1,911rate * 512, SND_SOC_CLOCK_IN);912if (ret) {913dev_err(card->dev, "failed to set sysclk\n");914return ret;915}916917return snd_soc_dai_set_sysclk(cpu_dai, 0, rate * 128,918SND_SOC_CLOCK_OUT);919}920921static const struct snd_soc_ops mt8188_rt5682s_i2s_ops = {922.hw_params = mt8188_rt5682s_i2s_hw_params,923};924925static int mt8188_sof_be_hw_params(struct snd_pcm_substream *substream,926struct snd_pcm_hw_params *params)927{928struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);929struct snd_soc_component *cmpnt_afe = NULL;930struct snd_soc_pcm_runtime *runtime;931932/* find afe component */933for_each_card_rtds(rtd->card, runtime) {934cmpnt_afe = snd_soc_rtdcom_lookup(runtime, AFE_PCM_NAME);935if (cmpnt_afe)936break;937}938939if (cmpnt_afe && !pm_runtime_active(cmpnt_afe->dev)) {940dev_err(rtd->dev, "afe pm runtime is not active!!\n");941return -EINVAL;942}943944return 0;945}946947static const struct snd_soc_ops mt8188_sof_be_ops = {948.hw_params = mt8188_sof_be_hw_params,949};950951static int mt8188_es8326_hw_params(struct snd_pcm_substream *substream,952struct snd_pcm_hw_params *params)953{954struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);955struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);956struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);957unsigned int rate = params_rate(params);958int ret;959960/* Configure MCLK for codec */961ret = snd_soc_dai_set_sysclk(codec_dai, 0, rate * 256, SND_SOC_CLOCK_IN);962if (ret < 0) {963dev_err(codec_dai->dev, "can't set MCLK %d\n", ret);964return ret;965}966967/* Configure MCLK for cpu */968return snd_soc_dai_set_sysclk(cpu_dai, 0, rate * 256, SND_SOC_CLOCK_OUT);969}970971static const struct snd_soc_ops mt8188_es8326_ops = {972.hw_params = mt8188_es8326_hw_params,973};974975static struct snd_soc_dai_link mt8188_mt6359_dai_links[] = {976/* FE */977[DAI_LINK_DL2_FE] = {978.name = "DL2_FE",979.stream_name = "DL2 Playback",980.trigger = {981SND_SOC_DPCM_TRIGGER_POST,982SND_SOC_DPCM_TRIGGER_POST,983},984.dynamic = 1,985.playback_only = 1,986.dpcm_merged_chan = 1,987.dpcm_merged_rate = 1,988.dpcm_merged_format = 1,989SND_SOC_DAILINK_REG(playback2),990},991[DAI_LINK_DL3_FE] = {992.name = "DL3_FE",993.stream_name = "DL3 Playback",994.trigger = {995SND_SOC_DPCM_TRIGGER_POST,996SND_SOC_DPCM_TRIGGER_POST,997},998.dynamic = 1,999.playback_only = 1,1000.dpcm_merged_chan = 1,1001.dpcm_merged_rate = 1,1002.dpcm_merged_format = 1,1003SND_SOC_DAILINK_REG(playback3),1004},1005[DAI_LINK_DL6_FE] = {1006.name = "DL6_FE",1007.stream_name = "DL6 Playback",1008.trigger = {1009SND_SOC_DPCM_TRIGGER_POST,1010SND_SOC_DPCM_TRIGGER_POST,1011},1012.dynamic = 1,1013.playback_only = 1,1014.dpcm_merged_chan = 1,1015.dpcm_merged_rate = 1,1016.dpcm_merged_format = 1,1017SND_SOC_DAILINK_REG(playback6),1018},1019[DAI_LINK_DL7_FE] = {1020.name = "DL7_FE",1021.stream_name = "DL7 Playback",1022.trigger = {1023SND_SOC_DPCM_TRIGGER_PRE,1024SND_SOC_DPCM_TRIGGER_PRE,1025},1026.dynamic = 1,1027.playback_only = 1,1028SND_SOC_DAILINK_REG(playback7),1029},1030[DAI_LINK_DL8_FE] = {1031.name = "DL8_FE",1032.stream_name = "DL8 Playback",1033.trigger = {1034SND_SOC_DPCM_TRIGGER_POST,1035SND_SOC_DPCM_TRIGGER_POST,1036},1037.dynamic = 1,1038.playback_only = 1,1039SND_SOC_DAILINK_REG(playback8),1040},1041[DAI_LINK_DL10_FE] = {1042.name = "DL10_FE",1043.stream_name = "DL10 Playback",1044.trigger = {1045SND_SOC_DPCM_TRIGGER_POST,1046SND_SOC_DPCM_TRIGGER_POST,1047},1048.dynamic = 1,1049.playback_only = 1,1050SND_SOC_DAILINK_REG(playback10),1051},1052[DAI_LINK_DL11_FE] = {1053.name = "DL11_FE",1054.stream_name = "DL11 Playback",1055.trigger = {1056SND_SOC_DPCM_TRIGGER_POST,1057SND_SOC_DPCM_TRIGGER_POST,1058},1059.dynamic = 1,1060.playback_only = 1,1061SND_SOC_DAILINK_REG(playback11),1062},1063[DAI_LINK_UL1_FE] = {1064.name = "UL1_FE",1065.stream_name = "UL1 Capture",1066.trigger = {1067SND_SOC_DPCM_TRIGGER_PRE,1068SND_SOC_DPCM_TRIGGER_PRE,1069},1070.dynamic = 1,1071.capture_only = 1,1072SND_SOC_DAILINK_REG(capture1),1073},1074[DAI_LINK_UL2_FE] = {1075.name = "UL2_FE",1076.stream_name = "UL2 Capture",1077.trigger = {1078SND_SOC_DPCM_TRIGGER_POST,1079SND_SOC_DPCM_TRIGGER_POST,1080},1081.dynamic = 1,1082.capture_only = 1,1083SND_SOC_DAILINK_REG(capture2),1084},1085[DAI_LINK_UL3_FE] = {1086.name = "UL3_FE",1087.stream_name = "UL3 Capture",1088.trigger = {1089SND_SOC_DPCM_TRIGGER_POST,1090SND_SOC_DPCM_TRIGGER_POST,1091},1092.dynamic = 1,1093.capture_only = 1,1094SND_SOC_DAILINK_REG(capture3),1095},1096[DAI_LINK_UL4_FE] = {1097.name = "UL4_FE",1098.stream_name = "UL4 Capture",1099.trigger = {1100SND_SOC_DPCM_TRIGGER_POST,1101SND_SOC_DPCM_TRIGGER_POST,1102},1103.dynamic = 1,1104.capture_only = 1,1105.dpcm_merged_chan = 1,1106.dpcm_merged_rate = 1,1107.dpcm_merged_format = 1,1108SND_SOC_DAILINK_REG(capture4),1109},1110[DAI_LINK_UL5_FE] = {1111.name = "UL5_FE",1112.stream_name = "UL5 Capture",1113.trigger = {1114SND_SOC_DPCM_TRIGGER_POST,1115SND_SOC_DPCM_TRIGGER_POST,1116},1117.dynamic = 1,1118.capture_only = 1,1119.dpcm_merged_chan = 1,1120.dpcm_merged_rate = 1,1121.dpcm_merged_format = 1,1122SND_SOC_DAILINK_REG(capture5),1123},1124[DAI_LINK_UL6_FE] = {1125.name = "UL6_FE",1126.stream_name = "UL6 Capture",1127.trigger = {1128SND_SOC_DPCM_TRIGGER_PRE,1129SND_SOC_DPCM_TRIGGER_PRE,1130},1131.dynamic = 1,1132.capture_only = 1,1133SND_SOC_DAILINK_REG(capture6),1134},1135[DAI_LINK_UL8_FE] = {1136.name = "UL8_FE",1137.stream_name = "UL8 Capture",1138.trigger = {1139SND_SOC_DPCM_TRIGGER_POST,1140SND_SOC_DPCM_TRIGGER_POST,1141},1142.dynamic = 1,1143.capture_only = 1,1144SND_SOC_DAILINK_REG(capture8),1145},1146[DAI_LINK_UL9_FE] = {1147.name = "UL9_FE",1148.stream_name = "UL9 Capture",1149.trigger = {1150SND_SOC_DPCM_TRIGGER_POST,1151SND_SOC_DPCM_TRIGGER_POST,1152},1153.dynamic = 1,1154.capture_only = 1,1155SND_SOC_DAILINK_REG(capture9),1156},1157[DAI_LINK_UL10_FE] = {1158.name = "UL10_FE",1159.stream_name = "UL10 Capture",1160.trigger = {1161SND_SOC_DPCM_TRIGGER_POST,1162SND_SOC_DPCM_TRIGGER_POST,1163},1164.dynamic = 1,1165.capture_only = 1,1166SND_SOC_DAILINK_REG(capture10),1167},1168/* BE */1169[DAI_LINK_DL_SRC_BE] = {1170.name = "DL_SRC_BE",1171.no_pcm = 1,1172.playback_only = 1,1173SND_SOC_DAILINK_REG(dl_src),1174},1175[DAI_LINK_DMIC_BE] = {1176.name = "DMIC_BE",1177.no_pcm = 1,1178.capture_only = 1,1179.ignore_suspend = 1,1180SND_SOC_DAILINK_REG(DMIC_BE),1181},1182[DAI_LINK_DPTX_BE] = {1183.name = "DPTX_BE",1184.ops = &mt8188_dptx_ops,1185.be_hw_params_fixup = mt8188_dptx_hw_params_fixup,1186.no_pcm = 1,1187.playback_only = 1,1188SND_SOC_DAILINK_REG(dptx),1189},1190[DAI_LINK_ETDM1_IN_BE] = {1191.name = "ETDM1_IN_BE",1192.no_pcm = 1,1193.dai_fmt = SND_SOC_DAIFMT_I2S |1194SND_SOC_DAIFMT_NB_NF |1195SND_SOC_DAIFMT_CBP_CFP,1196.capture_only = 1,1197.ignore_suspend = 1,1198SND_SOC_DAILINK_REG(etdm1_in),1199},1200[DAI_LINK_ETDM2_IN_BE] = {1201.name = "ETDM2_IN_BE",1202.no_pcm = 1,1203.dai_fmt = SND_SOC_DAIFMT_I2S |1204SND_SOC_DAIFMT_NB_NF |1205SND_SOC_DAIFMT_CBP_CFP,1206.capture_only = 1,1207SND_SOC_DAILINK_REG(etdm2_in),1208},1209[DAI_LINK_ETDM1_OUT_BE] = {1210.name = "ETDM1_OUT_BE",1211.no_pcm = 1,1212.dai_fmt = SND_SOC_DAIFMT_I2S |1213SND_SOC_DAIFMT_NB_NF |1214SND_SOC_DAIFMT_CBC_CFC,1215.playback_only = 1,1216SND_SOC_DAILINK_REG(etdm1_out),1217},1218[DAI_LINK_ETDM2_OUT_BE] = {1219.name = "ETDM2_OUT_BE",1220.no_pcm = 1,1221.dai_fmt = SND_SOC_DAIFMT_I2S |1222SND_SOC_DAIFMT_NB_NF |1223SND_SOC_DAIFMT_CBC_CFC,1224.playback_only = 1,1225SND_SOC_DAILINK_REG(etdm2_out),1226},1227[DAI_LINK_ETDM3_OUT_BE] = {1228.name = "ETDM3_OUT_BE",1229.no_pcm = 1,1230.dai_fmt = SND_SOC_DAIFMT_I2S |1231SND_SOC_DAIFMT_NB_NF |1232SND_SOC_DAIFMT_CBC_CFC,1233.playback_only = 1,1234SND_SOC_DAILINK_REG(etdm3_out),1235},1236[DAI_LINK_PCM1_BE] = {1237.name = "PCM1_BE",1238.no_pcm = 1,1239.dai_fmt = SND_SOC_DAIFMT_I2S |1240SND_SOC_DAIFMT_NB_NF |1241SND_SOC_DAIFMT_CBC_CFC,1242SND_SOC_DAILINK_REG(pcm1),1243},1244[DAI_LINK_UL_SRC_BE] = {1245.name = "UL_SRC_BE",1246.no_pcm = 1,1247.capture_only = 1,1248SND_SOC_DAILINK_REG(ul_src),1249},12501251/* SOF BE */1252[DAI_LINK_SOF_DL2_BE] = {1253.name = "AFE_SOF_DL2",1254.no_pcm = 1,1255.playback_only = 1,1256.ops = &mt8188_sof_be_ops,1257SND_SOC_DAILINK_REG(AFE_SOF_DL2),1258},1259[DAI_LINK_SOF_DL3_BE] = {1260.name = "AFE_SOF_DL3",1261.no_pcm = 1,1262.playback_only = 1,1263.ops = &mt8188_sof_be_ops,1264SND_SOC_DAILINK_REG(AFE_SOF_DL3),1265},1266[DAI_LINK_SOF_UL4_BE] = {1267.name = "AFE_SOF_UL4",1268.no_pcm = 1,1269.capture_only = 1,1270.ops = &mt8188_sof_be_ops,1271SND_SOC_DAILINK_REG(AFE_SOF_UL4),1272},1273[DAI_LINK_SOF_UL5_BE] = {1274.name = "AFE_SOF_UL5",1275.no_pcm = 1,1276.capture_only = 1,1277.ops = &mt8188_sof_be_ops,1278SND_SOC_DAILINK_REG(AFE_SOF_UL5),1279},1280};12811282static void mt8188_fixup_controls(struct snd_soc_card *card)1283{1284struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);1285struct mtk_platform_card_data *card_data = soc_card_data->card_data;1286struct snd_kcontrol *kctl;12871288if (card_data->flags & (NAU8825_HS_PRESENT | RT5682S_HS_PRESENT | ES8326_HS_PRESENT)) {1289struct snd_soc_dapm_widget *w, *next_w;12901291for_each_card_widgets_safe(card, w, next_w) {1292if (strcmp(w->name, "Headphone"))1293continue;12941295snd_soc_dapm_free_widget(w);1296}12971298kctl = snd_ctl_find_id_mixer(card->snd_card, "Headphone Switch");1299if (kctl)1300snd_ctl_remove(card->snd_card, kctl);1301else1302dev_warn(card->dev, "Cannot find ctl : Headphone Switch\n");1303}1304}13051306static struct snd_soc_card mt8188_mt6359_soc_card = {1307.owner = THIS_MODULE,1308.dai_link = mt8188_mt6359_dai_links,1309.num_links = ARRAY_SIZE(mt8188_mt6359_dai_links),1310.dapm_widgets = mt8188_mt6359_widgets,1311.num_dapm_widgets = ARRAY_SIZE(mt8188_mt6359_widgets),1312.dapm_routes = mt8188_mt6359_routes,1313.num_dapm_routes = ARRAY_SIZE(mt8188_mt6359_routes),1314.controls = mt8188_mt6359_controls,1315.num_controls = ARRAY_SIZE(mt8188_mt6359_controls),1316.fixup_controls = mt8188_fixup_controls,1317};13181319static int mt8188_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, bool legacy)1320{1321struct mtk_platform_card_data *card_data = soc_card_data->card_data;1322struct snd_soc_card *card = soc_card_data->card_data->card;1323struct snd_soc_dai_link *dai_link;1324bool init_mt6359 = false;1325bool init_es8326 = false;1326bool init_nau8825 = false;1327bool init_rt5682s = false;1328bool init_max98390 = false;1329bool init_dumb = false;1330int i;13311332if (legacy)1333return -EINVAL;13341335for_each_card_prelinks(card, i, dai_link) {1336if (strcmp(dai_link->name, "DPTX_BE") == 0) {1337if (dai_link->num_codecs &&1338!snd_soc_dlc_is_dummy(dai_link->codecs))1339dai_link->init = mt8188_dptx_codec_init;1340} else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) {1341if (dai_link->num_codecs &&1342!snd_soc_dlc_is_dummy(dai_link->codecs))1343dai_link->init = mt8188_hdmi_codec_init;1344} else if (strcmp(dai_link->name, "DL_SRC_BE") == 0 ||1345strcmp(dai_link->name, "UL_SRC_BE") == 0) {1346if (!init_mt6359) {1347dai_link->init = mt8188_mt6359_init;1348init_mt6359 = true;1349}1350} else if (strcmp(dai_link->name, "ETDM1_OUT_BE") == 0 ||1351strcmp(dai_link->name, "ETDM2_OUT_BE") == 0 ||1352strcmp(dai_link->name, "ETDM1_IN_BE") == 0 ||1353strcmp(dai_link->name, "ETDM2_IN_BE") == 0) {1354if (!dai_link->num_codecs)1355continue;13561357if (!strcmp(dai_link->codecs->dai_name, MAX98390_CODEC_DAI)) {1358/*1359* The TDM protocol settings with fixed 4 slots are defined in1360* mt8188_max98390_ops. Two amps is I2S mode,1361* SOC and codec don't require TDM settings.1362*/1363if (!(card_data->flags & MAX98390_TWO_AMP)) {1364dai_link->ops = &mt8188_max98390_ops;1365}1366if (!init_max98390) {1367dai_link->init = mt8188_max98390_codec_init;1368init_max98390 = true;1369}1370} else if (!strcmp(dai_link->codecs->dai_name, NAU8825_CODEC_DAI)) {1371dai_link->ops = &mt8188_nau8825_ops;1372if (!init_nau8825) {1373dai_link->init = mt8188_headset_codec_init;1374dai_link->exit = mt8188_headset_codec_exit;1375init_nau8825 = true;1376}1377} else if (!strcmp(dai_link->codecs->dai_name, RT5682S_CODEC_DAI)) {1378dai_link->ops = &mt8188_rt5682s_i2s_ops;1379if (!init_rt5682s) {1380dai_link->init = mt8188_headset_codec_init;1381dai_link->exit = mt8188_headset_codec_exit;1382init_rt5682s = true;1383}1384} else if (!strcmp(dai_link->codecs->dai_name, ES8326_CODEC_DAI)) {1385dai_link->ops = &mt8188_es8326_ops;1386if (!init_es8326) {1387dai_link->init = mt8188_headset_codec_init;1388dai_link->exit = mt8188_headset_codec_exit;1389init_es8326 = true;1390}1391} else {1392if (!snd_soc_dlc_is_dummy(dai_link->codecs)) {1393if (!init_dumb) {1394dai_link->init = mt8188_dumb_amp_init;1395init_dumb = true;1396}1397}1398}1399}1400}14011402return 0;1403}14041405static const struct mtk_sof_priv mt8188_sof_priv = {1406.conn_streams = g_sof_conn_streams,1407.num_streams = ARRAY_SIZE(g_sof_conn_streams),1408};14091410static const struct mtk_soundcard_pdata mt8188_evb_card = {1411.card_name = "mt8188_mt6359",1412.card_data = &(struct mtk_platform_card_data) {1413.card = &mt8188_mt6359_soc_card,1414.num_jacks = MT8188_JACK_MAX,1415},1416.sof_priv = &mt8188_sof_priv,1417.soc_probe = mt8188_mt6359_soc_card_probe,1418};14191420static const struct mtk_soundcard_pdata mt8188_nau8825_card = {1421.card_name = "mt8188_nau8825",1422.card_data = &(struct mtk_platform_card_data) {1423.card = &mt8188_mt6359_soc_card,1424.num_jacks = MT8188_JACK_MAX,1425.flags = NAU8825_HS_PRESENT1426},1427.sof_priv = &mt8188_sof_priv,1428.soc_probe = mt8188_mt6359_soc_card_probe,1429};14301431static const struct mtk_soundcard_pdata mt8188_rt5682s_card = {1432.card_name = "mt8188_rt5682s",1433.card_data = &(struct mtk_platform_card_data) {1434.card = &mt8188_mt6359_soc_card,1435.num_jacks = MT8188_JACK_MAX,1436.flags = RT5682S_HS_PRESENT | MAX98390_TWO_AMP1437},1438.sof_priv = &mt8188_sof_priv,1439.soc_probe = mt8188_mt6359_soc_card_probe,1440};14411442static const struct mtk_soundcard_pdata mt8188_es8326_card = {1443.card_name = "mt8188_es8326",1444.card_data = &(struct mtk_platform_card_data) {1445.card = &mt8188_mt6359_soc_card,1446.num_jacks = MT8188_JACK_MAX,1447.flags = ES8326_HS_PRESENT | MAX98390_TWO_AMP1448},1449.sof_priv = &mt8188_sof_priv,1450.soc_probe = mt8188_mt6359_soc_card_probe,1451};14521453static const struct of_device_id mt8188_mt6359_dt_match[] = {1454{ .compatible = "mediatek,mt8188-mt6359-evb", .data = &mt8188_evb_card, },1455{ .compatible = "mediatek,mt8188-nau8825", .data = &mt8188_nau8825_card, },1456{ .compatible = "mediatek,mt8188-rt5682s", .data = &mt8188_rt5682s_card, },1457{ .compatible = "mediatek,mt8188-es8326", .data = &mt8188_es8326_card, },1458{ /* sentinel */ },1459};1460MODULE_DEVICE_TABLE(of, mt8188_mt6359_dt_match);14611462static struct platform_driver mt8188_mt6359_driver = {1463.driver = {1464.name = "mt8188_mt6359",1465.of_match_table = mt8188_mt6359_dt_match,1466.pm = &snd_soc_pm_ops,1467},1468.probe = mtk_soundcard_common_probe,1469};14701471module_platform_driver(mt8188_mt6359_driver);14721473/* Module information */1474MODULE_DESCRIPTION("MT8188-MT6359 ALSA SoC machine driver");1475MODULE_AUTHOR("Trevor Wu <[email protected]>");1476MODULE_LICENSE("GPL");1477MODULE_ALIAS("mt8188 mt6359 soc card");147814791480