Commit | Line | Data |
---|---|---|
06f6e1d4 KM |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // | |
3 | // soc-dai.c | |
4 | // | |
5 | // Copyright (C) 2019 Renesas Electronics Corp. | |
6 | // Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | |
7 | // | |
8 | ||
9 | #include <sound/soc.h> | |
10 | #include <sound/soc-dai.h> | |
0cbbf8a0 | 11 | #include <sound/soc-link.h> |
06f6e1d4 | 12 | |
aa7b8230 KM |
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) | |
16 | { | |
17 | switch (ret) { | |
18 | case -EPROBE_DEFER: | |
19 | case -ENOTSUPP: | |
20 | case 0: | |
21 | break; | |
22 | default: | |
23 | dev_err(dai->dev, | |
24 | "ASoC: error at %s on %s: %d\n", | |
25 | func, dai->name, ret); | |
26 | } | |
27 | ||
28 | return ret; | |
29 | } | |
30 | ||
06f6e1d4 KM |
31 | /** |
32 | * snd_soc_dai_set_sysclk - configure DAI system or master clock. | |
33 | * @dai: DAI | |
34 | * @clk_id: DAI specific clock ID | |
35 | * @freq: new clock frequency in Hz | |
36 | * @dir: new clock direction - input/output. | |
37 | * | |
38 | * Configures the DAI master (MCLK) or system (SYSCLK) clocking. | |
39 | */ | |
40 | int snd_soc_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, | |
41 | unsigned int freq, int dir) | |
42 | { | |
aa7b8230 KM |
43 | int ret; |
44 | ||
479914ed KM |
45 | if (dai->driver->ops && |
46 | dai->driver->ops->set_sysclk) | |
aa7b8230 KM |
47 | ret = dai->driver->ops->set_sysclk(dai, clk_id, freq, dir); |
48 | else | |
49 | ret = snd_soc_component_set_sysclk(dai->component, clk_id, 0, | |
50 | freq, dir); | |
06f6e1d4 | 51 | |
aa7b8230 | 52 | return soc_dai_ret(dai, ret); |
06f6e1d4 KM |
53 | } |
54 | EXPORT_SYMBOL_GPL(snd_soc_dai_set_sysclk); | |
55 | ||
56 | /** | |
57 | * snd_soc_dai_set_clkdiv - configure DAI clock dividers. | |
58 | * @dai: DAI | |
59 | * @div_id: DAI specific clock divider ID | |
60 | * @div: new clock divisor. | |
61 | * | |
62 | * Configures the clock dividers. This is used to derive the best DAI bit and | |
63 | * frame clocks from the system or master clock. It's best to set the DAI bit | |
64 | * and frame clocks as low as possible to save system power. | |
65 | */ | |
66 | int snd_soc_dai_set_clkdiv(struct snd_soc_dai *dai, | |
67 | int div_id, int div) | |
68 | { | |
aa7b8230 KM |
69 | int ret = -EINVAL; |
70 | ||
479914ed KM |
71 | if (dai->driver->ops && |
72 | dai->driver->ops->set_clkdiv) | |
aa7b8230 KM |
73 | ret = dai->driver->ops->set_clkdiv(dai, div_id, div); |
74 | ||
75 | return soc_dai_ret(dai, ret); | |
06f6e1d4 KM |
76 | } |
77 | EXPORT_SYMBOL_GPL(snd_soc_dai_set_clkdiv); | |
78 | ||
79 | /** | |
80 | * snd_soc_dai_set_pll - configure DAI PLL. | |
81 | * @dai: DAI | |
82 | * @pll_id: DAI specific PLL ID | |
83 | * @source: DAI specific source for the PLL | |
84 | * @freq_in: PLL input clock frequency in Hz | |
85 | * @freq_out: requested PLL output clock frequency in Hz | |
86 | * | |
87 | * Configures and enables PLL to generate output clock based on input clock. | |
88 | */ | |
89 | int snd_soc_dai_set_pll(struct snd_soc_dai *dai, int pll_id, int source, | |
90 | unsigned int freq_in, unsigned int freq_out) | |
91 | { | |
aa7b8230 KM |
92 | int ret; |
93 | ||
479914ed KM |
94 | if (dai->driver->ops && |
95 | dai->driver->ops->set_pll) | |
aa7b8230 KM |
96 | ret = dai->driver->ops->set_pll(dai, pll_id, source, |
97 | freq_in, freq_out); | |
98 | else | |
99 | ret = snd_soc_component_set_pll(dai->component, pll_id, source, | |
100 | freq_in, freq_out); | |
06f6e1d4 | 101 | |
aa7b8230 | 102 | return soc_dai_ret(dai, ret); |
06f6e1d4 KM |
103 | } |
104 | EXPORT_SYMBOL_GPL(snd_soc_dai_set_pll); | |
105 | ||
106 | /** | |
107 | * snd_soc_dai_set_bclk_ratio - configure BCLK to sample rate ratio. | |
108 | * @dai: DAI | |
109 | * @ratio: Ratio of BCLK to Sample rate. | |
110 | * | |
111 | * Configures the DAI for a preset BCLK to sample rate ratio. | |
112 | */ | |
113 | int snd_soc_dai_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) | |
114 | { | |
aa7b8230 KM |
115 | int ret = -EINVAL; |
116 | ||
479914ed KM |
117 | if (dai->driver->ops && |
118 | dai->driver->ops->set_bclk_ratio) | |
aa7b8230 KM |
119 | ret = dai->driver->ops->set_bclk_ratio(dai, ratio); |
120 | ||
121 | return soc_dai_ret(dai, ret); | |
06f6e1d4 KM |
122 | } |
123 | EXPORT_SYMBOL_GPL(snd_soc_dai_set_bclk_ratio); | |
124 | ||
125 | /** | |
126 | * snd_soc_dai_set_fmt - configure DAI hardware audio format. | |
127 | * @dai: DAI | |
128 | * @fmt: SND_SOC_DAIFMT_* format value. | |
129 | * | |
130 | * Configures the DAI hardware format and clocking. | |
131 | */ | |
132 | int snd_soc_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |
133 | { | |
aa7b8230 KM |
134 | int ret = -ENOTSUPP; |
135 | ||
479914ed KM |
136 | if (dai->driver->ops && |
137 | dai->driver->ops->set_fmt) | |
aa7b8230 KM |
138 | ret = dai->driver->ops->set_fmt(dai, fmt); |
139 | ||
140 | return soc_dai_ret(dai, ret); | |
06f6e1d4 KM |
141 | } |
142 | EXPORT_SYMBOL_GPL(snd_soc_dai_set_fmt); | |
143 | ||
144 | /** | |
145 | * snd_soc_xlate_tdm_slot - generate tx/rx slot mask. | |
146 | * @slots: Number of slots in use. | |
147 | * @tx_mask: bitmask representing active TX slots. | |
148 | * @rx_mask: bitmask representing active RX slots. | |
149 | * | |
150 | * Generates the TDM tx and rx slot default masks for DAI. | |
151 | */ | |
152 | static int snd_soc_xlate_tdm_slot_mask(unsigned int slots, | |
153 | unsigned int *tx_mask, | |
154 | unsigned int *rx_mask) | |
155 | { | |
156 | if (*tx_mask || *rx_mask) | |
157 | return 0; | |
158 | ||
159 | if (!slots) | |
160 | return -EINVAL; | |
161 | ||
162 | *tx_mask = (1 << slots) - 1; | |
163 | *rx_mask = (1 << slots) - 1; | |
164 | ||
165 | return 0; | |
166 | } | |
167 | ||
168 | /** | |
169 | * snd_soc_dai_set_tdm_slot() - Configures a DAI for TDM operation | |
170 | * @dai: The DAI to configure | |
171 | * @tx_mask: bitmask representing active TX slots. | |
172 | * @rx_mask: bitmask representing active RX slots. | |
173 | * @slots: Number of slots in use. | |
174 | * @slot_width: Width in bits for each slot. | |
175 | * | |
176 | * This function configures the specified DAI for TDM operation. @slot contains | |
177 | * the total number of slots of the TDM stream and @slot_with the width of each | |
178 | * slot in bit clock cycles. @tx_mask and @rx_mask are bitmasks specifying the | |
179 | * active slots of the TDM stream for the specified DAI, i.e. which slots the | |
180 | * DAI should write to or read from. If a bit is set the corresponding slot is | |
181 | * active, if a bit is cleared the corresponding slot is inactive. Bit 0 maps to | |
182 | * the first slot, bit 1 to the second slot and so on. The first active slot | |
183 | * maps to the first channel of the DAI, the second active slot to the second | |
184 | * channel and so on. | |
185 | * | |
186 | * TDM mode can be disabled by passing 0 for @slots. In this case @tx_mask, | |
187 | * @rx_mask and @slot_width will be ignored. | |
188 | * | |
189 | * Returns 0 on success, a negative error code otherwise. | |
190 | */ | |
191 | int snd_soc_dai_set_tdm_slot(struct snd_soc_dai *dai, | |
192 | unsigned int tx_mask, unsigned int rx_mask, | |
193 | int slots, int slot_width) | |
194 | { | |
aa7b8230 KM |
195 | int ret = -ENOTSUPP; |
196 | ||
479914ed KM |
197 | if (dai->driver->ops && |
198 | dai->driver->ops->xlate_tdm_slot_mask) | |
06f6e1d4 KM |
199 | dai->driver->ops->xlate_tdm_slot_mask(slots, |
200 | &tx_mask, &rx_mask); | |
201 | else | |
202 | snd_soc_xlate_tdm_slot_mask(slots, &tx_mask, &rx_mask); | |
203 | ||
204 | dai->tx_mask = tx_mask; | |
205 | dai->rx_mask = rx_mask; | |
206 | ||
479914ed KM |
207 | if (dai->driver->ops && |
208 | dai->driver->ops->set_tdm_slot) | |
aa7b8230 | 209 | ret = dai->driver->ops->set_tdm_slot(dai, tx_mask, rx_mask, |
06f6e1d4 | 210 | slots, slot_width); |
aa7b8230 | 211 | return soc_dai_ret(dai, ret); |
06f6e1d4 KM |
212 | } |
213 | EXPORT_SYMBOL_GPL(snd_soc_dai_set_tdm_slot); | |
214 | ||
215 | /** | |
216 | * snd_soc_dai_set_channel_map - configure DAI audio channel map | |
217 | * @dai: DAI | |
218 | * @tx_num: how many TX channels | |
219 | * @tx_slot: pointer to an array which imply the TX slot number channel | |
220 | * 0~num-1 uses | |
221 | * @rx_num: how many RX channels | |
222 | * @rx_slot: pointer to an array which imply the RX slot number channel | |
223 | * 0~num-1 uses | |
224 | * | |
225 | * configure the relationship between channel number and TDM slot number. | |
226 | */ | |
227 | int snd_soc_dai_set_channel_map(struct snd_soc_dai *dai, | |
228 | unsigned int tx_num, unsigned int *tx_slot, | |
229 | unsigned int rx_num, unsigned int *rx_slot) | |
230 | { | |
aa7b8230 KM |
231 | int ret = -ENOTSUPP; |
232 | ||
479914ed KM |
233 | if (dai->driver->ops && |
234 | dai->driver->ops->set_channel_map) | |
aa7b8230 KM |
235 | ret = dai->driver->ops->set_channel_map(dai, tx_num, tx_slot, |
236 | rx_num, rx_slot); | |
237 | return soc_dai_ret(dai, ret); | |
06f6e1d4 KM |
238 | } |
239 | EXPORT_SYMBOL_GPL(snd_soc_dai_set_channel_map); | |
240 | ||
241 | /** | |
242 | * snd_soc_dai_get_channel_map - Get DAI audio channel map | |
243 | * @dai: DAI | |
244 | * @tx_num: how many TX channels | |
245 | * @tx_slot: pointer to an array which imply the TX slot number channel | |
246 | * 0~num-1 uses | |
247 | * @rx_num: how many RX channels | |
248 | * @rx_slot: pointer to an array which imply the RX slot number channel | |
249 | * 0~num-1 uses | |
250 | */ | |
251 | int snd_soc_dai_get_channel_map(struct snd_soc_dai *dai, | |
252 | unsigned int *tx_num, unsigned int *tx_slot, | |
253 | unsigned int *rx_num, unsigned int *rx_slot) | |
254 | { | |
aa7b8230 KM |
255 | int ret = -ENOTSUPP; |
256 | ||
479914ed KM |
257 | if (dai->driver->ops && |
258 | dai->driver->ops->get_channel_map) | |
aa7b8230 KM |
259 | ret = dai->driver->ops->get_channel_map(dai, tx_num, tx_slot, |
260 | rx_num, rx_slot); | |
261 | return soc_dai_ret(dai, ret); | |
06f6e1d4 KM |
262 | } |
263 | EXPORT_SYMBOL_GPL(snd_soc_dai_get_channel_map); | |
264 | ||
265 | /** | |
266 | * snd_soc_dai_set_tristate - configure DAI system or master clock. | |
267 | * @dai: DAI | |
268 | * @tristate: tristate enable | |
269 | * | |
270 | * Tristates the DAI so that others can use it. | |
271 | */ | |
272 | int snd_soc_dai_set_tristate(struct snd_soc_dai *dai, int tristate) | |
273 | { | |
aa7b8230 KM |
274 | int ret = -EINVAL; |
275 | ||
479914ed KM |
276 | if (dai->driver->ops && |
277 | dai->driver->ops->set_tristate) | |
aa7b8230 KM |
278 | ret = dai->driver->ops->set_tristate(dai, tristate); |
279 | ||
280 | return soc_dai_ret(dai, ret); | |
06f6e1d4 KM |
281 | } |
282 | EXPORT_SYMBOL_GPL(snd_soc_dai_set_tristate); | |
283 | ||
284 | /** | |
285 | * snd_soc_dai_digital_mute - configure DAI system or master clock. | |
286 | * @dai: DAI | |
287 | * @mute: mute enable | |
288 | * @direction: stream to mute | |
289 | * | |
290 | * Mutes the DAI DAC. | |
291 | */ | |
292 | int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute, | |
293 | int direction) | |
294 | { | |
aa7b8230 KM |
295 | int ret = -ENOTSUPP; |
296 | ||
479914ed KM |
297 | if (dai->driver->ops && |
298 | dai->driver->ops->mute_stream) | |
aa7b8230 | 299 | ret = dai->driver->ops->mute_stream(dai, mute, direction); |
06f6e1d4 | 300 | else if (direction == SNDRV_PCM_STREAM_PLAYBACK && |
479914ed | 301 | dai->driver->ops && |
06f6e1d4 | 302 | dai->driver->ops->digital_mute) |
aa7b8230 KM |
303 | ret = dai->driver->ops->digital_mute(dai, mute); |
304 | ||
305 | return soc_dai_ret(dai, ret); | |
06f6e1d4 KM |
306 | } |
307 | EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute); | |
aa6166c2 KM |
308 | |
309 | int snd_soc_dai_hw_params(struct snd_soc_dai *dai, | |
310 | struct snd_pcm_substream *substream, | |
311 | struct snd_pcm_hw_params *params) | |
312 | { | |
313 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
aa7b8230 | 314 | int ret = 0; |
aa6166c2 KM |
315 | |
316 | /* perform any topology hw_params fixups before DAI */ | |
0cbbf8a0 KM |
317 | ret = snd_soc_link_be_hw_params_fixup(rtd, params); |
318 | if (ret < 0) | |
319 | goto end; | |
aa6166c2 | 320 | |
479914ed KM |
321 | if (dai->driver->ops && |
322 | dai->driver->ops->hw_params) | |
aa6166c2 | 323 | ret = dai->driver->ops->hw_params(substream, params, dai); |
aa7b8230 KM |
324 | end: |
325 | return soc_dai_ret(dai, ret); | |
aa6166c2 | 326 | } |
846faaed KM |
327 | |
328 | void snd_soc_dai_hw_free(struct snd_soc_dai *dai, | |
329 | struct snd_pcm_substream *substream) | |
330 | { | |
479914ed KM |
331 | if (dai->driver->ops && |
332 | dai->driver->ops->hw_free) | |
846faaed KM |
333 | dai->driver->ops->hw_free(substream, dai); |
334 | } | |
5a52a045 KM |
335 | |
336 | int snd_soc_dai_startup(struct snd_soc_dai *dai, | |
337 | struct snd_pcm_substream *substream) | |
338 | { | |
339 | int ret = 0; | |
340 | ||
479914ed KM |
341 | if (dai->driver->ops && |
342 | dai->driver->ops->startup) | |
5a52a045 KM |
343 | ret = dai->driver->ops->startup(substream, dai); |
344 | ||
aa7b8230 | 345 | return soc_dai_ret(dai, ret); |
5a52a045 | 346 | } |
330fcb51 KM |
347 | |
348 | void snd_soc_dai_shutdown(struct snd_soc_dai *dai, | |
349 | struct snd_pcm_substream *substream) | |
350 | { | |
479914ed KM |
351 | if (dai->driver->ops && |
352 | dai->driver->ops->shutdown) | |
330fcb51 KM |
353 | dai->driver->ops->shutdown(substream, dai); |
354 | } | |
4beb8e10 | 355 | |
1dea80d4 KM |
356 | snd_pcm_sframes_t snd_soc_dai_delay(struct snd_soc_dai *dai, |
357 | struct snd_pcm_substream *substream) | |
358 | { | |
359 | int delay = 0; | |
360 | ||
479914ed KM |
361 | if (dai->driver->ops && |
362 | dai->driver->ops->delay) | |
1dea80d4 KM |
363 | delay = dai->driver->ops->delay(substream, dai); |
364 | ||
365 | return delay; | |
366 | } | |
e0f22622 | 367 | |
b423c420 KM |
368 | int snd_soc_dai_compress_new(struct snd_soc_dai *dai, |
369 | struct snd_soc_pcm_runtime *rtd, int num) | |
370 | { | |
aa7b8230 | 371 | int ret = -ENOTSUPP; |
b423c420 | 372 | if (dai->driver->compress_new) |
aa7b8230 KM |
373 | ret = dai->driver->compress_new(rtd, num); |
374 | return soc_dai_ret(dai, ret); | |
b423c420 | 375 | } |
467fece8 KM |
376 | |
377 | /* | |
378 | * snd_soc_dai_stream_valid() - check if a DAI supports the given stream | |
379 | * | |
380 | * Returns true if the DAI supports the indicated stream type. | |
381 | */ | |
382 | bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int dir) | |
383 | { | |
acf253c1 | 384 | struct snd_soc_pcm_stream *stream = snd_soc_dai_get_pcm_stream(dai, dir); |
467fece8 KM |
385 | |
386 | /* If the codec specifies any channels at all, it supports the stream */ | |
387 | return stream->channels_min; | |
388 | } | |
0b73ba55 | 389 | |
dc829106 KM |
390 | void snd_soc_dai_action(struct snd_soc_dai *dai, |
391 | int stream, int action) | |
392 | { | |
5552f8d7 | 393 | /* see snd_soc_dai_stream_active() */ |
dc829106 | 394 | dai->stream_active[stream] += action; |
0812a08a | 395 | |
488b2ca5 | 396 | /* see snd_soc_component_active() */ |
dc829106 KM |
397 | dai->component->active += action; |
398 | } | |
399 | EXPORT_SYMBOL_GPL(snd_soc_dai_action); | |
400 | ||
efffd9b3 KM |
401 | int snd_soc_dai_active(struct snd_soc_dai *dai) |
402 | { | |
403 | int stream, active; | |
404 | ||
405 | active = 0; | |
406 | for_each_pcm_streams(stream) | |
407 | active += dai->stream_active[stream]; | |
408 | ||
409 | return active; | |
410 | } | |
411 | EXPORT_SYMBOL_GPL(snd_soc_dai_active); | |
412 | ||
51801aea KM |
413 | int snd_soc_pcm_dai_probe(struct snd_soc_pcm_runtime *rtd, int order) |
414 | { | |
415 | struct snd_soc_dai *dai; | |
416 | int i; | |
417 | ||
418 | for_each_rtd_dais(rtd, i, dai) { | |
419 | if (dai->driver->probe_order != order) | |
420 | continue; | |
421 | ||
422 | if (dai->driver->probe) { | |
423 | int ret = dai->driver->probe(dai); | |
424 | ||
425 | if (ret < 0) | |
426 | return soc_dai_ret(dai, ret); | |
427 | } | |
428 | ||
429 | dai->probed = 1; | |
430 | } | |
431 | ||
432 | return 0; | |
433 | } | |
434 | ||
7eaa313b KM |
435 | int snd_soc_pcm_dai_remove(struct snd_soc_pcm_runtime *rtd, int order) |
436 | { | |
437 | struct snd_soc_dai *dai; | |
438 | int i, r, ret = 0; | |
439 | ||
440 | for_each_rtd_dais(rtd, i, dai) { | |
441 | if (dai->driver->remove_order != order) | |
442 | continue; | |
443 | ||
444 | if (dai->probed && | |
445 | dai->driver->remove) { | |
446 | r = dai->driver->remove(dai); | |
447 | if (r < 0) | |
448 | ret = r; /* use last error */ | |
449 | } | |
450 | ||
451 | dai->probed = 0; | |
452 | } | |
453 | ||
454 | return ret; | |
455 | } | |
456 | ||
0b73ba55 KM |
457 | int snd_soc_pcm_dai_new(struct snd_soc_pcm_runtime *rtd) |
458 | { | |
459 | struct snd_soc_dai *dai; | |
460 | int i, ret = 0; | |
461 | ||
462 | for_each_rtd_dais(rtd, i, dai) { | |
463 | if (dai->driver->pcm_new) { | |
464 | ret = dai->driver->pcm_new(rtd, dai); | |
465 | if (ret < 0) | |
466 | return soc_dai_ret(dai, ret); | |
467 | } | |
468 | } | |
469 | ||
470 | return 0; | |
471 | } | |
d108c7fd KM |
472 | |
473 | int snd_soc_pcm_dai_prepare(struct snd_pcm_substream *substream) | |
474 | { | |
475 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
476 | struct snd_soc_dai *dai; | |
477 | int i, ret; | |
478 | ||
479 | for_each_rtd_dais(rtd, i, dai) { | |
480 | if (dai->driver->ops && | |
481 | dai->driver->ops->prepare) { | |
482 | ret = dai->driver->ops->prepare(substream, dai); | |
483 | if (ret < 0) | |
484 | return soc_dai_ret(dai, ret); | |
485 | } | |
486 | } | |
487 | ||
488 | return 0; | |
489 | } | |
42f2472d KM |
490 | |
491 | int snd_soc_pcm_dai_trigger(struct snd_pcm_substream *substream, | |
492 | int cmd) | |
493 | { | |
494 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
495 | struct snd_soc_dai *dai; | |
496 | int i, ret; | |
497 | ||
498 | for_each_rtd_dais(rtd, i, dai) { | |
499 | if (dai->driver->ops && | |
500 | dai->driver->ops->trigger) { | |
501 | ret = dai->driver->ops->trigger(substream, cmd, dai); | |
502 | if (ret < 0) | |
503 | return soc_dai_ret(dai, ret); | |
504 | } | |
505 | } | |
506 | ||
507 | return 0; | |
508 | } | |
30819358 KM |
509 | |
510 | int snd_soc_pcm_dai_bespoke_trigger(struct snd_pcm_substream *substream, | |
511 | int cmd) | |
512 | { | |
513 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | |
514 | struct snd_soc_dai *dai; | |
515 | int i, ret; | |
516 | ||
517 | for_each_rtd_dais(rtd, i, dai) { | |
518 | if (dai->driver->ops && | |
519 | dai->driver->ops->bespoke_trigger) { | |
520 | ret = dai->driver->ops->bespoke_trigger(substream, | |
521 | cmd, dai); | |
522 | if (ret < 0) | |
523 | return soc_dai_ret(dai, ret); | |
524 | } | |
525 | } | |
526 | ||
527 | return 0; | |
528 | } | |
b5ae4cce KM |
529 | |
530 | int snd_soc_dai_compr_startup(struct snd_soc_dai *dai, | |
531 | struct snd_compr_stream *cstream) | |
532 | { | |
533 | int ret = 0; | |
534 | ||
535 | if (dai->driver->cops && | |
536 | dai->driver->cops->startup) | |
537 | ret = dai->driver->cops->startup(cstream, dai); | |
538 | ||
539 | return soc_dai_ret(dai, ret); | |
540 | } | |
541 | EXPORT_SYMBOL_GPL(snd_soc_dai_compr_startup); | |
2b25f81d KM |
542 | |
543 | void snd_soc_dai_compr_shutdown(struct snd_soc_dai *dai, | |
544 | struct snd_compr_stream *cstream) | |
545 | { | |
546 | if (dai->driver->cops && | |
547 | dai->driver->cops->shutdown) | |
548 | dai->driver->cops->shutdown(cstream, dai); | |
549 | } | |
550 | EXPORT_SYMBOL_GPL(snd_soc_dai_compr_shutdown); | |
eb08411b KM |
551 | |
552 | int snd_soc_dai_compr_trigger(struct snd_soc_dai *dai, | |
553 | struct snd_compr_stream *cstream, int cmd) | |
554 | { | |
555 | int ret = 0; | |
556 | ||
557 | if (dai->driver->cops && | |
558 | dai->driver->cops->trigger) | |
559 | ret = dai->driver->cops->trigger(cstream, cmd, dai); | |
560 | ||
561 | return soc_dai_ret(dai, ret); | |
562 | } | |
563 | EXPORT_SYMBOL_GPL(snd_soc_dai_compr_trigger); | |
8dfedafb KM |
564 | |
565 | int snd_soc_dai_compr_set_params(struct snd_soc_dai *dai, | |
566 | struct snd_compr_stream *cstream, | |
567 | struct snd_compr_params *params) | |
568 | { | |
569 | int ret = 0; | |
570 | ||
571 | if (dai->driver->cops && | |
572 | dai->driver->cops->set_params) | |
573 | ret = dai->driver->cops->set_params(cstream, params, dai); | |
574 | ||
575 | return soc_dai_ret(dai, ret); | |
576 | } | |
577 | EXPORT_SYMBOL_GPL(snd_soc_dai_compr_set_params); | |
adbef543 KM |
578 | |
579 | int snd_soc_dai_compr_get_params(struct snd_soc_dai *dai, | |
580 | struct snd_compr_stream *cstream, | |
581 | struct snd_codec *params) | |
582 | { | |
583 | int ret = 0; | |
584 | ||
585 | if (dai->driver->cops && | |
586 | dai->driver->cops->get_params) | |
587 | ret = dai->driver->cops->get_params(cstream, params, dai); | |
588 | ||
589 | return soc_dai_ret(dai, ret); | |
590 | } | |
591 | EXPORT_SYMBOL_GPL(snd_soc_dai_compr_get_params); | |
53294353 KM |
592 | |
593 | int snd_soc_dai_compr_ack(struct snd_soc_dai *dai, | |
594 | struct snd_compr_stream *cstream, | |
595 | size_t bytes) | |
596 | { | |
597 | int ret = 0; | |
598 | ||
599 | if (dai->driver->cops && | |
600 | dai->driver->cops->ack) | |
601 | ret = dai->driver->cops->ack(cstream, bytes, dai); | |
602 | ||
603 | return soc_dai_ret(dai, ret); | |
604 | } | |
605 | EXPORT_SYMBOL_GPL(snd_soc_dai_compr_ack); | |
ed38cc59 KM |
606 | |
607 | int snd_soc_dai_compr_pointer(struct snd_soc_dai *dai, | |
608 | struct snd_compr_stream *cstream, | |
609 | struct snd_compr_tstamp *tstamp) | |
610 | { | |
611 | int ret = 0; | |
612 | ||
613 | if (dai->driver->cops && | |
614 | dai->driver->cops->pointer) | |
615 | ret = dai->driver->cops->pointer(cstream, tstamp, dai); | |
616 | ||
617 | return soc_dai_ret(dai, ret); | |
618 | } | |
619 | EXPORT_SYMBOL_GPL(snd_soc_dai_compr_pointer); | |
88b3a7df KM |
620 | |
621 | int snd_soc_dai_compr_set_metadata(struct snd_soc_dai *dai, | |
622 | struct snd_compr_stream *cstream, | |
623 | struct snd_compr_metadata *metadata) | |
624 | { | |
625 | int ret = 0; | |
626 | ||
627 | if (dai->driver->cops && | |
628 | dai->driver->cops->set_metadata) | |
629 | ret = dai->driver->cops->set_metadata(cstream, metadata, dai); | |
630 | ||
631 | return soc_dai_ret(dai, ret); | |
632 | } | |
633 | EXPORT_SYMBOL_GPL(snd_soc_dai_compr_set_metadata); | |
94d72819 KM |
634 | |
635 | int snd_soc_dai_compr_get_metadata(struct snd_soc_dai *dai, | |
636 | struct snd_compr_stream *cstream, | |
637 | struct snd_compr_metadata *metadata) | |
638 | { | |
639 | int ret = 0; | |
640 | ||
641 | if (dai->driver->cops && | |
642 | dai->driver->cops->get_metadata) | |
643 | ret = dai->driver->cops->get_metadata(cstream, metadata, dai); | |
644 | ||
645 | return soc_dai_ret(dai, ret); | |
646 | } | |
647 | EXPORT_SYMBOL_GPL(snd_soc_dai_compr_get_metadata); |