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

Commit f45c5b45 authored by Deru Wang's avatar Deru Wang
Browse files

asoc: active GPIO122 and enable mclk for sa6155 auto platform



enable GPIO122 as mclk2 for externel AMP on sa6155 auto platform.

Change-Id: I9cb9012096a3a7620aeaeae5c690ae9ff168457a
Signed-off-by: default avatarDeru Wang <deruwang@codeaurora.org>
parent 1c3c1cf2
Loading
Loading
Loading
Loading
+60 −0
Original line number Original line Diff line number Diff line
@@ -32224,6 +32224,62 @@ static const struct snd_kcontrol_new asrc_config_controls[] = {
				 msm_dai_q6_asrc_config_put),
				 msm_dai_q6_asrc_config_put),
};
};
enum {
	IDX_MCLK1 = 1,
	IDX_MCLK2,
};
/* default internal mclk config. Only MCLK2 is needed now */
static struct afe_clk_set internal_mclk = {
	AFE_API_VERSION_CLOCK_SET_V2,
	Q6AFE_LPASS_CLK_ID_MCLK_2,
	Q6AFE_LPASS_IBIT_CLK_12_P288_MHZ,
	Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
	Q6AFE_LPASS_CLK_ROOT_DEFAULT,
	1,
};
static int msm_internal_mclk_ctl_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	/* default mclk id is 2 */
	ucontrol->value.integer.value[0] = 2;
	ucontrol->value.integer.value[1] = internal_mclk.clk_freq_in_hz;
	ucontrol->value.integer.value[2] = internal_mclk.enable;
	return 0;
}
static int msm_internal_mclk_ctl_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	int ret = -EINVAL;
	int32_t mclk_id = 0;
	mclk_id = ucontrol->value.integer.value[0];
	if (mclk_id != IDX_MCLK2) {
		pr_err("%s: invalid mclk id: %d, only mclk2 is supported now\n",
			__func__, mclk_id);
		return -EINVAL;
	}
	internal_mclk.clk_freq_in_hz = ucontrol->value.integer.value[1];
	internal_mclk.enable = ucontrol->value.integer.value[2];
	ret = afe_set_lpass_clock_v2(AFE_PORT_ID_TDM_PORT_RANGE_START,
				     &internal_mclk);
	if (ret)
		pr_err("%s: mclk enable failed %d\n", __func__, ret);
	return ret;
}
static const struct snd_kcontrol_new internal_mclk_control[] = {
	SOC_SINGLE_MULTI_EXT("internal mclk enable", SND_SOC_NOPM, 0,
				 0x7FFFFFFF, 0, 3,
				 msm_internal_mclk_ctl_get,
				 msm_internal_mclk_ctl_put),
};
static const struct snd_pcm_ops msm_routing_pcm_ops = {
static const struct snd_pcm_ops msm_routing_pcm_ops = {
	.hw_params	= msm_pcm_routing_hw_params,
	.hw_params	= msm_pcm_routing_hw_params,
	.close          = msm_pcm_routing_close,
	.close          = msm_pcm_routing_close,
@@ -32418,6 +32474,10 @@ static int msm_routing_probe(struct snd_soc_component *component)
				      ARRAY_SIZE(mclk_src_controls));
				      ARRAY_SIZE(mclk_src_controls));
	snd_soc_add_component_controls(component, asrc_config_controls,
	snd_soc_add_component_controls(component, asrc_config_controls,
				      ARRAY_SIZE(asrc_config_controls));
				      ARRAY_SIZE(asrc_config_controls));
#ifdef CONFIG_MSM_INTERNAL_MCLK
	snd_soc_add_component_controls(component, internal_mclk_control,
				      ARRAY_SIZE(internal_mclk_control));
#endif
	return 0;
	return 0;
}
}
+112 −20
Original line number Original line Diff line number Diff line
@@ -140,6 +140,8 @@ static const char *const tdm_gpio_phandle[] = {"qcom,pri-tdm-gpios",
						"qcom,quat-tdm-gpios",
						"qcom,quat-tdm-gpios",
						"qcom,quin-tdm-gpios"};
						"qcom,quin-tdm-gpios"};


static const char *const mclk_gpio_phandle[] = { "qcom,internal-mclk2-gpios" };

enum {
enum {
	TDM_0 = 0,
	TDM_0 = 0,
	TDM_1,
	TDM_1,
@@ -161,6 +163,16 @@ enum {
	TDM_INTERFACE_MAX,
	TDM_INTERFACE_MAX,
};
};


enum {
	MCLK2 = 0,
	MCLK_MAX,
};

enum pinctrl_mode {
	TDM_PINCTRL,
	MCLK_PINCTRL,
};

struct tdm_port {
struct tdm_port {
	u32 mode;
	u32 mode;
	u32 channel;
	u32 channel;
@@ -701,6 +713,17 @@ static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text);
static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text);


static struct afe_clk_set internal_mclk[MCLK_MAX] = {
	{
		AFE_API_VERSION_CLOCK_SET_V2,
		Q6AFE_LPASS_CLK_ID_MCLK_2,
		Q6AFE_LPASS_IBIT_CLK_12_P288_MHZ,
		Q6AFE_LPASS_CLK_ATTRIBUTE_COUPLE_NO,
		Q6AFE_LPASS_CLK_ROOT_DEFAULT,
		1,
	}
};

static struct afe_clk_set mi2s_clk[MI2S_MAX] = {
static struct afe_clk_set mi2s_clk[MI2S_MAX] = {
	{
	{
		AFE_API_VERSION_I2S_CONFIG,
		AFE_API_VERSION_I2S_CONFIG,
@@ -747,6 +770,7 @@ static struct afe_clk_set mi2s_clk[MI2S_MAX] = {


struct msm_asoc_mach_data {
struct msm_asoc_mach_data {
	struct msm_pinctrl_info pinctrl_info[TDM_INTERFACE_MAX];
	struct msm_pinctrl_info pinctrl_info[TDM_INTERFACE_MAX];
	struct msm_pinctrl_info mclk_pinctrl_info[MCLK_MAX];
	struct mi2s_conf mi2s_intf_conf[MI2S_MAX];
	struct mi2s_conf mi2s_intf_conf[MI2S_MAX];
	struct tdm_conf tdm_intf_conf[TDM_INTERFACE_MAX];
	struct tdm_conf tdm_intf_conf[TDM_INTERFACE_MAX];
};
};
@@ -3857,18 +3881,29 @@ static void msm_release_pinctrl(struct platform_device *pdev)
	}
	}
}
}


static int msm_get_pinctrl(struct platform_device *pdev)
static int msm_pinctrl_init(struct platform_device *pdev, enum pinctrl_mode mode)
{
{
	struct snd_soc_card *card = platform_get_drvdata(pdev);
	struct snd_soc_card *card = platform_get_drvdata(pdev);
	struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
	struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
	struct msm_pinctrl_info *pinctrl_info = NULL;
	struct msm_pinctrl_info *pinctrl_info = NULL;
	struct pinctrl *pinctrl = NULL;
	struct pinctrl *pinctrl = NULL;
	int pinctrl_num;
	int i, j;
	int i, j;
	struct device_node *np = NULL;
	struct device_node *np = NULL;
	struct platform_device *pdev_np = NULL;
	struct platform_device *pdev_np = NULL;
	int ret = 0;
	int ret = 0;


	for (i = TDM_PRI; i < TDM_INTERFACE_MAX; i++) {
	if (mode == TDM_PINCTRL) {
		pinctrl_num = TDM_INTERFACE_MAX;
	} else if (mode == MCLK_PINCTRL) {
		pinctrl_num = MCLK_MAX;
	} else {
		pr_err("%s: invalid mode %d\n", __func__, mode);
		return -EINVAL;
	}

	for (i = 0; i < pinctrl_num; i++) {
		if (mode == TDM_PINCTRL) {
			np = of_parse_phandle(pdev->dev.of_node,
			np = of_parse_phandle(pdev->dev.of_node,
				tdm_gpio_phandle[i], 0);
				tdm_gpio_phandle[i], 0);
			if (!np) {
			if (!np) {
@@ -3876,6 +3911,16 @@ static int msm_get_pinctrl(struct platform_device *pdev)
					__func__, tdm_gpio_phandle[i]);
					__func__, tdm_gpio_phandle[i]);
				continue;
				continue;
			}
			}
		}
		else {
			np = of_parse_phandle(pdev->dev.of_node,
				mclk_gpio_phandle[i], 0);
			if (!np) {
				pr_debug("%s: device node %s is null\n",
					__func__, mclk_gpio_phandle[i]);
				continue;
			}
		}


		pdev_np = of_find_device_by_node(np);
		pdev_np = of_find_device_by_node(np);
		if (!pdev_np) {
		if (!pdev_np) {
@@ -3883,7 +3928,10 @@ static int msm_get_pinctrl(struct platform_device *pdev)
			continue;
			continue;
		}
		}


		if (mode == TDM_PINCTRL)
			pinctrl_info = &pdata->pinctrl_info[i];
			pinctrl_info = &pdata->pinctrl_info[i];
		else
			pinctrl_info = &pdata->mclk_pinctrl_info[i];
		if (pinctrl_info == NULL) {
		if (pinctrl_info == NULL) {
			pr_err("%s: pinctrl info is null\n", __func__);
			pr_err("%s: pinctrl info is null\n", __func__);
			continue;
			continue;
@@ -3911,9 +3959,9 @@ static int msm_get_pinctrl(struct platform_device *pdev)
			goto err;
			goto err;
		}
		}


		if (mode == TDM_PINCTRL) {
			/* Reset the TLMM pins to a sleep state */
			/* Reset the TLMM pins to a sleep state */
		ret = pinctrl_select_state(pinctrl_info->pinctrl,
			ret = pinctrl_select_state(pinctrl_info->pinctrl, pinctrl_info->sleep);
						pinctrl_info->sleep);
			if (ret != 0) {
			if (ret != 0) {
				pr_err("%s: set pin state to sleep failed with %d\n",
				pr_err("%s: set pin state to sleep failed with %d\n",
					__func__, ret);
					__func__, ret);
@@ -3922,11 +3970,35 @@ static int msm_get_pinctrl(struct platform_device *pdev)
			}
			}
			pinctrl_info->curr_state = STATE_SLEEP;
			pinctrl_info->curr_state = STATE_SLEEP;
		}
		}
		else {
			/* Reset the mclk pins to a active state */
			ret = afe_set_lpass_clock_v2(AFE_PORT_ID_TDM_PORT_RANGE_START,
				&internal_mclk[i]);
			if (ret < 0) {
				pr_err("%s: afe lpass clock failed to enable clock, err:%d\n",
					__func__, ret);
				ret = -EIO;
				goto err;
			}

			ret = pinctrl_select_state(pinctrl_info->pinctrl, pinctrl_info->active);
			if (ret != 0) {
				pr_err("%s: set pin state to active failed with %d\n",
					__func__, ret);
				ret = -EIO;
				goto err;
			}
			pinctrl_info->curr_state = STATE_ACTIVE;
		}
	}
	return 0;
	return 0;


err:
err:
	for (j = i; j >= 0; j--) {
	for (j = i; j >= 0; j--) {
		pinctrl_info = &pdata->pinctrl_info[j];
		if (mode == TDM_PINCTRL)
			pinctrl_info = &pdata->pinctrl_info[i];
		else
			pinctrl_info = &pdata->mclk_pinctrl_info[i];
		if (pinctrl_info == NULL)
		if (pinctrl_info == NULL)
			continue;
			continue;
		if (pinctrl_info->pinctrl) {
		if (pinctrl_info->pinctrl) {
@@ -3937,6 +4009,26 @@ static int msm_get_pinctrl(struct platform_device *pdev)
	return -EINVAL;
	return -EINVAL;
}
}


static int msm_get_pinctrl(struct platform_device *pdev)
{
	int ret = 0;

	ret = msm_pinctrl_init(pdev, TDM_PINCTRL);
	if (ret != 0) {
		pr_err("%s: set tdm pin state to sleep failed with %d\n",
			__func__, ret);
		return -EIO;
	}

	ret = msm_pinctrl_init(pdev, MCLK_PINCTRL);
	if (ret != 0) {
		pr_err("%s: set mclk pin state to active failed with %d\n",
			__func__, ret);
		return -EIO;
	}
	return ret;
}

static int msm_tdm_get_intf_idx(u16 id)
static int msm_tdm_get_intf_idx(u16 id)
{
{
	switch (id) {
	switch (id) {
+1 −0
Original line number Original line Diff line number Diff line
@@ -16,3 +16,4 @@ export CONFIG_SND_SOC_SA6155=m
export CONFIG_SOUNDWIRE=m
export CONFIG_SOUNDWIRE=m
export CONFIG_SOUNDWIRE_MSTR_CTRL=m
export CONFIG_SOUNDWIRE_MSTR_CTRL=m
export CONFIG_SND_EVENT=m
export CONFIG_SND_EVENT=m
export CONFIG_MSM_INTERNAL_MCLK=m
+2 −1
Original line number Original line Diff line number Diff line
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2018-2019, 2021, The Linux Foundation. All rights reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * it under the terms of the GNU General Public License version 2 and
@@ -28,3 +28,4 @@
#define CONFIG_SOUNDWIRE 1
#define CONFIG_SOUNDWIRE 1
#define CONFIG_SOUNDWIRE_MSTR_CTRL 1
#define CONFIG_SOUNDWIRE_MSTR_CTRL 1
#define CONFIG_SND_EVENT 1
#define CONFIG_SND_EVENT 1
#define CONFIG_MSM_INTERNAL_MCLK 1