File Index
Files and directories
Sign in
FILE

mt8186-dai-i2s.c

File preview with syntax highlighting.

linux-6.19.14/sound/soc/mediatek/mt8186/mt8186-dai-i2s.c C
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// MediaTek ALSA SoC Audio DAI I2S Control
   4//
   5// Copyright (c) 2022 MediaTek Inc.
   6// Author: Jiaxin Yu <jiaxin.yu@mediatek.com>
   7
   8#include <linux/bitops.h>
   9#include <linux/regmap.h>
  10#include <sound/pcm_params.h>
  11#include "mt8186-afe-clk.h"
  12#include "mt8186-afe-common.h"
  13#include "mt8186-afe-gpio.h"
  14#include "mt8186-interconnection.h"
  15
  16enum {
  17	I2S_FMT_EIAJ = 0,
  18	I2S_FMT_I2S = 1,
  19};
  20
  21enum {
  22	I2S_WLEN_16_BIT = 0,
  23	I2S_WLEN_32_BIT = 1,
  24};
  25
  26enum {
  27	I2S_HD_NORMAL = 0,
  28	I2S_HD_LOW_JITTER = 1,
  29};
  30
  31enum {
  32	I2S1_SEL_O28_O29 = 0,
  33	I2S1_SEL_O03_O04 = 1,
  34};
  35
  36enum {
  37	I2S_IN_PAD_CONNSYS = 0,
  38	I2S_IN_PAD_IO_MUX = 1,
  39};
  40
  41struct mtk_afe_i2s_priv {
  42	int id;
  43	int rate; /* for determine which apll to use */
  44	int low_jitter_en;
  45	int master; /* only i2s0 has slave mode*/
  46
  47	int share_i2s_id;
  48
  49	int mclk_id;
  50	int mclk_rate;
  51	int mclk_apll;
  52};
  53
  54static unsigned int get_i2s_wlen(snd_pcm_format_t format)
  55{
  56	return snd_pcm_format_physical_width(format) <= 16 ?
  57	       I2S_WLEN_16_BIT : I2S_WLEN_32_BIT;
  58}
  59
  60#define MTK_AFE_I2S0_KCONTROL_NAME "I2S0_HD_Mux"
  61#define MTK_AFE_I2S1_KCONTROL_NAME "I2S1_HD_Mux"
  62#define MTK_AFE_I2S2_KCONTROL_NAME "I2S2_HD_Mux"
  63#define MTK_AFE_I2S3_KCONTROL_NAME "I2S3_HD_Mux"
  64#define MTK_AFE_I2S0_SRC_KCONTROL_NAME "I2S0_SRC_Mux"
  65
  66#define I2S0_HD_EN_W_NAME "I2S0_HD_EN"
  67#define I2S1_HD_EN_W_NAME "I2S1_HD_EN"
  68#define I2S2_HD_EN_W_NAME "I2S2_HD_EN"
  69#define I2S3_HD_EN_W_NAME "I2S3_HD_EN"
  70
  71#define I2S0_MCLK_EN_W_NAME "I2S0_MCLK_EN"
  72#define I2S1_MCLK_EN_W_NAME "I2S1_MCLK_EN"
  73#define I2S2_MCLK_EN_W_NAME "I2S2_MCLK_EN"
  74#define I2S3_MCLK_EN_W_NAME "I2S3_MCLK_EN"
  75
  76static int get_i2s_id_by_name(struct mtk_base_afe *afe,
  77			      const char *name)
  78{
  79	if (strncmp(name, "I2S0", 4) == 0)
  80		return MT8186_DAI_I2S_0;
  81	else if (strncmp(name, "I2S1", 4) == 0)
  82		return MT8186_DAI_I2S_1;
  83	else if (strncmp(name, "I2S2", 4) == 0)
  84		return MT8186_DAI_I2S_2;
  85	else if (strncmp(name, "I2S3", 4) == 0)
  86		return MT8186_DAI_I2S_3;
  87
  88	return -EINVAL;
  89}
  90
  91static struct mtk_afe_i2s_priv *get_i2s_priv_by_name(struct mtk_base_afe *afe,
  92						     const char *name)
  93{
  94	struct mt8186_afe_private *afe_priv = afe->platform_priv;
  95	int dai_id = get_i2s_id_by_name(afe, name);
  96
  97	if (dai_id < 0)
  98		return NULL;
  99
 100	return afe_priv->dai_priv[dai_id];
 101}
 102
 103/* low jitter control */
 104static const char * const mt8186_i2s_hd_str[] = {
 105	"Normal", "Low_Jitter"
 106};
 107
 108static const struct soc_enum mt8186_i2s_enum[] = {
 109	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(mt8186_i2s_hd_str),
 110			    mt8186_i2s_hd_str),
 111};
 112
 113static int mt8186_i2s_hd_get(struct snd_kcontrol *kcontrol,
 114			     struct snd_ctl_elem_value *ucontrol)
 115{
 116	struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
 117	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 118	struct mtk_afe_i2s_priv *i2s_priv;
 119
 120	i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
 121	ucontrol->value.integer.value[0] = i2s_priv->low_jitter_en;
 122
 123	return 0;
 124}
 125
 126static int mt8186_i2s_hd_set(struct snd_kcontrol *kcontrol,
 127			     struct snd_ctl_elem_value *ucontrol)
 128{
 129	struct snd_soc_component *cmpnt = snd_kcontrol_chip(kcontrol);
 130	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 131	struct mtk_afe_i2s_priv *i2s_priv;
 132	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 133	int hd_en;
 134
 135	if (ucontrol->value.enumerated.item[0] >= e->items)
 136		return -EINVAL;
 137
 138	hd_en = ucontrol->value.integer.value[0];
 139
 140	dev_dbg(afe->dev, "%s(), kcontrol name %s, hd_en %d\n",
 141		__func__, kcontrol->id.name, hd_en);
 142
 143	i2s_priv = get_i2s_priv_by_name(afe, kcontrol->id.name);
 144	if (i2s_priv->low_jitter_en == hd_en)
 145		return 0;
 146
 147	i2s_priv->low_jitter_en = hd_en;
 148
 149	return 1;
 150}
 151
 152static const struct snd_kcontrol_new mtk_dai_i2s_controls[] = {
 153	SOC_ENUM_EXT(MTK_AFE_I2S0_KCONTROL_NAME, mt8186_i2s_enum[0],
 154		     mt8186_i2s_hd_get, mt8186_i2s_hd_set),
 155	SOC_ENUM_EXT(MTK_AFE_I2S1_KCONTROL_NAME, mt8186_i2s_enum[0],
 156		     mt8186_i2s_hd_get, mt8186_i2s_hd_set),
 157	SOC_ENUM_EXT(MTK_AFE_I2S2_KCONTROL_NAME, mt8186_i2s_enum[0],
 158		     mt8186_i2s_hd_get, mt8186_i2s_hd_set),
 159	SOC_ENUM_EXT(MTK_AFE_I2S3_KCONTROL_NAME, mt8186_i2s_enum[0],
 160		     mt8186_i2s_hd_get, mt8186_i2s_hd_set),
 161};
 162
 163/* dai component */
 164/* i2s virtual mux to output widget */
 165static const char * const i2s_mux_map[] = {
 166	"Normal", "Dummy_Widget",
 167};
 168
 169static int i2s_mux_map_value[] = {
 170	0, 1,
 171};
 172
 173static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s_mux_map_enum,
 174					      SND_SOC_NOPM,
 175					      0,
 176					      1,
 177					      i2s_mux_map,
 178					      i2s_mux_map_value);
 179
 180static const struct snd_kcontrol_new i2s0_in_mux_control =
 181	SOC_DAPM_ENUM("I2S0 In Select", i2s_mux_map_enum);
 182
 183static const struct snd_kcontrol_new i2s1_out_mux_control =
 184	SOC_DAPM_ENUM("I2S1 Out Select", i2s_mux_map_enum);
 185
 186static const struct snd_kcontrol_new i2s2_in_mux_control =
 187	SOC_DAPM_ENUM("I2S2 In Select", i2s_mux_map_enum);
 188
 189static const struct snd_kcontrol_new i2s3_out_mux_control =
 190	SOC_DAPM_ENUM("I2S3 Out Select", i2s_mux_map_enum);
 191
 192/* i2s in lpbk */
 193static const char * const i2s_lpbk_mux_map[] = {
 194	"Normal", "Lpbk",
 195};
 196
 197static int i2s_lpbk_mux_map_value[] = {
 198	0, 1,
 199};
 200
 201static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s0_lpbk_mux_map_enum,
 202					      AFE_I2S_CON,
 203					      I2S_LOOPBACK_SFT,
 204					      1,
 205					      i2s_lpbk_mux_map,
 206					      i2s_lpbk_mux_map_value);
 207
 208static const struct snd_kcontrol_new i2s0_lpbk_mux_control =
 209	SOC_DAPM_ENUM("I2S Lpbk Select", i2s0_lpbk_mux_map_enum);
 210
 211static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(i2s2_lpbk_mux_map_enum,
 212					      AFE_I2S_CON2,
 213					      I2S3_LOOPBACK_SFT,
 214					      1,
 215					      i2s_lpbk_mux_map,
 216					      i2s_lpbk_mux_map_value);
 217
 218static const struct snd_kcontrol_new i2s2_lpbk_mux_control =
 219	SOC_DAPM_ENUM("I2S Lpbk Select", i2s2_lpbk_mux_map_enum);
 220
 221/* interconnection */
 222static const struct snd_kcontrol_new mtk_i2s3_ch1_mix[] = {
 223	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN0,
 224				    I_DL1_CH1, 1, 0),
 225	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN0,
 226				    I_DL2_CH1, 1, 0),
 227	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN0,
 228				    I_DL3_CH1, 1, 0),
 229	SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH1 Switch", AFE_CONN0,
 230				    I_DL12_CH1, 1, 0),
 231	SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH3 Switch", AFE_CONN0,
 232				    I_DL12_CH3, 1, 0),
 233	SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN0_1,
 234				    I_DL6_CH1, 1, 0),
 235	SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN0_1,
 236				    I_DL4_CH1, 1, 0),
 237	SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN0_1,
 238				    I_DL5_CH1, 1, 0),
 239	SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1 Switch", AFE_CONN0_1,
 240				    I_DL8_CH1, 1, 0),
 241	SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1 Switch", AFE_CONN0,
 242				    I_GAIN1_OUT_CH1, 1, 0),
 243	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN0,
 244				    I_ADDA_UL_CH1, 1, 0),
 245	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN0,
 246				    I_ADDA_UL_CH2, 1, 0),
 247	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3 Switch", AFE_CONN0,
 248				    I_ADDA_UL_CH3, 1, 0),
 249	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1 Switch", AFE_CONN0,
 250				    I_PCM_1_CAP_CH1, 1, 0),
 251	SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH1 Switch", AFE_CONN0_1,
 252				    I_SRC_1_OUT_CH1, 1, 0),
 253};
 254
 255static const struct snd_kcontrol_new mtk_i2s3_ch2_mix[] = {
 256	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN1,
 257				    I_DL1_CH2, 1, 0),
 258	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN1,
 259				    I_DL2_CH2, 1, 0),
 260	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN1,
 261				    I_DL3_CH2, 1, 0),
 262	SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH2 Switch", AFE_CONN1,
 263				    I_DL12_CH2, 1, 0),
 264	SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH4 Switch", AFE_CONN1,
 265				    I_DL12_CH4, 1, 0),
 266	SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN1_1,
 267				    I_DL6_CH2, 1, 0),
 268	SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN1_1,
 269				    I_DL4_CH2, 1, 0),
 270	SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN1_1,
 271				    I_DL5_CH2, 1, 0),
 272	SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2 Switch", AFE_CONN1_1,
 273				    I_DL8_CH2, 1, 0),
 274	SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2 Switch", AFE_CONN1,
 275				    I_GAIN1_OUT_CH2, 1, 0),
 276	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN1,
 277				    I_ADDA_UL_CH1, 1, 0),
 278	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN1,
 279				    I_ADDA_UL_CH2, 1, 0),
 280	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH3 Switch", AFE_CONN1,
 281				    I_ADDA_UL_CH3, 1, 0),
 282	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2 Switch", AFE_CONN1,
 283				    I_PCM_1_CAP_CH2, 1, 0),
 284	SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2 Switch", AFE_CONN1,
 285				    I_PCM_2_CAP_CH2, 1, 0),
 286	SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH2 Switch", AFE_CONN1_1,
 287				    I_SRC_1_OUT_CH2, 1, 0),
 288};
 289
 290static const struct snd_kcontrol_new mtk_i2s1_ch1_mix[] = {
 291	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH1 Switch", AFE_CONN28,
 292				    I_DL1_CH1, 1, 0),
 293	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH1 Switch", AFE_CONN28,
 294				    I_DL2_CH1, 1, 0),
 295	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH1 Switch", AFE_CONN28,
 296				    I_DL3_CH1, 1, 0),
 297	SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH1 Switch", AFE_CONN28,
 298				    I_DL12_CH1, 1, 0),
 299	SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH3 Switch", AFE_CONN28,
 300				    I_DL12_CH3, 1, 0),
 301	SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH1 Switch", AFE_CONN28_1,
 302				    I_DL6_CH1, 1, 0),
 303	SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH1 Switch", AFE_CONN28_1,
 304				    I_DL4_CH1, 1, 0),
 305	SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH1 Switch", AFE_CONN28_1,
 306				    I_DL5_CH1, 1, 0),
 307	SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH1 Switch", AFE_CONN28_1,
 308				    I_DL8_CH1, 1, 0),
 309	SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH1 Switch", AFE_CONN28,
 310				    I_GAIN1_OUT_CH1, 1, 0),
 311	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH1 Switch", AFE_CONN28,
 312				    I_ADDA_UL_CH1, 1, 0),
 313	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH1 Switch", AFE_CONN28,
 314				    I_PCM_1_CAP_CH1, 1, 0),
 315	SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH1 Switch", AFE_CONN28_1,
 316				    I_SRC_1_OUT_CH1, 1, 0),
 317};
 318
 319static const struct snd_kcontrol_new mtk_i2s1_ch2_mix[] = {
 320	SOC_DAPM_SINGLE_AUTODISABLE("DL1_CH2 Switch", AFE_CONN29,
 321				    I_DL1_CH2, 1, 0),
 322	SOC_DAPM_SINGLE_AUTODISABLE("DL2_CH2 Switch", AFE_CONN29,
 323				    I_DL2_CH2, 1, 0),
 324	SOC_DAPM_SINGLE_AUTODISABLE("DL3_CH2 Switch", AFE_CONN29,
 325				    I_DL3_CH2, 1, 0),
 326	SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH2 Switch", AFE_CONN29,
 327				    I_DL12_CH2, 1, 0),
 328	SOC_DAPM_SINGLE_AUTODISABLE("DL12_CH4 Switch", AFE_CONN29,
 329				    I_DL12_CH4, 1, 0),
 330	SOC_DAPM_SINGLE_AUTODISABLE("DL6_CH2 Switch", AFE_CONN29_1,
 331				    I_DL6_CH2, 1, 0),
 332	SOC_DAPM_SINGLE_AUTODISABLE("DL4_CH2 Switch", AFE_CONN29_1,
 333				    I_DL4_CH2, 1, 0),
 334	SOC_DAPM_SINGLE_AUTODISABLE("DL5_CH2 Switch", AFE_CONN29_1,
 335				    I_DL5_CH2, 1, 0),
 336	SOC_DAPM_SINGLE_AUTODISABLE("DL8_CH2 Switch", AFE_CONN29_1,
 337				    I_DL8_CH2, 1, 0),
 338	SOC_DAPM_SINGLE_AUTODISABLE("GAIN1_OUT_CH2 Switch", AFE_CONN29,
 339				    I_GAIN1_OUT_CH2, 1, 0),
 340	SOC_DAPM_SINGLE_AUTODISABLE("ADDA_UL_CH2 Switch", AFE_CONN29,
 341				    I_ADDA_UL_CH2, 1, 0),
 342	SOC_DAPM_SINGLE_AUTODISABLE("PCM_1_CAP_CH2 Switch", AFE_CONN29,
 343				    I_PCM_1_CAP_CH2, 1, 0),
 344	SOC_DAPM_SINGLE_AUTODISABLE("PCM_2_CAP_CH2 Switch", AFE_CONN29,
 345				    I_PCM_2_CAP_CH2, 1, 0),
 346	SOC_DAPM_SINGLE_AUTODISABLE("SRC_1_OUT_CH2 Switch", AFE_CONN29_1,
 347				    I_SRC_1_OUT_CH2, 1, 0),
 348};
 349
 350enum {
 351	SUPPLY_SEQ_APLL,
 352	SUPPLY_SEQ_I2S_MCLK_EN,
 353	SUPPLY_SEQ_I2S_HD_EN,
 354	SUPPLY_SEQ_I2S_EN,
 355};
 356
 357static int mtk_i2s_en_event(struct snd_soc_dapm_widget *w,
 358			    struct snd_kcontrol *kcontrol,
 359			    int event)
 360{
 361	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 362	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 363	struct mtk_afe_i2s_priv *i2s_priv;
 364
 365	i2s_priv = get_i2s_priv_by_name(afe, w->name);
 366
 367	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
 368		__func__, w->name, event);
 369
 370	switch (event) {
 371	case SND_SOC_DAPM_PRE_PMU:
 372		mt8186_afe_gpio_request(afe->dev, true, i2s_priv->id, 0);
 373		break;
 374	case SND_SOC_DAPM_POST_PMD:
 375		mt8186_afe_gpio_request(afe->dev, false, i2s_priv->id, 0);
 376		break;
 377	default:
 378		break;
 379	}
 380
 381	return 0;
 382}
 383
 384static int mtk_apll_event(struct snd_soc_dapm_widget *w,
 385			  struct snd_kcontrol *kcontrol,
 386			  int event)
 387{
 388	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 389	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 390
 391	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
 392		__func__, w->name, event);
 393
 394	switch (event) {
 395	case SND_SOC_DAPM_PRE_PMU:
 396		if (snd_soc_dapm_widget_name_cmp(w, APLL1_W_NAME) == 0)
 397			mt8186_apll1_enable(afe);
 398		else
 399			mt8186_apll2_enable(afe);
 400		break;
 401	case SND_SOC_DAPM_POST_PMD:
 402		if (snd_soc_dapm_widget_name_cmp(w, APLL1_W_NAME) == 0)
 403			mt8186_apll1_disable(afe);
 404		else
 405			mt8186_apll2_disable(afe);
 406		break;
 407	default:
 408		break;
 409	}
 410
 411	return 0;
 412}
 413
 414static int mtk_mclk_en_event(struct snd_soc_dapm_widget *w,
 415			     struct snd_kcontrol *kcontrol,
 416			     int event)
 417{
 418	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 419	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 420	struct mtk_afe_i2s_priv *i2s_priv;
 421
 422	dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n",
 423		__func__, w->name, event);
 424
 425	i2s_priv = get_i2s_priv_by_name(afe, w->name);
 426
 427	switch (event) {
 428	case SND_SOC_DAPM_PRE_PMU:
 429		mt8186_mck_enable(afe, i2s_priv->mclk_id, i2s_priv->mclk_rate);
 430		break;
 431	case SND_SOC_DAPM_POST_PMD:
 432		i2s_priv->mclk_rate = 0;
 433		mt8186_mck_disable(afe, i2s_priv->mclk_id);
 434		break;
 435	default:
 436		break;
 437	}
 438
 439	return 0;
 440}
 441
 442static const struct snd_soc_dapm_widget mtk_dai_i2s_widgets[] = {
 443	SND_SOC_DAPM_INPUT("CONNSYS"),
 444
 445	SND_SOC_DAPM_MIXER("I2S1_CH1", SND_SOC_NOPM, 0, 0,
 446			   mtk_i2s1_ch1_mix,
 447			   ARRAY_SIZE(mtk_i2s1_ch1_mix)),
 448	SND_SOC_DAPM_MIXER("I2S1_CH2", SND_SOC_NOPM, 0, 0,
 449			   mtk_i2s1_ch2_mix,
 450			   ARRAY_SIZE(mtk_i2s1_ch2_mix)),
 451
 452	SND_SOC_DAPM_MIXER("I2S3_CH1", SND_SOC_NOPM, 0, 0,
 453			   mtk_i2s3_ch1_mix,
 454			   ARRAY_SIZE(mtk_i2s3_ch1_mix)),
 455	SND_SOC_DAPM_MIXER("I2S3_CH2", SND_SOC_NOPM, 0, 0,
 456			   mtk_i2s3_ch2_mix,
 457			   ARRAY_SIZE(mtk_i2s3_ch2_mix)),
 458
 459	/* i2s en*/
 460	SND_SOC_DAPM_SUPPLY_S("I2S0_EN", SUPPLY_SEQ_I2S_EN,
 461			      AFE_I2S_CON, I2S_EN_SFT, 0,
 462			      mtk_i2s_en_event,
 463			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 464	SND_SOC_DAPM_SUPPLY_S("I2S1_EN", SUPPLY_SEQ_I2S_EN,
 465			      AFE_I2S_CON1, I2S_EN_SFT, 0,
 466			      mtk_i2s_en_event,
 467			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 468	SND_SOC_DAPM_SUPPLY_S("I2S2_EN", SUPPLY_SEQ_I2S_EN,
 469			      AFE_I2S_CON2, I2S_EN_SFT, 0,
 470			      mtk_i2s_en_event,
 471			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 472	SND_SOC_DAPM_SUPPLY_S("I2S3_EN", SUPPLY_SEQ_I2S_EN,
 473			      AFE_I2S_CON3, I2S_EN_SFT, 0,
 474			      mtk_i2s_en_event,
 475			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 476	/* i2s hd en */
 477	SND_SOC_DAPM_SUPPLY_S(I2S0_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
 478			      AFE_I2S_CON, I2S1_HD_EN_SFT, 0, NULL,
 479			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 480	SND_SOC_DAPM_SUPPLY_S(I2S1_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
 481			      AFE_I2S_CON1, I2S2_HD_EN_SFT, 0, NULL,
 482			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 483	SND_SOC_DAPM_SUPPLY_S(I2S2_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
 484			      AFE_I2S_CON2, I2S3_HD_EN_SFT, 0, NULL,
 485			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 486	SND_SOC_DAPM_SUPPLY_S(I2S3_HD_EN_W_NAME, SUPPLY_SEQ_I2S_HD_EN,
 487			      AFE_I2S_CON3, I2S4_HD_EN_SFT, 0, NULL,
 488			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 489
 490	/* i2s mclk en */
 491	SND_SOC_DAPM_SUPPLY_S(I2S0_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
 492			      SND_SOC_NOPM, 0, 0,
 493			      mtk_mclk_en_event,
 494			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 495	SND_SOC_DAPM_SUPPLY_S(I2S1_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
 496			      SND_SOC_NOPM, 0, 0,
 497			      mtk_mclk_en_event,
 498			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 499	SND_SOC_DAPM_SUPPLY_S(I2S2_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
 500			      SND_SOC_NOPM, 0, 0,
 501			      mtk_mclk_en_event,
 502			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 503	SND_SOC_DAPM_SUPPLY_S(I2S3_MCLK_EN_W_NAME, SUPPLY_SEQ_I2S_MCLK_EN,
 504			      SND_SOC_NOPM, 0, 0,
 505			      mtk_mclk_en_event,
 506			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 507
 508	/* apll */
 509	SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL,
 510			      SND_SOC_NOPM, 0, 0,
 511			      mtk_apll_event,
 512			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 513	SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL,
 514			      SND_SOC_NOPM, 0, 0,
 515			      mtk_apll_event,
 516			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 517
 518	/* allow i2s on without codec on */
 519	SND_SOC_DAPM_OUTPUT("I2S_DUMMY_OUT"),
 520	SND_SOC_DAPM_MUX("I2S1_Out_Mux",
 521			 SND_SOC_NOPM, 0, 0, &i2s1_out_mux_control),
 522	SND_SOC_DAPM_MUX("I2S3_Out_Mux",
 523			 SND_SOC_NOPM, 0, 0, &i2s3_out_mux_control),
 524	SND_SOC_DAPM_INPUT("I2S_DUMMY_IN"),
 525	SND_SOC_DAPM_MUX("I2S0_In_Mux",
 526			 SND_SOC_NOPM, 0, 0, &i2s0_in_mux_control),
 527	SND_SOC_DAPM_MUX("I2S2_In_Mux",
 528			 SND_SOC_NOPM, 0, 0, &i2s2_in_mux_control),
 529
 530	/* i2s in lpbk */
 531	SND_SOC_DAPM_MUX("I2S0_Lpbk_Mux",
 532			 SND_SOC_NOPM, 0, 0, &i2s0_lpbk_mux_control),
 533	SND_SOC_DAPM_MUX("I2S2_Lpbk_Mux",
 534			 SND_SOC_NOPM, 0, 0, &i2s2_lpbk_mux_control),
 535};
 536
 537static int mtk_afe_i2s_share_connect(struct snd_soc_dapm_widget *source,
 538				     struct snd_soc_dapm_widget *sink)
 539{
 540	struct snd_soc_dapm_widget *w = sink;
 541	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 542	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 543	struct mtk_afe_i2s_priv *i2s_priv;
 544
 545	i2s_priv = get_i2s_priv_by_name(afe, sink->name);
 546	if (i2s_priv->share_i2s_id < 0)
 547		return 0;
 548
 549	return i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name);
 550}
 551
 552static int mtk_afe_i2s_hd_connect(struct snd_soc_dapm_widget *source,
 553				  struct snd_soc_dapm_widget *sink)
 554{
 555	struct snd_soc_dapm_widget *w = sink;
 556	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 557	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 558	struct mtk_afe_i2s_priv *i2s_priv;
 559
 560	i2s_priv = get_i2s_priv_by_name(afe, sink->name);
 561	if (get_i2s_id_by_name(afe, sink->name) ==
 562	    get_i2s_id_by_name(afe, source->name))
 563		return i2s_priv->low_jitter_en;
 564
 565	/* check if share i2s need hd en */
 566	if (i2s_priv->share_i2s_id < 0)
 567		return 0;
 568
 569	if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))
 570		return i2s_priv->low_jitter_en;
 571
 572	return 0;
 573}
 574
 575static int mtk_afe_i2s_apll_connect(struct snd_soc_dapm_widget *source,
 576				    struct snd_soc_dapm_widget *sink)
 577{
 578	struct snd_soc_dapm_widget *w = sink;
 579	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 580	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 581	struct mtk_afe_i2s_priv *i2s_priv;
 582	int cur_apll;
 583	int i2s_need_apll;
 584
 585	i2s_priv = get_i2s_priv_by_name(afe, w->name);
 586	/* which apll */
 587	cur_apll = mt8186_get_apll_by_name(afe, source->name);
 588	/* choose APLL from i2s rate */
 589	i2s_need_apll = mt8186_get_apll_by_rate(afe, i2s_priv->rate);
 590
 591	return (i2s_need_apll == cur_apll) ? 1 : 0;
 592}
 593
 594static int mtk_afe_i2s_mclk_connect(struct snd_soc_dapm_widget *source,
 595				    struct snd_soc_dapm_widget *sink)
 596{
 597	struct snd_soc_dapm_widget *w = sink;
 598	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 599	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 600	struct mtk_afe_i2s_priv *i2s_priv;
 601
 602	i2s_priv = get_i2s_priv_by_name(afe, sink->name);
 603	if (get_i2s_id_by_name(afe, sink->name) ==
 604	    get_i2s_id_by_name(afe, source->name))
 605		return (i2s_priv->mclk_rate > 0) ? 1 : 0;
 606
 607	/* check if share i2s need mclk */
 608	if (i2s_priv->share_i2s_id < 0)
 609		return 0;
 610
 611	if (i2s_priv->share_i2s_id == get_i2s_id_by_name(afe, source->name))
 612		return (i2s_priv->mclk_rate > 0) ? 1 : 0;
 613
 614	return 0;
 615}
 616
 617static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source,
 618				     struct snd_soc_dapm_widget *sink)
 619{
 620	struct snd_soc_dapm_widget *w = sink;
 621	struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
 622	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
 623	struct mtk_afe_i2s_priv *i2s_priv;
 624	int cur_apll;
 625
 626	i2s_priv = get_i2s_priv_by_name(afe, w->name);
 627	/* which apll */
 628	cur_apll = mt8186_get_apll_by_name(afe, source->name);
 629
 630	return (i2s_priv->mclk_apll == cur_apll) ? 1 : 0;
 631}
 632
 633static const struct snd_soc_dapm_route mtk_dai_i2s_routes[] = {
 634	{"Connsys I2S", NULL, "CONNSYS"},
 635
 636	/* i2s0 */
 637	{"I2S0", NULL, "I2S0_EN"},
 638	{"I2S0", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
 639	{"I2S0", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
 640	{"I2S0", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
 641
 642	{"I2S0", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 643	{"I2S0", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 644	{"I2S0", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 645	{"I2S0", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 646	{I2S0_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
 647	{I2S0_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
 648
 649	{"I2S0", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 650	{"I2S0", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 651	{"I2S0", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 652	{"I2S0", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 653	{I2S0_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
 654	{I2S0_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
 655
 656	/* i2s1 */
 657	{"I2S1_CH1", "DL1_CH1 Switch", "DL1"},
 658	{"I2S1_CH2", "DL1_CH2 Switch", "DL1"},
 659
 660	{"I2S1_CH1", "DL1_CH1 Switch", "DSP_DL1_VIRT"},
 661	{"I2S1_CH2", "DL1_CH2 Switch", "DSP_DL1_VIRT"},
 662
 663	{"I2S1_CH1", "DL2_CH1 Switch", "DL2"},
 664	{"I2S1_CH2", "DL2_CH2 Switch", "DL2"},
 665
 666	{"I2S1_CH1", "DL2_CH1 Switch", "DSP_DL2_VIRT"},
 667	{"I2S1_CH2", "DL2_CH2 Switch", "DSP_DL2_VIRT"},
 668
 669	{"I2S1_CH1", "DL3_CH1 Switch", "DL3"},
 670	{"I2S1_CH2", "DL3_CH2 Switch", "DL3"},
 671
 672	{"I2S1_CH1", "DL12_CH1 Switch", "DL12"},
 673	{"I2S1_CH2", "DL12_CH2 Switch", "DL12"},
 674
 675	{"I2S1_CH1", "DL12_CH3 Switch", "DL12"},
 676	{"I2S1_CH2", "DL12_CH4 Switch", "DL12"},
 677
 678	{"I2S1_CH1", "DL6_CH1 Switch", "DL6"},
 679	{"I2S1_CH2", "DL6_CH2 Switch", "DL6"},
 680
 681	{"I2S1_CH1", "DL4_CH1 Switch", "DL4"},
 682	{"I2S1_CH2", "DL4_CH2 Switch", "DL4"},
 683
 684	{"I2S1_CH1", "DL5_CH1 Switch", "DL5"},
 685	{"I2S1_CH2", "DL5_CH2 Switch", "DL5"},
 686
 687	{"I2S1_CH1", "DL8_CH1 Switch", "DL8"},
 688	{"I2S1_CH2", "DL8_CH2 Switch", "DL8"},
 689
 690	{"I2S1", NULL, "I2S1_CH1"},
 691	{"I2S1", NULL, "I2S1_CH2"},
 692
 693	{"I2S1", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
 694	{"I2S1", NULL, "I2S1_EN"},
 695	{"I2S1", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
 696	{"I2S1", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
 697
 698	{"I2S1", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 699	{"I2S1", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 700	{"I2S1", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 701	{"I2S1", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 702	{I2S1_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
 703	{I2S1_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
 704
 705	{"I2S1", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 706	{"I2S1", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 707	{"I2S1", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 708	{"I2S1", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 709	{I2S1_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
 710	{I2S1_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
 711
 712	/* i2s2 */
 713	{"I2S2", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
 714	{"I2S2", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
 715	{"I2S2", NULL, "I2S2_EN"},
 716	{"I2S2", NULL, "I2S3_EN", mtk_afe_i2s_share_connect},
 717
 718	{"I2S2", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 719	{"I2S2", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 720	{"I2S2", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 721	{"I2S2", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 722	{I2S2_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
 723	{I2S2_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
 724
 725	{"I2S2", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 726	{"I2S2", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 727	{"I2S2", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 728	{"I2S2", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 729	{I2S2_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
 730	{I2S2_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
 731
 732	/* i2s3 */
 733	{"I2S3_CH1", "DL1_CH1 Switch", "DL1"},
 734	{"I2S3_CH2", "DL1_CH2 Switch", "DL1"},
 735
 736	{"I2S3_CH1", "DL1_CH1 Switch", "DSP_DL1_VIRT"},
 737	{"I2S3_CH2", "DL1_CH2 Switch", "DSP_DL1_VIRT"},
 738
 739	{"I2S3_CH1", "DL2_CH1 Switch", "DL2"},
 740	{"I2S3_CH2", "DL2_CH2 Switch", "DL2"},
 741
 742	{"I2S3_CH1", "DL2_CH1 Switch", "DSP_DL2_VIRT"},
 743	{"I2S3_CH2", "DL2_CH2 Switch", "DSP_DL2_VIRT"},
 744
 745	{"I2S3_CH1", "DL3_CH1 Switch", "DL3"},
 746	{"I2S3_CH2", "DL3_CH2 Switch", "DL3"},
 747
 748	{"I2S3_CH1", "DL12_CH1 Switch", "DL12"},
 749	{"I2S3_CH2", "DL12_CH2 Switch", "DL12"},
 750
 751	{"I2S3_CH1", "DL12_CH3 Switch", "DL12"},
 752	{"I2S3_CH2", "DL12_CH4 Switch", "DL12"},
 753
 754	{"I2S3_CH1", "DL6_CH1 Switch", "DL6"},
 755	{"I2S3_CH2", "DL6_CH2 Switch", "DL6"},
 756
 757	{"I2S3_CH1", "DL4_CH1 Switch", "DL4"},
 758	{"I2S3_CH2", "DL4_CH2 Switch", "DL4"},
 759
 760	{"I2S3_CH1", "DL5_CH1 Switch", "DL5"},
 761	{"I2S3_CH2", "DL5_CH2 Switch", "DL5"},
 762
 763	{"I2S3_CH1", "DL8_CH1 Switch", "DL8"},
 764	{"I2S3_CH2", "DL8_CH2 Switch", "DL8"},
 765
 766	{"I2S3", NULL, "I2S3_CH1"},
 767	{"I2S3", NULL, "I2S3_CH2"},
 768
 769	{"I2S3", NULL, "I2S0_EN", mtk_afe_i2s_share_connect},
 770	{"I2S3", NULL, "I2S1_EN", mtk_afe_i2s_share_connect},
 771	{"I2S3", NULL, "I2S2_EN", mtk_afe_i2s_share_connect},
 772	{"I2S3", NULL, "I2S3_EN"},
 773
 774	{"I2S3", NULL, I2S0_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 775	{"I2S3", NULL, I2S1_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 776	{"I2S3", NULL, I2S2_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 777	{"I2S3", NULL, I2S3_HD_EN_W_NAME, mtk_afe_i2s_hd_connect},
 778	{I2S3_HD_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_i2s_apll_connect},
 779	{I2S3_HD_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_i2s_apll_connect},
 780
 781	{"I2S3", NULL, I2S0_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 782	{"I2S3", NULL, I2S1_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 783	{"I2S3", NULL, I2S2_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 784	{"I2S3", NULL, I2S3_MCLK_EN_W_NAME, mtk_afe_i2s_mclk_connect},
 785	{I2S3_MCLK_EN_W_NAME, NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect},
 786	{I2S3_MCLK_EN_W_NAME, NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect},
 787
 788	/* allow i2s on without codec on */
 789	{"I2S0", NULL, "I2S0_In_Mux"},
 790	{"I2S0_In_Mux", "Dummy_Widget", "I2S_DUMMY_IN"},
 791
 792	{"I2S1_Out_Mux", "Dummy_Widget", "I2S1"},
 793	{"I2S_DUMMY_OUT", NULL, "I2S1_Out_Mux"},
 794
 795	{"I2S2", NULL, "I2S2_In_Mux"},
 796	{"I2S2_In_Mux", "Dummy_Widget", "I2S_DUMMY_IN"},
 797
 798	{"I2S3_Out_Mux", "Dummy_Widget", "I2S3"},
 799	{"I2S_DUMMY_OUT", NULL, "I2S3_Out_Mux"},
 800
 801	/* i2s in lpbk */
 802	{"I2S0_Lpbk_Mux", "Lpbk", "I2S3"},
 803	{"I2S2_Lpbk_Mux", "Lpbk", "I2S1"},
 804	{"I2S0", NULL, "I2S0_Lpbk_Mux"},
 805	{"I2S2", NULL, "I2S2_Lpbk_Mux"},
 806};
 807
 808/* dai ops */
 809static int mtk_dai_connsys_i2s_hw_params(struct snd_pcm_substream *substream,
 810					 struct snd_pcm_hw_params *params,
 811					 struct snd_soc_dai *dai)
 812{
 813	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
 814	unsigned int rate = params_rate(params);
 815	unsigned int rate_reg = mt8186_rate_transform(afe->dev,
 816						      rate, dai->id);
 817	unsigned int i2s_con = 0;
 818
 819	dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
 820		__func__, dai->id, substream->stream, rate);
 821
 822	/* non-inverse, i2s mode, slave, 16bits, from connsys */
 823	i2s_con |= 0 << INV_PAD_CTRL_SFT;
 824	i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT;
 825	i2s_con |= 1 << I2S_SRC_SFT;
 826	i2s_con |= get_i2s_wlen(SNDRV_PCM_FORMAT_S16_LE) << I2S_WLEN_SFT;
 827	i2s_con |= 0 << I2SIN_PAD_SEL_SFT;
 828	regmap_write(afe->regmap, AFE_CONNSYS_I2S_CON, i2s_con);
 829
 830	/* use asrc */
 831	regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,
 832			   I2S_BYPSRC_MASK_SFT, 0);
 833
 834	/* slave mode, set i2s for asrc */
 835	regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,
 836			   I2S_MODE_MASK_SFT, rate_reg << I2S_MODE_SFT);
 837
 838	if (rate == 44100)
 839		regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x1b9000);
 840	else if (rate == 32000)
 841		regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x140000);
 842	else
 843		regmap_write(afe->regmap, AFE_ASRC_2CH_CON3, 0x1e0000);
 844
 845	/* Calibration setting */
 846	regmap_write(afe->regmap, AFE_ASRC_2CH_CON4, 0x140000);
 847	regmap_write(afe->regmap, AFE_ASRC_2CH_CON9, 0x36000);
 848	regmap_write(afe->regmap, AFE_ASRC_2CH_CON10, 0x2fc00);
 849	regmap_write(afe->regmap, AFE_ASRC_2CH_CON6, 0x7ef4);
 850	regmap_write(afe->regmap, AFE_ASRC_2CH_CON5, 0xff5986);
 851
 852	/* 0:Stereo 1:Mono */
 853	regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON2,
 854			   CHSET_IS_MONO_MASK_SFT, 0);
 855
 856	return 0;
 857}
 858
 859static int mtk_dai_connsys_i2s_trigger(struct snd_pcm_substream *substream,
 860				       int cmd, struct snd_soc_dai *dai)
 861{
 862	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
 863	struct mt8186_afe_private *afe_priv = afe->platform_priv;
 864
 865	dev_dbg(afe->dev, "%s(), cmd %d, stream %d\n",
 866		__func__, cmd, substream->stream);
 867
 868	switch (cmd) {
 869	case SNDRV_PCM_TRIGGER_START:
 870	case SNDRV_PCM_TRIGGER_RESUME:
 871		/* i2s enable */
 872		regmap_update_bits(afe->regmap,
 873				   AFE_CONNSYS_I2S_CON,
 874				   I2S_EN_MASK_SFT,
 875				   BIT(I2S_EN_SFT));
 876
 877		/* calibrator enable */
 878		regmap_update_bits(afe->regmap,
 879				   AFE_ASRC_2CH_CON5,
 880				   CALI_EN_MASK_SFT,
 881				   BIT(CALI_EN_SFT));
 882
 883		/* asrc enable */
 884		regmap_update_bits(afe->regmap,
 885				   AFE_ASRC_2CH_CON0,
 886				   CON0_CHSET_STR_CLR_MASK_SFT,
 887				   BIT(CON0_CHSET_STR_CLR_SFT));
 888		regmap_update_bits(afe->regmap,
 889				   AFE_ASRC_2CH_CON0,
 890				   CON0_ASM_ON_MASK_SFT,
 891				   BIT(CON0_ASM_ON_SFT));
 892
 893		afe_priv->dai_on[dai->id] = true;
 894		return 0;
 895	case SNDRV_PCM_TRIGGER_STOP:
 896	case SNDRV_PCM_TRIGGER_SUSPEND:
 897		regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON0,
 898				   CON0_ASM_ON_MASK_SFT, 0);
 899		regmap_update_bits(afe->regmap, AFE_ASRC_2CH_CON5,
 900				   CALI_EN_MASK_SFT, 0);
 901
 902		/* i2s disable */
 903		regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,
 904				   I2S_EN_MASK_SFT, 0);
 905
 906		/* bypass asrc */
 907		regmap_update_bits(afe->regmap, AFE_CONNSYS_I2S_CON,
 908				   I2S_BYPSRC_MASK_SFT, BIT(I2S_BYPSRC_SFT));
 909
 910		afe_priv->dai_on[dai->id] = false;
 911		return 0;
 912	default:
 913		return -EINVAL;
 914	}
 915	return 0;
 916}
 917
 918static const struct snd_soc_dai_ops mtk_dai_connsys_i2s_ops = {
 919	.hw_params = mtk_dai_connsys_i2s_hw_params,
 920	.trigger = mtk_dai_connsys_i2s_trigger,
 921};
 922
 923/* i2s */
 924static int mtk_dai_i2s_config(struct mtk_base_afe *afe,
 925			      struct snd_pcm_hw_params *params,
 926			      int i2s_id)
 927{
 928	struct mt8186_afe_private *afe_priv = afe->platform_priv;
 929	struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[i2s_id];
 930
 931	unsigned int rate = params_rate(params);
 932	unsigned int rate_reg = mt8186_rate_transform(afe->dev,
 933						      rate, i2s_id);
 934	snd_pcm_format_t format = params_format(params);
 935	unsigned int i2s_con = 0;
 936	int ret;
 937
 938	dev_dbg(afe->dev, "%s(), id %d, rate %d, format %d\n",
 939		__func__, i2s_id, rate, format);
 940
 941	i2s_priv->rate = rate;
 942
 943	switch (i2s_id) {
 944	case MT8186_DAI_I2S_0:
 945		i2s_con = I2S_IN_PAD_IO_MUX << I2SIN_PAD_SEL_SFT;
 946		i2s_con |= rate_reg << I2S_OUT_MODE_SFT;
 947		i2s_con |= I2S_FMT_I2S << I2S_FMT_SFT;
 948		i2s_con |= get_i2s_wlen(format) << I2S_WLEN_SFT;
 949		regmap_update_bits(afe->regmap, AFE_I2S_CON,
 950				   0xffffeffa, i2s_con);
 951		break;
 952	case MT8186_DAI_I2S_1:
 953		i2s_con = I2S1_SEL_O28_O29 << I2S2_SEL_O03_O04_SFT;
 954		i2s_con |= rate_reg << I2S2_OUT_MODE_SFT;
 955		i2s_con |= I2S_FMT_I2S << I2S2_FMT_SFT;
 956		i2s_con |= get_i2s_wlen(format) << I2S2_WLEN_SFT;
 957		regmap_update_bits(afe->regmap, AFE_I2S_CON1,
 958				   0xffffeffa, i2s_con);
 959		break;
 960	case MT8186_DAI_I2S_2:
 961		i2s_con = 8 << I2S3_UPDATE_WORD_SFT;
 962		i2s_con |= rate_reg << I2S3_OUT_MODE_SFT;
 963		i2s_con |= I2S_FMT_I2S << I2S3_FMT_SFT;
 964		i2s_con |= get_i2s_wlen(format) << I2S3_WLEN_SFT;
 965		regmap_update_bits(afe->regmap, AFE_I2S_CON2,
 966				   0xffffeffa, i2s_con);
 967		break;
 968	case MT8186_DAI_I2S_3:
 969		i2s_con = rate_reg << I2S4_OUT_MODE_SFT;
 970		i2s_con |= I2S_FMT_I2S << I2S4_FMT_SFT;
 971		i2s_con |= get_i2s_wlen(format) << I2S4_WLEN_SFT;
 972		regmap_update_bits(afe->regmap, AFE_I2S_CON3,
 973				   0xffffeffa, i2s_con);
 974		break;
 975	default:
 976		dev_err(afe->dev, "%s(), id %d not support\n",
 977			__func__, i2s_id);
 978		return -EINVAL;
 979	}
 980
 981	/* set share i2s */
 982	if (i2s_priv->share_i2s_id >= 0) {
 983		ret = mtk_dai_i2s_config(afe, params, i2s_priv->share_i2s_id);
 984		if (ret)
 985			return ret;
 986	}
 987
 988	return 0;
 989}
 990
 991static int mtk_dai_i2s_hw_params(struct snd_pcm_substream *substream,
 992				 struct snd_pcm_hw_params *params,
 993				 struct snd_soc_dai *dai)
 994{
 995	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
 996
 997	return mtk_dai_i2s_config(afe, params, dai->id);
 998}
 999
1000static int mtk_dai_i2s_set_sysclk(struct snd_soc_dai *dai,
1001				  int clk_id, unsigned int freq, int dir)
1002{
1003	struct mtk_base_afe *afe = dev_get_drvdata(dai->dev);
1004	struct mt8186_afe_private *afe_priv = afe->platform_priv;
1005	struct mtk_afe_i2s_priv *i2s_priv = afe_priv->dai_priv[dai->id];
1006	int apll;
1007	int apll_rate;
1008
1009	if (dir != SND_SOC_CLOCK_OUT) {
1010		dev_err(afe->dev, "%s(), dir != SND_SOC_CLOCK_OUT", __func__);
1011		return -EINVAL;
1012	}
1013
1014	dev_dbg(afe->dev, "%s(), freq %d\n", __func__, freq);
1015
1016	apll = mt8186_get_apll_by_rate(afe, freq);
1017	apll_rate = mt8186_get_apll_rate(afe, apll);
1018
1019	if (freq > apll_rate) {
1020		dev_err(afe->dev, "%s(), freq > apll rate", __func__);
1021		return -EINVAL;
1022	}
1023
1024	if (apll_rate % freq != 0) {
1025		dev_err(afe->dev, "%s(), APLL cannot generate freq Hz", __func__);
1026		return -EINVAL;
1027	}
1028
1029	i2s_priv->mclk_rate = freq;
1030	i2s_priv->mclk_apll = apll;
1031
1032	if (i2s_priv->share_i2s_id > 0) {
1033		struct mtk_afe_i2s_priv *share_i2s_priv;
1034
1035		share_i2s_priv = afe_priv->dai_priv[i2s_priv->share_i2s_id];
1036		if (!share_i2s_priv) {
1037			dev_err(afe->dev, "%s(), share_i2s_priv == NULL", __func__);
1038			return -EINVAL;
1039		}
1040
1041		share_i2s_priv->mclk_rate = i2s_priv->mclk_rate;
1042		share_i2s_priv->mclk_apll = i2s_priv->mclk_apll;
1043	}
1044
1045	return 0;
1046}
1047
1048static const struct snd_soc_dai_ops mtk_dai_i2s_ops = {
1049	.hw_params = mtk_dai_i2s_hw_params,
1050	.set_sysclk = mtk_dai_i2s_set_sysclk,
1051};
1052
1053/* dai driver */
1054#define MTK_CONNSYS_I2S_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
1055
1056#define MTK_I2S_RATES (SNDRV_PCM_RATE_8000_48000 |\
1057		       SNDRV_PCM_RATE_88200 |\
1058		       SNDRV_PCM_RATE_96000 |\
1059		       SNDRV_PCM_RATE_176400 |\
1060		       SNDRV_PCM_RATE_192000)
1061
1062#define MTK_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1063			 SNDRV_PCM_FMTBIT_S24_LE |\
1064			 SNDRV_PCM_FMTBIT_S32_LE)
1065
1066static struct snd_soc_dai_driver mtk_dai_i2s_driver[] = {
1067	{
1068		.name = "CONNSYS_I2S",
1069		.id = MT8186_DAI_CONNSYS_I2S,
1070		.capture = {
1071			.stream_name = "Connsys I2S",
1072			.channels_min = 1,
1073			.channels_max = 2,
1074			.rates = MTK_CONNSYS_I2S_RATES,
1075			.formats = MTK_I2S_FORMATS,
1076		},
1077		.ops = &mtk_dai_connsys_i2s_ops,
1078	},
1079	{
1080		.name = "I2S0",
1081		.id = MT8186_DAI_I2S_0,
1082		.capture = {
1083			.stream_name = "I2S0",
1084			.channels_min = 1,
1085			.channels_max = 2,
1086			.rates = MTK_I2S_RATES,
1087			.formats = MTK_I2S_FORMATS,
1088		},
1089		.ops = &mtk_dai_i2s_ops,
1090	},
1091	{
1092		.name = "I2S1",
1093		.id = MT8186_DAI_I2S_1,
1094		.playback = {
1095			.stream_name = "I2S1",
1096			.channels_min = 1,
1097			.channels_max = 2,
1098			.rates = MTK_I2S_RATES,
1099			.formats = MTK_I2S_FORMATS,
1100		},
1101		.ops = &mtk_dai_i2s_ops,
1102	},
1103	{
1104		.name = "I2S2",
1105		.id = MT8186_DAI_I2S_2,
1106		.capture = {
1107			.stream_name = "I2S2",
1108			.channels_min = 1,
1109			.channels_max = 2,
1110			.rates = MTK_I2S_RATES,
1111			.formats = MTK_I2S_FORMATS,
1112		},
1113		.ops = &mtk_dai_i2s_ops,
1114	},
1115	{
1116		.name = "I2S3",
1117		.id = MT8186_DAI_I2S_3,
1118		.playback = {
1119			.stream_name = "I2S3",
1120			.channels_min = 1,
1121			.channels_max = 2,
1122			.rates = MTK_I2S_RATES,
1123			.formats = MTK_I2S_FORMATS,
1124		},
1125		.ops = &mtk_dai_i2s_ops,
1126	}
1127};
1128
1129/* this enum is merely for mtk_afe_i2s_priv declare */
1130enum {
1131	DAI_I2S0 = 0,
1132	DAI_I2S1,
1133	DAI_I2S2,
1134	DAI_I2S3,
1135	DAI_I2S_NUM,
1136};
1137
1138static const struct mtk_afe_i2s_priv mt8186_i2s_priv[DAI_I2S_NUM] = {
1139	[DAI_I2S0] = {
1140		.id = MT8186_DAI_I2S_0,
1141		.mclk_id = MT8186_I2S0_MCK,
1142		.share_i2s_id = -1,
1143	},
1144	[DAI_I2S1] = {
1145		.id = MT8186_DAI_I2S_1,
1146		.mclk_id = MT8186_I2S1_MCK,
1147		.share_i2s_id = -1,
1148	},
1149	[DAI_I2S2] = {
1150		.id = MT8186_DAI_I2S_2,
1151		.mclk_id = MT8186_I2S2_MCK,
1152		.share_i2s_id = -1,
1153	},
1154	[DAI_I2S3] = {
1155		.id = MT8186_DAI_I2S_3,
1156		/*  clock gate naming is hf_faud_i2s4_m_ck*/
1157		.mclk_id = MT8186_I2S4_MCK,
1158		.share_i2s_id = -1,
1159	}
1160};
1161
1162/**
1163 * mt8186_dai_i2s_set_share() - Set up I2S ports to share a single clock.
1164 * @afe: Pointer to &struct mtk_base_afe
1165 * @main_i2s_name: The name of the I2S port that will provide the clock
1166 * @secondary_i2s_name: The name of the I2S port that will use this clock
1167 */
1168int mt8186_dai_i2s_set_share(struct mtk_base_afe *afe, const char *main_i2s_name,
1169			     const char *secondary_i2s_name)
1170{
1171	struct mtk_afe_i2s_priv *secondary_i2s_priv;
1172	int main_i2s_id;
1173
1174	secondary_i2s_priv = get_i2s_priv_by_name(afe, secondary_i2s_name);
1175	if (!secondary_i2s_priv)
1176		return -EINVAL;
1177
1178	main_i2s_id = get_i2s_id_by_name(afe, main_i2s_name);
1179	if (main_i2s_id < 0)
1180		return main_i2s_id;
1181
1182	secondary_i2s_priv->share_i2s_id = main_i2s_id;
1183
1184	return 0;
1185}
1186EXPORT_SYMBOL_GPL(mt8186_dai_i2s_set_share);
1187
1188static int mt8186_dai_i2s_set_priv(struct mtk_base_afe *afe)
1189{
1190	int i;
1191	int ret;
1192
1193	for (i = 0; i < DAI_I2S_NUM; i++) {
1194		ret = mt8186_dai_set_priv(afe, mt8186_i2s_priv[i].id,
1195					  sizeof(struct mtk_afe_i2s_priv),
1196					  &mt8186_i2s_priv[i]);
1197		if (ret)
1198			return ret;
1199	}
1200
1201	return 0;
1202}
1203
1204int mt8186_dai_i2s_register(struct mtk_base_afe *afe)
1205{
1206	struct mtk_base_afe_dai *dai;
1207	int ret;
1208
1209	dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
1210	if (!dai)
1211		return -ENOMEM;
1212
1213	list_add(&dai->list, &afe->sub_dais);
1214
1215	dai->dai_drivers = mtk_dai_i2s_driver;
1216	dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_i2s_driver);
1217
1218	dai->controls = mtk_dai_i2s_controls;
1219	dai->num_controls = ARRAY_SIZE(mtk_dai_i2s_controls);
1220	dai->dapm_widgets = mtk_dai_i2s_widgets;
1221	dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_i2s_widgets);
1222	dai->dapm_routes = mtk_dai_i2s_routes;
1223	dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_i2s_routes);
1224
1225	/* set all dai i2s private data */
1226	ret = mt8186_dai_i2s_set_priv(afe);
1227	if (ret)
1228		return ret;
1229
1230	return 0;
1231}
~/ Read-only file preview.