xref: /openbmc/linux/sound/soc/soc-component.c (revision 15d5761a)
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  */
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  */
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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  */
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 
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 
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 
314 int snd_soc_component_open(struct snd_soc_component *component,
315 			   struct snd_pcm_substream *substream)
316 {
317 	if (component->driver->open)
318 		return component->driver->open(component, substream);
319 	return 0;
320 }
321 
322 int snd_soc_component_close(struct snd_soc_component *component,
323 			    struct snd_pcm_substream *substream)
324 {
325 	if (component->driver->close)
326 		return component->driver->close(component, substream);
327 	return 0;
328 }
329 
330 int snd_soc_component_prepare(struct snd_soc_component *component,
331 			      struct snd_pcm_substream *substream)
332 {
333 	if (component->driver->prepare)
334 		return component->driver->prepare(component, substream);
335 	return 0;
336 }
337 
338 int snd_soc_component_hw_params(struct snd_soc_component *component,
339 				struct snd_pcm_substream *substream,
340 				struct snd_pcm_hw_params *params)
341 {
342 	if (component->driver->hw_params)
343 		return component->driver->hw_params(component,
344 						    substream, params);
345 	return 0;
346 }
347 
348 int snd_soc_component_hw_free(struct snd_soc_component *component,
349 			       struct snd_pcm_substream *substream)
350 {
351 	if (component->driver->hw_free)
352 		return component->driver->hw_free(component, substream);
353 	return 0;
354 }
355 
356 int snd_soc_component_trigger(struct snd_soc_component *component,
357 			      struct snd_pcm_substream *substream,
358 			      int cmd)
359 {
360 	if (component->driver->trigger)
361 		return component->driver->trigger(component, substream, cmd);
362 	return 0;
363 }
364 
365 void snd_soc_component_suspend(struct snd_soc_component *component)
366 {
367 	if (component->driver->suspend)
368 		component->driver->suspend(component);
369 	component->suspended = 1;
370 }
371 
372 void snd_soc_component_resume(struct snd_soc_component *component)
373 {
374 	if (component->driver->resume)
375 		component->driver->resume(component);
376 	component->suspended = 0;
377 }
378 
379 int snd_soc_component_is_suspended(struct snd_soc_component *component)
380 {
381 	return component->suspended;
382 }
383 
384 int snd_soc_component_probe(struct snd_soc_component *component)
385 {
386 	if (component->driver->probe)
387 		return component->driver->probe(component);
388 
389 	return 0;
390 }
391 
392 void snd_soc_component_remove(struct snd_soc_component *component)
393 {
394 	if (component->driver->remove)
395 		component->driver->remove(component);
396 }
397 
398 int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
399 				      struct device_node *ep)
400 {
401 	if (component->driver->of_xlate_dai_id)
402 		return component->driver->of_xlate_dai_id(component, ep);
403 
404 	return -ENOTSUPP;
405 }
406 
407 int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
408 					struct of_phandle_args *args,
409 					const char **dai_name)
410 {
411 	if (component->driver->of_xlate_dai_name)
412 		return component->driver->of_xlate_dai_name(component,
413 						     args, dai_name);
414 	return -ENOTSUPP;
415 }
416 
417 int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
418 {
419 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
420 	struct snd_soc_component *component;
421 	int i;
422 
423 	/* FIXME: use 1st pointer */
424 	for_each_rtd_components(rtd, i, component)
425 		if (component->driver->pointer)
426 			return component->driver->pointer(component, substream);
427 
428 	return 0;
429 }
430 
431 int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
432 				unsigned int cmd, void *arg)
433 {
434 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
435 	struct snd_soc_component *component;
436 	int i;
437 
438 	/* FIXME: use 1st ioctl */
439 	for_each_rtd_components(rtd, i, component)
440 		if (component->driver->ioctl)
441 			return component->driver->ioctl(component, substream,
442 							cmd, arg);
443 
444 	return snd_pcm_lib_ioctl(substream, cmd, arg);
445 }
446 
447 int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream)
448 {
449 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
450 	struct snd_soc_component *component;
451 	int i, ret;
452 
453 	for_each_rtd_components(rtd, i, component) {
454 		if (component->driver->sync_stop) {
455 			ret = component->driver->sync_stop(component,
456 							   substream);
457 			if (ret < 0)
458 				return ret;
459 		}
460 	}
461 
462 	return 0;
463 }
464 
465 int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
466 				    int channel, unsigned long pos,
467 				    void __user *buf, unsigned long bytes)
468 {
469 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
470 	struct snd_soc_component *component;
471 	int i;
472 
473 	/* FIXME. it returns 1st copy now */
474 	for_each_rtd_components(rtd, i, component)
475 		if (component->driver->copy_user)
476 			return component->driver->copy_user(
477 				component, substream, channel, pos, buf, bytes);
478 
479 	return -EINVAL;
480 }
481 
482 struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
483 					unsigned long offset)
484 {
485 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
486 	struct snd_soc_component *component;
487 	struct page *page;
488 	int i;
489 
490 	/* FIXME. it returns 1st page now */
491 	for_each_rtd_components(rtd, i, component) {
492 		if (component->driver->page) {
493 			page = component->driver->page(component,
494 						       substream, offset);
495 			if (page)
496 				return page;
497 		}
498 	}
499 
500 	return NULL;
501 }
502 
503 int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
504 			       struct vm_area_struct *vma)
505 {
506 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
507 	struct snd_soc_component *component;
508 	int i;
509 
510 	/* FIXME. it returns 1st mmap now */
511 	for_each_rtd_components(rtd, i, component)
512 		if (component->driver->mmap)
513 			return component->driver->mmap(component,
514 						       substream, vma);
515 
516 	return -EINVAL;
517 }
518 
519 int snd_soc_pcm_component_new(struct snd_soc_pcm_runtime *rtd)
520 {
521 	struct snd_soc_component *component;
522 	int ret;
523 	int i;
524 
525 	for_each_rtd_components(rtd, i, component) {
526 		if (component->driver->pcm_construct) {
527 			ret = component->driver->pcm_construct(component, rtd);
528 			if (ret < 0)
529 				return ret;
530 		}
531 	}
532 
533 	return 0;
534 }
535 
536 void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd)
537 {
538 	struct snd_soc_component *component;
539 	int i;
540 
541 	if (!rtd->pcm)
542 		return;
543 
544 	for_each_rtd_components(rtd, i, component)
545 		if (component->driver->pcm_destruct)
546 			component->driver->pcm_destruct(component, rtd->pcm);
547 }
548