Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
26488 views
1
// SPDX-License-Identifier: GPL-2.0
2
//
3
// mt8183-mt6358.c --
4
// MT8183-MT6358-TS3A227-MAX98357 ALSA SoC machine driver
5
//
6
// Copyright (c) 2018 MediaTek Inc.
7
// Author: Shunli Wang <[email protected]>
8
9
#include <linux/module.h>
10
#include <linux/of.h>
11
#include <linux/pinctrl/consumer.h>
12
#include <sound/jack.h>
13
#include <sound/pcm_params.h>
14
#include <sound/soc.h>
15
16
#include "../../codecs/rt1015.h"
17
#include "../../codecs/ts3a227e.h"
18
#include "../common/mtk-afe-platform-driver.h"
19
#include "mt8183-afe-common.h"
20
21
#define RT1015_CODEC_DAI "rt1015-aif"
22
#define RT1015_DEV0_NAME "rt1015.6-0028"
23
#define RT1015_DEV1_NAME "rt1015.6-0029"
24
25
enum PINCTRL_PIN_STATE {
26
PIN_STATE_DEFAULT = 0,
27
PIN_TDM_OUT_ON,
28
PIN_TDM_OUT_OFF,
29
PIN_WOV,
30
PIN_STATE_MAX
31
};
32
33
static const char * const mt8183_pin_str[PIN_STATE_MAX] = {
34
"default", "aud_tdm_out_on", "aud_tdm_out_off", "wov",
35
};
36
37
struct mt8183_mt6358_ts3a227_max98357_priv {
38
struct pinctrl *pinctrl;
39
struct pinctrl_state *pin_states[PIN_STATE_MAX];
40
struct snd_soc_jack headset_jack, hdmi_jack;
41
};
42
43
static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream,
44
struct snd_pcm_hw_params *params)
45
{
46
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
47
unsigned int rate = params_rate(params);
48
unsigned int mclk_fs_ratio = 128;
49
unsigned int mclk_fs = rate * mclk_fs_ratio;
50
51
return snd_soc_dai_set_sysclk(snd_soc_rtd_to_cpu(rtd, 0),
52
0, mclk_fs, SND_SOC_CLOCK_OUT);
53
}
54
55
static const struct snd_soc_ops mt8183_mt6358_i2s_ops = {
56
.hw_params = mt8183_mt6358_i2s_hw_params,
57
};
58
59
static int
60
mt8183_mt6358_rt1015_i2s_hw_params(struct snd_pcm_substream *substream,
61
struct snd_pcm_hw_params *params)
62
{
63
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
64
unsigned int rate = params_rate(params);
65
unsigned int mclk_fs_ratio = 128;
66
unsigned int mclk_fs = rate * mclk_fs_ratio;
67
struct snd_soc_card *card = rtd->card;
68
struct snd_soc_dai *codec_dai;
69
int ret, i;
70
71
for_each_rtd_codec_dais(rtd, i, codec_dai) {
72
ret = snd_soc_dai_set_pll(codec_dai, 0, RT1015_PLL_S_BCLK,
73
rate * 64, rate * 256);
74
if (ret < 0) {
75
dev_err(card->dev, "failed to set pll\n");
76
return ret;
77
}
78
79
ret = snd_soc_dai_set_sysclk(codec_dai, RT1015_SCLK_S_PLL,
80
rate * 256, SND_SOC_CLOCK_IN);
81
if (ret < 0) {
82
dev_err(card->dev, "failed to set sysclk\n");
83
return ret;
84
}
85
}
86
87
return snd_soc_dai_set_sysclk(snd_soc_rtd_to_cpu(rtd, 0),
88
0, mclk_fs, SND_SOC_CLOCK_OUT);
89
}
90
91
static const struct snd_soc_ops mt8183_mt6358_rt1015_i2s_ops = {
92
.hw_params = mt8183_mt6358_rt1015_i2s_hw_params,
93
};
94
95
static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
96
struct snd_pcm_hw_params *params)
97
{
98
dev_dbg(rtd->dev, "%s(), fix format to S32_LE\n", __func__);
99
100
/* fix BE i2s format to S32_LE, clean param mask first */
101
snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
102
0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
103
104
params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);
105
return 0;
106
}
107
108
static int mt8183_rt1015_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
109
struct snd_pcm_hw_params *params)
110
{
111
dev_dbg(rtd->dev, "%s(), fix format to S24_LE\n", __func__);
112
113
/* fix BE i2s format to S24_LE, clean param mask first */
114
snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
115
0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST);
116
117
params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
118
return 0;
119
}
120
121
static int
122
mt8183_mt6358_startup(struct snd_pcm_substream *substream)
123
{
124
static const unsigned int rates[] = {
125
48000,
126
};
127
static const struct snd_pcm_hw_constraint_list constraints_rates = {
128
.count = ARRAY_SIZE(rates),
129
.list = rates,
130
.mask = 0,
131
};
132
static const unsigned int channels[] = {
133
2,
134
};
135
static const struct snd_pcm_hw_constraint_list constraints_channels = {
136
.count = ARRAY_SIZE(channels),
137
.list = channels,
138
.mask = 0,
139
};
140
141
struct snd_pcm_runtime *runtime = substream->runtime;
142
143
snd_pcm_hw_constraint_list(runtime, 0,
144
SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
145
runtime->hw.channels_max = 2;
146
snd_pcm_hw_constraint_list(runtime, 0,
147
SNDRV_PCM_HW_PARAM_CHANNELS,
148
&constraints_channels);
149
150
runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
151
snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
152
153
return 0;
154
}
155
156
static const struct snd_soc_ops mt8183_mt6358_ops = {
157
.startup = mt8183_mt6358_startup,
158
};
159
160
static int
161
mt8183_mt6358_ts3a227_max98357_bt_sco_startup(
162
struct snd_pcm_substream *substream)
163
{
164
static const unsigned int rates[] = {
165
8000, 16000
166
};
167
static const struct snd_pcm_hw_constraint_list constraints_rates = {
168
.count = ARRAY_SIZE(rates),
169
.list = rates,
170
.mask = 0,
171
};
172
static const unsigned int channels[] = {
173
1,
174
};
175
static const struct snd_pcm_hw_constraint_list constraints_channels = {
176
.count = ARRAY_SIZE(channels),
177
.list = channels,
178
.mask = 0,
179
};
180
181
struct snd_pcm_runtime *runtime = substream->runtime;
182
183
snd_pcm_hw_constraint_list(runtime, 0,
184
SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
185
runtime->hw.channels_max = 1;
186
snd_pcm_hw_constraint_list(runtime, 0,
187
SNDRV_PCM_HW_PARAM_CHANNELS,
188
&constraints_channels);
189
190
runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
191
snd_pcm_hw_constraint_msbits(runtime, 0, 16, 16);
192
193
return 0;
194
}
195
196
static const struct snd_soc_ops mt8183_mt6358_ts3a227_max98357_bt_sco_ops = {
197
.startup = mt8183_mt6358_ts3a227_max98357_bt_sco_startup,
198
};
199
200
/* FE */
201
SND_SOC_DAILINK_DEFS(playback1,
202
DAILINK_COMP_ARRAY(COMP_CPU("DL1")),
203
DAILINK_COMP_ARRAY(COMP_DUMMY()),
204
DAILINK_COMP_ARRAY(COMP_EMPTY()));
205
206
SND_SOC_DAILINK_DEFS(playback2,
207
DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
208
DAILINK_COMP_ARRAY(COMP_DUMMY()),
209
DAILINK_COMP_ARRAY(COMP_EMPTY()));
210
211
SND_SOC_DAILINK_DEFS(playback3,
212
DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
213
DAILINK_COMP_ARRAY(COMP_DUMMY()),
214
DAILINK_COMP_ARRAY(COMP_EMPTY()));
215
216
SND_SOC_DAILINK_DEFS(capture1,
217
DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
218
DAILINK_COMP_ARRAY(COMP_DUMMY()),
219
DAILINK_COMP_ARRAY(COMP_EMPTY()));
220
221
SND_SOC_DAILINK_DEFS(capture2,
222
DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
223
DAILINK_COMP_ARRAY(COMP_DUMMY()),
224
DAILINK_COMP_ARRAY(COMP_EMPTY()));
225
226
SND_SOC_DAILINK_DEFS(capture3,
227
DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
228
DAILINK_COMP_ARRAY(COMP_DUMMY()),
229
DAILINK_COMP_ARRAY(COMP_EMPTY()));
230
231
SND_SOC_DAILINK_DEFS(capture_mono,
232
DAILINK_COMP_ARRAY(COMP_CPU("UL_MONO_1")),
233
DAILINK_COMP_ARRAY(COMP_DUMMY()),
234
DAILINK_COMP_ARRAY(COMP_EMPTY()));
235
236
SND_SOC_DAILINK_DEFS(playback_hdmi,
237
DAILINK_COMP_ARRAY(COMP_CPU("HDMI")),
238
DAILINK_COMP_ARRAY(COMP_DUMMY()),
239
DAILINK_COMP_ARRAY(COMP_EMPTY()));
240
241
SND_SOC_DAILINK_DEFS(wake_on_voice,
242
DAILINK_COMP_ARRAY(COMP_DUMMY()),
243
DAILINK_COMP_ARRAY(COMP_DUMMY()),
244
DAILINK_COMP_ARRAY(COMP_EMPTY()));
245
246
/* BE */
247
SND_SOC_DAILINK_DEFS(primary_codec,
248
DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
249
DAILINK_COMP_ARRAY(COMP_CODEC("mt6358-sound", "mt6358-snd-codec-aif1")),
250
DAILINK_COMP_ARRAY(COMP_EMPTY()));
251
252
SND_SOC_DAILINK_DEFS(pcm1,
253
DAILINK_COMP_ARRAY(COMP_CPU("PCM 1")),
254
DAILINK_COMP_ARRAY(COMP_DUMMY()),
255
DAILINK_COMP_ARRAY(COMP_EMPTY()));
256
257
SND_SOC_DAILINK_DEFS(pcm2,
258
DAILINK_COMP_ARRAY(COMP_CPU("PCM 2")),
259
DAILINK_COMP_ARRAY(COMP_DUMMY()),
260
DAILINK_COMP_ARRAY(COMP_EMPTY()));
261
262
SND_SOC_DAILINK_DEFS(i2s0,
263
DAILINK_COMP_ARRAY(COMP_CPU("I2S0")),
264
DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm-wb")),
265
DAILINK_COMP_ARRAY(COMP_EMPTY()));
266
267
SND_SOC_DAILINK_DEFS(i2s1,
268
DAILINK_COMP_ARRAY(COMP_CPU("I2S1")),
269
DAILINK_COMP_ARRAY(COMP_DUMMY()),
270
DAILINK_COMP_ARRAY(COMP_EMPTY()));
271
272
SND_SOC_DAILINK_DEFS(i2s2,
273
DAILINK_COMP_ARRAY(COMP_CPU("I2S2")),
274
DAILINK_COMP_ARRAY(COMP_DUMMY()),
275
DAILINK_COMP_ARRAY(COMP_EMPTY()));
276
277
SND_SOC_DAILINK_DEFS(i2s3_max98357a,
278
DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
279
DAILINK_COMP_ARRAY(COMP_CODEC("max98357a", "HiFi")),
280
DAILINK_COMP_ARRAY(COMP_EMPTY()));
281
282
SND_SOC_DAILINK_DEFS(i2s3_rt1015,
283
DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
284
DAILINK_COMP_ARRAY(COMP_CODEC(RT1015_DEV0_NAME, RT1015_CODEC_DAI),
285
COMP_CODEC(RT1015_DEV1_NAME, RT1015_CODEC_DAI)),
286
DAILINK_COMP_ARRAY(COMP_EMPTY()));
287
288
SND_SOC_DAILINK_DEFS(i2s3_rt1015p,
289
DAILINK_COMP_ARRAY(COMP_CPU("I2S3")),
290
DAILINK_COMP_ARRAY(COMP_CODEC("rt1015p", "HiFi")),
291
DAILINK_COMP_ARRAY(COMP_EMPTY()));
292
293
SND_SOC_DAILINK_DEFS(i2s5,
294
DAILINK_COMP_ARRAY(COMP_CPU("I2S5")),
295
DAILINK_COMP_ARRAY(COMP_CODEC("bt-sco", "bt-sco-pcm-wb")),
296
DAILINK_COMP_ARRAY(COMP_EMPTY()));
297
298
SND_SOC_DAILINK_DEFS(tdm,
299
DAILINK_COMP_ARRAY(COMP_CPU("TDM")),
300
DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "i2s-hifi")),
301
DAILINK_COMP_ARRAY(COMP_EMPTY()));
302
303
static int mt8183_mt6358_tdm_startup(struct snd_pcm_substream *substream)
304
{
305
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
306
struct mt8183_mt6358_ts3a227_max98357_priv *priv =
307
snd_soc_card_get_drvdata(rtd->card);
308
int ret;
309
310
if (IS_ERR(priv->pin_states[PIN_TDM_OUT_ON]))
311
return PTR_ERR(priv->pin_states[PIN_TDM_OUT_ON]);
312
313
ret = pinctrl_select_state(priv->pinctrl,
314
priv->pin_states[PIN_TDM_OUT_ON]);
315
if (ret)
316
dev_err(rtd->card->dev, "%s failed to select state %d\n",
317
__func__, ret);
318
319
return ret;
320
}
321
322
static void mt8183_mt6358_tdm_shutdown(struct snd_pcm_substream *substream)
323
{
324
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
325
struct mt8183_mt6358_ts3a227_max98357_priv *priv =
326
snd_soc_card_get_drvdata(rtd->card);
327
int ret;
328
329
if (IS_ERR(priv->pin_states[PIN_TDM_OUT_OFF]))
330
return;
331
332
ret = pinctrl_select_state(priv->pinctrl,
333
priv->pin_states[PIN_TDM_OUT_OFF]);
334
if (ret)
335
dev_err(rtd->card->dev, "%s failed to select state %d\n",
336
__func__, ret);
337
}
338
339
static const struct snd_soc_ops mt8183_mt6358_tdm_ops = {
340
.startup = mt8183_mt6358_tdm_startup,
341
.shutdown = mt8183_mt6358_tdm_shutdown,
342
};
343
344
static int
345
mt8183_mt6358_ts3a227_max98357_wov_startup(
346
struct snd_pcm_substream *substream)
347
{
348
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
349
struct snd_soc_card *card = rtd->card;
350
struct mt8183_mt6358_ts3a227_max98357_priv *priv =
351
snd_soc_card_get_drvdata(card);
352
353
return pinctrl_select_state(priv->pinctrl,
354
priv->pin_states[PIN_WOV]);
355
}
356
357
static void
358
mt8183_mt6358_ts3a227_max98357_wov_shutdown(
359
struct snd_pcm_substream *substream)
360
{
361
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
362
struct snd_soc_card *card = rtd->card;
363
struct mt8183_mt6358_ts3a227_max98357_priv *priv =
364
snd_soc_card_get_drvdata(card);
365
int ret;
366
367
ret = pinctrl_select_state(priv->pinctrl,
368
priv->pin_states[PIN_STATE_DEFAULT]);
369
if (ret)
370
dev_err(card->dev, "%s failed to select state %d\n",
371
__func__, ret);
372
}
373
374
static const struct snd_soc_ops mt8183_mt6358_ts3a227_max98357_wov_ops = {
375
.startup = mt8183_mt6358_ts3a227_max98357_wov_startup,
376
.shutdown = mt8183_mt6358_ts3a227_max98357_wov_shutdown,
377
};
378
379
static int
380
mt8183_mt6358_ts3a227_max98357_hdmi_init(struct snd_soc_pcm_runtime *rtd)
381
{
382
struct mt8183_mt6358_ts3a227_max98357_priv *priv =
383
snd_soc_card_get_drvdata(rtd->card);
384
int ret;
385
386
ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
387
&priv->hdmi_jack);
388
if (ret)
389
return ret;
390
391
return snd_soc_component_set_jack(snd_soc_rtd_to_codec(rtd, 0)->component,
392
&priv->hdmi_jack, NULL);
393
}
394
395
static int mt8183_bt_init(struct snd_soc_pcm_runtime *rtd)
396
{
397
struct snd_soc_component *cmpnt_afe =
398
snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
399
struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
400
int ret;
401
402
ret = mt8183_dai_i2s_set_share(afe, "I2S5", "I2S0");
403
if (ret) {
404
dev_err(rtd->dev, "Failed to set up shared clocks\n");
405
return ret;
406
}
407
return 0;
408
}
409
410
static int mt8183_i2s2_init(struct snd_soc_pcm_runtime *rtd)
411
{
412
struct snd_soc_component *cmpnt_afe =
413
snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
414
struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe);
415
int ret;
416
417
ret = mt8183_dai_i2s_set_share(afe, "I2S2", "I2S3");
418
if (ret) {
419
dev_err(rtd->dev, "Failed to set up shared clocks\n");
420
return ret;
421
}
422
return 0;
423
}
424
425
static struct snd_soc_dai_link mt8183_mt6358_ts3a227_dai_links[] = {
426
/* FE */
427
{
428
.name = "Playback_1",
429
.stream_name = "Playback_1",
430
.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
431
SND_SOC_DPCM_TRIGGER_PRE},
432
.dynamic = 1,
433
.playback_only = 1,
434
.ops = &mt8183_mt6358_ops,
435
SND_SOC_DAILINK_REG(playback1),
436
},
437
{
438
.name = "Playback_2",
439
.stream_name = "Playback_2",
440
.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
441
SND_SOC_DPCM_TRIGGER_PRE},
442
.dynamic = 1,
443
.playback_only = 1,
444
.ops = &mt8183_mt6358_ts3a227_max98357_bt_sco_ops,
445
SND_SOC_DAILINK_REG(playback2),
446
},
447
{
448
.name = "Playback_3",
449
.stream_name = "Playback_3",
450
.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
451
SND_SOC_DPCM_TRIGGER_PRE},
452
.dynamic = 1,
453
.playback_only = 1,
454
SND_SOC_DAILINK_REG(playback3),
455
},
456
{
457
.name = "Capture_1",
458
.stream_name = "Capture_1",
459
.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
460
SND_SOC_DPCM_TRIGGER_PRE},
461
.dynamic = 1,
462
.capture_only = 1,
463
.ops = &mt8183_mt6358_ts3a227_max98357_bt_sco_ops,
464
SND_SOC_DAILINK_REG(capture1),
465
},
466
{
467
.name = "Capture_2",
468
.stream_name = "Capture_2",
469
.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
470
SND_SOC_DPCM_TRIGGER_PRE},
471
.dynamic = 1,
472
.capture_only = 1,
473
SND_SOC_DAILINK_REG(capture2),
474
},
475
{
476
.name = "Capture_3",
477
.stream_name = "Capture_3",
478
.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
479
SND_SOC_DPCM_TRIGGER_PRE},
480
.dynamic = 1,
481
.capture_only = 1,
482
.ops = &mt8183_mt6358_ops,
483
SND_SOC_DAILINK_REG(capture3),
484
},
485
{
486
.name = "Capture_Mono_1",
487
.stream_name = "Capture_Mono_1",
488
.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
489
SND_SOC_DPCM_TRIGGER_PRE},
490
.dynamic = 1,
491
.capture_only = 1,
492
SND_SOC_DAILINK_REG(capture_mono),
493
},
494
{
495
.name = "Playback_HDMI",
496
.stream_name = "Playback_HDMI",
497
.trigger = {SND_SOC_DPCM_TRIGGER_PRE,
498
SND_SOC_DPCM_TRIGGER_PRE},
499
.dynamic = 1,
500
.playback_only = 1,
501
SND_SOC_DAILINK_REG(playback_hdmi),
502
},
503
{
504
.name = "Wake on Voice",
505
.stream_name = "Wake on Voice",
506
.ignore_suspend = 1,
507
.ignore = 1,
508
SND_SOC_DAILINK_REG(wake_on_voice),
509
.ops = &mt8183_mt6358_ts3a227_max98357_wov_ops,
510
},
511
512
/* BE */
513
{
514
.name = "Primary Codec",
515
.no_pcm = 1,
516
.ignore_suspend = 1,
517
SND_SOC_DAILINK_REG(primary_codec),
518
},
519
{
520
.name = "PCM 1",
521
.no_pcm = 1,
522
.ignore_suspend = 1,
523
SND_SOC_DAILINK_REG(pcm1),
524
},
525
{
526
.name = "PCM 2",
527
.no_pcm = 1,
528
.ignore_suspend = 1,
529
SND_SOC_DAILINK_REG(pcm2),
530
},
531
{
532
.name = "I2S0",
533
.no_pcm = 1,
534
.capture_only = 1,
535
.ignore_suspend = 1,
536
.ops = &mt8183_mt6358_i2s_ops,
537
SND_SOC_DAILINK_REG(i2s0),
538
},
539
{
540
.name = "I2S1",
541
.no_pcm = 1,
542
.playback_only = 1,
543
.ignore_suspend = 1,
544
.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
545
.ops = &mt8183_mt6358_i2s_ops,
546
SND_SOC_DAILINK_REG(i2s1),
547
},
548
{
549
.name = "I2S2",
550
.no_pcm = 1,
551
.capture_only = 1,
552
.ignore_suspend = 1,
553
.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
554
.ops = &mt8183_mt6358_i2s_ops,
555
.init = &mt8183_i2s2_init,
556
SND_SOC_DAILINK_REG(i2s2),
557
},
558
{
559
.name = "I2S3",
560
.no_pcm = 1,
561
.playback_only = 1,
562
.ignore_suspend = 1,
563
},
564
{
565
.name = "I2S5",
566
.no_pcm = 1,
567
.playback_only = 1,
568
.ignore_suspend = 1,
569
.ops = &mt8183_mt6358_i2s_ops,
570
.init = &mt8183_bt_init,
571
SND_SOC_DAILINK_REG(i2s5),
572
},
573
{
574
.name = "TDM",
575
.no_pcm = 1,
576
.dai_fmt = SND_SOC_DAIFMT_I2S |
577
SND_SOC_DAIFMT_IB_IF |
578
SND_SOC_DAIFMT_CBP_CFP,
579
.playback_only = 1,
580
.ignore_suspend = 1,
581
.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
582
.ops = &mt8183_mt6358_tdm_ops,
583
.ignore = 1,
584
.init = mt8183_mt6358_ts3a227_max98357_hdmi_init,
585
SND_SOC_DAILINK_REG(tdm),
586
},
587
};
588
589
static const
590
struct snd_kcontrol_new mt8183_mt6358_ts3a227_max98357_snd_controls[] = {
591
SOC_DAPM_PIN_SWITCH("Headphone"),
592
SOC_DAPM_PIN_SWITCH("Headset Mic"),
593
};
594
595
static const
596
struct snd_soc_dapm_widget mt8183_mt6358_ts3a227_max98357_dapm_widgets[] = {
597
SND_SOC_DAPM_HP("Headphone", NULL),
598
SND_SOC_DAPM_MIC("Headset Mic", NULL),
599
};
600
601
static struct snd_soc_jack_pin mt8183_mt6358_ts3a227_max98357_jack_pins[] = {
602
{
603
.pin = "Headphone",
604
.mask = SND_JACK_HEADPHONE,
605
},
606
{
607
.pin = "Headset Mic",
608
.mask = SND_JACK_MICROPHONE,
609
},
610
};
611
612
static struct snd_soc_card mt8183_mt6358_ts3a227_max98357_card = {
613
.name = "mt8183_mt6358_ts3a227_max98357",
614
.owner = THIS_MODULE,
615
.dai_link = mt8183_mt6358_ts3a227_dai_links,
616
.num_links = ARRAY_SIZE(mt8183_mt6358_ts3a227_dai_links),
617
.controls = mt8183_mt6358_ts3a227_max98357_snd_controls,
618
.num_controls = ARRAY_SIZE(mt8183_mt6358_ts3a227_max98357_snd_controls),
619
.dapm_widgets = mt8183_mt6358_ts3a227_max98357_dapm_widgets,
620
.num_dapm_widgets = ARRAY_SIZE(mt8183_mt6358_ts3a227_max98357_dapm_widgets),
621
};
622
623
static struct snd_soc_card mt8183_mt6358_ts3a227_max98357b_card = {
624
.name = "mt8183_mt6358_ts3a227_max98357b",
625
.owner = THIS_MODULE,
626
.dai_link = mt8183_mt6358_ts3a227_dai_links,
627
.num_links = ARRAY_SIZE(mt8183_mt6358_ts3a227_dai_links),
628
.controls = mt8183_mt6358_ts3a227_max98357_snd_controls,
629
.num_controls = ARRAY_SIZE(mt8183_mt6358_ts3a227_max98357_snd_controls),
630
.dapm_widgets = mt8183_mt6358_ts3a227_max98357_dapm_widgets,
631
.num_dapm_widgets = ARRAY_SIZE(mt8183_mt6358_ts3a227_max98357_dapm_widgets),
632
};
633
634
static struct snd_soc_codec_conf mt8183_mt6358_ts3a227_rt1015_amp_conf[] = {
635
{
636
.dlc = COMP_CODEC_CONF(RT1015_DEV0_NAME),
637
.name_prefix = "Left",
638
},
639
{
640
.dlc = COMP_CODEC_CONF(RT1015_DEV1_NAME),
641
.name_prefix = "Right",
642
},
643
};
644
645
static struct snd_soc_card mt8183_mt6358_ts3a227_rt1015_card = {
646
.name = "mt8183_mt6358_ts3a227_rt1015",
647
.owner = THIS_MODULE,
648
.dai_link = mt8183_mt6358_ts3a227_dai_links,
649
.num_links = ARRAY_SIZE(mt8183_mt6358_ts3a227_dai_links),
650
.codec_conf = mt8183_mt6358_ts3a227_rt1015_amp_conf,
651
.num_configs = ARRAY_SIZE(mt8183_mt6358_ts3a227_rt1015_amp_conf),
652
.controls = mt8183_mt6358_ts3a227_max98357_snd_controls,
653
.num_controls = ARRAY_SIZE(mt8183_mt6358_ts3a227_max98357_snd_controls),
654
.dapm_widgets = mt8183_mt6358_ts3a227_max98357_dapm_widgets,
655
.num_dapm_widgets = ARRAY_SIZE(mt8183_mt6358_ts3a227_max98357_dapm_widgets),
656
};
657
658
static struct snd_soc_card mt8183_mt6358_ts3a227_rt1015p_card = {
659
.name = "mt8183_mt6358_ts3a227_rt1015p",
660
.owner = THIS_MODULE,
661
.dai_link = mt8183_mt6358_ts3a227_dai_links,
662
.num_links = ARRAY_SIZE(mt8183_mt6358_ts3a227_dai_links),
663
.controls = mt8183_mt6358_ts3a227_max98357_snd_controls,
664
.num_controls = ARRAY_SIZE(mt8183_mt6358_ts3a227_max98357_snd_controls),
665
.dapm_widgets = mt8183_mt6358_ts3a227_max98357_dapm_widgets,
666
.num_dapm_widgets = ARRAY_SIZE(mt8183_mt6358_ts3a227_max98357_dapm_widgets),
667
};
668
669
static int
670
mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *component)
671
{
672
int ret;
673
struct mt8183_mt6358_ts3a227_max98357_priv *priv =
674
snd_soc_card_get_drvdata(component->card);
675
676
/* Enable Headset and 4 Buttons Jack detection */
677
ret = snd_soc_card_jack_new_pins(component->card,
678
"Headset Jack",
679
SND_JACK_HEADSET |
680
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
681
SND_JACK_BTN_2 | SND_JACK_BTN_3,
682
&priv->headset_jack,
683
mt8183_mt6358_ts3a227_max98357_jack_pins,
684
ARRAY_SIZE(mt8183_mt6358_ts3a227_max98357_jack_pins));
685
if (ret)
686
return ret;
687
688
ret = ts3a227e_enable_jack_detect(component, &priv->headset_jack);
689
690
return ret;
691
}
692
693
static struct snd_soc_aux_dev mt8183_mt6358_ts3a227_max98357_headset_dev = {
694
.dlc = COMP_EMPTY(),
695
.init = mt8183_mt6358_ts3a227_max98357_headset_init,
696
};
697
698
static int
699
mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
700
{
701
struct snd_soc_card *card;
702
struct device_node *platform_node, *ec_codec, *hdmi_codec;
703
struct snd_soc_dai_link *dai_link;
704
struct mt8183_mt6358_ts3a227_max98357_priv *priv;
705
int ret, i;
706
707
platform_node = of_parse_phandle(pdev->dev.of_node,
708
"mediatek,platform", 0);
709
if (!platform_node) {
710
dev_err(&pdev->dev, "Property 'platform' missing or invalid\n");
711
return -EINVAL;
712
}
713
714
card = (struct snd_soc_card *)of_device_get_match_data(&pdev->dev);
715
if (!card) {
716
of_node_put(platform_node);
717
return -EINVAL;
718
}
719
card->dev = &pdev->dev;
720
721
ec_codec = of_parse_phandle(pdev->dev.of_node, "mediatek,ec-codec", 0);
722
hdmi_codec = of_parse_phandle(pdev->dev.of_node,
723
"mediatek,hdmi-codec", 0);
724
725
for_each_card_prelinks(card, i, dai_link) {
726
if (ec_codec && strcmp(dai_link->name, "Wake on Voice") == 0) {
727
dai_link->cpus[0].name = NULL;
728
dai_link->cpus[0].of_node = ec_codec;
729
dai_link->cpus[0].dai_name = NULL;
730
dai_link->codecs[0].name = NULL;
731
dai_link->codecs[0].of_node = ec_codec;
732
dai_link->codecs[0].dai_name = "Wake on Voice";
733
dai_link->platforms[0].of_node = ec_codec;
734
dai_link->ignore = 0;
735
}
736
737
if (strcmp(dai_link->name, "I2S3") == 0) {
738
if (card == &mt8183_mt6358_ts3a227_max98357_card ||
739
card == &mt8183_mt6358_ts3a227_max98357b_card) {
740
dai_link->be_hw_params_fixup =
741
mt8183_i2s_hw_params_fixup;
742
dai_link->ops = &mt8183_mt6358_i2s_ops;
743
dai_link->cpus = i2s3_max98357a_cpus;
744
dai_link->num_cpus =
745
ARRAY_SIZE(i2s3_max98357a_cpus);
746
dai_link->codecs = i2s3_max98357a_codecs;
747
dai_link->num_codecs =
748
ARRAY_SIZE(i2s3_max98357a_codecs);
749
dai_link->platforms = i2s3_max98357a_platforms;
750
dai_link->num_platforms =
751
ARRAY_SIZE(i2s3_max98357a_platforms);
752
} else if (card == &mt8183_mt6358_ts3a227_rt1015_card) {
753
dai_link->be_hw_params_fixup =
754
mt8183_rt1015_i2s_hw_params_fixup;
755
dai_link->ops = &mt8183_mt6358_rt1015_i2s_ops;
756
dai_link->cpus = i2s3_rt1015_cpus;
757
dai_link->num_cpus =
758
ARRAY_SIZE(i2s3_rt1015_cpus);
759
dai_link->codecs = i2s3_rt1015_codecs;
760
dai_link->num_codecs =
761
ARRAY_SIZE(i2s3_rt1015_codecs);
762
dai_link->platforms = i2s3_rt1015_platforms;
763
dai_link->num_platforms =
764
ARRAY_SIZE(i2s3_rt1015_platforms);
765
} else if (card == &mt8183_mt6358_ts3a227_rt1015p_card) {
766
dai_link->be_hw_params_fixup =
767
mt8183_rt1015_i2s_hw_params_fixup;
768
dai_link->ops = &mt8183_mt6358_i2s_ops;
769
dai_link->cpus = i2s3_rt1015p_cpus;
770
dai_link->num_cpus =
771
ARRAY_SIZE(i2s3_rt1015p_cpus);
772
dai_link->codecs = i2s3_rt1015p_codecs;
773
dai_link->num_codecs =
774
ARRAY_SIZE(i2s3_rt1015p_codecs);
775
dai_link->platforms = i2s3_rt1015p_platforms;
776
dai_link->num_platforms =
777
ARRAY_SIZE(i2s3_rt1015p_platforms);
778
}
779
}
780
781
if (card == &mt8183_mt6358_ts3a227_max98357b_card) {
782
if (strcmp(dai_link->name, "I2S2") == 0 ||
783
strcmp(dai_link->name, "I2S3") == 0)
784
dai_link->dai_fmt = SND_SOC_DAIFMT_LEFT_J |
785
SND_SOC_DAIFMT_NB_NF |
786
SND_SOC_DAIFMT_CBP_CFP;
787
}
788
789
if (hdmi_codec && strcmp(dai_link->name, "TDM") == 0) {
790
dai_link->codecs->of_node = hdmi_codec;
791
dai_link->ignore = 0;
792
}
793
794
if (!dai_link->platforms->name)
795
dai_link->platforms->of_node = platform_node;
796
}
797
798
mt8183_mt6358_ts3a227_max98357_headset_dev.dlc.of_node =
799
of_parse_phandle(pdev->dev.of_node,
800
"mediatek,headset-codec", 0);
801
if (mt8183_mt6358_ts3a227_max98357_headset_dev.dlc.of_node) {
802
card->aux_dev = &mt8183_mt6358_ts3a227_max98357_headset_dev;
803
card->num_aux_devs = 1;
804
}
805
806
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
807
if (!priv) {
808
ret = -ENOMEM;
809
goto out;
810
}
811
812
snd_soc_card_set_drvdata(card, priv);
813
814
priv->pinctrl = devm_pinctrl_get(&pdev->dev);
815
if (IS_ERR(priv->pinctrl)) {
816
dev_err(&pdev->dev, "%s devm_pinctrl_get failed\n",
817
__func__);
818
ret = PTR_ERR(priv->pinctrl);
819
goto out;
820
}
821
822
for (i = 0; i < PIN_STATE_MAX; i++) {
823
priv->pin_states[i] = pinctrl_lookup_state(priv->pinctrl,
824
mt8183_pin_str[i]);
825
if (IS_ERR(priv->pin_states[i])) {
826
ret = PTR_ERR(priv->pin_states[i]);
827
dev_info(&pdev->dev, "%s Can't find pin state %s %d\n",
828
__func__, mt8183_pin_str[i], ret);
829
}
830
}
831
832
if (!IS_ERR(priv->pin_states[PIN_TDM_OUT_OFF])) {
833
ret = pinctrl_select_state(priv->pinctrl,
834
priv->pin_states[PIN_TDM_OUT_OFF]);
835
if (ret)
836
dev_info(&pdev->dev,
837
"%s failed to select state %d\n",
838
__func__, ret);
839
}
840
841
if (!IS_ERR(priv->pin_states[PIN_STATE_DEFAULT])) {
842
ret = pinctrl_select_state(priv->pinctrl,
843
priv->pin_states[PIN_STATE_DEFAULT]);
844
if (ret)
845
dev_info(&pdev->dev,
846
"%s failed to select state %d\n",
847
__func__, ret);
848
}
849
850
ret = devm_snd_soc_register_card(&pdev->dev, card);
851
852
out:
853
of_node_put(platform_node);
854
of_node_put(ec_codec);
855
of_node_put(hdmi_codec);
856
return ret;
857
}
858
859
#ifdef CONFIG_OF
860
static const struct of_device_id mt8183_mt6358_ts3a227_max98357_dt_match[] = {
861
{
862
.compatible = "mediatek,mt8183_mt6358_ts3a227_max98357",
863
.data = &mt8183_mt6358_ts3a227_max98357_card,
864
},
865
{
866
.compatible = "mediatek,mt8183_mt6358_ts3a227_max98357b",
867
.data = &mt8183_mt6358_ts3a227_max98357b_card,
868
},
869
{
870
.compatible = "mediatek,mt8183_mt6358_ts3a227_rt1015",
871
.data = &mt8183_mt6358_ts3a227_rt1015_card,
872
},
873
{
874
.compatible = "mediatek,mt8183_mt6358_ts3a227_rt1015p",
875
.data = &mt8183_mt6358_ts3a227_rt1015p_card,
876
},
877
{}
878
};
879
MODULE_DEVICE_TABLE(of, mt8183_mt6358_ts3a227_max98357_dt_match);
880
#endif
881
882
static struct platform_driver mt8183_mt6358_ts3a227_max98357_driver = {
883
.driver = {
884
.name = "mt8183_mt6358_ts3a227",
885
#ifdef CONFIG_OF
886
.of_match_table = mt8183_mt6358_ts3a227_max98357_dt_match,
887
#endif
888
.pm = &snd_soc_pm_ops,
889
},
890
.probe = mt8183_mt6358_ts3a227_max98357_dev_probe,
891
};
892
893
module_platform_driver(mt8183_mt6358_ts3a227_max98357_driver);
894
895
/* Module information */
896
MODULE_DESCRIPTION("MT8183-MT6358-TS3A227-MAX98357 ALSA SoC machine driver");
897
MODULE_AUTHOR("Shunli Wang <[email protected]>");
898
MODULE_LICENSE("GPL v2");
899
MODULE_ALIAS("mt8183_mt6358_ts3a227_max98357 soc card");
900
901