mirror of https://gitee.com/openkylin/linux.git
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: Akshu Agrawal <akshu.agrawal@amd.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
e36a1d0d24
commit
8dcb0c90c6
|
@ -133,7 +133,7 @@ static const struct snd_pcm_hw_constraint_list constraints_channels = {
|
||||||
.mask = 0,
|
.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_pcm_runtime *runtime = substream->runtime;
|
||||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
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,
|
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
|
||||||
&constraints_rates);
|
&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;
|
machine->capture_channel = CAP_CHANNEL1;
|
||||||
return da7219_clk_enable(substream);
|
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,
|
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
|
||||||
&constraints_rates);
|
&constraints_rates);
|
||||||
|
|
||||||
machine->i2s_instance = I2S_BT_INSTANCE;
|
machine->play_i2s_instance = I2S_BT_INSTANCE;
|
||||||
return da7219_clk_enable(substream);
|
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,
|
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
|
||||||
&constraints_rates);
|
&constraints_rates);
|
||||||
|
|
||||||
machine->i2s_instance = I2S_BT_INSTANCE;
|
machine->cap_i2s_instance = I2S_BT_INSTANCE;
|
||||||
return da7219_clk_enable(substream);
|
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,
|
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
|
||||||
&constraints_rates);
|
&constraints_rates);
|
||||||
|
|
||||||
machine->i2s_instance = I2S_SP_INSTANCE;
|
machine->cap_i2s_instance = I2S_SP_INSTANCE;
|
||||||
machine->capture_channel = CAP_CHANNEL0;
|
machine->capture_channel = CAP_CHANNEL0;
|
||||||
return da7219_clk_enable(substream);
|
return da7219_clk_enable(substream);
|
||||||
}
|
}
|
||||||
|
@ -234,8 +255,13 @@ static void cz_dmic_shutdown(struct snd_pcm_substream *substream)
|
||||||
da7219_clk_disable();
|
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 = {
|
static const struct snd_soc_ops cz_da7219_cap_ops = {
|
||||||
.startup = cz_da7219_startup,
|
.startup = cz_da7219_cap_startup,
|
||||||
.shutdown = cz_da7219_shutdown,
|
.shutdown = cz_da7219_shutdown,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -266,7 +292,7 @@ static struct snd_soc_dai_link cz_dai_7219_98357[] = {
|
||||||
| SND_SOC_DAIFMT_CBM_CFM,
|
| SND_SOC_DAIFMT_CBM_CFM,
|
||||||
.init = cz_da7219_init,
|
.init = cz_da7219_init,
|
||||||
.dpcm_playback = 1,
|
.dpcm_playback = 1,
|
||||||
.ops = &cz_da7219_cap_ops,
|
.ops = &cz_da7219_play_ops,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.name = "amd-da7219-cap",
|
.name = "amd-da7219-cap",
|
||||||
|
|
|
@ -846,8 +846,12 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (pinfo) {
|
if (pinfo) {
|
||||||
rtd->i2s_instance = pinfo->i2s_instance;
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
||||||
rtd->capture_channel = pinfo->capture_channel;
|
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) {
|
if (adata->asic_type == CHIP_STONEY) {
|
||||||
val = acp_reg_read(adata->acp_mmio,
|
val = acp_reg_read(adata->acp_mmio,
|
||||||
|
|
|
@ -158,7 +158,8 @@ struct audio_drv_data {
|
||||||
* and dma driver
|
* and dma driver
|
||||||
*/
|
*/
|
||||||
struct acp_platform_info {
|
struct acp_platform_info {
|
||||||
u16 i2s_instance;
|
u16 play_i2s_instance;
|
||||||
|
u16 cap_i2s_instance;
|
||||||
u16 capture_channel;
|
u16 capture_channel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue