blob: 2d9cb763e63a91406f9eeffb9a025f6ac1afdbb9 [file] [log] [blame]
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +09001// SPDX-License-Identifier: GPL-2.0
2//
3// soc-component.c
4//
5// Copyright (C) 2019 Renesas Electronics Corp.
6// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
7//
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +09008#include <linux/module.h>
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +09009#include <sound/soc.h>
10
11/**
12 * snd_soc_component_set_sysclk - configure COMPONENT system or master clock.
13 * @component: COMPONENT
14 * @clk_id: DAI specific clock ID
15 * @source: Source for the clock
16 * @freq: new clock frequency in Hz
17 * @dir: new clock direction - input/output.
18 *
19 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
20 */
21int snd_soc_component_set_sysclk(struct snd_soc_component *component,
22 int clk_id, int source, unsigned int freq,
23 int dir)
24{
25 if (component->driver->set_sysclk)
26 return component->driver->set_sysclk(component, clk_id, source,
27 freq, dir);
28
29 return -ENOTSUPP;
30}
31EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk);
32
33/*
34 * snd_soc_component_set_pll - configure component PLL.
35 * @component: COMPONENT
36 * @pll_id: DAI specific PLL ID
37 * @source: DAI specific source for the PLL
38 * @freq_in: PLL input clock frequency in Hz
39 * @freq_out: requested PLL output clock frequency in Hz
40 *
41 * Configures and enables PLL to generate output clock based on input clock.
42 */
43int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
44 int source, unsigned int freq_in,
45 unsigned int freq_out)
46{
47 if (component->driver->set_pll)
48 return component->driver->set_pll(component, pll_id, source,
49 freq_in, freq_out);
50
51 return -EINVAL;
52}
53EXPORT_SYMBOL_GPL(snd_soc_component_set_pll);
54
Kuninori Morimoto9d415fb2019-07-26 13:51:35 +090055void snd_soc_component_seq_notifier(struct snd_soc_component *component,
56 enum snd_soc_dapm_type type, int subseq)
57{
58 if (component->driver->seq_notifier)
59 component->driver->seq_notifier(component, type, subseq);
60}
61
Kuninori Morimoto8e2a9902019-07-26 13:51:39 +090062int snd_soc_component_stream_event(struct snd_soc_component *component,
63 int event)
64{
65 if (component->driver->stream_event)
66 return component->driver->stream_event(component, event);
67
68 return 0;
69}
70
Kuninori Morimoto7951b1462019-07-26 13:51:43 +090071int snd_soc_component_set_bias_level(struct snd_soc_component *component,
72 enum snd_soc_bias_level level)
73{
74 if (component->driver->set_bias_level)
75 return component->driver->set_bias_level(component, level);
76
77 return 0;
78}
79
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090080int snd_soc_component_enable_pin(struct snd_soc_component *component,
81 const char *pin)
82{
83 struct snd_soc_dapm_context *dapm =
84 snd_soc_component_get_dapm(component);
85 char *full_name;
86 int ret;
87
88 if (!component->name_prefix)
89 return snd_soc_dapm_enable_pin(dapm, pin);
90
91 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
92 if (!full_name)
93 return -ENOMEM;
94
95 ret = snd_soc_dapm_enable_pin(dapm, full_name);
96 kfree(full_name);
97
98 return ret;
99}
100EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin);
101
102int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component,
103 const char *pin)
104{
105 struct snd_soc_dapm_context *dapm =
106 snd_soc_component_get_dapm(component);
107 char *full_name;
108 int ret;
109
110 if (!component->name_prefix)
111 return snd_soc_dapm_enable_pin_unlocked(dapm, pin);
112
113 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
114 if (!full_name)
115 return -ENOMEM;
116
117 ret = snd_soc_dapm_enable_pin_unlocked(dapm, full_name);
118 kfree(full_name);
119
120 return ret;
121}
122EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked);
123
124int snd_soc_component_disable_pin(struct snd_soc_component *component,
125 const char *pin)
126{
127 struct snd_soc_dapm_context *dapm =
128 snd_soc_component_get_dapm(component);
129 char *full_name;
130 int ret;
131
132 if (!component->name_prefix)
133 return snd_soc_dapm_disable_pin(dapm, pin);
134
135 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
136 if (!full_name)
137 return -ENOMEM;
138
139 ret = snd_soc_dapm_disable_pin(dapm, full_name);
140 kfree(full_name);
141
142 return ret;
143}
144EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin);
145
146int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
147 const char *pin)
148{
149 struct snd_soc_dapm_context *dapm =
150 snd_soc_component_get_dapm(component);
151 char *full_name;
152 int ret;
153
154 if (!component->name_prefix)
155 return snd_soc_dapm_disable_pin_unlocked(dapm, pin);
156
157 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
158 if (!full_name)
159 return -ENOMEM;
160
161 ret = snd_soc_dapm_disable_pin_unlocked(dapm, full_name);
162 kfree(full_name);
163
164 return ret;
165}
166EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked);
167
168int snd_soc_component_nc_pin(struct snd_soc_component *component,
169 const char *pin)
170{
171 struct snd_soc_dapm_context *dapm =
172 snd_soc_component_get_dapm(component);
173 char *full_name;
174 int ret;
175
176 if (!component->name_prefix)
177 return snd_soc_dapm_nc_pin(dapm, pin);
178
179 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
180 if (!full_name)
181 return -ENOMEM;
182
183 ret = snd_soc_dapm_nc_pin(dapm, full_name);
184 kfree(full_name);
185
186 return ret;
187}
188EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin);
189
190int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
191 const char *pin)
192{
193 struct snd_soc_dapm_context *dapm =
194 snd_soc_component_get_dapm(component);
195 char *full_name;
196 int ret;
197
198 if (!component->name_prefix)
199 return snd_soc_dapm_nc_pin_unlocked(dapm, pin);
200
201 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
202 if (!full_name)
203 return -ENOMEM;
204
205 ret = snd_soc_dapm_nc_pin_unlocked(dapm, full_name);
206 kfree(full_name);
207
208 return ret;
209}
210EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked);
211
212int snd_soc_component_get_pin_status(struct snd_soc_component *component,
213 const char *pin)
214{
215 struct snd_soc_dapm_context *dapm =
216 snd_soc_component_get_dapm(component);
217 char *full_name;
218 int ret;
219
220 if (!component->name_prefix)
221 return snd_soc_dapm_get_pin_status(dapm, pin);
222
223 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
224 if (!full_name)
225 return -ENOMEM;
226
227 ret = snd_soc_dapm_get_pin_status(dapm, full_name);
228 kfree(full_name);
229
230 return ret;
231}
232EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status);
233
234int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
235 const char *pin)
236{
237 struct snd_soc_dapm_context *dapm =
238 snd_soc_component_get_dapm(component);
239 char *full_name;
240 int ret;
241
242 if (!component->name_prefix)
243 return snd_soc_dapm_force_enable_pin(dapm, pin);
244
245 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
246 if (!full_name)
247 return -ENOMEM;
248
249 ret = snd_soc_dapm_force_enable_pin(dapm, full_name);
250 kfree(full_name);
251
252 return ret;
253}
254EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin);
255
256int snd_soc_component_force_enable_pin_unlocked(
257 struct snd_soc_component *component,
258 const char *pin)
259{
260 struct snd_soc_dapm_context *dapm =
261 snd_soc_component_get_dapm(component);
262 char *full_name;
263 int ret;
264
265 if (!component->name_prefix)
266 return snd_soc_dapm_force_enable_pin_unlocked(dapm, pin);
267
268 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
269 if (!full_name)
270 return -ENOMEM;
271
272 ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, full_name);
273 kfree(full_name);
274
275 return ret;
276}
277EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked);
278
279/**
280 * snd_soc_component_set_jack - configure component jack.
281 * @component: COMPONENTs
282 * @jack: structure to use for the jack
283 * @data: can be used if codec driver need extra data for configuring jack
284 *
285 * Configures and enables jack detection function.
286 */
287int snd_soc_component_set_jack(struct snd_soc_component *component,
288 struct snd_soc_jack *jack, void *data)
289{
290 if (component->driver->set_jack)
291 return component->driver->set_jack(component, jack, data);
292
293 return -ENOTSUPP;
294}
295EXPORT_SYMBOL_GPL(snd_soc_component_set_jack);
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900296
297int snd_soc_component_module_get(struct snd_soc_component *component,
298 int upon_open)
299{
300 if (component->driver->module_get_upon_open == !!upon_open &&
301 !try_module_get(component->dev->driver->owner))
302 return -ENODEV;
303
304 return 0;
305}
306
307void snd_soc_component_module_put(struct snd_soc_component *component,
308 int upon_open)
309{
310 if (component->driver->module_get_upon_open == !!upon_open)
311 module_put(component->dev->driver->owner);
312}
Kuninori Morimotoae2f4842019-07-26 13:50:01 +0900313
314int snd_soc_component_open(struct snd_soc_component *component,
315 struct snd_pcm_substream *substream)
316{
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900317 if (component->driver->open)
318 return component->driver->open(component, substream);
319
320 /* remove me */
Kuninori Morimotoae2f4842019-07-26 13:50:01 +0900321 if (component->driver->ops &&
322 component->driver->ops->open)
323 return component->driver->ops->open(substream);
324
325 return 0;
326}
Kuninori Morimoto3672beb2019-07-26 13:50:07 +0900327
328int snd_soc_component_close(struct snd_soc_component *component,
329 struct snd_pcm_substream *substream)
330{
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900331 if (component->driver->close)
332 return component->driver->close(component, substream);
333
334 /* remove me */
Kuninori Morimoto3672beb2019-07-26 13:50:07 +0900335 if (component->driver->ops &&
336 component->driver->ops->close)
337 return component->driver->ops->close(substream);
338
339 return 0;
340}
Kuninori Morimoto6d537232019-07-26 13:50:13 +0900341
342int snd_soc_component_prepare(struct snd_soc_component *component,
343 struct snd_pcm_substream *substream)
344{
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900345 if (component->driver->prepare)
346 return component->driver->prepare(component, substream);
347
348 /* remove me */
Kuninori Morimoto6d537232019-07-26 13:50:13 +0900349 if (component->driver->ops &&
350 component->driver->ops->prepare)
351 return component->driver->ops->prepare(substream);
352
353 return 0;
354}
Kuninori Morimoto245c5392019-07-26 13:50:19 +0900355
356int snd_soc_component_hw_params(struct snd_soc_component *component,
357 struct snd_pcm_substream *substream,
358 struct snd_pcm_hw_params *params)
359{
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900360 if (component->driver->hw_params)
361 return component->driver->hw_params(component,
362 substream, params);
363
364 /* remove me */
Kuninori Morimoto245c5392019-07-26 13:50:19 +0900365 if (component->driver->ops &&
366 component->driver->ops->hw_params)
367 return component->driver->ops->hw_params(substream, params);
368
369 return 0;
370}
Kuninori Morimotoeae71362019-07-26 13:50:24 +0900371
372int snd_soc_component_hw_free(struct snd_soc_component *component,
373 struct snd_pcm_substream *substream)
374{
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900375 if (component->driver->hw_free)
376 return component->driver->hw_free(component, substream);
377
378 /* remove me */
Kuninori Morimotoeae71362019-07-26 13:50:24 +0900379 if (component->driver->ops &&
380 component->driver->ops->hw_free)
381 return component->driver->ops->hw_free(substream);
382
383 return 0;
384}
Kuninori Morimoto5693d502019-07-26 13:50:29 +0900385
386int snd_soc_component_trigger(struct snd_soc_component *component,
387 struct snd_pcm_substream *substream,
388 int cmd)
389{
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900390 if (component->driver->trigger)
391 return component->driver->trigger(component, substream, cmd);
392
393 /* remove me */
Kuninori Morimoto5693d502019-07-26 13:50:29 +0900394 if (component->driver->ops &&
395 component->driver->ops->trigger)
396 return component->driver->ops->trigger(substream, cmd);
397
398 return 0;
399}
Kuninori Morimoto66c51572019-07-26 13:50:34 +0900400
401void snd_soc_component_suspend(struct snd_soc_component *component)
402{
403 if (component->driver->suspend)
404 component->driver->suspend(component);
405 component->suspended = 1;
406}
Kuninori Morimoto9a840cb2019-07-26 13:51:08 +0900407
408void snd_soc_component_resume(struct snd_soc_component *component)
409{
410 if (component->driver->resume)
411 component->driver->resume(component);
412 component->suspended = 0;
413}
Kuninori Morimotoe40fadb2019-07-26 13:51:13 +0900414
415int snd_soc_component_is_suspended(struct snd_soc_component *component)
416{
417 return component->suspended;
418}
Kuninori Morimoto08e837d2019-07-26 13:51:17 +0900419
420int snd_soc_component_probe(struct snd_soc_component *component)
421{
422 if (component->driver->probe)
423 return component->driver->probe(component);
424
425 return 0;
426}
Kuninori Morimoto03b34dd2019-07-26 13:51:22 +0900427
428void snd_soc_component_remove(struct snd_soc_component *component)
429{
430 if (component->driver->remove)
431 component->driver->remove(component);
432}
Kuninori Morimoto2c7b1702019-07-26 13:51:26 +0900433
434int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
435 struct device_node *ep)
436{
437 if (component->driver->of_xlate_dai_id)
438 return component->driver->of_xlate_dai_id(component, ep);
439
440 return -ENOTSUPP;
441}
Kuninori Morimotoa2a34172019-07-26 13:51:31 +0900442
443int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
444 struct of_phandle_args *args,
445 const char **dai_name)
446{
447 if (component->driver->of_xlate_dai_name)
448 return component->driver->of_xlate_dai_name(component,
449 args, dai_name);
450 return -ENOTSUPP;
451}
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900452
453int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
454{
455 struct snd_soc_pcm_runtime *rtd = substream->private_data;
456 struct snd_soc_component *component;
457 struct snd_soc_rtdcom_list *rtdcom;
458
459 for_each_rtdcom(rtd, rtdcom) {
460 component = rtdcom->component;
461
462 /* FIXME: use 1st pointer */
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900463 if (component->driver->pointer)
464 return component->driver->pointer(component, substream);
465
466 /* remove me */
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900467 if (component->driver->ops &&
468 component->driver->ops->pointer)
469 return component->driver->ops->pointer(substream);
470 }
471
472 return 0;
473}
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900474
475int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
476 unsigned int cmd, void *arg)
477{
478 struct snd_soc_pcm_runtime *rtd = substream->private_data;
479 struct snd_soc_component *component;
480 struct snd_soc_rtdcom_list *rtdcom;
481
482 for_each_rtdcom(rtd, rtdcom) {
483 component = rtdcom->component;
484
485 /* FIXME: use 1st ioctl */
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900486 if (component->driver->ioctl)
487 return component->driver->ioctl(component, substream,
488 cmd, arg);
489
490 /* remove me */
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900491 if (component->driver->ops &&
492 component->driver->ops->ioctl)
493 return component->driver->ops->ioctl(substream,
494 cmd, arg);
495 }
496
497 return snd_pcm_lib_ioctl(substream, cmd, arg);
498}
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900499
500int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
501 int channel, unsigned long pos,
502 void __user *buf, unsigned long bytes)
503{
504 struct snd_soc_pcm_runtime *rtd = substream->private_data;
505 struct snd_soc_rtdcom_list *rtdcom;
506 struct snd_soc_component *component;
507
508 for_each_rtdcom(rtd, rtdcom) {
509 component = rtdcom->component;
510
511 /* FIXME. it returns 1st copy now */
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900512 if (component->driver->copy_user)
513 return component->driver->copy_user(
514 component, substream, channel, pos, buf, bytes);
515
516 /* remove me */
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900517 if (component->driver->ops &&
518 component->driver->ops->copy_user)
519 return component->driver->ops->copy_user(
520 substream, channel, pos, buf, bytes);
521 }
522
523 return -EINVAL;
524}
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900525
526struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
527 unsigned long offset)
528{
529 struct snd_soc_pcm_runtime *rtd = substream->private_data;
530 struct snd_soc_rtdcom_list *rtdcom;
531 struct snd_soc_component *component;
532 struct page *page;
533
534 for_each_rtdcom(rtd, rtdcom) {
535 component = rtdcom->component;
536
537 /* FIXME. it returns 1st page now */
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900538 if (component->driver->page) {
539 page = component->driver->page(component,
540 substream, offset);
541 if (page)
542 return page;
543 }
544
545 /* remove me */
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900546 if (component->driver->ops &&
547 component->driver->ops->page) {
548 page = component->driver->ops->page(substream, offset);
549 if (page)
550 return page;
551 }
552 }
553
554 return NULL;
555}
Kuninori Morimoto205875e2019-07-26 13:52:04 +0900556
557int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
558 struct vm_area_struct *vma)
559{
560 struct snd_soc_pcm_runtime *rtd = substream->private_data;
561 struct snd_soc_rtdcom_list *rtdcom;
562 struct snd_soc_component *component;
563
564 for_each_rtdcom(rtd, rtdcom) {
565 component = rtdcom->component;
566
567 /* FIXME. it returns 1st mmap now */
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900568 if (component->driver->mmap)
569 return component->driver->mmap(component,
570 substream, vma);
571
572 /* remove me */
Kuninori Morimoto205875e2019-07-26 13:52:04 +0900573 if (component->driver->ops &&
574 component->driver->ops->mmap)
575 return component->driver->ops->mmap(substream, vma);
576 }
577
578 return -EINVAL;
579}
Kuninori Morimoto74842912019-07-26 13:52:08 +0900580
581int snd_soc_pcm_component_new(struct snd_pcm *pcm)
582{
583 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
584 struct snd_soc_rtdcom_list *rtdcom;
585 struct snd_soc_component *component;
586 int ret;
587
588 for_each_rtdcom(rtd, rtdcom) {
589 component = rtdcom->component;
590
591 if (component->driver->pcm_new) {
592 ret = component->driver->pcm_new(rtd);
593 if (ret < 0)
594 return ret;
595 }
596 }
597
598 return 0;
599}
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900600
601void snd_soc_pcm_component_free(struct snd_pcm *pcm)
602{
603 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
604 struct snd_soc_rtdcom_list *rtdcom;
605 struct snd_soc_component *component;
606
607 for_each_rtdcom(rtd, rtdcom) {
608 component = rtdcom->component;
609
610 if (component->driver->pcm_free)
611 component->driver->pcm_free(pcm);
612 }
613}