Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/soc/intel/boards/bytcr_rt5640.c
29268 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* byt_cr_dpcm_rt5640.c - ASoc Machine driver for Intel Byt CR platform
4
*
5
* Copyright (C) 2014 Intel Corp
6
* Author: Subhransu S. Prusty <[email protected]>
7
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8
*
9
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10
*/
11
12
#include <linux/i2c.h>
13
#include <linux/init.h>
14
#include <linux/module.h>
15
#include <linux/moduleparam.h>
16
#include <linux/platform_device.h>
17
#include <linux/acpi.h>
18
#include <linux/clk.h>
19
#include <linux/device.h>
20
#include <linux/device/bus.h>
21
#include <linux/dmi.h>
22
#include <linux/gpio/consumer.h>
23
#include <linux/gpio/machine.h>
24
#include <linux/input.h>
25
#include <linux/slab.h>
26
#include <sound/pcm.h>
27
#include <sound/pcm_params.h>
28
#include <sound/soc.h>
29
#include <sound/jack.h>
30
#include <sound/soc-acpi.h>
31
#include <dt-bindings/sound/rt5640.h>
32
#include "../../codecs/rt5640.h"
33
#include "../atom/sst-atom-controls.h"
34
#include "../common/soc-intel-quirks.h"
35
36
#define BYT_RT5640_FALLBACK_CODEC_DEV_NAME "i2c-rt5640"
37
38
enum {
39
BYT_RT5640_DMIC1_MAP,
40
BYT_RT5640_DMIC2_MAP,
41
BYT_RT5640_IN1_MAP,
42
BYT_RT5640_IN3_MAP,
43
BYT_RT5640_NO_INTERNAL_MIC_MAP,
44
};
45
46
#define RT5640_JD_SRC_EXT_GPIO 0x0f
47
48
enum {
49
BYT_RT5640_JD_SRC_GPIO1 = (RT5640_JD_SRC_GPIO1 << 4),
50
BYT_RT5640_JD_SRC_JD1_IN4P = (RT5640_JD_SRC_JD1_IN4P << 4),
51
BYT_RT5640_JD_SRC_JD2_IN4N = (RT5640_JD_SRC_JD2_IN4N << 4),
52
BYT_RT5640_JD_SRC_GPIO2 = (RT5640_JD_SRC_GPIO2 << 4),
53
BYT_RT5640_JD_SRC_GPIO3 = (RT5640_JD_SRC_GPIO3 << 4),
54
BYT_RT5640_JD_SRC_GPIO4 = (RT5640_JD_SRC_GPIO4 << 4),
55
BYT_RT5640_JD_SRC_EXT_GPIO = (RT5640_JD_SRC_EXT_GPIO << 4)
56
};
57
58
enum {
59
BYT_RT5640_OVCD_TH_600UA = (6 << 8),
60
BYT_RT5640_OVCD_TH_1500UA = (15 << 8),
61
BYT_RT5640_OVCD_TH_2000UA = (20 << 8),
62
};
63
64
enum {
65
BYT_RT5640_OVCD_SF_0P5 = (RT5640_OVCD_SF_0P5 << 13),
66
BYT_RT5640_OVCD_SF_0P75 = (RT5640_OVCD_SF_0P75 << 13),
67
BYT_RT5640_OVCD_SF_1P0 = (RT5640_OVCD_SF_1P0 << 13),
68
BYT_RT5640_OVCD_SF_1P5 = (RT5640_OVCD_SF_1P5 << 13),
69
};
70
71
#define BYT_RT5640_MAP_MASK GENMASK(3, 0)
72
#define BYT_RT5640_MAP(quirk) ((quirk) & BYT_RT5640_MAP_MASK)
73
#define BYT_RT5640_JDSRC(quirk) (((quirk) & GENMASK(7, 4)) >> 4)
74
#define BYT_RT5640_OVCD_TH(quirk) (((quirk) & GENMASK(12, 8)) >> 8)
75
#define BYT_RT5640_OVCD_SF(quirk) (((quirk) & GENMASK(14, 13)) >> 13)
76
#define BYT_RT5640_JD_NOT_INV BIT(16)
77
#define BYT_RT5640_MONO_SPEAKER BIT(17)
78
#define BYT_RT5640_DIFF_MIC BIT(18) /* default is single-ended */
79
#define BYT_RT5640_SSP2_AIF2 BIT(19) /* default is using AIF1 */
80
#define BYT_RT5640_SSP0_AIF1 BIT(20)
81
#define BYT_RT5640_SSP0_AIF2 BIT(21)
82
#define BYT_RT5640_MCLK_EN BIT(22)
83
#define BYT_RT5640_MCLK_25MHZ BIT(23)
84
#define BYT_RT5640_NO_SPEAKERS BIT(24)
85
#define BYT_RT5640_LINEOUT BIT(25)
86
#define BYT_RT5640_LINEOUT_AS_HP2 BIT(26)
87
#define BYT_RT5640_HSMIC2_ON_IN1 BIT(27)
88
#define BYT_RT5640_JD_HP_ELITEP_1000G2 BIT(28)
89
#define BYT_RT5640_USE_AMCR0F28 BIT(29)
90
#define BYT_RT5640_SWAPPED_SPEAKERS BIT(30)
91
92
#define BYTCR_INPUT_DEFAULTS \
93
(BYT_RT5640_IN3_MAP | \
94
BYT_RT5640_JD_SRC_JD1_IN4P | \
95
BYT_RT5640_OVCD_TH_2000UA | \
96
BYT_RT5640_OVCD_SF_0P75 | \
97
BYT_RT5640_DIFF_MIC)
98
99
/* in-diff or dmic-pin + jdsrc + ovcd-th + -sf + jd-inv + terminating entry */
100
#define MAX_NO_PROPS 6
101
102
struct byt_rt5640_private {
103
struct snd_soc_jack jack;
104
struct snd_soc_jack jack2;
105
struct rt5640_set_jack_data jack_data;
106
struct gpio_desc *hsmic_detect;
107
struct clk *mclk;
108
struct device *codec_dev;
109
};
110
static bool is_bytcr;
111
112
static unsigned long byt_rt5640_quirk = BYT_RT5640_MCLK_EN;
113
static int quirk_override = -1;
114
module_param_named(quirk, quirk_override, int, 0444);
115
MODULE_PARM_DESC(quirk, "Board-specific quirk override");
116
117
static void log_quirks(struct device *dev)
118
{
119
int map;
120
bool has_mclk = false;
121
bool has_ssp0 = false;
122
bool has_ssp0_aif1 = false;
123
bool has_ssp0_aif2 = false;
124
bool has_ssp2_aif2 = false;
125
126
map = BYT_RT5640_MAP(byt_rt5640_quirk);
127
switch (map) {
128
case BYT_RT5640_DMIC1_MAP:
129
dev_info(dev, "quirk DMIC1_MAP enabled\n");
130
break;
131
case BYT_RT5640_DMIC2_MAP:
132
dev_info(dev, "quirk DMIC2_MAP enabled\n");
133
break;
134
case BYT_RT5640_IN1_MAP:
135
dev_info(dev, "quirk IN1_MAP enabled\n");
136
break;
137
case BYT_RT5640_IN3_MAP:
138
dev_info(dev, "quirk IN3_MAP enabled\n");
139
break;
140
case BYT_RT5640_NO_INTERNAL_MIC_MAP:
141
dev_info(dev, "quirk NO_INTERNAL_MIC_MAP enabled\n");
142
break;
143
default:
144
dev_warn_once(dev, "quirk sets invalid input map: 0x%x, default to DMIC1_MAP\n", map);
145
byt_rt5640_quirk &= ~BYT_RT5640_MAP_MASK;
146
byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP;
147
break;
148
}
149
if (byt_rt5640_quirk & BYT_RT5640_HSMIC2_ON_IN1)
150
dev_info(dev, "quirk HSMIC2_ON_IN1 enabled\n");
151
if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
152
dev_info(dev, "quirk realtek,jack-detect-source %ld\n",
153
BYT_RT5640_JDSRC(byt_rt5640_quirk));
154
dev_info(dev, "quirk realtek,over-current-threshold-microamp %ld\n",
155
BYT_RT5640_OVCD_TH(byt_rt5640_quirk) * 100);
156
dev_info(dev, "quirk realtek,over-current-scale-factor %ld\n",
157
BYT_RT5640_OVCD_SF(byt_rt5640_quirk));
158
}
159
if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
160
dev_info(dev, "quirk JD_NOT_INV enabled\n");
161
if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2)
162
dev_info(dev, "quirk JD_HP_ELITEPAD_1000G2 enabled\n");
163
if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER)
164
dev_info(dev, "quirk MONO_SPEAKER enabled\n");
165
if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS)
166
dev_info(dev, "quirk NO_SPEAKERS enabled\n");
167
if (byt_rt5640_quirk & BYT_RT5640_SWAPPED_SPEAKERS)
168
dev_info(dev, "quirk SWAPPED_SPEAKERS enabled\n");
169
if (byt_rt5640_quirk & BYT_RT5640_LINEOUT)
170
dev_info(dev, "quirk LINEOUT enabled\n");
171
if (byt_rt5640_quirk & BYT_RT5640_LINEOUT_AS_HP2)
172
dev_info(dev, "quirk LINEOUT_AS_HP2 enabled\n");
173
if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
174
dev_info(dev, "quirk DIFF_MIC enabled\n");
175
if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
176
dev_info(dev, "quirk SSP0_AIF1 enabled\n");
177
has_ssp0 = true;
178
has_ssp0_aif1 = true;
179
}
180
if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
181
dev_info(dev, "quirk SSP0_AIF2 enabled\n");
182
has_ssp0 = true;
183
has_ssp0_aif2 = true;
184
}
185
if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
186
dev_info(dev, "quirk SSP2_AIF2 enabled\n");
187
has_ssp2_aif2 = true;
188
}
189
if (is_bytcr && !has_ssp0)
190
dev_err(dev, "Invalid routing, bytcr detected but no SSP0-based quirk, audio cannot work with SSP2 on bytcr\n");
191
if (has_ssp0_aif1 && has_ssp0_aif2)
192
dev_err(dev, "Invalid routing, SSP0 cannot be connected to both AIF1 and AIF2\n");
193
if (has_ssp0 && has_ssp2_aif2)
194
dev_err(dev, "Invalid routing, cannot have both SSP0 and SSP2 connected to codec\n");
195
196
if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
197
dev_info(dev, "quirk MCLK_EN enabled\n");
198
has_mclk = true;
199
}
200
if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
201
if (has_mclk)
202
dev_info(dev, "quirk MCLK_25MHZ enabled\n");
203
else
204
dev_err(dev, "quirk MCLK_25MHZ enabled but quirk MCLK not selected, will be ignored\n");
205
}
206
}
207
208
static int byt_rt5640_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai,
209
int rate)
210
{
211
int ret;
212
213
/* Configure the PLL before selecting it */
214
if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
215
/* use bitclock as PLL input */
216
if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
217
(byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
218
/* 2x16 bit slots on SSP0 */
219
ret = snd_soc_dai_set_pll(codec_dai, 0,
220
RT5640_PLL1_S_BCLK1,
221
rate * 32, rate * 512);
222
} else {
223
/* 2x15 bit slots on SSP2 */
224
ret = snd_soc_dai_set_pll(codec_dai, 0,
225
RT5640_PLL1_S_BCLK1,
226
rate * 50, rate * 512);
227
}
228
} else {
229
if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
230
ret = snd_soc_dai_set_pll(codec_dai, 0,
231
RT5640_PLL1_S_MCLK,
232
25000000, rate * 512);
233
} else {
234
ret = snd_soc_dai_set_pll(codec_dai, 0,
235
RT5640_PLL1_S_MCLK,
236
19200000, rate * 512);
237
}
238
}
239
240
if (ret < 0) {
241
dev_err(codec_dai->component->dev, "can't set pll: %d\n", ret);
242
return ret;
243
}
244
245
ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
246
rate * 512, SND_SOC_CLOCK_IN);
247
if (ret < 0) {
248
dev_err(codec_dai->component->dev, "can't set clock %d\n", ret);
249
return ret;
250
}
251
252
return 0;
253
}
254
255
#define BYT_CODEC_DAI1 "rt5640-aif1"
256
#define BYT_CODEC_DAI2 "rt5640-aif2"
257
258
static struct snd_soc_dai *byt_rt5640_get_codec_dai(struct snd_soc_dapm_context *dapm)
259
{
260
struct snd_soc_card *card = dapm->card;
261
struct snd_soc_dai *codec_dai;
262
263
codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1);
264
if (!codec_dai)
265
codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI2);
266
if (!codec_dai)
267
dev_err(card->dev, "Error codec dai not found\n");
268
269
return codec_dai;
270
}
271
272
static int platform_clock_control(struct snd_soc_dapm_widget *w,
273
struct snd_kcontrol *k, int event)
274
{
275
struct snd_soc_dapm_context *dapm = w->dapm;
276
struct snd_soc_card *card = dapm->card;
277
struct snd_soc_dai *codec_dai;
278
struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
279
int ret;
280
281
codec_dai = byt_rt5640_get_codec_dai(dapm);
282
if (!codec_dai)
283
return -EIO;
284
285
if (SND_SOC_DAPM_EVENT_ON(event)) {
286
ret = clk_prepare_enable(priv->mclk);
287
if (ret < 0) {
288
dev_err(card->dev, "could not configure MCLK state\n");
289
return ret;
290
}
291
ret = byt_rt5640_prepare_and_enable_pll1(codec_dai, 48000);
292
} else {
293
/*
294
* Set codec clock source to internal clock before
295
* turning off the platform clock. Codec needs clock
296
* for Jack detection and button press
297
*/
298
ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_RCCLK,
299
48000 * 512,
300
SND_SOC_CLOCK_IN);
301
if (!ret)
302
clk_disable_unprepare(priv->mclk);
303
}
304
305
if (ret < 0) {
306
dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
307
return ret;
308
}
309
310
return 0;
311
}
312
313
static int byt_rt5640_event_lineout(struct snd_soc_dapm_widget *w,
314
struct snd_kcontrol *k, int event)
315
{
316
unsigned int gpio_ctrl3_val = RT5640_GP1_PF_OUT;
317
struct snd_soc_dai *codec_dai;
318
319
if (!(byt_rt5640_quirk & BYT_RT5640_LINEOUT_AS_HP2))
320
return 0;
321
322
/*
323
* On devices which use line-out as a second headphones output,
324
* the codec's GPIO1 pin is used to enable an external HP-amp.
325
*/
326
327
codec_dai = byt_rt5640_get_codec_dai(w->dapm);
328
if (!codec_dai)
329
return -EIO;
330
331
if (SND_SOC_DAPM_EVENT_ON(event))
332
gpio_ctrl3_val |= RT5640_GP1_OUT_HI;
333
334
snd_soc_component_update_bits(codec_dai->component, RT5640_GPIO_CTRL3,
335
RT5640_GP1_PF_MASK | RT5640_GP1_OUT_MASK, gpio_ctrl3_val);
336
337
return 0;
338
}
339
340
static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
341
SND_SOC_DAPM_HP("Headphone", NULL),
342
SND_SOC_DAPM_MIC("Headset Mic", NULL),
343
SND_SOC_DAPM_MIC("Headset Mic 2", NULL),
344
SND_SOC_DAPM_MIC("Internal Mic", NULL),
345
SND_SOC_DAPM_SPK("Speaker", NULL),
346
SND_SOC_DAPM_LINE("Line Out", byt_rt5640_event_lineout),
347
SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
348
platform_clock_control, SND_SOC_DAPM_PRE_PMU |
349
SND_SOC_DAPM_POST_PMD),
350
};
351
352
static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
353
{"Headphone", NULL, "Platform Clock"},
354
{"Headset Mic", NULL, "Platform Clock"},
355
{"Headset Mic", NULL, "MICBIAS1"},
356
{"IN2P", NULL, "Headset Mic"},
357
{"Headphone", NULL, "HPOL"},
358
{"Headphone", NULL, "HPOR"},
359
};
360
361
static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = {
362
{"Internal Mic", NULL, "Platform Clock"},
363
{"DMIC1", NULL, "Internal Mic"},
364
};
365
366
static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic2_map[] = {
367
{"Internal Mic", NULL, "Platform Clock"},
368
{"DMIC2", NULL, "Internal Mic"},
369
};
370
371
static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = {
372
{"Internal Mic", NULL, "Platform Clock"},
373
{"Internal Mic", NULL, "MICBIAS1"},
374
{"IN1P", NULL, "Internal Mic"},
375
};
376
377
static const struct snd_soc_dapm_route byt_rt5640_intmic_in3_map[] = {
378
{"Internal Mic", NULL, "Platform Clock"},
379
{"Internal Mic", NULL, "MICBIAS1"},
380
{"IN3P", NULL, "Internal Mic"},
381
};
382
383
static const struct snd_soc_dapm_route byt_rt5640_hsmic2_in1_map[] = {
384
{"Headset Mic 2", NULL, "Platform Clock"},
385
{"Headset Mic 2", NULL, "MICBIAS1"},
386
{"IN1P", NULL, "Headset Mic 2"},
387
};
388
389
static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif1_map[] = {
390
{"ssp2 Tx", NULL, "codec_out0"},
391
{"ssp2 Tx", NULL, "codec_out1"},
392
{"codec_in0", NULL, "ssp2 Rx"},
393
{"codec_in1", NULL, "ssp2 Rx"},
394
395
{"AIF1 Playback", NULL, "ssp2 Tx"},
396
{"ssp2 Rx", NULL, "AIF1 Capture"},
397
};
398
399
static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif2_map[] = {
400
{"ssp2 Tx", NULL, "codec_out0"},
401
{"ssp2 Tx", NULL, "codec_out1"},
402
{"codec_in0", NULL, "ssp2 Rx"},
403
{"codec_in1", NULL, "ssp2 Rx"},
404
405
{"AIF2 Playback", NULL, "ssp2 Tx"},
406
{"ssp2 Rx", NULL, "AIF2 Capture"},
407
};
408
409
static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif1_map[] = {
410
{"ssp0 Tx", NULL, "modem_out"},
411
{"modem_in", NULL, "ssp0 Rx"},
412
413
{"AIF1 Playback", NULL, "ssp0 Tx"},
414
{"ssp0 Rx", NULL, "AIF1 Capture"},
415
};
416
417
static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif2_map[] = {
418
{"ssp0 Tx", NULL, "modem_out"},
419
{"modem_in", NULL, "ssp0 Rx"},
420
421
{"AIF2 Playback", NULL, "ssp0 Tx"},
422
{"ssp0 Rx", NULL, "AIF2 Capture"},
423
};
424
425
static const struct snd_soc_dapm_route byt_rt5640_stereo_spk_map[] = {
426
{"Speaker", NULL, "Platform Clock"},
427
{"Speaker", NULL, "SPOLP"},
428
{"Speaker", NULL, "SPOLN"},
429
{"Speaker", NULL, "SPORP"},
430
{"Speaker", NULL, "SPORN"},
431
};
432
433
static const struct snd_soc_dapm_route byt_rt5640_mono_spk_map[] = {
434
{"Speaker", NULL, "Platform Clock"},
435
{"Speaker", NULL, "SPOLP"},
436
{"Speaker", NULL, "SPOLN"},
437
};
438
439
static const struct snd_soc_dapm_route byt_rt5640_lineout_map[] = {
440
{"Line Out", NULL, "Platform Clock"},
441
{"Line Out", NULL, "LOUTR"},
442
{"Line Out", NULL, "LOUTL"},
443
};
444
445
static const struct snd_kcontrol_new byt_rt5640_controls[] = {
446
SOC_DAPM_PIN_SWITCH("Headphone"),
447
SOC_DAPM_PIN_SWITCH("Headset Mic"),
448
SOC_DAPM_PIN_SWITCH("Headset Mic 2"),
449
SOC_DAPM_PIN_SWITCH("Internal Mic"),
450
SOC_DAPM_PIN_SWITCH("Speaker"),
451
SOC_DAPM_PIN_SWITCH("Line Out"),
452
};
453
454
static struct snd_soc_jack_pin rt5640_pins[] = {
455
{
456
.pin = "Headphone",
457
.mask = SND_JACK_HEADPHONE,
458
},
459
{
460
.pin = "Headset Mic",
461
.mask = SND_JACK_MICROPHONE,
462
},
463
};
464
465
static struct snd_soc_jack_pin rt5640_pins2[] = {
466
{
467
/* The 2nd headset jack uses lineout with an external HP-amp */
468
.pin = "Line Out",
469
.mask = SND_JACK_HEADPHONE,
470
},
471
{
472
.pin = "Headset Mic 2",
473
.mask = SND_JACK_MICROPHONE,
474
},
475
};
476
477
static struct snd_soc_jack_gpio rt5640_jack_gpio = {
478
.name = "hp-detect",
479
.report = SND_JACK_HEADSET,
480
.invert = true,
481
.debounce_time = 200,
482
};
483
484
static struct snd_soc_jack_gpio rt5640_jack2_gpio = {
485
.name = "hp2-detect",
486
.report = SND_JACK_HEADSET,
487
.invert = true,
488
.debounce_time = 200,
489
};
490
491
static const struct acpi_gpio_params acpi_gpio0 = { 0, 0, false };
492
static const struct acpi_gpio_params acpi_gpio1 = { 1, 0, false };
493
static const struct acpi_gpio_params acpi_gpio2 = { 2, 0, false };
494
495
static const struct acpi_gpio_mapping byt_rt5640_hp_elitepad_1000g2_gpios[] = {
496
{ "hp-detect-gpios", &acpi_gpio0, 1, },
497
{ "headset-mic-detect-gpios", &acpi_gpio1, 1, },
498
{ "hp2-detect-gpios", &acpi_gpio2, 1, },
499
{ },
500
};
501
502
static int byt_rt5640_hp_elitepad_1000g2_jack1_check(void *data)
503
{
504
struct byt_rt5640_private *priv = data;
505
int jack_status, mic_status;
506
507
jack_status = gpiod_get_value_cansleep(rt5640_jack_gpio.desc);
508
if (jack_status)
509
return 0;
510
511
mic_status = gpiod_get_value_cansleep(priv->hsmic_detect);
512
if (mic_status)
513
return SND_JACK_HEADPHONE;
514
else
515
return SND_JACK_HEADSET;
516
}
517
518
static int byt_rt5640_hp_elitepad_1000g2_jack2_check(void *data)
519
{
520
struct snd_soc_component *component = data;
521
int jack_status, report;
522
523
jack_status = gpiod_get_value_cansleep(rt5640_jack2_gpio.desc);
524
if (jack_status)
525
return 0;
526
527
rt5640_enable_micbias1_for_ovcd(component);
528
report = rt5640_detect_headset(component, rt5640_jack2_gpio.desc);
529
rt5640_disable_micbias1_for_ovcd(component);
530
531
return report;
532
}
533
534
static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
535
struct snd_pcm_hw_params *params)
536
{
537
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
538
struct snd_soc_dai *dai = snd_soc_rtd_to_codec(rtd, 0);
539
540
return byt_rt5640_prepare_and_enable_pll1(dai, params_rate(params));
541
}
542
543
/* Please keep this list alphabetically sorted */
544
static const struct dmi_system_id byt_rt5640_quirk_table[] = {
545
{ /* Acer Iconia One 7 B1-750 */
546
.matches = {
547
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
548
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "VESPA2"),
549
},
550
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
551
BYT_RT5640_JD_SRC_JD1_IN4P |
552
BYT_RT5640_OVCD_TH_1500UA |
553
BYT_RT5640_OVCD_SF_0P75 |
554
BYT_RT5640_SSP0_AIF1 |
555
BYT_RT5640_MCLK_EN),
556
},
557
{ /* Acer Iconia Tab 8 W1-810 */
558
.matches = {
559
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
560
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Iconia W1-810"),
561
},
562
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
563
BYT_RT5640_JD_SRC_JD1_IN4P |
564
BYT_RT5640_OVCD_TH_1500UA |
565
BYT_RT5640_OVCD_SF_0P75 |
566
BYT_RT5640_SSP0_AIF1 |
567
BYT_RT5640_MCLK_EN),
568
},
569
{ /* Acer One 10 S1002 */
570
.matches = {
571
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
572
DMI_MATCH(DMI_PRODUCT_NAME, "One S1002"),
573
},
574
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
575
BYT_RT5640_JD_SRC_JD2_IN4N |
576
BYT_RT5640_OVCD_TH_2000UA |
577
BYT_RT5640_OVCD_SF_0P75 |
578
BYT_RT5640_DIFF_MIC |
579
BYT_RT5640_SSP0_AIF2 |
580
BYT_RT5640_MCLK_EN),
581
},
582
{ /* Acer Aspire SW3-013 */
583
.matches = {
584
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
585
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW3-013"),
586
},
587
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
588
BYT_RT5640_JD_SRC_JD2_IN4N |
589
BYT_RT5640_OVCD_TH_2000UA |
590
BYT_RT5640_OVCD_SF_0P75 |
591
BYT_RT5640_DIFF_MIC |
592
BYT_RT5640_SSP0_AIF1 |
593
BYT_RT5640_MCLK_EN),
594
},
595
{
596
.matches = {
597
DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
598
DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
599
},
600
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
601
BYT_RT5640_JD_SRC_JD2_IN4N |
602
BYT_RT5640_OVCD_TH_2000UA |
603
BYT_RT5640_OVCD_SF_0P75 |
604
BYT_RT5640_SSP0_AIF1 |
605
BYT_RT5640_MCLK_EN),
606
},
607
{
608
/* Advantech MICA-071 */
609
.matches = {
610
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Advantech"),
611
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MICA-071"),
612
},
613
/* OVCD Th = 1500uA to reliable detect head-phones vs -set */
614
.driver_data = (void *)(BYT_RT5640_IN3_MAP |
615
BYT_RT5640_JD_SRC_JD2_IN4N |
616
BYT_RT5640_OVCD_TH_1500UA |
617
BYT_RT5640_OVCD_SF_0P75 |
618
BYT_RT5640_MONO_SPEAKER |
619
BYT_RT5640_DIFF_MIC |
620
BYT_RT5640_MCLK_EN),
621
},
622
{
623
.matches = {
624
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"),
625
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 80 Cesium"),
626
},
627
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
628
BYT_RT5640_MONO_SPEAKER |
629
BYT_RT5640_SSP0_AIF1 |
630
BYT_RT5640_MCLK_EN),
631
},
632
{
633
.matches = {
634
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"),
635
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 101 CESIUM"),
636
},
637
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
638
BYT_RT5640_JD_NOT_INV |
639
BYT_RT5640_DIFF_MIC |
640
BYT_RT5640_SSP0_AIF1 |
641
BYT_RT5640_MCLK_EN),
642
},
643
{
644
.matches = {
645
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"),
646
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 140 CESIUM"),
647
},
648
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
649
BYT_RT5640_JD_SRC_JD2_IN4N |
650
BYT_RT5640_OVCD_TH_2000UA |
651
BYT_RT5640_OVCD_SF_0P75 |
652
BYT_RT5640_SSP0_AIF1 |
653
BYT_RT5640_MCLK_EN),
654
},
655
{
656
.matches = {
657
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
658
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ME176C"),
659
},
660
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
661
BYT_RT5640_JD_SRC_JD2_IN4N |
662
BYT_RT5640_OVCD_TH_2000UA |
663
BYT_RT5640_OVCD_SF_0P75 |
664
BYT_RT5640_SSP0_AIF1 |
665
BYT_RT5640_MCLK_EN |
666
BYT_RT5640_USE_AMCR0F28),
667
},
668
{
669
/* Asus T100TAF, unlike other T100TA* models this one has a mono speaker */
670
.matches = {
671
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
672
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
673
},
674
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
675
BYT_RT5640_JD_SRC_JD2_IN4N |
676
BYT_RT5640_OVCD_TH_2000UA |
677
BYT_RT5640_OVCD_SF_0P75 |
678
BYT_RT5640_MONO_SPEAKER |
679
BYT_RT5640_DIFF_MIC |
680
BYT_RT5640_SSP0_AIF2 |
681
BYT_RT5640_MCLK_EN),
682
},
683
{
684
/* Asus T100TA and T100TAM, must come after T100TAF (mono spk) match */
685
.matches = {
686
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
687
DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"),
688
},
689
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
690
BYT_RT5640_JD_SRC_JD2_IN4N |
691
BYT_RT5640_OVCD_TH_2000UA |
692
BYT_RT5640_OVCD_SF_0P75 |
693
BYT_RT5640_MCLK_EN),
694
},
695
{
696
.matches = {
697
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
698
DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"),
699
},
700
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
701
BYT_RT5640_JD_SRC_EXT_GPIO |
702
BYT_RT5640_OVCD_TH_2000UA |
703
BYT_RT5640_OVCD_SF_0P75 |
704
BYT_RT5640_SSP0_AIF1 |
705
BYT_RT5640_MCLK_EN |
706
BYT_RT5640_USE_AMCR0F28),
707
},
708
{ /* Chuwi Vi8 (CWI506) */
709
.matches = {
710
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
711
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "i86"),
712
/* The above are too generic, also match BIOS info */
713
DMI_MATCH(DMI_BIOS_VERSION, "CHUWI.D86JLBNR"),
714
},
715
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
716
BYT_RT5640_MONO_SPEAKER |
717
BYT_RT5640_SSP0_AIF1 |
718
BYT_RT5640_MCLK_EN),
719
},
720
{ /* Chuwi Vi8 dual-boot (CWI506) */
721
.matches = {
722
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
723
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "i86"),
724
/* The above are too generic, also match BIOS info */
725
DMI_MATCH(DMI_BIOS_VERSION, "CHUWI2.D86JHBNR02"),
726
},
727
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
728
BYT_RT5640_MONO_SPEAKER |
729
BYT_RT5640_SSP0_AIF1 |
730
BYT_RT5640_MCLK_EN),
731
},
732
{
733
/* Chuwi Vi10 (CWI505) */
734
.matches = {
735
DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
736
DMI_MATCH(DMI_BOARD_NAME, "BYT-PF02"),
737
DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
738
DMI_MATCH(DMI_PRODUCT_NAME, "S165"),
739
},
740
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
741
BYT_RT5640_JD_SRC_JD2_IN4N |
742
BYT_RT5640_OVCD_TH_2000UA |
743
BYT_RT5640_OVCD_SF_0P75 |
744
BYT_RT5640_DIFF_MIC |
745
BYT_RT5640_SSP0_AIF1 |
746
BYT_RT5640_MCLK_EN),
747
},
748
{
749
/* Chuwi Hi8 (CWI509) */
750
.matches = {
751
DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
752
DMI_MATCH(DMI_BOARD_NAME, "BYT-PA03C"),
753
DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
754
DMI_MATCH(DMI_PRODUCT_NAME, "S806"),
755
},
756
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
757
BYT_RT5640_JD_SRC_JD2_IN4N |
758
BYT_RT5640_OVCD_TH_2000UA |
759
BYT_RT5640_OVCD_SF_0P75 |
760
BYT_RT5640_MONO_SPEAKER |
761
BYT_RT5640_DIFF_MIC |
762
BYT_RT5640_SSP0_AIF1 |
763
BYT_RT5640_MCLK_EN),
764
},
765
{
766
.matches = {
767
DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
768
DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
769
},
770
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP),
771
},
772
{ /* Connect Tablet 9 */
773
.matches = {
774
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Connect"),
775
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Tablet 9"),
776
},
777
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
778
BYT_RT5640_MONO_SPEAKER |
779
BYT_RT5640_SSP0_AIF1 |
780
BYT_RT5640_MCLK_EN),
781
},
782
{
783
.matches = {
784
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
785
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
786
},
787
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
788
BYT_RT5640_JD_SRC_JD2_IN4N |
789
BYT_RT5640_OVCD_TH_2000UA |
790
BYT_RT5640_OVCD_SF_0P75 |
791
BYT_RT5640_MONO_SPEAKER |
792
BYT_RT5640_MCLK_EN),
793
},
794
{ /* Estar Beauty HD MID 7316R */
795
.matches = {
796
DMI_MATCH(DMI_SYS_VENDOR, "Estar"),
797
DMI_MATCH(DMI_PRODUCT_NAME, "eSTAR BEAUTY HD Intel Quad core"),
798
},
799
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
800
BYT_RT5640_MONO_SPEAKER |
801
BYT_RT5640_SSP0_AIF1 |
802
BYT_RT5640_MCLK_EN),
803
},
804
{ /* Glavey TM800A550L */
805
.matches = {
806
DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
807
DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
808
/* Above strings are too generic, also match on BIOS version */
809
DMI_MATCH(DMI_BIOS_VERSION, "ZY-8-BI-PX4S70VTR400-X423B-005-D"),
810
},
811
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
812
BYT_RT5640_SSP0_AIF1 |
813
BYT_RT5640_MCLK_EN),
814
},
815
{
816
.matches = {
817
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
818
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
819
},
820
.driver_data = (void *)(BYT_RT5640_DMIC2_MAP |
821
BYT_RT5640_MCLK_EN |
822
BYT_RT5640_LINEOUT |
823
BYT_RT5640_LINEOUT_AS_HP2 |
824
BYT_RT5640_HSMIC2_ON_IN1 |
825
BYT_RT5640_JD_HP_ELITEP_1000G2),
826
},
827
{ /* HP Pavilion x2 10-k0XX, 10-n0XX */
828
.matches = {
829
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
830
DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
831
},
832
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
833
BYT_RT5640_JD_SRC_JD2_IN4N |
834
BYT_RT5640_OVCD_TH_1500UA |
835
BYT_RT5640_OVCD_SF_0P75 |
836
BYT_RT5640_SSP0_AIF1 |
837
BYT_RT5640_MCLK_EN),
838
},
839
{ /* HP Pavilion x2 10-p0XX */
840
.matches = {
841
DMI_MATCH(DMI_SYS_VENDOR, "HP"),
842
DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"),
843
},
844
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
845
BYT_RT5640_JD_SRC_JD1_IN4P |
846
BYT_RT5640_OVCD_TH_2000UA |
847
BYT_RT5640_OVCD_SF_0P75 |
848
BYT_RT5640_MCLK_EN),
849
},
850
{ /* HP Pro Tablet 408 */
851
.matches = {
852
DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
853
DMI_MATCH(DMI_PRODUCT_NAME, "HP Pro Tablet 408"),
854
},
855
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
856
BYT_RT5640_JD_SRC_JD2_IN4N |
857
BYT_RT5640_OVCD_TH_1500UA |
858
BYT_RT5640_OVCD_SF_0P75 |
859
BYT_RT5640_SSP0_AIF1 |
860
BYT_RT5640_MCLK_EN),
861
},
862
{ /* HP Stream 7 */
863
.matches = {
864
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
865
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Stream 7 Tablet"),
866
},
867
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
868
BYT_RT5640_MONO_SPEAKER |
869
BYT_RT5640_JD_NOT_INV |
870
BYT_RT5640_SSP0_AIF1 |
871
BYT_RT5640_MCLK_EN),
872
},
873
{ /* HP Stream 8 */
874
.matches = {
875
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
876
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Stream 8 Tablet"),
877
},
878
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
879
BYT_RT5640_JD_NOT_INV |
880
BYT_RT5640_SSP0_AIF1 |
881
BYT_RT5640_MCLK_EN),
882
},
883
{ /* I.T.Works TW891 */
884
.matches = {
885
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
886
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"),
887
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."),
888
DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"),
889
},
890
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
891
BYT_RT5640_MONO_SPEAKER |
892
BYT_RT5640_SSP0_AIF1 |
893
BYT_RT5640_MCLK_EN),
894
},
895
{ /* Lamina I8270 / T701BR.SE */
896
.matches = {
897
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Lamina"),
898
DMI_EXACT_MATCH(DMI_BOARD_NAME, "T701BR.SE"),
899
},
900
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
901
BYT_RT5640_MONO_SPEAKER |
902
BYT_RT5640_JD_NOT_INV |
903
BYT_RT5640_SSP0_AIF1 |
904
BYT_RT5640_MCLK_EN),
905
},
906
{ /* Lenovo Miix 2 8 */
907
.matches = {
908
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
909
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "20326"),
910
DMI_EXACT_MATCH(DMI_BOARD_NAME, "Hiking"),
911
},
912
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
913
BYT_RT5640_JD_SRC_JD2_IN4N |
914
BYT_RT5640_OVCD_TH_2000UA |
915
BYT_RT5640_OVCD_SF_0P75 |
916
BYT_RT5640_MONO_SPEAKER |
917
BYT_RT5640_MCLK_EN),
918
},
919
{ /* Lenovo Miix 3-830 */
920
.matches = {
921
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
922
DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 3-830"),
923
},
924
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
925
BYT_RT5640_JD_SRC_JD2_IN4N |
926
BYT_RT5640_OVCD_TH_2000UA |
927
BYT_RT5640_OVCD_SF_0P75 |
928
BYT_RT5640_MONO_SPEAKER |
929
BYT_RT5640_DIFF_MIC |
930
BYT_RT5640_SSP0_AIF1 |
931
BYT_RT5640_MCLK_EN),
932
},
933
{ /* Linx Linx7 tablet */
934
.matches = {
935
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LINX"),
936
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LINX7"),
937
},
938
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
939
BYT_RT5640_MONO_SPEAKER |
940
BYT_RT5640_JD_NOT_INV |
941
BYT_RT5640_SSP0_AIF1 |
942
BYT_RT5640_MCLK_EN),
943
},
944
{
945
/* Medion Lifetab S10346 */
946
.matches = {
947
DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
948
DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
949
/* Above strings are much too generic, also match on BIOS date */
950
DMI_MATCH(DMI_BIOS_DATE, "10/22/2015"),
951
},
952
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
953
BYT_RT5640_SWAPPED_SPEAKERS |
954
BYT_RT5640_SSP0_AIF1 |
955
BYT_RT5640_MCLK_EN),
956
},
957
{ /* Mele PCG03 Mini PC */
958
.matches = {
959
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Mini PC"),
960
DMI_EXACT_MATCH(DMI_BOARD_NAME, "Mini PC"),
961
},
962
.driver_data = (void *)(BYT_RT5640_NO_INTERNAL_MIC_MAP |
963
BYT_RT5640_NO_SPEAKERS |
964
BYT_RT5640_SSP0_AIF1),
965
},
966
{ /* MPMAN Converter 9, similar hw as the I.T.Works TW891 2-in-1 */
967
.matches = {
968
DMI_MATCH(DMI_SYS_VENDOR, "MPMAN"),
969
DMI_MATCH(DMI_PRODUCT_NAME, "Converter9"),
970
},
971
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
972
BYT_RT5640_MONO_SPEAKER |
973
BYT_RT5640_SSP0_AIF1 |
974
BYT_RT5640_MCLK_EN),
975
},
976
{
977
/* MPMAN MPWIN895CL */
978
.matches = {
979
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MPMAN"),
980
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MPWIN8900CL"),
981
},
982
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
983
BYT_RT5640_MONO_SPEAKER |
984
BYT_RT5640_SSP0_AIF1 |
985
BYT_RT5640_MCLK_EN),
986
},
987
{ /* MSI S100 tablet */
988
.matches = {
989
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
990
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "S100"),
991
},
992
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
993
BYT_RT5640_JD_SRC_JD2_IN4N |
994
BYT_RT5640_OVCD_TH_2000UA |
995
BYT_RT5640_OVCD_SF_0P75 |
996
BYT_RT5640_MONO_SPEAKER |
997
BYT_RT5640_DIFF_MIC |
998
BYT_RT5640_MCLK_EN),
999
},
1000
{ /* Nuvison/TMax TM800W560 */
1001
.matches = {
1002
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TMAX"),
1003
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TM800W560L"),
1004
},
1005
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
1006
BYT_RT5640_JD_SRC_JD2_IN4N |
1007
BYT_RT5640_OVCD_TH_2000UA |
1008
BYT_RT5640_OVCD_SF_0P75 |
1009
BYT_RT5640_JD_NOT_INV |
1010
BYT_RT5640_DIFF_MIC |
1011
BYT_RT5640_SSP0_AIF1 |
1012
BYT_RT5640_MCLK_EN),
1013
},
1014
{ /* Onda v975w */
1015
.matches = {
1016
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
1017
DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
1018
/* The above are too generic, also match BIOS info */
1019
DMI_EXACT_MATCH(DMI_BIOS_VERSION, "5.6.5"),
1020
DMI_EXACT_MATCH(DMI_BIOS_DATE, "07/25/2014"),
1021
},
1022
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
1023
BYT_RT5640_JD_SRC_JD2_IN4N |
1024
BYT_RT5640_OVCD_TH_2000UA |
1025
BYT_RT5640_OVCD_SF_0P75 |
1026
BYT_RT5640_DIFF_MIC |
1027
BYT_RT5640_MCLK_EN),
1028
},
1029
{ /* Pipo W4 */
1030
.matches = {
1031
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
1032
DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
1033
/* The above are too generic, also match BIOS info */
1034
DMI_MATCH(DMI_BIOS_VERSION, "V8L_WIN32_CHIPHD"),
1035
},
1036
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
1037
BYT_RT5640_MONO_SPEAKER |
1038
BYT_RT5640_SSP0_AIF1 |
1039
BYT_RT5640_MCLK_EN),
1040
},
1041
{ /* Point of View Mobii TAB-P800W (V2.0) */
1042
.matches = {
1043
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
1044
DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
1045
/* The above are too generic, also match BIOS info */
1046
DMI_EXACT_MATCH(DMI_BIOS_VERSION, "3BAIR1014"),
1047
DMI_EXACT_MATCH(DMI_BIOS_DATE, "10/24/2014"),
1048
},
1049
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
1050
BYT_RT5640_JD_SRC_JD2_IN4N |
1051
BYT_RT5640_OVCD_TH_2000UA |
1052
BYT_RT5640_OVCD_SF_0P75 |
1053
BYT_RT5640_MONO_SPEAKER |
1054
BYT_RT5640_DIFF_MIC |
1055
BYT_RT5640_SSP0_AIF2 |
1056
BYT_RT5640_MCLK_EN),
1057
},
1058
{ /* Point of View Mobii TAB-P800W (V2.1) */
1059
.matches = {
1060
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
1061
DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
1062
/* The above are too generic, also match BIOS info */
1063
DMI_EXACT_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
1064
DMI_EXACT_MATCH(DMI_BIOS_DATE, "08/22/2014"),
1065
},
1066
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
1067
BYT_RT5640_JD_SRC_JD2_IN4N |
1068
BYT_RT5640_OVCD_TH_2000UA |
1069
BYT_RT5640_OVCD_SF_0P75 |
1070
BYT_RT5640_MONO_SPEAKER |
1071
BYT_RT5640_DIFF_MIC |
1072
BYT_RT5640_SSP0_AIF2 |
1073
BYT_RT5640_MCLK_EN),
1074
},
1075
{ /* Point of View Mobii TAB-P1005W-232 (V2.0) */
1076
.matches = {
1077
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "POV"),
1078
DMI_EXACT_MATCH(DMI_BOARD_NAME, "I102A"),
1079
},
1080
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
1081
BYT_RT5640_JD_SRC_JD2_IN4N |
1082
BYT_RT5640_OVCD_TH_2000UA |
1083
BYT_RT5640_OVCD_SF_0P75 |
1084
BYT_RT5640_DIFF_MIC |
1085
BYT_RT5640_SSP0_AIF1 |
1086
BYT_RT5640_MCLK_EN),
1087
},
1088
{
1089
/* Prowise PT301 */
1090
.matches = {
1091
DMI_MATCH(DMI_SYS_VENDOR, "Prowise"),
1092
DMI_MATCH(DMI_PRODUCT_NAME, "PT301"),
1093
},
1094
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
1095
BYT_RT5640_JD_SRC_JD2_IN4N |
1096
BYT_RT5640_OVCD_TH_2000UA |
1097
BYT_RT5640_OVCD_SF_0P75 |
1098
BYT_RT5640_DIFF_MIC |
1099
BYT_RT5640_SSP0_AIF1 |
1100
BYT_RT5640_MCLK_EN),
1101
},
1102
{
1103
/* Teclast X89 */
1104
.matches = {
1105
DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
1106
DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
1107
},
1108
.driver_data = (void *)(BYT_RT5640_IN3_MAP |
1109
BYT_RT5640_JD_SRC_JD1_IN4P |
1110
BYT_RT5640_OVCD_TH_2000UA |
1111
BYT_RT5640_OVCD_SF_1P0 |
1112
BYT_RT5640_SSP0_AIF1 |
1113
BYT_RT5640_MCLK_EN),
1114
},
1115
{ /* Toshiba Satellite Click Mini L9W-B */
1116
.matches = {
1117
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
1118
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"),
1119
},
1120
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
1121
BYT_RT5640_JD_SRC_JD2_IN4N |
1122
BYT_RT5640_OVCD_TH_1500UA |
1123
BYT_RT5640_OVCD_SF_0P75 |
1124
BYT_RT5640_SSP0_AIF1 |
1125
BYT_RT5640_MCLK_EN),
1126
},
1127
{ /* Toshiba Encore WT8-A */
1128
.matches = {
1129
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
1130
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TOSHIBA WT8-A"),
1131
},
1132
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
1133
BYT_RT5640_JD_SRC_JD2_IN4N |
1134
BYT_RT5640_OVCD_TH_2000UA |
1135
BYT_RT5640_OVCD_SF_0P75 |
1136
BYT_RT5640_JD_NOT_INV |
1137
BYT_RT5640_MCLK_EN),
1138
},
1139
{ /* Toshiba Encore WT10-A */
1140
.matches = {
1141
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
1142
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TOSHIBA WT10-A-103"),
1143
},
1144
.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
1145
BYT_RT5640_JD_SRC_JD1_IN4P |
1146
BYT_RT5640_OVCD_TH_2000UA |
1147
BYT_RT5640_OVCD_SF_0P75 |
1148
BYT_RT5640_SSP0_AIF2 |
1149
BYT_RT5640_MCLK_EN),
1150
},
1151
{
1152
/* Vexia Edu Atla 10 tablet 5V version */
1153
.matches = {
1154
/* Having all 3 of these not set is somewhat unique */
1155
DMI_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
1156
DMI_MATCH(DMI_PRODUCT_NAME, "To be filled by O.E.M."),
1157
DMI_MATCH(DMI_BOARD_NAME, "To be filled by O.E.M."),
1158
/* Above strings are too generic, also match on BIOS date */
1159
DMI_MATCH(DMI_BIOS_DATE, "05/14/2015"),
1160
},
1161
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
1162
BYT_RT5640_JD_NOT_INV |
1163
BYT_RT5640_SSP0_AIF1 |
1164
BYT_RT5640_MCLK_EN),
1165
},
1166
{ /* Vexia Edu Atla 10 tablet 9V version */
1167
.matches = {
1168
DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
1169
DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
1170
/* Above strings are too generic, also match on BIOS date */
1171
DMI_MATCH(DMI_BIOS_DATE, "08/25/2014"),
1172
},
1173
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
1174
BYT_RT5640_JD_SRC_JD2_IN4N |
1175
BYT_RT5640_OVCD_TH_2000UA |
1176
BYT_RT5640_OVCD_SF_0P75 |
1177
BYT_RT5640_DIFF_MIC |
1178
BYT_RT5640_SSP0_AIF2 |
1179
BYT_RT5640_MCLK_EN),
1180
},
1181
{ /* Voyo Winpad A15 */
1182
.matches = {
1183
DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
1184
DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
1185
/* Above strings are too generic, also match on BIOS date */
1186
DMI_MATCH(DMI_BIOS_DATE, "11/20/2014"),
1187
},
1188
.driver_data = (void *)(BYT_RT5640_IN1_MAP |
1189
BYT_RT5640_JD_SRC_JD2_IN4N |
1190
BYT_RT5640_OVCD_TH_2000UA |
1191
BYT_RT5640_OVCD_SF_0P75 |
1192
BYT_RT5640_DIFF_MIC |
1193
BYT_RT5640_MCLK_EN),
1194
},
1195
{ /* Catch-all for generic Insyde tablets, must be last */
1196
.matches = {
1197
DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
1198
},
1199
.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
1200
BYT_RT5640_MCLK_EN |
1201
BYT_RT5640_SSP0_AIF1),
1202
1203
},
1204
{}
1205
};
1206
1207
/*
1208
* Note this MUST be called before snd_soc_register_card(), so that the props
1209
* are in place before the codec component driver's probe function parses them.
1210
*/
1211
static int byt_rt5640_add_codec_device_props(struct device *i2c_dev,
1212
struct byt_rt5640_private *priv)
1213
{
1214
struct property_entry props[MAX_NO_PROPS] = {};
1215
struct fwnode_handle *fwnode;
1216
int cnt = 0;
1217
int ret;
1218
1219
switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
1220
case BYT_RT5640_DMIC1_MAP:
1221
props[cnt++] = PROPERTY_ENTRY_U32("realtek,dmic1-data-pin",
1222
RT5640_DMIC1_DATA_PIN_IN1P);
1223
break;
1224
case BYT_RT5640_DMIC2_MAP:
1225
props[cnt++] = PROPERTY_ENTRY_U32("realtek,dmic2-data-pin",
1226
RT5640_DMIC2_DATA_PIN_IN1N);
1227
break;
1228
case BYT_RT5640_IN1_MAP:
1229
if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
1230
props[cnt++] =
1231
PROPERTY_ENTRY_BOOL("realtek,in1-differential");
1232
break;
1233
case BYT_RT5640_IN3_MAP:
1234
if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
1235
props[cnt++] =
1236
PROPERTY_ENTRY_BOOL("realtek,in3-differential");
1237
break;
1238
}
1239
1240
if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
1241
if (BYT_RT5640_JDSRC(byt_rt5640_quirk) != RT5640_JD_SRC_EXT_GPIO) {
1242
props[cnt++] = PROPERTY_ENTRY_U32(
1243
"realtek,jack-detect-source",
1244
BYT_RT5640_JDSRC(byt_rt5640_quirk));
1245
}
1246
1247
props[cnt++] = PROPERTY_ENTRY_U32(
1248
"realtek,over-current-threshold-microamp",
1249
BYT_RT5640_OVCD_TH(byt_rt5640_quirk) * 100);
1250
1251
props[cnt++] = PROPERTY_ENTRY_U32(
1252
"realtek,over-current-scale-factor",
1253
BYT_RT5640_OVCD_SF(byt_rt5640_quirk));
1254
}
1255
1256
if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
1257
props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted");
1258
1259
fwnode = fwnode_create_software_node(props, NULL);
1260
if (IS_ERR(fwnode)) {
1261
/* put_device() is handled in caller */
1262
return PTR_ERR(fwnode);
1263
}
1264
1265
ret = device_add_software_node(i2c_dev, to_software_node(fwnode));
1266
1267
fwnode_handle_put(fwnode);
1268
1269
return ret;
1270
}
1271
1272
/* Some Android devs specify IRQs/GPIOS in a special AMCR0F28 ACPI device */
1273
static const struct acpi_gpio_params amcr0f28_jd_gpio = { 1, 0, false };
1274
1275
static const struct acpi_gpio_mapping amcr0f28_gpios[] = {
1276
{ "rt5640-jd-gpios", &amcr0f28_jd_gpio, 1 },
1277
{ }
1278
};
1279
1280
static int byt_rt5640_get_amcr0f28_settings(struct snd_soc_card *card)
1281
{
1282
struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
1283
struct rt5640_set_jack_data *data = &priv->jack_data;
1284
struct acpi_device *adev;
1285
int ret = 0;
1286
1287
adev = acpi_dev_get_first_match_dev("AMCR0F28", "1", -1);
1288
if (!adev) {
1289
dev_err(card->dev, "error cannot find AMCR0F28 adev\n");
1290
return -ENOENT;
1291
}
1292
1293
data->codec_irq_override = acpi_dev_gpio_irq_get(adev, 0);
1294
if (data->codec_irq_override < 0) {
1295
ret = data->codec_irq_override;
1296
dev_err(card->dev, "error %d getting codec IRQ\n", ret);
1297
goto put_adev;
1298
}
1299
1300
if (BYT_RT5640_JDSRC(byt_rt5640_quirk) == RT5640_JD_SRC_EXT_GPIO) {
1301
acpi_dev_add_driver_gpios(adev, amcr0f28_gpios);
1302
data->jd_gpio = devm_fwnode_gpiod_get(card->dev, acpi_fwnode_handle(adev),
1303
"rt5640-jd", GPIOD_IN, "rt5640-jd");
1304
acpi_dev_remove_driver_gpios(adev);
1305
1306
if (IS_ERR(data->jd_gpio)) {
1307
ret = PTR_ERR(data->jd_gpio);
1308
dev_err(card->dev, "error %d getting jd GPIO\n", ret);
1309
}
1310
}
1311
1312
put_adev:
1313
acpi_dev_put(adev);
1314
return ret;
1315
}
1316
1317
static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
1318
{
1319
struct snd_soc_card *card = runtime->card;
1320
struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
1321
struct rt5640_set_jack_data *jack_data = &priv->jack_data;
1322
struct snd_soc_component *component = snd_soc_rtd_to_codec(runtime, 0)->component;
1323
const struct snd_soc_dapm_route *custom_map = NULL;
1324
int num_routes = 0;
1325
int ret;
1326
1327
card->dapm.idle_bias = false;
1328
jack_data->use_platform_clock = true;
1329
1330
/* Start with RC clk for jack-detect (we disable MCLK below) */
1331
if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
1332
snd_soc_component_update_bits(component, RT5640_GLB_CLK,
1333
RT5640_SCLK_SRC_MASK, RT5640_SCLK_SRC_RCCLK);
1334
1335
rt5640_sel_asrc_clk_src(component,
1336
RT5640_DA_STEREO_FILTER |
1337
RT5640_DA_MONO_L_FILTER |
1338
RT5640_DA_MONO_R_FILTER |
1339
RT5640_AD_STEREO_FILTER |
1340
RT5640_AD_MONO_L_FILTER |
1341
RT5640_AD_MONO_R_FILTER,
1342
RT5640_CLK_SEL_ASRC);
1343
1344
ret = snd_soc_add_card_controls(card, byt_rt5640_controls,
1345
ARRAY_SIZE(byt_rt5640_controls));
1346
if (ret) {
1347
dev_err(card->dev, "unable to add card controls\n");
1348
return ret;
1349
}
1350
1351
switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
1352
case BYT_RT5640_IN1_MAP:
1353
custom_map = byt_rt5640_intmic_in1_map;
1354
num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map);
1355
break;
1356
case BYT_RT5640_IN3_MAP:
1357
custom_map = byt_rt5640_intmic_in3_map;
1358
num_routes = ARRAY_SIZE(byt_rt5640_intmic_in3_map);
1359
break;
1360
case BYT_RT5640_DMIC1_MAP:
1361
custom_map = byt_rt5640_intmic_dmic1_map;
1362
num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map);
1363
break;
1364
case BYT_RT5640_DMIC2_MAP:
1365
custom_map = byt_rt5640_intmic_dmic2_map;
1366
num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map);
1367
break;
1368
}
1369
1370
ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
1371
if (ret)
1372
return ret;
1373
1374
if (byt_rt5640_quirk & BYT_RT5640_HSMIC2_ON_IN1) {
1375
ret = snd_soc_dapm_add_routes(&card->dapm,
1376
byt_rt5640_hsmic2_in1_map,
1377
ARRAY_SIZE(byt_rt5640_hsmic2_in1_map));
1378
if (ret)
1379
return ret;
1380
}
1381
1382
if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
1383
ret = snd_soc_dapm_add_routes(&card->dapm,
1384
byt_rt5640_ssp2_aif2_map,
1385
ARRAY_SIZE(byt_rt5640_ssp2_aif2_map));
1386
} else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
1387
ret = snd_soc_dapm_add_routes(&card->dapm,
1388
byt_rt5640_ssp0_aif1_map,
1389
ARRAY_SIZE(byt_rt5640_ssp0_aif1_map));
1390
} else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
1391
ret = snd_soc_dapm_add_routes(&card->dapm,
1392
byt_rt5640_ssp0_aif2_map,
1393
ARRAY_SIZE(byt_rt5640_ssp0_aif2_map));
1394
} else {
1395
ret = snd_soc_dapm_add_routes(&card->dapm,
1396
byt_rt5640_ssp2_aif1_map,
1397
ARRAY_SIZE(byt_rt5640_ssp2_aif1_map));
1398
}
1399
if (ret)
1400
return ret;
1401
1402
if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) {
1403
ret = snd_soc_dapm_add_routes(&card->dapm,
1404
byt_rt5640_mono_spk_map,
1405
ARRAY_SIZE(byt_rt5640_mono_spk_map));
1406
} else if (!(byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS)) {
1407
ret = snd_soc_dapm_add_routes(&card->dapm,
1408
byt_rt5640_stereo_spk_map,
1409
ARRAY_SIZE(byt_rt5640_stereo_spk_map));
1410
}
1411
if (ret)
1412
return ret;
1413
1414
if (byt_rt5640_quirk & BYT_RT5640_LINEOUT) {
1415
ret = snd_soc_dapm_add_routes(&card->dapm,
1416
byt_rt5640_lineout_map,
1417
ARRAY_SIZE(byt_rt5640_lineout_map));
1418
if (ret)
1419
return ret;
1420
}
1421
1422
/*
1423
* The firmware might enable the clock at boot (this information
1424
* may or may not be reflected in the enable clock register).
1425
* To change the rate we must disable the clock first to cover
1426
* these cases. Due to common clock framework restrictions that
1427
* do not allow to disable a clock that has not been enabled,
1428
* we need to enable the clock first.
1429
*/
1430
ret = clk_prepare_enable(priv->mclk);
1431
if (!ret)
1432
clk_disable_unprepare(priv->mclk);
1433
1434
if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ)
1435
ret = clk_set_rate(priv->mclk, 25000000);
1436
else
1437
ret = clk_set_rate(priv->mclk, 19200000);
1438
if (ret) {
1439
dev_err(card->dev, "unable to set MCLK rate\n");
1440
return ret;
1441
}
1442
1443
if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
1444
ret = snd_soc_card_jack_new_pins(card, "Headset",
1445
SND_JACK_HEADSET | SND_JACK_BTN_0,
1446
&priv->jack, rt5640_pins,
1447
ARRAY_SIZE(rt5640_pins));
1448
if (ret) {
1449
dev_err(card->dev, "Jack creation failed %d\n", ret);
1450
return ret;
1451
}
1452
snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0,
1453
KEY_PLAYPAUSE);
1454
1455
if (byt_rt5640_quirk & BYT_RT5640_USE_AMCR0F28) {
1456
ret = byt_rt5640_get_amcr0f28_settings(card);
1457
if (ret)
1458
return ret;
1459
}
1460
1461
snd_soc_component_set_jack(component, &priv->jack, &priv->jack_data);
1462
}
1463
1464
if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) {
1465
ret = snd_soc_card_jack_new_pins(card, "Headset",
1466
SND_JACK_HEADSET,
1467
&priv->jack, rt5640_pins,
1468
ARRAY_SIZE(rt5640_pins));
1469
if (ret)
1470
return ret;
1471
1472
ret = snd_soc_card_jack_new_pins(card, "Headset 2",
1473
SND_JACK_HEADSET,
1474
&priv->jack2, rt5640_pins2,
1475
ARRAY_SIZE(rt5640_pins2));
1476
if (ret)
1477
return ret;
1478
1479
rt5640_jack_gpio.data = priv;
1480
rt5640_jack_gpio.gpiod_dev = priv->codec_dev;
1481
rt5640_jack_gpio.jack_status_check = byt_rt5640_hp_elitepad_1000g2_jack1_check;
1482
ret = snd_soc_jack_add_gpios(&priv->jack, 1, &rt5640_jack_gpio);
1483
if (ret)
1484
return ret;
1485
1486
rt5640_set_ovcd_params(component);
1487
rt5640_jack2_gpio.data = component;
1488
rt5640_jack2_gpio.gpiod_dev = priv->codec_dev;
1489
rt5640_jack2_gpio.jack_status_check = byt_rt5640_hp_elitepad_1000g2_jack2_check;
1490
ret = snd_soc_jack_add_gpios(&priv->jack2, 1, &rt5640_jack2_gpio);
1491
if (ret) {
1492
snd_soc_jack_free_gpios(&priv->jack, 1, &rt5640_jack_gpio);
1493
return ret;
1494
}
1495
}
1496
1497
return 0;
1498
}
1499
1500
static void byt_rt5640_exit(struct snd_soc_pcm_runtime *runtime)
1501
{
1502
struct snd_soc_card *card = runtime->card;
1503
struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
1504
1505
if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) {
1506
snd_soc_jack_free_gpios(&priv->jack2, 1, &rt5640_jack2_gpio);
1507
snd_soc_jack_free_gpios(&priv->jack, 1, &rt5640_jack_gpio);
1508
}
1509
}
1510
1511
static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd,
1512
struct snd_pcm_hw_params *params)
1513
{
1514
struct snd_interval *rate = hw_param_interval(params,
1515
SNDRV_PCM_HW_PARAM_RATE);
1516
struct snd_interval *channels = hw_param_interval(params,
1517
SNDRV_PCM_HW_PARAM_CHANNELS);
1518
int ret, bits;
1519
1520
/* The DSP will convert the FE rate to 48k, stereo */
1521
rate->min = rate->max = 48000;
1522
channels->min = channels->max = 2;
1523
1524
if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
1525
(byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
1526
/* set SSP0 to 16-bit */
1527
params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
1528
bits = 16;
1529
} else {
1530
/* set SSP2 to 24-bit */
1531
params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
1532
bits = 24;
1533
}
1534
1535
/*
1536
* Default mode for SSP configuration is TDM 4 slot, override config
1537
* with explicit setting to I2S 2ch. The word length is set with
1538
* dai_set_tdm_slot() since there is no other API exposed
1539
*/
1540
ret = snd_soc_dai_set_fmt(snd_soc_rtd_to_cpu(rtd, 0),
1541
SND_SOC_DAIFMT_I2S |
1542
SND_SOC_DAIFMT_NB_NF |
1543
SND_SOC_DAIFMT_BP_FP);
1544
if (ret < 0) {
1545
dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
1546
return ret;
1547
}
1548
1549
ret = snd_soc_dai_set_tdm_slot(snd_soc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits);
1550
if (ret < 0) {
1551
dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
1552
return ret;
1553
}
1554
1555
return 0;
1556
}
1557
1558
static int byt_rt5640_aif1_startup(struct snd_pcm_substream *substream)
1559
{
1560
return snd_pcm_hw_constraint_single(substream->runtime,
1561
SNDRV_PCM_HW_PARAM_RATE, 48000);
1562
}
1563
1564
static const struct snd_soc_ops byt_rt5640_aif1_ops = {
1565
.startup = byt_rt5640_aif1_startup,
1566
};
1567
1568
static const struct snd_soc_ops byt_rt5640_be_ssp2_ops = {
1569
.hw_params = byt_rt5640_aif1_hw_params,
1570
};
1571
1572
SND_SOC_DAILINK_DEF(dummy,
1573
DAILINK_COMP_ARRAY(COMP_DUMMY()));
1574
1575
SND_SOC_DAILINK_DEF(media,
1576
DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai")));
1577
1578
SND_SOC_DAILINK_DEF(deepbuffer,
1579
DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai")));
1580
1581
SND_SOC_DAILINK_DEF(ssp2_port,
1582
/* overwritten for ssp0 routing */
1583
DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port")));
1584
SND_SOC_DAILINK_DEF(ssp2_codec,
1585
DAILINK_COMP_ARRAY(COMP_CODEC(
1586
/* overwritten with HID */ "i2c-10EC5640:00",
1587
/* changed w/ quirk */ "rt5640-aif1")));
1588
1589
SND_SOC_DAILINK_DEF(platform,
1590
DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform")));
1591
1592
static struct snd_soc_dai_link byt_rt5640_dais[] = {
1593
[MERR_DPCM_AUDIO] = {
1594
.name = "Baytrail Audio Port",
1595
.stream_name = "Baytrail Audio",
1596
.nonatomic = true,
1597
.dynamic = 1,
1598
.ops = &byt_rt5640_aif1_ops,
1599
SND_SOC_DAILINK_REG(media, dummy, platform),
1600
},
1601
[MERR_DPCM_DEEP_BUFFER] = {
1602
.name = "Deep-Buffer Audio Port",
1603
.stream_name = "Deep-Buffer Audio",
1604
.nonatomic = true,
1605
.dynamic = 1,
1606
.playback_only = 1,
1607
.ops = &byt_rt5640_aif1_ops,
1608
SND_SOC_DAILINK_REG(deepbuffer, dummy, platform),
1609
},
1610
/* back ends */
1611
{
1612
.name = "SSP2-Codec",
1613
.id = 0,
1614
.no_pcm = 1,
1615
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
1616
| SND_SOC_DAIFMT_CBC_CFC,
1617
.be_hw_params_fixup = byt_rt5640_codec_fixup,
1618
.init = byt_rt5640_init,
1619
.exit = byt_rt5640_exit,
1620
.ops = &byt_rt5640_be_ssp2_ops,
1621
SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
1622
},
1623
};
1624
1625
/* SoC card */
1626
static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
1627
#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
1628
static char byt_rt5640_long_name[40]; /* = "bytcr-rt5640-*-spk-*-mic" */
1629
#endif
1630
static char byt_rt5640_components[64]; /* = "cfg-spk:* cfg-mic:* ..." */
1631
1632
static int byt_rt5640_suspend(struct snd_soc_card *card)
1633
{
1634
struct snd_soc_component *component;
1635
1636
if (!BYT_RT5640_JDSRC(byt_rt5640_quirk))
1637
return 0;
1638
1639
for_each_card_components(card, component) {
1640
if (!strcmp(component->name, byt_rt5640_codec_name)) {
1641
dev_dbg(component->dev, "disabling jack detect before suspend\n");
1642
snd_soc_component_set_jack(component, NULL, NULL);
1643
break;
1644
}
1645
}
1646
1647
return 0;
1648
}
1649
1650
static int byt_rt5640_resume(struct snd_soc_card *card)
1651
{
1652
struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
1653
struct snd_soc_component *component;
1654
1655
if (!BYT_RT5640_JDSRC(byt_rt5640_quirk))
1656
return 0;
1657
1658
for_each_card_components(card, component) {
1659
if (!strcmp(component->name, byt_rt5640_codec_name)) {
1660
dev_dbg(component->dev, "re-enabling jack detect after resume\n");
1661
snd_soc_component_set_jack(component, &priv->jack,
1662
&priv->jack_data);
1663
break;
1664
}
1665
}
1666
1667
return 0;
1668
}
1669
1670
/* use space before codec name to simplify card ID, and simplify driver name */
1671
#define SOF_CARD_NAME "bytcht rt5640" /* card name will be 'sof-bytcht rt5640' */
1672
#define SOF_DRIVER_NAME "SOF"
1673
1674
#define CARD_NAME "bytcr-rt5640"
1675
#define DRIVER_NAME NULL /* card name will be used for driver name */
1676
1677
static struct snd_soc_card byt_rt5640_card = {
1678
.owner = THIS_MODULE,
1679
.dai_link = byt_rt5640_dais,
1680
.num_links = ARRAY_SIZE(byt_rt5640_dais),
1681
.dapm_widgets = byt_rt5640_widgets,
1682
.num_dapm_widgets = ARRAY_SIZE(byt_rt5640_widgets),
1683
.dapm_routes = byt_rt5640_audio_map,
1684
.num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map),
1685
.fully_routed = true,
1686
.suspend_pre = byt_rt5640_suspend,
1687
.resume_post = byt_rt5640_resume,
1688
};
1689
1690
struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */
1691
u64 aif_value; /* 1: AIF1, 2: AIF2 */
1692
u64 mclock_value; /* usually 25MHz (0x17d7940), ignored */
1693
};
1694
1695
static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
1696
{
1697
struct device *dev = &pdev->dev;
1698
static const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3", "none" };
1699
struct snd_soc_acpi_mach *mach = dev_get_platdata(dev);
1700
__maybe_unused const char *spk_type;
1701
const struct dmi_system_id *dmi_id;
1702
const char *headset2_string = "";
1703
const char *lineout_string = "";
1704
struct byt_rt5640_private *priv;
1705
const char *platform_name;
1706
struct acpi_device *adev;
1707
struct device *codec_dev;
1708
const char *cfg_spk;
1709
bool sof_parent;
1710
int ret_val = 0;
1711
int dai_index = 0;
1712
int i, aif;
1713
1714
is_bytcr = false;
1715
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1716
if (!priv)
1717
return -ENOMEM;
1718
1719
/* register the soc card */
1720
byt_rt5640_card.dev = dev;
1721
snd_soc_card_set_drvdata(&byt_rt5640_card, priv);
1722
1723
/* fix index of codec dai */
1724
for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) {
1725
if (byt_rt5640_dais[i].num_codecs &&
1726
!strcmp(byt_rt5640_dais[i].codecs->name,
1727
"i2c-10EC5640:00")) {
1728
dai_index = i;
1729
break;
1730
}
1731
}
1732
1733
/* fixup codec name based on HID */
1734
adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1);
1735
if (adev) {
1736
snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
1737
"i2c-%s", acpi_dev_name(adev));
1738
byt_rt5640_dais[dai_index].codecs->name = byt_rt5640_codec_name;
1739
} else {
1740
dev_err(dev, "Error cannot find '%s' dev\n", mach->id);
1741
return -ENOENT;
1742
}
1743
1744
codec_dev = acpi_get_first_physical_node(adev);
1745
acpi_dev_put(adev);
1746
1747
if (codec_dev) {
1748
priv->codec_dev = get_device(codec_dev);
1749
} else {
1750
/*
1751
* Special case for Android tablets where the codec i2c_client
1752
* has been manually instantiated by x86_android_tablets.ko due
1753
* to a broken DSDT.
1754
*/
1755
codec_dev = bus_find_device_by_name(&i2c_bus_type, NULL,
1756
BYT_RT5640_FALLBACK_CODEC_DEV_NAME);
1757
if (!codec_dev)
1758
return -EPROBE_DEFER;
1759
1760
if (!i2c_verify_client(codec_dev)) {
1761
dev_err(dev, "Error '%s' is not an i2c_client\n",
1762
BYT_RT5640_FALLBACK_CODEC_DEV_NAME);
1763
put_device(codec_dev);
1764
}
1765
1766
/* fixup codec name */
1767
strscpy(byt_rt5640_codec_name, BYT_RT5640_FALLBACK_CODEC_DEV_NAME,
1768
sizeof(byt_rt5640_codec_name));
1769
1770
/* bus_find_device() returns a reference no need to get() */
1771
priv->codec_dev = codec_dev;
1772
}
1773
1774
/*
1775
* swap SSP0 if bytcr is detected
1776
* (will be overridden if DMI quirk is detected)
1777
*/
1778
if (soc_intel_is_byt()) {
1779
if (mach->mach_params.acpi_ipc_irq_index == 0)
1780
is_bytcr = true;
1781
}
1782
1783
if (is_bytcr) {
1784
/*
1785
* Baytrail CR platforms may have CHAN package in BIOS, try
1786
* to find relevant routing quirk based as done on Windows
1787
* platforms. We have to read the information directly from the
1788
* BIOS, at this stage the card is not created and the links
1789
* with the codec driver/pdata are non-existent
1790
*/
1791
1792
struct acpi_chan_package chan_package = { 0 };
1793
1794
/* format specified: 2 64-bit integers */
1795
struct acpi_buffer format = {sizeof("NN"), "NN"};
1796
struct acpi_buffer state = {0, NULL};
1797
struct snd_soc_acpi_package_context pkg_ctx;
1798
bool pkg_found = false;
1799
1800
state.length = sizeof(chan_package);
1801
state.pointer = &chan_package;
1802
1803
pkg_ctx.name = "CHAN";
1804
pkg_ctx.length = 2;
1805
pkg_ctx.format = &format;
1806
pkg_ctx.state = &state;
1807
pkg_ctx.data_valid = false;
1808
1809
pkg_found = snd_soc_acpi_find_package_from_hid(mach->id,
1810
&pkg_ctx);
1811
if (pkg_found) {
1812
if (chan_package.aif_value == 1) {
1813
dev_info(dev, "BIOS Routing: AIF1 connected\n");
1814
byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF1;
1815
} else if (chan_package.aif_value == 2) {
1816
dev_info(dev, "BIOS Routing: AIF2 connected\n");
1817
byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
1818
} else {
1819
dev_info(dev, "BIOS Routing isn't valid, ignored\n");
1820
pkg_found = false;
1821
}
1822
}
1823
1824
if (!pkg_found) {
1825
/* no BIOS indications, assume SSP0-AIF2 connection */
1826
byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
1827
}
1828
1829
/* change defaults for Baytrail-CR capture */
1830
byt_rt5640_quirk |= BYTCR_INPUT_DEFAULTS;
1831
} else {
1832
byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP |
1833
BYT_RT5640_JD_SRC_JD2_IN4N |
1834
BYT_RT5640_OVCD_TH_2000UA |
1835
BYT_RT5640_OVCD_SF_0P75;
1836
}
1837
1838
/* check quirks before creating card */
1839
dmi_id = dmi_first_match(byt_rt5640_quirk_table);
1840
if (dmi_id)
1841
byt_rt5640_quirk = (unsigned long)dmi_id->driver_data;
1842
if (quirk_override != -1) {
1843
dev_info(dev, "Overriding quirk 0x%lx => 0x%x\n",
1844
byt_rt5640_quirk, quirk_override);
1845
byt_rt5640_quirk = quirk_override;
1846
}
1847
1848
if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) {
1849
acpi_dev_add_driver_gpios(ACPI_COMPANION(priv->codec_dev),
1850
byt_rt5640_hp_elitepad_1000g2_gpios);
1851
1852
priv->hsmic_detect = devm_fwnode_gpiod_get(dev, codec_dev->fwnode,
1853
"headset-mic-detect", GPIOD_IN,
1854
"headset-mic-detect");
1855
if (IS_ERR(priv->hsmic_detect)) {
1856
ret_val = dev_err_probe(dev, PTR_ERR(priv->hsmic_detect),
1857
"getting hsmic-detect GPIO\n");
1858
goto err_device;
1859
}
1860
}
1861
1862
/* Must be called before register_card, also see declaration comment. */
1863
ret_val = byt_rt5640_add_codec_device_props(codec_dev, priv);
1864
if (ret_val)
1865
goto err_remove_gpios;
1866
1867
log_quirks(dev);
1868
1869
if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) ||
1870
(byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
1871
byt_rt5640_dais[dai_index].codecs->dai_name = "rt5640-aif2";
1872
aif = 2;
1873
} else {
1874
aif = 1;
1875
}
1876
1877
if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
1878
(byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2))
1879
byt_rt5640_dais[dai_index].cpus->dai_name = "ssp0-port";
1880
1881
if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
1882
priv->mclk = devm_clk_get_optional(dev, "pmc_plt_clk_3");
1883
if (IS_ERR(priv->mclk)) {
1884
ret_val = dev_err_probe(dev, PTR_ERR(priv->mclk),
1885
"Failed to get MCLK from pmc_plt_clk_3\n");
1886
goto err;
1887
}
1888
/*
1889
* Fall back to bit clock usage when clock is not
1890
* available likely due to missing dependencies.
1891
*/
1892
if (!priv->mclk)
1893
byt_rt5640_quirk &= ~BYT_RT5640_MCLK_EN;
1894
}
1895
1896
if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS) {
1897
cfg_spk = "0";
1898
spk_type = "none";
1899
} else if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) {
1900
cfg_spk = "1";
1901
spk_type = "mono";
1902
} else if (byt_rt5640_quirk & BYT_RT5640_SWAPPED_SPEAKERS) {
1903
cfg_spk = "swapped";
1904
spk_type = "swapped";
1905
} else {
1906
cfg_spk = "2";
1907
spk_type = "stereo";
1908
}
1909
1910
if (byt_rt5640_quirk & BYT_RT5640_LINEOUT) {
1911
if (byt_rt5640_quirk & BYT_RT5640_LINEOUT_AS_HP2)
1912
lineout_string = " cfg-hp2:lineout";
1913
else
1914
lineout_string = " cfg-lineout:2";
1915
}
1916
1917
if (byt_rt5640_quirk & BYT_RT5640_HSMIC2_ON_IN1)
1918
headset2_string = " cfg-hs2:in1";
1919
1920
snprintf(byt_rt5640_components, sizeof(byt_rt5640_components),
1921
"cfg-spk:%s cfg-mic:%s aif:%d%s%s", cfg_spk,
1922
map_name[BYT_RT5640_MAP(byt_rt5640_quirk)], aif,
1923
lineout_string, headset2_string);
1924
byt_rt5640_card.components = byt_rt5640_components;
1925
#if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
1926
snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name),
1927
"bytcr-rt5640-%s-spk-%s-mic", spk_type,
1928
map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]);
1929
byt_rt5640_card.long_name = byt_rt5640_long_name;
1930
#endif
1931
1932
/* override platform name, if required */
1933
platform_name = mach->mach_params.platform;
1934
1935
ret_val = snd_soc_fixup_dai_links_platform_name(&byt_rt5640_card,
1936
platform_name);
1937
if (ret_val)
1938
goto err;
1939
1940
sof_parent = snd_soc_acpi_sof_parent(dev);
1941
1942
/* set card and driver name */
1943
if (sof_parent) {
1944
byt_rt5640_card.name = SOF_CARD_NAME;
1945
byt_rt5640_card.driver_name = SOF_DRIVER_NAME;
1946
} else {
1947
byt_rt5640_card.name = CARD_NAME;
1948
byt_rt5640_card.driver_name = DRIVER_NAME;
1949
}
1950
1951
/* set pm ops */
1952
if (sof_parent)
1953
dev->driver->pm = &snd_soc_pm_ops;
1954
1955
ret_val = devm_snd_soc_register_card(dev, &byt_rt5640_card);
1956
if (ret_val) {
1957
dev_err(dev, "devm_snd_soc_register_card failed %d\n", ret_val);
1958
goto err;
1959
}
1960
platform_set_drvdata(pdev, &byt_rt5640_card);
1961
return ret_val;
1962
1963
err:
1964
device_remove_software_node(priv->codec_dev);
1965
err_remove_gpios:
1966
if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2)
1967
acpi_dev_remove_driver_gpios(ACPI_COMPANION(priv->codec_dev));
1968
err_device:
1969
put_device(priv->codec_dev);
1970
return ret_val;
1971
}
1972
1973
static void snd_byt_rt5640_mc_remove(struct platform_device *pdev)
1974
{
1975
struct snd_soc_card *card = platform_get_drvdata(pdev);
1976
struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
1977
1978
if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2)
1979
acpi_dev_remove_driver_gpios(ACPI_COMPANION(priv->codec_dev));
1980
1981
device_remove_software_node(priv->codec_dev);
1982
put_device(priv->codec_dev);
1983
}
1984
1985
static struct platform_driver snd_byt_rt5640_mc_driver = {
1986
.driver = {
1987
.name = "bytcr_rt5640",
1988
},
1989
.probe = snd_byt_rt5640_mc_probe,
1990
.remove = snd_byt_rt5640_mc_remove,
1991
};
1992
1993
module_platform_driver(snd_byt_rt5640_mc_driver);
1994
1995
MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver");
1996
MODULE_AUTHOR("Subhransu S. Prusty <[email protected]>");
1997
MODULE_LICENSE("GPL v2");
1998
MODULE_ALIAS("platform:bytcr_rt5640");
1999
2000