Skip to content

Commit 3bf82e4

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 f84617c commit 3bf82e4

6 files changed

Lines changed: 274 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: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,51 @@ 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+
/* compr params do not store bit depth, default to S32_LE */
171+
bps = snd_pcm_format_physical_width(params->codec.format);
172+
if (bps < 0)
173+
return bps;
174+
bits = hda_dsp_get_bits(sdev, bps);
175+
rate = hda_dsp_get_mult_div(sdev, params->codec.sample_rate);
176+
177+
hstream->format_val = rate | bits | (params->codec.ch_out - 1);
178+
hstream->bufsize = cstream->runtime->buffer_size;
179+
hstream->period_bytes = cstream->runtime->fragment_size;
180+
hstream->no_period_wakeup = false;
181+
182+
/* params is not used so pass NULL */
183+
dmab = cstream->runtime->dma_buffer_p;
184+
ret = hda_dsp_stream_hw_params(sdev, hext_stream, dmab, NULL);
185+
if (ret < 0) {
186+
dev_err(sdev->dev, "%s: hdac prepare failed: %d\n", __func__, ret);
187+
return ret;
188+
}
189+
190+
if (hda)
191+
platform_params->no_ipc_position = hda->no_ipc_position;
192+
193+
platform_params->stream_tag = hstream->stream_tag;
194+
195+
return 0;
196+
}
197+
EXPORT_SYMBOL_NS(hda_dsp_compr_hw_params, "SND_SOC_SOF_INTEL_HDA_COMMON");
198+
154199
/* update SPIB register with appl position */
155200
int hda_dsp_pcm_ack(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream)
156201
{
@@ -184,6 +229,16 @@ int hda_dsp_pcm_trigger(struct snd_sof_dev *sdev,
184229
}
185230
EXPORT_SYMBOL_NS(hda_dsp_pcm_trigger, "SND_SOC_SOF_INTEL_HDA_COMMON");
186231

232+
int hda_dsp_compr_trigger(struct snd_sof_dev *sdev,
233+
struct snd_compr_stream *cstream, int cmd)
234+
{
235+
struct hdac_stream *hstream = cstream->runtime->private_data;
236+
struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);
237+
238+
return hda_dsp_stream_trigger(sdev, hext_stream, cmd);
239+
}
240+
EXPORT_SYMBOL_NS(hda_dsp_compr_trigger, "SND_SOC_SOF_INTEL_HDA_COMMON");
241+
187242
snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,
188243
struct snd_pcm_substream *substream)
189244
{
@@ -216,6 +271,22 @@ snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,
216271
}
217272
EXPORT_SYMBOL_NS(hda_dsp_pcm_pointer, "SND_SOC_SOF_INTEL_HDA_COMMON");
218273

274+
int hda_dsp_compr_pointer(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream,
275+
struct snd_compr_tstamp64 *tstamp)
276+
{
277+
struct hdac_stream *hstream = cstream->runtime->private_data;
278+
snd_pcm_uframes_t pos;
279+
280+
/* hstream->curr_pos is updated when we receive the ioc */
281+
tstamp->copied_total += hstream->curr_pos;
282+
283+
pos = hda_dsp_stream_get_position(hstream, cstream->direction, true);
284+
tstamp->byte_offset = do_div(pos, cstream->runtime->buffer_size);
285+
286+
return 0;
287+
}
288+
EXPORT_SYMBOL_NS(hda_dsp_compr_pointer, "SND_SOC_SOF_INTEL_HDA_COMMON");
289+
219290
int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
220291
struct snd_pcm_substream *substream)
221292
{
@@ -332,6 +403,41 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
332403
}
333404
EXPORT_SYMBOL_NS(hda_dsp_pcm_open, "SND_SOC_SOF_INTEL_HDA_COMMON");
334405

406+
int hda_dsp_compr_open(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream)
407+
{
408+
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
409+
struct snd_soc_component *scomp = sdev->component;
410+
struct hdac_ext_stream *dsp_stream;
411+
struct snd_sof_pcm *spcm;
412+
int direction = cstream->direction;
413+
414+
spcm = snd_sof_find_spcm_dai(scomp, rtd);
415+
if (!spcm) {
416+
dev_err(sdev->dev, "%s: can't find PCM with DAI ID %d\n",
417+
__func__, rtd->dai_link->id);
418+
return -EINVAL;
419+
}
420+
421+
dsp_stream = hda_dsp_stream_get(sdev, direction, 0);
422+
if (!dsp_stream) {
423+
dev_err(sdev->dev, "%s: no stream available\n", __func__);
424+
return -ENODEV;
425+
}
426+
427+
/* binding compr stream to hda stream */
428+
cstream->runtime->private_data = &dsp_stream->hstream;
429+
430+
/*
431+
* Reset the llp cache values (they are used for LLP compensation in
432+
* case the counter is not reset)
433+
*/
434+
dsp_stream->pplcllpl = 0;
435+
dsp_stream->pplcllpu = 0;
436+
437+
return 0;
438+
}
439+
EXPORT_SYMBOL_NS(hda_dsp_compr_open, "SND_SOC_SOF_INTEL_HDA_COMMON");
440+
335441
int hda_dsp_pcm_close(struct snd_sof_dev *sdev,
336442
struct snd_pcm_substream *substream)
337443
{
@@ -351,3 +457,20 @@ int hda_dsp_pcm_close(struct snd_sof_dev *sdev,
351457
return 0;
352458
}
353459
EXPORT_SYMBOL_NS(hda_dsp_pcm_close, "SND_SOC_SOF_INTEL_HDA_COMMON");
460+
461+
int hda_dsp_compr_close(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream)
462+
{
463+
struct hdac_stream *hstream = cstream->runtime->private_data;
464+
int direction = cstream->direction;
465+
int ret;
466+
467+
ret = hda_dsp_stream_put(sdev, direction, hstream->stream_tag);
468+
if (ret)
469+
return -ENODEV;
470+
471+
/* unbinding compress stream to hda stream */
472+
hstream->cstream = NULL;
473+
cstream->runtime->private_data = NULL;
474+
return 0;
475+
}
476+
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)