Path: blob/master/sound/soc/mediatek/mt8188/mt8188-mt6359.c
26488 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_LINEOUT,253},254};255256static struct snd_soc_jack_pin mt8188_dp_jack_pins[] = {257{258.pin = "DP",259.mask = SND_JACK_LINEOUT,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_LINEOUT, 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_LINEOUT,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;686int ret = 0;687688ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_dumb_spk_widgets,689ARRAY_SIZE(mt8188_dumb_spk_widgets));690if (ret) {691dev_err(rtd->dev, "unable to add Dumb Speaker dapm, ret %d\n", ret);692return ret;693}694695ret = snd_soc_add_card_controls(card, mt8188_dumb_spk_controls,696ARRAY_SIZE(mt8188_dumb_spk_controls));697if (ret) {698dev_err(rtd->dev, "unable to add Dumb card controls, ret %d\n", ret);699return ret;700}701702return 0;703}704705static int mt8188_max98390_hw_params(struct snd_pcm_substream *substream,706struct snd_pcm_hw_params *params)707{708struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);709unsigned int bit_width = params_width(params);710struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);711struct snd_soc_dai *codec_dai;712int i;713714snd_soc_dai_set_tdm_slot(cpu_dai, 0xf, 0xf, 4, bit_width);715716for_each_rtd_codec_dais(rtd, i, codec_dai) {717if (!strcmp(codec_dai->component->name, MAX98390_DEV0_NAME))718snd_soc_dai_set_tdm_slot(codec_dai, 0x8, 0x3, 4, bit_width);719720if (!strcmp(codec_dai->component->name, MAX98390_DEV1_NAME))721snd_soc_dai_set_tdm_slot(codec_dai, 0x4, 0x3, 4, bit_width);722723if (!strcmp(codec_dai->component->name, MAX98390_DEV2_NAME))724snd_soc_dai_set_tdm_slot(codec_dai, 0x2, 0x3, 4, bit_width);725726if (!strcmp(codec_dai->component->name, MAX98390_DEV3_NAME))727snd_soc_dai_set_tdm_slot(codec_dai, 0x1, 0x3, 4, bit_width);728}729return 0;730}731732static const struct snd_soc_ops mt8188_max98390_ops = {733.hw_params = mt8188_max98390_hw_params,734};735736static int mt8188_max98390_codec_init(struct snd_soc_pcm_runtime *rtd)737{738struct snd_soc_card *card = rtd->card;739int ret;740741/* add regular speakers dapm route */742ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_dual_spk_widgets,743ARRAY_SIZE(mt8188_dual_spk_widgets));744if (ret) {745dev_err(rtd->dev, "unable to add Left/Right Speaker widget, ret %d\n", ret);746return ret;747}748749ret = snd_soc_add_card_controls(card, mt8188_dual_spk_controls,750ARRAY_SIZE(mt8188_dual_spk_controls));751if (ret) {752dev_err(rtd->dev, "unable to add Left/Right card controls, ret %d\n", ret);753return ret;754}755756if (rtd->dai_link->num_codecs <= 2)757return 0;758759/* add widgets/controls/dapm for rear speakers */760ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_rear_spk_widgets,761ARRAY_SIZE(mt8188_rear_spk_widgets));762if (ret) {763dev_err(rtd->dev, "unable to add Rear Speaker widget, ret %d\n", ret);764/* Don't need to add routes if widget addition failed */765return ret;766}767768ret = snd_soc_add_card_controls(card, mt8188_rear_spk_controls,769ARRAY_SIZE(mt8188_rear_spk_controls));770if (ret) {771dev_err(rtd->dev, "unable to add Rear card controls, ret %d\n", ret);772return ret;773}774775return 0;776}777778static int mt8188_headset_codec_init(struct snd_soc_pcm_runtime *rtd)779{780struct snd_soc_card *card = rtd->card;781struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(rtd->card);782struct snd_soc_jack *jack = &soc_card_data->card_data->jacks[MT8188_JACK_HEADSET];783struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;784struct mtk_platform_card_data *card_data = soc_card_data->card_data;785int ret;786787ret = snd_soc_dapm_new_controls(&card->dapm, mt8188_nau8825_widgets,788ARRAY_SIZE(mt8188_nau8825_widgets));789if (ret) {790dev_err(rtd->dev, "unable to add nau8825 card widget, ret %d\n", ret);791return ret;792}793794ret = snd_soc_add_card_controls(card, mt8188_nau8825_controls,795ARRAY_SIZE(mt8188_nau8825_controls));796if (ret) {797dev_err(rtd->dev, "unable to add nau8825 card controls, ret %d\n", ret);798return ret;799}800801ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack",802SND_JACK_HEADSET | SND_JACK_BTN_0 |803SND_JACK_BTN_1 | SND_JACK_BTN_2 |804SND_JACK_BTN_3,805jack,806nau8825_jack_pins,807ARRAY_SIZE(nau8825_jack_pins));808if (ret) {809dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret);810return ret;811}812813if (card_data->flags & ES8326_HS_PRESENT) {814snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);815snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP);816snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN);817snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOICECOMMAND);818} else {819snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);820snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);821snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP);822snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);823}824825ret = snd_soc_component_set_jack(component, jack, NULL);826827if (ret) {828dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);829return ret;830}831832return 0;833};834835static void mt8188_headset_codec_exit(struct snd_soc_pcm_runtime *rtd)836{837struct snd_soc_component *component = snd_soc_rtd_to_codec(rtd, 0)->component;838839snd_soc_component_set_jack(component, NULL, NULL);840}841842843static int mt8188_nau8825_hw_params(struct snd_pcm_substream *substream,844struct snd_pcm_hw_params *params)845{846struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);847struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);848unsigned int rate = params_rate(params);849unsigned int bit_width = params_width(params);850int clk_freq, ret;851852clk_freq = rate * 2 * bit_width;853854/* Configure clock for codec */855ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_BLK, 0,856SND_SOC_CLOCK_IN);857if (ret < 0) {858dev_err(codec_dai->dev, "can't set BCLK clock %d\n", ret);859return ret;860}861862/* Configure pll for codec */863ret = snd_soc_dai_set_pll(codec_dai, 0, 0, clk_freq,864params_rate(params) * 256);865if (ret < 0) {866dev_err(codec_dai->dev, "can't set BCLK: %d\n", ret);867return ret;868}869870return 0;871}872873static const struct snd_soc_ops mt8188_nau8825_ops = {874.hw_params = mt8188_nau8825_hw_params,875};876877static int mt8188_rt5682s_i2s_hw_params(struct snd_pcm_substream *substream,878struct snd_pcm_hw_params *params)879{880struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);881struct snd_soc_card *card = rtd->card;882struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);883struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);884unsigned int rate = params_rate(params);885int bitwidth;886int ret;887888bitwidth = snd_pcm_format_width(params_format(params));889if (bitwidth < 0) {890dev_err(card->dev, "invalid bit width: %d\n", bitwidth);891return bitwidth;892}893894ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth);895if (ret) {896dev_err(card->dev, "failed to set tdm slot\n");897return ret;898}899900ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1, RT5682_PLL1_S_BCLK1,901rate * 32, rate * 512);902if (ret) {903dev_err(card->dev, "failed to set pll\n");904return ret;905}906907ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL1,908rate * 512, SND_SOC_CLOCK_IN);909if (ret) {910dev_err(card->dev, "failed to set sysclk\n");911return ret;912}913914return snd_soc_dai_set_sysclk(cpu_dai, 0, rate * 128,915SND_SOC_CLOCK_OUT);916}917918static const struct snd_soc_ops mt8188_rt5682s_i2s_ops = {919.hw_params = mt8188_rt5682s_i2s_hw_params,920};921922static int mt8188_sof_be_hw_params(struct snd_pcm_substream *substream,923struct snd_pcm_hw_params *params)924{925struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);926struct snd_soc_component *cmpnt_afe = NULL;927struct snd_soc_pcm_runtime *runtime;928929/* find afe component */930for_each_card_rtds(rtd->card, runtime) {931cmpnt_afe = snd_soc_rtdcom_lookup(runtime, AFE_PCM_NAME);932if (cmpnt_afe)933break;934}935936if (cmpnt_afe && !pm_runtime_active(cmpnt_afe->dev)) {937dev_err(rtd->dev, "afe pm runtime is not active!!\n");938return -EINVAL;939}940941return 0;942}943944static const struct snd_soc_ops mt8188_sof_be_ops = {945.hw_params = mt8188_sof_be_hw_params,946};947948static int mt8188_es8326_hw_params(struct snd_pcm_substream *substream,949struct snd_pcm_hw_params *params)950{951struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);952struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);953struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);954unsigned int rate = params_rate(params);955int ret;956957/* Configure MCLK for codec */958ret = snd_soc_dai_set_sysclk(codec_dai, 0, rate * 256, SND_SOC_CLOCK_IN);959if (ret < 0) {960dev_err(codec_dai->dev, "can't set MCLK %d\n", ret);961return ret;962}963964/* Configure MCLK for cpu */965return snd_soc_dai_set_sysclk(cpu_dai, 0, rate * 256, SND_SOC_CLOCK_OUT);966}967968static const struct snd_soc_ops mt8188_es8326_ops = {969.hw_params = mt8188_es8326_hw_params,970};971972static struct snd_soc_dai_link mt8188_mt6359_dai_links[] = {973/* FE */974[DAI_LINK_DL2_FE] = {975.name = "DL2_FE",976.stream_name = "DL2 Playback",977.trigger = {978SND_SOC_DPCM_TRIGGER_POST,979SND_SOC_DPCM_TRIGGER_POST,980},981.dynamic = 1,982.playback_only = 1,983.dpcm_merged_chan = 1,984.dpcm_merged_rate = 1,985.dpcm_merged_format = 1,986SND_SOC_DAILINK_REG(playback2),987},988[DAI_LINK_DL3_FE] = {989.name = "DL3_FE",990.stream_name = "DL3 Playback",991.trigger = {992SND_SOC_DPCM_TRIGGER_POST,993SND_SOC_DPCM_TRIGGER_POST,994},995.dynamic = 1,996.playback_only = 1,997.dpcm_merged_chan = 1,998.dpcm_merged_rate = 1,999.dpcm_merged_format = 1,1000SND_SOC_DAILINK_REG(playback3),1001},1002[DAI_LINK_DL6_FE] = {1003.name = "DL6_FE",1004.stream_name = "DL6 Playback",1005.trigger = {1006SND_SOC_DPCM_TRIGGER_POST,1007SND_SOC_DPCM_TRIGGER_POST,1008},1009.dynamic = 1,1010.playback_only = 1,1011.dpcm_merged_chan = 1,1012.dpcm_merged_rate = 1,1013.dpcm_merged_format = 1,1014SND_SOC_DAILINK_REG(playback6),1015},1016[DAI_LINK_DL7_FE] = {1017.name = "DL7_FE",1018.stream_name = "DL7 Playback",1019.trigger = {1020SND_SOC_DPCM_TRIGGER_PRE,1021SND_SOC_DPCM_TRIGGER_PRE,1022},1023.dynamic = 1,1024.playback_only = 1,1025SND_SOC_DAILINK_REG(playback7),1026},1027[DAI_LINK_DL8_FE] = {1028.name = "DL8_FE",1029.stream_name = "DL8 Playback",1030.trigger = {1031SND_SOC_DPCM_TRIGGER_POST,1032SND_SOC_DPCM_TRIGGER_POST,1033},1034.dynamic = 1,1035.playback_only = 1,1036SND_SOC_DAILINK_REG(playback8),1037},1038[DAI_LINK_DL10_FE] = {1039.name = "DL10_FE",1040.stream_name = "DL10 Playback",1041.trigger = {1042SND_SOC_DPCM_TRIGGER_POST,1043SND_SOC_DPCM_TRIGGER_POST,1044},1045.dynamic = 1,1046.playback_only = 1,1047SND_SOC_DAILINK_REG(playback10),1048},1049[DAI_LINK_DL11_FE] = {1050.name = "DL11_FE",1051.stream_name = "DL11 Playback",1052.trigger = {1053SND_SOC_DPCM_TRIGGER_POST,1054SND_SOC_DPCM_TRIGGER_POST,1055},1056.dynamic = 1,1057.playback_only = 1,1058SND_SOC_DAILINK_REG(playback11),1059},1060[DAI_LINK_UL1_FE] = {1061.name = "UL1_FE",1062.stream_name = "UL1 Capture",1063.trigger = {1064SND_SOC_DPCM_TRIGGER_PRE,1065SND_SOC_DPCM_TRIGGER_PRE,1066},1067.dynamic = 1,1068.capture_only = 1,1069SND_SOC_DAILINK_REG(capture1),1070},1071[DAI_LINK_UL2_FE] = {1072.name = "UL2_FE",1073.stream_name = "UL2 Capture",1074.trigger = {1075SND_SOC_DPCM_TRIGGER_POST,1076SND_SOC_DPCM_TRIGGER_POST,1077},1078.dynamic = 1,1079.capture_only = 1,1080SND_SOC_DAILINK_REG(capture2),1081},1082[DAI_LINK_UL3_FE] = {1083.name = "UL3_FE",1084.stream_name = "UL3 Capture",1085.trigger = {1086SND_SOC_DPCM_TRIGGER_POST,1087SND_SOC_DPCM_TRIGGER_POST,1088},1089.dynamic = 1,1090.capture_only = 1,1091SND_SOC_DAILINK_REG(capture3),1092},1093[DAI_LINK_UL4_FE] = {1094.name = "UL4_FE",1095.stream_name = "UL4 Capture",1096.trigger = {1097SND_SOC_DPCM_TRIGGER_POST,1098SND_SOC_DPCM_TRIGGER_POST,1099},1100.dynamic = 1,1101.capture_only = 1,1102.dpcm_merged_chan = 1,1103.dpcm_merged_rate = 1,1104.dpcm_merged_format = 1,1105SND_SOC_DAILINK_REG(capture4),1106},1107[DAI_LINK_UL5_FE] = {1108.name = "UL5_FE",1109.stream_name = "UL5 Capture",1110.trigger = {1111SND_SOC_DPCM_TRIGGER_POST,1112SND_SOC_DPCM_TRIGGER_POST,1113},1114.dynamic = 1,1115.capture_only = 1,1116.dpcm_merged_chan = 1,1117.dpcm_merged_rate = 1,1118.dpcm_merged_format = 1,1119SND_SOC_DAILINK_REG(capture5),1120},1121[DAI_LINK_UL6_FE] = {1122.name = "UL6_FE",1123.stream_name = "UL6 Capture",1124.trigger = {1125SND_SOC_DPCM_TRIGGER_PRE,1126SND_SOC_DPCM_TRIGGER_PRE,1127},1128.dynamic = 1,1129.capture_only = 1,1130SND_SOC_DAILINK_REG(capture6),1131},1132[DAI_LINK_UL8_FE] = {1133.name = "UL8_FE",1134.stream_name = "UL8 Capture",1135.trigger = {1136SND_SOC_DPCM_TRIGGER_POST,1137SND_SOC_DPCM_TRIGGER_POST,1138},1139.dynamic = 1,1140.capture_only = 1,1141SND_SOC_DAILINK_REG(capture8),1142},1143[DAI_LINK_UL9_FE] = {1144.name = "UL9_FE",1145.stream_name = "UL9 Capture",1146.trigger = {1147SND_SOC_DPCM_TRIGGER_POST,1148SND_SOC_DPCM_TRIGGER_POST,1149},1150.dynamic = 1,1151.capture_only = 1,1152SND_SOC_DAILINK_REG(capture9),1153},1154[DAI_LINK_UL10_FE] = {1155.name = "UL10_FE",1156.stream_name = "UL10 Capture",1157.trigger = {1158SND_SOC_DPCM_TRIGGER_POST,1159SND_SOC_DPCM_TRIGGER_POST,1160},1161.dynamic = 1,1162.capture_only = 1,1163SND_SOC_DAILINK_REG(capture10),1164},1165/* BE */1166[DAI_LINK_DL_SRC_BE] = {1167.name = "DL_SRC_BE",1168.no_pcm = 1,1169.playback_only = 1,1170SND_SOC_DAILINK_REG(dl_src),1171},1172[DAI_LINK_DMIC_BE] = {1173.name = "DMIC_BE",1174.no_pcm = 1,1175.capture_only = 1,1176.ignore_suspend = 1,1177SND_SOC_DAILINK_REG(DMIC_BE),1178},1179[DAI_LINK_DPTX_BE] = {1180.name = "DPTX_BE",1181.ops = &mt8188_dptx_ops,1182.be_hw_params_fixup = mt8188_dptx_hw_params_fixup,1183.no_pcm = 1,1184.playback_only = 1,1185SND_SOC_DAILINK_REG(dptx),1186},1187[DAI_LINK_ETDM1_IN_BE] = {1188.name = "ETDM1_IN_BE",1189.no_pcm = 1,1190.dai_fmt = SND_SOC_DAIFMT_I2S |1191SND_SOC_DAIFMT_NB_NF |1192SND_SOC_DAIFMT_CBP_CFP,1193.capture_only = 1,1194.ignore_suspend = 1,1195SND_SOC_DAILINK_REG(etdm1_in),1196},1197[DAI_LINK_ETDM2_IN_BE] = {1198.name = "ETDM2_IN_BE",1199.no_pcm = 1,1200.dai_fmt = SND_SOC_DAIFMT_I2S |1201SND_SOC_DAIFMT_NB_NF |1202SND_SOC_DAIFMT_CBP_CFP,1203.capture_only = 1,1204SND_SOC_DAILINK_REG(etdm2_in),1205},1206[DAI_LINK_ETDM1_OUT_BE] = {1207.name = "ETDM1_OUT_BE",1208.no_pcm = 1,1209.dai_fmt = SND_SOC_DAIFMT_I2S |1210SND_SOC_DAIFMT_NB_NF |1211SND_SOC_DAIFMT_CBC_CFC,1212.playback_only = 1,1213SND_SOC_DAILINK_REG(etdm1_out),1214},1215[DAI_LINK_ETDM2_OUT_BE] = {1216.name = "ETDM2_OUT_BE",1217.no_pcm = 1,1218.dai_fmt = SND_SOC_DAIFMT_I2S |1219SND_SOC_DAIFMT_NB_NF |1220SND_SOC_DAIFMT_CBC_CFC,1221.playback_only = 1,1222SND_SOC_DAILINK_REG(etdm2_out),1223},1224[DAI_LINK_ETDM3_OUT_BE] = {1225.name = "ETDM3_OUT_BE",1226.no_pcm = 1,1227.dai_fmt = SND_SOC_DAIFMT_I2S |1228SND_SOC_DAIFMT_NB_NF |1229SND_SOC_DAIFMT_CBC_CFC,1230.playback_only = 1,1231SND_SOC_DAILINK_REG(etdm3_out),1232},1233[DAI_LINK_PCM1_BE] = {1234.name = "PCM1_BE",1235.no_pcm = 1,1236.dai_fmt = SND_SOC_DAIFMT_I2S |1237SND_SOC_DAIFMT_NB_NF |1238SND_SOC_DAIFMT_CBC_CFC,1239SND_SOC_DAILINK_REG(pcm1),1240},1241[DAI_LINK_UL_SRC_BE] = {1242.name = "UL_SRC_BE",1243.no_pcm = 1,1244.capture_only = 1,1245SND_SOC_DAILINK_REG(ul_src),1246},12471248/* SOF BE */1249[DAI_LINK_SOF_DL2_BE] = {1250.name = "AFE_SOF_DL2",1251.no_pcm = 1,1252.playback_only = 1,1253.ops = &mt8188_sof_be_ops,1254SND_SOC_DAILINK_REG(AFE_SOF_DL2),1255},1256[DAI_LINK_SOF_DL3_BE] = {1257.name = "AFE_SOF_DL3",1258.no_pcm = 1,1259.playback_only = 1,1260.ops = &mt8188_sof_be_ops,1261SND_SOC_DAILINK_REG(AFE_SOF_DL3),1262},1263[DAI_LINK_SOF_UL4_BE] = {1264.name = "AFE_SOF_UL4",1265.no_pcm = 1,1266.capture_only = 1,1267.ops = &mt8188_sof_be_ops,1268SND_SOC_DAILINK_REG(AFE_SOF_UL4),1269},1270[DAI_LINK_SOF_UL5_BE] = {1271.name = "AFE_SOF_UL5",1272.no_pcm = 1,1273.capture_only = 1,1274.ops = &mt8188_sof_be_ops,1275SND_SOC_DAILINK_REG(AFE_SOF_UL5),1276},1277};12781279static void mt8188_fixup_controls(struct snd_soc_card *card)1280{1281struct mtk_soc_card_data *soc_card_data = snd_soc_card_get_drvdata(card);1282struct mtk_platform_card_data *card_data = soc_card_data->card_data;1283struct snd_kcontrol *kctl;12841285if (card_data->flags & (NAU8825_HS_PRESENT | RT5682S_HS_PRESENT | ES8326_HS_PRESENT)) {1286struct snd_soc_dapm_widget *w, *next_w;12871288for_each_card_widgets_safe(card, w, next_w) {1289if (strcmp(w->name, "Headphone"))1290continue;12911292snd_soc_dapm_free_widget(w);1293}12941295kctl = snd_ctl_find_id_mixer(card->snd_card, "Headphone Switch");1296if (kctl)1297snd_ctl_remove(card->snd_card, kctl);1298else1299dev_warn(card->dev, "Cannot find ctl : Headphone Switch\n");1300}1301}13021303static struct snd_soc_card mt8188_mt6359_soc_card = {1304.owner = THIS_MODULE,1305.dai_link = mt8188_mt6359_dai_links,1306.num_links = ARRAY_SIZE(mt8188_mt6359_dai_links),1307.dapm_widgets = mt8188_mt6359_widgets,1308.num_dapm_widgets = ARRAY_SIZE(mt8188_mt6359_widgets),1309.dapm_routes = mt8188_mt6359_routes,1310.num_dapm_routes = ARRAY_SIZE(mt8188_mt6359_routes),1311.controls = mt8188_mt6359_controls,1312.num_controls = ARRAY_SIZE(mt8188_mt6359_controls),1313.fixup_controls = mt8188_fixup_controls,1314};13151316static int mt8188_mt6359_soc_card_probe(struct mtk_soc_card_data *soc_card_data, bool legacy)1317{1318struct mtk_platform_card_data *card_data = soc_card_data->card_data;1319struct snd_soc_card *card = soc_card_data->card_data->card;1320struct snd_soc_dai_link *dai_link;1321bool init_mt6359 = false;1322bool init_es8326 = false;1323bool init_nau8825 = false;1324bool init_rt5682s = false;1325bool init_max98390 = false;1326bool init_dumb = false;1327int i;13281329if (legacy)1330return -EINVAL;13311332for_each_card_prelinks(card, i, dai_link) {1333if (strcmp(dai_link->name, "DPTX_BE") == 0) {1334if (dai_link->num_codecs &&1335!snd_soc_dlc_is_dummy(dai_link->codecs))1336dai_link->init = mt8188_dptx_codec_init;1337} else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) {1338if (dai_link->num_codecs &&1339!snd_soc_dlc_is_dummy(dai_link->codecs))1340dai_link->init = mt8188_hdmi_codec_init;1341} else if (strcmp(dai_link->name, "DL_SRC_BE") == 0 ||1342strcmp(dai_link->name, "UL_SRC_BE") == 0) {1343if (!init_mt6359) {1344dai_link->init = mt8188_mt6359_init;1345init_mt6359 = true;1346}1347} else if (strcmp(dai_link->name, "ETDM1_OUT_BE") == 0 ||1348strcmp(dai_link->name, "ETDM2_OUT_BE") == 0 ||1349strcmp(dai_link->name, "ETDM1_IN_BE") == 0 ||1350strcmp(dai_link->name, "ETDM2_IN_BE") == 0) {1351if (!dai_link->num_codecs)1352continue;13531354if (!strcmp(dai_link->codecs->dai_name, MAX98390_CODEC_DAI)) {1355/*1356* The TDM protocol settings with fixed 4 slots are defined in1357* mt8188_max98390_ops. Two amps is I2S mode,1358* SOC and codec don't require TDM settings.1359*/1360if (!(card_data->flags & MAX98390_TWO_AMP)) {1361dai_link->ops = &mt8188_max98390_ops;1362}1363if (!init_max98390) {1364dai_link->init = mt8188_max98390_codec_init;1365init_max98390 = true;1366}1367} else if (!strcmp(dai_link->codecs->dai_name, NAU8825_CODEC_DAI)) {1368dai_link->ops = &mt8188_nau8825_ops;1369if (!init_nau8825) {1370dai_link->init = mt8188_headset_codec_init;1371dai_link->exit = mt8188_headset_codec_exit;1372init_nau8825 = true;1373}1374} else if (!strcmp(dai_link->codecs->dai_name, RT5682S_CODEC_DAI)) {1375dai_link->ops = &mt8188_rt5682s_i2s_ops;1376if (!init_rt5682s) {1377dai_link->init = mt8188_headset_codec_init;1378dai_link->exit = mt8188_headset_codec_exit;1379init_rt5682s = true;1380}1381} else if (!strcmp(dai_link->codecs->dai_name, ES8326_CODEC_DAI)) {1382dai_link->ops = &mt8188_es8326_ops;1383if (!init_es8326) {1384dai_link->init = mt8188_headset_codec_init;1385dai_link->exit = mt8188_headset_codec_exit;1386init_es8326 = true;1387}1388} else {1389if (!snd_soc_dlc_is_dummy(dai_link->codecs)) {1390if (!init_dumb) {1391dai_link->init = mt8188_dumb_amp_init;1392init_dumb = true;1393}1394}1395}1396}1397}13981399return 0;1400}14011402static const struct mtk_sof_priv mt8188_sof_priv = {1403.conn_streams = g_sof_conn_streams,1404.num_streams = ARRAY_SIZE(g_sof_conn_streams),1405};14061407static const struct mtk_soundcard_pdata mt8188_evb_card = {1408.card_name = "mt8188_mt6359",1409.card_data = &(struct mtk_platform_card_data) {1410.card = &mt8188_mt6359_soc_card,1411.num_jacks = MT8188_JACK_MAX,1412},1413.sof_priv = &mt8188_sof_priv,1414.soc_probe = mt8188_mt6359_soc_card_probe,1415};14161417static const struct mtk_soundcard_pdata mt8188_nau8825_card = {1418.card_name = "mt8188_nau8825",1419.card_data = &(struct mtk_platform_card_data) {1420.card = &mt8188_mt6359_soc_card,1421.num_jacks = MT8188_JACK_MAX,1422.flags = NAU8825_HS_PRESENT1423},1424.sof_priv = &mt8188_sof_priv,1425.soc_probe = mt8188_mt6359_soc_card_probe,1426};14271428static const struct mtk_soundcard_pdata mt8188_rt5682s_card = {1429.card_name = "mt8188_rt5682s",1430.card_data = &(struct mtk_platform_card_data) {1431.card = &mt8188_mt6359_soc_card,1432.num_jacks = MT8188_JACK_MAX,1433.flags = RT5682S_HS_PRESENT | MAX98390_TWO_AMP1434},1435.sof_priv = &mt8188_sof_priv,1436.soc_probe = mt8188_mt6359_soc_card_probe,1437};14381439static const struct mtk_soundcard_pdata mt8188_es8326_card = {1440.card_name = "mt8188_es8326",1441.card_data = &(struct mtk_platform_card_data) {1442.card = &mt8188_mt6359_soc_card,1443.num_jacks = MT8188_JACK_MAX,1444.flags = ES8326_HS_PRESENT | MAX98390_TWO_AMP1445},1446.sof_priv = &mt8188_sof_priv,1447.soc_probe = mt8188_mt6359_soc_card_probe,1448};14491450static const struct of_device_id mt8188_mt6359_dt_match[] = {1451{ .compatible = "mediatek,mt8188-mt6359-evb", .data = &mt8188_evb_card, },1452{ .compatible = "mediatek,mt8188-nau8825", .data = &mt8188_nau8825_card, },1453{ .compatible = "mediatek,mt8188-rt5682s", .data = &mt8188_rt5682s_card, },1454{ .compatible = "mediatek,mt8188-es8326", .data = &mt8188_es8326_card, },1455{ /* sentinel */ },1456};1457MODULE_DEVICE_TABLE(of, mt8188_mt6359_dt_match);14581459static struct platform_driver mt8188_mt6359_driver = {1460.driver = {1461.name = "mt8188_mt6359",1462.of_match_table = mt8188_mt6359_dt_match,1463.pm = &snd_soc_pm_ops,1464},1465.probe = mtk_soundcard_common_probe,1466};14671468module_platform_driver(mt8188_mt6359_driver);14691470/* Module information */1471MODULE_DESCRIPTION("MT8188-MT6359 ALSA SoC machine driver");1472MODULE_AUTHOR("Trevor Wu <[email protected]>");1473MODULE_LICENSE("GPL");1474MODULE_ALIAS("mt8188 mt6359 soc card");147514761477