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