Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/amd/acp/acp-mach-common.c
52979 views
1
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2
//
3
// This file is provided under a dual BSD/GPLv2 license. When using or
4
// redistributing this file, you may do so under either license.
5
//
6
// Copyright(c) 2021, 2023 Advanced Micro Devices, Inc.
7
//
8
// Authors: Ajit Kumar Pandey <[email protected]>
9
// Vijendar Mukunda <[email protected]>
10
//
11
12
/*
13
* Machine Driver Interface for ACP HW block
14
*/
15
16
#include <sound/core.h>
17
#include <sound/jack.h>
18
#include <sound/pcm_params.h>
19
#include <sound/soc-dapm.h>
20
#include <sound/soc.h>
21
#include <linux/input.h>
22
#include <linux/module.h>
23
24
#include "../../codecs/rt5682.h"
25
#include "../../codecs/rt1019.h"
26
#include "../../codecs/rt5682s.h"
27
#include "../../codecs/nau8825.h"
28
#include "../../codecs/nau8821.h"
29
#include "acp-mach.h"
30
31
#define PCO_PLAT_CLK 48000000
32
#define RT5682_PLL_FREQ (48000 * 512)
33
#define DUAL_CHANNEL 2
34
#define FOUR_CHANNEL 4
35
#define NAU8821_CODEC_DAI "nau8821-hifi"
36
#define NAU8821_BCLK 1536000
37
#define NAU8821_FREQ_OUT 12288000
38
#define MAX98388_CODEC_DAI "max98388-aif1"
39
40
#define TDM_MODE_ENABLE 1
41
42
const struct dmi_system_id acp_quirk_table[] = {
43
{
44
/* Google skyrim proto-0 */
45
.matches = {
46
DMI_EXACT_MATCH(DMI_PRODUCT_FAMILY, "Google_Skyrim"),
47
},
48
.driver_data = (void *)TDM_MODE_ENABLE,
49
},
50
{}
51
};
52
EXPORT_SYMBOL_GPL(acp_quirk_table);
53
54
static const unsigned int channels[] = {
55
DUAL_CHANNEL,
56
};
57
58
static const unsigned int rates[] = {
59
48000,
60
};
61
62
static const struct snd_pcm_hw_constraint_list constraints_rates = {
63
.count = ARRAY_SIZE(rates),
64
.list = rates,
65
.mask = 0,
66
};
67
68
static const struct snd_pcm_hw_constraint_list constraints_channels = {
69
.count = ARRAY_SIZE(channels),
70
.list = channels,
71
.mask = 0,
72
};
73
74
static int acp_clk_enable(struct acp_card_drvdata *drvdata,
75
unsigned int srate, unsigned int bclk_ratio)
76
{
77
clk_set_rate(drvdata->wclk, srate);
78
clk_set_rate(drvdata->bclk, srate * bclk_ratio);
79
80
return clk_prepare_enable(drvdata->wclk);
81
}
82
83
/* Declare RT5682 codec components */
84
SND_SOC_DAILINK_DEF(rt5682,
85
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5682:00", "rt5682-aif1")));
86
87
static struct snd_soc_jack rt5682_jack;
88
static struct snd_soc_jack_pin rt5682_jack_pins[] = {
89
{
90
.pin = "Headphone Jack",
91
.mask = SND_JACK_HEADPHONE,
92
},
93
{
94
.pin = "Headset Mic",
95
.mask = SND_JACK_MICROPHONE,
96
},
97
};
98
99
static const struct snd_kcontrol_new rt5682_controls[] = {
100
SOC_DAPM_PIN_SWITCH("Headphone Jack"),
101
SOC_DAPM_PIN_SWITCH("Headset Mic"),
102
};
103
104
static const struct snd_soc_dapm_widget rt5682_widgets[] = {
105
SND_SOC_DAPM_HP("Headphone Jack", NULL),
106
SND_SOC_DAPM_MIC("Headset Mic", NULL),
107
};
108
109
static const struct snd_soc_dapm_route rt5682_map[] = {
110
{ "Headphone Jack", NULL, "HPOL" },
111
{ "Headphone Jack", NULL, "HPOR" },
112
{ "IN1P", NULL, "Headset Mic" },
113
};
114
115
/* Define card ops for RT5682 CODEC */
116
static int acp_card_rt5682_init(struct snd_soc_pcm_runtime *rtd)
117
{
118
struct snd_soc_card *card = rtd->card;
119
struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
120
struct acp_card_drvdata *drvdata = card->drvdata;
121
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
122
struct snd_soc_component *component = codec_dai->component;
123
int ret;
124
125
dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
126
127
if (drvdata->hs_codec_id != RT5682)
128
return -EINVAL;
129
130
drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");
131
drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");
132
133
ret = snd_soc_dapm_new_controls(dapm, rt5682_widgets,
134
ARRAY_SIZE(rt5682_widgets));
135
if (ret) {
136
dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
137
return ret;
138
}
139
140
ret = snd_soc_add_card_controls(card, rt5682_controls,
141
ARRAY_SIZE(rt5682_controls));
142
if (ret) {
143
dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
144
return ret;
145
}
146
147
ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
148
SND_JACK_HEADSET | SND_JACK_LINEOUT |
149
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
150
SND_JACK_BTN_2 | SND_JACK_BTN_3,
151
&rt5682_jack,
152
rt5682_jack_pins,
153
ARRAY_SIZE(rt5682_jack_pins));
154
if (ret) {
155
dev_err(card->dev, "HP jack creation failed %d\n", ret);
156
return ret;
157
}
158
159
snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
160
snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
161
snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
162
snd_jack_set_key(rt5682_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
163
164
ret = snd_soc_component_set_jack(component, &rt5682_jack, NULL);
165
if (ret) {
166
dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
167
return ret;
168
}
169
170
return snd_soc_dapm_add_routes(dapm, rt5682_map, ARRAY_SIZE(rt5682_map));
171
}
172
173
static int acp_card_hs_startup(struct snd_pcm_substream *substream)
174
{
175
struct snd_pcm_runtime *runtime = substream->runtime;
176
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
177
struct snd_soc_card *card = rtd->card;
178
struct acp_card_drvdata *drvdata = card->drvdata;
179
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
180
int ret;
181
unsigned int fmt;
182
183
if (drvdata->tdm_mode)
184
fmt = SND_SOC_DAIFMT_DSP_A;
185
else
186
fmt = SND_SOC_DAIFMT_I2S;
187
188
if (drvdata->soc_mclk)
189
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
190
else
191
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
192
193
ret = snd_soc_dai_set_fmt(codec_dai, fmt);
194
if (ret < 0) {
195
dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
196
return ret;
197
}
198
199
runtime->hw.channels_max = DUAL_CHANNEL;
200
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
201
&constraints_channels);
202
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
203
&constraints_rates);
204
205
return ret;
206
}
207
208
static void acp_card_shutdown(struct snd_pcm_substream *substream)
209
{
210
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
211
struct snd_soc_card *card = rtd->card;
212
struct acp_card_drvdata *drvdata = card->drvdata;
213
214
if (!drvdata->soc_mclk)
215
clk_disable_unprepare(drvdata->wclk);
216
}
217
218
static int acp_card_rt5682_hw_params(struct snd_pcm_substream *substream,
219
struct snd_pcm_hw_params *params)
220
{
221
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
222
struct snd_soc_card *card = rtd->card;
223
struct acp_card_drvdata *drvdata = card->drvdata;
224
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
225
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
226
int ret;
227
unsigned int fmt, srate, ch, format;
228
229
srate = params_rate(params);
230
ch = params_channels(params);
231
format = params_physical_width(params);
232
233
if (drvdata->tdm_mode)
234
fmt = SND_SOC_DAIFMT_DSP_A;
235
else
236
fmt = SND_SOC_DAIFMT_I2S;
237
238
if (drvdata->soc_mclk)
239
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
240
else
241
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
242
243
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
244
if (ret && ret != -ENOTSUPP) {
245
dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
246
return ret;
247
}
248
249
ret = snd_soc_dai_set_fmt(codec_dai, fmt);
250
if (ret < 0) {
251
dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
252
return ret;
253
}
254
255
if (drvdata->tdm_mode) {
256
/**
257
* As codec supports slot 0 and slot 1 for playback and capture.
258
*/
259
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 8, 16);
260
if (ret && ret != -ENOTSUPP) {
261
dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
262
return ret;
263
}
264
265
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 0x3, 8, 16);
266
if (ret < 0) {
267
dev_warn(rtd->dev, "set TDM slot err:%d\n", ret);
268
return ret;
269
}
270
}
271
272
ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL2, RT5682_PLL2_S_MCLK,
273
PCO_PLAT_CLK, RT5682_PLL_FREQ);
274
if (ret < 0) {
275
dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
276
return ret;
277
}
278
279
ret = snd_soc_dai_set_sysclk(codec_dai, RT5682_SCLK_S_PLL2,
280
RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
281
if (ret < 0) {
282
dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
283
return ret;
284
}
285
286
if (drvdata->tdm_mode) {
287
ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL1, RT5682S_PLL_S_BCLK1,
288
6144000, 49152000);
289
if (ret < 0) {
290
dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
291
return ret;
292
}
293
294
ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL1,
295
49152000, SND_SOC_CLOCK_IN);
296
if (ret < 0) {
297
dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
298
return ret;
299
}
300
}
301
302
/* Set tdm/i2s1 master bclk ratio */
303
ret = snd_soc_dai_set_bclk_ratio(codec_dai, ch * format);
304
if (ret < 0) {
305
dev_err(rtd->dev, "Failed to set rt5682 tdm bclk ratio: %d\n", ret);
306
return ret;
307
}
308
309
if (!drvdata->soc_mclk) {
310
ret = acp_clk_enable(drvdata, srate, ch * format);
311
if (ret < 0) {
312
dev_err(rtd->card->dev, "Failed to enable HS clk: %d\n", ret);
313
return ret;
314
}
315
}
316
317
return 0;
318
}
319
320
static const struct snd_soc_ops acp_card_rt5682_ops = {
321
.startup = acp_card_hs_startup,
322
.shutdown = acp_card_shutdown,
323
.hw_params = acp_card_rt5682_hw_params,
324
};
325
326
/* Define RT5682S CODEC component*/
327
SND_SOC_DAILINK_DEF(rt5682s,
328
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-RTL5682:00", "rt5682s-aif1")));
329
330
static struct snd_soc_jack rt5682s_jack;
331
static struct snd_soc_jack_pin rt5682s_jack_pins[] = {
332
{
333
.pin = "Headphone Jack",
334
.mask = SND_JACK_HEADPHONE,
335
},
336
{
337
.pin = "Headset Mic",
338
.mask = SND_JACK_MICROPHONE,
339
},
340
};
341
342
static const struct snd_kcontrol_new rt5682s_controls[] = {
343
SOC_DAPM_PIN_SWITCH("Headphone Jack"),
344
SOC_DAPM_PIN_SWITCH("Headset Mic"),
345
};
346
347
static const struct snd_soc_dapm_widget rt5682s_widgets[] = {
348
SND_SOC_DAPM_HP("Headphone Jack", NULL),
349
SND_SOC_DAPM_MIC("Headset Mic", NULL),
350
};
351
352
static const struct snd_soc_dapm_route rt5682s_map[] = {
353
{ "Headphone Jack", NULL, "HPOL" },
354
{ "Headphone Jack", NULL, "HPOR" },
355
{ "IN1P", NULL, "Headset Mic" },
356
};
357
358
static int acp_card_rt5682s_init(struct snd_soc_pcm_runtime *rtd)
359
{
360
struct snd_soc_card *card = rtd->card;
361
struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
362
struct acp_card_drvdata *drvdata = card->drvdata;
363
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
364
struct snd_soc_component *component = codec_dai->component;
365
int ret;
366
367
dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
368
369
if (drvdata->hs_codec_id != RT5682S)
370
return -EINVAL;
371
372
if (!drvdata->soc_mclk) {
373
drvdata->wclk = clk_get(component->dev, "rt5682-dai-wclk");
374
drvdata->bclk = clk_get(component->dev, "rt5682-dai-bclk");
375
}
376
377
ret = snd_soc_dapm_new_controls(dapm, rt5682s_widgets,
378
ARRAY_SIZE(rt5682s_widgets));
379
if (ret) {
380
dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
381
return ret;
382
}
383
384
ret = snd_soc_add_card_controls(card, rt5682s_controls,
385
ARRAY_SIZE(rt5682s_controls));
386
if (ret) {
387
dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
388
return ret;
389
}
390
391
ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
392
SND_JACK_HEADSET | SND_JACK_LINEOUT |
393
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
394
SND_JACK_BTN_2 | SND_JACK_BTN_3,
395
&rt5682s_jack,
396
rt5682s_jack_pins,
397
ARRAY_SIZE(rt5682s_jack_pins));
398
if (ret) {
399
dev_err(card->dev, "HP jack creation failed %d\n", ret);
400
return ret;
401
}
402
403
snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
404
snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
405
snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
406
snd_jack_set_key(rt5682s_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
407
408
ret = snd_soc_component_set_jack(component, &rt5682s_jack, NULL);
409
if (ret) {
410
dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
411
return ret;
412
}
413
414
return snd_soc_dapm_add_routes(dapm, rt5682s_map, ARRAY_SIZE(rt5682s_map));
415
}
416
417
static int acp_card_rt5682s_hw_params(struct snd_pcm_substream *substream,
418
struct snd_pcm_hw_params *params)
419
{
420
struct snd_soc_pcm_runtime *rtd = substream->private_data;
421
struct snd_soc_card *card = rtd->card;
422
struct acp_card_drvdata *drvdata = card->drvdata;
423
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
424
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
425
int ret;
426
unsigned int fmt, srate, ch, format;
427
428
srate = params_rate(params);
429
ch = params_channels(params);
430
format = params_physical_width(params);
431
432
if (drvdata->tdm_mode)
433
fmt = SND_SOC_DAIFMT_DSP_A;
434
else
435
fmt = SND_SOC_DAIFMT_I2S;
436
437
if (drvdata->soc_mclk)
438
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
439
else
440
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
441
442
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
443
if (ret && ret != -ENOTSUPP) {
444
dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
445
return ret;
446
}
447
448
ret = snd_soc_dai_set_fmt(codec_dai, fmt);
449
if (ret < 0) {
450
dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
451
return ret;
452
}
453
454
if (drvdata->tdm_mode) {
455
/**
456
* As codec supports slot 0 and slot 1 for playback and capture.
457
*/
458
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x3, 0x3, 8, 16);
459
if (ret && ret != -ENOTSUPP) {
460
dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
461
return ret;
462
}
463
464
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x3, 0x3, 8, 16);
465
if (ret < 0) {
466
dev_warn(rtd->dev, "set TDM slot err:%d\n", ret);
467
return ret;
468
}
469
}
470
471
ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL2, RT5682S_PLL_S_MCLK,
472
PCO_PLAT_CLK, RT5682_PLL_FREQ);
473
if (ret < 0) {
474
dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
475
return ret;
476
}
477
478
ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL2,
479
RT5682_PLL_FREQ, SND_SOC_CLOCK_IN);
480
if (ret < 0) {
481
dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
482
return ret;
483
}
484
485
if (drvdata->tdm_mode) {
486
ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL1, RT5682S_PLL_S_BCLK1,
487
6144000, 49152000);
488
if (ret < 0) {
489
dev_err(rtd->dev, "Failed to set codec PLL: %d\n", ret);
490
return ret;
491
}
492
493
ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL1,
494
49152000, SND_SOC_CLOCK_IN);
495
if (ret < 0) {
496
dev_err(rtd->dev, "Failed to set codec SYSCLK: %d\n", ret);
497
return ret;
498
}
499
}
500
501
/* Set tdm/i2s1 master bclk ratio */
502
ret = snd_soc_dai_set_bclk_ratio(codec_dai, ch * format);
503
if (ret < 0) {
504
dev_err(rtd->dev, "Failed to set rt5682 tdm bclk ratio: %d\n", ret);
505
return ret;
506
}
507
508
clk_set_rate(drvdata->wclk, srate);
509
clk_set_rate(drvdata->bclk, srate * ch * format);
510
if (!drvdata->soc_mclk) {
511
ret = acp_clk_enable(drvdata, srate, ch * format);
512
if (ret < 0) {
513
dev_err(rtd->card->dev, "Failed to enable HS clk: %d\n", ret);
514
return ret;
515
}
516
}
517
518
return 0;
519
}
520
521
static const struct snd_soc_ops acp_card_rt5682s_ops = {
522
.startup = acp_card_hs_startup,
523
.hw_params = acp_card_rt5682s_hw_params,
524
};
525
526
static const unsigned int dmic_channels[] = {
527
DUAL_CHANNEL, FOUR_CHANNEL,
528
};
529
530
static const struct snd_pcm_hw_constraint_list dmic_constraints_channels = {
531
.count = ARRAY_SIZE(dmic_channels),
532
.list = dmic_channels,
533
.mask = 0,
534
};
535
536
static int acp_card_dmic_startup(struct snd_pcm_substream *substream)
537
{
538
struct snd_pcm_runtime *runtime = substream->runtime;
539
540
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
541
&dmic_constraints_channels);
542
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
543
&constraints_rates);
544
545
return 0;
546
}
547
548
static const struct snd_soc_ops acp_card_dmic_ops = {
549
.startup = acp_card_dmic_startup,
550
};
551
552
/* Declare RT1019 codec components */
553
SND_SOC_DAILINK_DEF(rt1019,
554
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC1019:00", "rt1019-aif"),
555
COMP_CODEC("i2c-10EC1019:01", "rt1019-aif")));
556
557
static const struct snd_kcontrol_new rt1019_controls[] = {
558
SOC_DAPM_PIN_SWITCH("Left Spk"),
559
SOC_DAPM_PIN_SWITCH("Right Spk"),
560
};
561
562
static const struct snd_soc_dapm_widget rt1019_widgets[] = {
563
SND_SOC_DAPM_SPK("Left Spk", NULL),
564
SND_SOC_DAPM_SPK("Right Spk", NULL),
565
};
566
567
static const struct snd_soc_dapm_route rt1019_map_lr[] = {
568
{ "Left Spk", NULL, "Left SPO" },
569
{ "Right Spk", NULL, "Right SPO" },
570
};
571
572
static struct snd_soc_codec_conf rt1019_conf[] = {
573
{
574
.dlc = COMP_CODEC_CONF("i2c-10EC1019:01"),
575
.name_prefix = "Left",
576
},
577
{
578
.dlc = COMP_CODEC_CONF("i2c-10EC1019:00"),
579
.name_prefix = "Right",
580
},
581
};
582
583
static int acp_card_rt1019_init(struct snd_soc_pcm_runtime *rtd)
584
{
585
struct snd_soc_card *card = rtd->card;
586
struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
587
struct acp_card_drvdata *drvdata = card->drvdata;
588
int ret;
589
590
if (drvdata->amp_codec_id != RT1019)
591
return -EINVAL;
592
593
ret = snd_soc_dapm_new_controls(dapm, rt1019_widgets,
594
ARRAY_SIZE(rt1019_widgets));
595
if (ret) {
596
dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
597
return ret;
598
}
599
600
ret = snd_soc_add_card_controls(card, rt1019_controls,
601
ARRAY_SIZE(rt1019_controls));
602
if (ret) {
603
dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
604
return ret;
605
}
606
607
return snd_soc_dapm_add_routes(dapm, rt1019_map_lr,
608
ARRAY_SIZE(rt1019_map_lr));
609
}
610
611
static int acp_card_rt1019_hw_params(struct snd_pcm_substream *substream,
612
struct snd_pcm_hw_params *params)
613
{
614
struct snd_soc_pcm_runtime *rtd = substream->private_data;
615
struct snd_soc_card *card = rtd->card;
616
struct acp_card_drvdata *drvdata = card->drvdata;
617
struct snd_soc_dai *codec_dai;
618
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
619
int i, ret = 0;
620
unsigned int fmt, srate, ch, format;
621
622
srate = params_rate(params);
623
ch = params_channels(params);
624
format = params_physical_width(params);
625
626
if (drvdata->amp_codec_id != RT1019)
627
return -EINVAL;
628
629
if (drvdata->tdm_mode)
630
fmt = SND_SOC_DAIFMT_DSP_A;
631
else
632
fmt = SND_SOC_DAIFMT_I2S;
633
634
if (drvdata->soc_mclk)
635
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
636
else
637
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
638
639
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
640
if (ret && ret != -ENOTSUPP) {
641
dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
642
return ret;
643
}
644
645
if (drvdata->tdm_mode) {
646
/**
647
* As codec supports slot 2 and slot 3 for playback.
648
*/
649
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xC, 0, 8, 16);
650
if (ret && ret != -ENOTSUPP) {
651
dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
652
return ret;
653
}
654
}
655
656
for_each_rtd_codec_dais(rtd, i, codec_dai) {
657
if (strcmp(codec_dai->name, "rt1019-aif"))
658
continue;
659
660
if (drvdata->tdm_mode)
661
ret = snd_soc_dai_set_pll(codec_dai, 0, RT1019_PLL_S_BCLK,
662
TDM_CHANNELS * format * srate, 256 * srate);
663
else
664
ret = snd_soc_dai_set_pll(codec_dai, 0, RT1019_PLL_S_BCLK,
665
ch * format * srate, 256 * srate);
666
667
if (ret < 0)
668
return ret;
669
670
ret = snd_soc_dai_set_sysclk(codec_dai, RT1019_SCLK_S_PLL,
671
256 * srate, SND_SOC_CLOCK_IN);
672
if (ret < 0)
673
return ret;
674
675
if (drvdata->tdm_mode) {
676
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A
677
| SND_SOC_DAIFMT_NB_NF);
678
if (ret < 0) {
679
dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
680
return ret;
681
}
682
683
/**
684
* As codec supports slot 2 for left channel playback.
685
*/
686
if (!strcmp(codec_dai->component->name, "i2c-10EC1019:00")) {
687
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x4, 0x4, 8, 16);
688
if (ret < 0)
689
break;
690
}
691
692
/**
693
* As codec supports slot 3 for right channel playback.
694
*/
695
if (!strcmp(codec_dai->component->name, "i2c-10EC1019:01")) {
696
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x8, 0x8, 8, 16);
697
if (ret < 0)
698
break;
699
}
700
}
701
}
702
703
if (!drvdata->soc_mclk) {
704
ret = acp_clk_enable(drvdata, srate, ch * format);
705
if (ret < 0) {
706
dev_err(rtd->card->dev, "Failed to enable AMP clk: %d\n", ret);
707
return ret;
708
}
709
}
710
711
return 0;
712
}
713
714
static int acp_card_amp_startup(struct snd_pcm_substream *substream)
715
{
716
struct snd_pcm_runtime *runtime = substream->runtime;
717
718
runtime->hw.channels_max = DUAL_CHANNEL;
719
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
720
&constraints_channels);
721
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
722
&constraints_rates);
723
724
return 0;
725
}
726
727
static const struct snd_soc_ops acp_card_rt1019_ops = {
728
.startup = acp_card_amp_startup,
729
.shutdown = acp_card_shutdown,
730
.hw_params = acp_card_rt1019_hw_params,
731
};
732
733
/* Declare Maxim codec components */
734
SND_SOC_DAILINK_DEF(max98360a,
735
DAILINK_COMP_ARRAY(COMP_CODEC("MX98360A:00", "HiFi")));
736
737
static const struct snd_kcontrol_new max98360a_controls[] = {
738
SOC_DAPM_PIN_SWITCH("Spk"),
739
};
740
741
static const struct snd_soc_dapm_widget max98360a_widgets[] = {
742
SND_SOC_DAPM_SPK("Spk", NULL),
743
};
744
745
static const struct snd_soc_dapm_route max98360a_map[] = {
746
{"Spk", NULL, "Speaker"},
747
};
748
749
static int acp_card_maxim_init(struct snd_soc_pcm_runtime *rtd)
750
{
751
struct snd_soc_card *card = rtd->card;
752
struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
753
struct acp_card_drvdata *drvdata = card->drvdata;
754
int ret;
755
756
if (drvdata->amp_codec_id != MAX98360A)
757
return -EINVAL;
758
759
ret = snd_soc_dapm_new_controls(dapm, max98360a_widgets,
760
ARRAY_SIZE(max98360a_widgets));
761
if (ret) {
762
dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
763
return ret;
764
}
765
766
ret = snd_soc_add_card_controls(card, max98360a_controls,
767
ARRAY_SIZE(max98360a_controls));
768
if (ret) {
769
dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
770
return ret;
771
}
772
773
return snd_soc_dapm_add_routes(dapm, max98360a_map,
774
ARRAY_SIZE(max98360a_map));
775
}
776
777
static int acp_card_maxim_hw_params(struct snd_pcm_substream *substream,
778
struct snd_pcm_hw_params *params)
779
{
780
struct snd_soc_pcm_runtime *rtd = substream->private_data;
781
struct snd_soc_card *card = rtd->card;
782
struct acp_card_drvdata *drvdata = card->drvdata;
783
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
784
unsigned int fmt, srate, ch, format;
785
int ret;
786
787
srate = params_rate(params);
788
ch = params_channels(params);
789
format = params_physical_width(params);
790
791
if (drvdata->tdm_mode)
792
fmt = SND_SOC_DAIFMT_DSP_A;
793
else
794
fmt = SND_SOC_DAIFMT_I2S;
795
796
if (drvdata->soc_mclk)
797
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
798
else
799
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
800
801
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
802
if (ret && ret != -ENOTSUPP) {
803
dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
804
return ret;
805
}
806
807
if (drvdata->tdm_mode) {
808
/**
809
* As codec supports slot 2 and slot 3 for playback.
810
*/
811
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0xC, 0, 8, 16);
812
if (ret && ret != -ENOTSUPP) {
813
dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
814
return ret;
815
}
816
}
817
818
if (!drvdata->soc_mclk) {
819
ret = acp_clk_enable(drvdata, srate, ch * format);
820
if (ret < 0) {
821
dev_err(rtd->card->dev, "Failed to enable AMP clk: %d\n", ret);
822
return ret;
823
}
824
}
825
return 0;
826
}
827
828
static const struct snd_soc_ops acp_card_maxim_ops = {
829
.startup = acp_card_amp_startup,
830
.shutdown = acp_card_shutdown,
831
.hw_params = acp_card_maxim_hw_params,
832
};
833
834
SND_SOC_DAILINK_DEF(max98388,
835
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-ADS8388:00", MAX98388_CODEC_DAI),
836
COMP_CODEC("i2c-ADS8388:01", MAX98388_CODEC_DAI)));
837
838
static const struct snd_kcontrol_new max98388_controls[] = {
839
SOC_DAPM_PIN_SWITCH("Left Spk"),
840
SOC_DAPM_PIN_SWITCH("Right Spk"),
841
};
842
843
static const struct snd_soc_dapm_widget max98388_widgets[] = {
844
SND_SOC_DAPM_SPK("Left Spk", NULL),
845
SND_SOC_DAPM_SPK("Right Spk", NULL),
846
};
847
848
static const struct snd_soc_dapm_route max98388_map[] = {
849
{ "Left Spk", NULL, "Left BE_OUT" },
850
{ "Right Spk", NULL, "Right BE_OUT" },
851
};
852
853
static struct snd_soc_codec_conf max98388_conf[] = {
854
{
855
.dlc = COMP_CODEC_CONF("i2c-ADS8388:00"),
856
.name_prefix = "Left",
857
},
858
{
859
.dlc = COMP_CODEC_CONF("i2c-ADS8388:01"),
860
.name_prefix = "Right",
861
},
862
};
863
864
static const unsigned int max98388_format[] = {16};
865
866
static struct snd_pcm_hw_constraint_list constraints_sample_bits_max = {
867
.list = max98388_format,
868
.count = ARRAY_SIZE(max98388_format),
869
};
870
871
static int acp_card_max98388_startup(struct snd_pcm_substream *substream)
872
{
873
struct snd_pcm_runtime *runtime = substream->runtime;
874
875
runtime->hw.channels_max = DUAL_CHANNEL;
876
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
877
&constraints_channels);
878
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
879
&constraints_rates);
880
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
881
&constraints_sample_bits_max);
882
883
return 0;
884
}
885
886
static int acp_card_max98388_init(struct snd_soc_pcm_runtime *rtd)
887
{
888
struct snd_soc_card *card = rtd->card;
889
struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
890
struct acp_card_drvdata *drvdata = card->drvdata;
891
int ret;
892
893
if (drvdata->amp_codec_id != MAX98388)
894
return -EINVAL;
895
896
ret = snd_soc_dapm_new_controls(dapm, max98388_widgets,
897
ARRAY_SIZE(max98388_widgets));
898
899
if (ret) {
900
dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
901
/* Don't need to add routes if widget addition failed */
902
return ret;
903
}
904
905
ret = snd_soc_add_card_controls(card, max98388_controls,
906
ARRAY_SIZE(max98388_controls));
907
if (ret) {
908
dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
909
return ret;
910
}
911
912
return snd_soc_dapm_add_routes(dapm, max98388_map,
913
ARRAY_SIZE(max98388_map));
914
}
915
916
static int acp_max98388_hw_params(struct snd_pcm_substream *substream,
917
struct snd_pcm_hw_params *params)
918
{
919
struct snd_soc_pcm_runtime *rtd = substream->private_data;
920
struct snd_soc_card *card = rtd->card;
921
struct snd_soc_dai *codec_dai =
922
snd_soc_card_get_codec_dai(card,
923
MAX98388_CODEC_DAI);
924
int ret;
925
926
ret = snd_soc_dai_set_fmt(codec_dai,
927
SND_SOC_DAIFMT_CBC_CFC | SND_SOC_DAIFMT_I2S |
928
SND_SOC_DAIFMT_NB_NF);
929
if (ret < 0)
930
return ret;
931
932
return ret;
933
}
934
935
static const struct snd_soc_ops acp_max98388_ops = {
936
.startup = acp_card_max98388_startup,
937
.hw_params = acp_max98388_hw_params,
938
};
939
940
/* Declare nau8825 codec components */
941
SND_SOC_DAILINK_DEF(nau8825,
942
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10508825:00", "nau8825-hifi")));
943
944
static struct snd_soc_jack nau8825_jack;
945
static struct snd_soc_jack_pin nau8825_jack_pins[] = {
946
{
947
.pin = "Headphone Jack",
948
.mask = SND_JACK_HEADPHONE,
949
},
950
{
951
.pin = "Headset Mic",
952
.mask = SND_JACK_MICROPHONE,
953
},
954
};
955
956
static const struct snd_kcontrol_new nau8825_controls[] = {
957
SOC_DAPM_PIN_SWITCH("Headphone Jack"),
958
SOC_DAPM_PIN_SWITCH("Headset Mic"),
959
};
960
961
static const struct snd_soc_dapm_widget nau8825_widgets[] = {
962
SND_SOC_DAPM_HP("Headphone Jack", NULL),
963
SND_SOC_DAPM_MIC("Headset Mic", NULL),
964
};
965
966
static const struct snd_soc_dapm_route nau8825_map[] = {
967
{ "Headphone Jack", NULL, "HPOL" },
968
{ "Headphone Jack", NULL, "HPOR" },
969
};
970
971
static int acp_card_nau8825_init(struct snd_soc_pcm_runtime *rtd)
972
{
973
struct snd_soc_card *card = rtd->card;
974
struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
975
struct acp_card_drvdata *drvdata = card->drvdata;
976
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
977
struct snd_soc_component *component = codec_dai->component;
978
int ret;
979
980
dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
981
982
if (drvdata->hs_codec_id != NAU8825)
983
return -EINVAL;
984
985
ret = snd_soc_dapm_new_controls(dapm, nau8825_widgets,
986
ARRAY_SIZE(nau8825_widgets));
987
if (ret) {
988
dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
989
return ret;
990
}
991
992
ret = snd_soc_add_card_controls(card, nau8825_controls,
993
ARRAY_SIZE(nau8825_controls));
994
if (ret) {
995
dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
996
return ret;
997
}
998
999
ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
1000
SND_JACK_HEADSET | SND_JACK_LINEOUT |
1001
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
1002
SND_JACK_BTN_2 | SND_JACK_BTN_3,
1003
&nau8825_jack,
1004
nau8825_jack_pins,
1005
ARRAY_SIZE(nau8825_jack_pins));
1006
if (ret) {
1007
dev_err(card->dev, "HP jack creation failed %d\n", ret);
1008
return ret;
1009
}
1010
1011
snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
1012
snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
1013
snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
1014
snd_jack_set_key(nau8825_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
1015
1016
ret = snd_soc_component_set_jack(component, &nau8825_jack, NULL);
1017
if (ret) {
1018
dev_err(rtd->dev, "Headset Jack call-back failed: %d\n", ret);
1019
return ret;
1020
}
1021
1022
return snd_soc_dapm_add_routes(dapm, nau8825_map, ARRAY_SIZE(nau8825_map));
1023
}
1024
1025
static int acp_nau8825_hw_params(struct snd_pcm_substream *substream,
1026
struct snd_pcm_hw_params *params)
1027
{
1028
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1029
struct snd_soc_card *card = rtd->card;
1030
struct acp_card_drvdata *drvdata = card->drvdata;
1031
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
1032
struct snd_soc_dai *cpu_dai = snd_soc_rtd_to_cpu(rtd, 0);
1033
int ret;
1034
unsigned int fmt;
1035
1036
ret = snd_soc_dai_set_sysclk(codec_dai, NAU8825_CLK_FLL_FS,
1037
(48000 * 256), SND_SOC_CLOCK_IN);
1038
if (ret < 0)
1039
dev_err(rtd->dev, "snd_soc_dai_set_sysclk err = %d\n", ret);
1040
1041
ret = snd_soc_dai_set_pll(codec_dai, 0, 0, params_rate(params),
1042
params_rate(params) * 256);
1043
if (ret < 0) {
1044
dev_err(rtd->dev, "can't set FLL: %d\n", ret);
1045
return ret;
1046
}
1047
1048
if (drvdata->tdm_mode)
1049
fmt = SND_SOC_DAIFMT_DSP_A;
1050
else
1051
fmt = SND_SOC_DAIFMT_I2S;
1052
1053
if (drvdata->soc_mclk)
1054
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
1055
else
1056
fmt |= SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
1057
1058
ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
1059
if (ret && ret != -ENOTSUPP) {
1060
dev_err(rtd->dev, "Failed to set dai fmt: %d\n", ret);
1061
return ret;
1062
}
1063
1064
ret = snd_soc_dai_set_fmt(codec_dai, fmt);
1065
if (ret < 0) {
1066
dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
1067
return ret;
1068
}
1069
1070
if (drvdata->tdm_mode) {
1071
/**
1072
* As codec supports slot 4 and slot 5 for playback and slot 6 for capture.
1073
*/
1074
ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0x30, 0xC0, 8, 16);
1075
if (ret && ret != -ENOTSUPP) {
1076
dev_err(rtd->dev, "set TDM slot err: %d\n", ret);
1077
return ret;
1078
}
1079
1080
ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x40, 0x30, 8, 16);
1081
if (ret < 0) {
1082
dev_warn(rtd->dev, "set TDM slot err:%d\n", ret);
1083
return ret;
1084
}
1085
}
1086
return ret;
1087
}
1088
1089
static int acp_nau8825_startup(struct snd_pcm_substream *substream)
1090
{
1091
struct snd_pcm_runtime *runtime = substream->runtime;
1092
1093
runtime->hw.channels_max = 2;
1094
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
1095
&constraints_channels);
1096
1097
runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
1098
snd_pcm_hw_constraint_list(runtime, 0,
1099
SNDRV_PCM_HW_PARAM_RATE, &constraints_rates);
1100
return 0;
1101
}
1102
1103
static const struct snd_soc_ops acp_card_nau8825_ops = {
1104
.startup = acp_nau8825_startup,
1105
.hw_params = acp_nau8825_hw_params,
1106
};
1107
1108
static int platform_clock_control(struct snd_soc_dapm_widget *w,
1109
struct snd_kcontrol *k, int event)
1110
{
1111
struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm);
1112
struct snd_soc_dai *codec_dai;
1113
int ret = 0;
1114
1115
codec_dai = snd_soc_card_get_codec_dai(card, NAU8821_CODEC_DAI);
1116
if (!codec_dai) {
1117
dev_err(card->dev, "Codec dai not found\n");
1118
return -EIO;
1119
}
1120
1121
if (SND_SOC_DAPM_EVENT_OFF(event)) {
1122
ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_INTERNAL,
1123
0, SND_SOC_CLOCK_IN);
1124
if (ret < 0) {
1125
dev_err(card->dev, "set sysclk err = %d\n", ret);
1126
return -EIO;
1127
}
1128
} else {
1129
ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_FLL_BLK, 0,
1130
SND_SOC_CLOCK_IN);
1131
if (ret < 0)
1132
dev_err(codec_dai->dev, "can't set FS clock %d\n", ret);
1133
ret = snd_soc_dai_set_pll(codec_dai, 0, 0, NAU8821_BCLK,
1134
NAU8821_FREQ_OUT);
1135
if (ret < 0)
1136
dev_err(codec_dai->dev, "can't set FLL: %d\n", ret);
1137
}
1138
return ret;
1139
}
1140
1141
static struct snd_soc_jack nau8821_jack;
1142
static struct snd_soc_jack_pin nau8821_jack_pins[] = {
1143
{
1144
.pin = "Headphone Jack",
1145
.mask = SND_JACK_HEADPHONE,
1146
},
1147
{
1148
.pin = "Headset Mic",
1149
.mask = SND_JACK_MICROPHONE,
1150
},
1151
};
1152
1153
static const struct snd_kcontrol_new nau8821_controls[] = {
1154
SOC_DAPM_PIN_SWITCH("Headphone Jack"),
1155
SOC_DAPM_PIN_SWITCH("Headset Mic"),
1156
};
1157
1158
static const struct snd_soc_dapm_widget nau8821_widgets[] = {
1159
SND_SOC_DAPM_HP("Headphone Jack", NULL),
1160
SND_SOC_DAPM_MIC("Headset Mic", NULL),
1161
SND_SOC_DAPM_MIC("Int Mic", NULL),
1162
SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
1163
platform_clock_control, SND_SOC_DAPM_PRE_PMU |
1164
SND_SOC_DAPM_POST_PMD),
1165
};
1166
1167
static const struct snd_soc_dapm_route nau8821_audio_route[] = {
1168
/* HP jack connectors - unknown if we have jack detection */
1169
{ "Headphone Jack", NULL, "HPOL" },
1170
{ "Headphone Jack", NULL, "HPOR" },
1171
{ "MICL", NULL, "Headset Mic" },
1172
{ "MICR", NULL, "Headset Mic" },
1173
{ "DMIC", NULL, "Int Mic" },
1174
{ "Headphone Jack", NULL, "Platform Clock" },
1175
{ "Headset Mic", NULL, "Platform Clock" },
1176
{ "Int Mic", NULL, "Platform Clock" },
1177
};
1178
1179
static const unsigned int nau8821_format[] = {16};
1180
1181
static struct snd_pcm_hw_constraint_list constraints_sample_bits = {
1182
.list = nau8821_format,
1183
.count = ARRAY_SIZE(nau8821_format),
1184
};
1185
1186
static int acp_8821_init(struct snd_soc_pcm_runtime *rtd)
1187
{
1188
struct snd_soc_card *card = rtd->card;
1189
struct snd_soc_dapm_context *dapm = snd_soc_card_to_dapm(card);
1190
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
1191
struct snd_soc_component *component = codec_dai->component;
1192
int ret;
1193
1194
dev_info(rtd->dev, "codec dai name = %s\n", codec_dai->name);
1195
1196
ret = snd_soc_dapm_new_controls(dapm, nau8821_widgets,
1197
ARRAY_SIZE(nau8821_widgets));
1198
if (ret) {
1199
dev_err(rtd->dev, "unable to add widget dapm controls, ret %d\n", ret);
1200
// Don't need to add routes if widget addition failed
1201
return ret;
1202
}
1203
1204
ret = snd_soc_add_card_controls(card, nau8821_controls,
1205
ARRAY_SIZE(nau8821_controls));
1206
if (ret) {
1207
dev_err(rtd->dev, "unable to add card controls, ret %d\n", ret);
1208
return ret;
1209
}
1210
1211
ret = snd_soc_card_jack_new_pins(card, "Headset Jack",
1212
SND_JACK_HEADSET | SND_JACK_LINEOUT |
1213
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
1214
SND_JACK_BTN_2 | SND_JACK_BTN_3,
1215
&nau8821_jack,
1216
nau8821_jack_pins,
1217
ARRAY_SIZE(nau8821_jack_pins));
1218
if (ret) {
1219
dev_err(rtd->dev, "Headset Jack creation failed %d\n", ret);
1220
return ret;
1221
}
1222
1223
snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_0, KEY_PLAYPAUSE);
1224
snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_1, KEY_VOICECOMMAND);
1225
snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_2, KEY_VOLUMEUP);
1226
snd_jack_set_key(nau8821_jack.jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN);
1227
1228
nau8821_enable_jack_detect(component, &nau8821_jack);
1229
1230
return snd_soc_dapm_add_routes(dapm, nau8821_audio_route,
1231
ARRAY_SIZE(nau8821_audio_route));
1232
}
1233
1234
static int acp_8821_startup(struct snd_pcm_substream *substream)
1235
{
1236
struct snd_pcm_runtime *runtime = substream->runtime;
1237
1238
runtime->hw.channels_max = DUAL_CHANNEL;
1239
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
1240
&constraints_channels);
1241
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
1242
&constraints_rates);
1243
snd_pcm_hw_constraint_list(substream->runtime, 0,
1244
SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
1245
&constraints_sample_bits);
1246
return 0;
1247
}
1248
1249
static int acp_nau8821_hw_params(struct snd_pcm_substream *substream,
1250
struct snd_pcm_hw_params *params)
1251
{
1252
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
1253
struct snd_soc_card *card = rtd->card;
1254
struct acp_card_drvdata *drvdata = card->drvdata;
1255
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
1256
int ret;
1257
unsigned int fmt;
1258
1259
if (drvdata->soc_mclk)
1260
fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC;
1261
else
1262
fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBP_CFP;
1263
1264
ret = snd_soc_dai_set_fmt(codec_dai, fmt);
1265
if (ret < 0) {
1266
dev_err(rtd->card->dev, "Failed to set dai fmt: %d\n", ret);
1267
return ret;
1268
}
1269
1270
ret = snd_soc_dai_set_sysclk(codec_dai, NAU8821_CLK_FLL_BLK, 0,
1271
SND_SOC_CLOCK_IN);
1272
if (ret < 0)
1273
dev_err(card->dev, "can't set FS clock %d\n", ret);
1274
ret = snd_soc_dai_set_pll(codec_dai, 0, 0, snd_soc_params_to_bclk(params),
1275
params_rate(params) * 256);
1276
if (ret < 0)
1277
dev_err(card->dev, "can't set FLL: %d\n", ret);
1278
1279
return ret;
1280
}
1281
1282
static const struct snd_soc_ops acp_8821_ops = {
1283
.startup = acp_8821_startup,
1284
.hw_params = acp_nau8821_hw_params,
1285
};
1286
1287
SND_SOC_DAILINK_DEF(nau8821,
1288
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-NVTN2020:00",
1289
NAU8821_CODEC_DAI)));
1290
1291
/* Declare DMIC codec components */
1292
SND_SOC_DAILINK_DEF(dmic_codec,
1293
DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec", "dmic-hifi")));
1294
1295
/* Declare ACP CPU components */
1296
static struct snd_soc_dai_link_component platform_component[] = {
1297
{
1298
.name = "acp_asoc_renoir.0",
1299
}
1300
};
1301
1302
static struct snd_soc_dai_link_component platform_rmb_component[] = {
1303
{
1304
.name = "acp_asoc_rembrandt.0",
1305
}
1306
};
1307
1308
static struct snd_soc_dai_link_component platform_acp63_component[] = {
1309
{
1310
.name = "acp_asoc_acp63.0",
1311
}
1312
};
1313
1314
static struct snd_soc_dai_link_component platform_acp70_component[] = {
1315
{
1316
.name = "acp_asoc_acp70.0",
1317
}
1318
};
1319
1320
static struct snd_soc_dai_link_component sof_component[] = {
1321
{
1322
.name = "0000:04:00.5",
1323
}
1324
};
1325
1326
SND_SOC_DAILINK_DEF(i2s_sp,
1327
DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-sp")));
1328
SND_SOC_DAILINK_DEF(i2s_hs,
1329
DAILINK_COMP_ARRAY(COMP_CPU("acp-i2s-hs")));
1330
SND_SOC_DAILINK_DEF(sof_sp,
1331
DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp")));
1332
SND_SOC_DAILINK_DEF(sof_sp_virtual,
1333
DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-sp-virtual")));
1334
SND_SOC_DAILINK_DEF(sof_hs,
1335
DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs")));
1336
SND_SOC_DAILINK_DEF(sof_hs_virtual,
1337
DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-hs-virtual")));
1338
SND_SOC_DAILINK_DEF(sof_bt,
1339
DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-bt")));
1340
SND_SOC_DAILINK_DEF(sof_dmic,
1341
DAILINK_COMP_ARRAY(COMP_CPU("acp-sof-dmic")));
1342
SND_SOC_DAILINK_DEF(pdm_dmic,
1343
DAILINK_COMP_ARRAY(COMP_CPU("acp-pdm-dmic")));
1344
1345
static int acp_rtk_set_bias_level(struct snd_soc_card *card,
1346
struct snd_soc_dapm_context *dapm,
1347
enum snd_soc_bias_level level)
1348
{
1349
struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
1350
struct acp_card_drvdata *drvdata = card->drvdata;
1351
int ret = 0;
1352
1353
if (!component)
1354
return 0;
1355
1356
if (strncmp(component->name, "i2c-RTL5682", 11) &&
1357
strncmp(component->name, "i2c-10EC1019", 12))
1358
return 0;
1359
1360
/*
1361
* For Realtek's codec and amplifier components,
1362
* the lrck and bclk must be enabled brfore their all dapms be powered on,
1363
* and must be disabled after their all dapms be powered down
1364
* to avoid any pop.
1365
*/
1366
switch (level) {
1367
case SND_SOC_BIAS_STANDBY:
1368
if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) {
1369
1370
/* Increase bclk's enable_count */
1371
ret = clk_prepare_enable(drvdata->bclk);
1372
if (ret < 0)
1373
dev_err(component->dev, "Failed to enable bclk %d\n", ret);
1374
} else {
1375
/*
1376
* Decrease bclk's enable_count.
1377
* While the enable_count is 0, the bclk would be closed.
1378
*/
1379
clk_disable_unprepare(drvdata->bclk);
1380
}
1381
break;
1382
default:
1383
break;
1384
}
1385
1386
return ret;
1387
}
1388
1389
int acp_sofdsp_dai_links_create(struct snd_soc_card *card)
1390
{
1391
struct snd_soc_dai_link *links;
1392
struct device *dev = card->dev;
1393
struct acp_card_drvdata *drv_data = card->drvdata;
1394
int i = 0, num_links = 0;
1395
1396
if (drv_data->hs_cpu_id)
1397
num_links++;
1398
if (drv_data->bt_cpu_id)
1399
num_links++;
1400
if (drv_data->amp_cpu_id)
1401
num_links++;
1402
if (drv_data->dmic_cpu_id)
1403
num_links++;
1404
1405
links = devm_kcalloc(dev, num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL);
1406
if (!links)
1407
return -ENOMEM;
1408
1409
if (drv_data->hs_cpu_id == I2S_SP) {
1410
links[i].name = "acp-headset-codec";
1411
links[i].id = HEADSET_BE_ID;
1412
links[i].cpus = sof_sp;
1413
links[i].num_cpus = ARRAY_SIZE(sof_sp);
1414
links[i].platforms = sof_component;
1415
links[i].num_platforms = ARRAY_SIZE(sof_component);
1416
links[i].nonatomic = true;
1417
links[i].no_pcm = 1;
1418
if (!drv_data->hs_codec_id) {
1419
/* Use dummy codec if codec id not specified */
1420
links[i].codecs = &snd_soc_dummy_dlc;
1421
links[i].num_codecs = 1;
1422
}
1423
if (drv_data->hs_codec_id == RT5682) {
1424
links[i].codecs = rt5682;
1425
links[i].num_codecs = ARRAY_SIZE(rt5682);
1426
links[i].init = acp_card_rt5682_init;
1427
links[i].ops = &acp_card_rt5682_ops;
1428
}
1429
if (drv_data->hs_codec_id == RT5682S) {
1430
links[i].codecs = rt5682s;
1431
links[i].num_codecs = ARRAY_SIZE(rt5682s);
1432
links[i].init = acp_card_rt5682s_init;
1433
links[i].ops = &acp_card_rt5682s_ops;
1434
}
1435
if (drv_data->hs_codec_id == NAU8821) {
1436
links[i].codecs = nau8821;
1437
links[i].num_codecs = ARRAY_SIZE(nau8821);
1438
links[i].init = acp_8821_init;
1439
links[i].ops = &acp_8821_ops;
1440
}
1441
i++;
1442
}
1443
1444
if (drv_data->hs_cpu_id == I2S_HS) {
1445
links[i].name = "acp-headset-codec";
1446
links[i].id = HEADSET_BE_ID;
1447
links[i].cpus = sof_hs;
1448
links[i].num_cpus = ARRAY_SIZE(sof_hs);
1449
links[i].platforms = sof_component;
1450
links[i].num_platforms = ARRAY_SIZE(sof_component);
1451
links[i].nonatomic = true;
1452
links[i].no_pcm = 1;
1453
if (!drv_data->hs_codec_id) {
1454
/* Use dummy codec if codec id not specified */
1455
links[i].codecs = &snd_soc_dummy_dlc;
1456
links[i].num_codecs = 1;
1457
}
1458
if (drv_data->hs_codec_id == NAU8825) {
1459
links[i].codecs = nau8825;
1460
links[i].num_codecs = ARRAY_SIZE(nau8825);
1461
links[i].init = acp_card_nau8825_init;
1462
links[i].ops = &acp_card_nau8825_ops;
1463
}
1464
if (drv_data->hs_codec_id == RT5682S) {
1465
links[i].codecs = rt5682s;
1466
links[i].num_codecs = ARRAY_SIZE(rt5682s);
1467
links[i].init = acp_card_rt5682s_init;
1468
links[i].ops = &acp_card_rt5682s_ops;
1469
}
1470
i++;
1471
}
1472
1473
if (drv_data->amp_cpu_id == I2S_SP) {
1474
links[i].name = "acp-amp-codec";
1475
links[i].id = AMP_BE_ID;
1476
if (drv_data->acp_rev == ACP_RN_PCI_ID) {
1477
links[i].cpus = sof_sp;
1478
links[i].num_cpus = ARRAY_SIZE(sof_sp);
1479
} else {
1480
links[i].cpus = sof_sp_virtual;
1481
links[i].num_cpus = ARRAY_SIZE(sof_sp_virtual);
1482
}
1483
links[i].platforms = sof_component;
1484
links[i].num_platforms = ARRAY_SIZE(sof_component);
1485
links[i].playback_only = 1;
1486
links[i].nonatomic = true;
1487
links[i].no_pcm = 1;
1488
if (!drv_data->amp_codec_id) {
1489
/* Use dummy codec if codec id not specified */
1490
links[i].codecs = &snd_soc_dummy_dlc;
1491
links[i].num_codecs = 1;
1492
}
1493
if (drv_data->amp_codec_id == RT1019) {
1494
links[i].codecs = rt1019;
1495
links[i].num_codecs = ARRAY_SIZE(rt1019);
1496
links[i].ops = &acp_card_rt1019_ops;
1497
links[i].init = acp_card_rt1019_init;
1498
card->codec_conf = rt1019_conf;
1499
card->num_configs = ARRAY_SIZE(rt1019_conf);
1500
}
1501
if (drv_data->amp_codec_id == MAX98360A) {
1502
links[i].codecs = max98360a;
1503
links[i].num_codecs = ARRAY_SIZE(max98360a);
1504
links[i].ops = &acp_card_maxim_ops;
1505
links[i].init = acp_card_maxim_init;
1506
}
1507
i++;
1508
}
1509
1510
if (drv_data->amp_cpu_id == I2S_HS) {
1511
links[i].name = "acp-amp-codec";
1512
links[i].id = AMP_BE_ID;
1513
links[i].cpus = sof_hs_virtual;
1514
links[i].num_cpus = ARRAY_SIZE(sof_hs_virtual);
1515
links[i].platforms = sof_component;
1516
links[i].num_platforms = ARRAY_SIZE(sof_component);
1517
links[i].playback_only = 1;
1518
links[i].nonatomic = true;
1519
links[i].no_pcm = 1;
1520
if (!drv_data->amp_codec_id) {
1521
/* Use dummy codec if codec id not specified */
1522
links[i].codecs = &snd_soc_dummy_dlc;
1523
links[i].num_codecs = 1;
1524
}
1525
if (drv_data->amp_codec_id == MAX98360A) {
1526
links[i].codecs = max98360a;
1527
links[i].num_codecs = ARRAY_SIZE(max98360a);
1528
links[i].ops = &acp_card_maxim_ops;
1529
links[i].init = acp_card_maxim_init;
1530
}
1531
if (drv_data->amp_codec_id == MAX98388) {
1532
links[i].playback_only = 0;
1533
links[i].codecs = max98388;
1534
links[i].num_codecs = ARRAY_SIZE(max98388);
1535
links[i].ops = &acp_max98388_ops;
1536
links[i].init = acp_card_max98388_init;
1537
card->codec_conf = max98388_conf;
1538
card->num_configs = ARRAY_SIZE(max98388_conf);
1539
}
1540
if (drv_data->amp_codec_id == RT1019) {
1541
links[i].codecs = rt1019;
1542
links[i].num_codecs = ARRAY_SIZE(rt1019);
1543
links[i].ops = &acp_card_rt1019_ops;
1544
links[i].init = acp_card_rt1019_init;
1545
card->codec_conf = rt1019_conf;
1546
card->num_configs = ARRAY_SIZE(rt1019_conf);
1547
}
1548
i++;
1549
}
1550
1551
if (drv_data->bt_cpu_id == I2S_BT) {
1552
links[i].name = "acp-bt-codec";
1553
links[i].id = BT_BE_ID;
1554
links[i].cpus = sof_bt;
1555
links[i].num_cpus = ARRAY_SIZE(sof_bt);
1556
links[i].platforms = sof_component;
1557
links[i].num_platforms = ARRAY_SIZE(sof_component);
1558
links[i].nonatomic = true;
1559
links[i].no_pcm = 1;
1560
if (!drv_data->bt_codec_id) {
1561
/* Use dummy codec if codec id not specified */
1562
links[i].codecs = &snd_soc_dummy_dlc;
1563
links[i].num_codecs = 1;
1564
}
1565
i++;
1566
}
1567
1568
if (drv_data->dmic_cpu_id == DMIC) {
1569
links[i].name = "acp-dmic-codec";
1570
links[i].id = DMIC_BE_ID;
1571
links[i].codecs = dmic_codec;
1572
links[i].num_codecs = ARRAY_SIZE(dmic_codec);
1573
links[i].cpus = sof_dmic;
1574
links[i].num_cpus = ARRAY_SIZE(sof_dmic);
1575
links[i].platforms = sof_component;
1576
links[i].num_platforms = ARRAY_SIZE(sof_component);
1577
links[i].capture_only = 1;
1578
links[i].nonatomic = true;
1579
links[i].no_pcm = 1;
1580
}
1581
1582
card->dai_link = links;
1583
card->num_links = num_links;
1584
card->set_bias_level = acp_rtk_set_bias_level;
1585
1586
return 0;
1587
}
1588
EXPORT_SYMBOL_NS_GPL(acp_sofdsp_dai_links_create, "SND_SOC_AMD_MACH");
1589
1590
int acp_legacy_dai_links_create(struct snd_soc_card *card)
1591
{
1592
struct snd_soc_dai_link *links;
1593
struct device *dev = card->dev;
1594
struct acp_card_drvdata *drv_data = card->drvdata;
1595
int i = 0, num_links = 0;
1596
int rc;
1597
1598
if (drv_data->hs_cpu_id)
1599
num_links++;
1600
if (drv_data->amp_cpu_id)
1601
num_links++;
1602
if (drv_data->dmic_cpu_id)
1603
num_links++;
1604
1605
links = devm_kcalloc(dev, num_links, sizeof(struct snd_soc_dai_link), GFP_KERNEL);
1606
if (!links)
1607
return -ENOMEM;
1608
1609
if (drv_data->hs_cpu_id == I2S_SP) {
1610
links[i].name = "acp-headset-codec";
1611
links[i].id = HEADSET_BE_ID;
1612
links[i].cpus = i2s_sp;
1613
links[i].num_cpus = ARRAY_SIZE(i2s_sp);
1614
links[i].platforms = platform_component;
1615
links[i].num_platforms = ARRAY_SIZE(platform_component);
1616
if (!drv_data->hs_codec_id) {
1617
/* Use dummy codec if codec id not specified */
1618
links[i].codecs = &snd_soc_dummy_dlc;
1619
links[i].num_codecs = 1;
1620
}
1621
if (drv_data->hs_codec_id == RT5682) {
1622
links[i].codecs = rt5682;
1623
links[i].num_codecs = ARRAY_SIZE(rt5682);
1624
links[i].init = acp_card_rt5682_init;
1625
links[i].ops = &acp_card_rt5682_ops;
1626
}
1627
if (drv_data->hs_codec_id == RT5682S) {
1628
links[i].codecs = rt5682s;
1629
links[i].num_codecs = ARRAY_SIZE(rt5682s);
1630
links[i].init = acp_card_rt5682s_init;
1631
links[i].ops = &acp_card_rt5682s_ops;
1632
}
1633
if (drv_data->hs_codec_id == ES83XX) {
1634
rc = acp_ops_configure_link(card, &links[i]);
1635
if (rc != 0) {
1636
dev_err(dev, "Failed to configure link for ES83XX: %d\n", rc);
1637
return rc;
1638
}
1639
}
1640
i++;
1641
}
1642
1643
if (drv_data->hs_cpu_id == I2S_HS) {
1644
links[i].name = "acp-headset-codec";
1645
links[i].id = HEADSET_BE_ID;
1646
links[i].cpus = i2s_hs;
1647
links[i].num_cpus = ARRAY_SIZE(i2s_hs);
1648
switch (drv_data->acp_rev) {
1649
case ACP_RMB_PCI_ID:
1650
links[i].platforms = platform_rmb_component;
1651
links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);
1652
break;
1653
case ACP63_PCI_ID:
1654
links[i].platforms = platform_acp63_component;
1655
links[i].num_platforms = ARRAY_SIZE(platform_acp63_component);
1656
break;
1657
default:
1658
links[i].platforms = platform_component;
1659
links[i].num_platforms = ARRAY_SIZE(platform_component);
1660
break;
1661
}
1662
1663
if (!drv_data->hs_codec_id) {
1664
/* Use dummy codec if codec id not specified */
1665
links[i].codecs = &snd_soc_dummy_dlc;
1666
links[i].num_codecs = 1;
1667
}
1668
if (drv_data->hs_codec_id == NAU8825) {
1669
links[i].codecs = nau8825;
1670
links[i].num_codecs = ARRAY_SIZE(nau8825);
1671
links[i].init = acp_card_nau8825_init;
1672
links[i].ops = &acp_card_nau8825_ops;
1673
}
1674
if (drv_data->hs_codec_id == RT5682S) {
1675
links[i].codecs = rt5682s;
1676
links[i].num_codecs = ARRAY_SIZE(rt5682s);
1677
links[i].init = acp_card_rt5682s_init;
1678
links[i].ops = &acp_card_rt5682s_ops;
1679
}
1680
i++;
1681
}
1682
1683
if (drv_data->amp_cpu_id == I2S_SP) {
1684
links[i].name = "acp-amp-codec";
1685
links[i].id = AMP_BE_ID;
1686
links[i].cpus = i2s_sp;
1687
links[i].num_cpus = ARRAY_SIZE(i2s_sp);
1688
links[i].platforms = platform_component;
1689
links[i].num_platforms = ARRAY_SIZE(platform_component);
1690
links[i].playback_only = 1;
1691
if (!drv_data->amp_codec_id) {
1692
/* Use dummy codec if codec id not specified */
1693
links[i].codecs = &snd_soc_dummy_dlc;
1694
links[i].num_codecs = 1;
1695
}
1696
if (drv_data->amp_codec_id == RT1019) {
1697
links[i].codecs = rt1019;
1698
links[i].num_codecs = ARRAY_SIZE(rt1019);
1699
links[i].ops = &acp_card_rt1019_ops;
1700
links[i].init = acp_card_rt1019_init;
1701
card->codec_conf = rt1019_conf;
1702
card->num_configs = ARRAY_SIZE(rt1019_conf);
1703
}
1704
if (drv_data->amp_codec_id == MAX98360A) {
1705
links[i].codecs = max98360a;
1706
links[i].num_codecs = ARRAY_SIZE(max98360a);
1707
links[i].ops = &acp_card_maxim_ops;
1708
links[i].init = acp_card_maxim_init;
1709
}
1710
i++;
1711
}
1712
1713
if (drv_data->amp_cpu_id == I2S_HS) {
1714
links[i].name = "acp-amp-codec";
1715
links[i].id = AMP_BE_ID;
1716
links[i].cpus = i2s_hs;
1717
links[i].num_cpus = ARRAY_SIZE(i2s_hs);
1718
switch (drv_data->acp_rev) {
1719
case ACP_RMB_PCI_ID:
1720
links[i].platforms = platform_rmb_component;
1721
links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);
1722
break;
1723
case ACP63_PCI_ID:
1724
links[i].platforms = platform_acp63_component;
1725
links[i].num_platforms = ARRAY_SIZE(platform_acp63_component);
1726
break;
1727
default:
1728
links[i].platforms = platform_component;
1729
links[i].num_platforms = ARRAY_SIZE(platform_component);
1730
break;
1731
}
1732
1733
links[i].playback_only = 1;
1734
if (!drv_data->amp_codec_id) {
1735
/* Use dummy codec if codec id not specified */
1736
links[i].codecs = &snd_soc_dummy_dlc;
1737
links[i].num_codecs = 1;
1738
}
1739
if (drv_data->amp_codec_id == MAX98360A) {
1740
links[i].codecs = max98360a;
1741
links[i].num_codecs = ARRAY_SIZE(max98360a);
1742
links[i].ops = &acp_card_maxim_ops;
1743
links[i].init = acp_card_maxim_init;
1744
}
1745
if (drv_data->amp_codec_id == RT1019) {
1746
links[i].codecs = rt1019;
1747
links[i].num_codecs = ARRAY_SIZE(rt1019);
1748
links[i].ops = &acp_card_rt1019_ops;
1749
links[i].init = acp_card_rt1019_init;
1750
card->codec_conf = rt1019_conf;
1751
card->num_configs = ARRAY_SIZE(rt1019_conf);
1752
}
1753
i++;
1754
}
1755
1756
if (drv_data->dmic_cpu_id == DMIC) {
1757
links[i].name = "acp-dmic-codec";
1758
links[i].stream_name = "DMIC capture";
1759
links[i].id = DMIC_BE_ID;
1760
if (drv_data->dmic_codec_id == DMIC) {
1761
links[i].codecs = dmic_codec;
1762
links[i].num_codecs = ARRAY_SIZE(dmic_codec);
1763
} else {
1764
/* Use dummy codec if codec id not specified */
1765
links[i].codecs = &snd_soc_dummy_dlc;
1766
links[i].num_codecs = 1;
1767
}
1768
links[i].cpus = pdm_dmic;
1769
links[i].num_cpus = ARRAY_SIZE(pdm_dmic);
1770
switch (drv_data->acp_rev) {
1771
case ACP_RMB_PCI_ID:
1772
links[i].platforms = platform_rmb_component;
1773
links[i].num_platforms = ARRAY_SIZE(platform_rmb_component);
1774
break;
1775
case ACP63_PCI_ID:
1776
links[i].platforms = platform_acp63_component;
1777
links[i].num_platforms = ARRAY_SIZE(platform_acp63_component);
1778
break;
1779
case ACP70_PCI_ID:
1780
case ACP71_PCI_ID:
1781
case ACP72_PCI_ID:
1782
links[i].platforms = platform_acp70_component;
1783
links[i].num_platforms = ARRAY_SIZE(platform_acp70_component);
1784
break;
1785
default:
1786
links[i].platforms = platform_component;
1787
links[i].num_platforms = ARRAY_SIZE(platform_component);
1788
break;
1789
}
1790
links[i].ops = &acp_card_dmic_ops;
1791
links[i].capture_only = 1;
1792
}
1793
1794
card->dai_link = links;
1795
card->num_links = num_links;
1796
card->set_bias_level = acp_rtk_set_bias_level;
1797
1798
return 0;
1799
}
1800
EXPORT_SYMBOL_NS_GPL(acp_legacy_dai_links_create, "SND_SOC_AMD_MACH");
1801
1802
MODULE_DESCRIPTION("AMD ACP Common Machine driver");
1803
MODULE_LICENSE("GPL v2");
1804
1805