bytcr_rt5640.c 25.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 *  byt_cr_dpcm_rt5640.c - ASoc Machine driver for Intel Byt CR platform
 *
 *  Copyright (C) 2014 Intel Corp
 *  Author: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */

#include <linux/init.h>
#include <linux/module.h>
22
#include <linux/moduleparam.h>
23
#include <linux/platform_device.h>
24
#include <linux/acpi.h>
25
#include <linux/clk.h>
26
#include <linux/device.h>
27
#include <linux/dmi.h>
28
#include <linux/slab.h>
29 30
#include <asm/cpu_device_id.h>
#include <asm/platform_sst_audio.h>
31 32 33
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
34
#include <sound/jack.h>
35
#include "../../codecs/rt5640.h"
36
#include "../atom/sst-atom-controls.h"
37
#include "../common/sst-acpi.h"
38
#include "../common/sst-dsp.h"
39

40 41 42 43
enum {
	BYT_RT5640_DMIC1_MAP,
	BYT_RT5640_DMIC2_MAP,
	BYT_RT5640_IN1_MAP,
44
	BYT_RT5640_IN3_MAP,
45 46
};

47
#define BYT_RT5640_MAP(quirk)	((quirk) &  GENMASK(7, 0))
48
#define BYT_RT5640_DMIC_EN	BIT(16)
49
#define BYT_RT5640_MONO_SPEAKER BIT(17)
50
#define BYT_RT5640_DIFF_MIC     BIT(18) /* defaut is single-ended */
51 52 53
#define BYT_RT5640_SSP2_AIF2    BIT(19) /* default is using AIF1  */
#define BYT_RT5640_SSP0_AIF1    BIT(20)
#define BYT_RT5640_SSP0_AIF2    BIT(21)
54 55 56 57 58 59
#define BYT_RT5640_MCLK_EN	BIT(22)
#define BYT_RT5640_MCLK_25MHZ	BIT(23)

struct byt_rt5640_private {
	struct clk *mclk;
};
60
static bool is_bytcr;
61

62
static unsigned long byt_rt5640_quirk = BYT_RT5640_MCLK_EN;
63
static unsigned int quirk_override;
64
module_param_named(quirk, quirk_override, uint, 0444);
65
MODULE_PARM_DESC(quirk, "Board-specific quirk override");
66

67 68
static void log_quirks(struct device *dev)
{
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
	int map;
	bool has_dmic = false;
	bool has_mclk = false;
	bool has_ssp0 = false;
	bool has_ssp0_aif1 = false;
	bool has_ssp0_aif2 = false;
	bool has_ssp2_aif2 = false;

	map = BYT_RT5640_MAP(byt_rt5640_quirk);
	switch (map) {
	case BYT_RT5640_DMIC1_MAP:
		dev_info(dev, "quirk DMIC1_MAP enabled\n");
		has_dmic = true;
		break;
	case BYT_RT5640_DMIC2_MAP:
		dev_info(dev, "quirk DMIC2_MAP enabled\n");
		has_dmic = true;
		break;
	case BYT_RT5640_IN1_MAP:
		dev_info(dev, "quirk IN1_MAP enabled\n");
		break;
	case BYT_RT5640_IN3_MAP:
		dev_info(dev, "quirk IN3_MAP enabled\n");
		break;
	default:
		dev_err(dev, "quirk map 0x%x is not supported, microphone input will not work\n", map);
		break;
	}
	if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
		if (has_dmic)
			dev_info(dev, "quirk DMIC enabled\n");
		else
			dev_err(dev, "quirk DMIC enabled but no DMIC input set, will be ignored\n");
	}
103
	if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER)
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
		dev_info(dev, "quirk MONO_SPEAKER enabled\n");
	if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) {
		if (!has_dmic)
			dev_info(dev, "quirk DIFF_MIC enabled\n");
		else
			dev_info(dev, "quirk DIFF_MIC enabled but DMIC input selected, will be ignored\n");
	}
	if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
		dev_info(dev, "quirk SSP0_AIF1 enabled\n");
		has_ssp0 = true;
		has_ssp0_aif1 = true;
	}
	if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
		dev_info(dev, "quirk SSP0_AIF2 enabled\n");
		has_ssp0 = true;
		has_ssp0_aif2 = true;
	}
	if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
		dev_info(dev, "quirk SSP2_AIF2 enabled\n");
		has_ssp2_aif2 = true;
	}
	if (is_bytcr && !has_ssp0)
		dev_err(dev, "Invalid routing, bytcr detected but no SSP0-based quirk, audio cannot work with SSP2 on bytcr\n");
	if (has_ssp0_aif1 && has_ssp0_aif2)
		dev_err(dev, "Invalid routing, SSP0 cannot be connected to both AIF1 and AIF2\n");
	if (has_ssp0 && has_ssp2_aif2)
		dev_err(dev, "Invalid routing, cannot have both SSP0 and SSP2 connected to codec\n");

	if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
		dev_info(dev, "quirk MCLK_EN enabled\n");
		has_mclk = true;
	}
	if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
		if (has_mclk)
			dev_info(dev, "quirk MCLK_25MHZ enabled\n");
		else
			dev_err(dev, "quirk MCLK_25MHZ enabled but quirk MCLK not selected, will be ignored\n");
	}
142 143 144
}


145 146 147 148 149 150 151 152 153 154 155 156
#define BYT_CODEC_DAI1	"rt5640-aif1"
#define BYT_CODEC_DAI2	"rt5640-aif2"

static int platform_clock_control(struct snd_soc_dapm_widget *w,
				  struct snd_kcontrol *k, int  event)
{
	struct snd_soc_dapm_context *dapm = w->dapm;
	struct snd_soc_card *card = dapm->card;
	struct snd_soc_dai *codec_dai;
	struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
	int ret;

157 158 159 160
	codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI1);
	if (!codec_dai)
		codec_dai = snd_soc_card_get_codec_dai(card, BYT_CODEC_DAI2);

161 162 163 164 165 166 167
	if (!codec_dai) {
		dev_err(card->dev,
			"Codec dai not found; Unable to set platform clock\n");
		return -EIO;
	}

	if (SND_SOC_DAPM_EVENT_ON(event)) {
168
		if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
169 170 171
			ret = clk_prepare_enable(priv->mclk);
			if (ret < 0) {
				dev_err(card->dev,
172
					"could not configure MCLK state\n");
173 174 175 176 177 178 179 180 181 182 183 184 185
				return ret;
			}
		}
		ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
					     48000 * 512,
					     SND_SOC_CLOCK_IN);
	} else {
		/*
		 * Set codec clock source to internal clock before
		 * turning off the platform clock. Codec needs clock
		 * for Jack detection and button press
		 */
		ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_RCCLK,
186
					     48000 * 512,
187 188
					     SND_SOC_CLOCK_IN);
		if (!ret) {
189
			if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN)
190 191 192 193 194 195 196 197 198 199 200
				clk_disable_unprepare(priv->mclk);
		}
	}

	if (ret < 0) {
		dev_err(card->dev, "can't set codec sysclk: %d\n", ret);
		return ret;
	}

	return 0;
}
201

202
static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
203 204
	SND_SOC_DAPM_HP("Headphone", NULL),
	SND_SOC_DAPM_MIC("Headset Mic", NULL),
205 206
	SND_SOC_DAPM_MIC("Internal Mic", NULL),
	SND_SOC_DAPM_SPK("Speaker", NULL),
207 208 209 210
	SND_SOC_DAPM_SUPPLY("Platform Clock", SND_SOC_NOPM, 0, 0,
			    platform_clock_control, SND_SOC_DAPM_PRE_PMU |
			    SND_SOC_DAPM_POST_PMD),

211 212
};

213
static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
214 215 216 217 218
	{"Headphone", NULL, "Platform Clock"},
	{"Headset Mic", NULL, "Platform Clock"},
	{"Internal Mic", NULL, "Platform Clock"},
	{"Speaker", NULL, "Platform Clock"},

219
	{"Headset Mic", NULL, "MICBIAS1"},
220
	{"IN2P", NULL, "Headset Mic"},
221 222 223 224
	{"Headphone", NULL, "HPOL"},
	{"Headphone", NULL, "HPOR"},
};

225 226 227 228 229 230 231 232 233 234 235 236 237
static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = {
	{"DMIC1", NULL, "Internal Mic"},
};

static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic2_map[] = {
	{"DMIC2", NULL, "Internal Mic"},
};

static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = {
	{"Internal Mic", NULL, "MICBIAS1"},
	{"IN1P", NULL, "Internal Mic"},
};

238 239 240 241 242
static const struct snd_soc_dapm_route byt_rt5640_intmic_in3_map[] = {
	{"Internal Mic", NULL, "MICBIAS1"},
	{"IN3P", NULL, "Internal Mic"},
};

243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif1_map[] = {
	{"ssp2 Tx", NULL, "codec_out0"},
	{"ssp2 Tx", NULL, "codec_out1"},
	{"codec_in0", NULL, "ssp2 Rx"},
	{"codec_in1", NULL, "ssp2 Rx"},

	{"AIF1 Playback", NULL, "ssp2 Tx"},
	{"ssp2 Rx", NULL, "AIF1 Capture"},
};

static const struct snd_soc_dapm_route byt_rt5640_ssp2_aif2_map[] = {
	{"ssp2 Tx", NULL, "codec_out0"},
	{"ssp2 Tx", NULL, "codec_out1"},
	{"codec_in0", NULL, "ssp2 Rx"},
	{"codec_in1", NULL, "ssp2 Rx"},

	{"AIF2 Playback", NULL, "ssp2 Tx"},
	{"ssp2 Rx", NULL, "AIF2 Capture"},
};

263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278
static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif1_map[] = {
	{"ssp0 Tx", NULL, "modem_out"},
	{"modem_in", NULL, "ssp0 Rx"},

	{"AIF1 Playback", NULL, "ssp0 Tx"},
	{"ssp0 Rx", NULL, "AIF1 Capture"},
};

static const struct snd_soc_dapm_route byt_rt5640_ssp0_aif2_map[] = {
	{"ssp0 Tx", NULL, "modem_out"},
	{"modem_in", NULL, "ssp0 Rx"},

	{"AIF2 Playback", NULL, "ssp0 Tx"},
	{"ssp0 Rx", NULL, "AIF2 Capture"},
};

279 280 281 282 283 284 285 286 287 288 289 290
static const struct snd_soc_dapm_route byt_rt5640_stereo_spk_map[] = {
	{"Speaker", NULL, "SPOLP"},
	{"Speaker", NULL, "SPOLN"},
	{"Speaker", NULL, "SPORP"},
	{"Speaker", NULL, "SPORN"},
};

static const struct snd_soc_dapm_route byt_rt5640_mono_spk_map[] = {
	{"Speaker", NULL, "SPOLP"},
	{"Speaker", NULL, "SPOLN"},
};

291
static const struct snd_kcontrol_new byt_rt5640_controls[] = {
292 293
	SOC_DAPM_PIN_SWITCH("Headphone"),
	SOC_DAPM_PIN_SWITCH("Headset Mic"),
294 295
	SOC_DAPM_PIN_SWITCH("Internal Mic"),
	SOC_DAPM_PIN_SWITCH("Speaker"),
296 297
};

298
static int byt_rt5640_aif1_hw_params(struct snd_pcm_substream *substream,
299 300 301 302 303 304 305 306 307
					struct snd_pcm_hw_params *params)
{
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_dai *codec_dai = rtd->codec_dai;
	int ret;

	ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
				     params_rate(params) * 512,
				     SND_SOC_CLOCK_IN);
308

309 310 311 312 313
	if (ret < 0) {
		dev_err(rtd->dev, "can't set codec clock %d\n", ret);
		return ret;
	}

314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
	if (!(byt_rt5640_quirk & BYT_RT5640_MCLK_EN)) {
		/* use bitclock as PLL input */
		if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
			(byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {

			/* 2x16 bit slots on SSP0 */
			ret = snd_soc_dai_set_pll(codec_dai, 0,
						RT5640_PLL1_S_BCLK1,
						params_rate(params) * 32,
						params_rate(params) * 512);
		} else {
			/* 2x15 bit slots on SSP2 */
			ret = snd_soc_dai_set_pll(codec_dai, 0,
						RT5640_PLL1_S_BCLK1,
						params_rate(params) * 50,
						params_rate(params) * 512);
		}
331
	} else {
332 333 334 335 336 337 338 339 340 341 342
		if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ) {
			ret = snd_soc_dai_set_pll(codec_dai, 0,
						RT5640_PLL1_S_MCLK,
						25000000,
						params_rate(params) * 512);
		} else {
			ret = snd_soc_dai_set_pll(codec_dai, 0,
						RT5640_PLL1_S_MCLK,
						19200000,
						params_rate(params) * 512);
		}
343 344
	}

345 346 347 348 349 350 351 352
	if (ret < 0) {
		dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
		return ret;
	}

	return 0;
}

353 354 355 356 357 358 359 360 361 362
static int byt_rt5640_quirk_cb(const struct dmi_system_id *id)
{
	byt_rt5640_quirk = (unsigned long)id->driver_data;
	return 1;
}

static const struct dmi_system_id byt_rt5640_quirk_table[] = {
	{
		.callback = byt_rt5640_quirk_cb,
		.matches = {
363 364
			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TA"),
365
		},
366 367
		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
					BYT_RT5640_MCLK_EN),
368 369 370 371
	},
	{
		.callback = byt_rt5640_quirk_cb,
		.matches = {
372 373 374
			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100TAF"),
		},
375 376 377 378 379
		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
					BYT_RT5640_MONO_SPEAKER |
					BYT_RT5640_DIFF_MIC |
					BYT_RT5640_SSP0_AIF2 |
					BYT_RT5640_MCLK_EN),
380 381 382 383 384 385
	},
	{
		.callback = byt_rt5640_quirk_cb,
		.matches = {
			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "DellInc."),
			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
386
		},
387 388 389
		.driver_data = (void *)(BYT_RT5640_DMIC2_MAP |
					BYT_RT5640_DMIC_EN |
					BYT_RT5640_MCLK_EN),
390
	},
391 392 393
	{
		.callback = byt_rt5640_quirk_cb,
		.matches = {
394 395
			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "HP ElitePad 1000 G2"),
396
		},
397 398
		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
					BYT_RT5640_MCLK_EN),
399
	},
400 401 402 403 404 405
	{
		.callback = byt_rt5640_quirk_cb,
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Circuitco"),
			DMI_MATCH(DMI_PRODUCT_NAME, "Minnowboard Max B3 PLATFORM"),
		},
406 407
		.driver_data = (void *)(BYT_RT5640_DMIC1_MAP |
					BYT_RT5640_DMIC_EN),
408
	},
409 410 411 412 413 414
	{
		.callback = byt_rt5640_quirk_cb,
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "TECLAST"),
			DMI_MATCH(DMI_BOARD_NAME, "tPAD"),
		},
415 416 417
		.driver_data = (void *)(BYT_RT5640_IN3_MAP |
					BYT_RT5640_MCLK_EN |
					BYT_RT5640_SSP0_AIF1),
418
	},
419 420 421 422 423 424
	{
		.callback = byt_rt5640_quirk_cb,
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
		},
425
		.driver_data = (void *)(BYT_RT5640_IN1_MAP |
426 427 428
						 BYT_RT5640_MCLK_EN |
						 BYT_RT5640_SSP0_AIF1),

429 430 431 432 433 434
	},
	{
		.callback = byt_rt5640_quirk_cb,
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
		},
435 436 437
		.driver_data = (void *)(BYT_RT5640_IN3_MAP |
					BYT_RT5640_MCLK_EN |
					BYT_RT5640_SSP0_AIF1),
438 439

	},
440 441 442
	{}
};

443 444 445
static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
{
	struct snd_soc_card *card = runtime->card;
446
	struct byt_rt5640_private *priv = snd_soc_card_get_drvdata(card);
447 448
	struct snd_soc_codec *codec = runtime->codec;
	const struct snd_soc_dapm_route *custom_map;
449
	int num_routes;
450
	int ret;
451 452 453

	card->dapm.idle_bias_off = true;

454 455
	rt5640_sel_asrc_clk_src(codec,
				RT5640_DA_STEREO_FILTER |
456 457 458 459 460
				RT5640_DA_MONO_L_FILTER	|
				RT5640_DA_MONO_R_FILTER	|
				RT5640_AD_STEREO_FILTER	|
				RT5640_AD_MONO_L_FILTER	|
				RT5640_AD_MONO_R_FILTER,
461 462
				RT5640_CLK_SEL_ASRC);

463 464 465 466 467 468 469 470 471 472 473 474
	ret = snd_soc_add_card_controls(card, byt_rt5640_controls,
					ARRAY_SIZE(byt_rt5640_controls));
	if (ret) {
		dev_err(card->dev, "unable to add card controls\n");
		return ret;
	}

	switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
	case BYT_RT5640_IN1_MAP:
		custom_map = byt_rt5640_intmic_in1_map;
		num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map);
		break;
475 476 477 478
	case BYT_RT5640_IN3_MAP:
		custom_map = byt_rt5640_intmic_in3_map;
		num_routes = ARRAY_SIZE(byt_rt5640_intmic_in3_map);
		break;
479 480 481 482 483 484 485 486 487 488 489 490 491
	case BYT_RT5640_DMIC2_MAP:
		custom_map = byt_rt5640_intmic_dmic2_map;
		num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map);
		break;
	default:
		custom_map = byt_rt5640_intmic_dmic1_map;
		num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map);
	}

	ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
	if (ret)
		return ret;

492 493 494 495
	if (byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) {
		ret = snd_soc_dapm_add_routes(&card->dapm,
					byt_rt5640_ssp2_aif2_map,
					ARRAY_SIZE(byt_rt5640_ssp2_aif2_map));
496 497 498 499 500 501 502 503
	} else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) {
		ret = snd_soc_dapm_add_routes(&card->dapm,
					byt_rt5640_ssp0_aif1_map,
					ARRAY_SIZE(byt_rt5640_ssp0_aif1_map));
	} else if (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2) {
		ret = snd_soc_dapm_add_routes(&card->dapm,
					byt_rt5640_ssp0_aif2_map,
					ARRAY_SIZE(byt_rt5640_ssp0_aif2_map));
504 505 506 507 508 509 510 511
	} else {
		ret = snd_soc_dapm_add_routes(&card->dapm,
					byt_rt5640_ssp2_aif1_map,
					ARRAY_SIZE(byt_rt5640_ssp2_aif1_map));
	}
	if (ret)
		return ret;

512 513 514 515 516 517 518 519 520 521 522 523
	if (byt_rt5640_quirk & BYT_RT5640_MONO_SPEAKER) {
		ret = snd_soc_dapm_add_routes(&card->dapm,
					byt_rt5640_mono_spk_map,
					ARRAY_SIZE(byt_rt5640_mono_spk_map));
	} else {
		ret = snd_soc_dapm_add_routes(&card->dapm,
					byt_rt5640_stereo_spk_map,
					ARRAY_SIZE(byt_rt5640_stereo_spk_map));
	}
	if (ret)
		return ret;

524 525 526 527 528
	if (byt_rt5640_quirk & BYT_RT5640_DIFF_MIC) {
		snd_soc_update_bits(codec,  RT5640_IN1_IN2, RT5640_IN_DF1,
				    RT5640_IN_DF1);
	}

529 530 531 532 533 534 535 536 537
	if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
		ret = rt5640_dmic_enable(codec, 0, 0);
		if (ret)
			return ret;
	}

	snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
	snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");

538
	if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
		/*
		 * The firmware might enable the clock at
		 * boot (this information may or may not
		 * be reflected in the enable clock register).
		 * To change the rate we must disable the clock
		 * first to cover these cases. Due to common
		 * clock framework restrictions that do not allow
		 * to disable a clock that has not been enabled,
		 * we need to enable the clock first.
		 */
		ret = clk_prepare_enable(priv->mclk);
		if (!ret)
			clk_disable_unprepare(priv->mclk);

		if (byt_rt5640_quirk & BYT_RT5640_MCLK_25MHZ)
			ret = clk_set_rate(priv->mclk, 25000000);
		else
			ret = clk_set_rate(priv->mclk, 19200000);

		if (ret)
			dev_err(card->dev, "unable to set MCLK rate\n");
	}

562 563 564
	return ret;
}

565
static const struct snd_soc_pcm_stream byt_rt5640_dai_params = {
566 567 568 569 570 571 572
	.formats = SNDRV_PCM_FMTBIT_S24_LE,
	.rate_min = 48000,
	.rate_max = 48000,
	.channels_min = 2,
	.channels_max = 2,
};

573
static int byt_rt5640_codec_fixup(struct snd_soc_pcm_runtime *rtd,
574 575 576 577 578 579
			    struct snd_pcm_hw_params *params)
{
	struct snd_interval *rate = hw_param_interval(params,
			SNDRV_PCM_HW_PARAM_RATE);
	struct snd_interval *channels = hw_param_interval(params,
						SNDRV_PCM_HW_PARAM_CHANNELS);
580
	int ret;
581

582
	/* The DSP will covert the FE rate to 48k, stereo */
583 584 585
	rate->min = rate->max = 48000;
	channels->min = channels->max = 2;

586 587 588
	if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
		(byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {

589
		/* set SSP0 to 16-bit */
590 591 592 593 594 595 596 597 598
		params_set_format(params, SNDRV_PCM_FORMAT_S16_LE);

		/*
		 * Default mode for SSP configuration is TDM 4 slot, override config
		 * with explicit setting to I2S 2ch 16-bit. The word length is set with
		 * dai_set_tdm_slot() since there is no other API exposed
		 */
		ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
					SND_SOC_DAIFMT_I2S     |
599
					SND_SOC_DAIFMT_NB_NF   |
600 601 602 603 604 605
					SND_SOC_DAIFMT_CBS_CFS
			);
		if (ret < 0) {
			dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
			return ret;
		}
606

607 608 609 610 611 612 613
		ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 16);
		if (ret < 0) {
			dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
			return ret;
		}

	} else {
614

615 616 617 618 619 620 621 622 623 624
		/* set SSP2 to 24-bit */
		params_set_format(params, SNDRV_PCM_FORMAT_S24_LE);

		/*
		 * Default mode for SSP configuration is TDM 4 slot, override config
		 * with explicit setting to I2S 2ch 24-bit. The word length is set with
		 * dai_set_tdm_slot() since there is no other API exposed
		 */
		ret = snd_soc_dai_set_fmt(rtd->cpu_dai,
					SND_SOC_DAIFMT_I2S     |
625
					SND_SOC_DAIFMT_NB_NF   |
626 627 628 629 630 631 632 633 634 635 636 637 638
					SND_SOC_DAIFMT_CBS_CFS
			);
		if (ret < 0) {
			dev_err(rtd->dev, "can't set format to I2S, err %d\n", ret);
			return ret;
		}

		ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2, 24);
		if (ret < 0) {
			dev_err(rtd->dev, "can't set I2S config, err %d\n", ret);
			return ret;
		}
	}
639 640 641
	return 0;
}

642
static int byt_rt5640_aif1_startup(struct snd_pcm_substream *substream)
643
{
644 645
	return snd_pcm_hw_constraint_single(substream->runtime,
			SNDRV_PCM_HW_PARAM_RATE, 48000);
646 647
}

648
static const struct snd_soc_ops byt_rt5640_aif1_ops = {
649
	.startup = byt_rt5640_aif1_startup,
650 651
};

652
static const struct snd_soc_ops byt_rt5640_be_ssp2_ops = {
653
	.hw_params = byt_rt5640_aif1_hw_params,
654 655
};

656
static struct snd_soc_dai_link byt_rt5640_dais[] = {
657 658 659 660 661 662 663
	[MERR_DPCM_AUDIO] = {
		.name = "Baytrail Audio Port",
		.stream_name = "Baytrail Audio",
		.cpu_dai_name = "media-cpu-dai",
		.codec_dai_name = "snd-soc-dummy-dai",
		.codec_name = "snd-soc-dummy",
		.platform_name = "sst-mfld-platform",
664
		.nonatomic = true,
665 666 667
		.dynamic = 1,
		.dpcm_playback = 1,
		.dpcm_capture = 1,
668
		.ops = &byt_rt5640_aif1_ops,
669
	},
670 671 672 673 674 675 676 677 678 679 680 681
	[MERR_DPCM_DEEP_BUFFER] = {
		.name = "Deep-Buffer Audio Port",
		.stream_name = "Deep-Buffer Audio",
		.cpu_dai_name = "deepbuffer-cpu-dai",
		.codec_dai_name = "snd-soc-dummy-dai",
		.codec_name = "snd-soc-dummy",
		.platform_name = "sst-mfld-platform",
		.nonatomic = true,
		.dynamic = 1,
		.dpcm_playback = 1,
		.ops = &byt_rt5640_aif1_ops,
	},
682 683 684 685 686 687 688 689 690 691 692
	[MERR_DPCM_COMPR] = {
		.name = "Baytrail Compressed Port",
		.stream_name = "Baytrail Compress",
		.cpu_dai_name = "compress-cpu-dai",
		.codec_dai_name = "snd-soc-dummy-dai",
		.codec_name = "snd-soc-dummy",
		.platform_name = "sst-mfld-platform",
	},
		/* back ends */
	{
		.name = "SSP2-Codec",
693
		.id = 1,
694
		.cpu_dai_name = "ssp2-port", /* overwritten for ssp0 routing */
695 696
		.platform_name = "sst-mfld-platform",
		.no_pcm = 1,
697
		.codec_dai_name = "rt5640-aif1", /* changed w/ quirk */
698
		.codec_name = "i2c-10EC5640:00", /* overwritten with HID */
699 700
		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
						| SND_SOC_DAIFMT_CBS_CFS,
701
		.be_hw_params_fixup = byt_rt5640_codec_fixup,
702
		.ignore_suspend = 1,
703
		.nonatomic = true,
704 705
		.dpcm_playback = 1,
		.dpcm_capture = 1,
706
		.init = byt_rt5640_init,
707
		.ops = &byt_rt5640_be_ssp2_ops,
708 709 710 711
	},
};

/* SoC card */
712
static struct snd_soc_card byt_rt5640_card = {
713
	.name = "bytcr-rt5640",
A
Axel Lin 已提交
714
	.owner = THIS_MODULE,
715 716 717 718 719 720
	.dai_link = byt_rt5640_dais,
	.num_links = ARRAY_SIZE(byt_rt5640_dais),
	.dapm_widgets = byt_rt5640_widgets,
	.num_dapm_widgets = ARRAY_SIZE(byt_rt5640_widgets),
	.dapm_routes = byt_rt5640_audio_map,
	.num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map),
721
	.fully_routed = true,
722 723
};

724
static char byt_rt5640_codec_name[16]; /* i2c-<HID>:00 with HID being 8 chars */
725
static char byt_rt5640_codec_aif_name[12]; /*  = "rt5640-aif[1|2]" */
726
static char byt_rt5640_cpu_dai_name[10]; /*  = "ssp[0|2]-port" */
727

728 729
static bool is_valleyview(void)
{
730
	static const struct x86_cpu_id cpu_ids[] = {
731 732 733 734 735 736 737 738 739
		{ X86_VENDOR_INTEL, 6, 55 }, /* Valleyview, Bay Trail */
		{}
	};

	if (!x86_match_cpu(cpu_ids))
		return false;
	return true;
}

740 741 742 743
struct acpi_chan_package {   /* ACPICA seems to require 64 bit integers */
	u64 aif_value;       /* 1: AIF1, 2: AIF2 */
	u64 mclock_value;    /* usually 25MHz (0x17d7940), ignored */
};
744

745
static int snd_byt_rt5640_mc_probe(struct platform_device *pdev)
746
{
747
	struct byt_rt5640_private *priv;
748
	struct sst_acpi_mach *mach;
749
	const char *i2c_name = NULL;
750
	int ret_val = 0;
751
	int dai_index;
752
	int i;
753

754
	is_bytcr = false;
755 756 757
	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_ATOMIC);
	if (!priv)
		return -ENOMEM;
758 759

	/* register the soc card */
760
	byt_rt5640_card.dev = &pdev->dev;
761
	mach = byt_rt5640_card.dev->platform_data;
762
	snd_soc_card_set_drvdata(&byt_rt5640_card, priv);
763

764 765 766 767 768 769 770 771 772
	/* fix index of codec dai */
	dai_index = MERR_DPCM_COMPR + 1;
	for (i = 0; i < ARRAY_SIZE(byt_rt5640_dais); i++) {
		if (!strcmp(byt_rt5640_dais[i].codec_name, "i2c-10EC5640:00")) {
			dai_index = i;
			break;
		}
	}

773
	/* fixup codec name based on HID */
774
	i2c_name = sst_acpi_find_name_from_hid(mach->id);
775
	if (i2c_name) {
776 777 778 779 780
		snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name),
			"%s%s", "i2c-", i2c_name);

		byt_rt5640_dais[dai_index].codec_name = byt_rt5640_codec_name;
	}
781

782 783 784 785 786 787 788 789
	/*
	 * swap SSP0 if bytcr is detected
	 * (will be overridden if DMI quirk is detected)
	 */
	if (is_valleyview()) {
		struct sst_platform_info *p_info = mach->pdata;
		const struct sst_res_info *res_info = p_info->res_info;

790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835
		if (res_info->acpi_ipc_irq_index == 0)
			is_bytcr = true;
	}

	if (is_bytcr) {
		/*
		 * Baytrail CR platforms may have CHAN package in BIOS, try
		 * to find relevant routing quirk based as done on Windows
		 * platforms. We have to read the information directly from the
		 * BIOS, at this stage the card is not created and the links
		 * with the codec driver/pdata are non-existent
		 */

		struct acpi_chan_package chan_package;

		/* format specified: 2 64-bit integers */
		struct acpi_buffer format = {sizeof("NN"), "NN"};
		struct acpi_buffer state = {0, NULL};
		struct sst_acpi_package_context pkg_ctx;
		bool pkg_found = false;

		state.length = sizeof(chan_package);
		state.pointer = &chan_package;

		pkg_ctx.name = "CHAN";
		pkg_ctx.length = 2;
		pkg_ctx.format = &format;
		pkg_ctx.state = &state;
		pkg_ctx.data_valid = false;

		pkg_found = sst_acpi_find_package_from_hid(mach->id, &pkg_ctx);
		if (pkg_found) {
			if (chan_package.aif_value == 1) {
				dev_info(&pdev->dev, "BIOS Routing: AIF1 connected\n");
				byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF1;
			} else  if (chan_package.aif_value == 2) {
				dev_info(&pdev->dev, "BIOS Routing: AIF2 connected\n");
				byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
			} else {
				dev_info(&pdev->dev, "BIOS Routing isn't valid, ignored\n");
				pkg_found = false;
			}
		}

		if (!pkg_found) {
			/* no BIOS indications, assume SSP0-AIF2 connection */
836 837
			byt_rt5640_quirk |= BYT_RT5640_SSP0_AIF2;
		}
838 839 840 841 842 843 844

		/* change defaults for Baytrail-CR capture */
		byt_rt5640_quirk |= BYT_RT5640_IN1_MAP;
		byt_rt5640_quirk |= BYT_RT5640_DIFF_MIC;
	} else {
		byt_rt5640_quirk |= (BYT_RT5640_DMIC1_MAP |
				BYT_RT5640_DMIC_EN);
845 846
	}

847 848
	/* check quirks before creating card */
	dmi_check_system(byt_rt5640_quirk_table);
849
	if (quirk_override) {
850
		dev_info(&pdev->dev, "Overriding quirk 0x%x => 0x%x\n",
851 852 853
			 (unsigned int)byt_rt5640_quirk, quirk_override);
		byt_rt5640_quirk = quirk_override;
	}
854
	log_quirks(&pdev->dev);
855

856 857
	if ((byt_rt5640_quirk & BYT_RT5640_SSP2_AIF2) ||
	    (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {
858 859 860 861 862 863 864 865 866 867

		/* fixup codec aif name */
		snprintf(byt_rt5640_codec_aif_name,
			sizeof(byt_rt5640_codec_aif_name),
			"%s", "rt5640-aif2");

		byt_rt5640_dais[dai_index].codec_dai_name =
			byt_rt5640_codec_aif_name;
	}

868 869 870 871 872 873 874 875 876 877 878 879
	if ((byt_rt5640_quirk & BYT_RT5640_SSP0_AIF1) ||
	    (byt_rt5640_quirk & BYT_RT5640_SSP0_AIF2)) {

		/* fixup cpu dai name name */
		snprintf(byt_rt5640_cpu_dai_name,
			sizeof(byt_rt5640_cpu_dai_name),
			"%s", "ssp0-port");

		byt_rt5640_dais[dai_index].cpu_dai_name =
			byt_rt5640_cpu_dai_name;
	}

880
	if (byt_rt5640_quirk & BYT_RT5640_MCLK_EN) {
881 882
		priv->mclk = devm_clk_get(&pdev->dev, "pmc_plt_clk_3");
		if (IS_ERR(priv->mclk)) {
883 884
			ret_val = PTR_ERR(priv->mclk);

885
			dev_err(&pdev->dev,
886 887 888 889 890 891 892 893 894 895 896
				"Failed to get MCLK from pmc_plt_clk_3: %d\n",
				ret_val);

			/*
			 * Fall back to bit clock usage for -ENOENT (clock not
			 * available likely due to missing dependencies), bail
			 * for all other errors, including -EPROBE_DEFER
			 */
			if (ret_val != -ENOENT)
				return ret_val;
			byt_rt5640_quirk &= ~BYT_RT5640_MCLK_EN;
897 898 899
		}
	}

900
	ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_rt5640_card);
901 902

	if (ret_val) {
903 904
		dev_err(&pdev->dev, "devm_snd_soc_register_card failed %d\n",
			ret_val);
905 906
		return ret_val;
	}
907
	platform_set_drvdata(pdev, &byt_rt5640_card);
908 909 910
	return ret_val;
}

911
static struct platform_driver snd_byt_rt5640_mc_driver = {
912
	.driver = {
913
		.name = "bytcr_rt5640",
914
	},
915
	.probe = snd_byt_rt5640_mc_probe,
916 917
};

918
module_platform_driver(snd_byt_rt5640_mc_driver);
919 920 921 922

MODULE_DESCRIPTION("ASoC Intel(R) Baytrail CR Machine driver");
MODULE_AUTHOR("Subhransu S. Prusty <subhransu.s.prusty@intel.com>");
MODULE_LICENSE("GPL v2");
923
MODULE_ALIAS("platform:bytcr_rt5640");