Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bbd4417a authored by Aviral Gupta's avatar Aviral Gupta
Browse files

ASoC: msm8939: add the support for the tomtom codec in 8939



Add the support for the tomtom codec on the 8939 as an
external codec.
Add the lsm FE and BE for the sva support.

Change-Id: I587b40d9cef3f349f4d8cc81e16c132abcdee7d4
Signed-off-by: default avatarAviral Gupta <aviralg@codeaurora.org>
parent bf072e59
Loading
Loading
Loading
Loading
+188 −163
Original line number Diff line number Diff line
@@ -79,23 +79,12 @@ static int msm_slim_0_tx_ch = 1;
static int msm_btsco_rate = BTSCO_RATE_8KHZ;
static int msm_btsco_ch = 1;
static int msm8939_spk_control = 1;
static int vdd_spkr_gpio = -1;
static int clk_users;
static struct platform_device *spdev;

static int msm_proxy_rx_ch = 2;
static void *adsp_state_notifier;

struct msm8939_asoc_mach_data {
	int mclk_gpio;
	u32 mclk_freq;
	int us_euro_gpio;
	struct mutex cdc_mclk_mutex;
	struct afe_digital_clk_cfg digital_cdc_clk;
	struct delayed_work hs_detect_dwork;
	struct snd_soc_codec *codec;
};

static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, int enable,
					bool dapm);
static struct wcd9xxx_mbhc_config wcd9xxx_mbhc_cfg = {
@@ -205,12 +194,28 @@ struct cdc_pinctrl_info {
	struct pinctrl_state *cdc_slim_act;
	struct pinctrl_state *cross_conn_det_sus;
	struct pinctrl_state *cross_conn_det_act;
	struct pinctrl_state *cdc_vdd_spkr_sus;
	struct pinctrl_state *cdc_vdd_spkr_act;
};

struct cdc_pinctrl_info pinctrl_info;
struct msm8939_codec {
	int (*mclk_enable_fn) (struct snd_soc_codec *codec,
			       int mclk_enable, bool dapm);
	void *(*get_afe_config_fn) (struct snd_soc_codec *codec,
				   enum afe_config_type config_type);
	int (*mbhc_hs_detect) (struct snd_soc_codec *codec,
			       struct wcd9xxx_mbhc_config *mbhc_cfg);
};

struct msm8939_asoc_mach_data {
	int mclk_gpio;
	u32 mclk_freq;
	int us_euro_gpio;
	struct mutex cdc_mclk_mutex;
	struct afe_digital_clk_cfg digital_cdc_clk;
	struct delayed_work hs_detect_dwork;
	struct snd_soc_codec *codec;
	struct msm8939_codec msm8939_codec_fn;
	struct cdc_pinctrl_info pinctrl_info;
};

static inline int param_is_mask(int p)
{
@@ -302,34 +307,28 @@ static int msm_snd_enable_codec_ext_clk(struct snd_soc_codec *codec, int enable,
			goto exit;
		}
		/* Reset the CDC PDM TLMM pins to active state */
		ret = pinctrl_select_state(pinctrl_info.pinctrl,
					pinctrl_info.cdc_slim_act);
		ret = pinctrl_select_state(pdata->pinctrl_info.pinctrl,
					pdata->pinctrl_info.cdc_slim_act);
		if (ret != 0) {
			pr_err("%s: Failed to enable the TLMM pins\n",
				__func__);
			mutex_unlock(&pdata->cdc_mclk_mutex);
			return -EIO;
		}
		if (!strcmp(card->name, "msm8939-tomtom9330-snd-card"))
			tomtom_mclk_enable(codec, 1, dapm);
		else
			tapan_mclk_enable(codec, 1, dapm);
		pdata->msm8939_codec_fn.mclk_enable_fn(codec, 1, dapm);
	} else {
		if (clk_users > 0) {
			clk_users--;
			if (clk_users == 0) {
				if (!strcmp(card->name,
					"msm8939-tomtom9330-snd-card"))
					tomtom_mclk_enable(codec, 0, dapm);
				else
					tapan_mclk_enable(codec, 0, dapm);
				pdata->msm8939_codec_fn.mclk_enable_fn(codec,
							0, dapm);
				/*
				 * Reset the CDC PDM TLMM pins
				 * to a default state
				 */
				ret = pinctrl_select_state(
					pinctrl_info.pinctrl,
					pinctrl_info.cdc_slim_sus);
					pdata->pinctrl_info.pinctrl,
					pdata->pinctrl_info.cdc_slim_sus);
				if (ret != 0) {
					pr_err("%s: Failed disable TLMM pins\n",
								__func__);
@@ -369,33 +368,6 @@ static int msm8x16_mclk_event(struct snd_soc_dapm_widget *w,
	return 0;
}

static int msm8939_vdd_spkr_event(struct snd_soc_dapm_widget *w,
		struct snd_kcontrol *kcontrol, int event)
{
	pr_debug("%s: event = %d\n", __func__, event);
	if (!gpio_is_valid(vdd_spkr_gpio)) {
		pr_err("%s: Invalid spkr gpio: %d", __func__, vdd_spkr_gpio);
		return false;
	}
	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
		if (vdd_spkr_gpio >= 0) {
			gpio_set_value_cansleep(vdd_spkr_gpio, 1);
			pr_debug("%s: Enabled 5V external supply for speaker\n",
					__func__);
		}
		break;
	case SND_SOC_DAPM_POST_PMD:
		if (vdd_spkr_gpio >= 0) {
			gpio_set_value_cansleep(vdd_spkr_gpio, 0);
			pr_debug("%s: Disable 5V external supply for speaker\n",
					__func__);
		}
		break;
	}
	return 0;
}

static const struct snd_soc_dapm_widget msm8939_dapm_widgets[] = {

	SND_SOC_DAPM_SUPPLY("MCLK",  SND_SOC_NOPM, 0, 0,
@@ -415,6 +387,7 @@ static const struct snd_soc_dapm_widget msm8939_dapm_widgets[] = {
	SND_SOC_DAPM_MIC("Digital Mic4", NULL),
	SND_SOC_DAPM_MIC("Digital Mic5", NULL),
	SND_SOC_DAPM_MIC("Digital Mic6", NULL),

};

static int slim0_rx_sample_rate_get(struct snd_kcontrol *kcontrol,
@@ -561,9 +534,6 @@ static const struct snd_soc_dapm_widget msm8x16_dapm_widgets[] = {
	SND_SOC_DAPM_MIC("Digital Mic4", NULL),
	SND_SOC_DAPM_MIC("Digital Mic5", NULL),
	SND_SOC_DAPM_MIC("Digital Mic6", NULL),

	SND_SOC_DAPM_SUPPLY("EXT_VDD_SPKR",  SND_SOC_NOPM, 0, 0,
	msm8939_vdd_spkr_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
};

static const char *const spk_function[] = {"Off", "On"};
@@ -660,14 +630,11 @@ static int msm_afe_set_config(struct snd_soc_codec *codec)
	int rc;
	void *config_data;
	struct snd_soc_card *card = codec->card;
	struct msm8939_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);

	pr_debug("%s: enter\n", __func__);

	if (!strcmp(card->name, "msm8939-tomtom9330-snd-card"))
		config_data = tomtom_get_afe_config(codec,
						AFE_CDC_REGISTERS_CONFIG);
	else
		config_data = tapan_get_afe_config(codec,
	config_data = pdata->msm8939_codec_fn.get_afe_config_fn(codec,
				AFE_CDC_REGISTERS_CONFIG);
	rc = afe_set_config(AFE_CDC_REGISTERS_CONFIG, config_data, 0);
	if (rc) {
@@ -676,11 +643,7 @@ static int msm_afe_set_config(struct snd_soc_codec *codec)
		return rc;
	}

	if (!strcmp(card->name, "msm8939-tomtom9330-snd-card"))
		config_data = tomtom_get_afe_config(codec,
						AFE_SLIMBUS_SLAVE_CONFIG);
	else
		config_data = tapan_get_afe_config(codec,
	config_data = pdata->msm8939_codec_fn.get_afe_config_fn(codec,
			AFE_SLIMBUS_SLAVE_CONFIG);
	rc = afe_set_config(AFE_SLIMBUS_SLAVE_CONFIG, config_data, 0);
	if (rc) {
@@ -689,9 +652,7 @@ static int msm_afe_set_config(struct snd_soc_codec *codec)
		return rc;
	}

	if (!strcmp(card->name, "msm8939-tapan-snd-card") ||
		!strcmp(card->name, "msm8939-tapan9302-snd-card")) {
		config_data = tapan_get_afe_config(codec,
	config_data = pdata->msm8939_codec_fn.get_afe_config_fn(codec,
			AFE_AANC_VERSION);
	rc = afe_set_config(AFE_AANC_VERSION, config_data, 0);
	if (rc) {
@@ -699,7 +660,6 @@ static int msm_afe_set_config(struct snd_soc_codec *codec)
				rc);
		return rc;
	}
	}
	return 0;
}

@@ -848,6 +808,8 @@ static int msm_audrx_init_tomtom(struct snd_soc_pcm_runtime *rtd)
	struct snd_soc_dapm_context *dapm = &codec->dapm;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	struct snd_soc_dai *codec_dai = rtd->codec_dai;
	struct snd_soc_card *card = codec->card;
	struct msm8939_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);

	/* Codec SLIMBUS configuration
	 * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13
@@ -891,13 +853,6 @@ static int msm_audrx_init_tomtom(struct snd_soc_pcm_runtime *rtd)
		goto out;
	}

	config_data = tomtom_get_afe_config(codec, AFE_AANC_VERSION);
	err = afe_set_config(AFE_AANC_VERSION, config_data, 0);
	if (err) {
		pr_err("%s: Failed to set aanc version %d\n",
			__func__, err);
		goto out;
	}
	config_data = tomtom_get_afe_config(codec,
				AFE_CDC_CLIP_REGISTERS_CONFIG);
	if (config_data) {
@@ -918,20 +873,13 @@ static int msm_audrx_init_tomtom(struct snd_soc_pcm_runtime *rtd)
			goto out;
		}
	}
	/* start mbhc */
	wcd9xxx_mbhc_cfg.calibration = def_codec_mbhc_cal();
	if (wcd9xxx_mbhc_cfg.calibration) {
		err = tomtom_hs_detect(codec, &wcd9xxx_mbhc_cfg);
	err = msm8939_gpio_set_mux_ctl();
	if (err) {
			pr_err("%s: tomtom_hs_detect failed, err:%d\n",
		pr_err("%s: Failed to set MUX CTL %d\n",
			__func__, err);
			goto out;
		}
	} else {
		pr_err("%s: wcd9xxx_mbhc_cfg calibration is NULL\n", __func__);
		err = -ENOMEM;
		goto out;
		return err;
	}

	adsp_state_notifier =
	    subsys_notif_register_notifier("modem",
					   &adsp_state_notifier_block);
@@ -939,7 +887,23 @@ static int msm_audrx_init_tomtom(struct snd_soc_pcm_runtime *rtd)
		pr_err("%s: Failed to register adsp state notifier\n",
		       __func__);
		err = -EFAULT;
		tomtom_hs_detect_exit(codec);
		goto out;
	}
	/* start mbhc */
	wcd9xxx_mbhc_cfg.calibration = def_codec_mbhc_cal();
	if (wcd9xxx_mbhc_cfg.calibration) {
		/*
		 * mbhc inital calibration needs mclk to be enabled, so schedule
		 * headset detection for 4sec so that modem gets loaded and
		 * will be ready to accept mclk request command.
		 */
		pdata->codec = codec;
		schedule_delayed_work(&pdata->hs_detect_dwork,
				  msecs_to_jiffies(HS_STARTWORK_TIMEOUT));

	} else {
		pr_err("%s: wcd9xxx_mbhc_cfg calibration is NULL\n", __func__);
		err = -ENOMEM;
		goto out;
	}

@@ -947,6 +911,7 @@ static int msm_audrx_init_tomtom(struct snd_soc_pcm_runtime *rtd)
	tomtom_register_ext_clk_cb(msm_snd_enable_codec_ext_clk,
				   msm_snd_get_ext_clk_cnt,
				   rtd->codec);

	return 0;
out:
	return err;
@@ -956,14 +921,17 @@ static void hs_detect_work(struct work_struct *work)
{
	struct delayed_work *dwork;
	struct msm8939_asoc_mach_data *pdata;
	int ret;
	int ret = 0;

	pr_debug("%s: enter\n", __func__);

	dwork = to_delayed_work(work);
	pdata = container_of(dwork, struct msm8939_asoc_mach_data,
			hs_detect_dwork);
	ret = tapan_hs_detect(pdata->codec, &wcd9xxx_mbhc_cfg);
	if (!pdata || !pdata->codec)
		return;
	pr_debug("%s: enter codec %s\n", __func__, pdata->codec->name);
	ret = pdata->msm8939_codec_fn.mbhc_hs_detect(pdata->codec,
						&wcd9xxx_mbhc_cfg);
	if (ret < 0)
		pr_err("%s: Failed to intialise mbhc %d\n", __func__, ret);

@@ -1174,6 +1142,36 @@ static int msm_slim_0_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
	return 0;
}

static int msm_slim_5_tx_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
					    struct snd_pcm_hw_params *params)
{
	int rc;
	void *config;
	struct snd_soc_codec *codec = rtd->codec;
	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);
	struct snd_soc_card *card = codec->card;
	struct msm8939_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);

	pr_debug("%s enter\n", __func__);

	rate->min = rate->max = 16000;
	channels->min = channels->max = 1;
	config = pdata->msm8939_codec_fn.get_afe_config_fn(codec,
			AFE_SLIMBUS_SLAVE_PORT_CONFIG);
	rc = afe_set_config(AFE_SLIMBUS_SLAVE_PORT_CONFIG, config,
			    SLIMBUS_5_TX);
	if (rc) {
		pr_err("%s: Failed to set slimbus slave port config %d\n",
		       __func__, rc);
		return rc;
	}
	return 0;
}


static struct snd_soc_ops slimbus_be_ops = {
	.hw_params = msm_snd_hw_params,
};
@@ -1498,6 +1496,34 @@ static struct snd_soc_dai_link msm8x16_9330_dai[] = {
		.ignore_pmdown_time = 1,
		.ignore_suspend = 1,
	},
	/* CPE LSM FE */
	{
		.name = "CPE Listen service",
		.stream_name = "CPE Listen Audio Service",
		.cpu_dai_name = "CPE_LSM_NOHOST",
		.platform_name = "msm-cpe-lsm",
		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
			    SND_SOC_DPCM_TRIGGER_POST },
		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
		.ignore_suspend = 1,
		.ignore_pmdown_time = 1,
		.codec_dai_name = "tomtom_mad1",
		.codec_name = "tomtom_codec",
	},
	/* MAD BE */
	{
		.name = LPASS_BE_SLIMBUS_5_TX,
		.stream_name = "Slimbus5 Capture",
		.cpu_dai_name = "msm-dai-q6-dev.16395",
		.platform_name = "msm-pcm-routing",
		.codec_name = "tomtom_codec",
		.codec_dai_name = "tomtom_mad1",
		.no_pcm = 1,
		.async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
		.be_id = MSM_BACKEND_DAI_SLIMBUS_5_TX,
		.be_hw_params_fixup = msm_slim_5_tx_be_hw_params_fixup,
		.ignore_suspend = 1,
	},
};

/* Digital audio interface glue - connects codec <---> CPU */
@@ -2045,8 +2071,15 @@ static struct snd_soc_dai_link msm8x16_9330_dai_links[
				ARRAY_SIZE(msm8x16_dai) +
				ARRAY_SIZE(msm8x16_9330_dai)];

static struct snd_soc_card snd_soc_card_msm = {};
enum codecs {
	TAPAN_CODEC,
	TAPAN_9302_CODEC,
	TOMTOM_CODEC,
	MAX_CODECS,
};

static struct snd_soc_card snd_soc_card_msm[MAX_CODECS];
static struct snd_soc_card snd_card_msm;

static bool msm8939_swap_gnd_mic(struct snd_soc_codec *codec)
{
@@ -2065,7 +2098,8 @@ static bool msm8939_swap_gnd_mic(struct snd_soc_codec *codec)
	return true;
}

static int cdc_slim_get_pinctrl(struct platform_device *pdev)
static int cdc_slim_get_pinctrl(struct platform_device *pdev,
			struct msm8939_asoc_mach_data *pdata)
{
	struct pinctrl *pinctrl;
	int ret;
@@ -2075,87 +2109,64 @@ static int cdc_slim_get_pinctrl(struct platform_device *pdev)
		pr_err("%s: Unable to get pinctrl handle\n", __func__);
		return -EINVAL;
	}
	pinctrl_info.pinctrl = pinctrl;
	pdata->pinctrl_info.pinctrl = pinctrl;
	/* get all the states handles from Device Tree*/
	pinctrl_info.cdc_slim_sus = pinctrl_lookup_state(pinctrl,
	pdata->pinctrl_info.cdc_slim_sus = pinctrl_lookup_state(pinctrl,
							"cdc_slim_lines_sus");
	if (IS_ERR(pinctrl_info.cdc_slim_sus)) {
	if (IS_ERR(pdata->pinctrl_info.cdc_slim_sus)) {
		pr_err("%s: Unable to get pinctrl suspend state handle\n",
								__func__);
		return -EINVAL;
	}
	pinctrl_info.cdc_slim_act = pinctrl_lookup_state(pinctrl,
	pdata->pinctrl_info.cdc_slim_act = pinctrl_lookup_state(pinctrl,
							"cdc_slim_lines_act");
	if (IS_ERR(pinctrl_info.cdc_slim_act)) {
	if (IS_ERR(pdata->pinctrl_info.cdc_slim_act)) {
		pr_err("%s: Unable to get pinctrl active state handle\n",
								__func__);
		return -EINVAL;
	}
	/* Reset the CDC PDM TLMM pins to a default state */
	ret = pinctrl_select_state(pinctrl_info.pinctrl,
					pinctrl_info.cdc_slim_sus);
	ret = pinctrl_select_state(pdata->pinctrl_info.pinctrl,
					pdata->pinctrl_info.cdc_slim_sus);
	if (ret != 0) {
		pr_err("%s: Failed to disable the TLMM pins\n", __func__);
		return -EIO;
	}
	pinctrl_info.cross_conn_det_sus = pinctrl_lookup_state(pinctrl,
	pdata->pinctrl_info.cross_conn_det_sus = pinctrl_lookup_state(pinctrl,
							"cross_conn_det_sus");
	if (IS_ERR(pinctrl_info.cross_conn_det_sus)) {
	if (IS_ERR(pdata->pinctrl_info.cross_conn_det_sus)) {
		pr_err("%s: Unable to get pinctrl suspend state handle\n",
								__func__);
		return -EINVAL;
	}
	pinctrl_info.cross_conn_det_act = pinctrl_lookup_state(pinctrl,
	pdata->pinctrl_info.cross_conn_det_act = pinctrl_lookup_state(pinctrl,
							"cross_conn_det_act");
	if (IS_ERR(pinctrl_info.cross_conn_det_act)) {
	if (IS_ERR(pdata->pinctrl_info.cross_conn_det_act)) {
		pr_err("%s: Unable to get pinctrl active state handle\n",
								__func__);
		return -EINVAL;
	}
	/* Reset the CDC PDM TLMM pins to a default state */
	ret = pinctrl_select_state(pinctrl_info.pinctrl,
					pinctrl_info.cross_conn_det_act);
	ret = pinctrl_select_state(pdata->pinctrl_info.pinctrl,
					pdata->pinctrl_info.cross_conn_det_act);
	if (ret != 0) {
		pr_err("%s: Failed to disable the us_euro pins\n", __func__);
		return -EIO;
	}
	pinctrl_info.cdc_vdd_spkr_sus = pinctrl_lookup_state(pinctrl,
							"cdc_vdd_spkr_sus");
	if (IS_ERR(pinctrl_info.cdc_vdd_spkr_sus)) {
		pr_err("%s: Unable to get pinctrl suspend state handle\n",
								__func__);
		return -EINVAL;
	}
	pinctrl_info.cdc_vdd_spkr_act = pinctrl_lookup_state(pinctrl,
							"cdc_vdd_spkr_act");
	if (IS_ERR(pinctrl_info.cdc_vdd_spkr_act)) {
		pr_err("%s: Unable to get pinctrl active state handle\n",
								__func__);
		return -EINVAL;
	}
	/* Reset the CDC PDM TLMM pins to a default state */
	ret = pinctrl_select_state(pinctrl_info.pinctrl,
					pinctrl_info.cdc_vdd_spkr_act);
	if (ret != 0) {
		pr_err("%s: Failed to enable the spkr pins\n", __func__);
		return -EIO;
	}
	return 0;
}


static int msm8939_asoc_machine_probe(struct platform_device *pdev)
{
	struct snd_soc_card *card = &snd_soc_card_msm;
	struct snd_soc_card *card = &snd_card_msm;
	struct msm8939_asoc_mach_data *pdata = NULL;
	int ret;
	int ret = 0;

	pdata = devm_kzalloc(&pdev->dev,
			sizeof(struct msm8939_asoc_mach_data), GFP_KERNEL);
	if (!pdata) {
		dev_err(&pdev->dev, "Can't allocate msm8939_asoc_mach_data\n");
		ret = -ENOMEM;
		goto err;
		return -ENOMEM;
	}

	pdev->id = 0;
@@ -2170,30 +2181,48 @@ static int msm8939_asoc_machine_probe(struct platform_device *pdev)
			ret);
		goto err;
	}

	if (!strcmp(card->name, "msm8939-tapan-snd-card")) {
		snd_soc_card_msm[TAPAN_CODEC].name = card->name;
		card = &snd_soc_card_msm[TAPAN_CODEC];
		memcpy(msm8x16_9306_dai_links, msm8x16_dai,
				sizeof(msm8x16_dai));
		memcpy(msm8x16_9306_dai_links + ARRAY_SIZE(msm8x16_dai),
			msm8x16_9306_dai, sizeof(msm8x16_9306_dai));
		card->dai_link	= msm8x16_9306_dai_links;
		card->num_links	= ARRAY_SIZE(msm8x16_9306_dai_links);
		pdata->msm8939_codec_fn.mclk_enable_fn = tapan_mclk_enable;
		pdata->msm8939_codec_fn.get_afe_config_fn =
							tapan_get_afe_config;
		pdata->msm8939_codec_fn.mbhc_hs_detect = tapan_hs_detect;
	} else if (!strcmp(card->name, "msm8939-tapan9302-snd-card")) {
		snd_soc_card_msm[TAPAN_9302_CODEC].name = card->name;
		card = &snd_soc_card_msm[TAPAN_9302_CODEC];
		memcpy(msm8x16_9302_dai_links, msm8x16_dai,
				sizeof(msm8x16_dai));
		memcpy(msm8x16_9302_dai_links + ARRAY_SIZE(msm8x16_dai),
			msm8x16_9302_dai, sizeof(msm8x16_9302_dai));
		card->dai_link	= msm8x16_9302_dai_links;
		card->num_links	= ARRAY_SIZE(msm8x16_9302_dai_links);
		pdata->msm8939_codec_fn.mclk_enable_fn = tapan_mclk_enable;
		pdata->msm8939_codec_fn.get_afe_config_fn =
						tapan_get_afe_config;
		pdata->msm8939_codec_fn.mbhc_hs_detect = tapan_hs_detect;
	} else if (!strcmp(card->name, "msm8939-tomtom9330-snd-card")) {
		snd_soc_card_msm[TOMTOM_CODEC].name = card->name;
		card = &snd_soc_card_msm[TOMTOM_CODEC];
		memcpy(msm8x16_9330_dai_links, msm8x16_dai,
				sizeof(msm8x16_dai));
		memcpy(msm8x16_9330_dai_links + ARRAY_SIZE(msm8x16_dai),
			msm8x16_9330_dai, sizeof(msm8x16_9330_dai));
		card->dai_link	= msm8x16_9330_dai_links;
		card->num_links	= ARRAY_SIZE(msm8x16_9330_dai_links);
		pdata->msm8939_codec_fn.mclk_enable_fn = tomtom_mclk_enable;
		pdata->msm8939_codec_fn.get_afe_config_fn =
						tomtom_get_afe_config;
		pdata->msm8939_codec_fn.mbhc_hs_detect = tomtom_hs_detect;
	}

	card->dev = &pdev->dev;
	platform_set_drvdata(pdev, card);
	snd_soc_card_set_drvdata(card, pdata);

@@ -2205,12 +2234,13 @@ static int msm8939_asoc_machine_probe(struct platform_device *pdev)
	if (ret)
		goto err;

	/*Populate external codec TLMM configs*/
	ret = cdc_slim_get_pinctrl(pdev);
	if (ret < 0) {
		pr_err("failed to get the pdm gpios\n");
		goto err;
	}
	/* initialize the mclk */
	pdata->digital_cdc_clk.i2s_cfg_minor_version =
					AFE_API_VERSION_I2S_CONFIG;
	pdata->digital_cdc_clk.clk_val = 9600000;
	pdata->digital_cdc_clk.clk_root = 5;
	pdata->digital_cdc_clk.reserved = 0;

	ret = snd_soc_register_card(card);
	if (ret) {
		dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
@@ -2218,6 +2248,13 @@ static int msm8939_asoc_machine_probe(struct platform_device *pdev)
		goto err;
	}

	/*Populate external codec TLMM configs*/
	ret = cdc_slim_get_pinctrl(pdev, pdata);
	if (ret < 0) {
		pr_err("failed to get the pdm gpios\n");
		goto err;
	}

	/* Parse US-Euro gpio info from DT. Report no error if us-euro
	 * entry is not found in DT file as some targets do not support
	 * US-Euro detection
@@ -2234,21 +2271,9 @@ static int msm8939_asoc_machine_probe(struct platform_device *pdev)
		wcd9xxx_mbhc_cfg.swap_gnd_mic = msm8939_swap_gnd_mic;
	}

	vdd_spkr_gpio = of_get_named_gpio(pdev->dev.of_node,
				"qcom,cdc-vdd-spkr-gpios", 0);
	if (vdd_spkr_gpio < 0)
		dev_err(&pdev->dev,
			"Looking up %s property in node %s failed %d\n",
			"qcom, cdc-vdd-spkr-gpios",
			pdev->dev.of_node->full_name, vdd_spkr_gpio);
	/* initialize the mclk */
	pdata->digital_cdc_clk.i2s_cfg_minor_version =
					AFE_API_VERSION_I2S_CONFIG;
	pdata->digital_cdc_clk.clk_val = 9600000;
	pdata->digital_cdc_clk.clk_root = 5;
	pdata->digital_cdc_clk.reserved = 0;
	return 0;
err:
	cancel_delayed_work_sync(&pdata->hs_detect_dwork);
	mutex_destroy(&pdata->cdc_mclk_mutex);
	devm_kfree(&pdev->dev, pdata);
	return ret;