2717 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * MediaTek ALSA SoC Audio DAI eTDM Control4 *5 * Copyright (c) 2022 MediaTek Inc.6 * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>7 * Trevor Wu <trevor.wu@mediatek.com>8 * Chun-Chia Chiu <chun-chia.chiu@mediatek.com>9 */10 11#include <linux/bitfield.h>12#include <linux/pm_runtime.h>13#include <linux/regmap.h>14#include <sound/pcm_params.h>15#include "mt8188-afe-clk.h"16#include "mt8188-afe-common.h"17#include "mt8188-reg.h"18 19#define MT8188_ETDM_MAX_CHANNELS 1620#define MT8188_ETDM_NORMAL_MAX_BCK_RATE 2457600021#define ETDM_TO_DAI_ID(x) ((x) + MT8188_AFE_IO_ETDM_START)22#define ENUM_TO_STR(x) #x23 24enum {25 SUPPLY_SEQ_APLL,26 SUPPLY_SEQ_ETDM_MCLK,27 SUPPLY_SEQ_ETDM_CG,28 SUPPLY_SEQ_DPTX_EN,29 SUPPLY_SEQ_ETDM_EN,30};31 32enum {33 MTK_DAI_ETDM_FORMAT_I2S = 0,34 MTK_DAI_ETDM_FORMAT_LJ,35 MTK_DAI_ETDM_FORMAT_RJ,36 MTK_DAI_ETDM_FORMAT_EIAJ,37 MTK_DAI_ETDM_FORMAT_DSPA,38 MTK_DAI_ETDM_FORMAT_DSPB,39};40 41enum {42 MTK_DAI_ETDM_DATA_ONE_PIN = 0,43 MTK_DAI_ETDM_DATA_MULTI_PIN,44};45 46enum {47 ETDM_IN,48 ETDM_OUT,49};50 51enum {52 COWORK_ETDM_NONE = 0,53 COWORK_ETDM_IN1_M = 2,54 COWORK_ETDM_IN1_S = 3,55 COWORK_ETDM_IN2_M = 4,56 COWORK_ETDM_IN2_S = 5,57 COWORK_ETDM_OUT1_M = 10,58 COWORK_ETDM_OUT1_S = 11,59 COWORK_ETDM_OUT2_M = 12,60 COWORK_ETDM_OUT2_S = 13,61 COWORK_ETDM_OUT3_M = 14,62 COWORK_ETDM_OUT3_S = 15,63};64 65enum {66 ETDM_RELATCH_TIMING_A1A2SYS,67 ETDM_RELATCH_TIMING_A3SYS,68 ETDM_RELATCH_TIMING_A4SYS,69};70 71enum {72 ETDM_SYNC_NONE,73 ETDM_SYNC_FROM_IN1 = 2,74 ETDM_SYNC_FROM_IN2 = 4,75 ETDM_SYNC_FROM_OUT1 = 10,76 ETDM_SYNC_FROM_OUT2 = 12,77 ETDM_SYNC_FROM_OUT3 = 14,78};79 80struct etdm_con_reg {81 unsigned int con0;82 unsigned int con1;83 unsigned int con2;84 unsigned int con3;85 unsigned int con4;86 unsigned int con5;87};88 89struct mtk_dai_etdm_rate {90 unsigned int rate;91 unsigned int reg_value;92};93 94struct mtk_dai_etdm_priv {95 unsigned int data_mode;96 bool slave_mode;97 bool lrck_inv;98 bool bck_inv;99 unsigned int rate;100 unsigned int format;101 unsigned int slots;102 unsigned int lrck_width;103 unsigned int mclk_freq;104 unsigned int mclk_fixed_apll;105 unsigned int mclk_apll;106 unsigned int mclk_dir;107 int cowork_source_id; //dai id108 unsigned int cowork_slv_count;109 int cowork_slv_id[MT8188_AFE_IO_ETDM_NUM - 1]; //dai_id110 bool in_disable_ch[MT8188_ETDM_MAX_CHANNELS];111};112 113static const struct mtk_dai_etdm_rate mt8188_etdm_rates[] = {114 { .rate = 8000, .reg_value = 0, },115 { .rate = 12000, .reg_value = 1, },116 { .rate = 16000, .reg_value = 2, },117 { .rate = 24000, .reg_value = 3, },118 { .rate = 32000, .reg_value = 4, },119 { .rate = 48000, .reg_value = 5, },120 { .rate = 96000, .reg_value = 7, },121 { .rate = 192000, .reg_value = 9, },122 { .rate = 384000, .reg_value = 11, },123 { .rate = 11025, .reg_value = 16, },124 { .rate = 22050, .reg_value = 17, },125 { .rate = 44100, .reg_value = 18, },126 { .rate = 88200, .reg_value = 19, },127 { .rate = 176400, .reg_value = 20, },128 { .rate = 352800, .reg_value = 21, },129};130 131static int get_etdm_fs_timing(unsigned int rate)132{133 int i;134 135 for (i = 0; i < ARRAY_SIZE(mt8188_etdm_rates); i++)136 if (mt8188_etdm_rates[i].rate == rate)137 return mt8188_etdm_rates[i].reg_value;138 139 return -EINVAL;140}141 142static unsigned int get_etdm_ch_fixup(unsigned int channels)143{144 if (channels > 16)145 return 24;146 else if (channels > 8)147 return 16;148 else if (channels > 4)149 return 8;150 else if (channels > 2)151 return 4;152 else153 return 2;154}155 156static int get_etdm_reg(unsigned int dai_id, struct etdm_con_reg *etdm_reg)157{158 switch (dai_id) {159 case MT8188_AFE_IO_ETDM1_IN:160 etdm_reg->con0 = ETDM_IN1_CON0;161 etdm_reg->con1 = ETDM_IN1_CON1;162 etdm_reg->con2 = ETDM_IN1_CON2;163 etdm_reg->con3 = ETDM_IN1_CON3;164 etdm_reg->con4 = ETDM_IN1_CON4;165 etdm_reg->con5 = ETDM_IN1_CON5;166 break;167 case MT8188_AFE_IO_ETDM2_IN:168 etdm_reg->con0 = ETDM_IN2_CON0;169 etdm_reg->con1 = ETDM_IN2_CON1;170 etdm_reg->con2 = ETDM_IN2_CON2;171 etdm_reg->con3 = ETDM_IN2_CON3;172 etdm_reg->con4 = ETDM_IN2_CON4;173 etdm_reg->con5 = ETDM_IN2_CON5;174 break;175 case MT8188_AFE_IO_ETDM1_OUT:176 etdm_reg->con0 = ETDM_OUT1_CON0;177 etdm_reg->con1 = ETDM_OUT1_CON1;178 etdm_reg->con2 = ETDM_OUT1_CON2;179 etdm_reg->con3 = ETDM_OUT1_CON3;180 etdm_reg->con4 = ETDM_OUT1_CON4;181 etdm_reg->con5 = ETDM_OUT1_CON5;182 break;183 case MT8188_AFE_IO_ETDM2_OUT:184 etdm_reg->con0 = ETDM_OUT2_CON0;185 etdm_reg->con1 = ETDM_OUT2_CON1;186 etdm_reg->con2 = ETDM_OUT2_CON2;187 etdm_reg->con3 = ETDM_OUT2_CON3;188 etdm_reg->con4 = ETDM_OUT2_CON4;189 etdm_reg->con5 = ETDM_OUT2_CON5;190 break;191 case MT8188_AFE_IO_ETDM3_OUT:192 case MT8188_AFE_IO_DPTX:193 etdm_reg->con0 = ETDM_OUT3_CON0;194 etdm_reg->con1 = ETDM_OUT3_CON1;195 etdm_reg->con2 = ETDM_OUT3_CON2;196 etdm_reg->con3 = ETDM_OUT3_CON3;197 etdm_reg->con4 = ETDM_OUT3_CON4;198 etdm_reg->con5 = ETDM_OUT3_CON5;199 break;200 default:201 return -EINVAL;202 }203 return 0;204}205 206static int get_etdm_dir(unsigned int dai_id)207{208 switch (dai_id) {209 case MT8188_AFE_IO_ETDM1_IN:210 case MT8188_AFE_IO_ETDM2_IN:211 return ETDM_IN;212 case MT8188_AFE_IO_ETDM1_OUT:213 case MT8188_AFE_IO_ETDM2_OUT:214 case MT8188_AFE_IO_ETDM3_OUT:215 return ETDM_OUT;216 default:217 return -EINVAL;218 }219}220 221static int get_etdm_wlen(unsigned int bitwidth)222{223 return bitwidth <= 16 ? 16 : 32;224}225 226static bool is_valid_etdm_dai(int dai_id)227{228 switch (dai_id) {229 case MT8188_AFE_IO_ETDM1_IN:230 fallthrough;231 case MT8188_AFE_IO_ETDM2_IN:232 fallthrough;233 case MT8188_AFE_IO_ETDM1_OUT:234 fallthrough;235 case MT8188_AFE_IO_ETDM2_OUT:236 fallthrough;237 case MT8188_AFE_IO_DPTX:238 fallthrough;239 case MT8188_AFE_IO_ETDM3_OUT:240 return true;241 default:242 return false;243 }244}245 246static int is_cowork_mode(struct snd_soc_dai *dai)247{248 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);249 struct mt8188_afe_private *afe_priv = afe->platform_priv;250 struct mtk_dai_etdm_priv *etdm_data;251 252 if (!is_valid_etdm_dai(dai->id))253 return -EINVAL;254 etdm_data = afe_priv->dai_priv[dai->id];255 256 return (etdm_data->cowork_slv_count > 0 ||257 etdm_data->cowork_source_id != COWORK_ETDM_NONE);258}259 260static int sync_to_dai_id(int source_sel)261{262 switch (source_sel) {263 case ETDM_SYNC_FROM_IN1:264 return MT8188_AFE_IO_ETDM1_IN;265 case ETDM_SYNC_FROM_IN2:266 return MT8188_AFE_IO_ETDM2_IN;267 case ETDM_SYNC_FROM_OUT1:268 return MT8188_AFE_IO_ETDM1_OUT;269 case ETDM_SYNC_FROM_OUT2:270 return MT8188_AFE_IO_ETDM2_OUT;271 case ETDM_SYNC_FROM_OUT3:272 return MT8188_AFE_IO_ETDM3_OUT;273 default:274 return 0;275 }276}277 278static int get_etdm_cowork_master_id(struct snd_soc_dai *dai)279{280 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);281 struct mt8188_afe_private *afe_priv = afe->platform_priv;282 struct mtk_dai_etdm_priv *etdm_data;283 int dai_id;284 285 if (!is_valid_etdm_dai(dai->id))286 return -EINVAL;287 etdm_data = afe_priv->dai_priv[dai->id];288 dai_id = etdm_data->cowork_source_id;289 290 if (dai_id == COWORK_ETDM_NONE)291 dai_id = dai->id;292 293 return dai_id;294}295 296static int mtk_dai_etdm_get_cg_id_by_dai_id(int dai_id)297{298 switch (dai_id) {299 case MT8188_AFE_IO_DPTX:300 return MT8188_CLK_AUD_HDMI_OUT;301 case MT8188_AFE_IO_ETDM1_IN:302 return MT8188_CLK_AUD_TDM_IN;303 case MT8188_AFE_IO_ETDM2_IN:304 return MT8188_CLK_AUD_I2SIN;305 case MT8188_AFE_IO_ETDM1_OUT:306 return MT8188_CLK_AUD_TDM_OUT;307 case MT8188_AFE_IO_ETDM2_OUT:308 return MT8188_CLK_AUD_I2S_OUT;309 case MT8188_AFE_IO_ETDM3_OUT:310 return MT8188_CLK_AUD_HDMI_OUT;311 default:312 return -EINVAL;313 }314}315 316static int mtk_dai_etdm_get_clk_id_by_dai_id(int dai_id)317{318 switch (dai_id) {319 case MT8188_AFE_IO_DPTX:320 return MT8188_CLK_TOP_DPTX_M_SEL;321 case MT8188_AFE_IO_ETDM1_IN:322 return MT8188_CLK_TOP_I2SI1_M_SEL;323 case MT8188_AFE_IO_ETDM2_IN:324 return MT8188_CLK_TOP_I2SI2_M_SEL;325 case MT8188_AFE_IO_ETDM1_OUT:326 return MT8188_CLK_TOP_I2SO1_M_SEL;327 case MT8188_AFE_IO_ETDM2_OUT:328 return MT8188_CLK_TOP_I2SO2_M_SEL;329 case MT8188_AFE_IO_ETDM3_OUT:330 default:331 return -EINVAL;332 }333}334 335static int mtk_dai_etdm_get_clkdiv_id_by_dai_id(int dai_id)336{337 switch (dai_id) {338 case MT8188_AFE_IO_DPTX:339 return MT8188_CLK_TOP_APLL12_DIV9;340 case MT8188_AFE_IO_ETDM1_IN:341 return MT8188_CLK_TOP_APLL12_DIV0;342 case MT8188_AFE_IO_ETDM2_IN:343 return MT8188_CLK_TOP_APLL12_DIV1;344 case MT8188_AFE_IO_ETDM1_OUT:345 return MT8188_CLK_TOP_APLL12_DIV2;346 case MT8188_AFE_IO_ETDM2_OUT:347 return MT8188_CLK_TOP_APLL12_DIV3;348 case MT8188_AFE_IO_ETDM3_OUT:349 default:350 return -EINVAL;351 }352}353 354static int get_etdm_id_by_name(struct mtk_base_afe *afe,355 const char *name)356{357 if (!strncmp(name, "ETDM1_IN", strlen("ETDM1_IN")))358 return MT8188_AFE_IO_ETDM1_IN;359 else if (!strncmp(name, "ETDM2_IN", strlen("ETDM2_IN")))360 return MT8188_AFE_IO_ETDM2_IN;361 else if (!strncmp(name, "ETDM1_OUT", strlen("ETDM1_OUT")))362 return MT8188_AFE_IO_ETDM1_OUT;363 else if (!strncmp(name, "ETDM2_OUT", strlen("ETDM2_OUT")))364 return MT8188_AFE_IO_ETDM2_OUT;365 else if (!strncmp(name, "ETDM3_OUT", strlen("ETDM3_OUT")))366 return MT8188_AFE_IO_ETDM3_OUT;367 else if (!strncmp(name, "DPTX", strlen("DPTX")))368 return MT8188_AFE_IO_ETDM3_OUT;369 else370 return -EINVAL;371}372 373static struct mtk_dai_etdm_priv *get_etdm_priv_by_name(struct mtk_base_afe *afe,374 const char *name)375{376 struct mt8188_afe_private *afe_priv = afe->platform_priv;377 int dai_id = get_etdm_id_by_name(afe, name);378 379 if (dai_id < MT8188_AFE_IO_ETDM_START ||380 dai_id >= MT8188_AFE_IO_ETDM_END)381 return NULL;382 383 return afe_priv->dai_priv[dai_id];384}385 386static int mtk_dai_etdm_enable_mclk(struct mtk_base_afe *afe, int dai_id)387{388 struct mt8188_afe_private *afe_priv = afe->platform_priv;389 struct mtk_dai_etdm_priv *etdm_data;390 struct etdm_con_reg etdm_reg;391 unsigned int val = 0;392 unsigned int mask;393 int clkmux_id = mtk_dai_etdm_get_clk_id_by_dai_id(dai_id);394 int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id);395 int apll_clk_id;396 int apll;397 int ret;398 399 if (!is_valid_etdm_dai(dai_id))400 return -EINVAL;401 etdm_data = afe_priv->dai_priv[dai_id];402 403 apll = etdm_data->mclk_apll;404 apll_clk_id = mt8188_afe_get_mclk_source_clk_id(apll);405 406 if (clkmux_id < 0 || clkdiv_id < 0)407 return -EINVAL;408 409 if (apll_clk_id < 0)410 return apll_clk_id;411 412 ret = get_etdm_reg(dai_id, &etdm_reg);413 if (ret < 0)414 return ret;415 416 mask = ETDM_CON1_MCLK_OUTPUT;417 if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT)418 val = ETDM_CON1_MCLK_OUTPUT;419 regmap_update_bits(afe->regmap, etdm_reg.con1, mask, val);420 421 /* enable parent clock before select apll*/422 mt8188_afe_enable_clk(afe, afe_priv->clk[clkmux_id]);423 424 /* select apll */425 ret = mt8188_afe_set_clk_parent(afe, afe_priv->clk[clkmux_id],426 afe_priv->clk[apll_clk_id]);427 if (ret)428 return ret;429 430 /* set rate */431 ret = mt8188_afe_set_clk_rate(afe, afe_priv->clk[clkdiv_id],432 etdm_data->mclk_freq);433 434 mt8188_afe_enable_clk(afe, afe_priv->clk[clkdiv_id]);435 436 return 0;437}438 439static int mtk_dai_etdm_disable_mclk(struct mtk_base_afe *afe, int dai_id)440{441 struct mt8188_afe_private *afe_priv = afe->platform_priv;442 int clkmux_id = mtk_dai_etdm_get_clk_id_by_dai_id(dai_id);443 int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id);444 445 if (clkmux_id < 0 || clkdiv_id < 0)446 return -EINVAL;447 448 mt8188_afe_disable_clk(afe, afe_priv->clk[clkdiv_id]);449 mt8188_afe_disable_clk(afe, afe_priv->clk[clkmux_id]);450 451 return 0;452}453 454static int mtk_afe_etdm_apll_connect(struct snd_soc_dapm_widget *source,455 struct snd_soc_dapm_widget *sink)456{457 struct snd_soc_dapm_widget *w = sink;458 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);459 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);460 struct mtk_dai_etdm_priv *etdm_priv;461 int cur_apll;462 int need_apll;463 464 etdm_priv = get_etdm_priv_by_name(afe, w->name);465 if (!etdm_priv) {466 dev_dbg(afe->dev, "etdm_priv == NULL\n");467 return 0;468 }469 470 cur_apll = mt8188_get_apll_by_name(afe, source->name);471 need_apll = mt8188_get_apll_by_rate(afe, etdm_priv->rate);472 473 return (need_apll == cur_apll) ? 1 : 0;474}475 476static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source,477 struct snd_soc_dapm_widget *sink)478{479 struct snd_soc_dapm_widget *w = sink;480 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);481 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);482 struct mtk_dai_etdm_priv *etdm_priv;483 int cur_apll;484 485 etdm_priv = get_etdm_priv_by_name(afe, w->name);486 487 cur_apll = mt8188_get_apll_by_name(afe, source->name);488 489 return (etdm_priv->mclk_apll == cur_apll) ? 1 : 0;490}491 492static int mtk_etdm_mclk_connect(struct snd_soc_dapm_widget *source,493 struct snd_soc_dapm_widget *sink)494{495 struct snd_soc_dapm_widget *w = sink;496 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);497 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);498 struct mt8188_afe_private *afe_priv = afe->platform_priv;499 struct mtk_dai_etdm_priv *etdm_priv;500 int mclk_id;501 502 mclk_id = get_etdm_id_by_name(afe, source->name);503 if (mclk_id < 0) {504 dev_dbg(afe->dev, "mclk_id < 0\n");505 return 0;506 }507 508 etdm_priv = get_etdm_priv_by_name(afe, w->name);509 if (!etdm_priv) {510 dev_dbg(afe->dev, "etdm_priv == NULL\n");511 return 0;512 }513 514 if (get_etdm_id_by_name(afe, sink->name) == mclk_id)515 return !!(etdm_priv->mclk_freq > 0);516 517 if (etdm_priv->cowork_source_id == mclk_id) {518 etdm_priv = afe_priv->dai_priv[mclk_id];519 return !!(etdm_priv->mclk_freq > 0);520 }521 522 return 0;523}524 525static int mtk_etdm_cowork_connect(struct snd_soc_dapm_widget *source,526 struct snd_soc_dapm_widget *sink)527{528 struct snd_soc_dapm_widget *w = sink;529 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);530 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);531 struct mt8188_afe_private *afe_priv = afe->platform_priv;532 struct mtk_dai_etdm_priv *etdm_priv;533 int source_id;534 int i;535 536 source_id = get_etdm_id_by_name(afe, source->name);537 if (source_id < 0) {538 dev_dbg(afe->dev, "%s() source_id < 0\n", __func__);539 return 0;540 }541 542 etdm_priv = get_etdm_priv_by_name(afe, w->name);543 if (!etdm_priv) {544 dev_dbg(afe->dev, "%s() etdm_priv == NULL\n", __func__);545 return 0;546 }547 548 if (etdm_priv->cowork_source_id != COWORK_ETDM_NONE) {549 if (etdm_priv->cowork_source_id == source_id)550 return 1;551 552 etdm_priv = afe_priv->dai_priv[etdm_priv->cowork_source_id];553 for (i = 0; i < etdm_priv->cowork_slv_count; i++) {554 if (etdm_priv->cowork_slv_id[i] == source_id)555 return 1;556 }557 } else {558 for (i = 0; i < etdm_priv->cowork_slv_count; i++) {559 if (etdm_priv->cowork_slv_id[i] == source_id)560 return 1;561 }562 }563 564 return 0;565}566 567static int mtk_apll_event(struct snd_soc_dapm_widget *w,568 struct snd_kcontrol *kcontrol,569 int event)570{571 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);572 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);573 574 dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",575 __func__, w->name, event);576 577 switch (event) {578 case SND_SOC_DAPM_PRE_PMU:579 if (snd_soc_dapm_widget_name_cmp(w, APLL1_W_NAME) == 0)580 mt8188_apll1_enable(afe);581 else582 mt8188_apll2_enable(afe);583 break;584 case SND_SOC_DAPM_POST_PMD:585 if (snd_soc_dapm_widget_name_cmp(w, APLL1_W_NAME) == 0)586 mt8188_apll1_disable(afe);587 else588 mt8188_apll2_disable(afe);589 break;590 default:591 break;592 }593 594 return 0;595}596 597static int mtk_etdm_mclk_event(struct snd_soc_dapm_widget *w,598 struct snd_kcontrol *kcontrol,599 int event)600{601 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);602 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);603 int mclk_id = get_etdm_id_by_name(afe, w->name);604 605 if (mclk_id < 0) {606 dev_dbg(afe->dev, "%s() mclk_id < 0\n", __func__);607 return 0;608 }609 610 dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",611 __func__, w->name, event);612 613 switch (event) {614 case SND_SOC_DAPM_PRE_PMU:615 mtk_dai_etdm_enable_mclk(afe, mclk_id);616 break;617 case SND_SOC_DAPM_POST_PMD:618 mtk_dai_etdm_disable_mclk(afe, mclk_id);619 break;620 default:621 break;622 }623 624 return 0;625}626 627static int mtk_dptx_mclk_event(struct snd_soc_dapm_widget *w,628 struct snd_kcontrol *kcontrol,629 int event)630{631 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);632 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);633 634 dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",635 __func__, w->name, event);636 637 switch (event) {638 case SND_SOC_DAPM_PRE_PMU:639 mtk_dai_etdm_enable_mclk(afe, MT8188_AFE_IO_DPTX);640 break;641 case SND_SOC_DAPM_POST_PMD:642 mtk_dai_etdm_disable_mclk(afe, MT8188_AFE_IO_DPTX);643 break;644 default:645 break;646 }647 648 return 0;649}650 651static int mtk_etdm_cg_event(struct snd_soc_dapm_widget *w,652 struct snd_kcontrol *kcontrol,653 int event)654{655 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);656 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);657 struct mt8188_afe_private *afe_priv = afe->platform_priv;658 int etdm_id;659 int cg_id;660 661 etdm_id = get_etdm_id_by_name(afe, w->name);662 if (etdm_id < 0) {663 dev_dbg(afe->dev, "%s() etdm_id < 0\n", __func__);664 return 0;665 }666 667 cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(etdm_id);668 if (cg_id < 0) {669 dev_dbg(afe->dev, "%s() cg_id < 0\n", __func__);670 return 0;671 }672 673 dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",674 __func__, w->name, event);675 676 switch (event) {677 case SND_SOC_DAPM_PRE_PMU:678 mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]);679 break;680 case SND_SOC_DAPM_POST_PMD:681 mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]);682 break;683 default:684 break;685 }686 687 return 0;688}689 690static int mtk_etdm3_cg_event(struct snd_soc_dapm_widget *w,691 struct snd_kcontrol *kcontrol,692 int event)693{694 struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);695 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);696 struct mt8188_afe_private *afe_priv = afe->platform_priv;697 698 dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",699 __func__, w->name, event);700 701 switch (event) {702 case SND_SOC_DAPM_PRE_PMU:703 mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_HDMI_OUT]);704 break;705 case SND_SOC_DAPM_POST_PMD:706 mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_HDMI_OUT]);707 break;708 default:709 break;710 }711 712 return 0;713}714 715static const struct snd_kcontrol_new mtk_dai_etdm_o048_mix[] = {716 SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN48, 20, 1, 0),717 SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN48, 22, 1, 0),718 SOC_DAPM_SINGLE_AUTODISABLE("I046 Switch", AFE_CONN48_1, 14, 1, 0),719 SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN48_2, 6, 1, 0),720};721 722static const struct snd_kcontrol_new mtk_dai_etdm_o049_mix[] = {723 SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN49, 21, 1, 0),724 SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN49, 23, 1, 0),725 SOC_DAPM_SINGLE_AUTODISABLE("I047 Switch", AFE_CONN49_1, 15, 1, 0),726 SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN49_2, 7, 1, 0),727};728 729static const struct snd_kcontrol_new mtk_dai_etdm_o050_mix[] = {730 SOC_DAPM_SINGLE_AUTODISABLE("I024 Switch", AFE_CONN50, 24, 1, 0),731 SOC_DAPM_SINGLE_AUTODISABLE("I048 Switch", AFE_CONN50_1, 16, 1, 0),732};733 734static const struct snd_kcontrol_new mtk_dai_etdm_o051_mix[] = {735 SOC_DAPM_SINGLE_AUTODISABLE("I025 Switch", AFE_CONN51, 25, 1, 0),736 SOC_DAPM_SINGLE_AUTODISABLE("I049 Switch", AFE_CONN51_1, 17, 1, 0),737};738 739static const struct snd_kcontrol_new mtk_dai_etdm_o052_mix[] = {740 SOC_DAPM_SINGLE_AUTODISABLE("I026 Switch", AFE_CONN52, 26, 1, 0),741 SOC_DAPM_SINGLE_AUTODISABLE("I050 Switch", AFE_CONN52_1, 18, 1, 0),742};743 744static const struct snd_kcontrol_new mtk_dai_etdm_o053_mix[] = {745 SOC_DAPM_SINGLE_AUTODISABLE("I027 Switch", AFE_CONN53, 27, 1, 0),746 SOC_DAPM_SINGLE_AUTODISABLE("I051 Switch", AFE_CONN53_1, 19, 1, 0),747};748 749static const struct snd_kcontrol_new mtk_dai_etdm_o054_mix[] = {750 SOC_DAPM_SINGLE_AUTODISABLE("I028 Switch", AFE_CONN54, 28, 1, 0),751 SOC_DAPM_SINGLE_AUTODISABLE("I052 Switch", AFE_CONN54_1, 20, 1, 0),752};753 754static const struct snd_kcontrol_new mtk_dai_etdm_o055_mix[] = {755 SOC_DAPM_SINGLE_AUTODISABLE("I029 Switch", AFE_CONN55, 29, 1, 0),756 SOC_DAPM_SINGLE_AUTODISABLE("I053 Switch", AFE_CONN55_1, 21, 1, 0),757};758 759static const struct snd_kcontrol_new mtk_dai_etdm_o056_mix[] = {760 SOC_DAPM_SINGLE_AUTODISABLE("I030 Switch", AFE_CONN56, 30, 1, 0),761 SOC_DAPM_SINGLE_AUTODISABLE("I054 Switch", AFE_CONN56_1, 22, 1, 0),762};763 764static const struct snd_kcontrol_new mtk_dai_etdm_o057_mix[] = {765 SOC_DAPM_SINGLE_AUTODISABLE("I031 Switch", AFE_CONN57, 31, 1, 0),766 SOC_DAPM_SINGLE_AUTODISABLE("I055 Switch", AFE_CONN57_1, 23, 1, 0),767};768 769static const struct snd_kcontrol_new mtk_dai_etdm_o058_mix[] = {770 SOC_DAPM_SINGLE_AUTODISABLE("I032 Switch", AFE_CONN58_1, 0, 1, 0),771 SOC_DAPM_SINGLE_AUTODISABLE("I056 Switch", AFE_CONN58_1, 24, 1, 0),772};773 774static const struct snd_kcontrol_new mtk_dai_etdm_o059_mix[] = {775 SOC_DAPM_SINGLE_AUTODISABLE("I033 Switch", AFE_CONN59_1, 1, 1, 0),776 SOC_DAPM_SINGLE_AUTODISABLE("I057 Switch", AFE_CONN59_1, 25, 1, 0),777};778 779static const struct snd_kcontrol_new mtk_dai_etdm_o060_mix[] = {780 SOC_DAPM_SINGLE_AUTODISABLE("I034 Switch", AFE_CONN60_1, 2, 1, 0),781 SOC_DAPM_SINGLE_AUTODISABLE("I058 Switch", AFE_CONN60_1, 26, 1, 0),782};783 784static const struct snd_kcontrol_new mtk_dai_etdm_o061_mix[] = {785 SOC_DAPM_SINGLE_AUTODISABLE("I035 Switch", AFE_CONN61_1, 3, 1, 0),786 SOC_DAPM_SINGLE_AUTODISABLE("I059 Switch", AFE_CONN61_1, 27, 1, 0),787};788 789static const struct snd_kcontrol_new mtk_dai_etdm_o062_mix[] = {790 SOC_DAPM_SINGLE_AUTODISABLE("I036 Switch", AFE_CONN62_1, 4, 1, 0),791 SOC_DAPM_SINGLE_AUTODISABLE("I060 Switch", AFE_CONN62_1, 28, 1, 0),792};793 794static const struct snd_kcontrol_new mtk_dai_etdm_o063_mix[] = {795 SOC_DAPM_SINGLE_AUTODISABLE("I037 Switch", AFE_CONN63_1, 5, 1, 0),796 SOC_DAPM_SINGLE_AUTODISABLE("I061 Switch", AFE_CONN63_1, 29, 1, 0),797};798 799static const struct snd_kcontrol_new mtk_dai_etdm_o072_mix[] = {800 SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN72, 20, 1, 0),801 SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN72, 22, 1, 0),802 SOC_DAPM_SINGLE_AUTODISABLE("I046 Switch", AFE_CONN72_1, 14, 1, 0),803 SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN72_2, 6, 1, 0),804};805 806static const struct snd_kcontrol_new mtk_dai_etdm_o073_mix[] = {807 SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN73, 21, 1, 0),808 SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN73, 23, 1, 0),809 SOC_DAPM_SINGLE_AUTODISABLE("I047 Switch", AFE_CONN73_1, 15, 1, 0),810 SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN73_2, 7, 1, 0),811};812 813static const struct snd_kcontrol_new mtk_dai_etdm_o074_mix[] = {814 SOC_DAPM_SINGLE_AUTODISABLE("I024 Switch", AFE_CONN74, 24, 1, 0),815 SOC_DAPM_SINGLE_AUTODISABLE("I048 Switch", AFE_CONN74_1, 16, 1, 0),816};817 818static const struct snd_kcontrol_new mtk_dai_etdm_o075_mix[] = {819 SOC_DAPM_SINGLE_AUTODISABLE("I025 Switch", AFE_CONN75, 25, 1, 0),820 SOC_DAPM_SINGLE_AUTODISABLE("I049 Switch", AFE_CONN75_1, 17, 1, 0),821};822 823static const struct snd_kcontrol_new mtk_dai_etdm_o076_mix[] = {824 SOC_DAPM_SINGLE_AUTODISABLE("I026 Switch", AFE_CONN76, 26, 1, 0),825 SOC_DAPM_SINGLE_AUTODISABLE("I050 Switch", AFE_CONN76_1, 18, 1, 0),826};827 828static const struct snd_kcontrol_new mtk_dai_etdm_o077_mix[] = {829 SOC_DAPM_SINGLE_AUTODISABLE("I027 Switch", AFE_CONN77, 27, 1, 0),830 SOC_DAPM_SINGLE_AUTODISABLE("I051 Switch", AFE_CONN77_1, 19, 1, 0),831};832 833static const struct snd_kcontrol_new mtk_dai_etdm_o078_mix[] = {834 SOC_DAPM_SINGLE_AUTODISABLE("I028 Switch", AFE_CONN78, 28, 1, 0),835 SOC_DAPM_SINGLE_AUTODISABLE("I052 Switch", AFE_CONN78_1, 20, 1, 0),836};837 838static const struct snd_kcontrol_new mtk_dai_etdm_o079_mix[] = {839 SOC_DAPM_SINGLE_AUTODISABLE("I029 Switch", AFE_CONN79, 29, 1, 0),840 SOC_DAPM_SINGLE_AUTODISABLE("I053 Switch", AFE_CONN79_1, 21, 1, 0),841};842 843static const struct snd_kcontrol_new mtk_dai_etdm_o080_mix[] = {844 SOC_DAPM_SINGLE_AUTODISABLE("I030 Switch", AFE_CONN80, 30, 1, 0),845 SOC_DAPM_SINGLE_AUTODISABLE("I054 Switch", AFE_CONN80_1, 22, 1, 0),846};847 848static const struct snd_kcontrol_new mtk_dai_etdm_o081_mix[] = {849 SOC_DAPM_SINGLE_AUTODISABLE("I031 Switch", AFE_CONN81, 31, 1, 0),850 SOC_DAPM_SINGLE_AUTODISABLE("I055 Switch", AFE_CONN81_1, 23, 1, 0),851};852 853static const struct snd_kcontrol_new mtk_dai_etdm_o082_mix[] = {854 SOC_DAPM_SINGLE_AUTODISABLE("I032 Switch", AFE_CONN82_1, 0, 1, 0),855 SOC_DAPM_SINGLE_AUTODISABLE("I056 Switch", AFE_CONN82_1, 24, 1, 0),856};857 858static const struct snd_kcontrol_new mtk_dai_etdm_o083_mix[] = {859 SOC_DAPM_SINGLE_AUTODISABLE("I033 Switch", AFE_CONN83_1, 1, 1, 0),860 SOC_DAPM_SINGLE_AUTODISABLE("I057 Switch", AFE_CONN83_1, 25, 1, 0),861};862 863static const struct snd_kcontrol_new mtk_dai_etdm_o084_mix[] = {864 SOC_DAPM_SINGLE_AUTODISABLE("I034 Switch", AFE_CONN84_1, 2, 1, 0),865 SOC_DAPM_SINGLE_AUTODISABLE("I058 Switch", AFE_CONN84_1, 26, 1, 0),866};867 868static const struct snd_kcontrol_new mtk_dai_etdm_o085_mix[] = {869 SOC_DAPM_SINGLE_AUTODISABLE("I035 Switch", AFE_CONN85_1, 3, 1, 0),870 SOC_DAPM_SINGLE_AUTODISABLE("I059 Switch", AFE_CONN85_1, 27, 1, 0),871};872 873static const struct snd_kcontrol_new mtk_dai_etdm_o086_mix[] = {874 SOC_DAPM_SINGLE_AUTODISABLE("I036 Switch", AFE_CONN86_1, 4, 1, 0),875 SOC_DAPM_SINGLE_AUTODISABLE("I060 Switch", AFE_CONN86_1, 28, 1, 0),876};877 878static const struct snd_kcontrol_new mtk_dai_etdm_o087_mix[] = {879 SOC_DAPM_SINGLE_AUTODISABLE("I037 Switch", AFE_CONN87_1, 5, 1, 0),880 SOC_DAPM_SINGLE_AUTODISABLE("I061 Switch", AFE_CONN87_1, 29, 1, 0),881};882 883static const char * const mt8188_etdm_clk_src_sel_text[] = {884 "26m",885 "a1sys_a2sys",886 "a3sys",887 "a4sys",888};889 890static SOC_ENUM_SINGLE_EXT_DECL(etdmout_clk_src_enum,891 mt8188_etdm_clk_src_sel_text);892 893static const char * const hdmitx_dptx_mux_map[] = {894 "Disconnect", "Connect",895};896 897static int hdmitx_dptx_mux_map_value[] = {898 0, 1,899};900 901/* HDMI_OUT_MUX */902static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(hdmi_out_mux_map_enum,903 SND_SOC_NOPM,904 0,905 1,906 hdmitx_dptx_mux_map,907 hdmitx_dptx_mux_map_value);908 909static const struct snd_kcontrol_new hdmi_out_mux_control =910 SOC_DAPM_ENUM("HDMI_OUT_MUX", hdmi_out_mux_map_enum);911 912/* DPTX_OUT_MUX */913static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(dptx_out_mux_map_enum,914 SND_SOC_NOPM,915 0,916 1,917 hdmitx_dptx_mux_map,918 hdmitx_dptx_mux_map_value);919 920static const struct snd_kcontrol_new dptx_out_mux_control =921 SOC_DAPM_ENUM("DPTX_OUT_MUX", dptx_out_mux_map_enum);922 923/* HDMI_CH0_MUX ~ HDMI_CH7_MUX */924static const char *const afe_conn_hdmi_mux_map[] = {925 "CH0", "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7",926};927 928static int afe_conn_hdmi_mux_map_value[] = {929 0, 1, 2, 3, 4, 5, 6, 7,930};931 932static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch0_mux_map_enum,933 AFE_TDMOUT_CONN0,934 0,935 0xf,936 afe_conn_hdmi_mux_map,937 afe_conn_hdmi_mux_map_value);938 939static const struct snd_kcontrol_new hdmi_ch0_mux_control =940 SOC_DAPM_ENUM("HDMI_CH0_MUX", hdmi_ch0_mux_map_enum);941 942static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch1_mux_map_enum,943 AFE_TDMOUT_CONN0,944 4,945 0xf,946 afe_conn_hdmi_mux_map,947 afe_conn_hdmi_mux_map_value);948 949static const struct snd_kcontrol_new hdmi_ch1_mux_control =950 SOC_DAPM_ENUM("HDMI_CH1_MUX", hdmi_ch1_mux_map_enum);951 952static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch2_mux_map_enum,953 AFE_TDMOUT_CONN0,954 8,955 0xf,956 afe_conn_hdmi_mux_map,957 afe_conn_hdmi_mux_map_value);958 959static const struct snd_kcontrol_new hdmi_ch2_mux_control =960 SOC_DAPM_ENUM("HDMI_CH2_MUX", hdmi_ch2_mux_map_enum);961 962static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch3_mux_map_enum,963 AFE_TDMOUT_CONN0,964 12,965 0xf,966 afe_conn_hdmi_mux_map,967 afe_conn_hdmi_mux_map_value);968 969static const struct snd_kcontrol_new hdmi_ch3_mux_control =970 SOC_DAPM_ENUM("HDMI_CH3_MUX", hdmi_ch3_mux_map_enum);971 972static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch4_mux_map_enum,973 AFE_TDMOUT_CONN0,974 16,975 0xf,976 afe_conn_hdmi_mux_map,977 afe_conn_hdmi_mux_map_value);978 979static const struct snd_kcontrol_new hdmi_ch4_mux_control =980 SOC_DAPM_ENUM("HDMI_CH4_MUX", hdmi_ch4_mux_map_enum);981 982static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch5_mux_map_enum,983 AFE_TDMOUT_CONN0,984 20,985 0xf,986 afe_conn_hdmi_mux_map,987 afe_conn_hdmi_mux_map_value);988 989static const struct snd_kcontrol_new hdmi_ch5_mux_control =990 SOC_DAPM_ENUM("HDMI_CH5_MUX", hdmi_ch5_mux_map_enum);991 992static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch6_mux_map_enum,993 AFE_TDMOUT_CONN0,994 24,995 0xf,996 afe_conn_hdmi_mux_map,997 afe_conn_hdmi_mux_map_value);998 999static const struct snd_kcontrol_new hdmi_ch6_mux_control =1000 SOC_DAPM_ENUM("HDMI_CH6_MUX", hdmi_ch6_mux_map_enum);1001 1002static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch7_mux_map_enum,1003 AFE_TDMOUT_CONN0,1004 28,1005 0xf,1006 afe_conn_hdmi_mux_map,1007 afe_conn_hdmi_mux_map_value);1008 1009static const struct snd_kcontrol_new hdmi_ch7_mux_control =1010 SOC_DAPM_ENUM("HDMI_CH7_MUX", hdmi_ch7_mux_map_enum);1011 1012static int mt8188_etdm_clk_src_sel_put(struct snd_kcontrol *kcontrol,1013 struct snd_ctl_elem_value *ucontrol)1014{1015 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);1016 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;1017 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);1018 unsigned int source = ucontrol->value.enumerated.item[0];1019 unsigned int val;1020 unsigned int old_val;1021 unsigned int mask;1022 unsigned int reg;1023 1024 if (source >= e->items)1025 return -EINVAL;1026 1027 if (!strcmp(kcontrol->id.name, "ETDM_OUT1_Clock_Source")) {1028 reg = ETDM_OUT1_CON4;1029 mask = ETDM_OUT_CON4_CLOCK_MASK;1030 val = FIELD_PREP(ETDM_OUT_CON4_CLOCK_MASK, source);1031 } else if (!strcmp(kcontrol->id.name, "ETDM_OUT2_Clock_Source")) {1032 reg = ETDM_OUT2_CON4;1033 mask = ETDM_OUT_CON4_CLOCK_MASK;1034 val = FIELD_PREP(ETDM_OUT_CON4_CLOCK_MASK, source);1035 } else if (!strcmp(kcontrol->id.name, "ETDM_OUT3_Clock_Source")) {1036 reg = ETDM_OUT3_CON4;1037 mask = ETDM_OUT_CON4_CLOCK_MASK;1038 val = FIELD_PREP(ETDM_OUT_CON4_CLOCK_MASK, source);1039 } else if (!strcmp(kcontrol->id.name, "ETDM_IN1_Clock_Source")) {1040 reg = ETDM_IN1_CON2;1041 mask = ETDM_IN_CON2_CLOCK_MASK;1042 val = FIELD_PREP(ETDM_IN_CON2_CLOCK_MASK, source);1043 } else if (!strcmp(kcontrol->id.name, "ETDM_IN2_Clock_Source")) {1044 reg = ETDM_IN2_CON2;1045 mask = ETDM_IN_CON2_CLOCK_MASK;1046 val = FIELD_PREP(ETDM_IN_CON2_CLOCK_MASK, source);1047 } else {1048 return -EINVAL;1049 }1050 1051 regmap_read(afe->regmap, reg, &old_val);1052 old_val &= mask;1053 if (old_val == val)1054 return 0;1055 1056 regmap_update_bits(afe->regmap, reg, mask, val);1057 1058 return 1;1059}1060 1061static int mt8188_etdm_clk_src_sel_get(struct snd_kcontrol *kcontrol,1062 struct snd_ctl_elem_value *ucontrol)1063{1064 struct snd_soc_component *component =1065 snd_soc_kcontrol_component(kcontrol);1066 struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);1067 unsigned int value;1068 unsigned int reg;1069 unsigned int mask;1070 unsigned int shift;1071 1072 if (!strcmp(kcontrol->id.name, "ETDM_OUT1_Clock_Source")) {1073 reg = ETDM_OUT1_CON4;1074 mask = ETDM_OUT_CON4_CLOCK_MASK;1075 shift = ETDM_OUT_CON4_CLOCK_SHIFT;1076 } else if (!strcmp(kcontrol->id.name, "ETDM_OUT2_Clock_Source")) {1077 reg = ETDM_OUT2_CON4;1078 mask = ETDM_OUT_CON4_CLOCK_MASK;1079 shift = ETDM_OUT_CON4_CLOCK_SHIFT;1080 } else if (!strcmp(kcontrol->id.name, "ETDM_OUT3_Clock_Source")) {1081 reg = ETDM_OUT3_CON4;1082 mask = ETDM_OUT_CON4_CLOCK_MASK;1083 shift = ETDM_OUT_CON4_CLOCK_SHIFT;1084 } else if (!strcmp(kcontrol->id.name, "ETDM_IN1_Clock_Source")) {1085 reg = ETDM_IN1_CON2;1086 mask = ETDM_IN_CON2_CLOCK_MASK;1087 shift = ETDM_IN_CON2_CLOCK_SHIFT;1088 } else if (!strcmp(kcontrol->id.name, "ETDM_IN2_Clock_Source")) {1089 reg = ETDM_IN2_CON2;1090 mask = ETDM_IN_CON2_CLOCK_MASK;1091 shift = ETDM_IN_CON2_CLOCK_SHIFT;1092 } else {1093 return -EINVAL;1094 }1095 1096 regmap_read(afe->regmap, reg, &value);1097 1098 value &= mask;1099 value >>= shift;1100 ucontrol->value.enumerated.item[0] = value;1101 return 0;1102}1103 1104static const struct snd_kcontrol_new mtk_dai_etdm_controls[] = {1105 SOC_ENUM_EXT("ETDM_OUT1_Clock_Source", etdmout_clk_src_enum,1106 mt8188_etdm_clk_src_sel_get,1107 mt8188_etdm_clk_src_sel_put),1108 SOC_ENUM_EXT("ETDM_OUT2_Clock_Source", etdmout_clk_src_enum,1109 mt8188_etdm_clk_src_sel_get,1110 mt8188_etdm_clk_src_sel_put),1111 SOC_ENUM_EXT("ETDM_OUT3_Clock_Source", etdmout_clk_src_enum,1112 mt8188_etdm_clk_src_sel_get,1113 mt8188_etdm_clk_src_sel_put),1114 SOC_ENUM_EXT("ETDM_IN1_Clock_Source", etdmout_clk_src_enum,1115 mt8188_etdm_clk_src_sel_get,1116 mt8188_etdm_clk_src_sel_put),1117 SOC_ENUM_EXT("ETDM_IN2_Clock_Source", etdmout_clk_src_enum,1118 mt8188_etdm_clk_src_sel_get,1119 mt8188_etdm_clk_src_sel_put),1120};1121 1122static const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] = {1123 /* eTDM_IN2 */1124 SND_SOC_DAPM_MIXER("I012", SND_SOC_NOPM, 0, 0, NULL, 0),1125 SND_SOC_DAPM_MIXER("I013", SND_SOC_NOPM, 0, 0, NULL, 0),1126 SND_SOC_DAPM_MIXER("I014", SND_SOC_NOPM, 0, 0, NULL, 0),1127 SND_SOC_DAPM_MIXER("I015", SND_SOC_NOPM, 0, 0, NULL, 0),1128 SND_SOC_DAPM_MIXER("I016", SND_SOC_NOPM, 0, 0, NULL, 0),1129 SND_SOC_DAPM_MIXER("I017", SND_SOC_NOPM, 0, 0, NULL, 0),1130 SND_SOC_DAPM_MIXER("I018", SND_SOC_NOPM, 0, 0, NULL, 0),1131 SND_SOC_DAPM_MIXER("I019", SND_SOC_NOPM, 0, 0, NULL, 0),1132 SND_SOC_DAPM_MIXER("I188", SND_SOC_NOPM, 0, 0, NULL, 0),1133 SND_SOC_DAPM_MIXER("I189", SND_SOC_NOPM, 0, 0, NULL, 0),1134 SND_SOC_DAPM_MIXER("I190", SND_SOC_NOPM, 0, 0, NULL, 0),1135 SND_SOC_DAPM_MIXER("I191", SND_SOC_NOPM, 0, 0, NULL, 0),1136 SND_SOC_DAPM_MIXER("I192", SND_SOC_NOPM, 0, 0, NULL, 0),1137 SND_SOC_DAPM_MIXER("I193", SND_SOC_NOPM, 0, 0, NULL, 0),1138 SND_SOC_DAPM_MIXER("I194", SND_SOC_NOPM, 0, 0, NULL, 0),1139 SND_SOC_DAPM_MIXER("I195", SND_SOC_NOPM, 0, 0, NULL, 0),1140 1141 /* eTDM_IN1 */1142 SND_SOC_DAPM_MIXER("I072", SND_SOC_NOPM, 0, 0, NULL, 0),1143 SND_SOC_DAPM_MIXER("I073", SND_SOC_NOPM, 0, 0, NULL, 0),1144 SND_SOC_DAPM_MIXER("I074", SND_SOC_NOPM, 0, 0, NULL, 0),1145 SND_SOC_DAPM_MIXER("I075", SND_SOC_NOPM, 0, 0, NULL, 0),1146 SND_SOC_DAPM_MIXER("I076", SND_SOC_NOPM, 0, 0, NULL, 0),1147 SND_SOC_DAPM_MIXER("I077", SND_SOC_NOPM, 0, 0, NULL, 0),1148 SND_SOC_DAPM_MIXER("I078", SND_SOC_NOPM, 0, 0, NULL, 0),1149 SND_SOC_DAPM_MIXER("I079", SND_SOC_NOPM, 0, 0, NULL, 0),1150 SND_SOC_DAPM_MIXER("I080", SND_SOC_NOPM, 0, 0, NULL, 0),1151 SND_SOC_DAPM_MIXER("I081", SND_SOC_NOPM, 0, 0, NULL, 0),1152 SND_SOC_DAPM_MIXER("I082", SND_SOC_NOPM, 0, 0, NULL, 0),1153 SND_SOC_DAPM_MIXER("I083", SND_SOC_NOPM, 0, 0, NULL, 0),1154 SND_SOC_DAPM_MIXER("I084", SND_SOC_NOPM, 0, 0, NULL, 0),1155 SND_SOC_DAPM_MIXER("I085", SND_SOC_NOPM, 0, 0, NULL, 0),1156 SND_SOC_DAPM_MIXER("I086", SND_SOC_NOPM, 0, 0, NULL, 0),1157 SND_SOC_DAPM_MIXER("I087", SND_SOC_NOPM, 0, 0, NULL, 0),1158 1159 /* eTDM_OUT2 */1160 SND_SOC_DAPM_MIXER("O048", SND_SOC_NOPM, 0, 0,1161 mtk_dai_etdm_o048_mix, ARRAY_SIZE(mtk_dai_etdm_o048_mix)),1162 SND_SOC_DAPM_MIXER("O049", SND_SOC_NOPM, 0, 0,1163 mtk_dai_etdm_o049_mix, ARRAY_SIZE(mtk_dai_etdm_o049_mix)),1164 SND_SOC_DAPM_MIXER("O050", SND_SOC_NOPM, 0, 0,1165 mtk_dai_etdm_o050_mix, ARRAY_SIZE(mtk_dai_etdm_o050_mix)),1166 SND_SOC_DAPM_MIXER("O051", SND_SOC_NOPM, 0, 0,1167 mtk_dai_etdm_o051_mix, ARRAY_SIZE(mtk_dai_etdm_o051_mix)),1168 SND_SOC_DAPM_MIXER("O052", SND_SOC_NOPM, 0, 0,1169 mtk_dai_etdm_o052_mix, ARRAY_SIZE(mtk_dai_etdm_o052_mix)),1170 SND_SOC_DAPM_MIXER("O053", SND_SOC_NOPM, 0, 0,1171 mtk_dai_etdm_o053_mix, ARRAY_SIZE(mtk_dai_etdm_o053_mix)),1172 SND_SOC_DAPM_MIXER("O054", SND_SOC_NOPM, 0, 0,1173 mtk_dai_etdm_o054_mix, ARRAY_SIZE(mtk_dai_etdm_o054_mix)),1174 SND_SOC_DAPM_MIXER("O055", SND_SOC_NOPM, 0, 0,1175 mtk_dai_etdm_o055_mix, ARRAY_SIZE(mtk_dai_etdm_o055_mix)),1176 SND_SOC_DAPM_MIXER("O056", SND_SOC_NOPM, 0, 0,1177 mtk_dai_etdm_o056_mix, ARRAY_SIZE(mtk_dai_etdm_o056_mix)),1178 SND_SOC_DAPM_MIXER("O057", SND_SOC_NOPM, 0, 0,1179 mtk_dai_etdm_o057_mix, ARRAY_SIZE(mtk_dai_etdm_o057_mix)),1180 SND_SOC_DAPM_MIXER("O058", SND_SOC_NOPM, 0, 0,1181 mtk_dai_etdm_o058_mix, ARRAY_SIZE(mtk_dai_etdm_o058_mix)),1182 SND_SOC_DAPM_MIXER("O059", SND_SOC_NOPM, 0, 0,1183 mtk_dai_etdm_o059_mix, ARRAY_SIZE(mtk_dai_etdm_o059_mix)),1184 SND_SOC_DAPM_MIXER("O060", SND_SOC_NOPM, 0, 0,1185 mtk_dai_etdm_o060_mix, ARRAY_SIZE(mtk_dai_etdm_o060_mix)),1186 SND_SOC_DAPM_MIXER("O061", SND_SOC_NOPM, 0, 0,1187 mtk_dai_etdm_o061_mix, ARRAY_SIZE(mtk_dai_etdm_o061_mix)),1188 SND_SOC_DAPM_MIXER("O062", SND_SOC_NOPM, 0, 0,1189 mtk_dai_etdm_o062_mix, ARRAY_SIZE(mtk_dai_etdm_o062_mix)),1190 SND_SOC_DAPM_MIXER("O063", SND_SOC_NOPM, 0, 0,1191 mtk_dai_etdm_o063_mix, ARRAY_SIZE(mtk_dai_etdm_o063_mix)),1192 1193 /* eTDM_OUT1 */1194 SND_SOC_DAPM_MIXER("O072", SND_SOC_NOPM, 0, 0,1195 mtk_dai_etdm_o072_mix, ARRAY_SIZE(mtk_dai_etdm_o072_mix)),1196 SND_SOC_DAPM_MIXER("O073", SND_SOC_NOPM, 0, 0,1197 mtk_dai_etdm_o073_mix, ARRAY_SIZE(mtk_dai_etdm_o073_mix)),1198 SND_SOC_DAPM_MIXER("O074", SND_SOC_NOPM, 0, 0,1199 mtk_dai_etdm_o074_mix, ARRAY_SIZE(mtk_dai_etdm_o074_mix)),1200 SND_SOC_DAPM_MIXER("O075", SND_SOC_NOPM, 0, 0,1201 mtk_dai_etdm_o075_mix, ARRAY_SIZE(mtk_dai_etdm_o075_mix)),1202 SND_SOC_DAPM_MIXER("O076", SND_SOC_NOPM, 0, 0,1203 mtk_dai_etdm_o076_mix, ARRAY_SIZE(mtk_dai_etdm_o076_mix)),1204 SND_SOC_DAPM_MIXER("O077", SND_SOC_NOPM, 0, 0,1205 mtk_dai_etdm_o077_mix, ARRAY_SIZE(mtk_dai_etdm_o077_mix)),1206 SND_SOC_DAPM_MIXER("O078", SND_SOC_NOPM, 0, 0,1207 mtk_dai_etdm_o078_mix, ARRAY_SIZE(mtk_dai_etdm_o078_mix)),1208 SND_SOC_DAPM_MIXER("O079", SND_SOC_NOPM, 0, 0,1209 mtk_dai_etdm_o079_mix, ARRAY_SIZE(mtk_dai_etdm_o079_mix)),1210 SND_SOC_DAPM_MIXER("O080", SND_SOC_NOPM, 0, 0,1211 mtk_dai_etdm_o080_mix, ARRAY_SIZE(mtk_dai_etdm_o080_mix)),1212 SND_SOC_DAPM_MIXER("O081", SND_SOC_NOPM, 0, 0,1213 mtk_dai_etdm_o081_mix, ARRAY_SIZE(mtk_dai_etdm_o081_mix)),1214 SND_SOC_DAPM_MIXER("O082", SND_SOC_NOPM, 0, 0,1215 mtk_dai_etdm_o082_mix, ARRAY_SIZE(mtk_dai_etdm_o082_mix)),1216 SND_SOC_DAPM_MIXER("O083", SND_SOC_NOPM, 0, 0,1217 mtk_dai_etdm_o083_mix, ARRAY_SIZE(mtk_dai_etdm_o083_mix)),1218 SND_SOC_DAPM_MIXER("O084", SND_SOC_NOPM, 0, 0,1219 mtk_dai_etdm_o084_mix, ARRAY_SIZE(mtk_dai_etdm_o084_mix)),1220 SND_SOC_DAPM_MIXER("O085", SND_SOC_NOPM, 0, 0,1221 mtk_dai_etdm_o085_mix, ARRAY_SIZE(mtk_dai_etdm_o085_mix)),1222 SND_SOC_DAPM_MIXER("O086", SND_SOC_NOPM, 0, 0,1223 mtk_dai_etdm_o086_mix, ARRAY_SIZE(mtk_dai_etdm_o086_mix)),1224 SND_SOC_DAPM_MIXER("O087", SND_SOC_NOPM, 0, 0,1225 mtk_dai_etdm_o087_mix, ARRAY_SIZE(mtk_dai_etdm_o087_mix)),1226 1227 /* eTDM_OUT3 */1228 SND_SOC_DAPM_MUX("HDMI_OUT_MUX", SND_SOC_NOPM, 0, 0,1229 &hdmi_out_mux_control),1230 SND_SOC_DAPM_MUX("DPTX_OUT_MUX", SND_SOC_NOPM, 0, 0,1231 &dptx_out_mux_control),1232 1233 SND_SOC_DAPM_MUX("HDMI_CH0_MUX", SND_SOC_NOPM, 0, 0,1234 &hdmi_ch0_mux_control),1235 SND_SOC_DAPM_MUX("HDMI_CH1_MUX", SND_SOC_NOPM, 0, 0,1236 &hdmi_ch1_mux_control),1237 SND_SOC_DAPM_MUX("HDMI_CH2_MUX", SND_SOC_NOPM, 0, 0,1238 &hdmi_ch2_mux_control),1239 SND_SOC_DAPM_MUX("HDMI_CH3_MUX", SND_SOC_NOPM, 0, 0,1240 &hdmi_ch3_mux_control),1241 SND_SOC_DAPM_MUX("HDMI_CH4_MUX", SND_SOC_NOPM, 0, 0,1242 &hdmi_ch4_mux_control),1243 SND_SOC_DAPM_MUX("HDMI_CH5_MUX", SND_SOC_NOPM, 0, 0,1244 &hdmi_ch5_mux_control),1245 SND_SOC_DAPM_MUX("HDMI_CH6_MUX", SND_SOC_NOPM, 0, 0,1246 &hdmi_ch6_mux_control),1247 SND_SOC_DAPM_MUX("HDMI_CH7_MUX", SND_SOC_NOPM, 0, 0,1248 &hdmi_ch7_mux_control),1249 1250 /* mclk en */1251 SND_SOC_DAPM_SUPPLY_S("ETDM1_IN_MCLK", SUPPLY_SEQ_ETDM_MCLK,1252 SND_SOC_NOPM, 0, 0,1253 mtk_etdm_mclk_event,1254 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),1255 SND_SOC_DAPM_SUPPLY_S("ETDM2_IN_MCLK", SUPPLY_SEQ_ETDM_MCLK,1256 SND_SOC_NOPM, 0, 0,1257 mtk_etdm_mclk_event,1258 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),1259 SND_SOC_DAPM_SUPPLY_S("ETDM1_OUT_MCLK", SUPPLY_SEQ_ETDM_MCLK,1260 SND_SOC_NOPM, 0, 0,1261 mtk_etdm_mclk_event,1262 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),1263 SND_SOC_DAPM_SUPPLY_S("ETDM2_OUT_MCLK", SUPPLY_SEQ_ETDM_MCLK,1264 SND_SOC_NOPM, 0, 0,1265 mtk_etdm_mclk_event,1266 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),1267 SND_SOC_DAPM_SUPPLY_S("DPTX_MCLK", SUPPLY_SEQ_ETDM_MCLK,1268 SND_SOC_NOPM, 0, 0,1269 mtk_dptx_mclk_event,1270 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),1271 1272 /* cg */1273 SND_SOC_DAPM_SUPPLY_S("ETDM1_IN_CG", SUPPLY_SEQ_ETDM_CG,1274 SND_SOC_NOPM, 0, 0,1275 mtk_etdm_cg_event,1276 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),1277 SND_SOC_DAPM_SUPPLY_S("ETDM2_IN_CG", SUPPLY_SEQ_ETDM_CG,1278 SND_SOC_NOPM, 0, 0,1279 mtk_etdm_cg_event,1280 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),1281 SND_SOC_DAPM_SUPPLY_S("ETDM1_OUT_CG", SUPPLY_SEQ_ETDM_CG,1282 SND_SOC_NOPM, 0, 0,1283 mtk_etdm_cg_event,1284 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),1285 SND_SOC_DAPM_SUPPLY_S("ETDM2_OUT_CG", SUPPLY_SEQ_ETDM_CG,1286 SND_SOC_NOPM, 0, 0,1287 mtk_etdm_cg_event,1288 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),1289 SND_SOC_DAPM_SUPPLY_S("ETDM3_OUT_CG", SUPPLY_SEQ_ETDM_CG,1290 SND_SOC_NOPM, 0, 0,1291 mtk_etdm3_cg_event,1292 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),1293 1294 /* en */1295 SND_SOC_DAPM_SUPPLY_S("ETDM1_IN_EN", SUPPLY_SEQ_ETDM_EN,1296 ETDM_IN1_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),1297 SND_SOC_DAPM_SUPPLY_S("ETDM2_IN_EN", SUPPLY_SEQ_ETDM_EN,1298 ETDM_IN2_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),1299 SND_SOC_DAPM_SUPPLY_S("ETDM1_OUT_EN", SUPPLY_SEQ_ETDM_EN,1300 ETDM_OUT1_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),1301 SND_SOC_DAPM_SUPPLY_S("ETDM2_OUT_EN", SUPPLY_SEQ_ETDM_EN,1302 ETDM_OUT2_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),1303 SND_SOC_DAPM_SUPPLY_S("ETDM3_OUT_EN", SUPPLY_SEQ_ETDM_EN,1304 ETDM_OUT3_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0),1305 SND_SOC_DAPM_SUPPLY_S("DPTX_EN", SUPPLY_SEQ_DPTX_EN,1306 AFE_DPTX_CON, AFE_DPTX_CON_ON_SHIFT, 0, NULL, 0),1307 1308 /* apll */1309 SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL,1310 SND_SOC_NOPM, 0, 0,1311 mtk_apll_event,1312 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),1313 SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL,1314 SND_SOC_NOPM, 0, 0,1315 mtk_apll_event,1316 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),1317 1318 SND_SOC_DAPM_INPUT("ETDM_INPUT"),1319 SND_SOC_DAPM_OUTPUT("ETDM_OUTPUT"),1320};1321 1322static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = {1323 /* mclk */1324 {"ETDM1_IN", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect},1325 {"ETDM1_IN", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect},1326 {"ETDM1_IN", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect},1327 {"ETDM1_IN", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect},1328 1329 {"ETDM2_IN", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect},1330 {"ETDM2_IN", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect},1331 {"ETDM2_IN", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect},1332 {"ETDM2_IN", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect},1333 1334 {"ETDM1_OUT", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect},1335 {"ETDM1_OUT", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect},1336 {"ETDM1_OUT", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect},1337 {"ETDM1_OUT", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect},1338 1339 {"ETDM2_OUT", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect},1340 {"ETDM2_OUT", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect},1341 {"ETDM2_OUT", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect},1342 {"ETDM2_OUT", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect},1343 1344 {"DPTX", NULL, "DPTX_MCLK"},1345 1346 {"ETDM1_IN_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},1347 {"ETDM1_IN_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},1348 1349 {"ETDM2_IN_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},1350 {"ETDM2_IN_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},1351 1352 {"ETDM1_OUT_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},1353 {"ETDM1_OUT_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},1354 1355 {"ETDM2_OUT_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},1356 {"ETDM2_OUT_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},1357 1358 {"DPTX_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},1359 {"DPTX_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},1360 1361 /* cg */1362 {"ETDM1_IN", NULL, "ETDM1_IN_CG"},1363 {"ETDM1_IN", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect},1364 {"ETDM1_IN", NULL, "ETDM1_OUT_CG", mtk_etdm_cowork_connect},1365 {"ETDM1_IN", NULL, "ETDM2_OUT_CG", mtk_etdm_cowork_connect},1366 1367 {"ETDM2_IN", NULL, "ETDM1_IN_CG", mtk_etdm_cowork_connect},1368 {"ETDM2_IN", NULL, "ETDM2_IN_CG"},1369 {"ETDM2_IN", NULL, "ETDM1_OUT_CG", mtk_etdm_cowork_connect},1370 {"ETDM2_IN", NULL, "ETDM2_OUT_CG", mtk_etdm_cowork_connect},1371 1372 {"ETDM1_OUT", NULL, "ETDM1_IN_CG", mtk_etdm_cowork_connect},1373 {"ETDM1_OUT", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect},1374 {"ETDM1_OUT", NULL, "ETDM1_OUT_CG"},1375 {"ETDM1_OUT", NULL, "ETDM2_OUT_CG", mtk_etdm_cowork_connect},1376 1377 {"ETDM2_OUT", NULL, "ETDM1_IN_CG", mtk_etdm_cowork_connect},1378 {"ETDM2_OUT", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect},1379 {"ETDM2_OUT", NULL, "ETDM1_OUT_CG", mtk_etdm_cowork_connect},1380 {"ETDM2_OUT", NULL, "ETDM2_OUT_CG"},1381 1382 {"ETDM3_OUT", NULL, "ETDM3_OUT_CG"},1383 {"DPTX", NULL, "ETDM3_OUT_CG"},1384 1385 /* en */1386 {"ETDM1_IN", NULL, "ETDM1_IN_EN"},1387 {"ETDM1_IN", NULL, "ETDM2_IN_EN", mtk_etdm_cowork_connect},1388 {"ETDM1_IN", NULL, "ETDM1_OUT_EN", mtk_etdm_cowork_connect},1389 {"ETDM1_IN", NULL, "ETDM2_OUT_EN", mtk_etdm_cowork_connect},1390 1391 {"ETDM2_IN", NULL, "ETDM1_IN_EN", mtk_etdm_cowork_connect},1392 {"ETDM2_IN", NULL, "ETDM2_IN_EN"},1393 {"ETDM2_IN", NULL, "ETDM1_OUT_EN", mtk_etdm_cowork_connect},1394 {"ETDM2_IN", NULL, "ETDM2_OUT_EN", mtk_etdm_cowork_connect},1395 1396 {"ETDM1_OUT", NULL, "ETDM1_IN_EN", mtk_etdm_cowork_connect},1397 {"ETDM1_OUT", NULL, "ETDM2_IN_EN", mtk_etdm_cowork_connect},1398 {"ETDM1_OUT", NULL, "ETDM1_OUT_EN"},1399 {"ETDM1_OUT", NULL, "ETDM2_OUT_EN", mtk_etdm_cowork_connect},1400 1401 {"ETDM2_OUT", NULL, "ETDM1_IN_EN", mtk_etdm_cowork_connect},1402 {"ETDM2_OUT", NULL, "ETDM2_IN_EN", mtk_etdm_cowork_connect},1403 {"ETDM2_OUT", NULL, "ETDM1_OUT_EN", mtk_etdm_cowork_connect},1404 {"ETDM2_OUT", NULL, "ETDM2_OUT_EN"},1405 1406 {"ETDM3_OUT", NULL, "ETDM3_OUT_EN"},1407 {"DPTX", NULL, "ETDM3_OUT_EN"},1408 {"DPTX", NULL, "DPTX_EN"},1409 1410 {"ETDM1_IN_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},1411 {"ETDM1_IN_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},1412 1413 {"ETDM2_IN_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},1414 {"ETDM2_IN_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},1415 1416 {"ETDM1_OUT_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},1417 {"ETDM1_OUT_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},1418 1419 {"ETDM2_OUT_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},1420 {"ETDM2_OUT_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},1421 1422 {"ETDM3_OUT_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect},1423 {"ETDM3_OUT_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect},1424 1425 {"I012", NULL, "ETDM2_IN"},1426 {"I013", NULL, "ETDM2_IN"},1427 {"I014", NULL, "ETDM2_IN"},1428 {"I015", NULL, "ETDM2_IN"},1429 {"I016", NULL, "ETDM2_IN"},1430 {"I017", NULL, "ETDM2_IN"},1431 {"I018", NULL, "ETDM2_IN"},1432 {"I019", NULL, "ETDM2_IN"},1433 {"I188", NULL, "ETDM2_IN"},1434 {"I189", NULL, "ETDM2_IN"},1435 {"I190", NULL, "ETDM2_IN"},1436 {"I191", NULL, "ETDM2_IN"},1437 {"I192", NULL, "ETDM2_IN"},1438 {"I193", NULL, "ETDM2_IN"},1439 {"I194", NULL, "ETDM2_IN"},1440 {"I195", NULL, "ETDM2_IN"},1441 1442 {"I072", NULL, "ETDM1_IN"},1443 {"I073", NULL, "ETDM1_IN"},1444 {"I074", NULL, "ETDM1_IN"},1445 {"I075", NULL, "ETDM1_IN"},1446 {"I076", NULL, "ETDM1_IN"},1447 {"I077", NULL, "ETDM1_IN"},1448 {"I078", NULL, "ETDM1_IN"},1449 {"I079", NULL, "ETDM1_IN"},1450 {"I080", NULL, "ETDM1_IN"},1451 {"I081", NULL, "ETDM1_IN"},1452 {"I082", NULL, "ETDM1_IN"},1453 {"I083", NULL, "ETDM1_IN"},1454 {"I084", NULL, "ETDM1_IN"},1455 {"I085", NULL, "ETDM1_IN"},1456 {"I086", NULL, "ETDM1_IN"},1457 {"I087", NULL, "ETDM1_IN"},1458 1459 {"UL8", NULL, "ETDM1_IN"},1460 {"UL3", NULL, "ETDM2_IN"},1461 1462 {"ETDM2_OUT", NULL, "O048"},1463 {"ETDM2_OUT", NULL, "O049"},1464 {"ETDM2_OUT", NULL, "O050"},1465 {"ETDM2_OUT", NULL, "O051"},1466 {"ETDM2_OUT", NULL, "O052"},1467 {"ETDM2_OUT", NULL, "O053"},1468 {"ETDM2_OUT", NULL, "O054"},1469 {"ETDM2_OUT", NULL, "O055"},1470 {"ETDM2_OUT", NULL, "O056"},1471 {"ETDM2_OUT", NULL, "O057"},1472 {"ETDM2_OUT", NULL, "O058"},1473 {"ETDM2_OUT", NULL, "O059"},1474 {"ETDM2_OUT", NULL, "O060"},1475 {"ETDM2_OUT", NULL, "O061"},1476 {"ETDM2_OUT", NULL, "O062"},1477 {"ETDM2_OUT", NULL, "O063"},1478 1479 {"ETDM1_OUT", NULL, "O072"},1480 {"ETDM1_OUT", NULL, "O073"},1481 {"ETDM1_OUT", NULL, "O074"},1482 {"ETDM1_OUT", NULL, "O075"},1483 {"ETDM1_OUT", NULL, "O076"},1484 {"ETDM1_OUT", NULL, "O077"},1485 {"ETDM1_OUT", NULL, "O078"},1486 {"ETDM1_OUT", NULL, "O079"},1487 {"ETDM1_OUT", NULL, "O080"},1488 {"ETDM1_OUT", NULL, "O081"},1489 {"ETDM1_OUT", NULL, "O082"},1490 {"ETDM1_OUT", NULL, "O083"},1491 {"ETDM1_OUT", NULL, "O084"},1492 {"ETDM1_OUT", NULL, "O085"},1493 {"ETDM1_OUT", NULL, "O086"},1494 {"ETDM1_OUT", NULL, "O087"},1495 1496 {"O048", "I020 Switch", "I020"},1497 {"O049", "I021 Switch", "I021"},1498 1499 {"O048", "I022 Switch", "I022"},1500 {"O049", "I023 Switch", "I023"},1501 {"O050", "I024 Switch", "I024"},1502 {"O051", "I025 Switch", "I025"},1503 {"O052", "I026 Switch", "I026"},1504 {"O053", "I027 Switch", "I027"},1505 {"O054", "I028 Switch", "I028"},1506 {"O055", "I029 Switch", "I029"},1507 {"O056", "I030 Switch", "I030"},1508 {"O057", "I031 Switch", "I031"},1509 {"O058", "I032 Switch", "I032"},1510 {"O059", "I033 Switch", "I033"},1511 {"O060", "I034 Switch", "I034"},1512 {"O061", "I035 Switch", "I035"},1513 {"O062", "I036 Switch", "I036"},1514 {"O063", "I037 Switch", "I037"},1515 1516 {"O048", "I046 Switch", "I046"},1517 {"O049", "I047 Switch", "I047"},1518 {"O050", "I048 Switch", "I048"},1519 {"O051", "I049 Switch", "I049"},1520 {"O052", "I050 Switch", "I050"},1521 {"O053", "I051 Switch", "I051"},1522 {"O054", "I052 Switch", "I052"},1523 {"O055", "I053 Switch", "I053"},1524 {"O056", "I054 Switch", "I054"},1525 {"O057", "I055 Switch", "I055"},1526 {"O058", "I056 Switch", "I056"},1527 {"O059", "I057 Switch", "I057"},1528 {"O060", "I058 Switch", "I058"},1529 {"O061", "I059 Switch", "I059"},1530 {"O062", "I060 Switch", "I060"},1531 {"O063", "I061 Switch", "I061"},1532 1533 {"O048", "I070 Switch", "I070"},1534 {"O049", "I071 Switch", "I071"},1535 1536 {"O072", "I020 Switch", "I020"},1537 {"O073", "I021 Switch", "I021"},1538 1539 {"O072", "I022 Switch", "I022"},1540 {"O073", "I023 Switch", "I023"},1541 {"O074", "I024 Switch", "I024"},1542 {"O075", "I025 Switch", "I025"},1543 {"O076", "I026 Switch", "I026"},1544 {"O077", "I027 Switch", "I027"},1545 {"O078", "I028 Switch", "I028"},1546 {"O079", "I029 Switch", "I029"},1547 {"O080", "I030 Switch", "I030"},1548 {"O081", "I031 Switch", "I031"},1549 {"O082", "I032 Switch", "I032"},1550 {"O083", "I033 Switch", "I033"},1551 {"O084", "I034 Switch", "I034"},1552 {"O085", "I035 Switch", "I035"},1553 {"O086", "I036 Switch", "I036"},1554 {"O087", "I037 Switch", "I037"},1555 1556 {"O072", "I046 Switch", "I046"},1557 {"O073", "I047 Switch", "I047"},1558 {"O074", "I048 Switch", "I048"},1559 {"O075", "I049 Switch", "I049"},1560 {"O076", "I050 Switch", "I050"},1561 {"O077", "I051 Switch", "I051"},1562 {"O078", "I052 Switch", "I052"},1563 {"O079", "I053 Switch", "I053"},1564 {"O080", "I054 Switch", "I054"},1565 {"O081", "I055 Switch", "I055"},1566 {"O082", "I056 Switch", "I056"},1567 {"O083", "I057 Switch", "I057"},1568 {"O084", "I058 Switch", "I058"},1569 {"O085", "I059 Switch", "I059"},1570 {"O086", "I060 Switch", "I060"},1571 {"O087", "I061 Switch", "I061"},1572 1573 {"O072", "I070 Switch", "I070"},1574 {"O073", "I071 Switch", "I071"},1575 1576 {"HDMI_CH0_MUX", "CH0", "DL10"},1577 {"HDMI_CH0_MUX", "CH1", "DL10"},1578 {"HDMI_CH0_MUX", "CH2", "DL10"},1579 {"HDMI_CH0_MUX", "CH3", "DL10"},1580 {"HDMI_CH0_MUX", "CH4", "DL10"},1581 {"HDMI_CH0_MUX", "CH5", "DL10"},1582 {"HDMI_CH0_MUX", "CH6", "DL10"},1583 {"HDMI_CH0_MUX", "CH7", "DL10"},1584 1585 {"HDMI_CH1_MUX", "CH0", "DL10"},1586 {"HDMI_CH1_MUX", "CH1", "DL10"},1587 {"HDMI_CH1_MUX", "CH2", "DL10"},1588 {"HDMI_CH1_MUX", "CH3", "DL10"},1589 {"HDMI_CH1_MUX", "CH4", "DL10"},1590 {"HDMI_CH1_MUX", "CH5", "DL10"},1591 {"HDMI_CH1_MUX", "CH6", "DL10"},1592 {"HDMI_CH1_MUX", "CH7", "DL10"},1593 1594 {"HDMI_CH2_MUX", "CH0", "DL10"},1595 {"HDMI_CH2_MUX", "CH1", "DL10"},1596 {"HDMI_CH2_MUX", "CH2", "DL10"},1597 {"HDMI_CH2_MUX", "CH3", "DL10"},1598 {"HDMI_CH2_MUX", "CH4", "DL10"},1599 {"HDMI_CH2_MUX", "CH5", "DL10"},1600 {"HDMI_CH2_MUX", "CH6", "DL10"},1601 {"HDMI_CH2_MUX", "CH7", "DL10"},1602 1603 {"HDMI_CH3_MUX", "CH0", "DL10"},1604 {"HDMI_CH3_MUX", "CH1", "DL10"},1605 {"HDMI_CH3_MUX", "CH2", "DL10"},1606 {"HDMI_CH3_MUX", "CH3", "DL10"},1607 {"HDMI_CH3_MUX", "CH4", "DL10"},1608 {"HDMI_CH3_MUX", "CH5", "DL10"},1609 {"HDMI_CH3_MUX", "CH6", "DL10"},1610 {"HDMI_CH3_MUX", "CH7", "DL10"},1611 1612 {"HDMI_CH4_MUX", "CH0", "DL10"},1613 {"HDMI_CH4_MUX", "CH1", "DL10"},1614 {"HDMI_CH4_MUX", "CH2", "DL10"},1615 {"HDMI_CH4_MUX", "CH3", "DL10"},1616 {"HDMI_CH4_MUX", "CH4", "DL10"},1617 {"HDMI_CH4_MUX", "CH5", "DL10"},1618 {"HDMI_CH4_MUX", "CH6", "DL10"},1619 {"HDMI_CH4_MUX", "CH7", "DL10"},1620 1621 {"HDMI_CH5_MUX", "CH0", "DL10"},1622 {"HDMI_CH5_MUX", "CH1", "DL10"},1623 {"HDMI_CH5_MUX", "CH2", "DL10"},1624 {"HDMI_CH5_MUX", "CH3", "DL10"},1625 {"HDMI_CH5_MUX", "CH4", "DL10"},1626 {"HDMI_CH5_MUX", "CH5", "DL10"},1627 {"HDMI_CH5_MUX", "CH6", "DL10"},1628 {"HDMI_CH5_MUX", "CH7", "DL10"},1629 1630 {"HDMI_CH6_MUX", "CH0", "DL10"},1631 {"HDMI_CH6_MUX", "CH1", "DL10"},1632 {"HDMI_CH6_MUX", "CH2", "DL10"},1633 {"HDMI_CH6_MUX", "CH3", "DL10"},1634 {"HDMI_CH6_MUX", "CH4", "DL10"},1635 {"HDMI_CH6_MUX", "CH5", "DL10"},1636 {"HDMI_CH6_MUX", "CH6", "DL10"},1637 {"HDMI_CH6_MUX", "CH7", "DL10"},1638 1639 {"HDMI_CH7_MUX", "CH0", "DL10"},1640 {"HDMI_CH7_MUX", "CH1", "DL10"},1641 {"HDMI_CH7_MUX", "CH2", "DL10"},1642 {"HDMI_CH7_MUX", "CH3", "DL10"},1643 {"HDMI_CH7_MUX", "CH4", "DL10"},1644 {"HDMI_CH7_MUX", "CH5", "DL10"},1645 {"HDMI_CH7_MUX", "CH6", "DL10"},1646 {"HDMI_CH7_MUX", "CH7", "DL10"},1647 1648 {"HDMI_OUT_MUX", "Connect", "HDMI_CH0_MUX"},1649 {"HDMI_OUT_MUX", "Connect", "HDMI_CH1_MUX"},1650 {"HDMI_OUT_MUX", "Connect", "HDMI_CH2_MUX"},1651 {"HDMI_OUT_MUX", "Connect", "HDMI_CH3_MUX"},1652 {"HDMI_OUT_MUX", "Connect", "HDMI_CH4_MUX"},1653 {"HDMI_OUT_MUX", "Connect", "HDMI_CH5_MUX"},1654 {"HDMI_OUT_MUX", "Connect", "HDMI_CH6_MUX"},1655 {"HDMI_OUT_MUX", "Connect", "HDMI_CH7_MUX"},1656 1657 {"DPTX_OUT_MUX", "Connect", "HDMI_CH0_MUX"},1658 {"DPTX_OUT_MUX", "Connect", "HDMI_CH1_MUX"},1659 {"DPTX_OUT_MUX", "Connect", "HDMI_CH2_MUX"},1660 {"DPTX_OUT_MUX", "Connect", "HDMI_CH3_MUX"},1661 {"DPTX_OUT_MUX", "Connect", "HDMI_CH4_MUX"},1662 {"DPTX_OUT_MUX", "Connect", "HDMI_CH5_MUX"},1663 {"DPTX_OUT_MUX", "Connect", "HDMI_CH6_MUX"},1664 {"DPTX_OUT_MUX", "Connect", "HDMI_CH7_MUX"},1665 1666 {"ETDM3_OUT", NULL, "HDMI_OUT_MUX"},1667 {"DPTX", NULL, "DPTX_OUT_MUX"},1668 1669 {"ETDM_OUTPUT", NULL, "DPTX"},1670 {"ETDM_OUTPUT", NULL, "ETDM1_OUT"},1671 {"ETDM_OUTPUT", NULL, "ETDM2_OUT"},1672 {"ETDM_OUTPUT", NULL, "ETDM3_OUT"},1673 {"ETDM1_IN", NULL, "ETDM_INPUT"},1674 {"ETDM2_IN", NULL, "ETDM_INPUT"},1675};1676 1677static int etdm_cowork_slv_sel(int id, int slave_mode)1678{1679 if (slave_mode) {1680 switch (id) {1681 case MT8188_AFE_IO_ETDM1_IN:1682 return COWORK_ETDM_IN1_S;1683 case MT8188_AFE_IO_ETDM2_IN:1684 return COWORK_ETDM_IN2_S;1685 case MT8188_AFE_IO_ETDM1_OUT:1686 return COWORK_ETDM_OUT1_S;1687 case MT8188_AFE_IO_ETDM2_OUT:1688 return COWORK_ETDM_OUT2_S;1689 case MT8188_AFE_IO_ETDM3_OUT:1690 return COWORK_ETDM_OUT3_S;1691 default:1692 return -EINVAL;1693 }1694 } else {1695 switch (id) {1696 case MT8188_AFE_IO_ETDM1_IN:1697 return COWORK_ETDM_IN1_M;1698 case MT8188_AFE_IO_ETDM2_IN:1699 return COWORK_ETDM_IN2_M;1700 case MT8188_AFE_IO_ETDM1_OUT:1701 return COWORK_ETDM_OUT1_M;1702 case MT8188_AFE_IO_ETDM2_OUT:1703 return COWORK_ETDM_OUT2_M;1704 case MT8188_AFE_IO_ETDM3_OUT:1705 return COWORK_ETDM_OUT3_M;1706 default:1707 return -EINVAL;1708 }1709 }1710}1711 1712static int etdm_cowork_sync_sel(int id)1713{1714 switch (id) {1715 case MT8188_AFE_IO_ETDM1_IN:1716 return ETDM_SYNC_FROM_IN1;1717 case MT8188_AFE_IO_ETDM2_IN:1718 return ETDM_SYNC_FROM_IN2;1719 case MT8188_AFE_IO_ETDM1_OUT:1720 return ETDM_SYNC_FROM_OUT1;1721 case MT8188_AFE_IO_ETDM2_OUT:1722 return ETDM_SYNC_FROM_OUT2;1723 case MT8188_AFE_IO_ETDM3_OUT:1724 return ETDM_SYNC_FROM_OUT3;1725 default:1726 return -EINVAL;1727 }1728}1729 1730static int mt8188_etdm_sync_mode_slv(struct mtk_base_afe *afe, int dai_id)1731{1732 struct mt8188_afe_private *afe_priv = afe->platform_priv;1733 struct mtk_dai_etdm_priv *etdm_data;1734 unsigned int reg = 0;1735 unsigned int mask;1736 unsigned int val;1737 int cowork_source_sel;1738 1739 if (!is_valid_etdm_dai(dai_id))1740 return -EINVAL;1741 etdm_data = afe_priv->dai_priv[dai_id];1742 1743 cowork_source_sel = etdm_cowork_slv_sel(etdm_data->cowork_source_id,1744 true);1745 if (cowork_source_sel < 0)1746 return cowork_source_sel;1747 1748 switch (dai_id) {1749 case MT8188_AFE_IO_ETDM1_IN:1750 reg = ETDM_COWORK_CON1;1751 mask = ETDM_IN1_SLAVE_SEL_MASK;1752 val = FIELD_PREP(ETDM_IN1_SLAVE_SEL_MASK, cowork_source_sel);1753 break;1754 case MT8188_AFE_IO_ETDM2_IN:1755 reg = ETDM_COWORK_CON2;1756 mask = ETDM_IN2_SLAVE_SEL_MASK;1757 val = FIELD_PREP(ETDM_IN2_SLAVE_SEL_MASK, cowork_source_sel);1758 break;1759 case MT8188_AFE_IO_ETDM1_OUT:1760 reg = ETDM_COWORK_CON0;1761 mask = ETDM_OUT1_SLAVE_SEL_MASK;1762 val = FIELD_PREP(ETDM_OUT1_SLAVE_SEL_MASK, cowork_source_sel);1763 break;1764 case MT8188_AFE_IO_ETDM2_OUT:1765 reg = ETDM_COWORK_CON2;1766 mask = ETDM_OUT2_SLAVE_SEL_MASK;1767 val = FIELD_PREP(ETDM_OUT2_SLAVE_SEL_MASK, cowork_source_sel);1768 break;1769 case MT8188_AFE_IO_ETDM3_OUT:1770 reg = ETDM_COWORK_CON2;1771 mask = ETDM_OUT3_SLAVE_SEL_MASK;1772 val = FIELD_PREP(ETDM_OUT3_SLAVE_SEL_MASK, cowork_source_sel);1773 break;1774 default:1775 return 0;1776 }1777 1778 regmap_update_bits(afe->regmap, reg, mask, val);1779 1780 return 0;1781}1782 1783static int mt8188_etdm_sync_mode_mst(struct mtk_base_afe *afe, int dai_id)1784{1785 struct mt8188_afe_private *afe_priv = afe->platform_priv;1786 struct mtk_dai_etdm_priv *etdm_data;1787 struct etdm_con_reg etdm_reg;1788 unsigned int reg = 0;1789 unsigned int mask;1790 unsigned int val;1791 int cowork_source_sel;1792 int ret;1793 1794 if (!is_valid_etdm_dai(dai_id))1795 return -EINVAL;1796 etdm_data = afe_priv->dai_priv[dai_id];1797 1798 cowork_source_sel = etdm_cowork_sync_sel(etdm_data->cowork_source_id);1799 if (cowork_source_sel < 0)1800 return cowork_source_sel;1801 1802 switch (dai_id) {1803 case MT8188_AFE_IO_ETDM1_IN:1804 reg = ETDM_COWORK_CON1;1805 mask = ETDM_IN1_SYNC_SEL_MASK;1806 val = FIELD_PREP(ETDM_IN1_SYNC_SEL_MASK, cowork_source_sel);1807 break;1808 case MT8188_AFE_IO_ETDM2_IN:1809 reg = ETDM_COWORK_CON2;1810 mask = ETDM_IN2_SYNC_SEL_MASK;1811 val = FIELD_PREP(ETDM_IN2_SYNC_SEL_MASK, cowork_source_sel);1812 break;1813 case MT8188_AFE_IO_ETDM1_OUT:1814 reg = ETDM_COWORK_CON0;1815 mask = ETDM_OUT1_SYNC_SEL_MASK;1816 val = FIELD_PREP(ETDM_OUT1_SYNC_SEL_MASK, cowork_source_sel);1817 break;1818 case MT8188_AFE_IO_ETDM2_OUT:1819 reg = ETDM_COWORK_CON2;1820 mask = ETDM_OUT2_SYNC_SEL_MASK;1821 val = FIELD_PREP(ETDM_OUT2_SYNC_SEL_MASK, cowork_source_sel);1822 break;1823 case MT8188_AFE_IO_ETDM3_OUT:1824 reg = ETDM_COWORK_CON2;1825 mask = ETDM_OUT3_SYNC_SEL_MASK;1826 val = FIELD_PREP(ETDM_OUT3_SYNC_SEL_MASK, cowork_source_sel);1827 break;1828 default:1829 return 0;1830 }1831 1832 ret = get_etdm_reg(dai_id, &etdm_reg);1833 if (ret < 0)1834 return ret;1835 1836 regmap_update_bits(afe->regmap, reg, mask, val);1837 1838 regmap_set_bits(afe->regmap, etdm_reg.con0, ETDM_CON0_SYNC_MODE);1839 1840 return 0;1841}1842 1843static int mt8188_etdm_sync_mode_configure(struct mtk_base_afe *afe, int dai_id)1844{1845 struct mt8188_afe_private *afe_priv = afe->platform_priv;1846 struct mtk_dai_etdm_priv *etdm_data;1847 1848 if (!is_valid_etdm_dai(dai_id))1849 return -EINVAL;1850 etdm_data = afe_priv->dai_priv[dai_id];1851 1852 if (etdm_data->cowork_source_id == COWORK_ETDM_NONE)1853 return 0;1854 1855 if (etdm_data->slave_mode)1856 mt8188_etdm_sync_mode_slv(afe, dai_id);1857 else1858 mt8188_etdm_sync_mode_mst(afe, dai_id);1859 1860 return 0;1861}1862 1863/* dai ops */1864static int mtk_dai_etdm_fifo_mode(struct mtk_base_afe *afe,1865 int dai_id, unsigned int rate)1866{1867 unsigned int mode = 0;1868 unsigned int reg = 0;1869 unsigned int val = 0;1870 unsigned int mask = (ETDM_IN_AFIFO_MODE_MASK | ETDM_IN_USE_AFIFO);1871 1872 if (rate != 0)1873 mode = mt8188_afe_fs_timing(rate);1874 1875 switch (dai_id) {1876 case MT8188_AFE_IO_ETDM1_IN:1877 reg = ETDM_IN1_AFIFO_CON;1878 if (rate == 0)1879 mode = MT8188_ETDM_IN1_1X_EN;1880 break;1881 case MT8188_AFE_IO_ETDM2_IN:1882 reg = ETDM_IN2_AFIFO_CON;1883 if (rate == 0)1884 mode = MT8188_ETDM_IN2_1X_EN;1885 break;1886 default:1887 return -EINVAL;1888 }1889 1890 val = (mode | ETDM_IN_USE_AFIFO);1891 1892 regmap_update_bits(afe->regmap, reg, mask, val);1893 return 0;1894}1895 1896static int mtk_dai_etdm_in_configure(struct mtk_base_afe *afe,1897 unsigned int rate,1898 unsigned int channels,1899 int dai_id)1900{1901 struct mt8188_afe_private *afe_priv = afe->platform_priv;1902 struct mtk_dai_etdm_priv *etdm_data;1903 struct etdm_con_reg etdm_reg;1904 bool slave_mode;1905 unsigned int data_mode;1906 unsigned int lrck_width;1907 unsigned int val = 0;1908 unsigned int mask = 0;1909 int ret;1910 int i;1911 1912 if (!is_valid_etdm_dai(dai_id))1913 return -EINVAL;1914 etdm_data = afe_priv->dai_priv[dai_id];1915 slave_mode = etdm_data->slave_mode;1916 data_mode = etdm_data->data_mode;1917 lrck_width = etdm_data->lrck_width;1918 1919 dev_dbg(afe->dev, "%s rate %u channels %u, id %d\n",1920 __func__, rate, channels, dai_id);1921 1922 ret = get_etdm_reg(dai_id, &etdm_reg);1923 if (ret < 0)1924 return ret;1925 1926 /* afifo */1927 if (slave_mode)1928 mtk_dai_etdm_fifo_mode(afe, dai_id, 0);1929 else1930 mtk_dai_etdm_fifo_mode(afe, dai_id, rate);1931 1932 /* con1 */1933 if (lrck_width > 0) {1934 mask |= (ETDM_IN_CON1_LRCK_AUTO_MODE |1935 ETDM_IN_CON1_LRCK_WIDTH_MASK);1936 val |= FIELD_PREP(ETDM_IN_CON1_LRCK_WIDTH_MASK, lrck_width - 1);1937 }1938 regmap_update_bits(afe->regmap, etdm_reg.con1, mask, val);1939 1940 mask = 0;1941 val = 0;1942 1943 /* con2 */1944 if (!slave_mode) {1945 mask |= ETDM_IN_CON2_UPDATE_GAP_MASK;1946 if (rate == 352800 || rate == 384000)1947 val |= FIELD_PREP(ETDM_IN_CON2_UPDATE_GAP_MASK, 4);1948 else1949 val |= FIELD_PREP(ETDM_IN_CON2_UPDATE_GAP_MASK, 3);1950 }1951 mask |= (ETDM_IN_CON2_MULTI_IP_2CH_MODE |1952 ETDM_IN_CON2_MULTI_IP_TOTAL_CH_MASK);1953 if (data_mode == MTK_DAI_ETDM_DATA_MULTI_PIN) {1954 val |= ETDM_IN_CON2_MULTI_IP_2CH_MODE |1955 FIELD_PREP(ETDM_IN_CON2_MULTI_IP_TOTAL_CH_MASK, channels - 1);1956 }1957 regmap_update_bits(afe->regmap, etdm_reg.con2, mask, val);1958 1959 mask = 0;1960 val = 0;1961 1962 /* con3 */1963 mask |= ETDM_IN_CON3_DISABLE_OUT_MASK;1964 for (i = 0; i < channels; i += 2) {1965 if (etdm_data->in_disable_ch[i] &&1966 etdm_data->in_disable_ch[i + 1])1967 val |= ETDM_IN_CON3_DISABLE_OUT(i >> 1);1968 }1969 if (!slave_mode) {1970 mask |= ETDM_IN_CON3_FS_MASK;1971 val |= FIELD_PREP(ETDM_IN_CON3_FS_MASK, get_etdm_fs_timing(rate));1972 }1973 regmap_update_bits(afe->regmap, etdm_reg.con3, mask, val);1974 1975 mask = 0;1976 val = 0;1977 1978 /* con4 */1979 mask |= (ETDM_IN_CON4_MASTER_LRCK_INV | ETDM_IN_CON4_MASTER_BCK_INV |1980 ETDM_IN_CON4_SLAVE_LRCK_INV | ETDM_IN_CON4_SLAVE_BCK_INV);1981 if (slave_mode) {1982 if (etdm_data->lrck_inv)1983 val |= ETDM_IN_CON4_SLAVE_LRCK_INV;1984 if (etdm_data->bck_inv)1985 val |= ETDM_IN_CON4_SLAVE_BCK_INV;1986 } else {1987 if (etdm_data->lrck_inv)1988 val |= ETDM_IN_CON4_MASTER_LRCK_INV;1989 if (etdm_data->bck_inv)1990 val |= ETDM_IN_CON4_MASTER_BCK_INV;1991 }1992 regmap_update_bits(afe->regmap, etdm_reg.con4, mask, val);1993 1994 mask = 0;1995 val = 0;1996 1997 /* con5 */1998 mask |= ETDM_IN_CON5_LR_SWAP_MASK;1999 mask |= ETDM_IN_CON5_ENABLE_ODD_MASK;2000 for (i = 0; i < channels; i += 2) {2001 if (etdm_data->in_disable_ch[i] &&2002 !etdm_data->in_disable_ch[i + 1]) {2003 val |= ETDM_IN_CON5_LR_SWAP(i >> 1);2004 val |= ETDM_IN_CON5_ENABLE_ODD(i >> 1);2005 } else if (!etdm_data->in_disable_ch[i] &&2006 etdm_data->in_disable_ch[i + 1]) {2007 val |= ETDM_IN_CON5_ENABLE_ODD(i >> 1);2008 }2009 }2010 regmap_update_bits(afe->regmap, etdm_reg.con5, mask, val);2011 return 0;2012}2013 2014static int mtk_dai_etdm_out_configure(struct mtk_base_afe *afe,2015 unsigned int rate,2016 unsigned int channels,2017 int dai_id)2018{2019 struct mt8188_afe_private *afe_priv = afe->platform_priv;2020 struct mtk_dai_etdm_priv *etdm_data;2021 struct etdm_con_reg etdm_reg;2022 bool slave_mode;2023 unsigned int lrck_width;2024 unsigned int val = 0;2025 unsigned int mask = 0;2026 int fs = 0;2027 int ret;2028 2029 if (!is_valid_etdm_dai(dai_id))2030 return -EINVAL;2031 etdm_data = afe_priv->dai_priv[dai_id];2032 slave_mode = etdm_data->slave_mode;2033 lrck_width = etdm_data->lrck_width;2034 2035 dev_dbg(afe->dev, "%s rate %u channels %u, id %d\n",2036 __func__, rate, channels, dai_id);2037 2038 ret = get_etdm_reg(dai_id, &etdm_reg);2039 if (ret < 0)2040 return ret;2041 2042 /* con0 */2043 mask = ETDM_OUT_CON0_RELATCH_DOMAIN_MASK;2044 val = FIELD_PREP(ETDM_OUT_CON0_RELATCH_DOMAIN_MASK,2045 ETDM_RELATCH_TIMING_A1A2SYS);2046 regmap_update_bits(afe->regmap, etdm_reg.con0, mask, val);2047 2048 mask = 0;2049 val = 0;2050 2051 /* con1 */2052 if (lrck_width > 0) {2053 mask |= (ETDM_OUT_CON1_LRCK_AUTO_MODE |2054 ETDM_OUT_CON1_LRCK_WIDTH_MASK);2055 val |= FIELD_PREP(ETDM_OUT_CON1_LRCK_WIDTH_MASK, lrck_width - 1);2056 }2057 regmap_update_bits(afe->regmap, etdm_reg.con1, mask, val);2058 2059 mask = 0;2060 val = 0;2061 2062 if (!slave_mode) {2063 /* con4 */2064 mask |= ETDM_OUT_CON4_FS_MASK;2065 val |= FIELD_PREP(ETDM_OUT_CON4_FS_MASK, get_etdm_fs_timing(rate));2066 }2067 2068 mask |= ETDM_OUT_CON4_RELATCH_EN_MASK;2069 if (dai_id == MT8188_AFE_IO_ETDM1_OUT)2070 fs = MT8188_ETDM_OUT1_1X_EN;2071 else if (dai_id == MT8188_AFE_IO_ETDM2_OUT)2072 fs = MT8188_ETDM_OUT2_1X_EN;2073 2074 val |= FIELD_PREP(ETDM_OUT_CON4_RELATCH_EN_MASK, fs);2075 2076 regmap_update_bits(afe->regmap, etdm_reg.con4, mask, val);2077 2078 mask = 0;2079 val = 0;2080 2081 /* con5 */2082 mask |= (ETDM_OUT_CON5_MASTER_LRCK_INV | ETDM_OUT_CON5_MASTER_BCK_INV |2083 ETDM_OUT_CON5_SLAVE_LRCK_INV | ETDM_OUT_CON5_SLAVE_BCK_INV);2084 if (slave_mode) {2085 if (etdm_data->lrck_inv)2086 val |= ETDM_OUT_CON5_SLAVE_LRCK_INV;2087 if (etdm_data->bck_inv)2088 val |= ETDM_OUT_CON5_SLAVE_BCK_INV;2089 } else {2090 if (etdm_data->lrck_inv)2091 val |= ETDM_OUT_CON5_MASTER_LRCK_INV;2092 if (etdm_data->bck_inv)2093 val |= ETDM_OUT_CON5_MASTER_BCK_INV;2094 }2095 regmap_update_bits(afe->regmap, etdm_reg.con5, mask, val);2096 2097 return 0;2098}2099 2100static int mtk_dai_etdm_configure(struct mtk_base_afe *afe,2101 unsigned int rate,2102 unsigned int channels,2103 unsigned int bit_width,2104 int dai_id)2105{2106 struct mt8188_afe_private *afe_priv = afe->platform_priv;2107 struct mtk_dai_etdm_priv *etdm_data;2108 struct etdm_con_reg etdm_reg;2109 bool slave_mode;2110 unsigned int etdm_channels;2111 unsigned int val = 0;2112 unsigned int mask = 0;2113 unsigned int bck;2114 unsigned int wlen = get_etdm_wlen(bit_width);2115 int ret;2116 2117 if (!is_valid_etdm_dai(dai_id))2118 return -EINVAL;2119 etdm_data = afe_priv->dai_priv[dai_id];2120 slave_mode = etdm_data->slave_mode;2121 etdm_data->rate = rate;2122 2123 ret = get_etdm_reg(dai_id, &etdm_reg);2124 if (ret < 0)2125 return ret;2126 2127 dev_dbg(afe->dev, "%s fmt %u data %u lrck %d-%u bck %d, slv %u\n",2128 __func__, etdm_data->format, etdm_data->data_mode,2129 etdm_data->lrck_inv, etdm_data->lrck_width, etdm_data->bck_inv,2130 etdm_data->slave_mode);2131 dev_dbg(afe->dev, "%s rate %u channels %u bitwidth %u, id %d\n",2132 __func__, rate, channels, bit_width, dai_id);2133 2134 etdm_channels = (etdm_data->data_mode == MTK_DAI_ETDM_DATA_ONE_PIN) ?2135 get_etdm_ch_fixup(channels) : 2;2136 2137 bck = rate * etdm_channels * wlen;2138 if (bck > MT8188_ETDM_NORMAL_MAX_BCK_RATE) {2139 dev_err(afe->dev, "%s bck rate %u not support\n",2140 __func__, bck);2141 return -EINVAL;2142 }2143 2144 /* con0 */2145 mask |= ETDM_CON0_BIT_LEN_MASK;2146 val |= FIELD_PREP(ETDM_CON0_BIT_LEN_MASK, bit_width - 1);2147 mask |= ETDM_CON0_WORD_LEN_MASK;2148 val |= FIELD_PREP(ETDM_CON0_WORD_LEN_MASK, wlen - 1);2149 mask |= ETDM_CON0_FORMAT_MASK;2150 val |= FIELD_PREP(ETDM_CON0_FORMAT_MASK, etdm_data->format);2151 mask |= ETDM_CON0_CH_NUM_MASK;2152 val |= FIELD_PREP(ETDM_CON0_CH_NUM_MASK, etdm_channels - 1);2153 2154 mask |= ETDM_CON0_SLAVE_MODE;2155 if (slave_mode) {2156 if (dai_id == MT8188_AFE_IO_ETDM1_OUT) {2157 dev_err(afe->dev, "%s id %d only support master mode\n",2158 __func__, dai_id);2159 return -EINVAL;2160 }2161 val |= ETDM_CON0_SLAVE_MODE;2162 }2163 regmap_update_bits(afe->regmap, etdm_reg.con0, mask, val);2164 2165 if (get_etdm_dir(dai_id) == ETDM_IN)2166 mtk_dai_etdm_in_configure(afe, rate, channels, dai_id);2167 else2168 mtk_dai_etdm_out_configure(afe, rate, channels, dai_id);2169 2170 return 0;2171}2172 2173static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,2174 struct snd_pcm_hw_params *params,2175 struct snd_soc_dai *dai)2176{2177 unsigned int rate = params_rate(params);2178 unsigned int bit_width = params_width(params);2179 unsigned int channels = params_channels(params);2180 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);2181 struct mt8188_afe_private *afe_priv = afe->platform_priv;2182 struct mtk_dai_etdm_priv *mst_etdm_data;2183 int mst_dai_id;2184 int slv_dai_id;2185 int ret;2186 int i;2187 2188 dev_dbg(afe->dev, "%s '%s' period %u-%u\n",2189 __func__, snd_pcm_stream_str(substream),2190 params_period_size(params), params_periods(params));2191 2192 if (is_cowork_mode(dai)) {2193 mst_dai_id = get_etdm_cowork_master_id(dai);2194 if (!is_valid_etdm_dai(mst_dai_id))2195 return -EINVAL;2196 2197 mst_etdm_data = afe_priv->dai_priv[mst_dai_id];2198 if (mst_etdm_data->slots)2199 channels = mst_etdm_data->slots;2200 2201 ret = mtk_dai_etdm_configure(afe, rate, channels,2202 bit_width, mst_dai_id);2203 if (ret)2204 return ret;2205 2206 for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {2207 slv_dai_id = mst_etdm_data->cowork_slv_id[i];2208 ret = mtk_dai_etdm_configure(afe, rate, channels,2209 bit_width, slv_dai_id);2210 if (ret)2211 return ret;2212 2213 ret = mt8188_etdm_sync_mode_configure(afe, slv_dai_id);2214 if (ret)2215 return ret;2216 }2217 } else {2218 if (!is_valid_etdm_dai(dai->id))2219 return -EINVAL;2220 mst_etdm_data = afe_priv->dai_priv[dai->id];2221 if (mst_etdm_data->slots)2222 channels = mst_etdm_data->slots;2223 2224 ret = mtk_dai_etdm_configure(afe, rate, channels,2225 bit_width, dai->id);2226 if (ret)2227 return ret;2228 }2229 2230 return 0;2231}2232 2233static int mtk_dai_etdm_cal_mclk(struct mtk_base_afe *afe, int freq, int dai_id)2234{2235 struct mt8188_afe_private *afe_priv = afe->platform_priv;2236 struct mtk_dai_etdm_priv *etdm_data;2237 int apll_rate;2238 int apll;2239 2240 if (!is_valid_etdm_dai(dai_id))2241 return -EINVAL;2242 etdm_data = afe_priv->dai_priv[dai_id];2243 2244 if (freq == 0) {2245 etdm_data->mclk_freq = freq;2246 return 0;2247 }2248 2249 if (etdm_data->mclk_fixed_apll == 0)2250 apll = mt8188_afe_get_default_mclk_source_by_rate(freq);2251 else2252 apll = etdm_data->mclk_apll;2253 2254 apll_rate = mt8188_afe_get_mclk_source_rate(afe, apll);2255 2256 if (freq > apll_rate) {2257 dev_err(afe->dev, "freq %d > apll rate %d\n", freq, apll_rate);2258 return -EINVAL;2259 }2260 2261 if (apll_rate % freq != 0) {2262 dev_err(afe->dev, "APLL%d cannot generate freq Hz\n", apll);2263 return -EINVAL;2264 }2265 2266 if (etdm_data->mclk_fixed_apll == 0)2267 etdm_data->mclk_apll = apll;2268 etdm_data->mclk_freq = freq;2269 2270 return 0;2271}2272 2273static int mtk_dai_etdm_set_sysclk(struct snd_soc_dai *dai,2274 int clk_id, unsigned int freq, int dir)2275{2276 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);2277 struct mt8188_afe_private *afe_priv = afe->platform_priv;2278 struct mtk_dai_etdm_priv *etdm_data;2279 int dai_id;2280 2281 dev_dbg(dai->dev, "%s id %d freq %u, dir %d\n",2282 __func__, dai->id, freq, dir);2283 if (is_cowork_mode(dai))2284 dai_id = get_etdm_cowork_master_id(dai);2285 else2286 dai_id = dai->id;2287 2288 if (!is_valid_etdm_dai(dai_id))2289 return -EINVAL;2290 etdm_data = afe_priv->dai_priv[dai_id];2291 etdm_data->mclk_dir = dir;2292 return mtk_dai_etdm_cal_mclk(afe, freq, dai_id);2293}2294 2295static int mtk_dai_etdm_set_tdm_slot(struct snd_soc_dai *dai,2296 unsigned int tx_mask, unsigned int rx_mask,2297 int slots, int slot_width)2298{2299 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);2300 struct mt8188_afe_private *afe_priv = afe->platform_priv;2301 struct mtk_dai_etdm_priv *etdm_data;2302 int dai_id;2303 2304 if (is_cowork_mode(dai))2305 dai_id = get_etdm_cowork_master_id(dai);2306 else2307 dai_id = dai->id;2308 2309 if (!is_valid_etdm_dai(dai_id))2310 return -EINVAL;2311 etdm_data = afe_priv->dai_priv[dai_id];2312 2313 dev_dbg(dai->dev, "%s id %d slot_width %d\n",2314 __func__, dai->id, slot_width);2315 2316 etdm_data->slots = slots;2317 etdm_data->lrck_width = slot_width;2318 return 0;2319}2320 2321static int mtk_dai_etdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)2322{2323 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);2324 struct mt8188_afe_private *afe_priv = afe->platform_priv;2325 struct mtk_dai_etdm_priv *etdm_data;2326 2327 if (!is_valid_etdm_dai(dai->id))2328 return -EINVAL;2329 etdm_data = afe_priv->dai_priv[dai->id];2330 2331 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {2332 case SND_SOC_DAIFMT_I2S:2333 etdm_data->format = MTK_DAI_ETDM_FORMAT_I2S;2334 break;2335 case SND_SOC_DAIFMT_LEFT_J:2336 etdm_data->format = MTK_DAI_ETDM_FORMAT_LJ;2337 break;2338 case SND_SOC_DAIFMT_RIGHT_J:2339 etdm_data->format = MTK_DAI_ETDM_FORMAT_RJ;2340 break;2341 case SND_SOC_DAIFMT_DSP_A:2342 etdm_data->format = MTK_DAI_ETDM_FORMAT_DSPA;2343 break;2344 case SND_SOC_DAIFMT_DSP_B:2345 etdm_data->format = MTK_DAI_ETDM_FORMAT_DSPB;2346 break;2347 default:2348 return -EINVAL;2349 }2350 2351 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {2352 case SND_SOC_DAIFMT_NB_NF:2353 etdm_data->bck_inv = false;2354 etdm_data->lrck_inv = false;2355 break;2356 case SND_SOC_DAIFMT_NB_IF:2357 etdm_data->bck_inv = false;2358 etdm_data->lrck_inv = true;2359 break;2360 case SND_SOC_DAIFMT_IB_NF:2361 etdm_data->bck_inv = true;2362 etdm_data->lrck_inv = false;2363 break;2364 case SND_SOC_DAIFMT_IB_IF:2365 etdm_data->bck_inv = true;2366 etdm_data->lrck_inv = true;2367 break;2368 default:2369 return -EINVAL;2370 }2371 2372 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {2373 case SND_SOC_DAIFMT_BC_FC:2374 etdm_data->slave_mode = true;2375 break;2376 case SND_SOC_DAIFMT_BP_FP:2377 etdm_data->slave_mode = false;2378 break;2379 default:2380 return -EINVAL;2381 }2382 2383 return 0;2384}2385 2386static unsigned int mtk_dai_get_dptx_ch_en(unsigned int channel)2387{2388 switch (channel) {2389 case 1 ... 2:2390 return AFE_DPTX_CON_CH_EN_2CH;2391 case 3 ... 4:2392 return AFE_DPTX_CON_CH_EN_4CH;2393 case 5 ... 6:2394 return AFE_DPTX_CON_CH_EN_6CH;2395 case 7 ... 8:2396 return AFE_DPTX_CON_CH_EN_8CH;2397 default:2398 return AFE_DPTX_CON_CH_EN_2CH;2399 }2400}2401 2402static unsigned int mtk_dai_get_dptx_ch(unsigned int ch)2403{2404 return (ch > 2) ?2405 AFE_DPTX_CON_CH_NUM_8CH : AFE_DPTX_CON_CH_NUM_2CH;2406}2407 2408static unsigned int mtk_dai_get_dptx_wlen(snd_pcm_format_t format)2409{2410 return snd_pcm_format_physical_width(format) <= 16 ?2411 AFE_DPTX_CON_16BIT : AFE_DPTX_CON_24BIT;2412}2413 2414static int mtk_dai_hdmitx_dptx_hw_params(struct snd_pcm_substream *substream,2415 struct snd_pcm_hw_params *params,2416 struct snd_soc_dai *dai)2417{2418 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);2419 struct mt8188_afe_private *afe_priv = afe->platform_priv;2420 struct mtk_dai_etdm_priv *etdm_data;2421 unsigned int rate = params_rate(params);2422 unsigned int channels = params_channels(params);2423 snd_pcm_format_t format = params_format(params);2424 int width = snd_pcm_format_physical_width(format);2425 int ret;2426 2427 if (!is_valid_etdm_dai(dai->id))2428 return -EINVAL;2429 etdm_data = afe_priv->dai_priv[dai->id];2430 2431 /* dptx configure */2432 if (dai->id == MT8188_AFE_IO_DPTX) {2433 regmap_update_bits(afe->regmap, AFE_DPTX_CON,2434 AFE_DPTX_CON_CH_EN_MASK,2435 mtk_dai_get_dptx_ch_en(channels));2436 regmap_update_bits(afe->regmap, AFE_DPTX_CON,2437 AFE_DPTX_CON_CH_NUM_MASK,2438 mtk_dai_get_dptx_ch(channels));2439 regmap_update_bits(afe->regmap, AFE_DPTX_CON,2440 AFE_DPTX_CON_16BIT_MASK,2441 mtk_dai_get_dptx_wlen(format));2442 2443 if (mtk_dai_get_dptx_ch(channels) == AFE_DPTX_CON_CH_NUM_8CH) {2444 etdm_data->data_mode = MTK_DAI_ETDM_DATA_ONE_PIN;2445 channels = 8;2446 } else {2447 channels = 2;2448 }2449 } else {2450 etdm_data->data_mode = MTK_DAI_ETDM_DATA_MULTI_PIN;2451 }2452 2453 ret = mtk_dai_etdm_configure(afe, rate, channels, width, dai->id);2454 2455 return ret;2456}2457 2458static int mtk_dai_hdmitx_dptx_set_sysclk(struct snd_soc_dai *dai,2459 int clk_id,2460 unsigned int freq,2461 int dir)2462{2463 struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);2464 struct mt8188_afe_private *afe_priv = afe->platform_priv;2465 struct mtk_dai_etdm_priv *etdm_data;2466 2467 if (!is_valid_etdm_dai(dai->id))2468 return -EINVAL;2469 etdm_data = afe_priv->dai_priv[dai->id];2470 2471 dev_dbg(dai->dev, "%s id %d freq %u, dir %d\n",2472 __func__, dai->id, freq, dir);2473 2474 etdm_data->mclk_dir = dir;2475 return mtk_dai_etdm_cal_mclk(afe, freq, dai->id);2476}2477 2478static const struct snd_soc_dai_ops mtk_dai_etdm_ops = {2479 .hw_params = mtk_dai_etdm_hw_params,2480 .set_sysclk = mtk_dai_etdm_set_sysclk,2481 .set_fmt = mtk_dai_etdm_set_fmt,2482 .set_tdm_slot = mtk_dai_etdm_set_tdm_slot,2483};2484 2485static const struct snd_soc_dai_ops mtk_dai_hdmitx_dptx_ops = {2486 .hw_params = mtk_dai_hdmitx_dptx_hw_params,2487 .set_sysclk = mtk_dai_hdmitx_dptx_set_sysclk,2488 .set_fmt = mtk_dai_etdm_set_fmt,2489};2490 2491/* dai driver */2492#define MTK_ETDM_RATES (SNDRV_PCM_RATE_8000_192000)2493 2494#define MTK_ETDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\2495 SNDRV_PCM_FMTBIT_S24_LE |\2496 SNDRV_PCM_FMTBIT_S32_LE)2497 2498static struct snd_soc_dai_driver mtk_dai_etdm_driver[] = {2499 {2500 .name = "DPTX",2501 .id = MT8188_AFE_IO_DPTX,2502 .playback = {2503 .stream_name = "DPTX",2504 .channels_min = 1,2505 .channels_max = 8,2506 .rates = MTK_ETDM_RATES,2507 .formats = MTK_ETDM_FORMATS,2508 },2509 .ops = &mtk_dai_hdmitx_dptx_ops,2510 },2511 {2512 .name = "ETDM1_IN",2513 .id = MT8188_AFE_IO_ETDM1_IN,2514 .capture = {2515 .stream_name = "ETDM1_IN",2516 .channels_min = 1,2517 .channels_max = 16,2518 .rates = MTK_ETDM_RATES,2519 .formats = MTK_ETDM_FORMATS,2520 },2521 .ops = &mtk_dai_etdm_ops,2522 },2523 {2524 .name = "ETDM2_IN",2525 .id = MT8188_AFE_IO_ETDM2_IN,2526 .capture = {2527 .stream_name = "ETDM2_IN",2528 .channels_min = 1,2529 .channels_max = 16,2530 .rates = MTK_ETDM_RATES,2531 .formats = MTK_ETDM_FORMATS,2532 },2533 .ops = &mtk_dai_etdm_ops,2534 },2535 {2536 .name = "ETDM1_OUT",2537 .id = MT8188_AFE_IO_ETDM1_OUT,2538 .playback = {2539 .stream_name = "ETDM1_OUT",2540 .channels_min = 1,2541 .channels_max = 16,2542 .rates = MTK_ETDM_RATES,2543 .formats = MTK_ETDM_FORMATS,2544 },2545 .ops = &mtk_dai_etdm_ops,2546 },2547 {2548 .name = "ETDM2_OUT",2549 .id = MT8188_AFE_IO_ETDM2_OUT,2550 .playback = {2551 .stream_name = "ETDM2_OUT",2552 .channels_min = 1,2553 .channels_max = 16,2554 .rates = MTK_ETDM_RATES,2555 .formats = MTK_ETDM_FORMATS,2556 },2557 .ops = &mtk_dai_etdm_ops,2558 },2559 {2560 .name = "ETDM3_OUT",2561 .id = MT8188_AFE_IO_ETDM3_OUT,2562 .playback = {2563 .stream_name = "ETDM3_OUT",2564 .channels_min = 1,2565 .channels_max = 8,2566 .rates = MTK_ETDM_RATES,2567 .formats = MTK_ETDM_FORMATS,2568 },2569 .ops = &mtk_dai_hdmitx_dptx_ops,2570 },2571};2572 2573static void mt8188_etdm_update_sync_info(struct mtk_base_afe *afe)2574{2575 struct mt8188_afe_private *afe_priv = afe->platform_priv;2576 struct mtk_dai_etdm_priv *etdm_data;2577 struct mtk_dai_etdm_priv *mst_data;2578 int mst_dai_id;2579 int i;2580 2581 for (i = MT8188_AFE_IO_ETDM_START; i < MT8188_AFE_IO_ETDM_END; i++) {2582 etdm_data = afe_priv->dai_priv[i];2583 if (etdm_data->cowork_source_id != COWORK_ETDM_NONE) {2584 mst_dai_id = etdm_data->cowork_source_id;2585 mst_data = afe_priv->dai_priv[mst_dai_id];2586 if (mst_data->cowork_source_id != COWORK_ETDM_NONE)2587 dev_err(afe->dev, "%s [%d] wrong sync source\n",2588 __func__, i);2589 mst_data->cowork_slv_id[mst_data->cowork_slv_count] = i;2590 mst_data->cowork_slv_count++;2591 }2592 }2593}2594 2595static void mt8188_dai_etdm_parse_of(struct mtk_base_afe *afe)2596{2597 const struct device_node *of_node = afe->dev->of_node;2598 struct mt8188_afe_private *afe_priv = afe->platform_priv;2599 struct mtk_dai_etdm_priv *etdm_data;2600 char prop[48];2601 u8 disable_chn[MT8188_ETDM_MAX_CHANNELS];2602 int max_chn = MT8188_ETDM_MAX_CHANNELS;2603 unsigned int sync_id;2604 u32 sel;2605 int ret;2606 int dai_id;2607 int i, j;2608 struct {2609 const char *name;2610 const unsigned int sync_id;2611 } of_afe_etdms[MT8188_AFE_IO_ETDM_NUM] = {2612 {"etdm-in1", ETDM_SYNC_FROM_IN1},2613 {"etdm-in2", ETDM_SYNC_FROM_IN2},2614 {"etdm-out1", ETDM_SYNC_FROM_OUT1},2615 {"etdm-out2", ETDM_SYNC_FROM_OUT2},2616 {"etdm-out3", ETDM_SYNC_FROM_OUT3},2617 };2618 2619 for (i = 0; i < MT8188_AFE_IO_ETDM_NUM; i++) {2620 dai_id = ETDM_TO_DAI_ID(i);2621 etdm_data = afe_priv->dai_priv[dai_id];2622 2623 snprintf(prop, sizeof(prop), "mediatek,%s-multi-pin-mode",2624 of_afe_etdms[i].name);2625 2626 etdm_data->data_mode = of_property_read_bool(of_node, prop);2627 2628 snprintf(prop, sizeof(prop), "mediatek,%s-cowork-source",2629 of_afe_etdms[i].name);2630 2631 ret = of_property_read_u32(of_node, prop, &sel);2632 if (ret == 0) {2633 if (sel >= MT8188_AFE_IO_ETDM_NUM) {2634 dev_err(afe->dev, "%s invalid id=%d\n",2635 __func__, sel);2636 etdm_data->cowork_source_id = COWORK_ETDM_NONE;2637 } else {2638 sync_id = of_afe_etdms[sel].sync_id;2639 etdm_data->cowork_source_id =2640 sync_to_dai_id(sync_id);2641 }2642 } else {2643 etdm_data->cowork_source_id = COWORK_ETDM_NONE;2644 }2645 }2646 2647 /* etdm in only */2648 for (i = 0; i < 2; i++) {2649 dai_id = ETDM_TO_DAI_ID(i);2650 etdm_data = afe_priv->dai_priv[dai_id];2651 2652 snprintf(prop, sizeof(prop), "mediatek,%s-chn-disabled",2653 of_afe_etdms[i].name);2654 2655 ret = of_property_read_variable_u8_array(of_node, prop,2656 disable_chn,2657 1, max_chn);2658 if (ret < 0)2659 continue;2660 2661 for (j = 0; j < ret; j++) {2662 if (disable_chn[j] >= MT8188_ETDM_MAX_CHANNELS)2663 dev_err(afe->dev, "%s [%d] invalid chn %u\n",2664 __func__, j, disable_chn[j]);2665 else2666 etdm_data->in_disable_ch[disable_chn[j]] = true;2667 }2668 }2669 mt8188_etdm_update_sync_info(afe);2670}2671 2672static int init_etdm_priv_data(struct mtk_base_afe *afe)2673{2674 struct mt8188_afe_private *afe_priv = afe->platform_priv;2675 struct mtk_dai_etdm_priv *etdm_priv;2676 int i;2677 2678 for (i = MT8188_AFE_IO_ETDM_START; i < MT8188_AFE_IO_ETDM_END; i++) {2679 etdm_priv = devm_kzalloc(afe->dev,2680 sizeof(struct mtk_dai_etdm_priv),2681 GFP_KERNEL);2682 if (!etdm_priv)2683 return -ENOMEM;2684 2685 afe_priv->dai_priv[i] = etdm_priv;2686 }2687 2688 afe_priv->dai_priv[MT8188_AFE_IO_DPTX] =2689 afe_priv->dai_priv[MT8188_AFE_IO_ETDM3_OUT];2690 2691 mt8188_dai_etdm_parse_of(afe);2692 return 0;2693}2694 2695int mt8188_dai_etdm_register(struct mtk_base_afe *afe)2696{2697 struct mtk_base_afe_dai *dai;2698 2699 dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);2700 if (!dai)2701 return -ENOMEM;2702 2703 list_add(&dai->list, &afe->sub_dais);2704 2705 dai->dai_drivers = mtk_dai_etdm_driver;2706 dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_etdm_driver);2707 2708 dai->dapm_widgets = mtk_dai_etdm_widgets;2709 dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_etdm_widgets);2710 dai->dapm_routes = mtk_dai_etdm_routes;2711 dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_etdm_routes);2712 dai->controls = mtk_dai_etdm_controls;2713 dai->num_controls = ARRAY_SIZE(mtk_dai_etdm_controls);2714 2715 return init_etdm_priv_data(afe);2716}2717