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

Unverified Commit 8dcb0c90 authored by Akshu Agrawal's avatar Akshu Agrawal Committed by Mark Brown
Browse files

ASoC: AMD: Fix simultaneous playback and capture on different channel



If capture and playback are started on different channel (I2S/BT)
there is a possibilty that channel information passed from machine driver
is overwritten before the configuration is done in dma driver.
Example:
113.597588: cz_max_startup: ---playback sets BT channel
113.597694: cz_dmic1_startup: ---capture sets I2S channel
113.597979: acp_dma_hw_params: ---configures capture for I2S channel
113.598114: acp_dma_hw_params: ---configures playback for I2S channel

This is fixed by having 2 separate instance for playback and capture.

Signed-off-by: default avatarAkshu Agrawal <akshu.agrawal@amd.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent e36a1d0d
Loading
Loading
Loading
Loading
+33 −7
Original line number Diff line number Diff line
@@ -133,7 +133,7 @@ static const struct snd_pcm_hw_constraint_list constraints_channels = {
	.mask = 0,
};

static int cz_da7219_startup(struct snd_pcm_substream *substream)
static int cz_da7219_play_startup(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
@@ -150,7 +150,28 @@ static int cz_da7219_startup(struct snd_pcm_substream *substream)
	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				   &constraints_rates);

	machine->i2s_instance = I2S_SP_INSTANCE;
	machine->play_i2s_instance = I2S_SP_INSTANCE;
	return da7219_clk_enable(substream);
}

static int cz_da7219_cap_startup(struct snd_pcm_substream *substream)
{
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct snd_soc_pcm_runtime *rtd = substream->private_data;
	struct snd_soc_card *card = rtd->card;
	struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);

	/*
	 * On this platform for PCM device we support stereo
	 */

	runtime->hw.channels_max = DUAL_CHANNEL;
	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
				   &constraints_channels);
	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				   &constraints_rates);

	machine->cap_i2s_instance = I2S_SP_INSTANCE;
	machine->capture_channel = CAP_CHANNEL1;
	return da7219_clk_enable(substream);
}
@@ -177,7 +198,7 @@ static int cz_max_startup(struct snd_pcm_substream *substream)
	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				   &constraints_rates);

	machine->i2s_instance = I2S_BT_INSTANCE;
	machine->play_i2s_instance = I2S_BT_INSTANCE;
	return da7219_clk_enable(substream);
}

@@ -203,7 +224,7 @@ static int cz_dmic0_startup(struct snd_pcm_substream *substream)
	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				   &constraints_rates);

	machine->i2s_instance = I2S_BT_INSTANCE;
	machine->cap_i2s_instance = I2S_BT_INSTANCE;
	return da7219_clk_enable(substream);
}

@@ -224,7 +245,7 @@ static int cz_dmic1_startup(struct snd_pcm_substream *substream)
	snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
				   &constraints_rates);

	machine->i2s_instance = I2S_SP_INSTANCE;
	machine->cap_i2s_instance = I2S_SP_INSTANCE;
	machine->capture_channel = CAP_CHANNEL0;
	return da7219_clk_enable(substream);
}
@@ -234,8 +255,13 @@ static void cz_dmic_shutdown(struct snd_pcm_substream *substream)
	da7219_clk_disable();
}

static const struct snd_soc_ops cz_da7219_play_ops = {
	.startup = cz_da7219_play_startup,
	.shutdown = cz_da7219_shutdown,
};

static const struct snd_soc_ops cz_da7219_cap_ops = {
	.startup = cz_da7219_startup,
	.startup = cz_da7219_cap_startup,
	.shutdown = cz_da7219_shutdown,
};

@@ -266,7 +292,7 @@ static struct snd_soc_dai_link cz_dai_7219_98357[] = {
				| SND_SOC_DAIFMT_CBM_CFM,
		.init = cz_da7219_init,
		.dpcm_playback = 1,
		.ops = &cz_da7219_cap_ops,
		.ops = &cz_da7219_play_ops,
	},
	{
		.name = "amd-da7219-cap",
+6 −2
Original line number Diff line number Diff line
@@ -846,9 +846,13 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
		return -EINVAL;

	if (pinfo) {
		rtd->i2s_instance = pinfo->i2s_instance;
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			rtd->i2s_instance = pinfo->play_i2s_instance;
		} else {
			rtd->i2s_instance = pinfo->cap_i2s_instance;
			rtd->capture_channel = pinfo->capture_channel;
		}
	}
	if (adata->asic_type == CHIP_STONEY) {
		val = acp_reg_read(adata->acp_mmio,
				   mmACP_I2S_16BIT_RESOLUTION_EN);
+2 −1
Original line number Diff line number Diff line
@@ -158,7 +158,8 @@ struct audio_drv_data {
 * and dma driver
 */
struct acp_platform_info {
	u16 i2s_instance;
	u16 play_i2s_instance;
	u16 cap_i2s_instance;
	u16 capture_channel;
};