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

Commit 8af2dfbf authored by Viraja Kommaraju's avatar Viraja Kommaraju Committed by Gerrit - the friendly Code Review server
Browse files

ASoC: msm: Changes for on-the-fly switch between master/slave modes



Update machine driver to use msm-audio-pinctrl driver and have
single pinctrl handle for all states master, slave and sleep.
This is applicable to both MI2S and AUXPCM. Also, update FE
DAIs for SEC MI2S TX/RX hostless, PRI AUXPCM TX/RX hostless,
SEC AUXPCM TX/RX hostless session.

CRs-fixed: 2105222
Change-Id: I9c4f3eae488c8632a762f36a3055f16c772dc1c2
Signed-off-by: default avatarViraja Kommaraju <virajak@codeaurora.org>
parent 951cbb66
Loading
Loading
Loading
Loading
+83 −8
Original line number Diff line number Diff line
@@ -2135,10 +2135,14 @@ sound-9330 {
- qcom,model : The user-visible name of this sound card.
- qcom,tasha-mclk-clk-freq : MCLK frequency value for tasha codec
                             and node is "sound-9335"
- qcom,prim_mi2s_aux_master : Handle to prim_master pinctrl configurations
- qcom,prim_mi2s_aux_slave : Handle to prim_slave pinctrl configurations
- qcom,sec_mi2s_aux_master : Handle to sec_master pinctrl configurations
- qcom,sec_mi2s_aux_slave : Handle to sec_slave pinctrl configurations
- qcom,pinctrl-names : Lists all the possible combinations of the gpio sets
                       mentioned in qcom,msm-gpios. Say we have 2^N combinations
                       for N GPIOs, this would list all the 2^N combinations.
- pinctrl-names : The combinations of gpio sets from above that are supported in
                  the flavor. This can be sometimes same as qcom,pinctrl-names
                  i.e with 2^N combinations or will have less incase if some
                  combination is not supported or invalid.
- pinctrl-# : Pinctrl states as mentioned in pinctrl-names.
- qcom,audio-routing : A list of the connections between audio components.
- asoc-platform: This is phandle list containing the references to platform device
                 nodes that are used as part of the sound card dai-links.
@@ -2197,10 +2201,81 @@ Example:
		"MIC BIAS4 External", "Digital Mic6";

		qcom,tasha-mclk-clk-freq = <12288000>;
		qcom,prim_mi2s_aux_master = <&prim_master>;
		qcom,prim_mi2s_aux_slave = <&prim_slave>;
		qcom,sec_mi2s_aux_master = <&sec_master>;
		qcom,sec_mi2s_aux_slave = <&sec_slave>;

		qcom,msm-gpios =
			"pri_mi2s_aux_master",
			"pri_mi2s_aux_slave",
			"sec_mi2s_aux_master",
			"sec_mi2s_aux_slave";
		qcom,pinctrl-names =
			"all_off",
			"pri_mi2s_aux_master_active",
			"pri_mi2s_aux_slave_active",
			"invalid_state_1",
			"sec_mi2s_aux_master_active",
			"pri_master_active_sec_master_active",
			"pri_slave_active_sec_master_active",
			"invalid_state_2",
			"sec_mi2s_aux_slave_active",
			"pri_master_active_sec_slave_active",
			"pri_slave_active_sec_slave_active";
		pinctrl-names =
			"all_off",
			"pri_mi2s_aux_master_active",
			"pri_mi2s_aux_slave_active",
			"invalid_state_1",
			"sec_mi2s_aux_master_active",
			"pri_master_active_sec_master_active",
			"pri_slave_active_sec_master_active",
			"invalid_state_2",
			"sec_mi2s_aux_slave_active",
			"pri_master_active_sec_slave_active",
			"pri_slave_active_sec_slave_active";
		pinctrl-0 = <&pri_ws_sleep &pri_sck_sleep
				&pri_dout_sleep &pri_din_sleep
				&sec_ws_sleep &sec_sck_sleep
				&sec_dout_sleep &sec_din_sleep>;
		pinctrl-1 = <&pri_ws_active_master &pri_sck_active_master
				&pri_dout_active &pri_din_active
				&sec_ws_sleep &sec_sck_sleep
				&sec_dout_sleep &sec_din_sleep>;
		pinctrl-2 = <&pri_ws_active_slave &pri_sck_active_slave
				&pri_dout_active &pri_din_active
				&sec_ws_sleep &sec_sck_sleep
				&sec_dout_sleep &sec_din_sleep>;
		pinctrl-3 = <&pri_ws_sleep &pri_sck_sleep
				&pri_dout_sleep &pri_din_sleep
				&sec_ws_sleep &sec_sck_sleep
				&sec_dout_sleep &sec_din_sleep>;
		pinctrl-4 = <&pri_ws_sleep &pri_sck_sleep
				&pri_dout_sleep &pri_din_sleep
				&sec_ws_active_master &sec_sck_active_master
				&sec_dout_active &sec_din_active>;
		pinctrl-5 = <&pri_ws_active_master &pri_sck_active_master
				&pri_dout_active &pri_din_active
				&sec_ws_active_master &sec_sck_active_master
				&sec_dout_active &sec_din_active>;
		pinctrl-6 = <&pri_ws_active_slave &pri_sck_active_slave
				&pri_dout_active &pri_din_active
				&sec_ws_active_master &sec_sck_active_master
				&sec_dout_active &sec_din_active>;
		pinctrl-7 = <&pri_ws_sleep &pri_sck_sleep
				&pri_dout_sleep &pri_din_sleep
				&sec_ws_sleep &sec_sck_sleep
				&sec_dout_sleep &sec_din_sleep>;
		pinctrl-8 = <&pri_ws_sleep &pri_sck_sleep
				&pri_dout_sleep &pri_din_sleep
				&sec_ws_active_slave &sec_sck_active_slave
				&sec_dout_active &sec_din_active>;
		pinctrl-9 = <&pri_ws_active_master &pri_sck_active_master
				&pri_dout_active &pri_din_active
				&sec_ws_active_slave &sec_sck_active_slave
				&sec_dout_active &sec_din_active>;
		pinctrl-10 = <&pri_ws_active_slave &pri_sck_active_slave
				&pri_dout_active &pri_din_active
				&sec_ws_active_slave &sec_sck_active_slave
				&sec_dout_active &sec_din_active>;

		asoc-platform = <&pcm0>, <&pcm1>, <&voip>, <&voice>,
				<&loopback>, <&hostless>, <&afe>, <&routing>,
				<&pcm_dtmf>, <&host_pcm>;
+1 −1
Original line number Diff line number Diff line
@@ -30,7 +30,7 @@ snd-soc-msm8x16-objs += msm8952-slimbus.o msm8952-dai-links.o
obj-$(CONFIG_SND_SOC_MSM8X16) += snd-soc-msm8x16.o

# for MDM 9650 sound card driver
snd-soc-mdm9650-objs := mdm9650.o
snd-soc-mdm9650-objs := mdm9650.o msm-audio-pinctrl.o
obj-$(CONFIG_SND_SOC_MDM9650) += snd-soc-mdm9650.o

# for MDM 9607 sound card driver
+132 −40
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include "../codecs/wcd9335.h"
#include "../codecs/wsa881x.h"
#include "../codecs/tlv320aic3x.h"
#include "msm-audio-pinctrl.h"

/* Spk control */
#define MDM_SPK_ON 1
@@ -369,11 +370,11 @@ static void mdm_mi2s_shutdown(struct snd_pcm_substream *substream)
			pr_err("%s Clock disable failed\n", __func__);

		if (pdata->prim_mi2s_mode == 1)
			ret = wcd_gpio_ctrl_select_sleep_state
						(pdata->prim_master_p);
			ret = msm_gpioset_suspend(CLIENT_WCD_EXT,
						"pri_mi2s_aux_master");
		else
			ret = wcd_gpio_ctrl_select_sleep_state
						(pdata->prim_slave_p);
			ret = msm_gpioset_suspend(CLIENT_WCD_EXT,
						"pri_mi2s_aux_slave");
		if (ret)
			pr_err("%s: failed to set pri gpios to sleep: %d\n",
					__func__, ret);
@@ -427,8 +428,8 @@ static int mdm_mi2s_startup(struct snd_pcm_substream *substream)
		 * 0 means external clock slave mode.
		 */
		if (pdata->prim_mi2s_mode == 1) {
			ret = wcd_gpio_ctrl_select_active_state
					(pdata->prim_master_p);
			ret = msm_gpioset_activate(CLIENT_WCD_EXT,
						"pri_mi2s_aux_master");
			if (ret < 0) {
				pr_err("%s pinctrl set failed\n", __func__);
				goto err;
@@ -471,8 +472,8 @@ static int mdm_mi2s_startup(struct snd_pcm_substream *substream)
			 * Disable bit clk in slave mode for QC codec.
			 * Enable only mclk.
			 */
			ret = wcd_gpio_ctrl_select_active_state
					(pdata->prim_slave_p);
			ret = msm_gpioset_activate(CLIENT_WCD_EXT,
						"pri_mi2s_aux_slave");
			if (ret < 0) {
				pr_err("%s pinctrl set failed\n", __func__);
				goto err;
@@ -533,11 +534,11 @@ static void mdm_sec_mi2s_shutdown(struct snd_pcm_substream *substream)
			pr_err("%s Clock disable failed\n", __func__);

		if (pdata->sec_mi2s_mode == 1)
			ret = wcd_gpio_ctrl_select_sleep_state
					(pdata->sec_master_p);
			ret = msm_gpioset_suspend(CLIENT_WCD_EXT,
						"sec_mi2s_aux_master");
		else
			ret = wcd_gpio_ctrl_select_sleep_state
					(pdata->sec_slave_p);
			ret = msm_gpioset_suspend(CLIENT_WCD_EXT,
						"sec_mi2s_aux_slave");
		if (ret)
			pr_err("%s: failed to set sec gpios to sleep: %d\n",
				__func__, ret);
@@ -591,8 +592,8 @@ static int mdm_sec_mi2s_startup(struct snd_pcm_substream *substream)
		 * 0 means external clock slave mode.
		 */
		if (pdata->sec_mi2s_mode == 1) {
			ret = wcd_gpio_ctrl_select_active_state
					(pdata->sec_master_p);
			ret = msm_gpioset_activate(CLIENT_WCD_EXT,
						"sec_mi2s_aux_master");
			if (ret < 0) {
				pr_err("%s pinctrl set failed\n", __func__);
				goto err;
@@ -619,8 +620,8 @@ static int mdm_sec_mi2s_startup(struct snd_pcm_substream *substream)
			 * Enable mclk here, if needed for external codecs.
			 * Optional. Refer primary mi2s slave interface.
			 */
			ret = wcd_gpio_ctrl_select_active_state
					(pdata->sec_slave_p);
			ret = msm_gpioset_activate(CLIENT_WCD_EXT,
						"sec_mi2s_aux_slave");
			if (ret < 0) {
				pr_err("%s pinctrl set failed\n", __func__);
				goto err;
@@ -1130,11 +1131,11 @@ static void mdm_auxpcm_shutdown(struct snd_pcm_substream *substream)
	struct mdm_machine_data *pdata = snd_soc_card_get_drvdata(card);

	if (pdata->prim_auxpcm_mode == 1)
		ret = wcd_gpio_ctrl_select_sleep_state
					(pdata->prim_master_p);
		ret = msm_gpioset_suspend(CLIENT_WCD_EXT,
					"pri_mi2s_aux_master");
	else
		ret = wcd_gpio_ctrl_select_sleep_state
					(pdata->prim_slave_p);
		ret = msm_gpioset_suspend(CLIENT_WCD_EXT,
					"pri_mi2s_aux_slave");
	if (ret)
		pr_err("%s: failed to set prim gpios to sleep: %d\n",
				__func__, ret);
@@ -1176,13 +1177,13 @@ static int mdm_auxpcm_startup(struct snd_pcm_substream *substream)
	}

	if (pdata->prim_auxpcm_mode == 1) {
		ret = wcd_gpio_ctrl_select_active_state
						(pdata->prim_master_p);
		ret = msm_gpioset_activate(CLIENT_WCD_EXT,
					"pri_mi2s_aux_master");
		if (ret < 0)
			pr_err("%s pinctrl set failed\n", __func__);
	} else {
		ret = wcd_gpio_ctrl_select_active_state
						(pdata->prim_slave_p);
		ret = msm_gpioset_activate(CLIENT_WCD_EXT,
					"pri_mi2s_aux_slave");
		if (ret < 0)
			pr_err("%s pinctrl set failed\n", __func__);
	}
@@ -1204,11 +1205,11 @@ static void mdm_sec_auxpcm_shutdown(struct snd_pcm_substream *substream)
	struct mdm_machine_data *pdata = snd_soc_card_get_drvdata(card);

	if (pdata->sec_auxpcm_mode == 1)
		ret = wcd_gpio_ctrl_select_sleep_state
				(pdata->sec_master_p);
		ret = msm_gpioset_suspend(CLIENT_WCD_EXT,
					"sec_mi2s_aux_master");
	else
		ret = wcd_gpio_ctrl_select_sleep_state
				(pdata->sec_slave_p);
		ret = msm_gpioset_suspend(CLIENT_WCD_EXT,
					"sec_mi2s_aux_slave");
	if (ret)
		pr_err("%s: failed to set sec gpios to sleep: %d\n",
			__func__, ret);
@@ -1251,13 +1252,13 @@ static int mdm_sec_auxpcm_startup(struct snd_pcm_substream *substream)
	}

	if (pdata->sec_auxpcm_mode == 1) {
		ret = wcd_gpio_ctrl_select_active_state
					(pdata->sec_master_p);
		ret = msm_gpioset_activate(CLIENT_WCD_EXT,
					"sec_mi2s_aux_master");
		if (ret < 0)
			pr_err("%s pinctrl set failed\n", __func__);
	} else {
		ret = wcd_gpio_ctrl_select_active_state
					(pdata->sec_slave_p);
		ret = msm_gpioset_activate(CLIENT_WCD_EXT,
					"sec_mi2s_aux_slave");
		if (ret < 0)
			pr_err("%s pinctrl set failed\n", __func__);
	}
@@ -1951,6 +1952,99 @@ static struct snd_soc_dai_link mdm_dai[] = {
		.ignore_suspend = 1,
		 .ignore_pmdown_time = 1,
	},
	{
		.name = "Secondary MI2S RX Hostless",
		.stream_name = "Secondary MI2S_RX Hostless Playback",
		.cpu_dai_name = "SEC_MI2S_RX_HOSTLESS",
		.platform_name  = "msm-pcm-hostless",
		.dynamic = 1,
		.dpcm_playback = 1,
		.dpcm_capture = 1,
		.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 = "snd-soc-dummy-dai",
		.codec_name = "snd-soc-dummy",
	},
	{
		.name = "Secondary MI2S TX Hostless",
		.stream_name = "Secondary MI2S_TX Hostless Playback",
		.cpu_dai_name = "SEC_MI2S_TX_HOSTLESS",
		.platform_name  = "msm-pcm-hostless",
		.dynamic = 1,
		.dpcm_capture = 1,
		.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 = "snd-soc-dummy-dai",
		.codec_name = "snd-soc-dummy",
	},
	{
		.name = "Primary AUXPCM RX Hostless",
		.stream_name = "AUXPCM_HOSTLESS Playback",
		.cpu_dai_name = "AUXPCM_HOSTLESS",
		.platform_name  = "msm-pcm-hostless",
		.dynamic = 1,
		.dpcm_playback = 1,
		.dpcm_capture = 1,
		.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 = "snd-soc-dummy-dai",
		.codec_name = "snd-soc-dummy",
	},
	{
		.name = "Primary AUXPCM TX Hostless",
		.stream_name = "AUXPCM_HOSTLESS Capture",
		.cpu_dai_name = "AUXPCM_HOSTLESS",
		.platform_name  = "msm-pcm-hostless",
		.dynamic = 1,
		.dpcm_capture = 1,
		.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 = "snd-soc-dummy-dai",
		.codec_name = "snd-soc-dummy",
	},
	{
		.name = "Secondary AUXPCM RX Hostless",
		.stream_name = "SEC_AUXPCM_HOSTLESS Playback",
		.cpu_dai_name = "SEC_AUXPCM_RX_HOSTLESS",
		.platform_name  = "msm-pcm-hostless",
		.dynamic = 1,
		.dpcm_playback = 1,
		.dpcm_capture = 1,
		.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 = "snd-soc-dummy-dai",
		.codec_name = "snd-soc-dummy",
	},
	{
		.name = "Secondary AUXPCM TX Hostless",
		.stream_name = "SEC_AUXPCM_HOSTLESS Capture",
		.cpu_dai_name = "SEC_AUXPCM_TX_HOSTLESS",
		.platform_name  = "msm-pcm-hostless",
		.dynamic = 1,
		.dpcm_capture = 1,
		.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 = "snd-soc-dummy-dai",
		.codec_name = "snd-soc-dummy",
	},
	/* Backend DAI Links */
	{
		.name = LPASS_BE_AFE_PCM_RX,
@@ -2548,14 +2642,12 @@ static int mdm_asoc_machine_probe(struct platform_device *pdev)
		goto err;
	}

	pdata->prim_master_p = of_parse_phandle(pdev->dev.of_node,
						"qcom,prim_mi2s_aux_master", 0);
	pdata->prim_slave_p = of_parse_phandle(pdev->dev.of_node,
						"qcom,prim_mi2s_aux_slave", 0);
	pdata->sec_master_p = of_parse_phandle(pdev->dev.of_node,
						"qcom,sec_mi2s_aux_master", 0);
	pdata->sec_slave_p = of_parse_phandle(pdev->dev.of_node,
						"qcom,sec_mi2s_aux_slave", 0);
	ret = msm_gpioset_initialize(CLIENT_WCD_EXT, &pdev->dev);
	if (ret < 0) {
		dev_err(&pdev->dev, "Error reading dtsi file for gpios\n");
		return -EINVAL;
	}

	mutex_init(&cdc_mclk_mutex);
	atomic_set(&mi2s_ref_count, 0);
	atomic_set(&sec_mi2s_ref_count, 0);