1 // 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 //
8 #include <linux/module.h>
9 #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 */
snd_soc_component_set_sysclk(struct snd_soc_component * component,int clk_id,int source,unsigned int freq,int dir)21 int 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 }
31 EXPORT_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 */
snd_soc_component_set_pll(struct snd_soc_component * component,int pll_id,int source,unsigned int freq_in,unsigned int freq_out)43 int 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 }
53 EXPORT_SYMBOL_GPL(snd_soc_component_set_pll);
54
snd_soc_component_seq_notifier(struct snd_soc_component * component,enum snd_soc_dapm_type type,int subseq)55 void 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
snd_soc_component_stream_event(struct snd_soc_component * component,int event)62 int 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
snd_soc_component_set_bias_level(struct snd_soc_component * component,enum snd_soc_bias_level level)71 int 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
snd_soc_component_enable_pin(struct snd_soc_component * component,const char * pin)80 int 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 }
100 EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin);
101
snd_soc_component_enable_pin_unlocked(struct snd_soc_component * component,const char * pin)102 int 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 }
122 EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked);
123
snd_soc_component_disable_pin(struct snd_soc_component * component,const char * pin)124 int 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 }
144 EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin);
145
snd_soc_component_disable_pin_unlocked(struct snd_soc_component * component,const char * pin)146 int 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 }
166 EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked);
167
snd_soc_component_nc_pin(struct snd_soc_component * component,const char * pin)168 int 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 }
188 EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin);
189
snd_soc_component_nc_pin_unlocked(struct snd_soc_component * component,const char * pin)190 int 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 }
210 EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked);
211
snd_soc_component_get_pin_status(struct snd_soc_component * component,const char * pin)212 int 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 }
232 EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status);
233
snd_soc_component_force_enable_pin(struct snd_soc_component * component,const char * pin)234 int 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 }
254 EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin);
255
snd_soc_component_force_enable_pin_unlocked(struct snd_soc_component * component,const char * pin)256 int 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 }
277 EXPORT_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 */
snd_soc_component_set_jack(struct snd_soc_component * component,struct snd_soc_jack * jack,void * data)287 int 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 }
295 EXPORT_SYMBOL_GPL(snd_soc_component_set_jack);
296
snd_soc_component_module_get(struct snd_soc_component * component,int upon_open)297 int 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
snd_soc_component_module_put(struct snd_soc_component * component,int upon_open)307 void 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 }
313
snd_soc_component_open(struct snd_soc_component * component,struct snd_pcm_substream * substream)314 int snd_soc_component_open(struct snd_soc_component *component,
315 struct snd_pcm_substream *substream)
316 {
317 if (component->driver->ops &&
318 component->driver->ops->open)
319 return component->driver->ops->open(substream);
320
321 return 0;
322 }
323
snd_soc_component_close(struct snd_soc_component * component,struct snd_pcm_substream * substream)324 int snd_soc_component_close(struct snd_soc_component *component,
325 struct snd_pcm_substream *substream)
326 {
327 if (component->driver->ops &&
328 component->driver->ops->close)
329 return component->driver->ops->close(substream);
330
331 return 0;
332 }
333
snd_soc_component_prepare(struct snd_soc_component * component,struct snd_pcm_substream * substream)334 int snd_soc_component_prepare(struct snd_soc_component *component,
335 struct snd_pcm_substream *substream)
336 {
337 if (component->driver->ops &&
338 component->driver->ops->prepare)
339 return component->driver->ops->prepare(substream);
340
341 return 0;
342 }
343
snd_soc_component_hw_params(struct snd_soc_component * component,struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params)344 int snd_soc_component_hw_params(struct snd_soc_component *component,
345 struct snd_pcm_substream *substream,
346 struct snd_pcm_hw_params *params)
347 {
348 if (component->driver->ops &&
349 component->driver->ops->hw_params)
350 return component->driver->ops->hw_params(substream, params);
351
352 return 0;
353 }
354
snd_soc_component_hw_free(struct snd_soc_component * component,struct snd_pcm_substream * substream)355 int snd_soc_component_hw_free(struct snd_soc_component *component,
356 struct snd_pcm_substream *substream)
357 {
358 if (component->driver->ops &&
359 component->driver->ops->hw_free)
360 return component->driver->ops->hw_free(substream);
361
362 return 0;
363 }
364
snd_soc_component_trigger(struct snd_soc_component * component,struct snd_pcm_substream * substream,int cmd)365 int snd_soc_component_trigger(struct snd_soc_component *component,
366 struct snd_pcm_substream *substream,
367 int cmd)
368 {
369 if (component->driver->ops &&
370 component->driver->ops->trigger)
371 return component->driver->ops->trigger(substream, cmd);
372
373 return 0;
374 }
375
snd_soc_component_suspend(struct snd_soc_component * component)376 void snd_soc_component_suspend(struct snd_soc_component *component)
377 {
378 if (component->driver->suspend)
379 component->driver->suspend(component);
380 component->suspended = 1;
381 }
382
snd_soc_component_resume(struct snd_soc_component * component)383 void snd_soc_component_resume(struct snd_soc_component *component)
384 {
385 if (component->driver->resume)
386 component->driver->resume(component);
387 component->suspended = 0;
388 }
389
snd_soc_component_is_suspended(struct snd_soc_component * component)390 int snd_soc_component_is_suspended(struct snd_soc_component *component)
391 {
392 return component->suspended;
393 }
394
snd_soc_component_probe(struct snd_soc_component * component)395 int snd_soc_component_probe(struct snd_soc_component *component)
396 {
397 if (component->driver->probe)
398 return component->driver->probe(component);
399
400 return 0;
401 }
402
snd_soc_component_remove(struct snd_soc_component * component)403 void snd_soc_component_remove(struct snd_soc_component *component)
404 {
405 if (component->driver->remove)
406 component->driver->remove(component);
407 }
408
snd_soc_component_of_xlate_dai_id(struct snd_soc_component * component,struct device_node * ep)409 int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
410 struct device_node *ep)
411 {
412 if (component->driver->of_xlate_dai_id)
413 return component->driver->of_xlate_dai_id(component, ep);
414
415 return -ENOTSUPP;
416 }
417
snd_soc_component_of_xlate_dai_name(struct snd_soc_component * component,struct of_phandle_args * args,const char ** dai_name)418 int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
419 struct of_phandle_args *args,
420 const char **dai_name)
421 {
422 if (component->driver->of_xlate_dai_name)
423 return component->driver->of_xlate_dai_name(component,
424 args, dai_name);
425 return -ENOTSUPP;
426 }
427
snd_soc_pcm_component_pointer(struct snd_pcm_substream * substream)428 int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
429 {
430 struct snd_soc_pcm_runtime *rtd = substream->private_data;
431 struct snd_soc_component *component;
432 struct snd_soc_rtdcom_list *rtdcom;
433
434 for_each_rtdcom(rtd, rtdcom) {
435 component = rtdcom->component;
436
437 /* FIXME: use 1st pointer */
438 if (component->driver->ops &&
439 component->driver->ops->pointer)
440 return component->driver->ops->pointer(substream);
441 }
442
443 return 0;
444 }
445
snd_soc_pcm_component_ioctl(struct snd_pcm_substream * substream,unsigned int cmd,void * arg)446 int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
447 unsigned int cmd, void *arg)
448 {
449 struct snd_soc_pcm_runtime *rtd = substream->private_data;
450 struct snd_soc_component *component;
451 struct snd_soc_rtdcom_list *rtdcom;
452
453 for_each_rtdcom(rtd, rtdcom) {
454 component = rtdcom->component;
455
456 /* FIXME: use 1st ioctl */
457 if (component->driver->ops &&
458 component->driver->ops->ioctl)
459 return component->driver->ops->ioctl(substream,
460 cmd, arg);
461 }
462
463 return snd_pcm_lib_ioctl(substream, cmd, arg);
464 }
465
snd_soc_pcm_component_copy_user(struct snd_pcm_substream * substream,int channel,unsigned long pos,void __user * buf,unsigned long bytes)466 int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
467 int channel, unsigned long pos,
468 void __user *buf, unsigned long bytes)
469 {
470 struct snd_soc_pcm_runtime *rtd = substream->private_data;
471 struct snd_soc_rtdcom_list *rtdcom;
472 struct snd_soc_component *component;
473
474 for_each_rtdcom(rtd, rtdcom) {
475 component = rtdcom->component;
476
477 /* FIXME. it returns 1st copy now */
478 if (component->driver->ops &&
479 component->driver->ops->copy_user)
480 return component->driver->ops->copy_user(
481 substream, channel, pos, buf, bytes);
482 }
483
484 return -EINVAL;
485 }
486
snd_soc_pcm_component_page(struct snd_pcm_substream * substream,unsigned long offset)487 struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
488 unsigned long offset)
489 {
490 struct snd_soc_pcm_runtime *rtd = substream->private_data;
491 struct snd_soc_rtdcom_list *rtdcom;
492 struct snd_soc_component *component;
493 struct page *page;
494
495 for_each_rtdcom(rtd, rtdcom) {
496 component = rtdcom->component;
497
498 /* FIXME. it returns 1st page now */
499 if (component->driver->ops &&
500 component->driver->ops->page) {
501 page = component->driver->ops->page(substream, offset);
502 if (page)
503 return page;
504 }
505 }
506
507 return NULL;
508 }
509
snd_soc_pcm_component_mmap(struct snd_pcm_substream * substream,struct vm_area_struct * vma)510 int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
511 struct vm_area_struct *vma)
512 {
513 struct snd_soc_pcm_runtime *rtd = substream->private_data;
514 struct snd_soc_rtdcom_list *rtdcom;
515 struct snd_soc_component *component;
516
517 for_each_rtdcom(rtd, rtdcom) {
518 component = rtdcom->component;
519
520 /* FIXME. it returns 1st mmap now */
521 if (component->driver->ops &&
522 component->driver->ops->mmap)
523 return component->driver->ops->mmap(substream, vma);
524 }
525
526 return -EINVAL;
527 }
528
snd_soc_pcm_component_new(struct snd_pcm * pcm)529 int snd_soc_pcm_component_new(struct snd_pcm *pcm)
530 {
531 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
532 struct snd_soc_rtdcom_list *rtdcom;
533 struct snd_soc_component *component;
534 int ret;
535
536 for_each_rtdcom(rtd, rtdcom) {
537 component = rtdcom->component;
538
539 if (component->driver->pcm_new) {
540 ret = component->driver->pcm_new(rtd);
541 if (ret < 0)
542 return ret;
543 }
544 }
545
546 return 0;
547 }
548
snd_soc_pcm_component_free(struct snd_pcm * pcm)549 void snd_soc_pcm_component_free(struct snd_pcm *pcm)
550 {
551 struct snd_soc_pcm_runtime *rtd = pcm->private_data;
552 struct snd_soc_rtdcom_list *rtdcom;
553 struct snd_soc_component *component;
554
555 for_each_rtdcom(rtd, rtdcom) {
556 component = rtdcom->component;
557
558 if (component->driver->pcm_free)
559 component->driver->pcm_free(pcm);
560 }
561 }
562