Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/mediatek/mt8186/mt8186-dai-i2s.c
26488 views
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 <[email protected]>
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
16
enum {
17
I2S_FMT_EIAJ = 0,
18
I2S_FMT_I2S = 1,
19
};
20
21
enum {
22
I2S_WLEN_16_BIT = 0,
23
I2S_WLEN_32_BIT = 1,
24
};
25
26
enum {
27
I2S_HD_NORMAL = 0,
28
I2S_HD_LOW_JITTER = 1,
29
};
30
31
enum {
32
I2S1_SEL_O28_O29 = 0,
33
I2S1_SEL_O03_O04 = 1,
34
};
35
36
enum {
37
I2S_IN_PAD_CONNSYS = 0,
38
I2S_IN_PAD_IO_MUX = 1,
39
};
40
41
struct 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
54
static 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
76
static 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
91
static 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 */
104
static const char * const mt8186_i2s_hd_str[] = {
105
"Normal", "Low_Jitter"
106
};
107
108
static 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
113
static int mt8186_i2s_hd_get(struct snd_kcontrol *kcontrol,
114
struct snd_ctl_elem_value *ucontrol)
115
{
116
struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(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
126
static int mt8186_i2s_hd_set(struct snd_kcontrol *kcontrol,
127
struct snd_ctl_elem_value *ucontrol)
128
{
129
struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(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
152
static 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 */
165
static const char * const i2s_mux_map[] = {
166
"Normal", "Dummy_Widget",
167
};
168
169
static int i2s_mux_map_value[] = {
170
0, 1,
171
};
172
173
static 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
180
static const struct snd_kcontrol_new i2s0_in_mux_control =
181
SOC_DAPM_ENUM("I2S0 In Select", i2s_mux_map_enum);
182
183
static const struct snd_kcontrol_new i2s1_out_mux_control =
184
SOC_DAPM_ENUM("I2S1 Out Select", i2s_mux_map_enum);
185
186
static const struct snd_kcontrol_new i2s2_in_mux_control =
187
SOC_DAPM_ENUM("I2S2 In Select", i2s_mux_map_enum);
188
189
static 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 */
193
static const char * const i2s_lpbk_mux_map[] = {
194
"Normal", "Lpbk",
195
};
196
197
static int i2s_lpbk_mux_map_value[] = {
198
0, 1,
199
};
200
201
static 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
208
static const struct snd_kcontrol_new i2s0_lpbk_mux_control =
209
SOC_DAPM_ENUM("I2S Lpbk Select", i2s0_lpbk_mux_map_enum);
210
211
static 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
218
static const struct snd_kcontrol_new i2s2_lpbk_mux_control =
219
SOC_DAPM_ENUM("I2S Lpbk Select", i2s2_lpbk_mux_map_enum);
220
221
/* interconnection */
222
static 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
255
static 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
290
static 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
319
static 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
350
enum {
351
SUPPLY_SEQ_APLL,
352
SUPPLY_SEQ_I2S_MCLK_EN,
353
SUPPLY_SEQ_I2S_HD_EN,
354
SUPPLY_SEQ_I2S_EN,
355
};
356
357
static 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
384
static 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
414
static 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
442
static 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
537
static 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
552
static 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
575
static 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
594
static 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
617
static 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
633
static 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 */
809
static 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
859
static 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
918
static 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 */
924
static 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
991
static 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
1000
static 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
1048
static 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
1066
static 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 */
1130
enum {
1131
DAI_I2S0 = 0,
1132
DAI_I2S1,
1133
DAI_I2S2,
1134
DAI_I2S3,
1135
DAI_I2S_NUM,
1136
};
1137
1138
static 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
*/
1168
int 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
}
1186
EXPORT_SYMBOL_GPL(mt8186_dai_i2s_set_share);
1187
1188
static 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
1204
int 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
}
1232
1233