Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/intel/boards/bytcr_rt5651.c
29268 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* bytcr_rt5651.c - ASoc Machine driver for Intel Byt CR platform
4
* (derived from bytcr_rt5640.c)
5
*
6
* Copyright (C) 2015 Intel Corp
7
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8
*
9
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10
*/
11
12
#include <linux/init.h>
13
#include <linux/i2c.h>
14
#include <linux/module.h>
15
#include <linux/platform_device.h>
16
#include <linux/property.h>
17
#include <linux/acpi.h>
18
#include <linux/clk.h>
19
#include <linux/device.h>
20
#include <linux/dmi.h>
21
#include <linux/input.h>
22
#include <linux/gpio/consumer.h>
23
#include <linux/gpio/machine.h>
24
#include <linux/slab.h>
25
#include <sound/pcm.h>
26
#include <sound/pcm_params.h>
27
#include <sound/soc.h>
28
#include <sound/jack.h>
29
#include <sound/soc-acpi.h>
30
#include "../../codecs/rt5651.h"
31
#include "../atom/sst-atom-controls.h"
32
#include "../common/soc-intel-quirks.h"
33
34
enum {
35
BYT_RT5651_DMIC_MAP,
36
BYT_RT5651_IN1_MAP,
37
BYT_RT5651_IN2_MAP,
38
BYT_RT5651_IN1_IN2_MAP,
39
};
40
41
enum {
42
BYT_RT5651_JD_NULL = (RT5651_JD_NULL << 4),
43
BYT_RT5651_JD1_1 = (RT5651_JD1_1 << 4),
44
BYT_RT5651_JD1_2 = (RT5651_JD1_2 << 4),
45
BYT_RT5651_JD2 = (RT5651_JD2 << 4),
46
};
47
48
enum {
49
BYT_RT5651_OVCD_TH_600UA = (6 << 8),
50
BYT_RT5651_OVCD_TH_1500UA = (15 << 8),
51
BYT_RT5651_OVCD_TH_2000UA = (20 << 8),
52
};
53
54
enum {
55
BYT_RT5651_OVCD_SF_0P5 = (RT5651_OVCD_SF_0P5 << 13),
56
BYT_RT5651_OVCD_SF_0P75 = (RT5651_OVCD_SF_0P75 << 13),
57
BYT_RT5651_OVCD_SF_1P0 = (RT5651_OVCD_SF_1P0 << 13),
58
BYT_RT5651_OVCD_SF_1P5 = (RT5651_OVCD_SF_1P5 << 13),
59
};
60
61
#define BYT_RT5651_MAP_MASK GENMASK(3, 0)
62
#define BYT_RT5651_MAP(quirk) ((quirk) & BYT_RT5651_MAP_MASK)
63
#define BYT_RT5651_JDSRC(quirk) (((quirk) & GENMASK(7, 4)) >> 4)
64
#define BYT_RT5651_OVCD_TH(quirk) (((quirk) & GENMASK(12, 8)) >> 8)
65
#define BYT_RT5651_OVCD_SF(quirk) (((quirk) & GENMASK(14, 13)) >> 13)
66
#define BYT_RT5651_DMIC_EN BIT(16)
67
#define BYT_RT5651_MCLK_EN BIT(17)
68
#define BYT_RT5651_MCLK_25MHZ BIT(18)
69
#define BYT_RT5651_SSP2_AIF2 BIT(19) /* default is using AIF1 */
70
#define BYT_RT5651_SSP0_AIF1 BIT(20)
71
#define BYT_RT5651_SSP0_AIF2 BIT(21)
72
#define BYT_RT5651_HP_LR_SWAPPED BIT(22)
73
#define BYT_RT5651_MONO_SPEAKER BIT(23)
74
#define BYT_RT5651_JD_NOT_INV BIT(24)
75
76
#define BYT_RT5651_DEFAULT_QUIRKS (BYT_RT5651_MCLK_EN | \
77
BYT_RT5651_JD1_1 | \
78
BYT_RT5651_OVCD_TH_2000UA | \
79
BYT_RT5651_OVCD_SF_0P75)
80
81
/* jack-detect-source + inv + dmic-en + ovcd-th + -sf + terminating entry */
82
#define MAX_NO_PROPS 6
83
84
struct byt_rt5651_private {
85
struct clk *mclk;
86
struct gpio_desc *ext_amp_gpio;
87
struct gpio_desc *hp_detect;
88
struct snd_soc_jack jack;
89
struct device *codec_dev;
90
};
91
92
static const struct acpi_gpio_mapping *byt_rt5651_gpios;
93
94
/* Default: jack-detect on JD1_1, internal mic on in2, headsetmic on in3 */
95
static unsigned long byt_rt5651_quirk = BYT_RT5651_DEFAULT_QUIRKS |
96
BYT_RT5651_IN2_MAP;
97
98
static int quirk_override = -1;
99
module_param_named(quirk, quirk_override, int, 0444);
100
MODULE_PARM_DESC(quirk, "Board-specific quirk override");
101
102
static void log_quirks(struct device *dev)
103
{
104
int map;
105
106
map = BYT_RT5651_MAP(byt_rt5651_quirk);
107
switch (map) {
108
case BYT_RT5651_DMIC_MAP:
109
dev_info(dev, "quirk DMIC_MAP enabled");
110
break;
111
case BYT_RT5651_IN1_MAP:
112
dev_info(dev, "quirk IN1_MAP enabled");
113
break;
114
case BYT_RT5651_IN2_MAP:
115
dev_info(dev, "quirk IN2_MAP enabled");
116
break;
117
case BYT_RT5651_IN1_IN2_MAP:
118
dev_info(dev, "quirk IN1_IN2_MAP enabled");
119
break;
120
default:
121
dev_warn_once(dev, "quirk sets invalid input map: 0x%x, default to DMIC_MAP\n", map);
122
byt_rt5651_quirk &= ~BYT_RT5651_MAP_MASK;
123
byt_rt5651_quirk |= BYT_RT5651_DMIC_MAP;
124
break;
125
}
126
127
if (BYT_RT5651_JDSRC(byt_rt5651_quirk)) {
128
dev_info(dev, "quirk realtek,jack-detect-source %ld\n",
129
BYT_RT5651_JDSRC(byt_rt5651_quirk));
130
dev_info(dev, "quirk realtek,over-current-threshold-microamp %ld\n",
131
BYT_RT5651_OVCD_TH(byt_rt5651_quirk) * 100);
132
dev_info(dev, "quirk realtek,over-current-scale-factor %ld\n",
133
BYT_RT5651_OVCD_SF(byt_rt5651_quirk));
134
}
135
if (byt_rt5651_quirk & BYT_RT5651_DMIC_EN)
136
dev_info(dev, "quirk DMIC enabled");
137
if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN)
138
dev_info(dev, "quirk MCLK_EN enabled");
139
if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ)
140
dev_info(dev, "quirk MCLK_25MHZ enabled");
141
if (byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2)
142
dev_info(dev, "quirk SSP2_AIF2 enabled\n");
143
if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1)
144
dev_info(dev, "quirk SSP0_AIF1 enabled\n");
145
if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2)
146
dev_info(dev, "quirk SSP0_AIF2 enabled\n");
147
if (byt_rt5651_quirk & BYT_RT5651_MONO_SPEAKER)
148
dev_info(dev, "quirk MONO_SPEAKER enabled\n");
149
if (byt_rt5651_quirk & BYT_RT5651_JD_NOT_INV)
150
dev_info(dev, "quirk JD_NOT_INV enabled\n");
151
}
152
153
#define BYT_CODEC_DAI1 "rt5651-aif1"
154
#define BYT_CODEC_DAI2 "rt5651-aif2"
155
156
static int byt_rt5651_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai,
157
int rate, int bclk_ratio)
158
{
159
int clk_id, clk_freq, ret;
160
161
/* Configure the PLL before selecting it */
162
if (!(byt_rt5651_quirk & BYT_RT5651_MCLK_EN)) {
163
clk_id = RT5651_PLL1_S_BCLK1;
164
clk_freq = rate * bclk_ratio;
165
} else {
166
clk_id = RT5651_PLL1_S_MCLK;
167
if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ)
168
clk_freq = 25000000;
169
else
170
clk_freq = 19200000;
171
}
172
ret = snd_soc_dai_set_pll(codec_dai, 0, clk_id, clk_freq, rate * 512);
173
if (ret < 0) {
174
dev_err(codec_dai->component->dev, "can't set pll: %d\n", ret);
175
return ret;
176
}
177
178
ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_PLL1,
179
rate * 512, SND_SOC_CLOCK_IN);
180
if (ret < 0) {
181
dev_err(codec_dai->component->dev, "can't set clock %d\n", ret);
182
return ret;
183
}
184
185
return 0;
186
}
187
188
static int platform_clock_control(struct snd_soc_dapm_widget *w,
189
struct snd_kcontrol *k, int event)
190
{
191
struct snd_soc_dapm_context *dapm = w->dapm;
192
struct snd_soc_card *card = dapm->card;
193
struct snd_soc_dai *codec_dai;
194
struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
195
int ret;
196
197
codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1);
198
if (!codec_dai)
199
codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI2);
200
if (!codec_dai) {
201
dev_err(card->dev,
202
"Codec dai not found; Unable to set platform clock\n");
203
return -EIO;
204
}
205
206
if (SND_SOC_DAPM_EVENT_ON(event)) {
207
ret = clk_prepare_enable(priv->mclk);
208
if (ret < 0) {
209
dev_err(card->dev, "could not configure MCLK state");
210
return ret;
211
}
212
ret = byt_rt5651_prepare_and_enable_pll1(codec_dai, 48000, 50);
213
} else {
214
/*
215
* Set codec clock source to internal clock before
216
* turning off the platform clock. Codec needs clock
217
* for Jack detection and button press
218
*/
219
ret = snd_soc_dai_set_sysclk(codec_dai, RT5651_SCLK_S_RCCLK,
220
48000 * 512,
221
SND_SOC_CLOCK_IN);
222
if (!ret)
223
clk_disable_unprepare(priv->mclk);
224
}
225
226
if (ret < 0) {
227
dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
228
return ret;
229
}
230
231
return 0;
232
}
233
234
static int rt5651_ext_amp_power_event(struct snd_soc_dapm_widget *w,
235
struct snd_kcontrol *kcontrol, int event)
236
{
237
struct snd_soc_card *card = w->dapm->card;
238
struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
239
240
if (SND_SOC_DAPM_EVENT_ON(event))
241
gpiod_set_value_cansleep(priv->ext_amp_gpio, 1);
242
else
243
gpiod_set_value_cansleep(priv->ext_amp_gpio, 0);
244
245
return 0;
246
}
247
248
static const struct snd_soc_dapm_widget byt_rt5651_widgets[] = {
249
SND_SOC_DAPM_HP("Headphone", NULL),
250
SND_SOC_DAPM_MIC("Headset Mic", NULL),
251
SND_SOC_DAPM_MIC("Internal Mic", NULL),
252
SND_SOC_DAPM_SPK("Speaker", NULL),
253
SND_SOC_DAPM_LINE("Line In", NULL),
254
SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
255
platform_clock_control, SND_SOC_DAPM_PRE_PMU |
256
SND_SOC_DAPM_POST_PMD),
257
SND_SOC_DAPM_SUPPLY("Ext Amp Power", SND_SOC_NOPM, 0, 0,
258
rt5651_ext_amp_power_event,
259
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
260
};
261
262
static const struct snd_soc_dapm_route byt_rt5651_audio_map[] = {
263
{"Headphone", NULL, "Platform Clock"},
264
{"Headset Mic", NULL, "Platform Clock"},
265
{"Internal Mic", NULL, "Platform Clock"},
266
{"Speaker", NULL, "Platform Clock"},
267
{"Speaker", NULL, "Ext Amp Power"},
268
{"Line In", NULL, "Platform Clock"},
269
270
{"Headset Mic", NULL, "micbias1"}, /* lowercase for rt5651 */
271
{"Headphone", NULL, "HPOL"},
272
{"Headphone", NULL, "HPOR"},
273
{"Speaker", NULL, "LOUTL"},
274
{"Speaker", NULL, "LOUTR"},
275
{"IN2P", NULL, "Line In"},
276
{"IN2N", NULL, "Line In"},
277
278
};
279
280
static const struct snd_soc_dapm_route byt_rt5651_intmic_dmic_map[] = {
281
{"DMIC L1", NULL, "Internal Mic"},
282
{"DMIC R1", NULL, "Internal Mic"},
283
{"IN2P", NULL, "Headset Mic"},
284
};
285
286
static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_map[] = {
287
{"Internal Mic", NULL, "micbias1"},
288
{"IN1P", NULL, "Internal Mic"},
289
{"IN3P", NULL, "Headset Mic"},
290
};
291
292
static const struct snd_soc_dapm_route byt_rt5651_intmic_in2_map[] = {
293
{"Internal Mic", NULL, "micbias1"},
294
{"IN2P", NULL, "Internal Mic"},
295
{"IN3P", NULL, "Headset Mic"},
296
};
297
298
static const struct snd_soc_dapm_route byt_rt5651_intmic_in1_in2_map[] = {
299
{"Internal Mic", NULL, "micbias1"},
300
{"IN1P", NULL, "Internal Mic"},
301
{"IN2P", NULL, "Internal Mic"},
302
{"IN3P", NULL, "Headset Mic"},
303
};
304
305
static const struct snd_soc_dapm_route byt_rt5651_ssp0_aif1_map[] = {
306
{"ssp0 Tx", NULL, "modem_out"},
307
{"modem_in", NULL, "ssp0 Rx"},
308
309
{"AIF1 Playback", NULL, "ssp0 Tx"},
310
{"ssp0 Rx", NULL, "AIF1 Capture"},
311
};
312
313
static const struct snd_soc_dapm_route byt_rt5651_ssp0_aif2_map[] = {
314
{"ssp0 Tx", NULL, "modem_out"},
315
{"modem_in", NULL, "ssp0 Rx"},
316
317
{"AIF2 Playback", NULL, "ssp0 Tx"},
318
{"ssp0 Rx", NULL, "AIF2 Capture"},
319
};
320
321
static const struct snd_soc_dapm_route byt_rt5651_ssp2_aif1_map[] = {
322
{"ssp2 Tx", NULL, "codec_out0"},
323
{"ssp2 Tx", NULL, "codec_out1"},
324
{"codec_in0", NULL, "ssp2 Rx"},
325
{"codec_in1", NULL, "ssp2 Rx"},
326
327
{"AIF1 Playback", NULL, "ssp2 Tx"},
328
{"ssp2 Rx", NULL, "AIF1 Capture"},
329
};
330
331
static const struct snd_soc_dapm_route byt_rt5651_ssp2_aif2_map[] = {
332
{"ssp2 Tx", NULL, "codec_out0"},
333
{"ssp2 Tx", NULL, "codec_out1"},
334
{"codec_in0", NULL, "ssp2 Rx"},
335
{"codec_in1", NULL, "ssp2 Rx"},
336
337
{"AIF2 Playback", NULL, "ssp2 Tx"},
338
{"ssp2 Rx", NULL, "AIF2 Capture"},
339
};
340
341
static const struct snd_kcontrol_new byt_rt5651_controls[] = {
342
SOC_DAPM_PIN_SWITCH("Headphone"),
343
SOC_DAPM_PIN_SWITCH("Headset Mic"),
344
SOC_DAPM_PIN_SWITCH("Internal Mic"),
345
SOC_DAPM_PIN_SWITCH("Speaker"),
346
SOC_DAPM_PIN_SWITCH("Line In"),
347
};
348
349
static struct snd_soc_jack_pin bytcr_jack_pins[] = {
350
{
351
.pin = "Headphone",
352
.mask = SND_JACK_HEADPHONE,
353
},
354
{
355
.pin = "Headset Mic",
356
.mask = SND_JACK_MICROPHONE,
357
},
358
};
359
360
static int byt_rt5651_aif1_hw_params(struct snd_pcm_substream *substream,
361
struct snd_pcm_hw_params *params)
362
{
363
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
364
struct snd_soc_dai *codec_dai = snd_soc_rtd_to_codec(rtd, 0);
365
snd_pcm_format_t format = params_format(params);
366
int rate = params_rate(params);
367
int bclk_ratio;
368
369
if (format == SNDRV_PCM_FORMAT_S16_LE)
370
bclk_ratio = 32;
371
else
372
bclk_ratio = 50;
373
374
return byt_rt5651_prepare_and_enable_pll1(codec_dai, rate, bclk_ratio);
375
}
376
377
static const struct acpi_gpio_params pov_p1006w_hp_detect = { 1, 0, false };
378
static const struct acpi_gpio_params pov_p1006w_ext_amp_en = { 2, 0, true };
379
380
static const struct acpi_gpio_mapping byt_rt5651_pov_p1006w_gpios[] = {
381
{ "hp-detect-gpios", &pov_p1006w_hp_detect, 1, },
382
{ "ext-amp-enable-gpios", &pov_p1006w_ext_amp_en, 1, },
383
{ },
384
};
385
386
static int byt_rt5651_pov_p1006w_quirk_cb(const struct dmi_system_id *id)
387
{
388
byt_rt5651_quirk = (unsigned long)id->driver_data;
389
byt_rt5651_gpios = byt_rt5651_pov_p1006w_gpios;
390
return 1;
391
}
392
393
static int byt_rt5651_quirk_cb(const struct dmi_system_id *id)
394
{
395
byt_rt5651_quirk = (unsigned long)id->driver_data;
396
return 1;
397
}
398
399
static const struct dmi_system_id byt_rt5651_quirk_table[] = {
400
{
401
/* Chuwi Hi8 Pro (CWI513) */
402
.callback = byt_rt5651_quirk_cb,
403
.matches = {
404
DMI_MATCH(DMI_SYS_VENDOR, "Hampoo"),
405
DMI_MATCH(DMI_PRODUCT_NAME, "X1D3_C806N"),
406
},
407
.driver_data = (void *)(BYT_RT5651_DEFAULT_QUIRKS |
408
BYT_RT5651_IN2_MAP |
409
BYT_RT5651_HP_LR_SWAPPED |
410
BYT_RT5651_MONO_SPEAKER),
411
},
412
{
413
/* Chuwi Vi8 Plus (CWI519) */
414
.callback = byt_rt5651_quirk_cb,
415
.matches = {
416
DMI_MATCH(DMI_SYS_VENDOR, "Hampoo"),
417
DMI_MATCH(DMI_PRODUCT_NAME, "D2D3_Vi8A1"),
418
},
419
.driver_data = (void *)(BYT_RT5651_DEFAULT_QUIRKS |
420
BYT_RT5651_IN2_MAP |
421
BYT_RT5651_HP_LR_SWAPPED |
422
BYT_RT5651_MONO_SPEAKER),
423
},
424
{
425
/* Complet Electro Serv MY8307 */
426
.callback = byt_rt5651_quirk_cb,
427
.matches = {
428
DMI_MATCH(DMI_SYS_VENDOR, "Complet Electro Serv"),
429
DMI_MATCH(DMI_PRODUCT_NAME, "MY8307"),
430
},
431
.driver_data = (void *)(BYT_RT5651_DEFAULT_QUIRKS |
432
BYT_RT5651_IN2_MAP |
433
BYT_RT5651_MONO_SPEAKER |
434
BYT_RT5651_JD_NOT_INV),
435
},
436
{
437
/* I.T.Works TW701, Ployer Momo7w and Trekstor ST70416-6
438
* (these all use the same mainboard) */
439
.callback = byt_rt5651_quirk_cb,
440
.matches = {
441
DMI_MATCH(DMI_BIOS_VENDOR, "INSYDE Corp."),
442
/* Partial match for all of itWORKS.G.WI71C.JGBMRBA,
443
* TREK.G.WI71C.JGBMRBA0x and MOMO.G.WI71C.MABMRBA02 */
444
DMI_MATCH(DMI_BIOS_VERSION, ".G.WI71C."),
445
},
446
.driver_data = (void *)(BYT_RT5651_DEFAULT_QUIRKS |
447
BYT_RT5651_IN2_MAP |
448
BYT_RT5651_SSP0_AIF1 |
449
BYT_RT5651_MONO_SPEAKER),
450
},
451
{
452
/* Jumper EZpad 7 */
453
.callback = byt_rt5651_quirk_cb,
454
.matches = {
455
DMI_MATCH(DMI_SYS_VENDOR, "Jumper"),
456
DMI_MATCH(DMI_PRODUCT_NAME, "EZpad"),
457
/* Jumper12x.WJ2012.bsBKRCP05 with the version dropped */
458
DMI_MATCH(DMI_BIOS_VERSION, "Jumper12x.WJ2012.bsBKRCP"),
459
},
460
.driver_data = (void *)(BYT_RT5651_DEFAULT_QUIRKS |
461
BYT_RT5651_IN2_MAP |
462
BYT_RT5651_JD_NOT_INV),
463
},
464
{
465
/* KIANO SlimNote 14.2 */
466
.callback = byt_rt5651_quirk_cb,
467
.matches = {
468
DMI_MATCH(DMI_SYS_VENDOR, "KIANO"),
469
DMI_MATCH(DMI_PRODUCT_NAME, "KIANO SlimNote 14.2"),
470
},
471
.driver_data = (void *)(BYT_RT5651_DEFAULT_QUIRKS |
472
BYT_RT5651_IN1_IN2_MAP),
473
},
474
{
475
/* Minnowboard Max B3 */
476
.callback = byt_rt5651_quirk_cb,
477
.matches = {
478
DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
479
DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
480
},
481
.driver_data = (void *)(BYT_RT5651_IN1_MAP),
482
},
483
{
484
/* Minnowboard Turbot */
485
.callback = byt_rt5651_quirk_cb,
486
.matches = {
487
DMI_MATCH(DMI_SYS_VENDOR, "ADI"),
488
DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Turbot"),
489
},
490
.driver_data = (void *)(BYT_RT5651_MCLK_EN |
491
BYT_RT5651_IN1_MAP),
492
},
493
{
494
/* Point of View mobii wintab p1006w (v1.0) */
495
.callback = byt_rt5651_pov_p1006w_quirk_cb,
496
.matches = {
497
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
498
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "BayTrail"),
499
/* Note 105b is Foxcon's USB/PCI vendor id */
500
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "105B"),
501
DMI_EXACT_MATCH(DMI_BOARD_NAME, "0E57"),
502
},
503
.driver_data = (void *)(BYT_RT5651_DMIC_MAP |
504
BYT_RT5651_OVCD_TH_2000UA |
505
BYT_RT5651_OVCD_SF_0P75 |
506
BYT_RT5651_DMIC_EN |
507
BYT_RT5651_MCLK_EN |
508
BYT_RT5651_SSP0_AIF1),
509
},
510
{
511
/* VIOS LTH17 */
512
.callback = byt_rt5651_quirk_cb,
513
.matches = {
514
DMI_MATCH(DMI_SYS_VENDOR, "VIOS"),
515
DMI_MATCH(DMI_PRODUCT_NAME, "LTH17"),
516
},
517
.driver_data = (void *)(BYT_RT5651_IN1_IN2_MAP |
518
BYT_RT5651_JD1_1 |
519
BYT_RT5651_OVCD_TH_2000UA |
520
BYT_RT5651_OVCD_SF_1P0 |
521
BYT_RT5651_MCLK_EN),
522
},
523
{
524
/* Yours Y8W81 (and others using the same mainboard) */
525
.callback = byt_rt5651_quirk_cb,
526
.matches = {
527
DMI_MATCH(DMI_BIOS_VENDOR, "INSYDE Corp."),
528
/* Partial match for all devs with a W86C mainboard */
529
DMI_MATCH(DMI_BIOS_VERSION, ".F.W86C."),
530
},
531
.driver_data = (void *)(BYT_RT5651_DEFAULT_QUIRKS |
532
BYT_RT5651_IN2_MAP |
533
BYT_RT5651_SSP0_AIF1 |
534
BYT_RT5651_MONO_SPEAKER),
535
},
536
{}
537
};
538
539
/*
540
* Note this MUST be called before snd_soc_register_card(), so that the props
541
* are in place before the codec component driver's probe function parses them.
542
*/
543
static int byt_rt5651_add_codec_device_props(struct device *i2c_dev,
544
struct byt_rt5651_private *priv)
545
{
546
struct property_entry props[MAX_NO_PROPS] = {};
547
struct fwnode_handle *fwnode;
548
int cnt = 0;
549
int ret;
550
551
props[cnt++] = PROPERTY_ENTRY_U32("realtek,jack-detect-source",
552
BYT_RT5651_JDSRC(byt_rt5651_quirk));
553
554
props[cnt++] = PROPERTY_ENTRY_U32("realtek,over-current-threshold-microamp",
555
BYT_RT5651_OVCD_TH(byt_rt5651_quirk) * 100);
556
557
props[cnt++] = PROPERTY_ENTRY_U32("realtek,over-current-scale-factor",
558
BYT_RT5651_OVCD_SF(byt_rt5651_quirk));
559
560
if (byt_rt5651_quirk & BYT_RT5651_DMIC_EN)
561
props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,dmic-en");
562
563
if (byt_rt5651_quirk & BYT_RT5651_JD_NOT_INV)
564
props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted");
565
566
fwnode = fwnode_create_software_node(props, NULL);
567
if (IS_ERR(fwnode)) {
568
/* put_device(i2c_dev) is handled in caller */
569
return PTR_ERR(fwnode);
570
}
571
572
ret = device_add_software_node(i2c_dev, to_software_node(fwnode));
573
574
fwnode_handle_put(fwnode);
575
576
return ret;
577
}
578
579
static int byt_rt5651_init(struct snd_soc_pcm_runtime *runtime)
580
{
581
struct snd_soc_card *card = runtime->card;
582
struct snd_soc_component *codec = snd_soc_rtd_to_codec(runtime, 0)->component;
583
struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
584
const struct snd_soc_dapm_route *custom_map;
585
int num_routes;
586
int report;
587
int ret;
588
589
card->dapm.idle_bias = false;
590
591
/* Start with RC clk for jack-detect (we disable MCLK below) */
592
if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN)
593
snd_soc_component_update_bits(codec, RT5651_GLB_CLK,
594
RT5651_SCLK_SRC_MASK, RT5651_SCLK_SRC_RCCLK);
595
596
switch (BYT_RT5651_MAP(byt_rt5651_quirk)) {
597
case BYT_RT5651_IN1_MAP:
598
custom_map = byt_rt5651_intmic_in1_map;
599
num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_map);
600
break;
601
case BYT_RT5651_IN2_MAP:
602
custom_map = byt_rt5651_intmic_in2_map;
603
num_routes = ARRAY_SIZE(byt_rt5651_intmic_in2_map);
604
break;
605
case BYT_RT5651_IN1_IN2_MAP:
606
custom_map = byt_rt5651_intmic_in1_in2_map;
607
num_routes = ARRAY_SIZE(byt_rt5651_intmic_in1_in2_map);
608
break;
609
default:
610
custom_map = byt_rt5651_intmic_dmic_map;
611
num_routes = ARRAY_SIZE(byt_rt5651_intmic_dmic_map);
612
}
613
ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
614
if (ret)
615
return ret;
616
617
if (byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2) {
618
ret = snd_soc_dapm_add_routes(&card->dapm,
619
byt_rt5651_ssp2_aif2_map,
620
ARRAY_SIZE(byt_rt5651_ssp2_aif2_map));
621
} else if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1) {
622
ret = snd_soc_dapm_add_routes(&card->dapm,
623
byt_rt5651_ssp0_aif1_map,
624
ARRAY_SIZE(byt_rt5651_ssp0_aif1_map));
625
} else if (byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2) {
626
ret = snd_soc_dapm_add_routes(&card->dapm,
627
byt_rt5651_ssp0_aif2_map,
628
ARRAY_SIZE(byt_rt5651_ssp0_aif2_map));
629
} else {
630
ret = snd_soc_dapm_add_routes(&card->dapm,
631
byt_rt5651_ssp2_aif1_map,
632
ARRAY_SIZE(byt_rt5651_ssp2_aif1_map));
633
}
634
if (ret)
635
return ret;
636
637
ret = snd_soc_add_card_controls(card, byt_rt5651_controls,
638
ARRAY_SIZE(byt_rt5651_controls));
639
if (ret) {
640
dev_err(card->dev, "unable to add card controls\n");
641
return ret;
642
}
643
644
/*
645
* The firmware might enable the clock at boot (this information
646
* may or may not be reflected in the enable clock register).
647
* To change the rate we must disable the clock first to cover
648
* these cases. Due to common clock framework restrictions that
649
* do not allow to disable a clock that has not been enabled,
650
* we need to enable the clock first.
651
*/
652
ret = clk_prepare_enable(priv->mclk);
653
if (!ret)
654
clk_disable_unprepare(priv->mclk);
655
656
if (byt_rt5651_quirk & BYT_RT5651_MCLK_25MHZ)
657
ret = clk_set_rate(priv->mclk, 25000000);
658
else
659
ret = clk_set_rate(priv->mclk, 19200000);
660
661
if (ret)
662
dev_err(card->dev, "unable to set MCLK rate\n");
663
664
report = 0;
665
if (BYT_RT5651_JDSRC(byt_rt5651_quirk))
666
report = SND_JACK_HEADSET | SND_JACK_BTN_0;
667
else if (priv->hp_detect)
668
report = SND_JACK_HEADSET;
669
670
if (report) {
671
ret = snd_soc_card_jack_new_pins(runtime->card, "Headset",
672
report, &priv->jack,
673
bytcr_jack_pins,
674
ARRAY_SIZE(bytcr_jack_pins));
675
if (ret) {
676
dev_err(runtime->dev, "jack creation failed %d\n", ret);
677
return ret;
678
}
679
680
if (report & SND_JACK_BTN_0)
681
snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0,
682
KEY_PLAYPAUSE);
683
684
ret = snd_soc_component_set_jack(codec, &priv->jack,
685
priv->hp_detect);
686
if (ret)
687
return ret;
688
}
689
690
return 0;
691
}
692
693
static int byt_rt5651_codec_fixup(struct snd_soc_pcm_runtime *rtd,
694
struct snd_pcm_hw_params *params)
695
{
696
struct snd_interval *rate = hw_param_interval(params,
697
SNDRV_PCM_HW_PARAM_RATE);
698
struct snd_interval *channels = hw_param_interval(params,
699
SNDRV_PCM_HW_PARAM_CHANNELS);
700
int ret, bits;
701
702
/* The DSP will convert the FE rate to 48k, stereo */
703
rate->min = rate->max = 48000;
704
channels->min = channels->max = 2;
705
706
if ((byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1) ||
707
(byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2)) {
708
/* set SSP0 to 16-bit */
709
params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
710
bits = 16;
711
} else {
712
/* set SSP2 to 24-bit */
713
params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
714
bits = 24;
715
}
716
717
/*
718
* Default mode for SSP configuration is TDM 4 slot, override config
719
* with explicit setting to I2S 2ch. The word length is set with
720
* dai_set_tdm_slot() since there is no other API exposed
721
*/
722
ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0),
723
SND_SOC_DAIFMT_I2S |
724
SND_SOC_DAIFMT_NB_NF |
725
SND_SOC_DAIFMT_BP_FP
726
);
727
728
if (ret < 0) {
729
dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
730
return ret;
731
}
732
733
ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits);
734
if (ret < 0) {
735
dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
736
return ret;
737
}
738
739
return 0;
740
}
741
742
static const unsigned int rates_48000[] = {
743
48000,
744
};
745
746
static const struct snd_pcm_hw_constraint_list constraints_48000 = {
747
.count = ARRAY_SIZE(rates_48000),
748
.list = rates_48000,
749
};
750
751
static int byt_rt5651_aif1_startup(struct snd_pcm_substream *substream)
752
{
753
return snd_pcm_hw_constraint_list(substream->runtime, 0,
754
SNDRV_PCM_HW_PARAM_RATE,
755
&constraints_48000);
756
}
757
758
static const struct snd_soc_ops byt_rt5651_aif1_ops = {
759
.startup = byt_rt5651_aif1_startup,
760
};
761
762
static const struct snd_soc_ops byt_rt5651_be_ssp2_ops = {
763
.hw_params = byt_rt5651_aif1_hw_params,
764
};
765
766
SND_SOC_DAILINK_DEF(dummy,
767
DAILINK_COMP_ARRAY(COMP_DUMMY()));
768
769
SND_SOC_DAILINK_DEF(media,
770
DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai")));
771
772
SND_SOC_DAILINK_DEF(deepbuffer,
773
DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai")));
774
775
SND_SOC_DAILINK_DEF(ssp2_port,
776
DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port")));
777
SND_SOC_DAILINK_DEF(ssp2_codec,
778
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5651:00", "rt5651-aif1")));
779
780
SND_SOC_DAILINK_DEF(platform,
781
DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform")));
782
783
static struct snd_soc_dai_link byt_rt5651_dais[] = {
784
[MERR_DPCM_AUDIO] = {
785
.name = "Audio Port",
786
.stream_name = "Audio",
787
.nonatomic = true,
788
.dynamic = 1,
789
.ops = &byt_rt5651_aif1_ops,
790
SND_SOC_DAILINK_REG(media, dummy, platform),
791
},
792
[MERR_DPCM_DEEP_BUFFER] = {
793
.name = "Deep-Buffer Audio Port",
794
.stream_name = "Deep-Buffer Audio",
795
.nonatomic = true,
796
.dynamic = 1,
797
.playback_only = 1,
798
.ops = &byt_rt5651_aif1_ops,
799
SND_SOC_DAILINK_REG(deepbuffer, dummy, platform),
800
},
801
/* CODEC<->CODEC link */
802
/* back ends */
803
{
804
.name = "SSP2-Codec",
805
.id = 0,
806
.no_pcm = 1,
807
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
808
| SND_SOC_DAIFMT_CBC_CFC,
809
.be_hw_params_fixup = byt_rt5651_codec_fixup,
810
.init = byt_rt5651_init,
811
.ops = &byt_rt5651_be_ssp2_ops,
812
SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
813
},
814
};
815
816
/* SoC card */
817
static char byt_rt5651_codec_name[SND_ACPI_I2C_ID_LEN];
818
#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
819
static char byt_rt5651_long_name[50]; /* = "bytcr-rt5651-*-spk-*-mic[-swapped-hp]" */
820
#endif
821
static char byt_rt5651_components[50]; /* = "cfg-spk:* cfg-mic:*" */
822
823
static int byt_rt5651_suspend(struct snd_soc_card *card)
824
{
825
struct snd_soc_component *component;
826
827
if (!BYT_RT5651_JDSRC(byt_rt5651_quirk))
828
return 0;
829
830
for_each_card_components(card, component) {
831
if (!strcmp(component->name, byt_rt5651_codec_name)) {
832
dev_dbg(component->dev, "disabling jack detect before suspend\n");
833
snd_soc_component_set_jack(component, NULL, NULL);
834
break;
835
}
836
}
837
838
return 0;
839
}
840
841
static int byt_rt5651_resume(struct snd_soc_card *card)
842
{
843
struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
844
struct snd_soc_component *component;
845
846
if (!BYT_RT5651_JDSRC(byt_rt5651_quirk))
847
return 0;
848
849
for_each_card_components(card, component) {
850
if (!strcmp(component->name, byt_rt5651_codec_name)) {
851
dev_dbg(component->dev, "re-enabling jack detect after resume\n");
852
snd_soc_component_set_jack(component, &priv->jack,
853
priv->hp_detect);
854
break;
855
}
856
}
857
858
return 0;
859
}
860
861
/* use space before codec name to simplify card ID, and simplify driver name */
862
#define SOF_CARD_NAME "bytcht rt5651" /* card name will be 'sof-bytcht rt5651' */
863
#define SOF_DRIVER_NAME "SOF"
864
865
#define CARD_NAME "bytcr-rt5651"
866
#define DRIVER_NAME NULL /* card name will be used for driver name */
867
868
static struct snd_soc_card byt_rt5651_card = {
869
.name = CARD_NAME,
870
.driver_name = DRIVER_NAME,
871
.owner = THIS_MODULE,
872
.dai_link = byt_rt5651_dais,
873
.num_links = ARRAY_SIZE(byt_rt5651_dais),
874
.dapm_widgets = byt_rt5651_widgets,
875
.num_dapm_widgets = ARRAY_SIZE(byt_rt5651_widgets),
876
.dapm_routes = byt_rt5651_audio_map,
877
.num_dapm_routes = ARRAY_SIZE(byt_rt5651_audio_map),
878
.fully_routed = true,
879
.suspend_pre = byt_rt5651_suspend,
880
.resume_post = byt_rt5651_resume,
881
};
882
883
static const struct acpi_gpio_params ext_amp_enable_gpios = { 0, 0, false };
884
885
static const struct acpi_gpio_mapping cht_rt5651_gpios[] = {
886
/*
887
* Some boards have I2cSerialBusV2, GpioIo, GpioInt as ACPI resources,
888
* other boards may have I2cSerialBusV2, GpioInt, GpioIo instead.
889
* We want the GpioIo one for the ext-amp-enable-gpio.
890
*/
891
{ "ext-amp-enable-gpios", &ext_amp_enable_gpios, 1, ACPI_GPIO_QUIRK_ONLY_GPIOIO },
892
{ },
893
};
894
895
struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */
896
u64 aif_value; /* 1: AIF1, 2: AIF2 */
897
u64 mclock_value; /* usually 25MHz (0x17d7940), ignored */
898
};
899
900
static int snd_byt_rt5651_mc_probe(struct platform_device *pdev)
901
{
902
struct device *dev = &pdev->dev;
903
static const char * const mic_name[] = { "dmic", "in1", "in2", "in12" };
904
struct snd_soc_acpi_mach *mach = dev_get_platdata(dev);
905
struct byt_rt5651_private *priv;
906
const char *platform_name;
907
struct acpi_device *adev;
908
struct device *codec_dev;
909
bool sof_parent;
910
bool is_bytcr = false;
911
int ret_val = 0;
912
int dai_index = 0;
913
int i;
914
915
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
916
if (!priv)
917
return -ENOMEM;
918
919
/* register the soc card */
920
byt_rt5651_card.dev = dev;
921
snd_soc_card_set_drvdata(&byt_rt5651_card, priv);
922
923
/* fix index of codec dai */
924
for (i = 0; i < ARRAY_SIZE(byt_rt5651_dais); i++) {
925
if (byt_rt5651_dais[i].num_codecs &&
926
!strcmp(byt_rt5651_dais[i].codecs->name,
927
"i2c-10EC5651:00")) {
928
dai_index = i;
929
break;
930
}
931
}
932
933
/* fixup codec name based on HID */
934
adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1);
935
if (adev) {
936
snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name),
937
"i2c-%s", acpi_dev_name(adev));
938
byt_rt5651_dais[dai_index].codecs->name = byt_rt5651_codec_name;
939
} else {
940
dev_err(dev, "Error cannot find '%s' dev\n", mach->id);
941
return -ENOENT;
942
}
943
944
codec_dev = acpi_get_first_physical_node(adev);
945
acpi_dev_put(adev);
946
if (!codec_dev)
947
return -EPROBE_DEFER;
948
priv->codec_dev = get_device(codec_dev);
949
950
/*
951
* swap SSP0 if bytcr is detected
952
* (will be overridden if DMI quirk is detected)
953
*/
954
if (soc_intel_is_byt()) {
955
if (mach->mach_params.acpi_ipc_irq_index == 0)
956
is_bytcr = true;
957
}
958
959
if (is_bytcr) {
960
/*
961
* Baytrail CR platforms may have CHAN package in BIOS, try
962
* to find relevant routing quirk based as done on Windows
963
* platforms. We have to read the information directly from the
964
* BIOS, at this stage the card is not created and the links
965
* with the codec driver/pdata are non-existent
966
*/
967
968
struct acpi_chan_package chan_package = { 0 };
969
970
/* format specified: 2 64-bit integers */
971
struct acpi_buffer format = {sizeof("NN"), "NN"};
972
struct acpi_buffer state = {0, NULL};
973
struct snd_soc_acpi_package_context pkg_ctx;
974
bool pkg_found = false;
975
976
state.length = sizeof(chan_package);
977
state.pointer = &chan_package;
978
979
pkg_ctx.name = "CHAN";
980
pkg_ctx.length = 2;
981
pkg_ctx.format = &format;
982
pkg_ctx.state = &state;
983
pkg_ctx.data_valid = false;
984
985
pkg_found = snd_soc_acpi_find_package_from_hid(mach->id,
986
&pkg_ctx);
987
if (pkg_found) {
988
if (chan_package.aif_value == 1) {
989
dev_info(dev, "BIOS Routing: AIF1 connected\n");
990
byt_rt5651_quirk |= BYT_RT5651_SSP0_AIF1;
991
} else if (chan_package.aif_value == 2) {
992
dev_info(dev, "BIOS Routing: AIF2 connected\n");
993
byt_rt5651_quirk |= BYT_RT5651_SSP0_AIF2;
994
} else {
995
dev_info(dev, "BIOS Routing isn't valid, ignored\n");
996
pkg_found = false;
997
}
998
}
999
1000
if (!pkg_found) {
1001
/* no BIOS indications, assume SSP0-AIF2 connection */
1002
byt_rt5651_quirk |= BYT_RT5651_SSP0_AIF2;
1003
}
1004
}
1005
1006
/* check quirks before creating card */
1007
dmi_check_system(byt_rt5651_quirk_table);
1008
1009
if (quirk_override != -1) {
1010
dev_info(dev, "Overriding quirk 0x%lx => 0x%x\n",
1011
byt_rt5651_quirk, quirk_override);
1012
byt_rt5651_quirk = quirk_override;
1013
}
1014
1015
/* Must be called before register_card, also see declaration comment. */
1016
ret_val = byt_rt5651_add_codec_device_props(codec_dev, priv);
1017
if (ret_val)
1018
goto err_device;
1019
1020
/* Cherry Trail devices use an external amplifier enable gpio */
1021
if (soc_intel_is_cht() && !byt_rt5651_gpios)
1022
byt_rt5651_gpios = cht_rt5651_gpios;
1023
1024
if (byt_rt5651_gpios) {
1025
devm_acpi_dev_add_driver_gpios(codec_dev, byt_rt5651_gpios);
1026
priv->ext_amp_gpio = devm_fwnode_gpiod_get(dev, codec_dev->fwnode,
1027
"ext-amp-enable",
1028
GPIOD_OUT_LOW,
1029
"speaker-amp");
1030
if (IS_ERR(priv->ext_amp_gpio)) {
1031
ret_val = PTR_ERR(priv->ext_amp_gpio);
1032
switch (ret_val) {
1033
case -ENOENT:
1034
priv->ext_amp_gpio = NULL;
1035
break;
1036
default:
1037
dev_err(dev, "Failed to get ext-amp-enable GPIO: %d\n", ret_val);
1038
fallthrough;
1039
case -EPROBE_DEFER:
1040
goto err;
1041
}
1042
}
1043
priv->hp_detect = devm_fwnode_gpiod_get(dev, codec_dev->fwnode,
1044
"hp-detect",
1045
GPIOD_IN,
1046
"hp-detect");
1047
if (IS_ERR(priv->hp_detect)) {
1048
ret_val = PTR_ERR(priv->hp_detect);
1049
switch (ret_val) {
1050
case -ENOENT:
1051
priv->hp_detect = NULL;
1052
break;
1053
default:
1054
dev_err(dev, "Failed to get hp-detect GPIO: %d\n", ret_val);
1055
fallthrough;
1056
case -EPROBE_DEFER:
1057
goto err;
1058
}
1059
}
1060
}
1061
1062
log_quirks(dev);
1063
1064
if ((byt_rt5651_quirk & BYT_RT5651_SSP2_AIF2) ||
1065
(byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2))
1066
byt_rt5651_dais[dai_index].codecs->dai_name = "rt5651-aif2";
1067
1068
if ((byt_rt5651_quirk & BYT_RT5651_SSP0_AIF1) ||
1069
(byt_rt5651_quirk & BYT_RT5651_SSP0_AIF2))
1070
byt_rt5651_dais[dai_index].cpus->dai_name = "ssp0-port";
1071
1072
if (byt_rt5651_quirk & BYT_RT5651_MCLK_EN) {
1073
priv->mclk = devm_clk_get_optional(dev, "pmc_plt_clk_3");
1074
if (IS_ERR(priv->mclk)) {
1075
ret_val = dev_err_probe(dev, PTR_ERR(priv->mclk),
1076
"Failed to get MCLK from pmc_plt_clk_3\n");
1077
goto err;
1078
}
1079
/*
1080
* Fall back to bit clock usage when clock is not
1081
* available likely due to missing dependencies.
1082
*/
1083
if (!priv->mclk)
1084
byt_rt5651_quirk &= ~BYT_RT5651_MCLK_EN;
1085
}
1086
1087
snprintf(byt_rt5651_components, sizeof(byt_rt5651_components),
1088
"cfg-spk:%s cfg-mic:%s%s",
1089
(byt_rt5651_quirk & BYT_RT5651_MONO_SPEAKER) ? "1" : "2",
1090
mic_name[BYT_RT5651_MAP(byt_rt5651_quirk)],
1091
(byt_rt5651_quirk & BYT_RT5651_HP_LR_SWAPPED) ?
1092
" cfg-hp:lrswap" : "");
1093
byt_rt5651_card.components = byt_rt5651_components;
1094
#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
1095
snprintf(byt_rt5651_long_name, sizeof(byt_rt5651_long_name),
1096
"bytcr-rt5651-%s-spk-%s-mic%s",
1097
(byt_rt5651_quirk & BYT_RT5651_MONO_SPEAKER) ?
1098
"mono" : "stereo",
1099
mic_name[BYT_RT5651_MAP(byt_rt5651_quirk)],
1100
(byt_rt5651_quirk & BYT_RT5651_HP_LR_SWAPPED) ?
1101
"-hp-swapped" : "");
1102
byt_rt5651_card.long_name = byt_rt5651_long_name;
1103
#endif
1104
1105
/* override platform name, if required */
1106
platform_name = mach->mach_params.platform;
1107
1108
ret_val = snd_soc_fixup_dai_links_platform_name(&byt_rt5651_card,
1109
platform_name);
1110
if (ret_val)
1111
goto err;
1112
1113
sof_parent = snd_soc_acpi_sof_parent(dev);
1114
1115
/* set card and driver name */
1116
if (sof_parent) {
1117
byt_rt5651_card.name = SOF_CARD_NAME;
1118
byt_rt5651_card.driver_name = SOF_DRIVER_NAME;
1119
} else {
1120
byt_rt5651_card.name = CARD_NAME;
1121
byt_rt5651_card.driver_name = DRIVER_NAME;
1122
}
1123
1124
/* set pm ops */
1125
if (sof_parent)
1126
dev->driver->pm = &snd_soc_pm_ops;
1127
1128
ret_val = devm_snd_soc_register_card(dev, &byt_rt5651_card);
1129
if (ret_val) {
1130
dev_err(dev, "devm_snd_soc_register_card failed %d\n", ret_val);
1131
goto err;
1132
}
1133
platform_set_drvdata(pdev, &byt_rt5651_card);
1134
return ret_val;
1135
1136
err:
1137
device_remove_software_node(priv->codec_dev);
1138
err_device:
1139
put_device(priv->codec_dev);
1140
return ret_val;
1141
}
1142
1143
static void snd_byt_rt5651_mc_remove(struct platform_device *pdev)
1144
{
1145
struct snd_soc_card *card = platform_get_drvdata(pdev);
1146
struct byt_rt5651_private *priv = snd_soc_card_get_drvdata(card);
1147
1148
device_remove_software_node(priv->codec_dev);
1149
put_device(priv->codec_dev);
1150
}
1151
1152
static struct platform_driver snd_byt_rt5651_mc_driver = {
1153
.driver = {
1154
.name = "bytcr_rt5651",
1155
},
1156
.probe = snd_byt_rt5651_mc_probe,
1157
.remove = snd_byt_rt5651_mc_remove,
1158
};
1159
1160
module_platform_driver(snd_byt_rt5651_mc_driver);
1161
1162
MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver for RT5651");
1163
MODULE_AUTHOR("Pierre-Louis Bossart <[email protected]>");
1164
MODULE_LICENSE("GPL v2");
1165
MODULE_ALIAS("platform:bytcr_rt5651");
1166
1167