• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *  byt_cr_dpcm_rt5640.c - ASoc Machine driver for Intel Byt CR platform
4  *
5  *  Copyright (C) 2014 Intel Corp
6  *  Author: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
7  *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8  *
9  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10  */
11 
12 #include <linux/i2c.h>
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/moduleparam.h>
16 #include <linux/platform_device.h>
17 #include <linux/acpi.h>
18 #include <linux/clk.h>
19 #include <linux/device.h>
20 #include <linux/dmi.h>
21 #include <linux/input.h>
22 #include <linux/slab.h>
23 #include <sound/pcm.h>
24 #include <sound/pcm_params.h>
25 #include <sound/soc.h>
26 #include <sound/jack.h>
27 #include <sound/soc-acpi.h>
28 #include <dt-bindings/sound/rt5640.h>
29 #include "../../codecs/rt5640.h"
30 #include "../atom/sst-atom-controls.h"
31 #include "../common/soc-intel-quirks.h"
32 
33 enum {
34 	BYT_RT5640_DMIC1_MAP,
35 	BYT_RT5640_DMIC2_MAP,
36 	BYT_RT5640_IN1_MAP,
37 	BYT_RT5640_IN3_MAP,
38 };
39 
40 enum {
41 	BYT_RT5640_JD_SRC_GPIO1		= (RT5640_JD_SRC_GPIO1 << 4),
42 	BYT_RT5640_JD_SRC_JD1_IN4P	= (RT5640_JD_SRC_JD1_IN4P << 4),
43 	BYT_RT5640_JD_SRC_JD2_IN4N	= (RT5640_JD_SRC_JD2_IN4N << 4),
44 	BYT_RT5640_JD_SRC_GPIO2		= (RT5640_JD_SRC_GPIO2 << 4),
45 	BYT_RT5640_JD_SRC_GPIO3		= (RT5640_JD_SRC_GPIO3 << 4),
46 	BYT_RT5640_JD_SRC_GPIO4		= (RT5640_JD_SRC_GPIO4 << 4),
47 };
48 
49 enum {
50 	BYT_RT5640_OVCD_TH_600UA	= (6 << 8),
51 	BYT_RT5640_OVCD_TH_1500UA	= (15 << 8),
52 	BYT_RT5640_OVCD_TH_2000UA	= (20 << 8),
53 };
54 
55 enum {
56 	BYT_RT5640_OVCD_SF_0P5		= (RT5640_OVCD_SF_0P5 << 13),
57 	BYT_RT5640_OVCD_SF_0P75		= (RT5640_OVCD_SF_0P75 << 13),
58 	BYT_RT5640_OVCD_SF_1P0		= (RT5640_OVCD_SF_1P0 << 13),
59 	BYT_RT5640_OVCD_SF_1P5		= (RT5640_OVCD_SF_1P5 << 13),
60 };
61 
62 #define BYT_RT5640_MAP(quirk)		((quirk) &  GENMASK(3, 0))
63 #define BYT_RT5640_JDSRC(quirk)		(((quirk) & GENMASK(7, 4)) >> 4)
64 #define BYT_RT5640_OVCD_TH(quirk)	(((quirk) & GENMASK(12, 8)) >> 8)
65 #define BYT_RT5640_OVCD_SF(quirk)	(((quirk) & GENMASK(14, 13)) >> 13)
66 #define BYT_RT5640_JD_NOT_INV		BIT(16)
67 #define BYT_RT5640_MONO_SPEAKER		BIT(17)
68 #define BYT_RT5640_DIFF_MIC		BIT(18) /* default is single-ended */
69 #define BYT_RT5640_SSP2_AIF2		BIT(19) /* default is using AIF1  */
70 #define BYT_RT5640_SSP0_AIF1		BIT(20)
71 #define BYT_RT5640_SSP0_AIF2		BIT(21)
72 #define BYT_RT5640_MCLK_EN		BIT(22)
73 #define BYT_RT5640_MCLK_25MHZ		BIT(23)
74 #define BYT_RT5640_NO_SPEAKERS		BIT(24)
75 
76 #define BYTCR_INPUT_DEFAULTS				\
77 	(BYT_RT5640_IN3_MAP |				\
78 	 BYT_RT5640_JD_SRC_JD1_IN4P |			\
79 	 BYT_RT5640_OVCD_TH_2000UA |			\
80 	 BYT_RT5640_OVCD_SF_0P75 |			\
81 	 BYT_RT5640_DIFF_MIC)
82 
83 /* in-diff or dmic-pin + jdsrc + ovcd-th + -sf + jd-inv + terminating entry */
84 #define MAX_NO_PROPS 6
85 
86 struct byt_rt5640_private {
87 	struct snd_soc_jack jack;
88 	struct clk *mclk;
89 	struct device *codec_dev;
90 };
91 static bool is_bytcr;
92 
93 static unsigned long byt_rt5640_quirk = BYT_RT5640_MCLK_EN;
94 static int quirk_override = -1;
95 module_param_named(quirk, quirk_override, int, 0444);
96 MODULE_PARM_DESC(quirk, "Board-specific quirk override");
97 
log_quirks(struct device * dev)98 static void log_quirks(struct device *dev)
99 {
100 	int map;
101 	bool has_mclk = false;
102 	bool has_ssp0 = false;
103 	bool has_ssp0_aif1 = false;
104 	bool has_ssp0_aif2 = false;
105 	bool has_ssp2_aif2 = false;
106 
107 	map = BYT_RT5640_MAP(byt_rt5640_quirk);
108 	switch (map) {
109 	case BYT_RT5640_DMIC1_MAP:
110 		dev_info(dev, "quirk DMIC1_MAP enabled\n");
111 		break;
112 	case BYT_RT5640_DMIC2_MAP:
113 		dev_info(dev, "quirk DMIC2_MAP enabled\n");
114 		break;
115 	case BYT_RT5640_IN1_MAP:
116 		dev_info(dev, "quirk IN1_MAP enabled\n");
117 		break;
118 	case BYT_RT5640_IN3_MAP:
119 		dev_info(dev, "quirk IN3_MAP enabled\n");
120 		break;
121 	default:
122 		dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map);
123 		break;
124 	}
125 	if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
126 		dev_info(dev, "quirk realtek,jack-detect-source %ld\n",
127 			 BYT_RT5640_JDSRC(byt_rt5640_quirk));
128 		dev_info(dev, "quirk realtek,over-current-threshold-microamp %ld\n",
129 			 BYT_RT5640_OVCD_TH(byt_rt5640_quirk) * 100);
130 		dev_info(dev, "quirk realtek,over-current-scale-factor %ld\n",
131 			 BYT_RT5640_OVCD_SF(byt_rt5640_quirk));
132 	}
133 	if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
134 		dev_info(dev, "quirk JD_NOT_INV enabled\n");
135 	if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER)
136 		dev_info(dev, "quirk MONO_SPEAKER enabled\n");
137 	if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS)
138 		dev_info(dev, "quirk NO_SPEAKERS enabled\n");
139 	if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
140 		dev_info(dev, "quirk DIFF_MIC enabled\n");
141 	if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
142 		dev_info(dev, "quirk SSP0_AIF1 enabled\n");
143 		has_ssp0 = true;
144 		has_ssp0_aif1 = true;
145 	}
146 	if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
147 		dev_info(dev, "quirk SSP0_AIF2 enabled\n");
148 		has_ssp0 = true;
149 		has_ssp0_aif2 = true;
150 	}
151 	if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
152 		dev_info(dev, "quirk SSP2_AIF2 enabled\n");
153 		has_ssp2_aif2 = true;
154 	}
155 	if (is_bytcr && !has_ssp0)
156 		dev_err(dev, "Invalid routing, bytcr detected but no SSP0-based quirk, audio cannot work with SSP2 on bytcr\n");
157 	if (has_ssp0_aif1 && has_ssp0_aif2)
158 		dev_err(dev, "Invalid routing, SSP0 cannot be connected to both AIF1 and AIF2\n");
159 	if (has_ssp0 && has_ssp2_aif2)
160 		dev_err(dev, "Invalid routing, cannot have both SSP0 and SSP2 connected to codec\n");
161 
162 	if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
163 		dev_info(dev, "quirk MCLK_EN enabled\n");
164 		has_mclk = true;
165 	}
166 	if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
167 		if (has_mclk)
168 			dev_info(dev, "quirk MCLK_25MHZ enabled\n");
169 		else
170 			dev_err(dev, "quirk MCLK_25MHZ enabled but quirk MCLK not selected, will be ignored\n");
171 	}
172 }
173 
byt_rt5640_prepare_and_enable_pll1(struct snd_soc_dai * codec_dai,int rate)174 static int byt_rt5640_prepare_and_enable_pll1(struct snd_soc_dai *codec_dai,
175 					      int rate)
176 {
177 	int ret;
178 
179 	/* Configure the PLL before selecting it */
180 	if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
181 		/* use bitclock as PLL input */
182 		if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
183 		    (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
184 			/* 2x16 bit slots on SSP0 */
185 			ret = snd_soc_dai_set_pll(codec_dai, 0,
186 						  RT5640_PLL1_S_BCLK1,
187 						  rate * 32, rate * 512);
188 		} else {
189 			/* 2x15 bit slots on SSP2 */
190 			ret = snd_soc_dai_set_pll(codec_dai, 0,
191 						  RT5640_PLL1_S_BCLK1,
192 						  rate * 50, rate * 512);
193 		}
194 	} else {
195 		if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
196 			ret = snd_soc_dai_set_pll(codec_dai, 0,
197 						  RT5640_PLL1_S_MCLK,
198 						  25000000, rate * 512);
199 		} else {
200 			ret = snd_soc_dai_set_pll(codec_dai, 0,
201 						  RT5640_PLL1_S_MCLK,
202 						  19200000, rate * 512);
203 		}
204 	}
205 
206 	if (ret < 0) {
207 		dev_err(codec_dai->component->dev, "can't set pll: %d\n", ret);
208 		return ret;
209 	}
210 
211 	ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
212 				     rate * 512, SND_SOC_CLOCK_IN);
213 	if (ret < 0) {
214 		dev_err(codec_dai->component->dev, "can't set clock %d\n", ret);
215 		return ret;
216 	}
217 
218 	return 0;
219 }
220 
221 #define BYT_CODEC_DAI1	"rt5640-aif1"
222 #define BYT_CODEC_DAI2	"rt5640-aif2"
223 
platform_clock_control(struct snd_soc_dapm_widget * w,struct snd_kcontrol * k,int event)224 static int platform_clock_control(struct snd_soc_dapm_widget *w,
225 				  struct snd_kcontrol *k, int  event)
226 {
227 	struct snd_soc_dapm_context *dapm = w->dapm;
228 	struct snd_soc_card *card = dapm->card;
229 	struct snd_soc_dai *codec_dai;
230 	struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
231 	int ret;
232 
233 	codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1);
234 	if (!codec_dai)
235 		codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI2);
236 
237 	if (!codec_dai) {
238 		dev_err(card->dev,
239 			"Codec dai not found; Unable to set platform clock\n");
240 		return -EIO;
241 	}
242 
243 	if (SND_SOC_DAPM_EVENT_ON(event)) {
244 		if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
245 			ret = clk_prepare_enable(priv->mclk);
246 			if (ret < 0) {
247 				dev_err(card->dev,
248 					"could not configure MCLK state\n");
249 				return ret;
250 			}
251 		}
252 		ret = byt_rt5640_prepare_and_enable_pll1(codec_dai, 48000);
253 	} else {
254 		/*
255 		 * Set codec clock source to internal clock before
256 		 * turning off the platform clock. Codec needs clock
257 		 * for Jack detection and button press
258 		 */
259 		ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_RCCLK,
260 					     48000 * 512,
261 					     SND_SOC_CLOCK_IN);
262 		if (!ret) {
263 			if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
264 				clk_disable_unprepare(priv->mclk);
265 		}
266 	}
267 
268 	if (ret < 0) {
269 		dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
270 		return ret;
271 	}
272 
273 	return 0;
274 }
275 
276 static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
277 	SND_SOC_DAPM_HP("Headphone", NULL),
278 	SND_SOC_DAPM_MIC("Headset Mic", NULL),
279 	SND_SOC_DAPM_MIC("Internal Mic", NULL),
280 	SND_SOC_DAPM_SPK("Speaker", NULL),
281 	SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
282 			    platform_clock_control, SND_SOC_DAPM_PRE_PMU |
283 			    SND_SOC_DAPM_POST_PMD),
284 
285 };
286 
287 static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
288 	{"Headphone", NULL, "Platform Clock"},
289 	{"Headset Mic", NULL, "Platform Clock"},
290 	{"Headset Mic", NULL, "MICBIAS1"},
291 	{"IN2P", NULL, "Headset Mic"},
292 	{"Headphone", NULL, "HPOL"},
293 	{"Headphone", NULL, "HPOR"},
294 };
295 
296 static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = {
297 	{"Internal Mic", NULL, "Platform Clock"},
298 	{"DMIC1", NULL, "Internal Mic"},
299 };
300 
301 static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic2_map[] = {
302 	{"Internal Mic", NULL, "Platform Clock"},
303 	{"DMIC2", NULL, "Internal Mic"},
304 };
305 
306 static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = {
307 	{"Internal Mic", NULL, "Platform Clock"},
308 	{"Internal Mic", NULL, "MICBIAS1"},
309 	{"IN1P", NULL, "Internal Mic"},
310 };
311 
312 static const struct snd_soc_dapm_route byt_rt5640_intmic_in3_map[] = {
313 	{"Internal Mic", NULL, "Platform Clock"},
314 	{"Internal Mic", NULL, "MICBIAS1"},
315 	{"IN3P", NULL, "Internal Mic"},
316 };
317 
318 static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif1_map[] = {
319 	{"ssp2 Tx", NULL, "codec_out0"},
320 	{"ssp2 Tx", NULL, "codec_out1"},
321 	{"codec_in0", NULL, "ssp2 Rx"},
322 	{"codec_in1", NULL, "ssp2 Rx"},
323 
324 	{"AIF1 Playback", NULL, "ssp2 Tx"},
325 	{"ssp2 Rx", NULL, "AIF1 Capture"},
326 };
327 
328 static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif2_map[] = {
329 	{"ssp2 Tx", NULL, "codec_out0"},
330 	{"ssp2 Tx", NULL, "codec_out1"},
331 	{"codec_in0", NULL, "ssp2 Rx"},
332 	{"codec_in1", NULL, "ssp2 Rx"},
333 
334 	{"AIF2 Playback", NULL, "ssp2 Tx"},
335 	{"ssp2 Rx", NULL, "AIF2 Capture"},
336 };
337 
338 static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif1_map[] = {
339 	{"ssp0 Tx", NULL, "modem_out"},
340 	{"modem_in", NULL, "ssp0 Rx"},
341 
342 	{"AIF1 Playback", NULL, "ssp0 Tx"},
343 	{"ssp0 Rx", NULL, "AIF1 Capture"},
344 };
345 
346 static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif2_map[] = {
347 	{"ssp0 Tx", NULL, "modem_out"},
348 	{"modem_in", NULL, "ssp0 Rx"},
349 
350 	{"AIF2 Playback", NULL, "ssp0 Tx"},
351 	{"ssp0 Rx", NULL, "AIF2 Capture"},
352 };
353 
354 static const struct snd_soc_dapm_route byt_rt5640_stereo_spk_map[] = {
355 	{"Speaker", NULL, "Platform Clock"},
356 	{"Speaker", NULL, "SPOLP"},
357 	{"Speaker", NULL, "SPOLN"},
358 	{"Speaker", NULL, "SPORP"},
359 	{"Speaker", NULL, "SPORN"},
360 };
361 
362 static const struct snd_soc_dapm_route byt_rt5640_mono_spk_map[] = {
363 	{"Speaker", NULL, "Platform Clock"},
364 	{"Speaker", NULL, "SPOLP"},
365 	{"Speaker", NULL, "SPOLN"},
366 };
367 
368 static const struct snd_kcontrol_new byt_rt5640_controls[] = {
369 	SOC_DAPM_PIN_SWITCH("Headphone"),
370 	SOC_DAPM_PIN_SWITCH("Headset Mic"),
371 	SOC_DAPM_PIN_SWITCH("Internal Mic"),
372 	SOC_DAPM_PIN_SWITCH("Speaker"),
373 };
374 
375 static struct snd_soc_jack_pin rt5640_pins[] = {
376 	{
377 		.pin	= "Headphone",
378 		.mask	= SND_JACK_HEADPHONE,
379 	},
380 	{
381 		.pin	= "Headset Mic",
382 		.mask	= SND_JACK_MICROPHONE,
383 	},
384 };
385 
byt_rt5640_aif1_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)386 static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
387 					struct snd_pcm_hw_params *params)
388 {
389 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
390 	struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0);
391 
392 	return byt_rt5640_prepare_and_enable_pll1(dai, params_rate(params));
393 }
394 
395 /* Please keep this list alphabetically sorted */
396 static const struct dmi_system_id byt_rt5640_quirk_table[] = {
397 	{	/* Acer Iconia One 7 B1-750 */
398 		.matches = {
399 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
400 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "VESPA2"),
401 		},
402 		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
403 					BYT_RT5640_JD_SRC_JD1_IN4P |
404 					BYT_RT5640_OVCD_TH_1500UA |
405 					BYT_RT5640_OVCD_SF_0P75 |
406 					BYT_RT5640_SSP0_AIF1 |
407 					BYT_RT5640_MCLK_EN),
408 	},
409 	{	/* Acer Iconia Tab 8 W1-810 */
410 		.matches = {
411 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Acer"),
412 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Iconia W1-810"),
413 		},
414 		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
415 					BYT_RT5640_JD_SRC_JD1_IN4P |
416 					BYT_RT5640_OVCD_TH_1500UA |
417 					BYT_RT5640_OVCD_SF_0P75 |
418 					BYT_RT5640_SSP0_AIF1 |
419 					BYT_RT5640_MCLK_EN),
420 	},
421 	{	/* Acer One 10 S1002 */
422 		.matches = {
423 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
424 			DMI_MATCH(DMI_PRODUCT_NAME, "One S1002"),
425 		},
426 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
427 					BYT_RT5640_JD_SRC_JD2_IN4N |
428 					BYT_RT5640_OVCD_TH_2000UA |
429 					BYT_RT5640_OVCD_SF_0P75 |
430 					BYT_RT5640_DIFF_MIC |
431 					BYT_RT5640_SSP0_AIF2 |
432 					BYT_RT5640_MCLK_EN),
433 	},
434 	{
435 		.matches = {
436 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
437 			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
438 		},
439 		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
440 					BYT_RT5640_JD_SRC_JD2_IN4N |
441 					BYT_RT5640_OVCD_TH_2000UA |
442 					BYT_RT5640_OVCD_SF_0P75 |
443 					BYT_RT5640_SSP0_AIF1 |
444 					BYT_RT5640_MCLK_EN),
445 	},
446 	{
447 		/* Advantech MICA-071 */
448 		.matches = {
449 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Advantech"),
450 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MICA-071"),
451 		},
452 		/* OVCD Th = 1500uA to reliable detect head-phones vs -set */
453 		.driver_data = (void *)(BYT_RT5640_IN3_MAP |
454 					BYT_RT5640_JD_SRC_JD2_IN4N |
455 					BYT_RT5640_OVCD_TH_1500UA |
456 					BYT_RT5640_OVCD_SF_0P75 |
457 					BYT_RT5640_MONO_SPEAKER |
458 					BYT_RT5640_DIFF_MIC |
459 					BYT_RT5640_MCLK_EN),
460 	},
461 	{
462 		.matches = {
463 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"),
464 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 80 Cesium"),
465 		},
466 		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
467 					BYT_RT5640_MONO_SPEAKER |
468 					BYT_RT5640_SSP0_AIF1 |
469 					BYT_RT5640_MCLK_EN),
470 	},
471 	{
472 		.matches = {
473 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ARCHOS"),
474 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ARCHOS 140 CESIUM"),
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_SSP0_AIF1 |
481 					BYT_RT5640_MCLK_EN),
482 	},
483 	{
484 		.matches = {
485 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
486 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ME176C"),
487 		},
488 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
489 					BYT_RT5640_JD_SRC_JD2_IN4N |
490 					BYT_RT5640_OVCD_TH_2000UA |
491 					BYT_RT5640_OVCD_SF_0P75 |
492 					BYT_RT5640_SSP0_AIF1 |
493 					BYT_RT5640_MCLK_EN),
494 	},
495 	{
496 		.matches = {
497 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
498 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
499 		},
500 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
501 					BYT_RT5640_JD_SRC_JD2_IN4N |
502 					BYT_RT5640_OVCD_TH_2000UA |
503 					BYT_RT5640_OVCD_SF_0P75 |
504 					BYT_RT5640_MCLK_EN),
505 	},
506 	{
507 		.matches = {
508 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
509 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
510 		},
511 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
512 					BYT_RT5640_JD_SRC_JD2_IN4N |
513 					BYT_RT5640_OVCD_TH_2000UA |
514 					BYT_RT5640_OVCD_SF_0P75 |
515 					BYT_RT5640_MONO_SPEAKER |
516 					BYT_RT5640_DIFF_MIC |
517 					BYT_RT5640_SSP0_AIF2 |
518 					BYT_RT5640_MCLK_EN),
519 	},
520 	{	/* Chuwi Vi8 (CWI506) */
521 		.matches = {
522 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
523 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "i86"),
524 			/* The above are too generic, also match BIOS info */
525 			DMI_MATCH(DMI_BIOS_VERSION, "CHUWI.D86JLBNR"),
526 		},
527 		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
528 					BYT_RT5640_MONO_SPEAKER |
529 					BYT_RT5640_SSP0_AIF1 |
530 					BYT_RT5640_MCLK_EN),
531 	},
532 	{
533 		/* Chuwi Vi10 (CWI505) */
534 		.matches = {
535 			DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
536 			DMI_MATCH(DMI_BOARD_NAME, "BYT-PF02"),
537 			DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
538 			DMI_MATCH(DMI_PRODUCT_NAME, "S165"),
539 		},
540 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
541 					BYT_RT5640_JD_SRC_JD2_IN4N |
542 					BYT_RT5640_OVCD_TH_2000UA |
543 					BYT_RT5640_OVCD_SF_0P75 |
544 					BYT_RT5640_DIFF_MIC |
545 					BYT_RT5640_SSP0_AIF1 |
546 					BYT_RT5640_MCLK_EN),
547 	},
548 	{
549 		/* Chuwi Hi8 (CWI509) */
550 		.matches = {
551 			DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"),
552 			DMI_MATCH(DMI_BOARD_NAME, "BYT-PA03C"),
553 			DMI_MATCH(DMI_SYS_VENDOR, "ilife"),
554 			DMI_MATCH(DMI_PRODUCT_NAME, "S806"),
555 		},
556 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
557 					BYT_RT5640_JD_SRC_JD2_IN4N |
558 					BYT_RT5640_OVCD_TH_2000UA |
559 					BYT_RT5640_OVCD_SF_0P75 |
560 					BYT_RT5640_MONO_SPEAKER |
561 					BYT_RT5640_DIFF_MIC |
562 					BYT_RT5640_SSP0_AIF1 |
563 					BYT_RT5640_MCLK_EN),
564 	},
565 	{
566 		.matches = {
567 			DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
568 			DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
569 		},
570 		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP),
571 	},
572 	{	/* Connect Tablet 9 */
573 		.matches = {
574 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Connect"),
575 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Tablet 9"),
576 		},
577 		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
578 					BYT_RT5640_MONO_SPEAKER |
579 					BYT_RT5640_SSP0_AIF1 |
580 					BYT_RT5640_MCLK_EN),
581 	},
582 	{
583 		.matches = {
584 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
585 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
586 		},
587 		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
588 					BYT_RT5640_JD_SRC_JD2_IN4N |
589 					BYT_RT5640_OVCD_TH_2000UA |
590 					BYT_RT5640_OVCD_SF_0P75 |
591 					BYT_RT5640_MONO_SPEAKER |
592 					BYT_RT5640_MCLK_EN),
593 	},
594 	{	/* Estar Beauty HD MID 7316R */
595 		.matches = {
596 			DMI_MATCH(DMI_SYS_VENDOR, "Estar"),
597 			DMI_MATCH(DMI_PRODUCT_NAME, "eSTAR BEAUTY HD Intel Quad core"),
598 		},
599 		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
600 					BYT_RT5640_MONO_SPEAKER |
601 					BYT_RT5640_SSP0_AIF1 |
602 					BYT_RT5640_MCLK_EN),
603 	},
604 	{	/* Glavey TM800A550L */
605 		.matches = {
606 			DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
607 			DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
608 			/* Above strings are too generic, also match on BIOS version */
609 			DMI_MATCH(DMI_BIOS_VERSION, "ZY-8-BI-PX4S70VTR400-X423B-005-D"),
610 		},
611 		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
612 					BYT_RT5640_SSP0_AIF1 |
613 					BYT_RT5640_MCLK_EN),
614 	},
615 	{
616 		.matches = {
617 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
618 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
619 		},
620 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
621 					BYT_RT5640_MCLK_EN),
622 	},
623 	{	/* HP Pavilion x2 10-k0XX, 10-n0XX */
624 		.matches = {
625 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
626 			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion x2 Detachable"),
627 		},
628 		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
629 					BYT_RT5640_JD_SRC_JD2_IN4N |
630 					BYT_RT5640_OVCD_TH_1500UA |
631 					BYT_RT5640_OVCD_SF_0P75 |
632 					BYT_RT5640_SSP0_AIF1 |
633 					BYT_RT5640_MCLK_EN),
634 	},
635 	{	/* HP Pavilion x2 10-p0XX */
636 		.matches = {
637 			DMI_MATCH(DMI_SYS_VENDOR, "HP"),
638 			DMI_MATCH(DMI_PRODUCT_NAME, "HP x2 Detachable 10-p0XX"),
639 		},
640 		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
641 					BYT_RT5640_JD_SRC_JD1_IN4P |
642 					BYT_RT5640_OVCD_TH_2000UA |
643 					BYT_RT5640_OVCD_SF_0P75 |
644 					BYT_RT5640_MCLK_EN),
645 	},
646 	{	/* HP Pro Tablet 408 */
647 		.matches = {
648 			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
649 			DMI_MATCH(DMI_PRODUCT_NAME, "HP Pro Tablet 408"),
650 		},
651 		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
652 					BYT_RT5640_JD_SRC_JD2_IN4N |
653 					BYT_RT5640_OVCD_TH_1500UA |
654 					BYT_RT5640_OVCD_SF_0P75 |
655 					BYT_RT5640_SSP0_AIF1 |
656 					BYT_RT5640_MCLK_EN),
657 	},
658 	{	/* HP Stream 7 */
659 		.matches = {
660 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
661 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP Stream 7 Tablet"),
662 		},
663 		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
664 					BYT_RT5640_MONO_SPEAKER |
665 					BYT_RT5640_JD_NOT_INV |
666 					BYT_RT5640_SSP0_AIF1 |
667 					BYT_RT5640_MCLK_EN),
668 	},
669 	{	/* I.T.Works TW891 */
670 		.matches = {
671 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."),
672 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TW891"),
673 			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "To be filled by O.E.M."),
674 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "TW891"),
675 		},
676 		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
677 					BYT_RT5640_MONO_SPEAKER |
678 					BYT_RT5640_SSP0_AIF1 |
679 					BYT_RT5640_MCLK_EN),
680 	},
681 	{	/* Lamina I8270 / T701BR.SE */
682 		.matches = {
683 			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Lamina"),
684 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "T701BR.SE"),
685 		},
686 		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
687 					BYT_RT5640_MONO_SPEAKER |
688 					BYT_RT5640_JD_NOT_INV |
689 					BYT_RT5640_SSP0_AIF1 |
690 					BYT_RT5640_MCLK_EN),
691 	},
692 	{	/* Lenovo Miix 2 8 */
693 		.matches = {
694 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
695 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "20326"),
696 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "Hiking"),
697 		},
698 		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
699 					BYT_RT5640_JD_SRC_JD2_IN4N |
700 					BYT_RT5640_OVCD_TH_2000UA |
701 					BYT_RT5640_OVCD_SF_0P75 |
702 					BYT_RT5640_MONO_SPEAKER |
703 					BYT_RT5640_MCLK_EN),
704 	},
705 	{	/* Lenovo Miix 3-830 */
706 		.matches = {
707 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LENOVO"),
708 			DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 3-830"),
709 		},
710 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
711 					BYT_RT5640_JD_SRC_JD2_IN4N |
712 					BYT_RT5640_OVCD_TH_2000UA |
713 					BYT_RT5640_OVCD_SF_0P75 |
714 					BYT_RT5640_MONO_SPEAKER |
715 					BYT_RT5640_DIFF_MIC |
716 					BYT_RT5640_SSP0_AIF1 |
717 					BYT_RT5640_MCLK_EN),
718 	},
719 	{	/* Linx Linx7 tablet */
720 		.matches = {
721 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "LINX"),
722 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "LINX7"),
723 		},
724 		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
725 					BYT_RT5640_MONO_SPEAKER |
726 					BYT_RT5640_JD_NOT_INV |
727 					BYT_RT5640_SSP0_AIF1 |
728 					BYT_RT5640_MCLK_EN),
729 	},
730 	{	/* MPMAN Converter 9, similar hw as the I.T.Works TW891 2-in-1 */
731 		.matches = {
732 			DMI_MATCH(DMI_SYS_VENDOR, "MPMAN"),
733 			DMI_MATCH(DMI_PRODUCT_NAME, "Converter9"),
734 		},
735 		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
736 					BYT_RT5640_MONO_SPEAKER |
737 					BYT_RT5640_SSP0_AIF1 |
738 					BYT_RT5640_MCLK_EN),
739 	},
740 	{
741 		/* MPMAN MPWIN895CL */
742 		.matches = {
743 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "MPMAN"),
744 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MPWIN8900CL"),
745 		},
746 		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
747 					BYT_RT5640_MONO_SPEAKER |
748 					BYT_RT5640_SSP0_AIF1 |
749 					BYT_RT5640_MCLK_EN),
750 	},
751 	{	/* MSI S100 tablet */
752 		.matches = {
753 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Micro-Star International Co., Ltd."),
754 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "S100"),
755 		},
756 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
757 					BYT_RT5640_JD_SRC_JD2_IN4N |
758 					BYT_RT5640_OVCD_TH_2000UA |
759 					BYT_RT5640_OVCD_SF_0P75 |
760 					BYT_RT5640_MONO_SPEAKER |
761 					BYT_RT5640_DIFF_MIC |
762 					BYT_RT5640_MCLK_EN),
763 	},
764 	{	/* Nuvison/TMax TM800W560 */
765 		.matches = {
766 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TMAX"),
767 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TM800W560L"),
768 		},
769 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
770 					BYT_RT5640_JD_SRC_JD2_IN4N |
771 					BYT_RT5640_OVCD_TH_2000UA |
772 					BYT_RT5640_OVCD_SF_0P75 |
773 					BYT_RT5640_JD_NOT_INV |
774 					BYT_RT5640_DIFF_MIC |
775 					BYT_RT5640_SSP0_AIF1 |
776 					BYT_RT5640_MCLK_EN),
777 	},
778 	{	/* Onda v975w */
779 		.matches = {
780 			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
781 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
782 			/* The above are too generic, also match BIOS info */
783 			DMI_EXACT_MATCH(DMI_BIOS_VERSION, "5.6.5"),
784 			DMI_EXACT_MATCH(DMI_BIOS_DATE, "07/25/2014"),
785 		},
786 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
787 					BYT_RT5640_JD_SRC_JD2_IN4N |
788 					BYT_RT5640_OVCD_TH_2000UA |
789 					BYT_RT5640_OVCD_SF_0P75 |
790 					BYT_RT5640_DIFF_MIC |
791 					BYT_RT5640_MCLK_EN),
792 	},
793 	{	/* Pipo W4 */
794 		.matches = {
795 			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
796 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
797 			/* The above are too generic, also match BIOS info */
798 			DMI_MATCH(DMI_BIOS_VERSION, "V8L_WIN32_CHIPHD"),
799 		},
800 		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
801 					BYT_RT5640_MONO_SPEAKER |
802 					BYT_RT5640_SSP0_AIF1 |
803 					BYT_RT5640_MCLK_EN),
804 	},
805 	{	/* Point of View Mobii TAB-P800W (V2.0) */
806 		.matches = {
807 			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
808 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
809 			/* The above are too generic, also match BIOS info */
810 			DMI_EXACT_MATCH(DMI_BIOS_VERSION, "3BAIR1014"),
811 			DMI_EXACT_MATCH(DMI_BIOS_DATE, "10/24/2014"),
812 		},
813 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
814 					BYT_RT5640_JD_SRC_JD2_IN4N |
815 					BYT_RT5640_OVCD_TH_2000UA |
816 					BYT_RT5640_OVCD_SF_0P75 |
817 					BYT_RT5640_MONO_SPEAKER |
818 					BYT_RT5640_DIFF_MIC |
819 					BYT_RT5640_SSP0_AIF2 |
820 					BYT_RT5640_MCLK_EN),
821 	},
822 	{	/* Point of View Mobii TAB-P800W (V2.1) */
823 		.matches = {
824 			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
825 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
826 			/* The above are too generic, also match BIOS info */
827 			DMI_EXACT_MATCH(DMI_BIOS_VERSION, "3BAIR1013"),
828 			DMI_EXACT_MATCH(DMI_BIOS_DATE, "08/22/2014"),
829 		},
830 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
831 					BYT_RT5640_JD_SRC_JD2_IN4N |
832 					BYT_RT5640_OVCD_TH_2000UA |
833 					BYT_RT5640_OVCD_SF_0P75 |
834 					BYT_RT5640_MONO_SPEAKER |
835 					BYT_RT5640_DIFF_MIC |
836 					BYT_RT5640_SSP0_AIF2 |
837 					BYT_RT5640_MCLK_EN),
838 	},
839 	{	/* Point of View Mobii TAB-P1005W-232 (V2.0) */
840 		.matches = {
841 			DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "POV"),
842 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "I102A"),
843 		},
844 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
845 					BYT_RT5640_JD_SRC_JD2_IN4N |
846 					BYT_RT5640_OVCD_TH_2000UA |
847 					BYT_RT5640_OVCD_SF_0P75 |
848 					BYT_RT5640_DIFF_MIC |
849 					BYT_RT5640_SSP0_AIF1 |
850 					BYT_RT5640_MCLK_EN),
851 	},
852 	{
853 		/* Prowise PT301 */
854 		.matches = {
855 			DMI_MATCH(DMI_SYS_VENDOR, "Prowise"),
856 			DMI_MATCH(DMI_PRODUCT_NAME, "PT301"),
857 		},
858 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
859 					BYT_RT5640_JD_SRC_JD2_IN4N |
860 					BYT_RT5640_OVCD_TH_2000UA |
861 					BYT_RT5640_OVCD_SF_0P75 |
862 					BYT_RT5640_DIFF_MIC |
863 					BYT_RT5640_SSP0_AIF1 |
864 					BYT_RT5640_MCLK_EN),
865 	},
866 	{
867 		/* Teclast X89 */
868 		.matches = {
869 			DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
870 			DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
871 		},
872 		.driver_data = (void *)(BYT_RT5640_IN3_MAP |
873 					BYT_RT5640_JD_SRC_JD1_IN4P |
874 					BYT_RT5640_OVCD_TH_2000UA |
875 					BYT_RT5640_OVCD_SF_1P0 |
876 					BYT_RT5640_SSP0_AIF1 |
877 					BYT_RT5640_MCLK_EN),
878 	},
879 	{	/* Toshiba Satellite Click Mini L9W-B */
880 		.matches = {
881 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
882 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SATELLITE Click Mini L9W-B"),
883 		},
884 		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
885 					BYT_RT5640_JD_SRC_JD2_IN4N |
886 					BYT_RT5640_OVCD_TH_1500UA |
887 					BYT_RT5640_OVCD_SF_0P75 |
888 					BYT_RT5640_SSP0_AIF1 |
889 					BYT_RT5640_MCLK_EN),
890 	},
891 	{	/* Toshiba Encore WT8-A */
892 		.matches = {
893 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
894 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TOSHIBA WT8-A"),
895 		},
896 		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
897 					BYT_RT5640_JD_SRC_JD2_IN4N |
898 					BYT_RT5640_OVCD_TH_2000UA |
899 					BYT_RT5640_OVCD_SF_0P75 |
900 					BYT_RT5640_JD_NOT_INV |
901 					BYT_RT5640_MCLK_EN),
902 	},
903 	{	/* Toshiba Encore WT10-A */
904 		.matches = {
905 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
906 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "TOSHIBA WT10-A-103"),
907 		},
908 		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
909 					BYT_RT5640_JD_SRC_JD1_IN4P |
910 					BYT_RT5640_OVCD_TH_2000UA |
911 					BYT_RT5640_OVCD_SF_0P75 |
912 					BYT_RT5640_SSP0_AIF2 |
913 					BYT_RT5640_MCLK_EN),
914 	},
915 	{	/* Voyo Winpad A15 */
916 		.matches = {
917 			DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
918 			DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"),
919 			/* Above strings are too generic, also match on BIOS date */
920 			DMI_MATCH(DMI_BIOS_DATE, "11/20/2014"),
921 		},
922 		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
923 					BYT_RT5640_JD_SRC_JD2_IN4N |
924 					BYT_RT5640_OVCD_TH_2000UA |
925 					BYT_RT5640_OVCD_SF_0P75 |
926 					BYT_RT5640_DIFF_MIC |
927 					BYT_RT5640_MCLK_EN),
928 	},
929 	{	/* Catch-all for generic Insyde tablets, must be last */
930 		.matches = {
931 			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
932 		},
933 		.driver_data = (void *)(BYTCR_INPUT_DEFAULTS |
934 					BYT_RT5640_MCLK_EN |
935 					BYT_RT5640_SSP0_AIF1),
936 
937 	},
938 	{}
939 };
940 
941 /*
942  * Note this MUST be called before snd_soc_register_card(), so that the props
943  * are in place before the codec component driver's probe function parses them.
944  */
byt_rt5640_add_codec_device_props(struct device * i2c_dev,struct byt_rt5640_private * priv)945 static int byt_rt5640_add_codec_device_props(struct device *i2c_dev,
946 					     struct byt_rt5640_private *priv)
947 {
948 	struct property_entry props[MAX_NO_PROPS] = {};
949 	int cnt = 0;
950 
951 	switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
952 	case BYT_RT5640_DMIC1_MAP:
953 		props[cnt++] = PROPERTY_ENTRY_U32("realtek,dmic1-data-pin",
954 						  RT5640_DMIC1_DATA_PIN_IN1P);
955 		break;
956 	case BYT_RT5640_DMIC2_MAP:
957 		props[cnt++] = PROPERTY_ENTRY_U32("realtek,dmic2-data-pin",
958 						  RT5640_DMIC2_DATA_PIN_IN1N);
959 		break;
960 	case BYT_RT5640_IN1_MAP:
961 		if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
962 			props[cnt++] =
963 				PROPERTY_ENTRY_BOOL("realtek,in1-differential");
964 		break;
965 	case BYT_RT5640_IN3_MAP:
966 		if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC)
967 			props[cnt++] =
968 				PROPERTY_ENTRY_BOOL("realtek,in3-differential");
969 		break;
970 	}
971 
972 	if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
973 		props[cnt++] = PROPERTY_ENTRY_U32(
974 				    "realtek,jack-detect-source",
975 				    BYT_RT5640_JDSRC(byt_rt5640_quirk));
976 
977 		props[cnt++] = PROPERTY_ENTRY_U32(
978 				    "realtek,over-current-threshold-microamp",
979 				    BYT_RT5640_OVCD_TH(byt_rt5640_quirk) * 100);
980 
981 		props[cnt++] = PROPERTY_ENTRY_U32(
982 				    "realtek,over-current-scale-factor",
983 				    BYT_RT5640_OVCD_SF(byt_rt5640_quirk));
984 	}
985 
986 	if (byt_rt5640_quirk & BYT_RT5640_JD_NOT_INV)
987 		props[cnt++] = PROPERTY_ENTRY_BOOL("realtek,jack-detect-not-inverted");
988 
989 	return device_add_properties(i2c_dev, props);
990 }
991 
byt_rt5640_init(struct snd_soc_pcm_runtime * runtime)992 static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
993 {
994 	struct snd_soc_card *card = runtime->card;
995 	struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
996 	struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component;
997 	const struct snd_soc_dapm_route *custom_map;
998 	int num_routes;
999 	int ret;
1000 
1001 	card->dapm.idle_bias_off = true;
1002 
1003 	/* Start with RC clk for jack-detect (we disable MCLK below) */
1004 	if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
1005 		snd_soc_component_update_bits(component, RT5640_GLB_CLK,
1006 			RT5640_SCLK_SRC_MASK, RT5640_SCLK_SRC_RCCLK);
1007 
1008 	rt5640_sel_asrc_clk_src(component,
1009 				RT5640_DA_STEREO_FILTER |
1010 				RT5640_DA_MONO_L_FILTER	|
1011 				RT5640_DA_MONO_R_FILTER	|
1012 				RT5640_AD_STEREO_FILTER	|
1013 				RT5640_AD_MONO_L_FILTER	|
1014 				RT5640_AD_MONO_R_FILTER,
1015 				RT5640_CLK_SEL_ASRC);
1016 
1017 	ret = snd_soc_add_card_controls(card, byt_rt5640_controls,
1018 					ARRAY_SIZE(byt_rt5640_controls));
1019 	if (ret) {
1020 		dev_err(card->dev, "unable to add card controls\n");
1021 		return ret;
1022 	}
1023 
1024 	switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
1025 	case BYT_RT5640_IN1_MAP:
1026 		custom_map = byt_rt5640_intmic_in1_map;
1027 		num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map);
1028 		break;
1029 	case BYT_RT5640_IN3_MAP:
1030 		custom_map = byt_rt5640_intmic_in3_map;
1031 		num_routes = ARRAY_SIZE(byt_rt5640_intmic_in3_map);
1032 		break;
1033 	case BYT_RT5640_DMIC2_MAP:
1034 		custom_map = byt_rt5640_intmic_dmic2_map;
1035 		num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map);
1036 		break;
1037 	default:
1038 		custom_map = byt_rt5640_intmic_dmic1_map;
1039 		num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map);
1040 	}
1041 
1042 	ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
1043 	if (ret)
1044 		return ret;
1045 
1046 	if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
1047 		ret = snd_soc_dapm_add_routes(&card->dapm,
1048 					byt_rt5640_ssp2_aif2_map,
1049 					ARRAY_SIZE(byt_rt5640_ssp2_aif2_map));
1050 	} else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
1051 		ret = snd_soc_dapm_add_routes(&card->dapm,
1052 					byt_rt5640_ssp0_aif1_map,
1053 					ARRAY_SIZE(byt_rt5640_ssp0_aif1_map));
1054 	} else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
1055 		ret = snd_soc_dapm_add_routes(&card->dapm,
1056 					byt_rt5640_ssp0_aif2_map,
1057 					ARRAY_SIZE(byt_rt5640_ssp0_aif2_map));
1058 	} else {
1059 		ret = snd_soc_dapm_add_routes(&card->dapm,
1060 					byt_rt5640_ssp2_aif1_map,
1061 					ARRAY_SIZE(byt_rt5640_ssp2_aif1_map));
1062 	}
1063 	if (ret)
1064 		return ret;
1065 
1066 	if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) {
1067 		ret = snd_soc_dapm_add_routes(&card->dapm,
1068 					byt_rt5640_mono_spk_map,
1069 					ARRAY_SIZE(byt_rt5640_mono_spk_map));
1070 	} else if (!(byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS)) {
1071 		ret = snd_soc_dapm_add_routes(&card->dapm,
1072 					byt_rt5640_stereo_spk_map,
1073 					ARRAY_SIZE(byt_rt5640_stereo_spk_map));
1074 	}
1075 	if (ret)
1076 		return ret;
1077 
1078 	if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
1079 		/*
1080 		 * The firmware might enable the clock at
1081 		 * boot (this information may or may not
1082 		 * be reflected in the enable clock register).
1083 		 * To change the rate we must disable the clock
1084 		 * first to cover these cases. Due to common
1085 		 * clock framework restrictions that do not allow
1086 		 * to disable a clock that has not been enabled,
1087 		 * we need to enable the clock first.
1088 		 */
1089 		ret = clk_prepare_enable(priv->mclk);
1090 		if (!ret)
1091 			clk_disable_unprepare(priv->mclk);
1092 
1093 		if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ)
1094 			ret = clk_set_rate(priv->mclk, 25000000);
1095 		else
1096 			ret = clk_set_rate(priv->mclk, 19200000);
1097 
1098 		if (ret) {
1099 			dev_err(card->dev, "unable to set MCLK rate\n");
1100 			return ret;
1101 		}
1102 	}
1103 
1104 	if (BYT_RT5640_JDSRC(byt_rt5640_quirk)) {
1105 		ret = snd_soc_card_jack_new(card, "Headset",
1106 					    SND_JACK_HEADSET | SND_JACK_BTN_0,
1107 					    &priv->jack, rt5640_pins,
1108 					    ARRAY_SIZE(rt5640_pins));
1109 		if (ret) {
1110 			dev_err(card->dev, "Jack creation failed %d\n", ret);
1111 			return ret;
1112 		}
1113 		snd_jack_set_key(priv->jack.jack, SND_JACK_BTN_0,
1114 				 KEY_PLAYPAUSE);
1115 		snd_soc_component_set_jack(component, &priv->jack, NULL);
1116 	}
1117 
1118 	return 0;
1119 }
1120 
byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime * rtd,struct snd_pcm_hw_params * params)1121 static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd,
1122 			    struct snd_pcm_hw_params *params)
1123 {
1124 	struct snd_interval *rate = hw_param_interval(params,
1125 			SNDRV_PCM_HW_PARAM_RATE);
1126 	struct snd_interval *channels = hw_param_interval(params,
1127 						SNDRV_PCM_HW_PARAM_CHANNELS);
1128 	int ret, bits;
1129 
1130 	/* The DSP will covert the FE rate to 48k, stereo */
1131 	rate->min = rate->max = 48000;
1132 	channels->min = channels->max = 2;
1133 
1134 	if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
1135 	    (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
1136 		/* set SSP0 to 16-bit */
1137 		params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);
1138 		bits = 16;
1139 	} else {
1140 		/* set SSP2 to 24-bit */
1141 		params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);
1142 		bits = 24;
1143 	}
1144 
1145 	/*
1146 	 * Default mode for SSP configuration is TDM 4 slot, override config
1147 	 * with explicit setting to I2S 2ch. The word length is set with
1148 	 * dai_set_tdm_slot() since there is no other API exposed
1149 	 */
1150 	ret = snd_soc_dai_set_fmt(asoc_rtd_to_cpu(rtd, 0),
1151 				  SND_SOC_DAIFMT_I2S     |
1152 				  SND_SOC_DAIFMT_NB_NF   |
1153 				  SND_SOC_DAIFMT_CBS_CFS);
1154 	if (ret < 0) {
1155 		dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
1156 		return ret;
1157 	}
1158 
1159 	ret = snd_soc_dai_set_tdm_slot(asoc_rtd_to_cpu(rtd, 0), 0x3, 0x3, 2, bits);
1160 	if (ret < 0) {
1161 		dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
1162 		return ret;
1163 	}
1164 
1165 	return 0;
1166 }
1167 
byt_rt5640_aif1_startup(struct snd_pcm_substream * substream)1168 static int byt_rt5640_aif1_startup(struct snd_pcm_substream *substream)
1169 {
1170 	return snd_pcm_hw_constraint_single(substream->runtime,
1171 			SNDRV_PCM_HW_PARAM_RATE, 48000);
1172 }
1173 
1174 static const struct snd_soc_ops byt_rt5640_aif1_ops = {
1175 	.startup = byt_rt5640_aif1_startup,
1176 };
1177 
1178 static const struct snd_soc_ops byt_rt5640_be_ssp2_ops = {
1179 	.hw_params = byt_rt5640_aif1_hw_params,
1180 };
1181 
1182 SND_SOC_DAILINK_DEF(dummy,
1183 	DAILINK_COMP_ARRAY(COMP_DUMMY()));
1184 
1185 SND_SOC_DAILINK_DEF(media,
1186 	DAILINK_COMP_ARRAY(COMP_CPU("media-cpu-dai")));
1187 
1188 SND_SOC_DAILINK_DEF(deepbuffer,
1189 	DAILINK_COMP_ARRAY(COMP_CPU("deepbuffer-cpu-dai")));
1190 
1191 SND_SOC_DAILINK_DEF(ssp2_port,
1192 	/* overwritten for ssp0 routing */
1193 	DAILINK_COMP_ARRAY(COMP_CPU("ssp2-port")));
1194 SND_SOC_DAILINK_DEF(ssp2_codec,
1195 	DAILINK_COMP_ARRAY(COMP_CODEC(
1196 	/* overwritten with HID */ "i2c-10EC5640:00",
1197 	/* changed w/ quirk */	"rt5640-aif1")));
1198 
1199 SND_SOC_DAILINK_DEF(platform,
1200 	DAILINK_COMP_ARRAY(COMP_PLATFORM("sst-mfld-platform")));
1201 
1202 static struct snd_soc_dai_link byt_rt5640_dais[] = {
1203 	[MERR_DPCM_AUDIO] = {
1204 		.name = "Baytrail Audio Port",
1205 		.stream_name = "Baytrail Audio",
1206 		.nonatomic = true,
1207 		.dynamic = 1,
1208 		.dpcm_playback = 1,
1209 		.dpcm_capture = 1,
1210 		.ops = &byt_rt5640_aif1_ops,
1211 		SND_SOC_DAILINK_REG(media, dummy, platform),
1212 	},
1213 	[MERR_DPCM_DEEP_BUFFER] = {
1214 		.name = "Deep-Buffer Audio Port",
1215 		.stream_name = "Deep-Buffer Audio",
1216 		.nonatomic = true,
1217 		.dynamic = 1,
1218 		.dpcm_playback = 1,
1219 		.ops = &byt_rt5640_aif1_ops,
1220 		SND_SOC_DAILINK_REG(deepbuffer, dummy, platform),
1221 	},
1222 		/* back ends */
1223 	{
1224 		.name = "SSP2-Codec",
1225 		.id = 0,
1226 		.no_pcm = 1,
1227 		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
1228 						| SND_SOC_DAIFMT_CBS_CFS,
1229 		.be_hw_params_fixup = byt_rt5640_codec_fixup,
1230 		.nonatomic = true,
1231 		.dpcm_playback = 1,
1232 		.dpcm_capture = 1,
1233 		.init = byt_rt5640_init,
1234 		.ops = &byt_rt5640_be_ssp2_ops,
1235 		SND_SOC_DAILINK_REG(ssp2_port, ssp2_codec, platform),
1236 	},
1237 };
1238 
1239 /* SoC card */
1240 static char byt_rt5640_codec_name[SND_ACPI_I2C_ID_LEN];
1241 #if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
1242 static char byt_rt5640_long_name[40]; /* = "bytcr-rt5640-*-spk-*-mic" */
1243 #endif
1244 static char byt_rt5640_components[32]; /* = "cfg-spk:* cfg-mic:*" */
1245 
byt_rt5640_suspend(struct snd_soc_card * card)1246 static int byt_rt5640_suspend(struct snd_soc_card *card)
1247 {
1248 	struct snd_soc_component *component;
1249 
1250 	if (!BYT_RT5640_JDSRC(byt_rt5640_quirk))
1251 		return 0;
1252 
1253 	for_each_card_components(card, component) {
1254 		if (!strcmp(component->name, byt_rt5640_codec_name)) {
1255 			dev_dbg(component->dev, "disabling jack detect before suspend\n");
1256 			snd_soc_component_set_jack(component, NULL, NULL);
1257 			break;
1258 		}
1259 	}
1260 
1261 	return 0;
1262 }
1263 
byt_rt5640_resume(struct snd_soc_card * card)1264 static int byt_rt5640_resume(struct snd_soc_card *card)
1265 {
1266 	struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
1267 	struct snd_soc_component *component;
1268 
1269 	if (!BYT_RT5640_JDSRC(byt_rt5640_quirk))
1270 		return 0;
1271 
1272 	for_each_card_components(card, component) {
1273 		if (!strcmp(component->name, byt_rt5640_codec_name)) {
1274 			dev_dbg(component->dev, "re-enabling jack detect after resume\n");
1275 			snd_soc_component_set_jack(component, &priv->jack, NULL);
1276 			break;
1277 		}
1278 	}
1279 
1280 	return 0;
1281 }
1282 
1283 #if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
1284 /* use space before codec name to simplify card ID, and simplify driver name */
1285 #define CARD_NAME "bytcht rt5640" /* card name will be 'sof-bytcht rt5640' */
1286 #define DRIVER_NAME "SOF"
1287 #else
1288 #define CARD_NAME "bytcr-rt5640"
1289 #define DRIVER_NAME NULL /* card name will be used for driver name */
1290 #endif
1291 
1292 static struct snd_soc_card byt_rt5640_card = {
1293 	.name = CARD_NAME,
1294 	.driver_name = DRIVER_NAME,
1295 	.owner = THIS_MODULE,
1296 	.dai_link = byt_rt5640_dais,
1297 	.num_links = ARRAY_SIZE(byt_rt5640_dais),
1298 	.dapm_widgets = byt_rt5640_widgets,
1299 	.num_dapm_widgets = ARRAY_SIZE(byt_rt5640_widgets),
1300 	.dapm_routes = byt_rt5640_audio_map,
1301 	.num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map),
1302 	.fully_routed = true,
1303 	.suspend_pre = byt_rt5640_suspend,
1304 	.resume_post = byt_rt5640_resume,
1305 };
1306 
1307 struct acpi_chan_package {   /* ACPICA seems to require 64 bit integers */
1308 	u64 aif_value;       /* 1: AIF1, 2: AIF2 */
1309 	u64 mclock_value;    /* usually 25MHz (0x17d7940), ignored */
1310 };
1311 
snd_byt_rt5640_mc_probe(struct platform_device * pdev)1312 static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
1313 {
1314 	static const char * const map_name[] = { "dmic1", "dmic2", "in1", "in3" };
1315 	__maybe_unused const char *spk_type;
1316 	const struct dmi_system_id *dmi_id;
1317 	struct byt_rt5640_private *priv;
1318 	struct snd_soc_acpi_mach *mach;
1319 	const char *platform_name;
1320 	struct acpi_device *adev;
1321 	struct device *codec_dev;
1322 	int ret_val = 0;
1323 	int dai_index = 0;
1324 	int i, cfg_spk;
1325 
1326 	is_bytcr = false;
1327 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
1328 	if (!priv)
1329 		return -ENOMEM;
1330 
1331 	/* register the soc card */
1332 	byt_rt5640_card.dev = &pdev->dev;
1333 	mach = byt_rt5640_card.dev->platform_data;
1334 	snd_soc_card_set_drvdata(&byt_rt5640_card, priv);
1335 
1336 	/* fix index of codec dai */
1337 	for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) {
1338 		if (!strcmp(byt_rt5640_dais[i].codecs->name,
1339 			    "i2c-10EC5640:00")) {
1340 			dai_index = i;
1341 			break;
1342 		}
1343 	}
1344 
1345 	/* fixup codec name based on HID */
1346 	adev = acpi_dev_get_first_match_dev(mach->id, NULL, -1);
1347 	if (adev) {
1348 		snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
1349 			 "i2c-%s", acpi_dev_name(adev));
1350 		put_device(&adev->dev);
1351 		byt_rt5640_dais[dai_index].codecs->name = byt_rt5640_codec_name;
1352 	}
1353 
1354 	/*
1355 	 * swap SSP0 if bytcr is detected
1356 	 * (will be overridden if DMI quirk is detected)
1357 	 */
1358 	if (soc_intel_is_byt()) {
1359 		if (mach->mach_params.acpi_ipc_irq_index == 0)
1360 			is_bytcr = true;
1361 	}
1362 
1363 	if (is_bytcr) {
1364 		/*
1365 		 * Baytrail CR platforms may have CHAN package in BIOS, try
1366 		 * to find relevant routing quirk based as done on Windows
1367 		 * platforms. We have to read the information directly from the
1368 		 * BIOS, at this stage the card is not created and the links
1369 		 * with the codec driver/pdata are non-existent
1370 		 */
1371 
1372 		struct acpi_chan_package chan_package;
1373 
1374 		/* format specified: 2 64-bit integers */
1375 		struct acpi_buffer format = {sizeof("NN"), "NN"};
1376 		struct acpi_buffer state = {0, NULL};
1377 		struct snd_soc_acpi_package_context pkg_ctx;
1378 		bool pkg_found = false;
1379 
1380 		state.length = sizeof(chan_package);
1381 		state.pointer = &chan_package;
1382 
1383 		pkg_ctx.name = "CHAN";
1384 		pkg_ctx.length = 2;
1385 		pkg_ctx.format = &format;
1386 		pkg_ctx.state = &state;
1387 		pkg_ctx.data_valid = false;
1388 
1389 		pkg_found = snd_soc_acpi_find_package_from_hid(mach->id,
1390 							       &pkg_ctx);
1391 		if (pkg_found) {
1392 			if (chan_package.aif_value == 1) {
1393 				dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n");
1394 				byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF1;
1395 			} else  if (chan_package.aif_value == 2) {
1396 				dev_info(&pdev->dev, "BIOS Routing: AIF2 connected\n");
1397 				byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
1398 			} else {
1399 				dev_info(&pdev->dev, "BIOS Routing isn't valid, ignored\n");
1400 				pkg_found = false;
1401 			}
1402 		}
1403 
1404 		if (!pkg_found) {
1405 			/* no BIOS indications, assume SSP0-AIF2 connection */
1406 			byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
1407 		}
1408 
1409 		/* change defaults for Baytrail-CR capture */
1410 		byt_rt5640_quirk |= BYTCR_INPUT_DEFAULTS;
1411 	} else {
1412 		byt_rt5640_quirk |= BYT_RT5640_DMIC1_MAP |
1413 				    BYT_RT5640_JD_SRC_JD2_IN4N |
1414 				    BYT_RT5640_OVCD_TH_2000UA |
1415 				    BYT_RT5640_OVCD_SF_0P75;
1416 	}
1417 
1418 	/* check quirks before creating card */
1419 	dmi_id = dmi_first_match(byt_rt5640_quirk_table);
1420 	if (dmi_id)
1421 		byt_rt5640_quirk = (unsigned long)dmi_id->driver_data;
1422 	if (quirk_override != -1) {
1423 		dev_info(&pdev->dev, "Overriding quirk 0x%lx => 0x%x\n",
1424 			 byt_rt5640_quirk, quirk_override);
1425 		byt_rt5640_quirk = quirk_override;
1426 	}
1427 
1428 	codec_dev = acpi_get_first_physical_node(adev);
1429 	if (!codec_dev)
1430 		return -EPROBE_DEFER;
1431 	priv->codec_dev = get_device(codec_dev);
1432 
1433 	/* Must be called before register_card, also see declaration comment. */
1434 	ret_val = byt_rt5640_add_codec_device_props(codec_dev, priv);
1435 	if (ret_val)
1436 		goto err;
1437 
1438 	log_quirks(&pdev->dev);
1439 
1440 	if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) ||
1441 	    (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2))
1442 		byt_rt5640_dais[dai_index].codecs->dai_name = "rt5640-aif2";
1443 
1444 	if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
1445 	    (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2))
1446 		byt_rt5640_dais[dai_index].cpus->dai_name = "ssp0-port";
1447 
1448 	if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
1449 		priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
1450 		if (IS_ERR(priv->mclk)) {
1451 			ret_val = PTR_ERR(priv->mclk);
1452 
1453 			dev_err(&pdev->dev,
1454 				"Failed to get MCLK from pmc_plt_clk_3: %d\n",
1455 				ret_val);
1456 
1457 			/*
1458 			 * Fall back to bit clock usage for -ENOENT (clock not
1459 			 * available likely due to missing dependencies), bail
1460 			 * for all other errors, including -EPROBE_DEFER
1461 			 */
1462 			if (ret_val != -ENOENT)
1463 				goto err;
1464 			byt_rt5640_quirk &= ~BYT_RT5640_MCLK_EN;
1465 		}
1466 	}
1467 
1468 	if (byt_rt5640_quirk & BYT_RT5640_NO_SPEAKERS) {
1469 		cfg_spk = 0;
1470 		spk_type = "none";
1471 	} else if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) {
1472 		cfg_spk = 1;
1473 		spk_type = "mono";
1474 	} else {
1475 		cfg_spk = 2;
1476 		spk_type = "stereo";
1477 	}
1478 
1479 	snprintf(byt_rt5640_components, sizeof(byt_rt5640_components),
1480 		 "cfg-spk:%d cfg-mic:%s", cfg_spk,
1481 		 map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]);
1482 	byt_rt5640_card.components = byt_rt5640_components;
1483 #if !IS_ENABLED(CONFIG_SND_SOC_INTEL_USER_FRIENDLY_LONG_NAMES)
1484 	snprintf(byt_rt5640_long_name, sizeof(byt_rt5640_long_name),
1485 		 "bytcr-rt5640-%s-spk-%s-mic", spk_type,
1486 		 map_name[BYT_RT5640_MAP(byt_rt5640_quirk)]);
1487 	byt_rt5640_card.long_name = byt_rt5640_long_name;
1488 #endif
1489 
1490 	/* override plaform name, if required */
1491 	platform_name = mach->mach_params.platform;
1492 
1493 	ret_val = snd_soc_fixup_dai_links_platform_name(&byt_rt5640_card,
1494 							platform_name);
1495 	if (ret_val)
1496 		goto err;
1497 
1498 	ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
1499 
1500 	if (ret_val) {
1501 		dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n",
1502 			ret_val);
1503 		goto err;
1504 	}
1505 	platform_set_drvdata(pdev, &byt_rt5640_card);
1506 	return ret_val;
1507 
1508 err:
1509 	put_device(priv->codec_dev);
1510 	return ret_val;
1511 }
1512 
snd_byt_rt5640_mc_remove(struct platform_device * pdev)1513 static int snd_byt_rt5640_mc_remove(struct platform_device *pdev)
1514 {
1515 	struct snd_soc_card *card = platform_get_drvdata(pdev);
1516 	struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
1517 
1518 	put_device(priv->codec_dev);
1519 	return 0;
1520 }
1521 
1522 static struct platform_driver snd_byt_rt5640_mc_driver = {
1523 	.driver = {
1524 		.name = "bytcr_rt5640",
1525 #if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL)
1526 		.pm = &snd_soc_pm_ops,
1527 #endif
1528 	},
1529 	.probe = snd_byt_rt5640_mc_probe,
1530 	.remove = snd_byt_rt5640_mc_remove,
1531 };
1532 
1533 module_platform_driver(snd_byt_rt5640_mc_driver);
1534 
1535 MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver");
1536 MODULE_AUTHOR("Subhransu S. Prusty <subhransu.s.prusty@intel.com>");
1537 MODULE_LICENSE("GPL v2");
1538 MODULE_ALIAS("platform:bytcr_rt5640");
1539