1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <linux/i2c.h>
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/platform_device.h>
25#include <linux/acpi.h>
26#include <linux/clk.h>
27#include <linux/device.h>
28#include <linux/dmi.h>
29#include <linux/input.h>
30#include <linux/slab.h>
31#include <asm/cpu_device_id.h>
32#include <asm/platform_sst_audio.h>
33#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/soc.h>
36#include <sound/jack.h>
37#include <sound/soc-acpi.h>
38#include <dt-bindings/sound/rt5640.h>
39#include "../../codecs/rt5640.h"
40#include "../atom/sst-atom-controls.h"
41#include "../common/sst-dsp.h"
42
43enum {
44 BYT_RT5640_DMIC1_MAP,
45 BYT_RT5640_DMIC2_MAP,
46 BYT_RT5640_IN1_MAP,
47 BYT_RT5640_IN3_MAP,
48};
49
50enum {
51 BYT_RT5640_JD_SRC_GPIO1 = (RT5640_JD_SRC_GPIO1 << 4),
52 BYT_RT5640_JD_SRC_JD1_IN4P = (RT5640_JD_SRC_JD1_IN4P << 4),
53 BYT_RT5640_JD_SRC_JD2_IN4N = (RT5640_JD_SRC_JD2_IN4N << 4),
54 BYT_RT5640_JD_SRC_GPIO2 = (RT5640_JD_SRC_GPIO2 << 4),
55 BYT_RT5640_JD_SRC_GPIO3 = (RT5640_JD_SRC_GPIO3 << 4),
56 BYT_RT5640_JD_SRC_GPIO4 = (RT5640_JD_SRC_GPIO4 << 4),
57};
58
59enum {
60 BYT_RT5640_OVCD_TH_600UA = (6 << 8),
61 BYT_RT5640_OVCD_TH_1500UA = (15 << 8),
62 BYT_RT5640_OVCD_TH_2000UA = (20 << 8),
63};
64
65enum {
66 BYT_RT5640_OVCD_SF_0P5 = (RT5640_OVCD_SF_0P5 << 13),
67 BYT_RT5640_OVCD_SF_0P75 = (RT5640_OVCD_SF_0P75 << 13),
68 BYT_RT5640_OVCD_SF_1P0 = (RT5640_OVCD_SF_1P0 << 13),
69 BYT_RT5640_OVCD_SF_1P5 = (RT5640_OVCD_SF_1P5 << 13),
70};
71
72#define BYT_RT5640_MAP(quirk) ((quirk) & GENMASK(3, 0))
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)
79#define BYT_RT5640_SSP2_AIF2 BIT(19)
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
85#define BYTCR_INPUT_DEFAULTS \
86 (BYT_RT5640_IN3_MAP | \
87 BYT_RT5640_JD_SRC_JD1_IN4P | \
88 BYT_RT5640_OVCD_TH_2000UA | \
89 BYT_RT5640_OVCD_SF_0P75 | \
90 BYT_RT5640_DIFF_MIC)
91
92
93#define MAX_NO_PROPS 6
94
95struct byt_rt5640_private {
96 struct snd_soc_jack jack;
97 struct clk *mclk;
98};
99static bool is_bytcr;
100
101static unsigned long byt_rt5640_quirk = BYT_RT5640_MCLK_EN;
102static unsigned int quirk_override;
103module_param_named(quirk, quirk_override, uint, 0444);
104MODULE_PARM_DESC(quirk, "Board-specific quirk override");
105
106static void log_quirks(struct device *dev)
107{
108 int map;
109 bool has_mclk = false;
110 bool has_ssp0 = false;
111 bool has_ssp0_aif1 = false;
112 bool has_ssp0_aif2 = false;
113 bool has_ssp2_aif2 = false;
114
115 map = BYT_RT5640_MAP(byt_rt5640_quirk);
116 switch (map) {
117 case BYT_RT5640_DMIC1_MAP:
118 dev_info(dev, "quirk DMIC1_MAP enabled\n");
119 break;
120 case BYT_RT5640_DMIC2_MAP:
121 dev_info(dev, "quirk DMIC2_MAP enabled\n");
122 break;
123 case BYT_RT5640_IN1_MAP:
124 dev_info(dev, "quirk IN1_MAP enabled\n");
125 break;
126 case BYT_RT5640_IN3_MAP:
127 dev_info(dev, "quirk IN3_MAP enabled\n");
128 break;
129 default:
130 dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map);
131 break;
132 }
133 if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
134 dev_info(dev, "quirk realtek,jack-detect-source %ld\n",
135 BYT_RT5640_JDSRC(byt_rt5640_quirk));
136 dev_info(dev, "quirk realtek,over-current-threshold-microamp %ld\n",
137 BYT_RT5640_OVCD_TH(byt_rt5640_quirk) * 100);
138 dev_info(dev, "quirk realtek,over-current-scale-factor %ld\n",
139 BYT_RT5640_OVCD_SF(byt_rt5640_quirk));
140 }
141 if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
142 dev_info(dev, "quirk JD_NOT_INV enabled\n");
143 if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER)
144 dev_info(dev, "quirk MONO_SPEAKER enabled\n");
145 if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
146 dev_info(dev, "quirk DIFF_MIC enabled\n");
147 if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
148 dev_info(dev, "quirk SSP0_AIF1 enabled\n");
149 has_ssp0 = true;
150 has_ssp0_aif1 = true;
151 }
152 if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
153 dev_info(dev, "quirk SSP0_AIF2 enabled\n");
154 has_ssp0 = true;
155 has_ssp0_aif2 = true;
156 }
157 if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
158 dev_info(dev, "quirk SSP2_AIF2 enabled\n");
159 has_ssp2_aif2 = true;
160 }
161 if (is_bytcr && !has_ssp0)
162 dev_err(dev, "Invalid routing, bytcr detected but no SSP0-based quirk, audio cannot work with SSP2 on bytcr\n");
163 if (has_ssp0_aif1 && has_ssp0_aif2)
164 dev_err(dev, "Invalid routing, SSP0 cannot be connected to both AIF1 and AIF2\n");
165 if (has_ssp0 && has_ssp2_aif2)
166 dev_err(dev, "Invalid routing, cannot have both SSP0 and SSP2 connected to codec\n");
167
168 if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
169 dev_info(dev, "quirk MCLK_EN enabled\n");
170 has_mclk = true;
171 }
172 if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
173 if (has_mclk)
174 dev_info(dev, "quirk MCLK_25MHZ enabled\n");
175 else
176 dev_err(dev, "quirk MCLK_25MHZ enabled but quirk MCLK not selected, will be ignored\n");
177 }
178}
179
180static int byt_rt5640_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai,
181 int rate)
182{
183 int ret;
184
185
186 if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
187
188 if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
189 (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
190
191 ret = snd_soc_dai_set_pll(codec_dai, 0,
192 RT5640_PLL1_S_BCLK1,
193 rate * 32, rate * 512);
194 } else {
195
196 ret = snd_soc_dai_set_pll(codec_dai, 0,
197 RT5640_PLL1_S_BCLK1,
198 rate * 50, rate * 512);
199 }
200 } else {
201 if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
202 ret = snd_soc_dai_set_pll(codec_dai, 0,
203 RT5640_PLL1_S_MCLK,
204 25000000, rate * 512);
205 } else {
206 ret = snd_soc_dai_set_pll(codec_dai, 0,
207 RT5640_PLL1_S_MCLK,
208 19200000, rate * 512);
209 }
210 }
211
212 if (ret < 0) {
213 dev_err(codec_dai->component->dev, "can't set pll: %d\n", ret);
214 return ret;
215 }
216
217 ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
218 rate * 512, SND_SOC_CLOCK_IN);
219 if (ret < 0) {
220 dev_err(codec_dai->component->dev, "can't set clock %d\n", ret);
221 return ret;
222 }
223
224 return 0;
225}
226
227#define BYT_CODEC_DAI1 "rt5640-aif1"
228#define BYT_CODEC_DAI2 "rt5640-aif2"
229
230static int platform_clock_control(struct snd_soc_dapm_widget *w,
231 struct snd_kcontrol *k, int event)
232{
233 struct snd_soc_dapm_context *dapm = w->dapm;
234 struct snd_soc_card *card = dapm->card;
235 struct snd_soc_dai *codec_dai;
236 struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
237 int ret;
238
239 codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1);
240 if (!codec_dai)
241 codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI2);
242
243 if (!codec_dai) {
244 dev_err(card->dev,
245 "Codec dai not found; Unable to set platform clock\n");
246 return -EIO;
247 }
248
249 if (SND_SOC_DAPM_EVENT_ON(event)) {
250 if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
251 ret = clk_prepare_enable(priv->mclk);
252 if (ret < 0) {
253 dev_err(card->dev,
254 "could not configure MCLK state\n");
255 return ret;
256 }
257 }
258 ret = byt_rt5640_prepare_and_enable_pll1(codec_dai, 48000);
259 } else {
260
261
262
263
264
265 ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_RCCLK,
266 48000 * 512,
267 SND_SOC_CLOCK_IN);
268 if (!ret) {
269 if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
270 clk_disable_unprepare(priv->mclk);
271 }
272 }
273
274 if (ret < 0) {
275 dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
276 return ret;
277 }
278
279 return 0;
280}
281
282static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
283 SND_SOC_DAPM_HP("Headphone", NULL),
284 SND_SOC_DAPM_MIC("Headset Mic", NULL),
285 SND_SOC_DAPM_MIC("Internal Mic", NULL),
286 SND_SOC_DAPM_SPK("Speaker", NULL),
287 SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
288 platform_clock_control, SND_SOC_DAPM_PRE_PMU |
289 SND_SOC_DAPM_POST_PMD),
290
291};
292
293static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
294 {"Headphone", NULL, "Platform Clock"},
295 {"Headset Mic", NULL, "Platform Clock"},
296 {"Internal Mic", NULL, "Platform Clock"},
297 {"Speaker", NULL, "Platform Clock"},
298
299 {"Headset Mic", NULL, "MICBIAS1"},
300 {"IN2P", NULL, "Headset Mic"},
301 {"Headphone", NULL, "HPOL"},
302 {"Headphone", NULL, "HPOR"},
303};
304
305static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = {
306 {"DMIC1", NULL, "Internal Mic"},
307};
308
309static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic2_map[] = {
310 {"DMIC2", NULL, "Internal Mic"},
311};
312
313static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = {
314 {"Internal Mic", NULL, "MICBIAS1"},
315 {"IN1P", NULL, "Internal Mic"},
316};
317
318static const struct snd_soc_dapm_route byt_rt5640_intmic_in3_map[] = {
319 {"Internal Mic", NULL, "MICBIAS1"},
320 {"IN3P", NULL, "Internal Mic"},
321};
322
323static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif1_map[] = {
324 {"ssp2 Tx", NULL, "codec_out0"},
325 {"ssp2 Tx", NULL, "codec_out1"},
326 {"codec_in0", NULL, "ssp2 Rx"},
327 {"codec_in1", NULL, "ssp2 Rx"},
328
329 {"AIF1 Playback", NULL, "ssp2 Tx"},
330 {"ssp2 Rx", NULL, "AIF1 Capture"},
331};
332
333static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif2_map[] = {
334 {"ssp2 Tx", NULL, "codec_out0"},
335 {"ssp2 Tx", NULL, "codec_out1"},
336 {"codec_in0", NULL, "ssp2 Rx"},
337 {"codec_in1", NULL, "ssp2 Rx"},
338
339 {"AIF2 Playback", NULL, "ssp2 Tx"},
340 {"ssp2 Rx", NULL, "AIF2 Capture"},
341};
342
343static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif1_map[] = {
344 {"ssp0 Tx", NULL, "modem_out"},
345 {"modem_in", NULL, "ssp0 Rx"},
346
347 {"AIF1 Playback", NULL, "ssp0 Tx"},
348 {"ssp0 Rx", NULL, "AIF1 Capture"},
349};
350
351static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif2_map[] = {
352 {"ssp0 Tx", NULL, "modem_out"},
353 {"modem_in", NULL, "ssp0 Rx"},
354
355 {"AIF2 Playback", NULL, "ssp0 Tx"},
356 {"ssp0 Rx", NULL, "AIF2 Capture"},
357};
358
359static const struct snd_soc_dapm_route byt_rt5640_stereo_spk_map[] = {
360 {"Speaker", NULL, "SPOLP"},
361 {"Speaker", NULL, "SPOLN"},
362 {"Speaker", NULL, "SPORP"},
363 {"Speaker", NULL, "SPORN"},
364};
365
366static const struct snd_soc_dapm_route byt_rt5640_mono_spk_map[] = {
367 {"Speaker", NULL, "SPOLP"},
368 {"Speaker", NULL, "SPOLN"},
369};
370
371static const struct snd_kcontrol_new byt_rt5640_controls[] = {
372 SOC_DAPM_PIN_SWITCH("Headphone"),
373 SOC_DAPM_PIN_SWITCH("Headset Mic"),
374 SOC_DAPM_PIN_SWITCH("Internal Mic"),
375 SOC_DAPM_PIN_SWITCH("Speaker"),
376};
377
378static struct snd_soc_jack_pin rt5640_pins[] = {
379 {
380 .pin = "Headphone",
381 .mask = SND_JACK_HEADPHONE,
382 },
383 {
384 .pin = "Headset Mic",
385 .mask = SND_JACK_MICROPHONE,
386 },
387};
388
389static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
390 struct snd_pcm_hw_params *params)
391{
392 struct snd_soc_pcm_runtime *rtd = substream->private_data;
393 struct snd_soc_dai *dai = rtd->codec_dai;
394
395 return byt_rt5640_prepare_and_enable_pll1(dai, params_rate(params));
396}
397
398
399static const struct dmi_system_id byt_rt5640_quirk_table[] = {
400 {
401 .matches = {
402 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
403 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Iconia W1-810"),
404 },
405 .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
406 BYT_RT5640_JD_SRC_JD1_IN4P |
407 BYT_RT5640_OVCD_TH_2000UA |
408 BYT_RT5640_OVCD_SF_0P75 |
409 BYT_RT5640_SSP0_AIF1 |
410 BYT_RT5640_MCLK_EN),
411 },
412 {
413 .matches = {
414 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
415 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
416 },
417 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
418 BYT_RT5640_MCLK_EN |
419 BYT_RT5640_SSP0_AIF1),
420
421 },
422 {
423 .matches = {
424 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"),
425 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 80 Cesium"),
426 },
427 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
428 BYT_RT5640_MONO_SPEAKER |
429 BYT_RT5640_SSP0_AIF1 |
430 BYT_RT5640_MCLK_EN),
431 },
432 {
433 .matches = {
434 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
435 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
436 },
437 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
438 BYT_RT5640_JD_SRC_JD2_IN4N |
439 BYT_RT5640_OVCD_TH_2000UA |
440 BYT_RT5640_OVCD_SF_0P75 |
441 BYT_RT5640_MCLK_EN),
442 },
443 {
444 .matches = {
445 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
446 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
447 },
448 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
449 BYT_RT5640_MONO_SPEAKER |
450 BYT_RT5640_DIFF_MIC |
451 BYT_RT5640_SSP0_AIF2 |
452 BYT_RT5640_MCLK_EN),
453 },
454 {
455 .matches = {
456 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
457 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "i86"),
458
459 DMI_MATCH(DMI_BIOS_VERSION, "CHUWI.D86JLBNR"),
460 },
461 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
462 BYT_RT5640_MONO_SPEAKER |
463 BYT_RT5640_SSP0_AIF1 |
464 BYT_RT5640_MCLK_EN),
465 },
466 {
467 .matches = {
468 DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
469 DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
470 },
471 .driver_data = (void *)(BYT_RT5640_DMIC1_MAP),
472 },
473 {
474 .matches = {
475 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
476 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
477 },
478 .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
479 BYT_RT5640_JD_SRC_JD2_IN4N |
480 BYT_RT5640_OVCD_TH_2000UA |
481 BYT_RT5640_OVCD_SF_0P75 |
482 BYT_RT5640_MONO_SPEAKER |
483 BYT_RT5640_MCLK_EN),
484 },
485 {
486 .matches = {
487 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
488 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
489 },
490 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
491 BYT_RT5640_MCLK_EN),
492 },
493 {
494 .matches = {
495 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
496 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
497 },
498 .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
499 BYT_RT5640_JD_SRC_JD2_IN4N |
500 BYT_RT5640_OVCD_TH_1500UA |
501 BYT_RT5640_OVCD_SF_0P75 |
502 BYT_RT5640_SSP0_AIF1 |
503 BYT_RT5640_MCLK_EN),
504 },
505 {
506 .matches = {
507 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
508 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Stream 7 Tablet"),
509 },
510 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
511 BYT_RT5640_MONO_SPEAKER |
512 BYT_RT5640_JD_NOT_INV |
513 BYT_RT5640_SSP0_AIF1 |
514 BYT_RT5640_MCLK_EN),
515 },
516 {
517 .matches = {
518 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
519 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"),
520 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."),
521 DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"),
522 },
523 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
524 BYT_RT5640_MONO_SPEAKER |
525 BYT_RT5640_SSP0_AIF1 |
526 BYT_RT5640_MCLK_EN),
527 },
528 {
529 .matches = {
530 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Lamina"),
531 DMI_EXACT_MATCH(DMI_BOARD_NAME, "T701BR.SE"),
532 },
533 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
534 BYT_RT5640_MONO_SPEAKER |
535 BYT_RT5640_JD_NOT_INV |
536 BYT_RT5640_SSP0_AIF1 |
537 BYT_RT5640_MCLK_EN),
538 },
539 {
540 .matches = {
541 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
542 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "S100"),
543 },
544 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
545 BYT_RT5640_JD_SRC_JD2_IN4N |
546 BYT_RT5640_OVCD_TH_2000UA |
547 BYT_RT5640_OVCD_SF_0P75 |
548 BYT_RT5640_MONO_SPEAKER |
549 BYT_RT5640_DIFF_MIC |
550 BYT_RT5640_MCLK_EN),
551 },
552 {
553 .matches = {
554 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
555 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
556
557 DMI_MATCH(DMI_BIOS_VERSION, "V8L_WIN32_CHIPHD"),
558 },
559 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
560 BYT_RT5640_MONO_SPEAKER |
561 BYT_RT5640_SSP0_AIF1 |
562 BYT_RT5640_MCLK_EN),
563 },
564 {
565 .matches = {
566 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
567 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
568
569 DMI_EXACT_MATCH(DMI_BIOS_VERSION, "3BAIR1014"),
570 DMI_EXACT_MATCH(DMI_BIOS_DATE, "10/24/2014"),
571 },
572 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
573 BYT_RT5640_JD_SRC_JD2_IN4N |
574 BYT_RT5640_OVCD_TH_2000UA |
575 BYT_RT5640_OVCD_SF_0P75 |
576 BYT_RT5640_MONO_SPEAKER |
577 BYT_RT5640_DIFF_MIC |
578 BYT_RT5640_SSP0_AIF2 |
579 BYT_RT5640_MCLK_EN),
580 },
581 {
582 .matches = {
583 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
584 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
585
586 DMI_EXACT_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
587 DMI_EXACT_MATCH(DMI_BIOS_DATE, "08/22/2014"),
588 },
589 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
590 BYT_RT5640_JD_SRC_JD2_IN4N |
591 BYT_RT5640_OVCD_TH_2000UA |
592 BYT_RT5640_OVCD_SF_0P75 |
593 BYT_RT5640_MONO_SPEAKER |
594 BYT_RT5640_DIFF_MIC |
595 BYT_RT5640_SSP0_AIF2 |
596 BYT_RT5640_MCLK_EN),
597 },
598 {
599 .matches = {
600 DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
601 DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
602 },
603 .driver_data = (void *)(BYT_RT5640_IN3_MAP |
604 BYT_RT5640_MCLK_EN |
605 BYT_RT5640_SSP0_AIF1),
606 },
607 {
608 .matches = {
609 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
610 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"),
611 },
612 .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
613 BYT_RT5640_JD_SRC_JD2_IN4N |
614 BYT_RT5640_OVCD_TH_1500UA |
615 BYT_RT5640_OVCD_SF_0P75 |
616 BYT_RT5640_SSP0_AIF1 |
617 BYT_RT5640_MCLK_EN),
618 },
619 {
620 .matches = {
621 DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
622 },
623 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
624 BYT_RT5640_MCLK_EN |
625 BYT_RT5640_SSP0_AIF1),
626
627 },
628 {}
629};
630
631
632
633
634
635static int byt_rt5640_add_codec_device_props(const char *i2c_dev_name)
636{
637 struct property_entry props[MAX_NO_PROPS] = {};
638 struct device *i2c_dev;
639 int ret, cnt = 0;
640
641 i2c_dev = bus_find_device_by_name(&i2c_bus_type, NULL, i2c_dev_name);
642 if (!i2c_dev)
643 return -EPROBE_DEFER;
644
645 switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
646 case BYT_RT5640_DMIC1_MAP:
647 props[cnt++] = PROPERTY_ENTRY_U32("realtek,dmic1-data-pin",
648 RT5640_DMIC1_DATA_PIN_IN1P);
649 break;
650 case BYT_RT5640_DMIC2_MAP:
651 props[cnt++] = PROPERTY_ENTRY_U32("realtek,dmic2-data-pin",
652 RT5640_DMIC2_DATA_PIN_IN1N);
653 break;
654 case BYT_RT5640_IN1_MAP:
655 if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
656 props[cnt++] =
657 PROPERTY_ENTRY_BOOL("realtek,in1-differential");
658 break;
659 case BYT_RT5640_IN3_MAP:
660 if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
661 props[cnt++] =
662 PROPERTY_ENTRY_BOOL("realtek,in3-differential");
663 break;
664 }
665
666 if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
667 props[cnt++] = PROPERTY_ENTRY_U32(
668 "realtek,jack-detect-source",
669 BYT_RT5640_JDSRC(byt_rt5640_quirk));
670
671 props[cnt++] = PROPERTY_ENTRY_U32(
672 "realtek,over-current-threshold-microamp",
673 BYT_RT5640_OVCD_TH(byt_rt5640_quirk) * 100);
674
675 props[cnt++] = PROPERTY_ENTRY_U32(
676 "realtek,over-current-scale-factor",
677 BYT_RT5640_OVCD_SF(byt_rt5640_quirk));
678 }
679
680 if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
681 props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted");
682
683 ret = device_add_properties(i2c_dev, props);
684 put_device(i2c_dev);
685
686 return ret;
687}
688
689static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
690{
691 struct snd_soc_card *card = runtime->card;
692 struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
693 struct snd_soc_component *component = runtime->codec_dai->component;
694 const struct snd_soc_dapm_route *custom_map;
695 int num_routes;
696 int ret;
697
698 card->dapm.idle_bias_off = true;
699
700
701 if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
702 snd_soc_component_update_bits(component, RT5640_GLB_CLK,
703 RT5640_SCLK_SRC_MASK, RT5640_SCLK_SRC_RCCLK);
704
705 rt5640_sel_asrc_clk_src(component,
706 RT5640_DA_STEREO_FILTER |
707 RT5640_DA_MONO_L_FILTER |
708 RT5640_DA_MONO_R_FILTER |
709 RT5640_AD_STEREO_FILTER |
710 RT5640_AD_MONO_L_FILTER |
711 RT5640_AD_MONO_R_FILTER,
712 RT5640_CLK_SEL_ASRC);
713
714 ret = snd_soc_add_card_controls(card, byt_rt5640_controls,
715 ARRAY_SIZE(byt_rt5640_controls));
716 if (ret) {
717 dev_err(card->dev, "unable to add card controls\n");
718 return ret;
719 }
720
721 switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
722 case BYT_RT5640_IN1_MAP:
723 custom_map = byt_rt5640_intmic_in1_map;
724 num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map);
725 break;
726 case BYT_RT5640_IN3_MAP:
727 custom_map = byt_rt5640_intmic_in3_map;
728 num_routes = ARRAY_SIZE(byt_rt5640_intmic_in3_map);
729 break;
730 case BYT_RT5640_DMIC2_MAP:
731 custom_map = byt_rt5640_intmic_dmic2_map;
732 num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map);
733 break;
734 default:
735 custom_map = byt_rt5640_intmic_dmic1_map;
736 num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map);
737 }
738
739 ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
740 if (ret)
741 return ret;
742
743 if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
744 ret = snd_soc_dapm_add_routes(&card->dapm,
745 byt_rt5640_ssp2_aif2_map,
746 ARRAY_SIZE(byt_rt5640_ssp2_aif2_map));
747 } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
748 ret = snd_soc_dapm_add_routes(&card->dapm,
749 byt_rt5640_ssp0_aif1_map,
750 ARRAY_SIZE(byt_rt5640_ssp0_aif1_map));
751 } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
752 ret = snd_soc_dapm_add_routes(&card->dapm,
753 byt_rt5640_ssp0_aif2_map,
754 ARRAY_SIZE(byt_rt5640_ssp0_aif2_map));
755 } else {
756 ret = snd_soc_dapm_add_routes(&card->dapm,
757 byt_rt5640_ssp2_aif1_map,
758 ARRAY_SIZE(byt_rt5640_ssp2_aif1_map));
759 }
760 if (ret)
761 return ret;
762
763 if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) {
764 ret = snd_soc_dapm_add_routes(&card->dapm,
765 byt_rt5640_mono_spk_map,
766 ARRAY_SIZE(byt_rt5640_mono_spk_map));
767 } else {
768 ret = snd_soc_dapm_add_routes(&card->dapm,
769 byt_rt5640_stereo_spk_map,
770 ARRAY_SIZE(byt_rt5640_stereo_spk_map));
771 }
772 if (ret)
773 return ret;
774
775 snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
776 snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
777
778 if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
779
780
781
782
783
784
785
786
787
788
789 ret = clk_prepare_enable(priv->mclk);
790 if (!ret)
791 clk_disable_unprepare(priv->mclk);
792
793 if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ)
794 ret = clk_set_rate(priv->mclk, 25000000);
795 else
796 ret = clk_set_rate(priv->mclk, 19200000);
797
798 if (ret) {
799 dev_err(card->dev, "unable to set MCLK rate\n");
800 return ret;
801 }
802 }
803
804 if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
805 ret = snd_soc_card_jack_new(card, "Headset",
806 SND_JACK_HEADSET | SND_JACK_BTN_0,
807 &priv->jack, rt5640_pins,
808 ARRAY_SIZE(rt5640_pins));
809 if (ret) {
810 dev_err(card->dev, "Jack creation failed %d\n", ret);
811 return ret;
812 }
813 snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0,
814 KEY_PLAYPAUSE);
815 snd_soc_component_set_jack(component, &priv->jack, NULL);
816 }
817
818 return 0;
819}
820
821static const struct snd_soc_pcm_stream byt_rt5640_dai_params = {
822 .formats = SNDRV_PCM_FMTBIT_S24_LE,
823 .rate_min = 48000,
824 .rate_max = 48000,
825 .channels_min = 2,
826 .channels_max = 2,
827};
828
829static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd,
830 struct snd_pcm_hw_params *params)
831{
832 struct snd_interval *rate = hw_param_interval(params,
833 SNDRV_PCM_HW_PARAM_RATE);
834 struct snd_interval *channels = hw_param_interval(params,
835 SNDRV_PCM_HW_PARAM_CHANNELS);
836 int ret;
837
838
839 rate->min = rate->max = 48000;
840 channels->min = channels->max = 2;
841
842 if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
843 (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
844
845
846 params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
847
848
849
850
851
852
853 ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
854 SND_SOC_DAIFMT_I2S |
855 SND_SOC_DAIFMT_NB_NF |
856 SND_SOC_DAIFMT_CBS_CFS
857 );
858 if (ret < 0) {
859 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
860 return ret;
861 }
862
863 ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 16);
864 if (ret < 0) {
865 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
866 return ret;
867 }
868
869 } else {
870
871
872 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
873
874
875
876
877
878
879 ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
880 SND_SOC_DAIFMT_I2S |
881 SND_SOC_DAIFMT_NB_NF |
882 SND_SOC_DAIFMT_CBS_CFS
883 );
884 if (ret < 0) {
885 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
886 return ret;
887 }
888
889 ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
890 if (ret < 0) {
891 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
892 return ret;
893 }
894 }
895 return 0;
896}
897
898static int byt_rt5640_aif1_startup(struct snd_pcm_substream *substream)
899{
900 return snd_pcm_hw_constraint_single(substream->runtime,
901 SNDRV_PCM_HW_PARAM_RATE, 48000);
902}
903
904static const struct snd_soc_ops byt_rt5640_aif1_ops = {
905 .startup = byt_rt5640_aif1_startup,
906};
907
908static const struct snd_soc_ops byt_rt5640_be_ssp2_ops = {
909 .hw_params = byt_rt5640_aif1_hw_params,
910};
911
912static struct snd_soc_dai_link byt_rt5640_dais[] = {
913 [MERR_DPCM_AUDIO] = {
914 .name = "Baytrail Audio Port",
915 .stream_name = "Baytrail Audio",
916 .cpu_dai_name = "media-cpu-dai",
917 .codec_dai_name = "snd-soc-dummy-dai",
918 .codec_name = "snd-soc-dummy",
919 .platform_name = "sst-mfld-platform",
920 .nonatomic = true,
921 .dynamic = 1,
922 .dpcm_playback = 1,
923 .dpcm_capture = 1,
924 .ops = &byt_rt5640_aif1_ops,
925 },
926 [MERR_DPCM_DEEP_BUFFER] = {
927 .name = "Deep-Buffer Audio Port",
928 .stream_name = "Deep-Buffer Audio",
929 .cpu_dai_name = "deepbuffer-cpu-dai",
930 .codec_dai_name = "snd-soc-dummy-dai",
931 .codec_name = "snd-soc-dummy",
932 .platform_name = "sst-mfld-platform",
933 .nonatomic = true,
934 .dynamic = 1,
935 .dpcm_playback = 1,
936 .ops = &byt_rt5640_aif1_ops,
937 },
938
939 {
940 .name = "SSP2-Codec",
941 .id = 0,
942 .cpu_dai_name = "ssp2-port",
943 .platform_name = "sst-mfld-platform",
944 .no_pcm = 1,
945 .codec_dai_name = "rt5640-aif1",
946 .codec_name = "i2c-10EC5640:00",
947 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
948 | SND_SOC_DAIFMT_CBS_CFS,
949 .be_hw_params_fixup = byt_rt5640_codec_fixup,
950 .ignore_suspend = 1,
951 .nonatomic = true,
952 .dpcm_playback = 1,
953 .dpcm_capture = 1,
954 .init = byt_rt5640_init,
955 .ops = &byt_rt5640_be_ssp2_ops,
956 },
957};
958
959
960static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
961static char byt_rt5640_codec_aif_name[12];
962static char byt_rt5640_cpu_dai_name[10];
963static char byt_rt5640_long_name[40];
964
965static int byt_rt5640_suspend(struct snd_soc_card *card)
966{
967 struct snd_soc_component *component;
968
969 if (!BYT_RT5640_JDSRC(byt_rt5640_quirk))
970 return 0;
971
972 list_for_each_entry(component, &card->component_dev_list, card_list) {
973 if (!strcmp(component->name, byt_rt5640_codec_name)) {
974 dev_dbg(component->dev, "disabling jack detect before suspend\n");
975 snd_soc_component_set_jack(component, NULL, NULL);
976 break;
977 }
978 }
979
980 return 0;
981}
982
983static int byt_rt5640_resume(struct snd_soc_card *card)
984{
985 struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
986 struct snd_soc_component *component;
987
988 if (!BYT_RT5640_JDSRC(byt_rt5640_quirk))
989 return 0;
990
991 list_for_each_entry(component, &card->component_dev_list, card_list) {
992 if (!strcmp(component->name, byt_rt5640_codec_name)) {
993 dev_dbg(component->dev, "re-enabling jack detect after resume\n");
994 snd_soc_component_set_jack(component, &priv->jack, NULL);
995 break;
996 }
997 }
998
999 return 0;
1000}
1001
1002static struct snd_soc_card byt_rt5640_card = {
1003 .name = "bytcr-rt5640",
1004 .owner = THIS_MODULE,
1005 .dai_link = byt_rt5640_dais,
1006 .num_links = ARRAY_SIZE(byt_rt5640_dais),
1007 .dapm_widgets = byt_rt5640_widgets,
1008 .num_dapm_widgets = ARRAY_SIZE(byt_rt5640_widgets),
1009 .dapm_routes = byt_rt5640_audio_map,
1010 .num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map),
1011 .fully_routed = true,
1012 .suspend_pre = byt_rt5640_suspend,
1013 .resume_post = byt_rt5640_resume,
1014};
1015
1016static bool is_valleyview(void)
1017{
1018 static const struct x86_cpu_id cpu_ids[] = {
1019 { X86_VENDOR_INTEL, 6, 55 },
1020 {}
1021 };
1022
1023 if (!x86_match_cpu(cpu_ids))
1024 return false;
1025 return true;
1026}
1027
1028struct acpi_chan_package {
1029 u64 aif_value;
1030 u64 mclock_value;
1031};
1032
1033static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
1034{
1035 const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" };
1036 const struct dmi_system_id *dmi_id;
1037 struct byt_rt5640_private *priv;
1038 struct snd_soc_acpi_mach *mach;
1039 const char *i2c_name = NULL;
1040 int ret_val = 0;
1041 int dai_index = 0;
1042 int i;
1043
1044 is_bytcr = false;
1045 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
1046 if (!priv)
1047 return -ENOMEM;
1048
1049
1050 byt_rt5640_card.dev = &pdev->dev;
1051 mach = byt_rt5640_card.dev->platform_data;
1052 snd_soc_card_set_drvdata(&byt_rt5640_card, priv);
1053
1054
1055 for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) {
1056 if (!strcmp(byt_rt5640_dais[i].codec_name, "i2c-10EC5640:00")) {
1057 dai_index = i;
1058 break;
1059 }
1060 }
1061
1062
1063 i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
1064 if (i2c_name) {
1065 snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
1066 "%s%s", "i2c-", i2c_name);
1067
1068 byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name;
1069 }
1070
1071
1072
1073
1074
1075 if (is_valleyview()) {
1076 struct sst_platform_info *p_info = mach->pdata;
1077 const struct sst_res_info *res_info = p_info->res_info;
1078
1079 if (res_info->acpi_ipc_irq_index == 0)
1080 is_bytcr = true;
1081 }
1082
1083 if (is_bytcr) {
1084
1085
1086
1087
1088
1089
1090
1091
1092 struct acpi_chan_package chan_package;
1093
1094
1095 struct acpi_buffer format = {sizeof("NN"), "NN"};
1096 struct acpi_buffer state = {0, NULL};
1097 struct snd_soc_acpi_package_context pkg_ctx;
1098 bool pkg_found = false;
1099
1100 state.length = sizeof(chan_package);
1101 state.pointer = &chan_package;
1102
1103 pkg_ctx.name = "CHAN";
1104 pkg_ctx.length = 2;
1105 pkg_ctx.format = &format;
1106 pkg_ctx.state = &state;
1107 pkg_ctx.data_valid = false;
1108
1109 pkg_found = snd_soc_acpi_find_package_from_hid(mach->id,
1110 &pkg_ctx);
1111 if (pkg_found) {
1112 if (chan_package.aif_value == 1) {
1113 dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n");
1114 byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF1;
1115 } else if (chan_package.aif_value == 2) {
1116 dev_info(&pdev->dev, "BIOS Routing: AIF2 connected\n");
1117 byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
1118 } else {
1119 dev_info(&pdev->dev, "BIOS Routing isn't valid, ignored\n");
1120 pkg_found = false;
1121 }
1122 }
1123
1124 if (!pkg_found) {
1125
1126 byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
1127 }
1128
1129
1130 byt_rt5640_quirk |= BYTCR_INPUT_DEFAULTS;
1131 } else {
1132 byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP |
1133 BYT_RT5640_JD_SRC_JD2_IN4N |
1134 BYT_RT5640_OVCD_TH_2000UA |
1135 BYT_RT5640_OVCD_SF_0P75;
1136 }
1137
1138
1139 dmi_id = dmi_first_match(byt_rt5640_quirk_table);
1140 if (dmi_id)
1141 byt_rt5640_quirk = (unsigned long)dmi_id->driver_data;
1142 if (quirk_override) {
1143 dev_info(&pdev->dev, "Overriding quirk 0x%x => 0x%x\n",
1144 (unsigned int)byt_rt5640_quirk, quirk_override);
1145 byt_rt5640_quirk = quirk_override;
1146 }
1147
1148
1149 ret_val = byt_rt5640_add_codec_device_props(byt_rt5640_codec_name);
1150 if (ret_val)
1151 return ret_val;
1152
1153 log_quirks(&pdev->dev);
1154
1155 if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) ||
1156 (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
1157
1158
1159 snprintf(byt_rt5640_codec_aif_name,
1160 sizeof(byt_rt5640_codec_aif_name),
1161 "%s", "rt5640-aif2");
1162
1163 byt_rt5640_dais[dai_index].codec_dai_name =
1164 byt_rt5640_codec_aif_name;
1165 }
1166
1167 if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
1168 (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
1169
1170
1171 snprintf(byt_rt5640_cpu_dai_name,
1172 sizeof(byt_rt5640_cpu_dai_name),
1173 "%s", "ssp0-port");
1174
1175 byt_rt5640_dais[dai_index].cpu_dai_name =
1176 byt_rt5640_cpu_dai_name;
1177 }
1178
1179 if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
1180 priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
1181 if (IS_ERR(priv->mclk)) {
1182 ret_val = PTR_ERR(priv->mclk);
1183
1184 dev_err(&pdev->dev,
1185 "Failed to get MCLK from pmc_plt_clk_3: %d\n",
1186 ret_val);
1187
1188
1189
1190
1191
1192
1193 if (ret_val != -ENOENT)
1194 return ret_val;
1195 byt_rt5640_quirk &= ~BYT_RT5640_MCLK_EN;
1196 }
1197 }
1198
1199 snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name),
1200 "bytcr-rt5640-%s-spk-%s-mic",
1201 (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ?
1202 "mono" : "stereo",
1203 map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]);
1204 byt_rt5640_card.long_name = byt_rt5640_long_name;
1205
1206 ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
1207
1208 if (ret_val) {
1209 dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n",
1210 ret_val);
1211 return ret_val;
1212 }
1213 platform_set_drvdata(pdev, &byt_rt5640_card);
1214 return ret_val;
1215}
1216
1217static struct platform_driver snd_byt_rt5640_mc_driver = {
1218 .driver = {
1219 .name = "bytcr_rt5640",
1220 },
1221 .probe = snd_byt_rt5640_mc_probe,
1222};
1223
1224module_platform_driver(snd_byt_rt5640_mc_driver);
1225
1226MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver");
1227MODULE_AUTHOR("Subhransu S. Prusty <subhransu.s.prusty@intel.com>");
1228MODULE_LICENSE("GPL v2");
1229MODULE_ALIAS("platform:bytcr_rt5640");
1230