Skip to content

Commit 7166437

Browse files
crojewsk-intelbroonie
authored andcommitted
ASoC: Intel: avs: PCM operations for LNL-based platforms
Starting from LNL platform the so-called non-HDAudio transfer types, e.g.: I2S/DMIC, utilize HDAudio LINK DMA rather than GPDMA for the data streaming. In essence, all transfer types now utilize HDAudio Link. Most of the existing code can be reused with the major difference being HDAudio Link query method: - fetch the Link by codec.addr in standard HDAudio transfer case - fetch the Link by LEPTR.ID in non-HDAudio transfer case To make the unification happen, store pointer to the Link in dma_data and utilize it in the common code. And to avoid confusion in transfer-type naming between cAVS-ACE 1.x (SkyLake till MeteorLake) and ACE 2.0+ architecture (LunarLake onward), use: - 'hda' for typical HDAudio transfer case - 'nonhda' for non-HDAudio transfer case, cAVS-ACE 1.x - 'althda' for non-HDAudio transfer case, ACE 2.0+ Reviewed-by: Amadeusz Sławiński <[email protected]> Signed-off-by: Cezary Rojewski <[email protected]> Acked-by: Liam Girdwood <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent af1c968 commit 7166437

File tree

1 file changed

+85
-31
lines changed

1 file changed

+85
-31
lines changed

sound/soc/intel/avs/pcm.c

Lines changed: 85 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct avs_dma_data {
3232
};
3333

3434
struct work_struct period_elapsed_work;
35+
struct hdac_ext_link *link;
3536
struct snd_pcm_substream *substream;
3637
};
3738

@@ -278,32 +279,75 @@ static const struct snd_soc_dai_ops avs_dai_nonhda_be_ops = {
278279
.trigger = avs_dai_nonhda_be_trigger,
279280
};
280281

281-
static int avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
282+
static int __avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai,
283+
struct hdac_ext_link *link)
282284
{
283-
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
284285
struct hdac_ext_stream *link_stream;
285286
struct avs_dma_data *data;
286-
struct hda_codec *codec;
287287
int ret;
288288

289289
ret = avs_dai_startup(substream, dai);
290290
if (ret)
291291
return ret;
292292

293-
codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
294-
link_stream = snd_hdac_ext_stream_assign(&codec->bus->core, substream,
293+
data = snd_soc_dai_get_dma_data(dai, substream);
294+
link_stream = snd_hdac_ext_stream_assign(&data->adev->base.core, substream,
295295
HDAC_EXT_STREAM_TYPE_LINK);
296296
if (!link_stream) {
297297
avs_dai_shutdown(substream, dai);
298298
return -EBUSY;
299299
}
300300

301-
data = snd_soc_dai_get_dma_data(dai, substream);
302301
data->link_stream = link_stream;
303-
substream->runtime->private_data = link_stream;
302+
data->link = link;
304303
return 0;
305304
}
306305

306+
static int avs_dai_hda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
307+
{
308+
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
309+
struct hdac_ext_link *link;
310+
struct avs_dma_data *data;
311+
struct hda_codec *codec;
312+
int ret;
313+
314+
codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
315+
316+
link = snd_hdac_ext_bus_get_hlink_by_addr(&codec->bus->core, codec->core.addr);
317+
if (!link)
318+
return -EINVAL;
319+
320+
ret = __avs_dai_hda_be_startup(substream, dai, link);
321+
if (!ret) {
322+
data = snd_soc_dai_get_dma_data(dai, substream);
323+
substream->runtime->private_data = data->link_stream;
324+
}
325+
326+
return ret;
327+
}
328+
329+
static int avs_dai_i2shda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
330+
{
331+
struct avs_dev *adev = to_avs_dev(dai->component->dev);
332+
struct hdac_ext_link *link;
333+
334+
link = snd_hdac_ext_bus_get_hlink_by_id(&adev->base.core, AZX_REG_ML_LEPTR_ID_INTEL_SSP);
335+
if (!link)
336+
return -EINVAL;
337+
return __avs_dai_hda_be_startup(substream, dai, link);
338+
}
339+
340+
static int avs_dai_dmichda_be_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
341+
{
342+
struct avs_dev *adev = to_avs_dev(dai->component->dev);
343+
struct hdac_ext_link *link;
344+
345+
link = snd_hdac_ext_bus_get_hlink_by_id(&adev->base.core, AZX_REG_ML_LEPTR_ID_INTEL_DMIC);
346+
if (!link)
347+
return -EINVAL;
348+
return __avs_dai_hda_be_startup(substream, dai, link);
349+
}
350+
307351
static void avs_dai_hda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
308352
{
309353
struct avs_dma_data *data = snd_soc_dai_get_dma_data(dai, substream);
@@ -313,6 +357,14 @@ static void avs_dai_hda_be_shutdown(struct snd_pcm_substream *substream, struct
313357
avs_dai_shutdown(substream, dai);
314358
}
315359

360+
static void avs_dai_althda_be_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
361+
{
362+
struct avs_dma_data *data = snd_soc_dai_get_dma_data(dai, substream);
363+
364+
snd_hdac_ext_stream_release(data->link_stream, HDAC_EXT_STREAM_TYPE_LINK);
365+
avs_dai_shutdown(substream, dai);
366+
}
367+
316368
static int avs_dai_hda_be_hw_params(struct snd_pcm_substream *substream,
317369
struct snd_pcm_hw_params *hw_params, struct snd_soc_dai *dai)
318370
{
@@ -328,13 +380,8 @@ static int avs_dai_hda_be_hw_params(struct snd_pcm_substream *substream,
328380

329381
static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
330382
{
331-
struct avs_dma_data *data;
332-
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
333383
struct hdac_ext_stream *link_stream;
334-
struct hdac_ext_link *link;
335-
struct hda_codec *codec;
336-
337-
dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name);
384+
struct avs_dma_data *data;
338385

339386
data = snd_soc_dai_get_dma_data(dai, substream);
340387
if (!data->path)
@@ -346,27 +393,19 @@ static int avs_dai_hda_be_hw_free(struct snd_pcm_substream *substream, struct sn
346393
data->path = NULL;
347394

348395
/* clear link <-> stream mapping */
349-
codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
350-
link = snd_hdac_ext_bus_get_hlink_by_addr(&codec->bus->core, codec->core.addr);
351-
if (!link)
352-
return -EINVAL;
353-
354396
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
355-
snd_hdac_ext_bus_link_clear_stream_id(link, hdac_stream(link_stream)->stream_tag);
397+
snd_hdac_ext_bus_link_clear_stream_id(data->link,
398+
hdac_stream(link_stream)->stream_tag);
356399

357400
return 0;
358401
}
359402

360403
static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
361404
{
362-
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
363405
struct snd_pcm_runtime *runtime = substream->runtime;
364406
const struct snd_soc_pcm_stream *stream_info;
365407
struct hdac_ext_stream *link_stream;
366-
struct hdac_ext_link *link;
367408
struct avs_dma_data *data;
368-
struct hda_codec *codec;
369-
struct hdac_bus *bus;
370409
unsigned int format_val;
371410
unsigned int bits;
372411
int ret;
@@ -377,23 +416,18 @@ static int avs_dai_hda_be_prepare(struct snd_pcm_substream *substream, struct sn
377416
if (link_stream->link_prepared)
378417
return 0;
379418

380-
codec = dev_to_hda_codec(snd_soc_rtd_to_codec(rtd, 0)->dev);
381-
bus = &codec->bus->core;
382419
stream_info = snd_soc_dai_get_pcm_stream(dai, substream->stream);
383420
bits = snd_hdac_stream_format_bits(runtime->format, runtime->subformat,
384421
stream_info->sig_bits);
385422
format_val = snd_hdac_stream_format(runtime->channels, bits, runtime->rate);
386423

387-
snd_hdac_ext_stream_decouple(bus, link_stream, true);
424+
snd_hdac_ext_stream_decouple(&data->adev->base.core, link_stream, true);
388425
snd_hdac_ext_stream_reset(link_stream);
389426
snd_hdac_ext_stream_setup(link_stream, format_val);
390427

391-
link = snd_hdac_ext_bus_get_hlink_by_addr(bus, codec->core.addr);
392-
if (!link)
393-
return -EINVAL;
394-
395428
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
396-
snd_hdac_ext_bus_link_set_stream_id(link, hdac_stream(link_stream)->stream_tag);
429+
snd_hdac_ext_bus_link_set_stream_id(data->link,
430+
hdac_stream(link_stream)->stream_tag);
397431

398432
ret = avs_dai_prepare(substream, dai);
399433
if (ret)
@@ -468,6 +502,26 @@ static const struct snd_soc_dai_ops avs_dai_hda_be_ops = {
468502
.trigger = avs_dai_hda_be_trigger,
469503
};
470504

505+
__maybe_unused
506+
static const struct snd_soc_dai_ops avs_dai_i2shda_be_ops = {
507+
.startup = avs_dai_i2shda_be_startup,
508+
.shutdown = avs_dai_althda_be_shutdown,
509+
.hw_params = avs_dai_hda_be_hw_params,
510+
.hw_free = avs_dai_hda_be_hw_free,
511+
.prepare = avs_dai_hda_be_prepare,
512+
.trigger = avs_dai_hda_be_trigger,
513+
};
514+
515+
__maybe_unused
516+
static const struct snd_soc_dai_ops avs_dai_dmichda_be_ops = {
517+
.startup = avs_dai_dmichda_be_startup,
518+
.shutdown = avs_dai_althda_be_shutdown,
519+
.hw_params = avs_dai_hda_be_hw_params,
520+
.hw_free = avs_dai_hda_be_hw_free,
521+
.prepare = avs_dai_hda_be_prepare,
522+
.trigger = avs_dai_hda_be_trigger,
523+
};
524+
471525
static int hw_rule_param_size(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule)
472526
{
473527
struct snd_interval *interval = hw_param_interval(params, rule->var);

0 commit comments

Comments
 (0)