ASoC: component: Add sync_stop PCM ops
[sfrench/cifs-2.6.git] / sound / soc / soc-component.c
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         struct snd_soc_rtdcom_list *rtdcom;
422
423         /* FIXME: use 1st pointer */
424         for_each_rtd_components(rtd, rtdcom, 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         struct snd_soc_rtdcom_list *rtdcom;
437
438         /* FIXME: use 1st ioctl */
439         for_each_rtd_components(rtd, rtdcom, 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         struct snd_soc_rtdcom_list *rtdcom;
452         int ret;
453
454         for_each_rtd_components(rtd, rtdcom, component) {
455                 if (component->driver->ioctl) {
456                         ret = component->driver->sync_stop(component,
457                                                            substream);
458                         if (ret < 0)
459                                 return ret;
460                 }
461         }
462
463         return 0;
464 }
465
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         /* FIXME. it returns 1st copy now */
475         for_each_rtd_components(rtd, rtdcom, component)
476                 if (component->driver->copy_user)
477                         return component->driver->copy_user(
478                                 component, substream, channel, pos, buf, bytes);
479
480         return -EINVAL;
481 }
482
483 struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
484                                         unsigned long offset)
485 {
486         struct snd_soc_pcm_runtime *rtd = substream->private_data;
487         struct snd_soc_rtdcom_list *rtdcom;
488         struct snd_soc_component *component;
489         struct page *page;
490
491         /* FIXME. it returns 1st page now */
492         for_each_rtd_components(rtd, rtdcom, component) {
493                 if (component->driver->page) {
494                         page = component->driver->page(component,
495                                                        substream, offset);
496                         if (page)
497                                 return page;
498                 }
499         }
500
501         return NULL;
502 }
503
504 int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
505                                struct vm_area_struct *vma)
506 {
507         struct snd_soc_pcm_runtime *rtd = substream->private_data;
508         struct snd_soc_rtdcom_list *rtdcom;
509         struct snd_soc_component *component;
510
511         /* FIXME. it returns 1st mmap now */
512         for_each_rtd_components(rtd, rtdcom, component)
513                 if (component->driver->mmap)
514                         return component->driver->mmap(component,
515                                                        substream, vma);
516
517         return -EINVAL;
518 }
519
520 int snd_soc_pcm_component_new(struct snd_pcm *pcm)
521 {
522         struct snd_soc_pcm_runtime *rtd = pcm->private_data;
523         struct snd_soc_rtdcom_list *rtdcom;
524         struct snd_soc_component *component;
525         int ret;
526
527         for_each_rtd_components(rtd, rtdcom, component) {
528                 if (component->driver->pcm_construct) {
529                         ret = component->driver->pcm_construct(component, rtd);
530                         if (ret < 0)
531                                 return ret;
532                 }
533         }
534
535         return 0;
536 }
537
538 void snd_soc_pcm_component_free(struct snd_pcm *pcm)
539 {
540         struct snd_soc_pcm_runtime *rtd = pcm->private_data;
541         struct snd_soc_rtdcom_list *rtdcom;
542         struct snd_soc_component *component;
543
544         for_each_rtd_components(rtd, rtdcom, component)
545                 if (component->driver->pcm_destruct)
546                         component->driver->pcm_destruct(component, pcm);
547 }