brintos

brintos / linux-shallow public Read only

0
0
Text · 39.1 KiB · 5f11bc5 Raw
1484 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Mediatek ALSA SoC AFE platform driver for 27014 *5 * Copyright (c) 2016 MediaTek Inc.6 * Author: Garlic Tseng <garlic.tseng@mediatek.com>7 *	   Ir Lian <ir.lian@mediatek.com>8 *	   Ryder Lee <ryder.lee@mediatek.com>9 */10 11#include <linux/delay.h>12#include <linux/module.h>13#include <linux/mfd/syscon.h>14#include <linux/of.h>15#include <linux/pm_runtime.h>16 17#include "mt2701-afe-common.h"18#include "mt2701-afe-clock-ctrl.h"19#include "../common/mtk-afe-platform-driver.h"20#include "../common/mtk-afe-fe-dai.h"21 22static const struct snd_pcm_hardware mt2701_afe_hardware = {23	.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED24		| SNDRV_PCM_INFO_RESUME | SNDRV_PCM_INFO_MMAP_VALID,25	.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE26		   | SNDRV_PCM_FMTBIT_S32_LE,27	.period_bytes_min = 1024,28	.period_bytes_max = 1024 * 256,29	.periods_min = 4,30	.periods_max = 1024,31	.buffer_bytes_max = 1024 * 1024,32	.fifo_size = 0,33};34 35struct mt2701_afe_rate {36	unsigned int rate;37	unsigned int regvalue;38};39 40static const struct mt2701_afe_rate mt2701_afe_i2s_rates[] = {41	{ .rate = 8000, .regvalue = 0 },42	{ .rate = 12000, .regvalue = 1 },43	{ .rate = 16000, .regvalue = 2 },44	{ .rate = 24000, .regvalue = 3 },45	{ .rate = 32000, .regvalue = 4 },46	{ .rate = 48000, .regvalue = 5 },47	{ .rate = 96000, .regvalue = 6 },48	{ .rate = 192000, .regvalue = 7 },49	{ .rate = 384000, .regvalue = 8 },50	{ .rate = 7350, .regvalue = 16 },51	{ .rate = 11025, .regvalue = 17 },52	{ .rate = 14700, .regvalue = 18 },53	{ .rate = 22050, .regvalue = 19 },54	{ .rate = 29400, .regvalue = 20 },55	{ .rate = 44100, .regvalue = 21 },56	{ .rate = 88200, .regvalue = 22 },57	{ .rate = 176400, .regvalue = 23 },58	{ .rate = 352800, .regvalue = 24 },59};60 61static const unsigned int mt2701_afe_backup_list[] = {62	AUDIO_TOP_CON0,63	AUDIO_TOP_CON4,64	AUDIO_TOP_CON5,65	ASYS_TOP_CON,66	AFE_CONN0,67	AFE_CONN1,68	AFE_CONN2,69	AFE_CONN3,70	AFE_CONN15,71	AFE_CONN16,72	AFE_CONN17,73	AFE_CONN18,74	AFE_CONN19,75	AFE_CONN20,76	AFE_CONN21,77	AFE_CONN22,78	AFE_DAC_CON0,79	AFE_MEMIF_PBUF_SIZE,80};81 82static int mt2701_dai_num_to_i2s(struct mtk_base_afe *afe, int num)83{84	struct mt2701_afe_private *afe_priv = afe->platform_priv;85	int val = num - MT2701_IO_I2S;86 87	if (val < 0 || val >= afe_priv->soc->i2s_num) {88		dev_err(afe->dev, "%s, num not available, num %d, val %d\n",89			__func__, num, val);90		return -EINVAL;91	}92	return val;93}94 95static int mt2701_afe_i2s_fs(unsigned int sample_rate)96{97	int i;98 99	for (i = 0; i < ARRAY_SIZE(mt2701_afe_i2s_rates); i++)100		if (mt2701_afe_i2s_rates[i].rate == sample_rate)101			return mt2701_afe_i2s_rates[i].regvalue;102 103	return -EINVAL;104}105 106static int mt2701_afe_i2s_startup(struct snd_pcm_substream *substream,107				  struct snd_soc_dai *dai)108{109	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);110	struct mt2701_afe_private *afe_priv = afe->platform_priv;111	int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);112	bool mode = afe_priv->soc->has_one_heart_mode;113 114	if (i2s_num < 0)115		return i2s_num;116 117	return mt2701_afe_enable_mclk(afe, mode ? 1 : i2s_num);118}119 120static int mt2701_afe_i2s_path_disable(struct mtk_base_afe *afe,121				       struct mt2701_i2s_path *i2s_path,122				       int stream_dir)123{124	const struct mt2701_i2s_data *i2s_data = i2s_path->i2s_data[stream_dir];125 126	if (--i2s_path->on[stream_dir] < 0)127		i2s_path->on[stream_dir] = 0;128 129	if (i2s_path->on[stream_dir])130		return 0;131 132	/* disable i2s */133	regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,134			   ASYS_I2S_CON_I2S_EN, 0);135 136	mt2701_afe_disable_i2s(afe, i2s_path, stream_dir);137 138	return 0;139}140 141static void mt2701_afe_i2s_shutdown(struct snd_pcm_substream *substream,142				    struct snd_soc_dai *dai)143{144	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);145	struct mt2701_afe_private *afe_priv = afe->platform_priv;146	int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);147	struct mt2701_i2s_path *i2s_path;148	bool mode = afe_priv->soc->has_one_heart_mode;149 150	if (i2s_num < 0)151		return;152 153	i2s_path = &afe_priv->i2s_path[i2s_num];154 155	if (i2s_path->occupied[substream->stream])156		i2s_path->occupied[substream->stream] = 0;157	else158		goto exit;159 160	mt2701_afe_i2s_path_disable(afe, i2s_path, substream->stream);161 162	/* need to disable i2s-out path when disable i2s-in */163	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)164		mt2701_afe_i2s_path_disable(afe, i2s_path, !substream->stream);165 166exit:167	/* disable mclk */168	mt2701_afe_disable_mclk(afe, mode ? 1 : i2s_num);169}170 171static int mt2701_i2s_path_enable(struct mtk_base_afe *afe,172				  struct mt2701_i2s_path *i2s_path,173				  int stream_dir, int rate)174{175	const struct mt2701_i2s_data *i2s_data = i2s_path->i2s_data[stream_dir];176	struct mt2701_afe_private *afe_priv = afe->platform_priv;177	int reg, fs, w_len = 1; /* now we support bck 64bits only */178	unsigned int mask, val;179 180	/* no need to enable if already done */181	if (++i2s_path->on[stream_dir] != 1)182		return 0;183 184	fs = mt2701_afe_i2s_fs(rate);185 186	mask = ASYS_I2S_CON_FS |187	       ASYS_I2S_CON_I2S_COUPLE_MODE | /* 0 */188	       ASYS_I2S_CON_I2S_MODE |189	       ASYS_I2S_CON_WIDE_MODE;190 191	val = ASYS_I2S_CON_FS_SET(fs) |192	      ASYS_I2S_CON_I2S_MODE |193	      ASYS_I2S_CON_WIDE_MODE_SET(w_len);194 195	if (stream_dir == SNDRV_PCM_STREAM_CAPTURE) {196		mask |= ASYS_I2S_IN_PHASE_FIX;197		val |= ASYS_I2S_IN_PHASE_FIX;198		reg = ASMI_TIMING_CON1;199	} else {200		if (afe_priv->soc->has_one_heart_mode) {201			mask |= ASYS_I2S_CON_ONE_HEART_MODE;202			val |= ASYS_I2S_CON_ONE_HEART_MODE;203		}204		reg = ASMO_TIMING_CON1;205	}206 207	regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg, mask, val);208 209	regmap_update_bits(afe->regmap, reg,210			   i2s_data->i2s_asrc_fs_mask211			   << i2s_data->i2s_asrc_fs_shift,212			   fs << i2s_data->i2s_asrc_fs_shift);213 214	/* enable i2s */215	mt2701_afe_enable_i2s(afe, i2s_path, stream_dir);216 217	/* reset i2s hw status before enable */218	regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,219			   ASYS_I2S_CON_RESET, ASYS_I2S_CON_RESET);220	udelay(1);221	regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,222			   ASYS_I2S_CON_RESET, 0);223	udelay(1);224	regmap_update_bits(afe->regmap, i2s_data->i2s_ctrl_reg,225			   ASYS_I2S_CON_I2S_EN, ASYS_I2S_CON_I2S_EN);226	return 0;227}228 229static int mt2701_afe_i2s_prepare(struct snd_pcm_substream *substream,230				  struct snd_soc_dai *dai)231{232	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);233	struct mt2701_afe_private *afe_priv = afe->platform_priv;234	int ret, i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);235	struct mt2701_i2s_path *i2s_path;236	bool mode = afe_priv->soc->has_one_heart_mode;237 238	if (i2s_num < 0)239		return i2s_num;240 241	i2s_path = &afe_priv->i2s_path[i2s_num];242 243	if (i2s_path->occupied[substream->stream])244		return -EBUSY;245 246	ret = mt2701_mclk_configuration(afe, mode ? 1 : i2s_num);247	if (ret)248		return ret;249 250	i2s_path->occupied[substream->stream] = 1;251 252	/* need to enable i2s-out path when enable i2s-in */253	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)254		mt2701_i2s_path_enable(afe, i2s_path, !substream->stream,255				       substream->runtime->rate);256 257	mt2701_i2s_path_enable(afe, i2s_path, substream->stream,258			       substream->runtime->rate);259 260	return 0;261}262 263static int mt2701_afe_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,264				     unsigned int freq, int dir)265{266	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);267	struct mt2701_afe_private *afe_priv = afe->platform_priv;268	int i2s_num = mt2701_dai_num_to_i2s(afe, dai->id);269	bool mode = afe_priv->soc->has_one_heart_mode;270 271	if (i2s_num < 0)272		return i2s_num;273 274	/* mclk */275	if (dir == SND_SOC_CLOCK_IN) {276		dev_warn(dai->dev, "The SoCs doesn't support mclk input\n");277		return -EINVAL;278	}279 280	afe_priv->i2s_path[mode ? 1 : i2s_num].mclk_rate = freq;281 282	return 0;283}284 285static int mt2701_btmrg_startup(struct snd_pcm_substream *substream,286				struct snd_soc_dai *dai)287{288	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);289	struct mt2701_afe_private *afe_priv = afe->platform_priv;290	int ret;291 292	ret = mt2701_enable_btmrg_clk(afe);293	if (ret)294		return ret;295 296	afe_priv->mrg_enable[substream->stream] = 1;297 298	return 0;299}300 301static int mt2701_btmrg_hw_params(struct snd_pcm_substream *substream,302				  struct snd_pcm_hw_params *params,303				  struct snd_soc_dai *dai)304{305	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);306	int stream_fs;307	u32 val, msk;308 309	stream_fs = params_rate(params);310 311	if (stream_fs != 8000 && stream_fs != 16000) {312		dev_err(afe->dev, "unsupported rate %d\n", stream_fs);313		return -EINVAL;314	}315 316	regmap_update_bits(afe->regmap, AFE_MRGIF_CON,317			   AFE_MRGIF_CON_I2S_MODE_MASK,318			   AFE_MRGIF_CON_I2S_MODE_32K);319 320	val = AFE_DAIBT_CON0_BT_FUNC_EN | AFE_DAIBT_CON0_BT_FUNC_RDY321	      | AFE_DAIBT_CON0_MRG_USE;322	msk = val;323 324	if (stream_fs == 16000)325		val |= AFE_DAIBT_CON0_BT_WIDE_MODE_EN;326 327	msk |= AFE_DAIBT_CON0_BT_WIDE_MODE_EN;328 329	regmap_update_bits(afe->regmap, AFE_DAIBT_CON0, msk, val);330 331	regmap_update_bits(afe->regmap, AFE_DAIBT_CON0,332			   AFE_DAIBT_CON0_DAIBT_EN,333			   AFE_DAIBT_CON0_DAIBT_EN);334	regmap_update_bits(afe->regmap, AFE_MRGIF_CON,335			   AFE_MRGIF_CON_MRG_I2S_EN,336			   AFE_MRGIF_CON_MRG_I2S_EN);337	regmap_update_bits(afe->regmap, AFE_MRGIF_CON,338			   AFE_MRGIF_CON_MRG_EN,339			   AFE_MRGIF_CON_MRG_EN);340	return 0;341}342 343static void mt2701_btmrg_shutdown(struct snd_pcm_substream *substream,344				  struct snd_soc_dai *dai)345{346	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);347	struct mt2701_afe_private *afe_priv = afe->platform_priv;348 349	/* if the other direction stream is not occupied */350	if (!afe_priv->mrg_enable[!substream->stream]) {351		regmap_update_bits(afe->regmap, AFE_DAIBT_CON0,352				   AFE_DAIBT_CON0_DAIBT_EN, 0);353		regmap_update_bits(afe->regmap, AFE_MRGIF_CON,354				   AFE_MRGIF_CON_MRG_EN, 0);355		regmap_update_bits(afe->regmap, AFE_MRGIF_CON,356				   AFE_MRGIF_CON_MRG_I2S_EN, 0);357		mt2701_disable_btmrg_clk(afe);358	}359 360	afe_priv->mrg_enable[substream->stream] = 0;361}362 363static int mt2701_simple_fe_startup(struct snd_pcm_substream *substream,364				    struct snd_soc_dai *dai)365{366	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);367	struct mtk_base_afe_memif *memif_tmp;368	int stream_dir = substream->stream;369 370	/* can't run single DL & DLM at the same time */371	if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK) {372		memif_tmp = &afe->memif[MT2701_MEMIF_DLM];373		if (memif_tmp->substream) {374			dev_warn(afe->dev, "memif is not available");375			return -EBUSY;376		}377	}378 379	return mtk_afe_fe_startup(substream, dai);380}381 382static int mt2701_simple_fe_hw_params(struct snd_pcm_substream *substream,383				      struct snd_pcm_hw_params *params,384				      struct snd_soc_dai *dai)385{386	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);387	int stream_dir = substream->stream;388 389	/* single DL use PAIR_INTERLEAVE */390	if (stream_dir == SNDRV_PCM_STREAM_PLAYBACK)391		regmap_update_bits(afe->regmap,392				   AFE_MEMIF_PBUF_SIZE,393				   AFE_MEMIF_PBUF_SIZE_DLM_MASK,394				   AFE_MEMIF_PBUF_SIZE_PAIR_INTERLEAVE);395 396	return mtk_afe_fe_hw_params(substream, params, dai);397}398 399static int mt2701_dlm_fe_startup(struct snd_pcm_substream *substream,400				 struct snd_soc_dai *dai)401{402	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);403	struct mtk_base_afe_memif *memif_tmp;404	const struct mtk_base_memif_data *memif_data;405	int i;406 407	for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) {408		memif_tmp = &afe->memif[i];409		if (memif_tmp->substream)410			return -EBUSY;411	}412 413	/* enable agent for all signal DL (due to hw design) */414	for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) {415		memif_data = afe->memif[i].data;416		regmap_update_bits(afe->regmap,417				   memif_data->agent_disable_reg,418				   1 << memif_data->agent_disable_shift,419				   0 << memif_data->agent_disable_shift);420	}421 422	return mtk_afe_fe_startup(substream, dai);423}424 425static void mt2701_dlm_fe_shutdown(struct snd_pcm_substream *substream,426				   struct snd_soc_dai *dai)427{428	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);429	const struct mtk_base_memif_data *memif_data;430	int i;431 432	for (i = MT2701_MEMIF_DL1; i < MT2701_MEMIF_DL_SINGLE_NUM; ++i) {433		memif_data = afe->memif[i].data;434		regmap_update_bits(afe->regmap,435				   memif_data->agent_disable_reg,436				   1 << memif_data->agent_disable_shift,437				   1 << memif_data->agent_disable_shift);438	}439 440	return mtk_afe_fe_shutdown(substream, dai);441}442 443static int mt2701_dlm_fe_hw_params(struct snd_pcm_substream *substream,444				   struct snd_pcm_hw_params *params,445				   struct snd_soc_dai *dai)446{447	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);448	int channels = params_channels(params);449 450	regmap_update_bits(afe->regmap,451			   AFE_MEMIF_PBUF_SIZE,452			   AFE_MEMIF_PBUF_SIZE_DLM_MASK,453			   AFE_MEMIF_PBUF_SIZE_FULL_INTERLEAVE);454	regmap_update_bits(afe->regmap,455			   AFE_MEMIF_PBUF_SIZE,456			   AFE_MEMIF_PBUF_SIZE_DLM_BYTE_MASK,457			   AFE_MEMIF_PBUF_SIZE_DLM_32BYTES);458	regmap_update_bits(afe->regmap,459			   AFE_MEMIF_PBUF_SIZE,460			   AFE_MEMIF_PBUF_SIZE_DLM_CH_MASK,461			   AFE_MEMIF_PBUF_SIZE_DLM_CH(channels));462 463	return mtk_afe_fe_hw_params(substream, params, dai);464}465 466static int mt2701_dlm_fe_trigger(struct snd_pcm_substream *substream,467				 int cmd, struct snd_soc_dai *dai)468{469	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);470	struct mtk_base_afe_memif *memif_tmp = &afe->memif[MT2701_MEMIF_DL1];471 472	switch (cmd) {473	case SNDRV_PCM_TRIGGER_START:474	case SNDRV_PCM_TRIGGER_RESUME:475		regmap_update_bits(afe->regmap, memif_tmp->data->enable_reg,476				   1 << memif_tmp->data->enable_shift,477				   1 << memif_tmp->data->enable_shift);478		mtk_afe_fe_trigger(substream, cmd, dai);479		return 0;480	case SNDRV_PCM_TRIGGER_STOP:481	case SNDRV_PCM_TRIGGER_SUSPEND:482		mtk_afe_fe_trigger(substream, cmd, dai);483		regmap_update_bits(afe->regmap, memif_tmp->data->enable_reg,484				   1 << memif_tmp->data->enable_shift, 0);485 486		return 0;487	default:488		return -EINVAL;489	}490}491 492static int mt2701_memif_fs(struct snd_pcm_substream *substream,493			   unsigned int rate)494{495	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);496	int fs;497 498	if (snd_soc_rtd_to_cpu(rtd, 0)->id != MT2701_MEMIF_ULBT)499		fs = mt2701_afe_i2s_fs(rate);500	else501		fs = (rate == 16000 ? 1 : 0);502 503	return fs;504}505 506static int mt2701_irq_fs(struct snd_pcm_substream *substream, unsigned int rate)507{508	return mt2701_afe_i2s_fs(rate);509}510 511/* FE DAIs */512static const struct snd_soc_dai_ops mt2701_single_memif_dai_ops = {513	.startup	= mt2701_simple_fe_startup,514	.shutdown	= mtk_afe_fe_shutdown,515	.hw_params	= mt2701_simple_fe_hw_params,516	.hw_free	= mtk_afe_fe_hw_free,517	.prepare	= mtk_afe_fe_prepare,518	.trigger	= mtk_afe_fe_trigger,519};520 521static const struct snd_soc_dai_ops mt2701_dlm_memif_dai_ops = {522	.startup	= mt2701_dlm_fe_startup,523	.shutdown	= mt2701_dlm_fe_shutdown,524	.hw_params	= mt2701_dlm_fe_hw_params,525	.hw_free	= mtk_afe_fe_hw_free,526	.prepare	= mtk_afe_fe_prepare,527	.trigger	= mt2701_dlm_fe_trigger,528};529 530/* I2S BE DAIs */531static const struct snd_soc_dai_ops mt2701_afe_i2s_ops = {532	.startup	= mt2701_afe_i2s_startup,533	.shutdown	= mt2701_afe_i2s_shutdown,534	.prepare	= mt2701_afe_i2s_prepare,535	.set_sysclk	= mt2701_afe_i2s_set_sysclk,536};537 538/* MRG BE DAIs */539static const struct snd_soc_dai_ops mt2701_btmrg_ops = {540	.startup = mt2701_btmrg_startup,541	.shutdown = mt2701_btmrg_shutdown,542	.hw_params = mt2701_btmrg_hw_params,543};544 545static struct snd_soc_dai_driver mt2701_afe_pcm_dais[] = {546	/* FE DAIs: memory intefaces to CPU */547	{548		.name = "PCMO0",549		.id = MT2701_MEMIF_DL1,550		.playback = {551			.stream_name = "DL1",552			.channels_min = 1,553			.channels_max = 2,554			.rates = SNDRV_PCM_RATE_8000_192000,555			.formats = (SNDRV_PCM_FMTBIT_S16_LE556				| SNDRV_PCM_FMTBIT_S24_LE557				| SNDRV_PCM_FMTBIT_S32_LE)558		},559		.ops = &mt2701_single_memif_dai_ops,560	},561	{562		.name = "PCM_multi",563		.id = MT2701_MEMIF_DLM,564		.playback = {565			.stream_name = "DLM",566			.channels_min = 1,567			.channels_max = 8,568			.rates = SNDRV_PCM_RATE_8000_192000,569			.formats = (SNDRV_PCM_FMTBIT_S16_LE570				| SNDRV_PCM_FMTBIT_S24_LE571				| SNDRV_PCM_FMTBIT_S32_LE)572 573		},574		.ops = &mt2701_dlm_memif_dai_ops,575	},576	{577		.name = "PCM0",578		.id = MT2701_MEMIF_UL1,579		.capture = {580			.stream_name = "UL1",581			.channels_min = 1,582			.channels_max = 2,583			.rates = SNDRV_PCM_RATE_8000_48000,584			.formats = (SNDRV_PCM_FMTBIT_S16_LE585				| SNDRV_PCM_FMTBIT_S24_LE586				| SNDRV_PCM_FMTBIT_S32_LE)587		},588		.ops = &mt2701_single_memif_dai_ops,589	},590	{591		.name = "PCM1",592		.id = MT2701_MEMIF_UL2,593		.capture = {594			.stream_name = "UL2",595			.channels_min = 1,596			.channels_max = 2,597			.rates = SNDRV_PCM_RATE_8000_192000,598			.formats = (SNDRV_PCM_FMTBIT_S16_LE599				| SNDRV_PCM_FMTBIT_S24_LE600				| SNDRV_PCM_FMTBIT_S32_LE)601 602		},603		.ops = &mt2701_single_memif_dai_ops,604	},605	{606		.name = "PCM_BT_DL",607		.id = MT2701_MEMIF_DLBT,608		.playback = {609			.stream_name = "DLBT",610			.channels_min = 1,611			.channels_max = 1,612			.rates = (SNDRV_PCM_RATE_8000613				| SNDRV_PCM_RATE_16000),614			.formats = SNDRV_PCM_FMTBIT_S16_LE,615		},616		.ops = &mt2701_single_memif_dai_ops,617	},618	{619		.name = "PCM_BT_UL",620		.id = MT2701_MEMIF_ULBT,621		.capture = {622			.stream_name = "ULBT",623			.channels_min = 1,624			.channels_max = 1,625			.rates = (SNDRV_PCM_RATE_8000626				| SNDRV_PCM_RATE_16000),627			.formats = SNDRV_PCM_FMTBIT_S16_LE,628		},629		.ops = &mt2701_single_memif_dai_ops,630	},631	/* BE DAIs */632	{633		.name = "I2S0",634		.id = MT2701_IO_I2S,635		.playback = {636			.stream_name = "I2S0 Playback",637			.channels_min = 1,638			.channels_max = 2,639			.rates = SNDRV_PCM_RATE_8000_192000,640			.formats = (SNDRV_PCM_FMTBIT_S16_LE641				| SNDRV_PCM_FMTBIT_S24_LE642				| SNDRV_PCM_FMTBIT_S32_LE)643 644		},645		.capture = {646			.stream_name = "I2S0 Capture",647			.channels_min = 1,648			.channels_max = 2,649			.rates = SNDRV_PCM_RATE_8000_192000,650			.formats = (SNDRV_PCM_FMTBIT_S16_LE651				| SNDRV_PCM_FMTBIT_S24_LE652				| SNDRV_PCM_FMTBIT_S32_LE)653 654		},655		.ops = &mt2701_afe_i2s_ops,656		.symmetric_rate = 1,657	},658	{659		.name = "I2S1",660		.id = MT2701_IO_2ND_I2S,661		.playback = {662			.stream_name = "I2S1 Playback",663			.channels_min = 1,664			.channels_max = 2,665			.rates = SNDRV_PCM_RATE_8000_192000,666			.formats = (SNDRV_PCM_FMTBIT_S16_LE667				| SNDRV_PCM_FMTBIT_S24_LE668				| SNDRV_PCM_FMTBIT_S32_LE)669			},670		.capture = {671			.stream_name = "I2S1 Capture",672			.channels_min = 1,673			.channels_max = 2,674			.rates = SNDRV_PCM_RATE_8000_192000,675			.formats = (SNDRV_PCM_FMTBIT_S16_LE676				| SNDRV_PCM_FMTBIT_S24_LE677				| SNDRV_PCM_FMTBIT_S32_LE)678			},679		.ops = &mt2701_afe_i2s_ops,680		.symmetric_rate = 1,681	},682	{683		.name = "I2S2",684		.id = MT2701_IO_3RD_I2S,685		.playback = {686			.stream_name = "I2S2 Playback",687			.channels_min = 1,688			.channels_max = 2,689			.rates = SNDRV_PCM_RATE_8000_192000,690			.formats = (SNDRV_PCM_FMTBIT_S16_LE691				| SNDRV_PCM_FMTBIT_S24_LE692				| SNDRV_PCM_FMTBIT_S32_LE)693			},694		.capture = {695			.stream_name = "I2S2 Capture",696			.channels_min = 1,697			.channels_max = 2,698			.rates = SNDRV_PCM_RATE_8000_192000,699			.formats = (SNDRV_PCM_FMTBIT_S16_LE700				| SNDRV_PCM_FMTBIT_S24_LE701				| SNDRV_PCM_FMTBIT_S32_LE)702			},703		.ops = &mt2701_afe_i2s_ops,704		.symmetric_rate = 1,705	},706	{707		.name = "I2S3",708		.id = MT2701_IO_4TH_I2S,709		.playback = {710			.stream_name = "I2S3 Playback",711			.channels_min = 1,712			.channels_max = 2,713			.rates = SNDRV_PCM_RATE_8000_192000,714			.formats = (SNDRV_PCM_FMTBIT_S16_LE715				| SNDRV_PCM_FMTBIT_S24_LE716				| SNDRV_PCM_FMTBIT_S32_LE)717			},718		.capture = {719			.stream_name = "I2S3 Capture",720			.channels_min = 1,721			.channels_max = 2,722			.rates = SNDRV_PCM_RATE_8000_192000,723			.formats = (SNDRV_PCM_FMTBIT_S16_LE724				| SNDRV_PCM_FMTBIT_S24_LE725				| SNDRV_PCM_FMTBIT_S32_LE)726			},727		.ops = &mt2701_afe_i2s_ops,728		.symmetric_rate = 1,729	},730	{731		.name = "MRG BT",732		.id = MT2701_IO_MRG,733		.playback = {734			.stream_name = "BT Playback",735			.channels_min = 1,736			.channels_max = 1,737			.rates = (SNDRV_PCM_RATE_8000738				| SNDRV_PCM_RATE_16000),739			.formats = SNDRV_PCM_FMTBIT_S16_LE,740		},741		.capture = {742			.stream_name = "BT Capture",743			.channels_min = 1,744			.channels_max = 1,745			.rates = (SNDRV_PCM_RATE_8000746				| SNDRV_PCM_RATE_16000),747			.formats = SNDRV_PCM_FMTBIT_S16_LE,748		},749		.ops = &mt2701_btmrg_ops,750		.symmetric_rate = 1,751	}752};753 754static const struct snd_kcontrol_new mt2701_afe_o00_mix[] = {755	SOC_DAPM_SINGLE_AUTODISABLE("I00 Switch", AFE_CONN0, 0, 1, 0),756};757 758static const struct snd_kcontrol_new mt2701_afe_o01_mix[] = {759	SOC_DAPM_SINGLE_AUTODISABLE("I01 Switch", AFE_CONN1, 1, 1, 0),760};761 762static const struct snd_kcontrol_new mt2701_afe_o02_mix[] = {763	SOC_DAPM_SINGLE_AUTODISABLE("I02 Switch", AFE_CONN2, 2, 1, 0),764};765 766static const struct snd_kcontrol_new mt2701_afe_o03_mix[] = {767	SOC_DAPM_SINGLE_AUTODISABLE("I03 Switch", AFE_CONN3, 3, 1, 0),768};769 770static const struct snd_kcontrol_new mt2701_afe_o14_mix[] = {771	SOC_DAPM_SINGLE_AUTODISABLE("I26 Switch", AFE_CONN14, 26, 1, 0),772};773 774static const struct snd_kcontrol_new mt2701_afe_o15_mix[] = {775	SOC_DAPM_SINGLE_AUTODISABLE("I12 Switch", AFE_CONN15, 12, 1, 0),776};777 778static const struct snd_kcontrol_new mt2701_afe_o16_mix[] = {779	SOC_DAPM_SINGLE_AUTODISABLE("I13 Switch", AFE_CONN16, 13, 1, 0),780};781 782static const struct snd_kcontrol_new mt2701_afe_o17_mix[] = {783	SOC_DAPM_SINGLE_AUTODISABLE("I14 Switch", AFE_CONN17, 14, 1, 0),784};785 786static const struct snd_kcontrol_new mt2701_afe_o18_mix[] = {787	SOC_DAPM_SINGLE_AUTODISABLE("I15 Switch", AFE_CONN18, 15, 1, 0),788};789 790static const struct snd_kcontrol_new mt2701_afe_o19_mix[] = {791	SOC_DAPM_SINGLE_AUTODISABLE("I16 Switch", AFE_CONN19, 16, 1, 0),792};793 794static const struct snd_kcontrol_new mt2701_afe_o20_mix[] = {795	SOC_DAPM_SINGLE_AUTODISABLE("I17 Switch", AFE_CONN20, 17, 1, 0),796};797 798static const struct snd_kcontrol_new mt2701_afe_o21_mix[] = {799	SOC_DAPM_SINGLE_AUTODISABLE("I18 Switch", AFE_CONN21, 18, 1, 0),800};801 802static const struct snd_kcontrol_new mt2701_afe_o22_mix[] = {803	SOC_DAPM_SINGLE_AUTODISABLE("I19 Switch", AFE_CONN22, 19, 1, 0),804};805 806static const struct snd_kcontrol_new mt2701_afe_o31_mix[] = {807	SOC_DAPM_SINGLE_AUTODISABLE("I35 Switch", AFE_CONN41, 9, 1, 0),808};809 810static const struct snd_kcontrol_new mt2701_afe_i02_mix[] = {811	SOC_DAPM_SINGLE("I2S0 Switch", SND_SOC_NOPM, 0, 1, 0),812};813 814static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s0[] = {815	SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S0 Out Switch",816				    ASYS_I2SO1_CON, 26, 1, 0),817};818 819static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s1[] = {820	SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S1 Out Switch",821				    ASYS_I2SO2_CON, 26, 1, 0),822};823 824static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s2[] = {825	SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S2 Out Switch",826				    PWR2_TOP_CON, 17, 1, 0),827};828 829static const struct snd_kcontrol_new mt2701_afe_multi_ch_out_i2s3[] = {830	SOC_DAPM_SINGLE_AUTODISABLE("Multich I2S3 Out Switch",831				    PWR2_TOP_CON, 18, 1, 0),832};833 834static const struct snd_soc_dapm_widget mt2701_afe_pcm_widgets[] = {835	/* inter-connections */836	SND_SOC_DAPM_MIXER("I00", SND_SOC_NOPM, 0, 0, NULL, 0),837	SND_SOC_DAPM_MIXER("I01", SND_SOC_NOPM, 0, 0, NULL, 0),838	SND_SOC_DAPM_MIXER("I02", SND_SOC_NOPM, 0, 0, mt2701_afe_i02_mix,839			   ARRAY_SIZE(mt2701_afe_i02_mix)),840	SND_SOC_DAPM_MIXER("I03", SND_SOC_NOPM, 0, 0, NULL, 0),841	SND_SOC_DAPM_MIXER("I12", SND_SOC_NOPM, 0, 0, NULL, 0),842	SND_SOC_DAPM_MIXER("I13", SND_SOC_NOPM, 0, 0, NULL, 0),843	SND_SOC_DAPM_MIXER("I14", SND_SOC_NOPM, 0, 0, NULL, 0),844	SND_SOC_DAPM_MIXER("I15", SND_SOC_NOPM, 0, 0, NULL, 0),845	SND_SOC_DAPM_MIXER("I16", SND_SOC_NOPM, 0, 0, NULL, 0),846	SND_SOC_DAPM_MIXER("I17", SND_SOC_NOPM, 0, 0, NULL, 0),847	SND_SOC_DAPM_MIXER("I18", SND_SOC_NOPM, 0, 0, NULL, 0),848	SND_SOC_DAPM_MIXER("I19", SND_SOC_NOPM, 0, 0, NULL, 0),849	SND_SOC_DAPM_MIXER("I26", SND_SOC_NOPM, 0, 0, NULL, 0),850	SND_SOC_DAPM_MIXER("I35", SND_SOC_NOPM, 0, 0, NULL, 0),851 852	SND_SOC_DAPM_MIXER("O00", SND_SOC_NOPM, 0, 0, mt2701_afe_o00_mix,853			   ARRAY_SIZE(mt2701_afe_o00_mix)),854	SND_SOC_DAPM_MIXER("O01", SND_SOC_NOPM, 0, 0, mt2701_afe_o01_mix,855			   ARRAY_SIZE(mt2701_afe_o01_mix)),856	SND_SOC_DAPM_MIXER("O02", SND_SOC_NOPM, 0, 0, mt2701_afe_o02_mix,857			   ARRAY_SIZE(mt2701_afe_o02_mix)),858	SND_SOC_DAPM_MIXER("O03", SND_SOC_NOPM, 0, 0, mt2701_afe_o03_mix,859			   ARRAY_SIZE(mt2701_afe_o03_mix)),860	SND_SOC_DAPM_MIXER("O14", SND_SOC_NOPM, 0, 0, mt2701_afe_o14_mix,861			   ARRAY_SIZE(mt2701_afe_o14_mix)),862	SND_SOC_DAPM_MIXER("O15", SND_SOC_NOPM, 0, 0, mt2701_afe_o15_mix,863			   ARRAY_SIZE(mt2701_afe_o15_mix)),864	SND_SOC_DAPM_MIXER("O16", SND_SOC_NOPM, 0, 0, mt2701_afe_o16_mix,865			   ARRAY_SIZE(mt2701_afe_o16_mix)),866	SND_SOC_DAPM_MIXER("O17", SND_SOC_NOPM, 0, 0, mt2701_afe_o17_mix,867			   ARRAY_SIZE(mt2701_afe_o17_mix)),868	SND_SOC_DAPM_MIXER("O18", SND_SOC_NOPM, 0, 0, mt2701_afe_o18_mix,869			   ARRAY_SIZE(mt2701_afe_o18_mix)),870	SND_SOC_DAPM_MIXER("O19", SND_SOC_NOPM, 0, 0, mt2701_afe_o19_mix,871			   ARRAY_SIZE(mt2701_afe_o19_mix)),872	SND_SOC_DAPM_MIXER("O20", SND_SOC_NOPM, 0, 0, mt2701_afe_o20_mix,873			   ARRAY_SIZE(mt2701_afe_o20_mix)),874	SND_SOC_DAPM_MIXER("O21", SND_SOC_NOPM, 0, 0, mt2701_afe_o21_mix,875			   ARRAY_SIZE(mt2701_afe_o21_mix)),876	SND_SOC_DAPM_MIXER("O22", SND_SOC_NOPM, 0, 0, mt2701_afe_o22_mix,877			   ARRAY_SIZE(mt2701_afe_o22_mix)),878	SND_SOC_DAPM_MIXER("O31", SND_SOC_NOPM, 0, 0, mt2701_afe_o31_mix,879			   ARRAY_SIZE(mt2701_afe_o31_mix)),880 881	SND_SOC_DAPM_MIXER("I12I13", SND_SOC_NOPM, 0, 0,882			   mt2701_afe_multi_ch_out_i2s0,883			   ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s0)),884	SND_SOC_DAPM_MIXER("I14I15", SND_SOC_NOPM, 0, 0,885			   mt2701_afe_multi_ch_out_i2s1,886			   ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s1)),887	SND_SOC_DAPM_MIXER("I16I17", SND_SOC_NOPM, 0, 0,888			   mt2701_afe_multi_ch_out_i2s2,889			   ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s2)),890	SND_SOC_DAPM_MIXER("I18I19", SND_SOC_NOPM, 0, 0,891			   mt2701_afe_multi_ch_out_i2s3,892			   ARRAY_SIZE(mt2701_afe_multi_ch_out_i2s3)),893};894 895static const struct snd_soc_dapm_route mt2701_afe_pcm_routes[] = {896	{"I12", NULL, "DL1"},897	{"I13", NULL, "DL1"},898	{"I35", NULL, "DLBT"},899 900	{"I2S0 Playback", NULL, "O15"},901	{"I2S0 Playback", NULL, "O16"},902	{"I2S1 Playback", NULL, "O17"},903	{"I2S1 Playback", NULL, "O18"},904	{"I2S2 Playback", NULL, "O19"},905	{"I2S2 Playback", NULL, "O20"},906	{"I2S3 Playback", NULL, "O21"},907	{"I2S3 Playback", NULL, "O22"},908	{"BT Playback", NULL, "O31"},909 910	{"UL1", NULL, "O00"},911	{"UL1", NULL, "O01"},912	{"UL2", NULL, "O02"},913	{"UL2", NULL, "O03"},914	{"ULBT", NULL, "O14"},915 916	{"I00", NULL, "I2S0 Capture"},917	{"I01", NULL, "I2S0 Capture"},918	{"I02", NULL, "I2S1 Capture"},919	{"I03", NULL, "I2S1 Capture"},920	/* I02,03 link to UL2, also need to open I2S0 */921	{"I02", "I2S0 Switch", "I2S0 Capture"},922 923	{"I26", NULL, "BT Capture"},924 925	{"I12I13", "Multich I2S0 Out Switch", "DLM"},926	{"I14I15", "Multich I2S1 Out Switch", "DLM"},927	{"I16I17", "Multich I2S2 Out Switch", "DLM"},928	{"I18I19", "Multich I2S3 Out Switch", "DLM"},929 930	{ "I12", NULL, "I12I13" },931	{ "I13", NULL, "I12I13" },932	{ "I14", NULL, "I14I15" },933	{ "I15", NULL, "I14I15" },934	{ "I16", NULL, "I16I17" },935	{ "I17", NULL, "I16I17" },936	{ "I18", NULL, "I18I19" },937	{ "I19", NULL, "I18I19" },938 939	{ "O00", "I00 Switch", "I00" },940	{ "O01", "I01 Switch", "I01" },941	{ "O02", "I02 Switch", "I02" },942	{ "O03", "I03 Switch", "I03" },943	{ "O14", "I26 Switch", "I26" },944	{ "O15", "I12 Switch", "I12" },945	{ "O16", "I13 Switch", "I13" },946	{ "O17", "I14 Switch", "I14" },947	{ "O18", "I15 Switch", "I15" },948	{ "O19", "I16 Switch", "I16" },949	{ "O20", "I17 Switch", "I17" },950	{ "O21", "I18 Switch", "I18" },951	{ "O22", "I19 Switch", "I19" },952	{ "O31", "I35 Switch", "I35" },953};954 955static int mt2701_afe_pcm_probe(struct snd_soc_component *component)956{957	struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);958 959	snd_soc_component_init_regmap(component, afe->regmap);960 961	return 0;962}963 964static const struct snd_soc_component_driver mt2701_afe_pcm_dai_component = {965	.probe = mt2701_afe_pcm_probe,966	.name = "mt2701-afe-pcm-dai",967	.dapm_widgets = mt2701_afe_pcm_widgets,968	.num_dapm_widgets = ARRAY_SIZE(mt2701_afe_pcm_widgets),969	.dapm_routes = mt2701_afe_pcm_routes,970	.num_dapm_routes = ARRAY_SIZE(mt2701_afe_pcm_routes),971	.suspend = mtk_afe_suspend,972	.resume = mtk_afe_resume,973};974 975static const struct mtk_base_memif_data memif_data_array[MT2701_MEMIF_NUM] = {976	{977		.name = "DL1",978		.id = MT2701_MEMIF_DL1,979		.reg_ofs_base = AFE_DL1_BASE,980		.reg_ofs_cur = AFE_DL1_CUR,981		.fs_reg = AFE_DAC_CON1,982		.fs_shift = 0,983		.fs_maskbit = 0x1f,984		.mono_reg = AFE_DAC_CON3,985		.mono_shift = 16,986		.enable_reg = AFE_DAC_CON0,987		.enable_shift = 1,988		.hd_reg = AFE_MEMIF_HD_CON0,989		.hd_shift = 0,990		.agent_disable_reg = AUDIO_TOP_CON5,991		.agent_disable_shift = 6,992		.msb_reg = -1,993	},994	{995		.name = "DL2",996		.id = MT2701_MEMIF_DL2,997		.reg_ofs_base = AFE_DL2_BASE,998		.reg_ofs_cur = AFE_DL2_CUR,999		.fs_reg = AFE_DAC_CON1,1000		.fs_shift = 5,1001		.fs_maskbit = 0x1f,1002		.mono_reg = AFE_DAC_CON3,1003		.mono_shift = 17,1004		.enable_reg = AFE_DAC_CON0,1005		.enable_shift = 2,1006		.hd_reg = AFE_MEMIF_HD_CON0,1007		.hd_shift = 2,1008		.agent_disable_reg = AUDIO_TOP_CON5,1009		.agent_disable_shift = 7,1010		.msb_reg = -1,1011	},1012	{1013		.name = "DL3",1014		.id = MT2701_MEMIF_DL3,1015		.reg_ofs_base = AFE_DL3_BASE,1016		.reg_ofs_cur = AFE_DL3_CUR,1017		.fs_reg = AFE_DAC_CON1,1018		.fs_shift = 10,1019		.fs_maskbit = 0x1f,1020		.mono_reg = AFE_DAC_CON3,1021		.mono_shift = 18,1022		.enable_reg = AFE_DAC_CON0,1023		.enable_shift = 3,1024		.hd_reg = AFE_MEMIF_HD_CON0,1025		.hd_shift = 4,1026		.agent_disable_reg = AUDIO_TOP_CON5,1027		.agent_disable_shift = 8,1028		.msb_reg = -1,1029	},1030	{1031		.name = "DL4",1032		.id = MT2701_MEMIF_DL4,1033		.reg_ofs_base = AFE_DL4_BASE,1034		.reg_ofs_cur = AFE_DL4_CUR,1035		.fs_reg = AFE_DAC_CON1,1036		.fs_shift = 15,1037		.fs_maskbit = 0x1f,1038		.mono_reg = AFE_DAC_CON3,1039		.mono_shift = 19,1040		.enable_reg = AFE_DAC_CON0,1041		.enable_shift = 4,1042		.hd_reg = AFE_MEMIF_HD_CON0,1043		.hd_shift = 6,1044		.agent_disable_reg = AUDIO_TOP_CON5,1045		.agent_disable_shift = 9,1046		.msb_reg = -1,1047	},1048	{1049		.name = "DL5",1050		.id = MT2701_MEMIF_DL5,1051		.reg_ofs_base = AFE_DL5_BASE,1052		.reg_ofs_cur = AFE_DL5_CUR,1053		.fs_reg = AFE_DAC_CON1,1054		.fs_shift = 20,1055		.fs_maskbit = 0x1f,1056		.mono_reg = AFE_DAC_CON3,1057		.mono_shift = 20,1058		.enable_reg = AFE_DAC_CON0,1059		.enable_shift = 5,1060		.hd_reg = AFE_MEMIF_HD_CON0,1061		.hd_shift = 8,1062		.agent_disable_reg = AUDIO_TOP_CON5,1063		.agent_disable_shift = 10,1064		.msb_reg = -1,1065	},1066	{1067		.name = "DLM",1068		.id = MT2701_MEMIF_DLM,1069		.reg_ofs_base = AFE_DLMCH_BASE,1070		.reg_ofs_cur = AFE_DLMCH_CUR,1071		.fs_reg = AFE_DAC_CON1,1072		.fs_shift = 0,1073		.fs_maskbit = 0x1f,1074		.mono_reg = -1,1075		.mono_shift = -1,1076		.enable_reg = AFE_DAC_CON0,1077		.enable_shift = 7,1078		.hd_reg = AFE_MEMIF_PBUF_SIZE,1079		.hd_shift = 28,1080		.agent_disable_reg = AUDIO_TOP_CON5,1081		.agent_disable_shift = 12,1082		.msb_reg = -1,1083	},1084	{1085		.name = "UL1",1086		.id = MT2701_MEMIF_UL1,1087		.reg_ofs_base = AFE_VUL_BASE,1088		.reg_ofs_cur = AFE_VUL_CUR,1089		.fs_reg = AFE_DAC_CON2,1090		.fs_shift = 0,1091		.fs_maskbit = 0x1f,1092		.mono_reg = AFE_DAC_CON4,1093		.mono_shift = 0,1094		.enable_reg = AFE_DAC_CON0,1095		.enable_shift = 10,1096		.hd_reg = AFE_MEMIF_HD_CON1,1097		.hd_shift = 0,1098		.agent_disable_reg = AUDIO_TOP_CON5,1099		.agent_disable_shift = 0,1100		.msb_reg = -1,1101	},1102	{1103		.name = "UL2",1104		.id = MT2701_MEMIF_UL2,1105		.reg_ofs_base = AFE_UL2_BASE,1106		.reg_ofs_cur = AFE_UL2_CUR,1107		.fs_reg = AFE_DAC_CON2,1108		.fs_shift = 5,1109		.fs_maskbit = 0x1f,1110		.mono_reg = AFE_DAC_CON4,1111		.mono_shift = 2,1112		.enable_reg = AFE_DAC_CON0,1113		.enable_shift = 11,1114		.hd_reg = AFE_MEMIF_HD_CON1,1115		.hd_shift = 2,1116		.agent_disable_reg = AUDIO_TOP_CON5,1117		.agent_disable_shift = 1,1118		.msb_reg = -1,1119	},1120	{1121		.name = "UL3",1122		.id = MT2701_MEMIF_UL3,1123		.reg_ofs_base = AFE_UL3_BASE,1124		.reg_ofs_cur = AFE_UL3_CUR,1125		.fs_reg = AFE_DAC_CON2,1126		.fs_shift = 10,1127		.fs_maskbit = 0x1f,1128		.mono_reg = AFE_DAC_CON4,1129		.mono_shift = 4,1130		.enable_reg = AFE_DAC_CON0,1131		.enable_shift = 12,1132		.hd_reg = AFE_MEMIF_HD_CON0,1133		.hd_shift = 0,1134		.agent_disable_reg = AUDIO_TOP_CON5,1135		.agent_disable_shift = 2,1136		.msb_reg = -1,1137	},1138	{1139		.name = "UL4",1140		.id = MT2701_MEMIF_UL4,1141		.reg_ofs_base = AFE_UL4_BASE,1142		.reg_ofs_cur = AFE_UL4_CUR,1143		.fs_reg = AFE_DAC_CON2,1144		.fs_shift = 15,1145		.fs_maskbit = 0x1f,1146		.mono_reg = AFE_DAC_CON4,1147		.mono_shift = 6,1148		.enable_reg = AFE_DAC_CON0,1149		.enable_shift = 13,1150		.hd_reg = AFE_MEMIF_HD_CON0,1151		.hd_shift = 6,1152		.agent_disable_reg = AUDIO_TOP_CON5,1153		.agent_disable_shift = 3,1154		.msb_reg = -1,1155	},1156	{1157		.name = "UL5",1158		.id = MT2701_MEMIF_UL5,1159		.reg_ofs_base = AFE_UL5_BASE,1160		.reg_ofs_cur = AFE_UL5_CUR,1161		.fs_reg = AFE_DAC_CON2,1162		.fs_shift = 20,1163		.mono_reg = AFE_DAC_CON4,1164		.mono_shift = 8,1165		.fs_maskbit = 0x1f,1166		.enable_reg = AFE_DAC_CON0,1167		.enable_shift = 14,1168		.hd_reg = AFE_MEMIF_HD_CON0,1169		.hd_shift = 8,1170		.agent_disable_reg = AUDIO_TOP_CON5,1171		.agent_disable_shift = 4,1172		.msb_reg = -1,1173	},1174	{1175		.name = "DLBT",1176		.id = MT2701_MEMIF_DLBT,1177		.reg_ofs_base = AFE_ARB1_BASE,1178		.reg_ofs_cur = AFE_ARB1_CUR,1179		.fs_reg = AFE_DAC_CON3,1180		.fs_shift = 10,1181		.fs_maskbit = 0x1f,1182		.mono_reg = AFE_DAC_CON3,1183		.mono_shift = 22,1184		.enable_reg = AFE_DAC_CON0,1185		.enable_shift = 8,1186		.hd_reg = AFE_MEMIF_HD_CON0,1187		.hd_shift = 14,1188		.agent_disable_reg = AUDIO_TOP_CON5,1189		.agent_disable_shift = 13,1190		.msb_reg = -1,1191	},1192	{1193		.name = "ULBT",1194		.id = MT2701_MEMIF_ULBT,1195		.reg_ofs_base = AFE_DAI_BASE,1196		.reg_ofs_cur = AFE_DAI_CUR,1197		.fs_reg = AFE_DAC_CON2,1198		.fs_shift = 30,1199		.fs_maskbit = 0x1,1200		.mono_reg = -1,1201		.mono_shift = -1,1202		.enable_reg = AFE_DAC_CON0,1203		.enable_shift = 17,1204		.hd_reg = AFE_MEMIF_HD_CON1,1205		.hd_shift = 20,1206		.agent_disable_reg = AUDIO_TOP_CON5,1207		.agent_disable_shift = 16,1208		.msb_reg = -1,1209	},1210};1211 1212static const struct mtk_base_irq_data irq_data[MT2701_IRQ_ASYS_END] = {1213	{1214		.id = MT2701_IRQ_ASYS_IRQ1,1215		.irq_cnt_reg = ASYS_IRQ1_CON,1216		.irq_cnt_shift = 0,1217		.irq_cnt_maskbit = 0xffffff,1218		.irq_fs_reg = ASYS_IRQ1_CON,1219		.irq_fs_shift = 24,1220		.irq_fs_maskbit = 0x1f,1221		.irq_en_reg = ASYS_IRQ1_CON,1222		.irq_en_shift = 31,1223		.irq_clr_reg = ASYS_IRQ_CLR,1224		.irq_clr_shift = 0,1225	},1226	{1227		.id = MT2701_IRQ_ASYS_IRQ2,1228		.irq_cnt_reg = ASYS_IRQ2_CON,1229		.irq_cnt_shift = 0,1230		.irq_cnt_maskbit = 0xffffff,1231		.irq_fs_reg = ASYS_IRQ2_CON,1232		.irq_fs_shift = 24,1233		.irq_fs_maskbit = 0x1f,1234		.irq_en_reg = ASYS_IRQ2_CON,1235		.irq_en_shift = 31,1236		.irq_clr_reg = ASYS_IRQ_CLR,1237		.irq_clr_shift = 1,1238	},1239	{1240		.id = MT2701_IRQ_ASYS_IRQ3,1241		.irq_cnt_reg = ASYS_IRQ3_CON,1242		.irq_cnt_shift = 0,1243		.irq_cnt_maskbit = 0xffffff,1244		.irq_fs_reg = ASYS_IRQ3_CON,1245		.irq_fs_shift = 24,1246		.irq_fs_maskbit = 0x1f,1247		.irq_en_reg = ASYS_IRQ3_CON,1248		.irq_en_shift = 31,1249		.irq_clr_reg = ASYS_IRQ_CLR,1250		.irq_clr_shift = 2,1251	}1252};1253 1254static const struct mt2701_i2s_data mt2701_i2s_data[][2] = {1255	{1256		{ ASYS_I2SO1_CON, 0, 0x1f },1257		{ ASYS_I2SIN1_CON, 0, 0x1f },1258	},1259	{1260		{ ASYS_I2SO2_CON, 5, 0x1f },1261		{ ASYS_I2SIN2_CON, 5, 0x1f },1262	},1263	{1264		{ ASYS_I2SO3_CON, 10, 0x1f },1265		{ ASYS_I2SIN3_CON, 10, 0x1f },1266	},1267	{1268		{ ASYS_I2SO4_CON, 15, 0x1f },1269		{ ASYS_I2SIN4_CON, 15, 0x1f },1270	},1271	/* TODO - extend control registers supported by newer SoCs */1272};1273 1274static irqreturn_t mt2701_asys_isr(int irq_id, void *dev)1275{1276	int id;1277	struct mtk_base_afe *afe = dev;1278	struct mtk_base_afe_memif *memif;1279	struct mtk_base_afe_irq *irq;1280	u32 status;1281 1282	regmap_read(afe->regmap, ASYS_IRQ_STATUS, &status);1283	regmap_write(afe->regmap, ASYS_IRQ_CLR, status);1284 1285	for (id = 0; id < MT2701_MEMIF_NUM; ++id) {1286		memif = &afe->memif[id];1287		if (memif->irq_usage < 0)1288			continue;1289 1290		irq = &afe->irqs[memif->irq_usage];1291		if (status & 1 << irq->irq_data->irq_clr_shift)1292			snd_pcm_period_elapsed(memif->substream);1293	}1294 1295	return IRQ_HANDLED;1296}1297 1298static int mt2701_afe_runtime_suspend(struct device *dev)1299{1300	struct mtk_base_afe *afe = dev_get_drvdata(dev);1301 1302	return mt2701_afe_disable_clock(afe);1303}1304 1305static int mt2701_afe_runtime_resume(struct device *dev)1306{1307	struct mtk_base_afe *afe = dev_get_drvdata(dev);1308 1309	return mt2701_afe_enable_clock(afe);1310}1311 1312static int mt2701_afe_pcm_dev_probe(struct platform_device *pdev)1313{1314	struct mtk_base_afe *afe;1315	struct mt2701_afe_private *afe_priv;1316	struct device *dev;1317	int i, irq_id, ret;1318 1319	afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL);1320	if (!afe)1321		return -ENOMEM;1322 1323	afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv),1324					  GFP_KERNEL);1325	if (!afe->platform_priv)1326		return -ENOMEM;1327 1328	afe_priv = afe->platform_priv;1329	afe_priv->soc = of_device_get_match_data(&pdev->dev);1330	afe->dev = &pdev->dev;1331	dev = afe->dev;1332 1333	afe_priv->i2s_path = devm_kcalloc(dev,1334					  afe_priv->soc->i2s_num,1335					  sizeof(struct mt2701_i2s_path),1336					  GFP_KERNEL);1337	if (!afe_priv->i2s_path)1338		return -ENOMEM;1339 1340	irq_id = platform_get_irq_byname(pdev, "asys");1341	if (irq_id < 0)1342		return irq_id;1343 1344	ret = devm_request_irq(dev, irq_id, mt2701_asys_isr,1345			       IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);1346	if (ret) {1347		dev_err(dev, "could not request_irq for asys-isr\n");1348		return ret;1349	}1350 1351	afe->regmap = syscon_node_to_regmap(dev->parent->of_node);1352	if (IS_ERR(afe->regmap)) {1353		dev_err(dev, "could not get regmap from parent\n");1354		return PTR_ERR(afe->regmap);1355	}1356 1357	mutex_init(&afe->irq_alloc_lock);1358 1359	/* memif initialize */1360	afe->memif_size = MT2701_MEMIF_NUM;1361	afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif),1362				  GFP_KERNEL);1363	if (!afe->memif)1364		return -ENOMEM;1365 1366	for (i = 0; i < afe->memif_size; i++) {1367		afe->memif[i].data = &memif_data_array[i];1368		afe->memif[i].irq_usage = -1;1369	}1370 1371	/* irq initialize */1372	afe->irqs_size = MT2701_IRQ_ASYS_END;1373	afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs),1374				 GFP_KERNEL);1375	if (!afe->irqs)1376		return -ENOMEM;1377 1378	for (i = 0; i < afe->irqs_size; i++)1379		afe->irqs[i].irq_data = &irq_data[i];1380 1381	/* I2S initialize */1382	for (i = 0; i < afe_priv->soc->i2s_num; i++) {1383		afe_priv->i2s_path[i].i2s_data[SNDRV_PCM_STREAM_PLAYBACK] =1384			&mt2701_i2s_data[i][SNDRV_PCM_STREAM_PLAYBACK];1385		afe_priv->i2s_path[i].i2s_data[SNDRV_PCM_STREAM_CAPTURE] =1386			&mt2701_i2s_data[i][SNDRV_PCM_STREAM_CAPTURE];1387	}1388 1389	afe->mtk_afe_hardware = &mt2701_afe_hardware;1390	afe->memif_fs = mt2701_memif_fs;1391	afe->irq_fs = mt2701_irq_fs;1392	afe->reg_back_up_list = mt2701_afe_backup_list;1393	afe->reg_back_up_list_num = ARRAY_SIZE(mt2701_afe_backup_list);1394	afe->runtime_resume = mt2701_afe_runtime_resume;1395	afe->runtime_suspend = mt2701_afe_runtime_suspend;1396 1397	/* initial audio related clock */1398	ret = mt2701_init_clock(afe);1399	if (ret) {1400		dev_err(dev, "init clock error\n");1401		return ret;1402	}1403 1404	platform_set_drvdata(pdev, afe);1405 1406	pm_runtime_enable(dev);1407	if (!pm_runtime_enabled(dev)) {1408		ret = mt2701_afe_runtime_resume(dev);1409		if (ret)1410			goto err_pm_disable;1411	}1412	pm_runtime_get_sync(dev);1413 1414	ret = devm_snd_soc_register_component(&pdev->dev, &mtk_afe_pcm_platform,1415					      NULL, 0);1416	if (ret) {1417		dev_warn(dev, "err_platform\n");1418		goto err_platform;1419	}1420 1421	ret = devm_snd_soc_register_component(&pdev->dev,1422					 &mt2701_afe_pcm_dai_component,1423					 mt2701_afe_pcm_dais,1424					 ARRAY_SIZE(mt2701_afe_pcm_dais));1425	if (ret) {1426		dev_warn(dev, "err_dai_component\n");1427		goto err_platform;1428	}1429 1430	return 0;1431 1432err_platform:1433	pm_runtime_put_sync(dev);1434err_pm_disable:1435	pm_runtime_disable(dev);1436 1437	return ret;1438}1439 1440static void mt2701_afe_pcm_dev_remove(struct platform_device *pdev)1441{1442	pm_runtime_put_sync(&pdev->dev);1443	pm_runtime_disable(&pdev->dev);1444	if (!pm_runtime_status_suspended(&pdev->dev))1445		mt2701_afe_runtime_suspend(&pdev->dev);1446}1447 1448static const struct mt2701_soc_variants mt2701_soc_v1 = {1449	.i2s_num = 4,1450};1451 1452static const struct mt2701_soc_variants mt2701_soc_v2 = {1453	.has_one_heart_mode = true,1454	.i2s_num = 4,1455};1456 1457static const struct of_device_id mt2701_afe_pcm_dt_match[] = {1458	{ .compatible = "mediatek,mt2701-audio", .data = &mt2701_soc_v1 },1459	{ .compatible = "mediatek,mt7622-audio", .data = &mt2701_soc_v2 },1460	{},1461};1462MODULE_DEVICE_TABLE(of, mt2701_afe_pcm_dt_match);1463 1464static const struct dev_pm_ops mt2701_afe_pm_ops = {1465	SET_RUNTIME_PM_OPS(mt2701_afe_runtime_suspend,1466			   mt2701_afe_runtime_resume, NULL)1467};1468 1469static struct platform_driver mt2701_afe_pcm_driver = {1470	.driver = {1471		   .name = "mt2701-audio",1472		   .of_match_table = mt2701_afe_pcm_dt_match,1473		   .pm = &mt2701_afe_pm_ops,1474	},1475	.probe = mt2701_afe_pcm_dev_probe,1476	.remove = mt2701_afe_pcm_dev_remove,1477};1478 1479module_platform_driver(mt2701_afe_pcm_driver);1480 1481MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for 2701");1482MODULE_AUTHOR("Garlic Tseng <garlic.tseng@mediatek.com>");1483MODULE_LICENSE("GPL v2");1484