Skip to content

Commit 589b466

Browse files
ranj063lgirdwood
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 413a226 commit 589b466

6 files changed

Lines changed: 293 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: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,71 @@ 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+
case SND_AUDIOCODEC_FLAC:
179+
{
180+
struct snd_dec_flac *dec_flac = &params->codec.options.flac_d;
181+
182+
if (dec_flac->sample_size == 16)
183+
bps = snd_pcm_format_physical_width(SNDRV_PCM_FORMAT_S16_LE);
184+
else
185+
bps = snd_pcm_format_physical_width(SNDRV_PCM_FORMAT_S32_LE);
186+
break;
187+
}
188+
default:
189+
bps = snd_pcm_format_physical_width(SNDRV_PCM_FORMAT_S32_LE);
190+
}
191+
192+
if (bps < 0)
193+
return bps;
194+
bits = hda_dsp_get_bits(sdev, bps);
195+
rate = hda_dsp_get_mult_div(sdev, params->codec.sample_rate);
196+
197+
hstream->format_val = rate | bits | (params->codec.ch_out - 1);
198+
hstream->bufsize = cstream->runtime->buffer_size;
199+
hstream->period_bytes = cstream->runtime->fragment_size;
200+
hstream->no_period_wakeup = false;
201+
202+
/* params is not used so pass NULL */
203+
dmab = cstream->runtime->dma_buffer_p;
204+
ret = hda_dsp_stream_hw_params(sdev, hext_stream, dmab, NULL);
205+
if (ret < 0) {
206+
dev_err(sdev->dev, "%s: hdac prepare failed: %d\n", __func__, ret);
207+
return ret;
208+
}
209+
210+
if (hda)
211+
platform_params->no_ipc_position = hda->no_ipc_position;
212+
213+
platform_params->stream_tag = hstream->stream_tag;
214+
215+
return 0;
216+
}
217+
EXPORT_SYMBOL_NS(hda_dsp_compr_hw_params, "SND_SOC_SOF_INTEL_HDA_COMMON");
218+
154219
/* update SPIB register with appl position */
155220
int hda_dsp_pcm_ack(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream)
156221
{
@@ -184,6 +249,16 @@ int hda_dsp_pcm_trigger(struct snd_sof_dev *sdev,
184249
}
185250
EXPORT_SYMBOL_NS(hda_dsp_pcm_trigger, "SND_SOC_SOF_INTEL_HDA_COMMON");
186251

252+
int hda_dsp_compr_trigger(struct snd_sof_dev *sdev,
253+
struct snd_compr_stream *cstream, int cmd)
254+
{
255+
struct hdac_stream *hstream = cstream->runtime->private_data;
256+
struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);
257+
258+
return hda_dsp_stream_trigger(sdev, hext_stream, cmd);
259+
}
260+
EXPORT_SYMBOL_NS(hda_dsp_compr_trigger, "SND_SOC_SOF_INTEL_HDA_COMMON");
261+
187262
snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,
188263
struct snd_pcm_substream *substream)
189264
{
@@ -216,6 +291,20 @@ snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,
216291
}
217292
EXPORT_SYMBOL_NS(hda_dsp_pcm_pointer, "SND_SOC_SOF_INTEL_HDA_COMMON");
218293

294+
int hda_dsp_compr_pointer(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream,
295+
struct snd_compr_tstamp64 *tstamp)
296+
{
297+
struct hdac_stream *hstream = cstream->runtime->private_data;
298+
299+
/* hstream->curr_pos is updated when we receive the ioc */
300+
tstamp->copied_total = hstream->curr_pos;
301+
302+
tstamp->byte_offset = hda_dsp_stream_get_position(hstream, cstream->direction, true);
303+
304+
return 0;
305+
}
306+
EXPORT_SYMBOL_NS(hda_dsp_compr_pointer, "SND_SOC_SOF_INTEL_HDA_COMMON");
307+
219308
int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
220309
struct snd_pcm_substream *substream)
221310
{
@@ -342,6 +431,41 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
342431
}
343432
EXPORT_SYMBOL_NS(hda_dsp_pcm_open, "SND_SOC_SOF_INTEL_HDA_COMMON");
344433

434+
int hda_dsp_compr_open(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream)
435+
{
436+
struct snd_soc_pcm_runtime *rtd = cstream->private_data;
437+
struct snd_soc_component *scomp = sdev->component;
438+
struct hdac_ext_stream *dsp_stream;
439+
struct snd_sof_pcm *spcm;
440+
int direction = cstream->direction;
441+
442+
spcm = snd_sof_find_spcm_dai(scomp, rtd);
443+
if (!spcm) {
444+
dev_err(sdev->dev, "%s: can't find PCM with DAI ID %d\n",
445+
__func__, rtd->dai_link->id);
446+
return -EINVAL;
447+
}
448+
449+
dsp_stream = hda_dsp_stream_get(sdev, direction, 0);
450+
if (!dsp_stream) {
451+
dev_err(sdev->dev, "%s: no stream available\n", __func__);
452+
return -ENODEV;
453+
}
454+
455+
/* binding compr stream to hda stream */
456+
cstream->runtime->private_data = &dsp_stream->hstream;
457+
458+
/*
459+
* Reset the llp cache values (they are used for LLP compensation in
460+
* case the counter is not reset)
461+
*/
462+
dsp_stream->pplcllpl = 0;
463+
dsp_stream->pplcllpu = 0;
464+
465+
return 0;
466+
}
467+
EXPORT_SYMBOL_NS(hda_dsp_compr_open, "SND_SOC_SOF_INTEL_HDA_COMMON");
468+
345469
int hda_dsp_pcm_close(struct snd_sof_dev *sdev,
346470
struct snd_pcm_substream *substream)
347471
{
@@ -361,3 +485,21 @@ int hda_dsp_pcm_close(struct snd_sof_dev *sdev,
361485
return 0;
362486
}
363487
EXPORT_SYMBOL_NS(hda_dsp_pcm_close, "SND_SOC_SOF_INTEL_HDA_COMMON");
488+
489+
int hda_dsp_compr_close(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream)
490+
{
491+
struct hdac_stream *hstream = cstream->runtime->private_data;
492+
int direction = cstream->direction;
493+
int ret;
494+
495+
ret = hda_dsp_stream_put(sdev, direction, hstream->stream_tag);
496+
if (ret)
497+
return -ENODEV;
498+
499+
/* unbinding compress stream to hda stream */
500+
hstream->cstream = NULL;
501+
cstream->runtime->private_data = NULL;
502+
503+
return 0;
504+
}
505+
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
@@ -755,13 +755,12 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev,
755755
return ret;
756756
}
757757

758-
int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev,
759-
struct snd_pcm_substream *substream)
758+
static int _hda_dsp_stream_hw_free(struct snd_sof_dev *sdev,
759+
struct hdac_stream *hstream)
760760
{
761-
struct hdac_stream *hstream = substream->runtime->private_data;
762761
struct hdac_ext_stream *hext_stream = container_of(hstream,
763-
struct hdac_ext_stream,
764-
hstream);
762+
struct hdac_ext_stream,
763+
hstream);
765764
int ret;
766765

767766
ret = hda_dsp_stream_reset(sdev, hstream);
@@ -786,8 +785,21 @@ int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev,
786785

787786
return 0;
788787
}
788+
789+
int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev,
790+
struct snd_pcm_substream *substream)
791+
{
792+
return _hda_dsp_stream_hw_free(sdev, substream->runtime->private_data);
793+
}
789794
EXPORT_SYMBOL_NS(hda_dsp_stream_hw_free, "SND_SOC_SOF_INTEL_HDA_COMMON");
790795

796+
int hda_dsp_stream_compr_hw_free(struct snd_sof_dev *sdev,
797+
struct snd_compr_stream *cstream)
798+
{
799+
return _hda_dsp_stream_hw_free(sdev, cstream->runtime->private_data);
800+
}
801+
EXPORT_SYMBOL_NS(hda_dsp_stream_compr_hw_free, "SND_SOC_SOF_INTEL_HDA_COMMON");
802+
791803
bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev)
792804
{
793805
struct hdac_bus *bus = sof_to_bus(sdev);
@@ -1170,11 +1182,9 @@ EXPORT_SYMBOL_NS(hda_dsp_stream_get_position, "SND_SOC_SOF_INTEL_HDA_COMMON");
11701182
*
11711183
* Returns the raw Linear Link Position value
11721184
*/
1173-
u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
1174-
struct snd_soc_component *component,
1175-
struct snd_pcm_substream *substream)
1185+
static u64 hda_dsp_get_llp(struct snd_sof_dev *sdev,
1186+
struct snd_soc_pcm_runtime *rtd, int dir)
11761187
{
1177-
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
11781188
struct snd_soc_pcm_runtime *be_rtd = NULL;
11791189
struct hdac_ext_stream *hext_stream;
11801190
struct snd_soc_dai *cpu_dai;
@@ -1185,7 +1195,7 @@ u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
11851195
* The LLP needs to be read from the Link DMA used for this FE as it is
11861196
* allowed to use any combination of Link and Host channels
11871197
*/
1188-
for_each_dpcm_be(rtd, substream->stream, dpcm) {
1198+
for_each_dpcm_be(rtd, dir, dpcm) {
11891199
if (dpcm->fe != rtd)
11901200
continue;
11911201

@@ -1199,7 +1209,7 @@ u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
11991209
if (!cpu_dai)
12001210
return 0;
12011211

1202-
hext_stream = snd_soc_dai_get_dma_data(cpu_dai, substream);
1212+
hext_stream = snd_soc_dai_dma_data_get(cpu_dai, dir);
12031213
if (!hext_stream)
12041214
return 0;
12051215

@@ -1223,8 +1233,29 @@ u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
12231233

12241234
return merge_u64(llp_u, llp_l);
12251235
}
1236+
1237+
u64 hda_dsp_get_stream_llp(struct snd_sof_dev *sdev,
1238+
struct snd_soc_component *component,
1239+
struct snd_pcm_substream *substream)
1240+
{
1241+
return hda_dsp_get_llp(sdev, snd_soc_substream_to_rtd(substream),
1242+
substream->stream);
1243+
}
12261244
EXPORT_SYMBOL_NS(hda_dsp_get_stream_llp, "SND_SOC_SOF_INTEL_HDA_COMMON");
12271245

1246+
/**
1247+
* hda_dsp_compr_get_stream_llp - Retrieve the LLP (Linear Link Position) of the stream
1248+
* @sdev: SOF device
1249+
* @cstream: Compress stream
1250+
*
1251+
* Returns the raw Linear Link Position value
1252+
*/
1253+
u64 hda_dsp_compr_get_stream_llp(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream)
1254+
{
1255+
return hda_dsp_get_llp(sdev, cstream->private_data, cstream->direction);
1256+
}
1257+
EXPORT_SYMBOL_NS(hda_dsp_compr_get_stream_llp, "SND_SOC_SOF_INTEL_HDA_COMMON");
1258+
12281259
/**
12291260
* hda_dsp_get_stream_ldp - Retrieve the LDP (Linear DMA Position) of the stream
12301261
* @sdev: SOF device

sound/soc/sof/intel/hda.h

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

686+
int hda_dsp_compr_open(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream);
687+
int hda_dsp_compr_close(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream);
688+
int hda_dsp_compr_hw_params(struct snd_sof_dev *sdev,
689+
struct snd_compr_stream *cstream,
690+
struct snd_compr_params *params,
691+
struct snd_sof_platform_stream_params *platform_params);
692+
int hda_dsp_stream_compr_hw_free(struct snd_sof_dev *sdev,
693+
struct snd_compr_stream *cstream);
694+
int hda_dsp_compr_trigger(struct snd_sof_dev *sdev,
695+
struct snd_compr_stream *cstream, int cmd);
696+
int hda_dsp_compr_pointer(struct snd_sof_dev *sdev, struct snd_compr_stream *cstream,
697+
struct snd_compr_tstamp64 *tstamp);
698+
u64 hda_dsp_compr_get_stream_llp(struct snd_sof_dev *sdev,
699+
struct snd_compr_stream *cstream);
700+
686701
/*
687702
* DSP Stream Operations.
688703
*/

0 commit comments

Comments
 (0)