Skip to content

Commit 8dcb0c9

Browse files
Akshu Agrawalbroonie
authored andcommitted
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>
1 parent e36a1d0 commit 8dcb0c9

File tree

3 files changed

+41
-10
lines changed

3 files changed

+41
-10
lines changed

sound/soc/amd/acp-da7219-max98357a.c

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ static const struct snd_pcm_hw_constraint_list constraints_channels = {
133133
.mask = 0,
134134
};
135135

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

153-
machine->i2s_instance = I2S_SP_INSTANCE;
153+
machine->play_i2s_instance = I2S_SP_INSTANCE;
154+
return da7219_clk_enable(substream);
155+
}
156+
157+
static int cz_da7219_cap_startup(struct snd_pcm_substream *substream)
158+
{
159+
struct snd_pcm_runtime *runtime = substream->runtime;
160+
struct snd_soc_pcm_runtime *rtd = substream->private_data;
161+
struct snd_soc_card *card = rtd->card;
162+
struct acp_platform_info *machine = snd_soc_card_get_drvdata(card);
163+
164+
/*
165+
* On this platform for PCM device we support stereo
166+
*/
167+
168+
runtime->hw.channels_max = DUAL_CHANNEL;
169+
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
170+
&constraints_channels);
171+
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
172+
&constraints_rates);
173+
174+
machine->cap_i2s_instance = I2S_SP_INSTANCE;
154175
machine->capture_channel = CAP_CHANNEL1;
155176
return da7219_clk_enable(substream);
156177
}
@@ -177,7 +198,7 @@ static int cz_max_startup(struct snd_pcm_substream *substream)
177198
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
178199
&constraints_rates);
179200

180-
machine->i2s_instance = I2S_BT_INSTANCE;
201+
machine->play_i2s_instance = I2S_BT_INSTANCE;
181202
return da7219_clk_enable(substream);
182203
}
183204

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

206-
machine->i2s_instance = I2S_BT_INSTANCE;
227+
machine->cap_i2s_instance = I2S_BT_INSTANCE;
207228
return da7219_clk_enable(substream);
208229
}
209230

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

227-
machine->i2s_instance = I2S_SP_INSTANCE;
248+
machine->cap_i2s_instance = I2S_SP_INSTANCE;
228249
machine->capture_channel = CAP_CHANNEL0;
229250
return da7219_clk_enable(substream);
230251
}
@@ -234,8 +255,13 @@ static void cz_dmic_shutdown(struct snd_pcm_substream *substream)
234255
da7219_clk_disable();
235256
}
236257

258+
static const struct snd_soc_ops cz_da7219_play_ops = {
259+
.startup = cz_da7219_play_startup,
260+
.shutdown = cz_da7219_shutdown,
261+
};
262+
237263
static const struct snd_soc_ops cz_da7219_cap_ops = {
238-
.startup = cz_da7219_startup,
264+
.startup = cz_da7219_cap_startup,
239265
.shutdown = cz_da7219_shutdown,
240266
};
241267

@@ -266,7 +292,7 @@ static struct snd_soc_dai_link cz_dai_7219_98357[] = {
266292
| SND_SOC_DAIFMT_CBM_CFM,
267293
.init = cz_da7219_init,
268294
.dpcm_playback = 1,
269-
.ops = &cz_da7219_cap_ops,
295+
.ops = &cz_da7219_play_ops,
270296
},
271297
{
272298
.name = "amd-da7219-cap",

sound/soc/amd/acp-pcm-dma.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -846,8 +846,12 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
846846
return -EINVAL;
847847

848848
if (pinfo) {
849-
rtd->i2s_instance = pinfo->i2s_instance;
850-
rtd->capture_channel = pinfo->capture_channel;
849+
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
850+
rtd->i2s_instance = pinfo->play_i2s_instance;
851+
} else {
852+
rtd->i2s_instance = pinfo->cap_i2s_instance;
853+
rtd->capture_channel = pinfo->capture_channel;
854+
}
851855
}
852856
if (adata->asic_type == CHIP_STONEY) {
853857
val = acp_reg_read(adata->acp_mmio,

sound/soc/amd/acp.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ struct audio_drv_data {
158158
* and dma driver
159159
*/
160160
struct acp_platform_info {
161-
u16 i2s_instance;
161+
u16 play_i2s_instance;
162+
u16 cap_i2s_instance;
162163
u16 capture_channel;
163164
};
164165

0 commit comments

Comments
 (0)