1 // SPDX-License-Identifier: GPL-2.0
5 // Copyright (C) 2019 Renesas Electronics Corp.
6 // Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
10 #include <sound/soc-dai.h>
11 #include <sound/soc-link.h>
13 #define soc_dai_ret(dai, ret) _soc_dai_ret(dai, __func__, ret)
14 static inline int _soc_dai_ret(struct snd_soc_dai
*dai
,
15 const char *func
, int ret
)
17 /* Positive, Zero values are not errors */
21 /* Negative values might be errors */
28 "ASoC: error at %s on %s: %d\n",
29 func
, dai
->name
, ret
);
36 * We might want to check substream by using list.
37 * In such case, we can update these macros.
39 #define soc_dai_mark_push(dai, substream, tgt) ((dai)->mark_##tgt = substream)
40 #define soc_dai_mark_pop(dai, substream, tgt) ((dai)->mark_##tgt = NULL)
41 #define soc_dai_mark_match(dai, substream, tgt) ((dai)->mark_##tgt == substream)
44 * snd_soc_dai_set_sysclk - configure DAI system or master clock.
46 * @clk_id: DAI specific clock ID
47 * @freq: new clock frequency in Hz
48 * @dir: new clock direction - input/output.
50 * Configures the DAI master (MCLK) or system (SYSCLK) clocking.
52 int snd_soc_dai_set_sysclk(struct snd_soc_dai
*dai
, int clk_id
,
53 unsigned int freq
, int dir
)
57 if (dai
->driver
->ops
&&
58 dai
->driver
->ops
->set_sysclk
)
59 ret
= dai
->driver
->ops
->set_sysclk(dai
, clk_id
, freq
, dir
);
61 ret
= snd_soc_component_set_sysclk(dai
->component
, clk_id
, 0,
64 return soc_dai_ret(dai
, ret
);
66 EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk
);
69 * snd_soc_dai_set_clkdiv - configure DAI clock dividers.
71 * @div_id: DAI specific clock divider ID
72 * @div: new clock divisor.
74 * Configures the clock dividers. This is used to derive the best DAI bit and
75 * frame clocks from the system or master clock. It's best to set the DAI bit
76 * and frame clocks as low as possible to save system power.
78 int snd_soc_dai_set_clkdiv(struct snd_soc_dai
*dai
,
83 if (dai
->driver
->ops
&&
84 dai
->driver
->ops
->set_clkdiv
)
85 ret
= dai
->driver
->ops
->set_clkdiv(dai
, div_id
, div
);
87 return soc_dai_ret(dai
, ret
);
89 EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv
);
92 * snd_soc_dai_set_pll - configure DAI PLL.
94 * @pll_id: DAI specific PLL ID
95 * @source: DAI specific source for the PLL
96 * @freq_in: PLL input clock frequency in Hz
97 * @freq_out: requested PLL output clock frequency in Hz
99 * Configures and enables PLL to generate output clock based on input clock.
101 int snd_soc_dai_set_pll(struct snd_soc_dai
*dai
, int pll_id
, int source
,
102 unsigned int freq_in
, unsigned int freq_out
)
106 if (dai
->driver
->ops
&&
107 dai
->driver
->ops
->set_pll
)
108 ret
= dai
->driver
->ops
->set_pll(dai
, pll_id
, source
,
111 ret
= snd_soc_component_set_pll(dai
->component
, pll_id
, source
,
114 return soc_dai_ret(dai
, ret
);
116 EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll
);
119 * snd_soc_dai_set_bclk_ratio - configure BCLK to sample rate ratio.
121 * @ratio: Ratio of BCLK to Sample rate.
123 * Configures the DAI for a preset BCLK to sample rate ratio.
125 int snd_soc_dai_set_bclk_ratio(struct snd_soc_dai
*dai
, unsigned int ratio
)
129 if (dai
->driver
->ops
&&
130 dai
->driver
->ops
->set_bclk_ratio
)
131 ret
= dai
->driver
->ops
->set_bclk_ratio(dai
, ratio
);
133 return soc_dai_ret(dai
, ret
);
135 EXPORT_SYMBOL_GPL(snd_soc_dai_set_bclk_ratio
);
137 int snd_soc_dai_get_fmt_max_priority(struct snd_soc_pcm_runtime
*rtd
)
139 struct snd_soc_dai
*dai
;
143 * return max num if *ALL* DAIs have .auto_selectable_formats
145 for_each_rtd_dais(rtd
, i
, dai
) {
146 if (dai
->driver
->ops
&&
147 dai
->driver
->ops
->num_auto_selectable_formats
)
148 max
= max(max
, dai
->driver
->ops
->num_auto_selectable_formats
);
157 * snd_soc_dai_get_fmt - get supported audio format.
159 * @priority: priority level of supported audio format.
161 * This should return only formats implemented with high
162 * quality by the DAI so that the core can configure a
163 * format which will work well with other devices.
164 * For example devices which don't support both edges of the
165 * LRCLK signal in I2S style formats should only list DSP
166 * modes. This will mean that sometimes fewer formats
167 * are reported here than are supported by set_fmt().
169 u64
snd_soc_dai_get_fmt(struct snd_soc_dai
*dai
, int priority
)
171 const struct snd_soc_dai_ops
*ops
= dai
->driver
->ops
;
173 int i
, max
= 0, until
= priority
;
176 * Collect auto_selectable_formats until priority
179 * auto_selectable_formats[] = { A, B, C };
180 * (A, B, C = SND_SOC_POSSIBLE_DAIFMT_xxx)
183 * priority = 2 : A | B
184 * priority = 3 : A | B | C
185 * priority = 4 : A | B | C
189 max
= ops
->num_auto_selectable_formats
;
194 for (i
= 0; i
< until
; i
++)
195 fmt
|= ops
->auto_selectable_formats
[i
];
201 * snd_soc_dai_set_fmt - configure DAI hardware audio format.
203 * @fmt: SND_SOC_DAIFMT_* format value.
205 * Configures the DAI hardware format and clocking.
207 int snd_soc_dai_set_fmt(struct snd_soc_dai
*dai
, unsigned int fmt
)
211 if (dai
->driver
->ops
&& dai
->driver
->ops
->set_fmt
)
212 ret
= dai
->driver
->ops
->set_fmt(dai
, fmt
);
214 return soc_dai_ret(dai
, ret
);
216 EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt
);
219 * snd_soc_xlate_tdm_slot_mask - generate tx/rx slot mask.
220 * @slots: Number of slots in use.
221 * @tx_mask: bitmask representing active TX slots.
222 * @rx_mask: bitmask representing active RX slots.
224 * Generates the TDM tx and rx slot default masks for DAI.
226 static int snd_soc_xlate_tdm_slot_mask(unsigned int slots
,
227 unsigned int *tx_mask
,
228 unsigned int *rx_mask
)
230 if (*tx_mask
|| *rx_mask
)
236 *tx_mask
= (1 << slots
) - 1;
237 *rx_mask
= (1 << slots
) - 1;
243 * snd_soc_dai_set_tdm_slot() - Configures a DAI for TDM operation
244 * @dai: The DAI to configure
245 * @tx_mask: bitmask representing active TX slots.
246 * @rx_mask: bitmask representing active RX slots.
247 * @slots: Number of slots in use.
248 * @slot_width: Width in bits for each slot.
250 * This function configures the specified DAI for TDM operation. @slot contains
251 * the total number of slots of the TDM stream and @slot_with the width of each
252 * slot in bit clock cycles. @tx_mask and @rx_mask are bitmasks specifying the
253 * active slots of the TDM stream for the specified DAI, i.e. which slots the
254 * DAI should write to or read from. If a bit is set the corresponding slot is
255 * active, if a bit is cleared the corresponding slot is inactive. Bit 0 maps to
256 * the first slot, bit 1 to the second slot and so on. The first active slot
257 * maps to the first channel of the DAI, the second active slot to the second
260 * TDM mode can be disabled by passing 0 for @slots. In this case @tx_mask,
261 * @rx_mask and @slot_width will be ignored.
263 * Returns 0 on success, a negative error code otherwise.
265 int snd_soc_dai_set_tdm_slot(struct snd_soc_dai
*dai
,
266 unsigned int tx_mask
, unsigned int rx_mask
,
267 int slots
, int slot_width
)
271 unsigned int *tdm_mask
[] = {
276 if (dai
->driver
->ops
&&
277 dai
->driver
->ops
->xlate_tdm_slot_mask
)
278 dai
->driver
->ops
->xlate_tdm_slot_mask(slots
,
281 snd_soc_xlate_tdm_slot_mask(slots
, &tx_mask
, &rx_mask
);
283 for_each_pcm_streams(stream
)
284 snd_soc_dai_tdm_mask_set(dai
, stream
, *tdm_mask
[stream
]);
286 if (dai
->driver
->ops
&&
287 dai
->driver
->ops
->set_tdm_slot
)
288 ret
= dai
->driver
->ops
->set_tdm_slot(dai
, tx_mask
, rx_mask
,
290 return soc_dai_ret(dai
, ret
);
292 EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot
);
295 * snd_soc_dai_set_channel_map - configure DAI audio channel map
297 * @tx_num: how many TX channels
298 * @tx_slot: pointer to an array which imply the TX slot number channel
300 * @rx_num: how many RX channels
301 * @rx_slot: pointer to an array which imply the RX slot number channel
304 * configure the relationship between channel number and TDM slot number.
306 int snd_soc_dai_set_channel_map(struct snd_soc_dai
*dai
,
307 unsigned int tx_num
, unsigned int *tx_slot
,
308 unsigned int rx_num
, unsigned int *rx_slot
)
312 if (dai
->driver
->ops
&&
313 dai
->driver
->ops
->set_channel_map
)
314 ret
= dai
->driver
->ops
->set_channel_map(dai
, tx_num
, tx_slot
,
316 return soc_dai_ret(dai
, ret
);
318 EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map
);
321 * snd_soc_dai_get_channel_map - Get DAI audio channel map
323 * @tx_num: how many TX channels
324 * @tx_slot: pointer to an array which imply the TX slot number channel
326 * @rx_num: how many RX channels
327 * @rx_slot: pointer to an array which imply the RX slot number channel
330 int snd_soc_dai_get_channel_map(struct snd_soc_dai
*dai
,
331 unsigned int *tx_num
, unsigned int *tx_slot
,
332 unsigned int *rx_num
, unsigned int *rx_slot
)
336 if (dai
->driver
->ops
&&
337 dai
->driver
->ops
->get_channel_map
)
338 ret
= dai
->driver
->ops
->get_channel_map(dai
, tx_num
, tx_slot
,
340 return soc_dai_ret(dai
, ret
);
342 EXPORT_SYMBOL_GPL(snd_soc_dai_get_channel_map
);
345 * snd_soc_dai_set_tristate - configure DAI system or master clock.
347 * @tristate: tristate enable
349 * Tristates the DAI so that others can use it.
351 int snd_soc_dai_set_tristate(struct snd_soc_dai
*dai
, int tristate
)
355 if (dai
->driver
->ops
&&
356 dai
->driver
->ops
->set_tristate
)
357 ret
= dai
->driver
->ops
->set_tristate(dai
, tristate
);
359 return soc_dai_ret(dai
, ret
);
361 EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate
);
364 * snd_soc_dai_digital_mute - configure DAI system or master clock.
367 * @direction: stream to mute
371 int snd_soc_dai_digital_mute(struct snd_soc_dai
*dai
, int mute
,
377 * ignore if direction was CAPTURE
378 * and it had .no_capture_mute flag
380 if (dai
->driver
->ops
&&
381 dai
->driver
->ops
->mute_stream
&&
382 (direction
== SNDRV_PCM_STREAM_PLAYBACK
||
383 !dai
->driver
->ops
->no_capture_mute
))
384 ret
= dai
->driver
->ops
->mute_stream(dai
, mute
, direction
);
386 return soc_dai_ret(dai
, ret
);
388 EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute
);
390 int snd_soc_dai_hw_params(struct snd_soc_dai
*dai
,
391 struct snd_pcm_substream
*substream
,
392 struct snd_pcm_hw_params
*params
)
396 if (dai
->driver
->ops
&&
397 dai
->driver
->ops
->hw_params
)
398 ret
= dai
->driver
->ops
->hw_params(substream
, params
, dai
);
400 /* mark substream if succeeded */
402 soc_dai_mark_push(dai
, substream
, hw_params
);
404 return soc_dai_ret(dai
, ret
);
407 void snd_soc_dai_hw_free(struct snd_soc_dai
*dai
,
408 struct snd_pcm_substream
*substream
,
411 if (rollback
&& !soc_dai_mark_match(dai
, substream
, hw_params
))
414 if (dai
->driver
->ops
&&
415 dai
->driver
->ops
->hw_free
)
416 dai
->driver
->ops
->hw_free(substream
, dai
);
418 /* remove marked substream */
419 soc_dai_mark_pop(dai
, substream
, hw_params
);
422 int snd_soc_dai_startup(struct snd_soc_dai
*dai
,
423 struct snd_pcm_substream
*substream
)
427 if (dai
->driver
->ops
&&
428 dai
->driver
->ops
->startup
)
429 ret
= dai
->driver
->ops
->startup(substream
, dai
);
431 /* mark substream if succeeded */
433 soc_dai_mark_push(dai
, substream
, startup
);
435 return soc_dai_ret(dai
, ret
);
438 void snd_soc_dai_shutdown(struct snd_soc_dai
*dai
,
439 struct snd_pcm_substream
*substream
,
442 if (rollback
&& !soc_dai_mark_match(dai
, substream
, startup
))
445 if (dai
->driver
->ops
&&
446 dai
->driver
->ops
->shutdown
)
447 dai
->driver
->ops
->shutdown(substream
, dai
);
449 /* remove marked substream */
450 soc_dai_mark_pop(dai
, substream
, startup
);
453 int snd_soc_dai_compress_new(struct snd_soc_dai
*dai
,
454 struct snd_soc_pcm_runtime
*rtd
, int num
)
457 if (dai
->driver
->compress_new
)
458 ret
= dai
->driver
->compress_new(rtd
, num
);
459 return soc_dai_ret(dai
, ret
);
463 * snd_soc_dai_stream_valid() - check if a DAI supports the given stream
465 * Returns true if the DAI supports the indicated stream type.
467 bool snd_soc_dai_stream_valid(struct snd_soc_dai
*dai
, int dir
)
469 struct snd_soc_pcm_stream
*stream
= snd_soc_dai_get_pcm_stream(dai
, dir
);
471 /* If the codec specifies any channels at all, it supports the stream */
472 return stream
->channels_min
;
476 * snd_soc_dai_link_set_capabilities() - set dai_link properties based on its DAIs
478 void snd_soc_dai_link_set_capabilities(struct snd_soc_dai_link
*dai_link
)
480 bool supported
[SNDRV_PCM_STREAM_LAST
+ 1];
483 for_each_pcm_streams(direction
) {
484 struct snd_soc_dai_link_component
*cpu
;
485 struct snd_soc_dai_link_component
*codec
;
486 struct snd_soc_dai
*dai
;
487 bool supported_cpu
= false;
488 bool supported_codec
= false;
491 for_each_link_cpus(dai_link
, i
, cpu
) {
492 dai
= snd_soc_find_dai_with_mutex(cpu
);
493 if (dai
&& snd_soc_dai_stream_valid(dai
, direction
)) {
494 supported_cpu
= true;
498 for_each_link_codecs(dai_link
, i
, codec
) {
499 dai
= snd_soc_find_dai_with_mutex(codec
);
500 if (dai
&& snd_soc_dai_stream_valid(dai
, direction
)) {
501 supported_codec
= true;
505 supported
[direction
] = supported_cpu
&& supported_codec
;
508 dai_link
->dpcm_playback
= supported
[SNDRV_PCM_STREAM_PLAYBACK
];
509 dai_link
->dpcm_capture
= supported
[SNDRV_PCM_STREAM_CAPTURE
];
511 EXPORT_SYMBOL_GPL(snd_soc_dai_link_set_capabilities
);
513 void snd_soc_dai_action(struct snd_soc_dai
*dai
,
514 int stream
, int action
)
516 /* see snd_soc_dai_stream_active() */
517 dai
->stream
[stream
].active
+= action
;
519 /* see snd_soc_component_active() */
520 dai
->component
->active
+= action
;
522 EXPORT_SYMBOL_GPL(snd_soc_dai_action
);
524 int snd_soc_dai_active(struct snd_soc_dai
*dai
)
529 for_each_pcm_streams(stream
)
530 active
+= dai
->stream
[stream
].active
;
534 EXPORT_SYMBOL_GPL(snd_soc_dai_active
);
536 int snd_soc_pcm_dai_probe(struct snd_soc_pcm_runtime
*rtd
, int order
)
538 struct snd_soc_dai
*dai
;
541 for_each_rtd_dais(rtd
, i
, dai
) {
542 if (dai
->driver
->probe_order
!= order
)
548 if (dai
->driver
->probe
) {
549 int ret
= dai
->driver
->probe(dai
);
552 return soc_dai_ret(dai
, ret
);
561 int snd_soc_pcm_dai_remove(struct snd_soc_pcm_runtime
*rtd
, int order
)
563 struct snd_soc_dai
*dai
;
566 for_each_rtd_dais(rtd
, i
, dai
) {
567 if (dai
->driver
->remove_order
!= order
)
571 dai
->driver
->remove
) {
572 r
= dai
->driver
->remove(dai
);
574 ret
= r
; /* use last error */
583 int snd_soc_pcm_dai_new(struct snd_soc_pcm_runtime
*rtd
)
585 struct snd_soc_dai
*dai
;
588 for_each_rtd_dais(rtd
, i
, dai
) {
589 if (dai
->driver
->pcm_new
) {
590 int ret
= dai
->driver
->pcm_new(rtd
, dai
);
592 return soc_dai_ret(dai
, ret
);
599 int snd_soc_pcm_dai_prepare(struct snd_pcm_substream
*substream
)
601 struct snd_soc_pcm_runtime
*rtd
= asoc_substream_to_rtd(substream
);
602 struct snd_soc_dai
*dai
;
605 for_each_rtd_dais(rtd
, i
, dai
) {
606 if (dai
->driver
->ops
&&
607 dai
->driver
->ops
->prepare
) {
608 ret
= dai
->driver
->ops
->prepare(substream
, dai
);
610 return soc_dai_ret(dai
, ret
);
617 static int soc_dai_trigger(struct snd_soc_dai
*dai
,
618 struct snd_pcm_substream
*substream
, int cmd
)
622 if (dai
->driver
->ops
&&
623 dai
->driver
->ops
->trigger
)
624 ret
= dai
->driver
->ops
->trigger(substream
, cmd
, dai
);
626 return soc_dai_ret(dai
, ret
);
629 int snd_soc_pcm_dai_trigger(struct snd_pcm_substream
*substream
,
630 int cmd
, int rollback
)
632 struct snd_soc_pcm_runtime
*rtd
= asoc_substream_to_rtd(substream
);
633 struct snd_soc_dai
*dai
;
637 case SNDRV_PCM_TRIGGER_START
:
638 case SNDRV_PCM_TRIGGER_RESUME
:
639 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
640 for_each_rtd_dais(rtd
, i
, dai
) {
641 ret
= soc_dai_trigger(dai
, substream
, cmd
);
644 soc_dai_mark_push(dai
, substream
, trigger
);
647 case SNDRV_PCM_TRIGGER_STOP
:
648 case SNDRV_PCM_TRIGGER_SUSPEND
:
649 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
650 for_each_rtd_dais(rtd
, i
, dai
) {
651 if (rollback
&& !soc_dai_mark_match(dai
, substream
, trigger
))
654 r
= soc_dai_trigger(dai
, substream
, cmd
);
656 ret
= r
; /* use last ret */
657 soc_dai_mark_pop(dai
, substream
, trigger
);
664 int snd_soc_pcm_dai_bespoke_trigger(struct snd_pcm_substream
*substream
,
667 struct snd_soc_pcm_runtime
*rtd
= asoc_substream_to_rtd(substream
);
668 struct snd_soc_dai
*dai
;
671 for_each_rtd_dais(rtd
, i
, dai
) {
672 if (dai
->driver
->ops
&&
673 dai
->driver
->ops
->bespoke_trigger
) {
674 ret
= dai
->driver
->ops
->bespoke_trigger(substream
,
677 return soc_dai_ret(dai
, ret
);
684 void snd_soc_pcm_dai_delay(struct snd_pcm_substream
*substream
,
685 snd_pcm_sframes_t
*cpu_delay
,
686 snd_pcm_sframes_t
*codec_delay
)
688 struct snd_soc_pcm_runtime
*rtd
= asoc_substream_to_rtd(substream
);
689 struct snd_soc_dai
*dai
;
693 * We're looking for the delay through the full audio path so it needs to
694 * be the maximum of the DAIs doing transmit and the maximum of the DAIs
695 * doing receive (ie, all CPUs and all CODECs) rather than just the maximum
700 for_each_rtd_cpu_dais(rtd
, i
, dai
)
701 if (dai
->driver
->ops
&&
702 dai
->driver
->ops
->delay
)
703 *cpu_delay
= max(*cpu_delay
, dai
->driver
->ops
->delay(substream
, dai
));
706 for_each_rtd_codec_dais(rtd
, i
, dai
)
707 if (dai
->driver
->ops
&&
708 dai
->driver
->ops
->delay
)
709 *codec_delay
= max(*codec_delay
, dai
->driver
->ops
->delay(substream
, dai
));
712 int snd_soc_dai_compr_startup(struct snd_soc_dai
*dai
,
713 struct snd_compr_stream
*cstream
)
717 if (dai
->driver
->cops
&&
718 dai
->driver
->cops
->startup
)
719 ret
= dai
->driver
->cops
->startup(cstream
, dai
);
721 /* mark cstream if succeeded */
723 soc_dai_mark_push(dai
, cstream
, compr_startup
);
725 return soc_dai_ret(dai
, ret
);
727 EXPORT_SYMBOL_GPL(snd_soc_dai_compr_startup
);
729 void snd_soc_dai_compr_shutdown(struct snd_soc_dai
*dai
,
730 struct snd_compr_stream
*cstream
,
733 if (rollback
&& !soc_dai_mark_match(dai
, cstream
, compr_startup
))
736 if (dai
->driver
->cops
&&
737 dai
->driver
->cops
->shutdown
)
738 dai
->driver
->cops
->shutdown(cstream
, dai
);
740 /* remove marked cstream */
741 soc_dai_mark_pop(dai
, cstream
, compr_startup
);
743 EXPORT_SYMBOL_GPL(snd_soc_dai_compr_shutdown
);
745 int snd_soc_dai_compr_trigger(struct snd_soc_dai
*dai
,
746 struct snd_compr_stream
*cstream
, int cmd
)
750 if (dai
->driver
->cops
&&
751 dai
->driver
->cops
->trigger
)
752 ret
= dai
->driver
->cops
->trigger(cstream
, cmd
, dai
);
754 return soc_dai_ret(dai
, ret
);
756 EXPORT_SYMBOL_GPL(snd_soc_dai_compr_trigger
);
758 int snd_soc_dai_compr_set_params(struct snd_soc_dai
*dai
,
759 struct snd_compr_stream
*cstream
,
760 struct snd_compr_params
*params
)
764 if (dai
->driver
->cops
&&
765 dai
->driver
->cops
->set_params
)
766 ret
= dai
->driver
->cops
->set_params(cstream
, params
, dai
);
768 return soc_dai_ret(dai
, ret
);
770 EXPORT_SYMBOL_GPL(snd_soc_dai_compr_set_params
);
772 int snd_soc_dai_compr_get_params(struct snd_soc_dai
*dai
,
773 struct snd_compr_stream
*cstream
,
774 struct snd_codec
*params
)
778 if (dai
->driver
->cops
&&
779 dai
->driver
->cops
->get_params
)
780 ret
= dai
->driver
->cops
->get_params(cstream
, params
, dai
);
782 return soc_dai_ret(dai
, ret
);
784 EXPORT_SYMBOL_GPL(snd_soc_dai_compr_get_params
);
786 int snd_soc_dai_compr_ack(struct snd_soc_dai
*dai
,
787 struct snd_compr_stream
*cstream
,
792 if (dai
->driver
->cops
&&
793 dai
->driver
->cops
->ack
)
794 ret
= dai
->driver
->cops
->ack(cstream
, bytes
, dai
);
796 return soc_dai_ret(dai
, ret
);
798 EXPORT_SYMBOL_GPL(snd_soc_dai_compr_ack
);
800 int snd_soc_dai_compr_pointer(struct snd_soc_dai
*dai
,
801 struct snd_compr_stream
*cstream
,
802 struct snd_compr_tstamp
*tstamp
)
806 if (dai
->driver
->cops
&&
807 dai
->driver
->cops
->pointer
)
808 ret
= dai
->driver
->cops
->pointer(cstream
, tstamp
, dai
);
810 return soc_dai_ret(dai
, ret
);
812 EXPORT_SYMBOL_GPL(snd_soc_dai_compr_pointer
);
814 int snd_soc_dai_compr_set_metadata(struct snd_soc_dai
*dai
,
815 struct snd_compr_stream
*cstream
,
816 struct snd_compr_metadata
*metadata
)
820 if (dai
->driver
->cops
&&
821 dai
->driver
->cops
->set_metadata
)
822 ret
= dai
->driver
->cops
->set_metadata(cstream
, metadata
, dai
);
824 return soc_dai_ret(dai
, ret
);
826 EXPORT_SYMBOL_GPL(snd_soc_dai_compr_set_metadata
);
828 int snd_soc_dai_compr_get_metadata(struct snd_soc_dai
*dai
,
829 struct snd_compr_stream
*cstream
,
830 struct snd_compr_metadata
*metadata
)
834 if (dai
->driver
->cops
&&
835 dai
->driver
->cops
->get_metadata
)
836 ret
= dai
->driver
->cops
->get_metadata(cstream
, metadata
, dai
);
838 return soc_dai_ret(dai
, ret
);
840 EXPORT_SYMBOL_GPL(snd_soc_dai_compr_get_metadata
);