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