Skip to content

Commit d52e85a

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 669ecaf commit d52e85a

6 files changed

Lines changed: 243 additions & 6 deletions

File tree

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ 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_close = hda_dsp_compr_close,
63+
.compr_trigger = hda_dsp_compr_trigger,
64+
.compr_pointer = hda_dsp_compr_pointer,
65+
.compr_get_dai_frame_counter = hda_dsp_compr_get_stream_llp,
66+
6067
.get_dai_frame_counter = hda_dsp_get_stream_llp,
6168
.get_host_byte_counter = hda_dsp_get_stream_ldp,
6269

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: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,11 +1158,9 @@ EXPORT_SYMBOL_NS(hda_dsp_stream_get_position, "SND_SOC_SOF_INTEL_HDA_COMMON");
11581158
*
11591159
* Returns the raw Linear Link Position value
11601160
*/
1161-
u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
1162-
struct snd_soc_component *component,
1163-
struct snd_pcm_substream *substream)
1161+
static u64 hda_dsp_get_llp(struct snd_sof_dev *sdev,
1162+
struct snd_soc_pcm_runtime *rtd, int dir)
11641163
{
1165-
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
11661164
struct snd_soc_pcm_runtime *be_rtd = NULL;
11671165
struct hdac_ext_stream *hext_stream;
11681166
struct snd_soc_dai *cpu_dai;
@@ -1173,7 +1171,7 @@ u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
11731171
* The LLP needs to be read from the Link DMA used for this FE as it is
11741172
* allowed to use any combination of Link and Host channels
11751173
*/
1176-
for_each_dpcm_be(rtd, substream->stream, dpcm) {
1174+
for_each_dpcm_be(rtd, dir, dpcm) {
11771175
if (dpcm->fe != rtd)
11781176
continue;
11791177

@@ -1187,7 +1185,7 @@ u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
11871185
if (!cpu_dai)
11881186
return 0;
11891187

1190-
hext_stream = snd_soc_dai_get_dma_data(cpu_dai, substream);
1188+
hext_stream = snd_soc_dai_dma_data_get(cpu_dai, dir);
11911189
if (!hext_stream)
11921190
return 0;
11931191

@@ -1211,8 +1209,29 @@ u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
12111209

12121210
return merge_u64(llp_u, llp_l);
12131211
}
1212+
1213+
u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
1214+
struct snd_soc_component *component,
1215+
struct snd_pcm_substream *substream)
1216+
{
1217+
return hda_dsp_get_llp(sdev, snd_soc_substream_to_rtd(substream),
1218+
substream->stream);
1219+
}
12141220
EXPORT_SYMBOL_NS(hda_dsp_get_stream_llp, "SND_SOC_SOF_INTEL_HDA_COMMON");
12151221

1222+
/**
1223+
* hda_dsp_compr_get_stream_llp - Retrieve the LLP (Linear Link Position) of the stream
1224+
* @sdev: SOF device
1225+
* @cstream: Compress stream
1226+
*
1227+
* Returns the raw Linear Link Position value
1228+
*/
1229+
u64 hda_dsp_compr_get_stream_llp(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream)
1230+
{
1231+
return hda_dsp_get_llp(sdev, cstream->private_data, cstream->direction);
1232+
}
1233+
EXPORT_SYMBOL_NS(hda_dsp_compr_get_stream_llp, "SND_SOC_SOF_INTEL_HDA_COMMON");
1234+
12161235
/**
12171236
* hda_dsp_get_stream_ldp - Retrieve the LDP (Linear DMA Position) of the stream
12181237
* @sdev: SOF device

sound/soc/sof/intel/hda.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,19 @@ 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_compr_trigger(struct snd_sof_dev *sdev,
670+
struct snd_compr_stream *cstream, int cmd);
671+
int hda_dsp_compr_pointer(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream,
672+
struct snd_compr_tstamp64 *tstamp);
673+
u64 hda_dsp_compr_get_stream_llp(struct snd_sof_dev *sdev,
674+
struct snd_compr_stream *cstream);
675+
663676
/*
664677
* DSP Stream Operations.
665678
*/

sound/soc/sof/ops.h

Lines changed: 64 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,69 @@ 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_trigger(struct snd_sof_dev *sdev,
486+
struct snd_compr_stream *cstream, int cmd)
487+
{
488+
if (sof_ops(sdev) && sof_ops(sdev)->compr_trigger)
489+
return sof_ops(sdev)->compr_trigger(sdev, cstream, cmd);
490+
491+
return 0;
492+
}
493+
494+
static inline snd_pcm_uframes_t
495+
snd_sof_compr_platform_pointer(struct snd_sof_dev *sdev,
496+
struct snd_compr_stream *cstream,
497+
struct snd_compr_tstamp64 *tstamp)
498+
{
499+
if (sof_ops(sdev) && sof_ops(sdev)->compr_pointer)
500+
return sof_ops(sdev)->compr_pointer(sdev, cstream, tstamp);
501+
502+
return 0;
503+
}
504+
505+
static inline u64
506+
snd_sof_compr_get_dai_frame_counter(struct snd_sof_dev *sdev,
507+
struct snd_compr_stream *cstream)
508+
{
509+
if (sof_ops(sdev) && sof_ops(sdev)->compr_get_dai_frame_counter)
510+
return sof_ops(sdev)->compr_get_dai_frame_counter(sdev, cstream);
511+
512+
return 0;
513+
}
514+
451515
/* host stream hw free */
452516
static inline int
453517
snd_sof_pcm_platform_hw_free(struct snd_sof_dev *sdev,

sound/soc/sof/sof-priv.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,17 @@ struct snd_sof_dsp_ops {
258258
/* pcm ack */
259259
int (*pcm_ack)(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream); /* optional */
260260

261+
int (*compr_open)(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream);
262+
int (*compr_close)(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream);
263+
int (*compr_hw_params)(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream,
264+
struct snd_compr_params *params,
265+
struct snd_sof_platform_stream_params *platform_params);
266+
int (*compr_trigger)(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream,
267+
int cmd);
268+
int (*compr_pointer)(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream,
269+
struct snd_compr_tstamp64 *tstamp);
270+
u64 (*compr_get_dai_frame_counter)(struct snd_sof_dev *sdev,
271+
struct snd_compr_stream *cstream);
261272
/*
262273
* optional callback to retrieve the number of frames left/arrived from/to
263274
* the DSP on the DAI side (link/codec/DMIC/etc).

0 commit comments

Comments
 (0)