Skip to content

Commit 007f7cd

Browse files
ranj063ujfalusi
authored andcommitted
ASoC: SOF: ops: Add new platform-specific ops for compress
Add new ops in the struct snd_sof_ops for platform-specific ops for compresssed streams. Also, define and set them for the HDA platforms. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Co-developed-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
1 parent 883326c commit 007f7cd

6 files changed

Lines changed: 282 additions & 11 deletions

File tree

sound/soc/sof/intel/hda-common-ops.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ const struct snd_sof_dsp_ops sof_hda_common_ops = {
5757
.pcm_pointer = hda_dsp_pcm_pointer,
5858
.pcm_ack = hda_dsp_pcm_ack,
5959

60+
.compr_open = hda_dsp_compr_open,
61+
.compr_hw_params = hda_dsp_compr_hw_params,
62+
.compr_hw_free = hda_dsp_stream_compr_hw_free,
63+
.compr_close = hda_dsp_compr_close,
64+
.compr_trigger = hda_dsp_compr_trigger,
65+
.compr_pointer = hda_dsp_compr_pointer,
66+
.compr_get_dai_frame_counter = hda_dsp_compr_get_stream_llp,
67+
6068
.get_dai_frame_counter = hda_dsp_get_stream_llp,
6169
.get_host_byte_counter = hda_dsp_get_stream_ldp,
6270

sound/soc/sof/intel/hda-pcm.c

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,61 @@ int hda_dsp_pcm_hw_params(struct snd_sof_dev *sdev,
151151
}
152152
EXPORT_SYMBOL_NS(hda_dsp_pcm_hw_params, "SND_SOC_SOF_INTEL_HDA_COMMON");
153153

154+
int hda_dsp_compr_hw_params(struct snd_sof_dev *sdev,
155+
struct snd_compr_stream *cstream,
156+
struct snd_compr_params *params,
157+
struct snd_sof_platform_stream_params *platform_params)
158+
{
159+
struct hdac_stream *hstream = cstream->runtime->private_data;
160+
struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);
161+
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
162+
struct snd_dma_buffer *dmab;
163+
u32 bits, rate;
164+
int bps;
165+
int ret;
166+
167+
hstream->cstream = cstream;
168+
dmab = cstream->runtime->dma_buffer_p;
169+
170+
/* Use correct format based on the used codec */
171+
switch (params->codec.id) {
172+
case SND_AUDIOCODEC_PCM:
173+
bps = snd_pcm_format_physical_width(params->codec.format);
174+
break;
175+
case SND_AUDIOCODEC_VORBIS:
176+
bps = snd_pcm_format_physical_width(SNDRV_PCM_FORMAT_S16_LE);
177+
break;
178+
default:
179+
bps = snd_pcm_format_physical_width(SNDRV_PCM_FORMAT_S32_LE);
180+
}
181+
182+
if (bps < 0)
183+
return bps;
184+
bits = hda_dsp_get_bits(sdev, bps);
185+
rate = hda_dsp_get_mult_div(sdev, params->codec.sample_rate);
186+
187+
hstream->format_val = rate | bits | (params->codec.ch_out - 1);
188+
hstream->bufsize = cstream->runtime->buffer_size;
189+
hstream->period_bytes = cstream->runtime->fragment_size;
190+
hstream->no_period_wakeup = false;
191+
192+
/* params is not used so pass NULL */
193+
dmab = cstream->runtime->dma_buffer_p;
194+
ret = hda_dsp_stream_hw_params(sdev, hext_stream, dmab, NULL);
195+
if (ret < 0) {
196+
dev_err(sdev->dev, "%s: hdac prepare failed: %d\n", __func__, ret);
197+
return ret;
198+
}
199+
200+
if (hda)
201+
platform_params->no_ipc_position = hda->no_ipc_position;
202+
203+
platform_params->stream_tag = hstream->stream_tag;
204+
205+
return 0;
206+
}
207+
EXPORT_SYMBOL_NS(hda_dsp_compr_hw_params, "SND_SOC_SOF_INTEL_HDA_COMMON");
208+
154209
/* update SPIB register with appl position */
155210
int hda_dsp_pcm_ack(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream)
156211
{
@@ -184,6 +239,16 @@ int hda_dsp_pcm_trigger(struct snd_sof_dev *sdev,
184239
}
185240
EXPORT_SYMBOL_NS(hda_dsp_pcm_trigger, "SND_SOC_SOF_INTEL_HDA_COMMON");
186241

242+
int hda_dsp_compr_trigger(struct snd_sof_dev *sdev,
243+
struct snd_compr_stream *cstream, int cmd)
244+
{
245+
struct hdac_stream *hstream = cstream->runtime->private_data;
246+
struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);
247+
248+
return hda_dsp_stream_trigger(sdev, hext_stream, cmd);
249+
}
250+
EXPORT_SYMBOL_NS(hda_dsp_compr_trigger, "SND_SOC_SOF_INTEL_HDA_COMMON");
251+
187252
snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,
188253
struct snd_pcm_substream *substream)
189254
{
@@ -216,6 +281,20 @@ snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,
216281
}
217282
EXPORT_SYMBOL_NS(hda_dsp_pcm_pointer, "SND_SOC_SOF_INTEL_HDA_COMMON");
218283

284+
int hda_dsp_compr_pointer(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream,
285+
struct snd_compr_tstamp64 *tstamp)
286+
{
287+
struct hdac_stream *hstream = cstream->runtime->private_data;
288+
289+
/* hstream->curr_pos is updated when we receive the ioc */
290+
tstamp->copied_total += hstream->curr_pos;
291+
292+
tstamp->byte_offset = hda_dsp_stream_get_position(hstream, cstream->direction, true);
293+
294+
return 0;
295+
}
296+
EXPORT_SYMBOL_NS(hda_dsp_compr_pointer, "SND_SOC_SOF_INTEL_HDA_COMMON");
297+
219298
int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
220299
struct snd_pcm_substream *substream)
221300
{
@@ -332,6 +411,41 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
332411
}
333412
EXPORT_SYMBOL_NS(hda_dsp_pcm_open, "SND_SOC_SOF_INTEL_HDA_COMMON");
334413

414+
int hda_dsp_compr_open(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream)
415+
{
416+
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
417+
struct snd_soc_component *scomp = sdev->component;
418+
struct hdac_ext_stream *dsp_stream;
419+
struct snd_sof_pcm *spcm;
420+
int direction = cstream->direction;
421+
422+
spcm = snd_sof_find_spcm_dai(scomp, rtd);
423+
if (!spcm) {
424+
dev_err(sdev->dev, "%s: can't find PCM with DAI ID %d\n",
425+
__func__, rtd->dai_link->id);
426+
return -EINVAL;
427+
}
428+
429+
dsp_stream = hda_dsp_stream_get(sdev, direction, 0);
430+
if (!dsp_stream) {
431+
dev_err(sdev->dev, "%s: no stream available\n", __func__);
432+
return -ENODEV;
433+
}
434+
435+
/* binding compr stream to hda stream */
436+
cstream->runtime->private_data = &dsp_stream->hstream;
437+
438+
/*
439+
* Reset the llp cache values (they are used for LLP compensation in
440+
* case the counter is not reset)
441+
*/
442+
dsp_stream->pplcllpl = 0;
443+
dsp_stream->pplcllpu = 0;
444+
445+
return 0;
446+
}
447+
EXPORT_SYMBOL_NS(hda_dsp_compr_open, "SND_SOC_SOF_INTEL_HDA_COMMON");
448+
335449
int hda_dsp_pcm_close(struct snd_sof_dev *sdev,
336450
struct snd_pcm_substream *substream)
337451
{
@@ -351,3 +465,20 @@ int hda_dsp_pcm_close(struct snd_sof_dev *sdev,
351465
return 0;
352466
}
353467
EXPORT_SYMBOL_NS(hda_dsp_pcm_close, "SND_SOC_SOF_INTEL_HDA_COMMON");
468+
469+
int hda_dsp_compr_close(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream)
470+
{
471+
struct hdac_stream *hstream = cstream->runtime->private_data;
472+
int direction = cstream->direction;
473+
int ret;
474+
475+
ret = hda_dsp_stream_put(sdev, direction, hstream->stream_tag);
476+
if (ret)
477+
return -ENODEV;
478+
479+
/* unbinding compress stream to hda stream */
480+
hstream->cstream = NULL;
481+
cstream->runtime->private_data = NULL;
482+
return 0;
483+
}
484+
EXPORT_SYMBOL_NS(hda_dsp_compr_close, "SND_SOC_SOF_INTEL_HDA_COMMON");

sound/soc/sof/intel/hda-stream.c

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -743,13 +743,12 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev,
743743
return ret;
744744
}
745745

746-
int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev,
747-
struct snd_pcm_substream *substream)
746+
static int _hda_dsp_stream_hw_free(struct snd_sof_dev *sdev,
747+
struct hdac_stream *hstream)
748748
{
749-
struct hdac_stream *hstream = substream->runtime->private_data;
750749
struct hdac_ext_stream *hext_stream = container_of(hstream,
751-
struct hdac_ext_stream,
752-
hstream);
750+
struct hdac_ext_stream,
751+
hstream);
753752
int ret;
754753

755754
ret = hda_dsp_stream_reset(sdev, hstream);
@@ -774,8 +773,21 @@ int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev,
774773

775774
return 0;
776775
}
776+
777+
int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev,
778+
struct snd_pcm_substream *substream)
779+
{
780+
return _hda_dsp_stream_hw_free(sdev, substream->runtime->private_data);
781+
}
777782
EXPORT_SYMBOL_NS(hda_dsp_stream_hw_free, "SND_SOC_SOF_INTEL_HDA_COMMON");
778783

784+
int hda_dsp_stream_compr_hw_free(struct snd_sof_dev *sdev,
785+
struct snd_compr_stream *cstream)
786+
{
787+
return _hda_dsp_stream_hw_free(sdev, cstream->runtime->private_data);
788+
}
789+
EXPORT_SYMBOL_NS(hda_dsp_stream_compr_hw_free, "SND_SOC_SOF_INTEL_HDA_COMMON");
790+
779791
bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev)
780792
{
781793
struct hdac_bus *bus = sof_to_bus(sdev);
@@ -1158,11 +1170,9 @@ EXPORT_SYMBOL_NS(hda_dsp_stream_get_position, "SND_SOC_SOF_INTEL_HDA_COMMON");
11581170
*
11591171
* Returns the raw Linear Link Position value
11601172
*/
1161-
u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
1162-
struct snd_soc_component *component,
1163-
struct snd_pcm_substream *substream)
1173+
static u64 hda_dsp_get_llp(struct snd_sof_dev *sdev,
1174+
struct snd_soc_pcm_runtime *rtd, int dir)
11641175
{
1165-
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
11661176
struct snd_soc_pcm_runtime *be_rtd = NULL;
11671177
struct hdac_ext_stream *hext_stream;
11681178
struct snd_soc_dai *cpu_dai;
@@ -1173,7 +1183,7 @@ u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
11731183
* The LLP needs to be read from the Link DMA used for this FE as it is
11741184
* allowed to use any combination of Link and Host channels
11751185
*/
1176-
for_each_dpcm_be(rtd, substream->stream, dpcm) {
1186+
for_each_dpcm_be(rtd, dir, dpcm) {
11771187
if (dpcm->fe != rtd)
11781188
continue;
11791189

@@ -1187,7 +1197,7 @@ u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
11871197
if (!cpu_dai)
11881198
return 0;
11891199

1190-
hext_stream = snd_soc_dai_get_dma_data(cpu_dai, substream);
1200+
hext_stream = snd_soc_dai_dma_data_get(cpu_dai, dir);
11911201
if (!hext_stream)
11921202
return 0;
11931203

@@ -1211,8 +1221,29 @@ u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
12111221

12121222
return merge_u64(llp_u, llp_l);
12131223
}
1224+
1225+
u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
1226+
struct snd_soc_component *component,
1227+
struct snd_pcm_substream *substream)
1228+
{
1229+
return hda_dsp_get_llp(sdev, snd_soc_substream_to_rtd(substream),
1230+
substream->stream);
1231+
}
12141232
EXPORT_SYMBOL_NS(hda_dsp_get_stream_llp, "SND_SOC_SOF_INTEL_HDA_COMMON");
12151233

1234+
/**
1235+
* hda_dsp_compr_get_stream_llp - Retrieve the LLP (Linear Link Position) of the stream
1236+
* @sdev: SOF device
1237+
* @cstream: Compress stream
1238+
*
1239+
* Returns the raw Linear Link Position value
1240+
*/
1241+
u64 hda_dsp_compr_get_stream_llp(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream)
1242+
{
1243+
return hda_dsp_get_llp(sdev, cstream->private_data, cstream->direction);
1244+
}
1245+
EXPORT_SYMBOL_NS(hda_dsp_compr_get_stream_llp, "SND_SOC_SOF_INTEL_HDA_COMMON");
1246+
12161247
/**
12171248
* hda_dsp_get_stream_ldp - Retrieve the LDP (Linear DMA Position) of the stream
12181249
* @sdev: SOF device

sound/soc/sof/intel/hda.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,21 @@ snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,
660660
struct snd_pcm_substream *substream);
661661
int hda_dsp_pcm_ack(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream);
662662

663+
int hda_dsp_compr_open(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream);
664+
int hda_dsp_compr_close(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream);
665+
int hda_dsp_compr_hw_params(struct snd_sof_dev *sdev,
666+
struct snd_compr_stream *cstream,
667+
struct snd_compr_params *params,
668+
struct snd_sof_platform_stream_params *platform_params);
669+
int hda_dsp_stream_compr_hw_free(struct snd_sof_dev *sdev,
670+
struct snd_compr_stream *cstream);
671+
int hda_dsp_compr_trigger(struct snd_sof_dev *sdev,
672+
struct snd_compr_stream *cstream, int cmd);
673+
int hda_dsp_compr_pointer(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream,
674+
struct snd_compr_tstamp64 *tstamp);
675+
u64 hda_dsp_compr_get_stream_llp(struct snd_sof_dev *sdev,
676+
struct snd_compr_stream *cstream);
677+
663678
/*
664679
* DSP Stream Operations.
665680
*/

sound/soc/sof/ops.h

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/interrupt.h>
1616
#include <linux/kernel.h>
1717
#include <linux/types.h>
18+
#include <sound/compress_driver.h>
1819
#include <sound/pcm.h>
1920
#include "sof-priv.h"
2021

@@ -448,6 +449,79 @@ snd_sof_pcm_platform_hw_params(struct snd_sof_dev *sdev,
448449
return 0;
449450
}
450451

452+
static inline int
453+
snd_sof_compr_platform_open(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream)
454+
{
455+
if (sof_ops(sdev) && sof_ops(sdev)->compr_open)
456+
return sof_ops(sdev)->compr_open(sdev, cstream);
457+
458+
return 0;
459+
}
460+
461+
/* disconnect pcm substream to a host stream */
462+
static inline int
463+
snd_sof_compr_platform_close(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream)
464+
{
465+
if (sof_ops(sdev) && sof_ops(sdev)->compr_close)
466+
return sof_ops(sdev)->compr_close(sdev, cstream);
467+
468+
return 0;
469+
}
470+
471+
/* host stream hw params */
472+
static inline int
473+
snd_sof_compr_platform_hw_params(struct snd_sof_dev *sdev,
474+
struct snd_compr_stream *cstream,
475+
struct snd_compr_params *params,
476+
struct snd_sof_platform_stream_params *platform_params)
477+
{
478+
if (sof_ops(sdev) && sof_ops(sdev)->compr_hw_params)
479+
return sof_ops(sdev)->compr_hw_params(sdev, cstream, params, platform_params);
480+
481+
return 0;
482+
}
483+
484+
static inline int
485+
snd_sof_compr_platform_hw_free(struct snd_sof_dev *sdev,
486+
struct snd_compr_stream *cstream)
487+
{
488+
if (sof_ops(sdev) && sof_ops(sdev)->compr_hw_free)
489+
return sof_ops(sdev)->compr_hw_free(sdev, cstream);
490+
491+
return 0;
492+
}
493+
494+
static inline int
495+
snd_sof_compr_platform_trigger(struct snd_sof_dev *sdev,
496+
struct snd_compr_stream *cstream, int cmd)
497+
{
498+
if (sof_ops(sdev) && sof_ops(sdev)->compr_trigger)
499+
return sof_ops(sdev)->compr_trigger(sdev, cstream, cmd);
500+
501+
return 0;
502+
}
503+
504+
static inline snd_pcm_uframes_t
505+
snd_sof_compr_platform_pointer(struct snd_sof_dev *sdev,
506+
struct snd_compr_stream *cstream,
507+
struct snd_compr_tstamp64 *tstamp)
508+
{
509+
if (sof_ops(sdev) && sof_ops(sdev)->compr_pointer)
510+
return sof_ops(sdev)->compr_pointer(sdev, cstream, tstamp);
511+
512+
return 0;
513+
}
514+
515+
static inline u64
516+
snd_sof_compr_get_dai_frame_counter(struct snd_sof_dev *sdev,
517+
struct snd_compr_stream *cstream)
518+
{
519+
if (sof_ops(sdev) && sof_ops(sdev)->compr_get_dai_frame_counter)
520+
return sof_ops(sdev)->compr_get_dai_frame_counter(sdev, cstream);
521+
522+
return 0;
523+
}
524+
451525
/* host stream hw free */
452526
static inline int
453527
snd_sof_pcm_platform_hw_free(struct snd_sof_dev *sdev,

0 commit comments

Comments
 (0)