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