cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

bytcr_rt5640.c (54499B)


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