1 /*
2 * byt_cr_dpcm_rt5640.c - ASoc Machine driver for Intel Byt CR platform
3 *
4 * Copyright (C) 2014 Intel Corp
5 * Author: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
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
43 enum {
44 BYT_RT5640_DMIC1_MAP,
45 BYT_RT5640_DMIC2_MAP,
46 BYT_RT5640_IN1_MAP,
47 BYT_RT5640_IN3_MAP,
48 };
49
50 enum {
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
59 enum {
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
65 enum {
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) /* 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
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 /* in-diff or dmic-pin + jdsrc + ovcd-th + -sf + jd-inv + terminating entry */
93 #define MAX_NO_PROPS 6
94
95 struct byt_rt5640_private {
96 struct snd_soc_jack jack;
97 struct clk *mclk;
98 };
99 static bool is_bytcr;
100
101 static unsigned long byt_rt5640_quirk = BYT_RT5640_MCLK_EN;
102 static unsigned int quirk_override;
103 module_param_named(quirk, quirk_override, uint, 0444);
104 MODULE_PARM_DESC(quirk, "Board-specific quirk override");
105
log_quirks(struct device * dev)106 static 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
byt_rt5640_prepare_and_enable_pll1(struct snd_soc_dai * codec_dai,int rate)180 static int byt_rt5640_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai,
181 int rate)
182 {
183 int ret;
184
185 /* Configure the PLL before selecting it */
186 if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
187 /* use bitclock as PLL input */
188 if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
189 (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
190 /* 2x16 bit slots on SSP0 */
191 ret = snd_soc_dai_set_pll(codec_dai, 0,
192 RT5640_PLL1_S_BCLK1,
193 rate * 32, rate * 512);
194 } else {
195 /* 2x15 bit slots on SSP2 */
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
platform_clock_control(struct snd_soc_dapm_widget * w,struct snd_kcontrol * k,int event)230 static 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 * Set codec clock source to internal clock before
262 * turning off the platform clock. Codec needs clock
263 * for Jack detection and button press
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
282 static 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
293 static 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
305 static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = {
306 {"DMIC1", NULL, "Internal Mic"},
307 };
308
309 static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic2_map[] = {
310 {"DMIC2", NULL, "Internal Mic"},
311 };
312
313 static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = {
314 {"Internal Mic", NULL, "MICBIAS1"},
315 {"IN1P", NULL, "Internal Mic"},
316 };
317
318 static const struct snd_soc_dapm_route byt_rt5640_intmic_in3_map[] = {
319 {"Internal Mic", NULL, "MICBIAS1"},
320 {"IN3P", NULL, "Internal Mic"},
321 };
322
323 static 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
333 static 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
343 static 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
351 static 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
359 static 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
366 static const struct snd_soc_dapm_route byt_rt5640_mono_spk_map[] = {
367 {"Speaker", NULL, "SPOLP"},
368 {"Speaker", NULL, "SPOLN"},
369 };
370
371 static 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
378 static 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
byt_rt5640_aif1_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)389 static 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 /* Please keep this list alphabetically sorted */
399 static const struct dmi_system_id byt_rt5640_quirk_table[] = {
400 { /* Acer Iconia Tab 8 W1-810 */
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_1500UA |
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_DMIC1_MAP |
418 BYT_RT5640_JD_SRC_JD2_IN4N |
419 BYT_RT5640_OVCD_TH_2000UA |
420 BYT_RT5640_OVCD_SF_0P75 |
421 BYT_RT5640_SSP0_AIF1 |
422 BYT_RT5640_MCLK_EN),
423 },
424 {
425 .matches = {
426 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"),
427 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 80 Cesium"),
428 },
429 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
430 BYT_RT5640_MONO_SPEAKER |
431 BYT_RT5640_SSP0_AIF1 |
432 BYT_RT5640_MCLK_EN),
433 },
434 {
435 .matches = {
436 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
437 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
438 },
439 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
440 BYT_RT5640_JD_SRC_JD2_IN4N |
441 BYT_RT5640_OVCD_TH_2000UA |
442 BYT_RT5640_OVCD_SF_0P75 |
443 BYT_RT5640_MCLK_EN),
444 },
445 {
446 .matches = {
447 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
448 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
449 },
450 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
451 BYT_RT5640_MONO_SPEAKER |
452 BYT_RT5640_DIFF_MIC |
453 BYT_RT5640_SSP0_AIF2 |
454 BYT_RT5640_MCLK_EN),
455 },
456 { /* Chuwi Vi8 (CWI506) */
457 .matches = {
458 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
459 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "i86"),
460 /* The above are too generic, also match BIOS info */
461 DMI_MATCH(DMI_BIOS_VERSION, "CHUWI.D86JLBNR"),
462 },
463 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
464 BYT_RT5640_MONO_SPEAKER |
465 BYT_RT5640_SSP0_AIF1 |
466 BYT_RT5640_MCLK_EN),
467 },
468 {
469 /* Chuwi Vi10 (CWI505) */
470 .matches = {
471 DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
472 DMI_MATCH(DMI_BOARD_NAME, "BYT-PF02"),
473 DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
474 DMI_MATCH(DMI_PRODUCT_NAME, "S165"),
475 },
476 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
477 BYT_RT5640_JD_SRC_JD2_IN4N |
478 BYT_RT5640_OVCD_TH_2000UA |
479 BYT_RT5640_OVCD_SF_0P75 |
480 BYT_RT5640_DIFF_MIC |
481 BYT_RT5640_SSP0_AIF1 |
482 BYT_RT5640_MCLK_EN),
483 },
484 {
485 .matches = {
486 DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
487 DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
488 },
489 .driver_data = (void *)(BYT_RT5640_DMIC1_MAP),
490 },
491 { /* Connect Tablet 9 */
492 .matches = {
493 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Connect"),
494 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Tablet 9"),
495 },
496 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
497 BYT_RT5640_MONO_SPEAKER |
498 BYT_RT5640_SSP0_AIF1 |
499 BYT_RT5640_MCLK_EN),
500 },
501 {
502 .matches = {
503 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
504 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
505 },
506 .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
507 BYT_RT5640_JD_SRC_JD2_IN4N |
508 BYT_RT5640_OVCD_TH_2000UA |
509 BYT_RT5640_OVCD_SF_0P75 |
510 BYT_RT5640_MONO_SPEAKER |
511 BYT_RT5640_MCLK_EN),
512 },
513 {
514 .matches = {
515 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
516 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
517 },
518 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
519 BYT_RT5640_MCLK_EN),
520 },
521 { /* HP Pavilion x2 10-n000nd */
522 .matches = {
523 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
524 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
525 },
526 .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
527 BYT_RT5640_JD_SRC_JD2_IN4N |
528 BYT_RT5640_OVCD_TH_1500UA |
529 BYT_RT5640_OVCD_SF_0P75 |
530 BYT_RT5640_SSP0_AIF1 |
531 BYT_RT5640_MCLK_EN),
532 },
533 { /* HP Stream 7 */
534 .matches = {
535 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
536 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Stream 7 Tablet"),
537 },
538 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
539 BYT_RT5640_MONO_SPEAKER |
540 BYT_RT5640_JD_NOT_INV |
541 BYT_RT5640_SSP0_AIF1 |
542 BYT_RT5640_MCLK_EN),
543 },
544 { /* I.T.Works TW891 */
545 .matches = {
546 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
547 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"),
548 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."),
549 DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"),
550 },
551 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
552 BYT_RT5640_MONO_SPEAKER |
553 BYT_RT5640_SSP0_AIF1 |
554 BYT_RT5640_MCLK_EN),
555 },
556 { /* Lamina I8270 / T701BR.SE */
557 .matches = {
558 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Lamina"),
559 DMI_EXACT_MATCH(DMI_BOARD_NAME, "T701BR.SE"),
560 },
561 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
562 BYT_RT5640_MONO_SPEAKER |
563 BYT_RT5640_JD_NOT_INV |
564 BYT_RT5640_SSP0_AIF1 |
565 BYT_RT5640_MCLK_EN),
566 },
567 { /* Lenovo Miix 2 8 */
568 .matches = {
569 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
570 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "20326"),
571 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Hiking"),
572 },
573 .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
574 BYT_RT5640_JD_SRC_JD2_IN4N |
575 BYT_RT5640_OVCD_TH_2000UA |
576 BYT_RT5640_OVCD_SF_0P75 |
577 BYT_RT5640_MONO_SPEAKER |
578 BYT_RT5640_MCLK_EN),
579 },
580 { /* Linx Linx7 tablet */
581 .matches = {
582 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LINX"),
583 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LINX7"),
584 },
585 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
586 BYT_RT5640_MONO_SPEAKER |
587 BYT_RT5640_JD_NOT_INV |
588 BYT_RT5640_SSP0_AIF1 |
589 BYT_RT5640_MCLK_EN),
590 },
591 { /* MPMAN Converter 9, similar hw as the I.T.Works TW891 2-in-1 */
592 .matches = {
593 DMI_MATCH(DMI_SYS_VENDOR, "MPMAN"),
594 DMI_MATCH(DMI_PRODUCT_NAME, "Converter9"),
595 },
596 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
597 BYT_RT5640_MONO_SPEAKER |
598 BYT_RT5640_SSP0_AIF1 |
599 BYT_RT5640_MCLK_EN),
600 },
601 {
602 /* MPMAN MPWIN895CL */
603 .matches = {
604 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MPMAN"),
605 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MPWIN8900CL"),
606 },
607 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
608 BYT_RT5640_MONO_SPEAKER |
609 BYT_RT5640_SSP0_AIF1 |
610 BYT_RT5640_MCLK_EN),
611 },
612 { /* MSI S100 tablet */
613 .matches = {
614 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
615 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "S100"),
616 },
617 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
618 BYT_RT5640_JD_SRC_JD2_IN4N |
619 BYT_RT5640_OVCD_TH_2000UA |
620 BYT_RT5640_OVCD_SF_0P75 |
621 BYT_RT5640_MONO_SPEAKER |
622 BYT_RT5640_DIFF_MIC |
623 BYT_RT5640_MCLK_EN),
624 },
625 { /* Nuvison/TMax TM800W560 */
626 .matches = {
627 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TMAX"),
628 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TM800W560L"),
629 },
630 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
631 BYT_RT5640_JD_SRC_JD2_IN4N |
632 BYT_RT5640_OVCD_TH_2000UA |
633 BYT_RT5640_OVCD_SF_0P75 |
634 BYT_RT5640_JD_NOT_INV |
635 BYT_RT5640_DIFF_MIC |
636 BYT_RT5640_SSP0_AIF1 |
637 BYT_RT5640_MCLK_EN),
638 },
639 { /* Onda v975w */
640 .matches = {
641 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
642 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
643 /* The above are too generic, also match BIOS info */
644 DMI_EXACT_MATCH(DMI_BIOS_VERSION, "5.6.5"),
645 DMI_EXACT_MATCH(DMI_BIOS_DATE, "07/25/2014"),
646 },
647 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
648 BYT_RT5640_JD_SRC_JD2_IN4N |
649 BYT_RT5640_OVCD_TH_2000UA |
650 BYT_RT5640_OVCD_SF_0P75 |
651 BYT_RT5640_DIFF_MIC |
652 BYT_RT5640_MCLK_EN),
653 },
654 { /* Pipo W4 */
655 .matches = {
656 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
657 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
658 /* The above are too generic, also match BIOS info */
659 DMI_MATCH(DMI_BIOS_VERSION, "V8L_WIN32_CHIPHD"),
660 },
661 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
662 BYT_RT5640_MONO_SPEAKER |
663 BYT_RT5640_SSP0_AIF1 |
664 BYT_RT5640_MCLK_EN),
665 },
666 { /* Point of View Mobii TAB-P800W (V2.0) */
667 .matches = {
668 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
669 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
670 /* The above are too generic, also match BIOS info */
671 DMI_EXACT_MATCH(DMI_BIOS_VERSION, "3BAIR1014"),
672 DMI_EXACT_MATCH(DMI_BIOS_DATE, "10/24/2014"),
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 { /* Point of View Mobii TAB-P800W (V2.1) */
684 .matches = {
685 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
686 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
687 /* The above are too generic, also match BIOS info */
688 DMI_EXACT_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
689 DMI_EXACT_MATCH(DMI_BIOS_DATE, "08/22/2014"),
690 },
691 .driver_data = (void *)(BYT_RT5640_IN1_MAP |
692 BYT_RT5640_JD_SRC_JD2_IN4N |
693 BYT_RT5640_OVCD_TH_2000UA |
694 BYT_RT5640_OVCD_SF_0P75 |
695 BYT_RT5640_MONO_SPEAKER |
696 BYT_RT5640_DIFF_MIC |
697 BYT_RT5640_SSP0_AIF2 |
698 BYT_RT5640_MCLK_EN),
699 },
700 {
701 /* Teclast X89 */
702 .matches = {
703 DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
704 DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
705 },
706 .driver_data = (void *)(BYT_RT5640_IN3_MAP |
707 BYT_RT5640_JD_SRC_JD1_IN4P |
708 BYT_RT5640_OVCD_TH_2000UA |
709 BYT_RT5640_OVCD_SF_1P0 |
710 BYT_RT5640_SSP0_AIF1 |
711 BYT_RT5640_MCLK_EN),
712 },
713 { /* Toshiba Satellite Click Mini L9W-B */
714 .matches = {
715 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
716 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"),
717 },
718 .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
719 BYT_RT5640_JD_SRC_JD2_IN4N |
720 BYT_RT5640_OVCD_TH_1500UA |
721 BYT_RT5640_OVCD_SF_0P75 |
722 BYT_RT5640_SSP0_AIF1 |
723 BYT_RT5640_MCLK_EN),
724 },
725 { /* Toshiba Encore WT8-A */
726 .matches = {
727 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
728 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TOSHIBA WT8-A"),
729 },
730 .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
731 BYT_RT5640_JD_SRC_JD2_IN4N |
732 BYT_RT5640_OVCD_TH_2000UA |
733 BYT_RT5640_OVCD_SF_0P75 |
734 BYT_RT5640_JD_NOT_INV |
735 BYT_RT5640_MCLK_EN),
736 },
737 { /* Toshiba Encore WT10-A */
738 .matches = {
739 DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
740 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TOSHIBA WT10-A-103"),
741 },
742 .driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
743 BYT_RT5640_JD_SRC_JD1_IN4P |
744 BYT_RT5640_OVCD_TH_2000UA |
745 BYT_RT5640_OVCD_SF_0P75 |
746 BYT_RT5640_SSP0_AIF2 |
747 BYT_RT5640_MCLK_EN),
748 },
749 { /* Catch-all for generic Insyde tablets, must be last */
750 .matches = {
751 DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
752 },
753 .driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
754 BYT_RT5640_MCLK_EN |
755 BYT_RT5640_SSP0_AIF1),
756
757 },
758 {}
759 };
760
761 /*
762 * Note this MUST be called before snd_soc_register_card(), so that the props
763 * are in place before the codec component driver's probe function parses them.
764 */
byt_rt5640_add_codec_device_props(const char * i2c_dev_name)765 static int byt_rt5640_add_codec_device_props(const char *i2c_dev_name)
766 {
767 struct property_entry props[MAX_NO_PROPS] = {};
768 struct device *i2c_dev;
769 int ret, cnt = 0;
770
771 i2c_dev = bus_find_device_by_name(&i2c_bus_type, NULL, i2c_dev_name);
772 if (!i2c_dev)
773 return -EPROBE_DEFER;
774
775 switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
776 case BYT_RT5640_DMIC1_MAP:
777 props[cnt++] = PROPERTY_ENTRY_U32("realtek,dmic1-data-pin",
778 RT5640_DMIC1_DATA_PIN_IN1P);
779 break;
780 case BYT_RT5640_DMIC2_MAP:
781 props[cnt++] = PROPERTY_ENTRY_U32("realtek,dmic2-data-pin",
782 RT5640_DMIC2_DATA_PIN_IN1N);
783 break;
784 case BYT_RT5640_IN1_MAP:
785 if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
786 props[cnt++] =
787 PROPERTY_ENTRY_BOOL("realtek,in1-differential");
788 break;
789 case BYT_RT5640_IN3_MAP:
790 if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
791 props[cnt++] =
792 PROPERTY_ENTRY_BOOL("realtek,in3-differential");
793 break;
794 }
795
796 if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
797 props[cnt++] = PROPERTY_ENTRY_U32(
798 "realtek,jack-detect-source",
799 BYT_RT5640_JDSRC(byt_rt5640_quirk));
800
801 props[cnt++] = PROPERTY_ENTRY_U32(
802 "realtek,over-current-threshold-microamp",
803 BYT_RT5640_OVCD_TH(byt_rt5640_quirk) * 100);
804
805 props[cnt++] = PROPERTY_ENTRY_U32(
806 "realtek,over-current-scale-factor",
807 BYT_RT5640_OVCD_SF(byt_rt5640_quirk));
808 }
809
810 if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
811 props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted");
812
813 ret = device_add_properties(i2c_dev, props);
814 put_device(i2c_dev);
815
816 return ret;
817 }
818
byt_rt5640_init(struct snd_soc_pcm_runtime * runtime)819 static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
820 {
821 struct snd_soc_card *card = runtime->card;
822 struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
823 struct snd_soc_component *component = runtime->codec_dai->component;
824 const struct snd_soc_dapm_route *custom_map;
825 int num_routes;
826 int ret;
827
828 card->dapm.idle_bias_off = true;
829
830 /* Start with RC clk for jack-detect (we disable MCLK below) */
831 if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
832 snd_soc_component_update_bits(component, RT5640_GLB_CLK,
833 RT5640_SCLK_SRC_MASK, RT5640_SCLK_SRC_RCCLK);
834
835 rt5640_sel_asrc_clk_src(component,
836 RT5640_DA_STEREO_FILTER |
837 RT5640_DA_MONO_L_FILTER |
838 RT5640_DA_MONO_R_FILTER |
839 RT5640_AD_STEREO_FILTER |
840 RT5640_AD_MONO_L_FILTER |
841 RT5640_AD_MONO_R_FILTER,
842 RT5640_CLK_SEL_ASRC);
843
844 ret = snd_soc_add_card_controls(card, byt_rt5640_controls,
845 ARRAY_SIZE(byt_rt5640_controls));
846 if (ret) {
847 dev_err(card->dev, "unable to add card controls\n");
848 return ret;
849 }
850
851 switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
852 case BYT_RT5640_IN1_MAP:
853 custom_map = byt_rt5640_intmic_in1_map;
854 num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map);
855 break;
856 case BYT_RT5640_IN3_MAP:
857 custom_map = byt_rt5640_intmic_in3_map;
858 num_routes = ARRAY_SIZE(byt_rt5640_intmic_in3_map);
859 break;
860 case BYT_RT5640_DMIC2_MAP:
861 custom_map = byt_rt5640_intmic_dmic2_map;
862 num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map);
863 break;
864 default:
865 custom_map = byt_rt5640_intmic_dmic1_map;
866 num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map);
867 }
868
869 ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
870 if (ret)
871 return ret;
872
873 if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
874 ret = snd_soc_dapm_add_routes(&card->dapm,
875 byt_rt5640_ssp2_aif2_map,
876 ARRAY_SIZE(byt_rt5640_ssp2_aif2_map));
877 } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
878 ret = snd_soc_dapm_add_routes(&card->dapm,
879 byt_rt5640_ssp0_aif1_map,
880 ARRAY_SIZE(byt_rt5640_ssp0_aif1_map));
881 } else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
882 ret = snd_soc_dapm_add_routes(&card->dapm,
883 byt_rt5640_ssp0_aif2_map,
884 ARRAY_SIZE(byt_rt5640_ssp0_aif2_map));
885 } else {
886 ret = snd_soc_dapm_add_routes(&card->dapm,
887 byt_rt5640_ssp2_aif1_map,
888 ARRAY_SIZE(byt_rt5640_ssp2_aif1_map));
889 }
890 if (ret)
891 return ret;
892
893 if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) {
894 ret = snd_soc_dapm_add_routes(&card->dapm,
895 byt_rt5640_mono_spk_map,
896 ARRAY_SIZE(byt_rt5640_mono_spk_map));
897 } else {
898 ret = snd_soc_dapm_add_routes(&card->dapm,
899 byt_rt5640_stereo_spk_map,
900 ARRAY_SIZE(byt_rt5640_stereo_spk_map));
901 }
902 if (ret)
903 return ret;
904
905 snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
906 snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
907
908 if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
909 /*
910 * The firmware might enable the clock at
911 * boot (this information may or may not
912 * be reflected in the enable clock register).
913 * To change the rate we must disable the clock
914 * first to cover these cases. Due to common
915 * clock framework restrictions that do not allow
916 * to disable a clock that has not been enabled,
917 * we need to enable the clock first.
918 */
919 ret = clk_prepare_enable(priv->mclk);
920 if (!ret)
921 clk_disable_unprepare(priv->mclk);
922
923 if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ)
924 ret = clk_set_rate(priv->mclk, 25000000);
925 else
926 ret = clk_set_rate(priv->mclk, 19200000);
927
928 if (ret) {
929 dev_err(card->dev, "unable to set MCLK rate\n");
930 return ret;
931 }
932 }
933
934 if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
935 ret = snd_soc_card_jack_new(card, "Headset",
936 SND_JACK_HEADSET | SND_JACK_BTN_0,
937 &priv->jack, rt5640_pins,
938 ARRAY_SIZE(rt5640_pins));
939 if (ret) {
940 dev_err(card->dev, "Jack creation failed %d\n", ret);
941 return ret;
942 }
943 snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0,
944 KEY_PLAYPAUSE);
945 snd_soc_component_set_jack(component, &priv->jack, NULL);
946 }
947
948 return 0;
949 }
950
951 static const struct snd_soc_pcm_stream byt_rt5640_dai_params = {
952 .formats = SNDRV_PCM_FMTBIT_S24_LE,
953 .rate_min = 48000,
954 .rate_max = 48000,
955 .channels_min = 2,
956 .channels_max = 2,
957 };
958
byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime * rtd,struct snd_pcm_hw_params * params)959 static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd,
960 struct snd_pcm_hw_params *params)
961 {
962 struct snd_interval *rate = hw_param_interval(params,
963 SNDRV_PCM_HW_PARAM_RATE);
964 struct snd_interval *channels = hw_param_interval(params,
965 SNDRV_PCM_HW_PARAM_CHANNELS);
966 int ret;
967
968 /* The DSP will covert the FE rate to 48k, stereo */
969 rate->min = rate->max = 48000;
970 channels->min = channels->max = 2;
971
972 if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
973 (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
974
975 /* set SSP0 to 16-bit */
976 params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
977
978 /*
979 * Default mode for SSP configuration is TDM 4 slot, override config
980 * with explicit setting to I2S 2ch 16-bit. The word length is set with
981 * dai_set_tdm_slot() since there is no other API exposed
982 */
983 ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
984 SND_SOC_DAIFMT_I2S |
985 SND_SOC_DAIFMT_NB_NF |
986 SND_SOC_DAIFMT_CBS_CFS
987 );
988 if (ret < 0) {
989 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
990 return ret;
991 }
992
993 ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 16);
994 if (ret < 0) {
995 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
996 return ret;
997 }
998
999 } else {
1000
1001 /* set SSP2 to 24-bit */
1002 params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
1003
1004 /*
1005 * Default mode for SSP configuration is TDM 4 slot, override config
1006 * with explicit setting to I2S 2ch 24-bit. The word length is set with
1007 * dai_set_tdm_slot() since there is no other API exposed
1008 */
1009 ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
1010 SND_SOC_DAIFMT_I2S |
1011 SND_SOC_DAIFMT_NB_NF |
1012 SND_SOC_DAIFMT_CBS_CFS
1013 );
1014 if (ret < 0) {
1015 dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
1016 return ret;
1017 }
1018
1019 ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
1020 if (ret < 0) {
1021 dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
1022 return ret;
1023 }
1024 }
1025 return 0;
1026 }
1027
byt_rt5640_aif1_startup(struct snd_pcm_substream * substream)1028 static int byt_rt5640_aif1_startup(struct snd_pcm_substream *substream)
1029 {
1030 return snd_pcm_hw_constraint_single(substream->runtime,
1031 SNDRV_PCM_HW_PARAM_RATE, 48000);
1032 }
1033
1034 static const struct snd_soc_ops byt_rt5640_aif1_ops = {
1035 .startup = byt_rt5640_aif1_startup,
1036 };
1037
1038 static const struct snd_soc_ops byt_rt5640_be_ssp2_ops = {
1039 .hw_params = byt_rt5640_aif1_hw_params,
1040 };
1041
1042 static struct snd_soc_dai_link byt_rt5640_dais[] = {
1043 [MERR_DPCM_AUDIO] = {
1044 .name = "Baytrail Audio Port",
1045 .stream_name = "Baytrail Audio",
1046 .cpu_dai_name = "media-cpu-dai",
1047 .codec_dai_name = "snd-soc-dummy-dai",
1048 .codec_name = "snd-soc-dummy",
1049 .platform_name = "sst-mfld-platform",
1050 .nonatomic = true,
1051 .dynamic = 1,
1052 .dpcm_playback = 1,
1053 .dpcm_capture = 1,
1054 .ops = &byt_rt5640_aif1_ops,
1055 },
1056 [MERR_DPCM_DEEP_BUFFER] = {
1057 .name = "Deep-Buffer Audio Port",
1058 .stream_name = "Deep-Buffer Audio",
1059 .cpu_dai_name = "deepbuffer-cpu-dai",
1060 .codec_dai_name = "snd-soc-dummy-dai",
1061 .codec_name = "snd-soc-dummy",
1062 .platform_name = "sst-mfld-platform",
1063 .nonatomic = true,
1064 .dynamic = 1,
1065 .dpcm_playback = 1,
1066 .ops = &byt_rt5640_aif1_ops,
1067 },
1068 /* back ends */
1069 {
1070 .name = "SSP2-Codec",
1071 .id = 0,
1072 .cpu_dai_name = "ssp2-port", /* overwritten for ssp0 routing */
1073 .platform_name = "sst-mfld-platform",
1074 .no_pcm = 1,
1075 .codec_dai_name = "rt5640-aif1", /* changed w/ quirk */
1076 .codec_name = "i2c-10EC5640:00", /* overwritten with HID */
1077 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
1078 | SND_SOC_DAIFMT_CBS_CFS,
1079 .be_hw_params_fixup = byt_rt5640_codec_fixup,
1080 .ignore_suspend = 1,
1081 .nonatomic = true,
1082 .dpcm_playback = 1,
1083 .dpcm_capture = 1,
1084 .init = byt_rt5640_init,
1085 .ops = &byt_rt5640_be_ssp2_ops,
1086 },
1087 };
1088
1089 /* SoC card */
1090 static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
1091 static char byt_rt5640_codec_aif_name[12]; /* = "rt5640-aif[1|2]" */
1092 static char byt_rt5640_cpu_dai_name[10]; /* = "ssp[0|2]-port" */
1093 static char byt_rt5640_long_name[40]; /* = "bytcr-rt5640-*-spk-*-mic" */
1094
byt_rt5640_suspend(struct snd_soc_card * card)1095 static int byt_rt5640_suspend(struct snd_soc_card *card)
1096 {
1097 struct snd_soc_component *component;
1098
1099 if (!BYT_RT5640_JDSRC(byt_rt5640_quirk))
1100 return 0;
1101
1102 list_for_each_entry(component, &card->component_dev_list, card_list) {
1103 if (!strcmp(component->name, byt_rt5640_codec_name)) {
1104 dev_dbg(component->dev, "disabling jack detect before suspend\n");
1105 snd_soc_component_set_jack(component, NULL, NULL);
1106 break;
1107 }
1108 }
1109
1110 return 0;
1111 }
1112
byt_rt5640_resume(struct snd_soc_card * card)1113 static int byt_rt5640_resume(struct snd_soc_card *card)
1114 {
1115 struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
1116 struct snd_soc_component *component;
1117
1118 if (!BYT_RT5640_JDSRC(byt_rt5640_quirk))
1119 return 0;
1120
1121 list_for_each_entry(component, &card->component_dev_list, card_list) {
1122 if (!strcmp(component->name, byt_rt5640_codec_name)) {
1123 dev_dbg(component->dev, "re-enabling jack detect after resume\n");
1124 snd_soc_component_set_jack(component, &priv->jack, NULL);
1125 break;
1126 }
1127 }
1128
1129 return 0;
1130 }
1131
1132 static struct snd_soc_card byt_rt5640_card = {
1133 .name = "bytcr-rt5640",
1134 .owner = THIS_MODULE,
1135 .dai_link = byt_rt5640_dais,
1136 .num_links = ARRAY_SIZE(byt_rt5640_dais),
1137 .dapm_widgets = byt_rt5640_widgets,
1138 .num_dapm_widgets = ARRAY_SIZE(byt_rt5640_widgets),
1139 .dapm_routes = byt_rt5640_audio_map,
1140 .num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map),
1141 .fully_routed = true,
1142 .suspend_pre = byt_rt5640_suspend,
1143 .resume_post = byt_rt5640_resume,
1144 };
1145
is_valleyview(void)1146 static bool is_valleyview(void)
1147 {
1148 static const struct x86_cpu_id cpu_ids[] = {
1149 { X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
1150 {}
1151 };
1152
1153 if (!x86_match_cpu(cpu_ids))
1154 return false;
1155 return true;
1156 }
1157
1158 struct acpi_chan_package { /* ACPICA seems to require 64 bit integers */
1159 u64 aif_value; /* 1: AIF1, 2: AIF2 */
1160 u64 mclock_value; /* usually 25MHz (0x17d7940), ignored */
1161 };
1162
snd_byt_rt5640_mc_probe(struct platform_device * pdev)1163 static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
1164 {
1165 const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" };
1166 const struct dmi_system_id *dmi_id;
1167 struct byt_rt5640_private *priv;
1168 struct snd_soc_acpi_mach *mach;
1169 const char *i2c_name = NULL;
1170 int ret_val = 0;
1171 int dai_index = 0;
1172 int i;
1173
1174 is_bytcr = false;
1175 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
1176 if (!priv)
1177 return -ENOMEM;
1178
1179 /* register the soc card */
1180 byt_rt5640_card.dev = &pdev->dev;
1181 mach = byt_rt5640_card.dev->platform_data;
1182 snd_soc_card_set_drvdata(&byt_rt5640_card, priv);
1183
1184 /* fix index of codec dai */
1185 for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) {
1186 if (!strcmp(byt_rt5640_dais[i].codec_name, "i2c-10EC5640:00")) {
1187 dai_index = i;
1188 break;
1189 }
1190 }
1191
1192 /* fixup codec name based on HID */
1193 i2c_name = acpi_dev_get_first_match_name(mach->id, NULL, -1);
1194 if (i2c_name) {
1195 snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
1196 "%s%s", "i2c-", i2c_name);
1197
1198 byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name;
1199 }
1200
1201 /*
1202 * swap SSP0 if bytcr is detected
1203 * (will be overridden if DMI quirk is detected)
1204 */
1205 if (is_valleyview()) {
1206 struct sst_platform_info *p_info = mach->pdata;
1207 const struct sst_res_info *res_info = p_info->res_info;
1208
1209 if (res_info->acpi_ipc_irq_index == 0)
1210 is_bytcr = true;
1211 }
1212
1213 if (is_bytcr) {
1214 /*
1215 * Baytrail CR platforms may have CHAN package in BIOS, try
1216 * to find relevant routing quirk based as done on Windows
1217 * platforms. We have to read the information directly from the
1218 * BIOS, at this stage the card is not created and the links
1219 * with the codec driver/pdata are non-existent
1220 */
1221
1222 struct acpi_chan_package chan_package;
1223
1224 /* format specified: 2 64-bit integers */
1225 struct acpi_buffer format = {sizeof("NN"), "NN"};
1226 struct acpi_buffer state = {0, NULL};
1227 struct snd_soc_acpi_package_context pkg_ctx;
1228 bool pkg_found = false;
1229
1230 state.length = sizeof(chan_package);
1231 state.pointer = &chan_package;
1232
1233 pkg_ctx.name = "CHAN";
1234 pkg_ctx.length = 2;
1235 pkg_ctx.format = &format;
1236 pkg_ctx.state = &state;
1237 pkg_ctx.data_valid = false;
1238
1239 pkg_found = snd_soc_acpi_find_package_from_hid(mach->id,
1240 &pkg_ctx);
1241 if (pkg_found) {
1242 if (chan_package.aif_value == 1) {
1243 dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n");
1244 byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF1;
1245 } else if (chan_package.aif_value == 2) {
1246 dev_info(&pdev->dev, "BIOS Routing: AIF2 connected\n");
1247 byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
1248 } else {
1249 dev_info(&pdev->dev, "BIOS Routing isn't valid, ignored\n");
1250 pkg_found = false;
1251 }
1252 }
1253
1254 if (!pkg_found) {
1255 /* no BIOS indications, assume SSP0-AIF2 connection */
1256 byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
1257 }
1258
1259 /* change defaults for Baytrail-CR capture */
1260 byt_rt5640_quirk |= BYTCR_INPUT_DEFAULTS;
1261 } else {
1262 byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP |
1263 BYT_RT5640_JD_SRC_JD2_IN4N |
1264 BYT_RT5640_OVCD_TH_2000UA |
1265 BYT_RT5640_OVCD_SF_0P75;
1266 }
1267
1268 /* check quirks before creating card */
1269 dmi_id = dmi_first_match(byt_rt5640_quirk_table);
1270 if (dmi_id)
1271 byt_rt5640_quirk = (unsigned long)dmi_id->driver_data;
1272 if (quirk_override) {
1273 dev_info(&pdev->dev, "Overriding quirk 0x%x => 0x%x\n",
1274 (unsigned int)byt_rt5640_quirk, quirk_override);
1275 byt_rt5640_quirk = quirk_override;
1276 }
1277
1278 /* Must be called before register_card, also see declaration comment. */
1279 ret_val = byt_rt5640_add_codec_device_props(byt_rt5640_codec_name);
1280 if (ret_val)
1281 return ret_val;
1282
1283 log_quirks(&pdev->dev);
1284
1285 if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) ||
1286 (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
1287
1288 /* fixup codec aif name */
1289 snprintf(byt_rt5640_codec_aif_name,
1290 sizeof(byt_rt5640_codec_aif_name),
1291 "%s", "rt5640-aif2");
1292
1293 byt_rt5640_dais[dai_index].codec_dai_name =
1294 byt_rt5640_codec_aif_name;
1295 }
1296
1297 if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
1298 (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
1299
1300 /* fixup cpu dai name name */
1301 snprintf(byt_rt5640_cpu_dai_name,
1302 sizeof(byt_rt5640_cpu_dai_name),
1303 "%s", "ssp0-port");
1304
1305 byt_rt5640_dais[dai_index].cpu_dai_name =
1306 byt_rt5640_cpu_dai_name;
1307 }
1308
1309 if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
1310 priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
1311 if (IS_ERR(priv->mclk)) {
1312 ret_val = PTR_ERR(priv->mclk);
1313
1314 dev_err(&pdev->dev,
1315 "Failed to get MCLK from pmc_plt_clk_3: %d\n",
1316 ret_val);
1317
1318 /*
1319 * Fall back to bit clock usage for -ENOENT (clock not
1320 * available likely due to missing dependencies), bail
1321 * for all other errors, including -EPROBE_DEFER
1322 */
1323 if (ret_val != -ENOENT)
1324 return ret_val;
1325 byt_rt5640_quirk &= ~BYT_RT5640_MCLK_EN;
1326 }
1327 }
1328
1329 snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name),
1330 "bytcr-rt5640-%s-spk-%s-mic",
1331 (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) ?
1332 "mono" : "stereo",
1333 map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]);
1334 byt_rt5640_card.long_name = byt_rt5640_long_name;
1335
1336 ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
1337
1338 if (ret_val) {
1339 dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n",
1340 ret_val);
1341 return ret_val;
1342 }
1343 platform_set_drvdata(pdev, &byt_rt5640_card);
1344 return ret_val;
1345 }
1346
1347 static struct platform_driver snd_byt_rt5640_mc_driver = {
1348 .driver = {
1349 .name = "bytcr_rt5640",
1350 },
1351 .probe = snd_byt_rt5640_mc_probe,
1352 };
1353
1354 module_platform_driver(snd_byt_rt5640_mc_driver);
1355
1356 MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver");
1357 MODULE_AUTHOR("Subhransu S. Prusty <subhransu.s.prusty@intel.com>");
1358 MODULE_LICENSE("GPL v2");
1359 MODULE_ALIAS("platform:bytcr_rt5640");
1360