1*a94aec03SShunli Wang // SPDX-License-Identifier: GPL-2.0
2*a94aec03SShunli Wang //
3*a94aec03SShunli Wang // MediaTek ALSA SoC Audio DAI Hostless Control
4*a94aec03SShunli Wang //
5*a94aec03SShunli Wang // Copyright (c) 2018 MediaTek Inc.
6*a94aec03SShunli Wang // Author: KaiChieh Chuang <kaichieh.chuang@mediatek.com>
7*a94aec03SShunli Wang
8*a94aec03SShunli Wang #include "mt8183-afe-common.h"
9*a94aec03SShunli Wang
10*a94aec03SShunli Wang /* dai component */
11*a94aec03SShunli Wang static const struct snd_soc_dapm_route mtk_dai_hostless_routes[] = {
12*a94aec03SShunli Wang /* Hostless ADDA Loopback */
13*a94aec03SShunli Wang {"ADDA_DL_CH1", "ADDA_UL_CH1", "Hostless LPBK DL"},
14*a94aec03SShunli Wang {"ADDA_DL_CH1", "ADDA_UL_CH2", "Hostless LPBK DL"},
15*a94aec03SShunli Wang {"ADDA_DL_CH2", "ADDA_UL_CH1", "Hostless LPBK DL"},
16*a94aec03SShunli Wang {"ADDA_DL_CH2", "ADDA_UL_CH2", "Hostless LPBK DL"},
17*a94aec03SShunli Wang {"Hostless LPBK UL", NULL, "ADDA Capture"},
18*a94aec03SShunli Wang
19*a94aec03SShunli Wang /* Hostless Speech */
20*a94aec03SShunli Wang {"ADDA_DL_CH1", "PCM_1_CAP_CH1", "Hostless Speech DL"},
21*a94aec03SShunli Wang {"ADDA_DL_CH2", "PCM_1_CAP_CH1", "Hostless Speech DL"},
22*a94aec03SShunli Wang {"ADDA_DL_CH2", "PCM_1_CAP_CH2", "Hostless Speech DL"},
23*a94aec03SShunli Wang {"ADDA_DL_CH1", "PCM_2_CAP_CH1", "Hostless Speech DL"},
24*a94aec03SShunli Wang {"ADDA_DL_CH2", "PCM_2_CAP_CH1", "Hostless Speech DL"},
25*a94aec03SShunli Wang {"ADDA_DL_CH2", "PCM_2_CAP_CH2", "Hostless Speech DL"},
26*a94aec03SShunli Wang {"PCM_1_PB_CH1", "ADDA_UL_CH1", "Hostless Speech DL"},
27*a94aec03SShunli Wang {"PCM_1_PB_CH2", "ADDA_UL_CH2", "Hostless Speech DL"},
28*a94aec03SShunli Wang {"PCM_2_PB_CH1", "ADDA_UL_CH1", "Hostless Speech DL"},
29*a94aec03SShunli Wang {"PCM_2_PB_CH2", "ADDA_UL_CH2", "Hostless Speech DL"},
30*a94aec03SShunli Wang
31*a94aec03SShunli Wang {"Hostless Speech UL", NULL, "PCM 1 Capture"},
32*a94aec03SShunli Wang {"Hostless Speech UL", NULL, "PCM 2 Capture"},
33*a94aec03SShunli Wang {"Hostless Speech UL", NULL, "ADDA Capture"},
34*a94aec03SShunli Wang };
35*a94aec03SShunli Wang
36*a94aec03SShunli Wang /* dai ops */
mtk_dai_hostless_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)37*a94aec03SShunli Wang static int mtk_dai_hostless_startup(struct snd_pcm_substream *substream,
38*a94aec03SShunli Wang struct snd_soc_dai *dai)
39*a94aec03SShunli Wang {
40*a94aec03SShunli Wang struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
41*a94aec03SShunli Wang
42*a94aec03SShunli Wang return snd_soc_set_runtime_hwparams(substream, afe->mtk_afe_hardware);
43*a94aec03SShunli Wang }
44*a94aec03SShunli Wang
45*a94aec03SShunli Wang static const struct snd_soc_dai_ops mtk_dai_hostless_ops = {
46*a94aec03SShunli Wang .startup = mtk_dai_hostless_startup,
47*a94aec03SShunli Wang };
48*a94aec03SShunli Wang
49*a94aec03SShunli Wang /* dai driver */
50*a94aec03SShunli Wang #define MTK_HOSTLESS_RATES (SNDRV_PCM_RATE_8000_48000 |\
51*a94aec03SShunli Wang SNDRV_PCM_RATE_88200 |\
52*a94aec03SShunli Wang SNDRV_PCM_RATE_96000 |\
53*a94aec03SShunli Wang SNDRV_PCM_RATE_176400 |\
54*a94aec03SShunli Wang SNDRV_PCM_RATE_192000)
55*a94aec03SShunli Wang
56*a94aec03SShunli Wang #define MTK_HOSTLESS_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
57*a94aec03SShunli Wang SNDRV_PCM_FMTBIT_S24_LE |\
58*a94aec03SShunli Wang SNDRV_PCM_FMTBIT_S32_LE)
59*a94aec03SShunli Wang
60*a94aec03SShunli Wang static struct snd_soc_dai_driver mtk_dai_hostless_driver[] = {
61*a94aec03SShunli Wang {
62*a94aec03SShunli Wang .name = "Hostless LPBK DAI",
63*a94aec03SShunli Wang .id = MT8183_DAI_HOSTLESS_LPBK,
64*a94aec03SShunli Wang .playback = {
65*a94aec03SShunli Wang .stream_name = "Hostless LPBK DL",
66*a94aec03SShunli Wang .channels_min = 1,
67*a94aec03SShunli Wang .channels_max = 2,
68*a94aec03SShunli Wang .rates = MTK_HOSTLESS_RATES,
69*a94aec03SShunli Wang .formats = MTK_HOSTLESS_FORMATS,
70*a94aec03SShunli Wang },
71*a94aec03SShunli Wang .capture = {
72*a94aec03SShunli Wang .stream_name = "Hostless LPBK UL",
73*a94aec03SShunli Wang .channels_min = 1,
74*a94aec03SShunli Wang .channels_max = 2,
75*a94aec03SShunli Wang .rates = MTK_HOSTLESS_RATES,
76*a94aec03SShunli Wang .formats = MTK_HOSTLESS_FORMATS,
77*a94aec03SShunli Wang },
78*a94aec03SShunli Wang .ops = &mtk_dai_hostless_ops,
79*a94aec03SShunli Wang },
80*a94aec03SShunli Wang {
81*a94aec03SShunli Wang .name = "Hostless Speech DAI",
82*a94aec03SShunli Wang .id = MT8183_DAI_HOSTLESS_SPEECH,
83*a94aec03SShunli Wang .playback = {
84*a94aec03SShunli Wang .stream_name = "Hostless Speech DL",
85*a94aec03SShunli Wang .channels_min = 1,
86*a94aec03SShunli Wang .channels_max = 2,
87*a94aec03SShunli Wang .rates = MTK_HOSTLESS_RATES,
88*a94aec03SShunli Wang .formats = MTK_HOSTLESS_FORMATS,
89*a94aec03SShunli Wang },
90*a94aec03SShunli Wang .capture = {
91*a94aec03SShunli Wang .stream_name = "Hostless Speech UL",
92*a94aec03SShunli Wang .channels_min = 1,
93*a94aec03SShunli Wang .channels_max = 2,
94*a94aec03SShunli Wang .rates = MTK_HOSTLESS_RATES,
95*a94aec03SShunli Wang .formats = MTK_HOSTLESS_FORMATS,
96*a94aec03SShunli Wang },
97*a94aec03SShunli Wang .ops = &mtk_dai_hostless_ops,
98*a94aec03SShunli Wang },
99*a94aec03SShunli Wang };
100*a94aec03SShunli Wang
mt8183_dai_hostless_register(struct mtk_base_afe * afe)101*a94aec03SShunli Wang int mt8183_dai_hostless_register(struct mtk_base_afe *afe)
102*a94aec03SShunli Wang {
103*a94aec03SShunli Wang struct mtk_base_afe_dai *dai;
104*a94aec03SShunli Wang
105*a94aec03SShunli Wang dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
106*a94aec03SShunli Wang if (!dai)
107*a94aec03SShunli Wang return -ENOMEM;
108*a94aec03SShunli Wang
109*a94aec03SShunli Wang list_add(&dai->list, &afe->sub_dais);
110*a94aec03SShunli Wang
111*a94aec03SShunli Wang dai->dai_drivers = mtk_dai_hostless_driver;
112*a94aec03SShunli Wang dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_hostless_driver);
113*a94aec03SShunli Wang
114*a94aec03SShunli Wang dai->dapm_routes = mtk_dai_hostless_routes;
115*a94aec03SShunli Wang dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_hostless_routes);
116*a94aec03SShunli Wang
117*a94aec03SShunli Wang return 0;
118*a94aec03SShunli Wang }
119