Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
[linux-2.6-block.git] / sound / soc / soc-component.c
CommitLineData
4ff1fef1
KM
1// SPDX-License-Identifier: GPL-2.0
2//
3// soc-component.c
4//
460b42d1 5// Copyright 2009-2011 Wolfson Microelectronics PLC.
4ff1fef1 6// Copyright (C) 2019 Renesas Electronics Corp.
460b42d1
KM
7//
8// Mark Brown <broonie@opensource.wolfsonmicro.com>
4ff1fef1
KM
9// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
10//
4a81e8f3 11#include <linux/module.h>
4ff1fef1
KM
12#include <sound/soc.h>
13
e2329eeb
KM
14#define soc_component_ret(dai, ret) _soc_component_ret(dai, __func__, ret)
15static inline int _soc_component_ret(struct snd_soc_component *component,
16 const char *func, int ret)
17{
18 /* Positive/Zero values are not errors */
19 if (ret >= 0)
20 return ret;
21
22 /* Negative values might be errors */
23 switch (ret) {
24 case -EPROBE_DEFER:
25 case -ENOTSUPP:
26 break;
27 default:
28 dev_err(component->dev,
29 "ASoC: error at %s on %s: %d\n",
30 func, component->name, ret);
31 }
32
33 return ret;
34}
35
257c4dac
KM
36void snd_soc_component_set_aux(struct snd_soc_component *component,
37 struct snd_soc_aux_dev *aux)
38{
39 component->init = (aux) ? aux->init : NULL;
40}
41
42int snd_soc_component_init(struct snd_soc_component *component)
43{
44 int ret = 0;
45
46 if (component->init)
47 ret = component->init(component);
48
49 return soc_component_ret(component, ret);
50}
51
4ff1fef1
KM
52/**
53 * snd_soc_component_set_sysclk - configure COMPONENT system or master clock.
54 * @component: COMPONENT
55 * @clk_id: DAI specific clock ID
56 * @source: Source for the clock
57 * @freq: new clock frequency in Hz
58 * @dir: new clock direction - input/output.
59 *
60 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
61 */
62int snd_soc_component_set_sysclk(struct snd_soc_component *component,
63 int clk_id, int source, unsigned int freq,
64 int dir)
65{
e2329eeb
KM
66 int ret = -ENOTSUPP;
67
4ff1fef1 68 if (component->driver->set_sysclk)
e2329eeb 69 ret = component->driver->set_sysclk(component, clk_id, source,
4ff1fef1
KM
70 freq, dir);
71
e2329eeb 72 return soc_component_ret(component, ret);
4ff1fef1
KM
73}
74EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk);
75
76/*
77 * snd_soc_component_set_pll - configure component PLL.
78 * @component: COMPONENT
79 * @pll_id: DAI specific PLL ID
80 * @source: DAI specific source for the PLL
81 * @freq_in: PLL input clock frequency in Hz
82 * @freq_out: requested PLL output clock frequency in Hz
83 *
84 * Configures and enables PLL to generate output clock based on input clock.
85 */
86int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
87 int source, unsigned int freq_in,
88 unsigned int freq_out)
89{
e2329eeb
KM
90 int ret = -EINVAL;
91
4ff1fef1 92 if (component->driver->set_pll)
e2329eeb 93 ret = component->driver->set_pll(component, pll_id, source,
4ff1fef1
KM
94 freq_in, freq_out);
95
e2329eeb 96 return soc_component_ret(component, ret);
4ff1fef1
KM
97}
98EXPORT_SYMBOL_GPL(snd_soc_component_set_pll);
99
9d415fbf
KM
100void snd_soc_component_seq_notifier(struct snd_soc_component *component,
101 enum snd_soc_dapm_type type, int subseq)
102{
103 if (component->driver->seq_notifier)
104 component->driver->seq_notifier(component, type, subseq);
105}
106
8e2a990d
KM
107int snd_soc_component_stream_event(struct snd_soc_component *component,
108 int event)
109{
e2329eeb
KM
110 int ret = 0;
111
8e2a990d 112 if (component->driver->stream_event)
e2329eeb 113 ret = component->driver->stream_event(component, event);
8e2a990d 114
e2329eeb 115 return soc_component_ret(component, ret);
8e2a990d
KM
116}
117
7951b146
KM
118int snd_soc_component_set_bias_level(struct snd_soc_component *component,
119 enum snd_soc_bias_level level)
120{
e2329eeb
KM
121 int ret = 0;
122
7951b146 123 if (component->driver->set_bias_level)
e2329eeb 124 ret = component->driver->set_bias_level(component, level);
7951b146 125
e2329eeb 126 return soc_component_ret(component, ret);
7951b146
KM
127}
128
4ca8701e
KM
129static int soc_component_pin(struct snd_soc_component *component,
130 const char *pin,
131 int (*pin_func)(struct snd_soc_dapm_context *dapm,
132 const char *pin))
4ff1fef1
KM
133{
134 struct snd_soc_dapm_context *dapm =
135 snd_soc_component_get_dapm(component);
136 char *full_name;
137 int ret;
138
e2329eeb
KM
139 if (!component->name_prefix) {
140 ret = pin_func(dapm, pin);
141 goto end;
142 }
4ff1fef1
KM
143
144 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
e2329eeb
KM
145 if (!full_name) {
146 ret = -ENOMEM;
147 goto end;
148 }
4ff1fef1 149
4ca8701e 150 ret = pin_func(dapm, full_name);
4ff1fef1 151 kfree(full_name);
e2329eeb
KM
152end:
153 return soc_component_ret(component, ret);
4ff1fef1 154}
4ca8701e
KM
155
156int snd_soc_component_enable_pin(struct snd_soc_component *component,
157 const char *pin)
158{
159 return soc_component_pin(component, pin, snd_soc_dapm_enable_pin);
160}
4ff1fef1
KM
161EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin);
162
163int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component,
164 const char *pin)
165{
4ca8701e 166 return soc_component_pin(component, pin, snd_soc_dapm_enable_pin_unlocked);
4ff1fef1
KM
167}
168EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked);
169
170int snd_soc_component_disable_pin(struct snd_soc_component *component,
171 const char *pin)
172{
4ca8701e 173 return soc_component_pin(component, pin, snd_soc_dapm_disable_pin);
4ff1fef1
KM
174}
175EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin);
176
177int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
178 const char *pin)
179{
4ca8701e 180 return soc_component_pin(component, pin, snd_soc_dapm_disable_pin_unlocked);
4ff1fef1
KM
181}
182EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked);
183
184int snd_soc_component_nc_pin(struct snd_soc_component *component,
185 const char *pin)
186{
4ca8701e 187 return soc_component_pin(component, pin, snd_soc_dapm_nc_pin);
4ff1fef1
KM
188}
189EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin);
190
191int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
192 const char *pin)
193{
4ca8701e 194 return soc_component_pin(component, pin, snd_soc_dapm_nc_pin_unlocked);
4ff1fef1
KM
195}
196EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked);
197
198int snd_soc_component_get_pin_status(struct snd_soc_component *component,
199 const char *pin)
200{
4ca8701e 201 return soc_component_pin(component, pin, snd_soc_dapm_get_pin_status);
4ff1fef1
KM
202}
203EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status);
204
205int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
206 const char *pin)
207{
4ca8701e 208 return soc_component_pin(component, pin, snd_soc_dapm_force_enable_pin);
4ff1fef1
KM
209}
210EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin);
211
212int snd_soc_component_force_enable_pin_unlocked(
213 struct snd_soc_component *component,
214 const char *pin)
215{
4ca8701e 216 return soc_component_pin(component, pin, snd_soc_dapm_force_enable_pin_unlocked);
4ff1fef1
KM
217}
218EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked);
219
220/**
221 * snd_soc_component_set_jack - configure component jack.
222 * @component: COMPONENTs
223 * @jack: structure to use for the jack
224 * @data: can be used if codec driver need extra data for configuring jack
225 *
226 * Configures and enables jack detection function.
227 */
228int snd_soc_component_set_jack(struct snd_soc_component *component,
229 struct snd_soc_jack *jack, void *data)
230{
e2329eeb
KM
231 int ret = -ENOTSUPP;
232
4ff1fef1 233 if (component->driver->set_jack)
e2329eeb 234 ret = component->driver->set_jack(component, jack, data);
4ff1fef1 235
e2329eeb 236 return soc_component_ret(component, ret);
4ff1fef1
KM
237}
238EXPORT_SYMBOL_GPL(snd_soc_component_set_jack);
4a81e8f3
KM
239
240int snd_soc_component_module_get(struct snd_soc_component *component,
241 int upon_open)
242{
e2329eeb
KM
243 int ret = 0;
244
4a81e8f3
KM
245 if (component->driver->module_get_upon_open == !!upon_open &&
246 !try_module_get(component->dev->driver->owner))
e2329eeb 247 ret = -ENODEV;
4a81e8f3 248
e2329eeb 249 return soc_component_ret(component, ret);
4a81e8f3
KM
250}
251
252void snd_soc_component_module_put(struct snd_soc_component *component,
253 int upon_open)
254{
255 if (component->driver->module_get_upon_open == !!upon_open)
256 module_put(component->dev->driver->owner);
257}
ae2f4849
KM
258
259int snd_soc_component_open(struct snd_soc_component *component,
260 struct snd_pcm_substream *substream)
261{
e2329eeb
KM
262 int ret = 0;
263
e2cb4a14 264 if (component->driver->open)
e2329eeb
KM
265 ret = component->driver->open(component, substream);
266
267 return soc_component_ret(component, ret);
ae2f4849 268}
3672beb8
KM
269
270int snd_soc_component_close(struct snd_soc_component *component,
271 struct snd_pcm_substream *substream)
272{
e2329eeb
KM
273 int ret = 0;
274
e2cb4a14 275 if (component->driver->close)
e2329eeb
KM
276 ret = component->driver->close(component, substream);
277
278 return soc_component_ret(component, ret);
3672beb8 279}
6d537233 280
66c51573
KM
281void snd_soc_component_suspend(struct snd_soc_component *component)
282{
283 if (component->driver->suspend)
284 component->driver->suspend(component);
285 component->suspended = 1;
286}
9a840cba
KM
287
288void snd_soc_component_resume(struct snd_soc_component *component)
289{
290 if (component->driver->resume)
291 component->driver->resume(component);
292 component->suspended = 0;
293}
e40fadbc
KM
294
295int snd_soc_component_is_suspended(struct snd_soc_component *component)
296{
297 return component->suspended;
298}
08e837dd
KM
299
300int snd_soc_component_probe(struct snd_soc_component *component)
301{
e2329eeb
KM
302 int ret = 0;
303
08e837dd 304 if (component->driver->probe)
e2329eeb 305 ret = component->driver->probe(component);
08e837dd 306
e2329eeb 307 return soc_component_ret(component, ret);
08e837dd 308}
03b34dd7
KM
309
310void snd_soc_component_remove(struct snd_soc_component *component)
311{
312 if (component->driver->remove)
313 component->driver->remove(component);
314}
2c7b1704
KM
315
316int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
317 struct device_node *ep)
318{
e2329eeb
KM
319 int ret = -ENOTSUPP;
320
2c7b1704 321 if (component->driver->of_xlate_dai_id)
e2329eeb 322 ret = component->driver->of_xlate_dai_id(component, ep);
2c7b1704 323
e2329eeb 324 return soc_component_ret(component, ret);
2c7b1704 325}
a2a34175
KM
326
327int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
328 struct of_phandle_args *args,
329 const char **dai_name)
330{
331 if (component->driver->of_xlate_dai_name)
cc4d8ceb
JB
332 return component->driver->of_xlate_dai_name(component,
333 args, dai_name);
334 /*
335 * Don't use soc_component_ret here because we may not want to report
336 * the error just yet. If a device has more than one component, the
337 * first may not match and we don't want spam the log with this.
338 */
339 return -ENOTSUPP;
a2a34175 340}
0035e256 341
c7d75b59
KM
342void snd_soc_component_setup_regmap(struct snd_soc_component *component)
343{
344 int val_bytes = regmap_get_val_bytes(component->regmap);
345
346 /* Errors are legitimate for non-integer byte multiples */
347 if (val_bytes > 0)
348 component->val_bytes = val_bytes;
349}
350
351#ifdef CONFIG_REGMAP
352
353/**
354 * snd_soc_component_init_regmap() - Initialize regmap instance for the
355 * component
356 * @component: The component for which to initialize the regmap instance
357 * @regmap: The regmap instance that should be used by the component
358 *
359 * This function allows deferred assignment of the regmap instance that is
360 * associated with the component. Only use this if the regmap instance is not
361 * yet ready when the component is registered. The function must also be called
362 * before the first IO attempt of the component.
363 */
364void snd_soc_component_init_regmap(struct snd_soc_component *component,
365 struct regmap *regmap)
366{
367 component->regmap = regmap;
368 snd_soc_component_setup_regmap(component);
369}
370EXPORT_SYMBOL_GPL(snd_soc_component_init_regmap);
371
372/**
373 * snd_soc_component_exit_regmap() - De-initialize regmap instance for the
374 * component
375 * @component: The component for which to de-initialize the regmap instance
376 *
377 * Calls regmap_exit() on the regmap instance associated to the component and
378 * removes the regmap instance from the component.
379 *
380 * This function should only be used if snd_soc_component_init_regmap() was used
381 * to initialize the regmap instance.
382 */
383void snd_soc_component_exit_regmap(struct snd_soc_component *component)
384{
385 regmap_exit(component->regmap);
386 component->regmap = NULL;
387}
388EXPORT_SYMBOL_GPL(snd_soc_component_exit_regmap);
389
390#endif
391
e8712315
KM
392static unsigned int soc_component_read_no_lock(
393 struct snd_soc_component *component,
394 unsigned int reg)
460b42d1
KM
395{
396 int ret;
cf6e26c7 397 unsigned int val = 0;
460b42d1
KM
398
399 if (component->regmap)
cf6e26c7 400 ret = regmap_read(component->regmap, reg, &val);
460b42d1 401 else if (component->driver->read) {
460b42d1 402 ret = 0;
cf6e26c7 403 val = component->driver->read(component, reg);
460b42d1
KM
404 }
405 else
406 ret = -EIO;
407
460b42d1 408 if (ret < 0)
cf6e26c7 409 soc_component_ret(component, ret);
460b42d1
KM
410
411 return val;
412}
e8712315
KM
413
414/**
415 * snd_soc_component_read() - Read register value
416 * @component: Component to read from
417 * @reg: Register to read
418 *
419 * Return: read value
420 */
421unsigned int snd_soc_component_read(struct snd_soc_component *component,
422 unsigned int reg)
423{
424 unsigned int val;
425
426 mutex_lock(&component->io_mutex);
427 val = soc_component_read_no_lock(component, reg);
428 mutex_unlock(&component->io_mutex);
429
430 return val;
431}
cf6e26c7 432EXPORT_SYMBOL_GPL(snd_soc_component_read);
460b42d1 433
e8712315
KM
434static int soc_component_write_no_lock(
435 struct snd_soc_component *component,
436 unsigned int reg, unsigned int val)
437{
438 int ret = -EIO;
439
440 if (component->regmap)
441 ret = regmap_write(component->regmap, reg, val);
442 else if (component->driver->write)
443 ret = component->driver->write(component, reg, val);
444
445 return soc_component_ret(component, ret);
446}
447
460b42d1
KM
448/**
449 * snd_soc_component_write() - Write register value
450 * @component: Component to write to
451 * @reg: Register to write
452 * @val: Value to write to the register
453 *
454 * Return: 0 on success, a negative error code otherwise.
455 */
456int snd_soc_component_write(struct snd_soc_component *component,
457 unsigned int reg, unsigned int val)
458{
e8712315 459 int ret;
460b42d1 460
e8712315
KM
461 mutex_lock(&component->io_mutex);
462 ret = soc_component_write_no_lock(component, reg, val);
463 mutex_unlock(&component->io_mutex);
460b42d1 464
e8712315 465 return ret;
460b42d1
KM
466}
467EXPORT_SYMBOL_GPL(snd_soc_component_write);
468
469static int snd_soc_component_update_bits_legacy(
470 struct snd_soc_component *component, unsigned int reg,
471 unsigned int mask, unsigned int val, bool *change)
472{
473 unsigned int old, new;
cf6e26c7 474 int ret = 0;
460b42d1
KM
475
476 mutex_lock(&component->io_mutex);
477
e8712315 478 old = soc_component_read_no_lock(component, reg);
460b42d1
KM
479
480 new = (old & ~mask) | (val & mask);
481 *change = old != new;
482 if (*change)
e8712315 483 ret = soc_component_write_no_lock(component, reg, new);
cf6e26c7 484
460b42d1
KM
485 mutex_unlock(&component->io_mutex);
486
487 return soc_component_ret(component, ret);
488}
489
490/**
491 * snd_soc_component_update_bits() - Perform read/modify/write cycle
492 * @component: Component to update
493 * @reg: Register to update
494 * @mask: Mask that specifies which bits to update
495 * @val: New value for the bits specified by mask
496 *
497 * Return: 1 if the operation was successful and the value of the register
498 * changed, 0 if the operation was successful, but the value did not change.
499 * Returns a negative error code otherwise.
500 */
501int snd_soc_component_update_bits(struct snd_soc_component *component,
502 unsigned int reg, unsigned int mask, unsigned int val)
503{
504 bool change;
505 int ret;
506
507 if (component->regmap)
508 ret = regmap_update_bits_check(component->regmap, reg, mask,
509 val, &change);
510 else
511 ret = snd_soc_component_update_bits_legacy(component, reg,
512 mask, val, &change);
513
514 if (ret < 0)
515 return soc_component_ret(component, ret);
516 return change;
517}
518EXPORT_SYMBOL_GPL(snd_soc_component_update_bits);
519
520/**
521 * snd_soc_component_update_bits_async() - Perform asynchronous
522 * read/modify/write cycle
523 * @component: Component to update
524 * @reg: Register to update
525 * @mask: Mask that specifies which bits to update
526 * @val: New value for the bits specified by mask
527 *
528 * This function is similar to snd_soc_component_update_bits(), but the update
529 * operation is scheduled asynchronously. This means it may not be completed
530 * when the function returns. To make sure that all scheduled updates have been
531 * completed snd_soc_component_async_complete() must be called.
532 *
533 * Return: 1 if the operation was successful and the value of the register
534 * changed, 0 if the operation was successful, but the value did not change.
535 * Returns a negative error code otherwise.
536 */
537int snd_soc_component_update_bits_async(struct snd_soc_component *component,
538 unsigned int reg, unsigned int mask, unsigned int val)
539{
540 bool change;
541 int ret;
542
543 if (component->regmap)
544 ret = regmap_update_bits_check_async(component->regmap, reg,
545 mask, val, &change);
546 else
547 ret = snd_soc_component_update_bits_legacy(component, reg,
548 mask, val, &change);
549
550 if (ret < 0)
551 return soc_component_ret(component, ret);
552 return change;
553}
554EXPORT_SYMBOL_GPL(snd_soc_component_update_bits_async);
555
556/**
557 * snd_soc_component_async_complete() - Ensure asynchronous I/O has completed
558 * @component: Component for which to wait
559 *
560 * This function blocks until all asynchronous I/O which has previously been
561 * scheduled using snd_soc_component_update_bits_async() has completed.
562 */
563void snd_soc_component_async_complete(struct snd_soc_component *component)
564{
565 if (component->regmap)
566 regmap_async_complete(component->regmap);
567}
568EXPORT_SYMBOL_GPL(snd_soc_component_async_complete);
569
570/**
571 * snd_soc_component_test_bits - Test register for change
572 * @component: component
573 * @reg: Register to test
574 * @mask: Mask that specifies which bits to test
575 * @value: Value to test against
576 *
577 * Tests a register with a new value and checks if the new value is
578 * different from the old value.
579 *
580 * Return: 1 for change, otherwise 0.
581 */
582int snd_soc_component_test_bits(struct snd_soc_component *component,
583 unsigned int reg, unsigned int mask, unsigned int value)
584{
585 unsigned int old, new;
460b42d1 586
cf6e26c7 587 old = snd_soc_component_read(component, reg);
460b42d1
KM
588 new = (old & ~mask) | value;
589 return old != new;
590}
591EXPORT_SYMBOL_GPL(snd_soc_component_test_bits);
592
0035e256
KM
593int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
594{
0ceef681 595 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
0035e256 596 struct snd_soc_component *component;
613fb500 597 int i;
0035e256 598
2b544dd7 599 /* FIXME: use 1st pointer */
613fb500 600 for_each_rtd_components(rtd, i, component)
e2cb4a14
KM
601 if (component->driver->pointer)
602 return component->driver->pointer(component, substream);
0035e256
KM
603
604 return 0;
605}
96a47908
KM
606
607int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
608 unsigned int cmd, void *arg)
609{
0ceef681 610 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
96a47908 611 struct snd_soc_component *component;
613fb500 612 int i;
96a47908 613
2b544dd7 614 /* FIXME: use 1st ioctl */
613fb500 615 for_each_rtd_components(rtd, i, component)
e2cb4a14 616 if (component->driver->ioctl)
e2329eeb
KM
617 return soc_component_ret(
618 component,
619 component->driver->ioctl(component,
620 substream, cmd, arg));
96a47908
KM
621
622 return snd_pcm_lib_ioctl(substream, cmd, arg);
623}
82d81f5c 624
1e5ddb6b
TI
625int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream)
626{
0ceef681 627 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
1e5ddb6b 628 struct snd_soc_component *component;
613fb500 629 int i, ret;
1e5ddb6b 630
613fb500 631 for_each_rtd_components(rtd, i, component) {
f1861a7c 632 if (component->driver->sync_stop) {
1e5ddb6b
TI
633 ret = component->driver->sync_stop(component,
634 substream);
635 if (ret < 0)
be75db57 636 return soc_component_ret(component, ret);
1e5ddb6b
TI
637 }
638 }
639
640 return 0;
641}
642
82d81f5c
KM
643int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
644 int channel, unsigned long pos,
645 void __user *buf, unsigned long bytes)
646{
0ceef681 647 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
82d81f5c 648 struct snd_soc_component *component;
613fb500 649 int i;
82d81f5c 650
2b544dd7 651 /* FIXME. it returns 1st copy now */
613fb500 652 for_each_rtd_components(rtd, i, component)
e2cb4a14 653 if (component->driver->copy_user)
e2329eeb
KM
654 return soc_component_ret(
655 component,
656 component->driver->copy_user(
657 component, substream, channel,
658 pos, buf, bytes));
82d81f5c
KM
659
660 return -EINVAL;
661}
9c712e4f
KM
662
663struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
664 unsigned long offset)
665{
0ceef681 666 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
9c712e4f
KM
667 struct snd_soc_component *component;
668 struct page *page;
613fb500 669 int i;
9c712e4f 670
2b544dd7 671 /* FIXME. it returns 1st page now */
613fb500 672 for_each_rtd_components(rtd, i, component) {
e2cb4a14
KM
673 if (component->driver->page) {
674 page = component->driver->page(component,
675 substream, offset);
676 if (page)
677 return page;
678 }
9c712e4f
KM
679 }
680
681 return NULL;
682}
205875e1
KM
683
684int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
685 struct vm_area_struct *vma)
686{
0ceef681 687 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
205875e1 688 struct snd_soc_component *component;
613fb500 689 int i;
205875e1 690
2b544dd7 691 /* FIXME. it returns 1st mmap now */
613fb500 692 for_each_rtd_components(rtd, i, component)
e2cb4a14 693 if (component->driver->mmap)
be75db57 694 return soc_component_ret(
e2329eeb
KM
695 component,
696 component->driver->mmap(component,
697 substream, vma));
205875e1
KM
698
699 return -EINVAL;
700}
7484291e 701
b2b2afbb 702int snd_soc_pcm_component_new(struct snd_soc_pcm_runtime *rtd)
7484291e 703{
7484291e
KM
704 struct snd_soc_component *component;
705 int ret;
613fb500 706 int i;
7484291e 707
613fb500 708 for_each_rtd_components(rtd, i, component) {
c64bfc90
KM
709 if (component->driver->pcm_construct) {
710 ret = component->driver->pcm_construct(component, rtd);
711 if (ret < 0)
be75db57 712 return soc_component_ret(component, ret);
c64bfc90 713 }
7484291e
KM
714 }
715
716 return 0;
717}
79776da0 718
b2b2afbb 719void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd)
79776da0 720{
79776da0 721 struct snd_soc_component *component;
613fb500 722 int i;
79776da0 723
8e3366ca
TI
724 if (!rtd->pcm)
725 return;
726
613fb500 727 for_each_rtd_components(rtd, i, component)
c64bfc90 728 if (component->driver->pcm_destruct)
b2b2afbb 729 component->driver->pcm_destruct(component, rtd->pcm);
79776da0 730}
4f39514f
KM
731
732int snd_soc_pcm_component_prepare(struct snd_pcm_substream *substream)
733{
0ceef681 734 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
4f39514f
KM
735 struct snd_soc_component *component;
736 int i, ret;
737
738 for_each_rtd_components(rtd, i, component) {
739 if (component->driver->prepare) {
740 ret = component->driver->prepare(component, substream);
741 if (ret < 0)
742 return soc_component_ret(component, ret);
743 }
744 }
745
746 return 0;
747}
e1bafa82
KM
748
749int snd_soc_pcm_component_hw_params(struct snd_pcm_substream *substream,
750 struct snd_pcm_hw_params *params,
751 struct snd_soc_component **last)
752{
0ceef681 753 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
e1bafa82
KM
754 struct snd_soc_component *component;
755 int i, ret;
756
757 for_each_rtd_components(rtd, i, component) {
758 if (component->driver->hw_params) {
759 ret = component->driver->hw_params(component,
760 substream, params);
761 if (ret < 0) {
762 *last = component;
763 return soc_component_ret(component, ret);
764 }
765 }
766 }
767
768 *last = NULL;
769 return 0;
770}
04751119
KM
771
772void snd_soc_pcm_component_hw_free(struct snd_pcm_substream *substream,
773 struct snd_soc_component *last)
774{
0ceef681 775 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
04751119
KM
776 struct snd_soc_component *component;
777 int i, ret;
778
779 for_each_rtd_components(rtd, i, component) {
780 if (component == last)
781 break;
782
783 if (component->driver->hw_free) {
784 ret = component->driver->hw_free(component, substream);
785 if (ret < 0)
786 soc_component_ret(component, ret);
787 }
788 }
789}
32fd1204
KM
790
791int snd_soc_pcm_component_trigger(struct snd_pcm_substream *substream,
792 int cmd)
793{
0ceef681 794 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
32fd1204
KM
795 struct snd_soc_component *component;
796 int i, ret;
797
798 for_each_rtd_components(rtd, i, component) {
799 if (component->driver->trigger) {
800 ret = component->driver->trigger(component, substream, cmd);
801 if (ret < 0)
802 return soc_component_ret(component, ret);
803 }
804 }
805
806 return 0;
807}