18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci//
38c2ecf20Sopenharmony_ci// MediaTek ALSA SoC Audio DAI Hostless Control
48c2ecf20Sopenharmony_ci//
58c2ecf20Sopenharmony_ci// Copyright (c) 2018 MediaTek Inc.
68c2ecf20Sopenharmony_ci// Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include "mt8183-afe-common.h"
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci/* dai component */
118c2ecf20Sopenharmony_cistatic const struct snd_soc_dapm_route mtk_dai_hostless_routes[] = {
128c2ecf20Sopenharmony_ci	/* Hostless ADDA Loopback */
138c2ecf20Sopenharmony_ci	{"ADDA_DL_CH1", "ADDA_UL_CH1", "Hostless LPBK DL"},
148c2ecf20Sopenharmony_ci	{"ADDA_DL_CH1", "ADDA_UL_CH2", "Hostless LPBK DL"},
158c2ecf20Sopenharmony_ci	{"ADDA_DL_CH2", "ADDA_UL_CH1", "Hostless LPBK DL"},
168c2ecf20Sopenharmony_ci	{"ADDA_DL_CH2", "ADDA_UL_CH2", "Hostless LPBK DL"},
178c2ecf20Sopenharmony_ci	{"Hostless LPBK UL", NULL, "ADDA Capture"},
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci	/* Hostless Speech */
208c2ecf20Sopenharmony_ci	{"ADDA_DL_CH1", "PCM_1_CAP_CH1", "Hostless Speech DL"},
218c2ecf20Sopenharmony_ci	{"ADDA_DL_CH2", "PCM_1_CAP_CH1", "Hostless Speech DL"},
228c2ecf20Sopenharmony_ci	{"ADDA_DL_CH2", "PCM_1_CAP_CH2", "Hostless Speech DL"},
238c2ecf20Sopenharmony_ci	{"ADDA_DL_CH1", "PCM_2_CAP_CH1", "Hostless Speech DL"},
248c2ecf20Sopenharmony_ci	{"ADDA_DL_CH2", "PCM_2_CAP_CH1", "Hostless Speech DL"},
258c2ecf20Sopenharmony_ci	{"ADDA_DL_CH2", "PCM_2_CAP_CH2", "Hostless Speech DL"},
268c2ecf20Sopenharmony_ci	{"PCM_1_PB_CH1", "ADDA_UL_CH1", "Hostless Speech DL"},
278c2ecf20Sopenharmony_ci	{"PCM_1_PB_CH2", "ADDA_UL_CH2", "Hostless Speech DL"},
288c2ecf20Sopenharmony_ci	{"PCM_2_PB_CH1", "ADDA_UL_CH1", "Hostless Speech DL"},
298c2ecf20Sopenharmony_ci	{"PCM_2_PB_CH2", "ADDA_UL_CH2", "Hostless Speech DL"},
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci	{"Hostless Speech UL", NULL, "PCM 1 Capture"},
328c2ecf20Sopenharmony_ci	{"Hostless Speech UL", NULL, "PCM 2 Capture"},
338c2ecf20Sopenharmony_ci	{"Hostless Speech UL", NULL, "ADDA Capture"},
348c2ecf20Sopenharmony_ci};
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci/* dai ops */
378c2ecf20Sopenharmony_cistatic int mtk_dai_hostless_startup(struct snd_pcm_substream *substream,
388c2ecf20Sopenharmony_ci				    struct snd_soc_dai *dai)
398c2ecf20Sopenharmony_ci{
408c2ecf20Sopenharmony_ci	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	return snd_soc_set_runtime_hwparams(substream, afe->mtk_afe_hardware);
438c2ecf20Sopenharmony_ci}
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_cistatic const struct snd_soc_dai_ops mtk_dai_hostless_ops = {
468c2ecf20Sopenharmony_ci	.startup = mtk_dai_hostless_startup,
478c2ecf20Sopenharmony_ci};
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci/* dai driver */
508c2ecf20Sopenharmony_ci#define MTK_HOSTLESS_RATES (SNDRV_PCM_RATE_8000_48000 |\
518c2ecf20Sopenharmony_ci			   SNDRV_PCM_RATE_88200 |\
528c2ecf20Sopenharmony_ci			   SNDRV_PCM_RATE_96000 |\
538c2ecf20Sopenharmony_ci			   SNDRV_PCM_RATE_176400 |\
548c2ecf20Sopenharmony_ci			   SNDRV_PCM_RATE_192000)
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci#define MTK_HOSTLESS_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
578c2ecf20Sopenharmony_ci			     SNDRV_PCM_FMTBIT_S24_LE |\
588c2ecf20Sopenharmony_ci			     SNDRV_PCM_FMTBIT_S32_LE)
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_cistatic struct snd_soc_dai_driver mtk_dai_hostless_driver[] = {
618c2ecf20Sopenharmony_ci	{
628c2ecf20Sopenharmony_ci		.name = "Hostless LPBK DAI",
638c2ecf20Sopenharmony_ci		.id = MT8183_DAI_HOSTLESS_LPBK,
648c2ecf20Sopenharmony_ci		.playback = {
658c2ecf20Sopenharmony_ci			.stream_name = "Hostless LPBK DL",
668c2ecf20Sopenharmony_ci			.channels_min = 1,
678c2ecf20Sopenharmony_ci			.channels_max = 2,
688c2ecf20Sopenharmony_ci			.rates = MTK_HOSTLESS_RATES,
698c2ecf20Sopenharmony_ci			.formats = MTK_HOSTLESS_FORMATS,
708c2ecf20Sopenharmony_ci		},
718c2ecf20Sopenharmony_ci		.capture = {
728c2ecf20Sopenharmony_ci			.stream_name = "Hostless LPBK UL",
738c2ecf20Sopenharmony_ci			.channels_min = 1,
748c2ecf20Sopenharmony_ci			.channels_max = 2,
758c2ecf20Sopenharmony_ci			.rates = MTK_HOSTLESS_RATES,
768c2ecf20Sopenharmony_ci			.formats = MTK_HOSTLESS_FORMATS,
778c2ecf20Sopenharmony_ci		},
788c2ecf20Sopenharmony_ci		.ops = &mtk_dai_hostless_ops,
798c2ecf20Sopenharmony_ci	},
808c2ecf20Sopenharmony_ci	{
818c2ecf20Sopenharmony_ci		.name = "Hostless Speech DAI",
828c2ecf20Sopenharmony_ci		.id = MT8183_DAI_HOSTLESS_SPEECH,
838c2ecf20Sopenharmony_ci		.playback = {
848c2ecf20Sopenharmony_ci			.stream_name = "Hostless Speech DL",
858c2ecf20Sopenharmony_ci			.channels_min = 1,
868c2ecf20Sopenharmony_ci			.channels_max = 2,
878c2ecf20Sopenharmony_ci			.rates = MTK_HOSTLESS_RATES,
888c2ecf20Sopenharmony_ci			.formats = MTK_HOSTLESS_FORMATS,
898c2ecf20Sopenharmony_ci		},
908c2ecf20Sopenharmony_ci		.capture = {
918c2ecf20Sopenharmony_ci			.stream_name = "Hostless Speech UL",
928c2ecf20Sopenharmony_ci			.channels_min = 1,
938c2ecf20Sopenharmony_ci			.channels_max = 2,
948c2ecf20Sopenharmony_ci			.rates = MTK_HOSTLESS_RATES,
958c2ecf20Sopenharmony_ci			.formats = MTK_HOSTLESS_FORMATS,
968c2ecf20Sopenharmony_ci		},
978c2ecf20Sopenharmony_ci		.ops = &mtk_dai_hostless_ops,
988c2ecf20Sopenharmony_ci	},
998c2ecf20Sopenharmony_ci};
1008c2ecf20Sopenharmony_ci
1018c2ecf20Sopenharmony_ciint mt8183_dai_hostless_register(struct mtk_base_afe *afe)
1028c2ecf20Sopenharmony_ci{
1038c2ecf20Sopenharmony_ci	struct mtk_base_afe_dai *dai;
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
1068c2ecf20Sopenharmony_ci	if (!dai)
1078c2ecf20Sopenharmony_ci		return -ENOMEM;
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci	list_add(&dai->list, &afe->sub_dais);
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci	dai->dai_drivers = mtk_dai_hostless_driver;
1128c2ecf20Sopenharmony_ci	dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_hostless_driver);
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	dai->dapm_routes = mtk_dai_hostless_routes;
1158c2ecf20Sopenharmony_ci	dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_hostless_routes);
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	return 0;
1188c2ecf20Sopenharmony_ci}
119