blob: 3c96a1adaa8b0106a5060674940071a2d65a84a3 [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 Morimoto4ca87012020-06-04 17:06:11 +090080static int soc_component_pin(struct snd_soc_component *component,
81 const char *pin,
82 int (*pin_func)(struct snd_soc_dapm_context *dapm,
83 const char *pin))
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090084{
85 struct snd_soc_dapm_context *dapm =
86 snd_soc_component_get_dapm(component);
87 char *full_name;
88 int ret;
89
90 if (!component->name_prefix)
Kuninori Morimoto4ca87012020-06-04 17:06:11 +090091 return pin_func(dapm, pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090092
93 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
94 if (!full_name)
95 return -ENOMEM;
96
Kuninori Morimoto4ca87012020-06-04 17:06:11 +090097 ret = pin_func(dapm, full_name);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090098 kfree(full_name);
99
100 return ret;
101}
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900102
103int snd_soc_component_enable_pin(struct snd_soc_component *component,
104 const char *pin)
105{
106 return soc_component_pin(component, pin, snd_soc_dapm_enable_pin);
107}
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900108EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin);
109
110int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component,
111 const char *pin)
112{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900113 return soc_component_pin(component, pin, snd_soc_dapm_enable_pin_unlocked);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900114}
115EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked);
116
117int snd_soc_component_disable_pin(struct snd_soc_component *component,
118 const char *pin)
119{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900120 return soc_component_pin(component, pin, snd_soc_dapm_disable_pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900121}
122EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin);
123
124int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
125 const char *pin)
126{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900127 return soc_component_pin(component, pin, snd_soc_dapm_disable_pin_unlocked);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900128}
129EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked);
130
131int snd_soc_component_nc_pin(struct snd_soc_component *component,
132 const char *pin)
133{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900134 return soc_component_pin(component, pin, snd_soc_dapm_nc_pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900135}
136EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin);
137
138int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
139 const char *pin)
140{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900141 return soc_component_pin(component, pin, snd_soc_dapm_nc_pin_unlocked);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900142}
143EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked);
144
145int snd_soc_component_get_pin_status(struct snd_soc_component *component,
146 const char *pin)
147{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900148 return soc_component_pin(component, pin, snd_soc_dapm_get_pin_status);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900149}
150EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status);
151
152int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
153 const char *pin)
154{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900155 return soc_component_pin(component, pin, snd_soc_dapm_force_enable_pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900156}
157EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin);
158
159int snd_soc_component_force_enable_pin_unlocked(
160 struct snd_soc_component *component,
161 const char *pin)
162{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900163 return soc_component_pin(component, pin, snd_soc_dapm_force_enable_pin_unlocked);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900164}
165EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked);
166
167/**
168 * snd_soc_component_set_jack - configure component jack.
169 * @component: COMPONENTs
170 * @jack: structure to use for the jack
171 * @data: can be used if codec driver need extra data for configuring jack
172 *
173 * Configures and enables jack detection function.
174 */
175int snd_soc_component_set_jack(struct snd_soc_component *component,
176 struct snd_soc_jack *jack, void *data)
177{
178 if (component->driver->set_jack)
179 return component->driver->set_jack(component, jack, data);
180
181 return -ENOTSUPP;
182}
183EXPORT_SYMBOL_GPL(snd_soc_component_set_jack);
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900184
185int snd_soc_component_module_get(struct snd_soc_component *component,
186 int upon_open)
187{
188 if (component->driver->module_get_upon_open == !!upon_open &&
189 !try_module_get(component->dev->driver->owner))
190 return -ENODEV;
191
192 return 0;
193}
194
195void snd_soc_component_module_put(struct snd_soc_component *component,
196 int upon_open)
197{
198 if (component->driver->module_get_upon_open == !!upon_open)
199 module_put(component->dev->driver->owner);
200}
Kuninori Morimotoae2f4842019-07-26 13:50:01 +0900201
202int snd_soc_component_open(struct snd_soc_component *component,
203 struct snd_pcm_substream *substream)
204{
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900205 if (component->driver->open)
206 return component->driver->open(component, substream);
Kuninori Morimotoae2f4842019-07-26 13:50:01 +0900207 return 0;
208}
Kuninori Morimoto3672beb2019-07-26 13:50:07 +0900209
210int snd_soc_component_close(struct snd_soc_component *component,
211 struct snd_pcm_substream *substream)
212{
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900213 if (component->driver->close)
214 return component->driver->close(component, substream);
Kuninori Morimoto3672beb2019-07-26 13:50:07 +0900215 return 0;
216}
Kuninori Morimoto6d537232019-07-26 13:50:13 +0900217
218int snd_soc_component_prepare(struct snd_soc_component *component,
219 struct snd_pcm_substream *substream)
220{
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900221 if (component->driver->prepare)
222 return component->driver->prepare(component, substream);
Kuninori Morimoto6d537232019-07-26 13:50:13 +0900223 return 0;
224}
Kuninori Morimoto245c5392019-07-26 13:50:19 +0900225
226int snd_soc_component_hw_params(struct snd_soc_component *component,
227 struct snd_pcm_substream *substream,
228 struct snd_pcm_hw_params *params)
229{
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900230 if (component->driver->hw_params)
231 return component->driver->hw_params(component,
232 substream, params);
Kuninori Morimoto245c5392019-07-26 13:50:19 +0900233 return 0;
234}
Kuninori Morimotoeae71362019-07-26 13:50:24 +0900235
236int snd_soc_component_hw_free(struct snd_soc_component *component,
237 struct snd_pcm_substream *substream)
238{
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900239 if (component->driver->hw_free)
240 return component->driver->hw_free(component, substream);
Kuninori Morimotoeae71362019-07-26 13:50:24 +0900241 return 0;
242}
Kuninori Morimoto5693d502019-07-26 13:50:29 +0900243
244int snd_soc_component_trigger(struct snd_soc_component *component,
245 struct snd_pcm_substream *substream,
246 int cmd)
247{
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900248 if (component->driver->trigger)
249 return component->driver->trigger(component, substream, cmd);
Kuninori Morimoto5693d502019-07-26 13:50:29 +0900250 return 0;
251}
Kuninori Morimoto66c51572019-07-26 13:50:34 +0900252
253void snd_soc_component_suspend(struct snd_soc_component *component)
254{
255 if (component->driver->suspend)
256 component->driver->suspend(component);
257 component->suspended = 1;
258}
Kuninori Morimoto9a840cb2019-07-26 13:51:08 +0900259
260void snd_soc_component_resume(struct snd_soc_component *component)
261{
262 if (component->driver->resume)
263 component->driver->resume(component);
264 component->suspended = 0;
265}
Kuninori Morimotoe40fadb2019-07-26 13:51:13 +0900266
267int snd_soc_component_is_suspended(struct snd_soc_component *component)
268{
269 return component->suspended;
270}
Kuninori Morimoto08e837d2019-07-26 13:51:17 +0900271
272int snd_soc_component_probe(struct snd_soc_component *component)
273{
274 if (component->driver->probe)
275 return component->driver->probe(component);
276
277 return 0;
278}
Kuninori Morimoto03b34dd2019-07-26 13:51:22 +0900279
280void snd_soc_component_remove(struct snd_soc_component *component)
281{
282 if (component->driver->remove)
283 component->driver->remove(component);
284}
Kuninori Morimoto2c7b1702019-07-26 13:51:26 +0900285
286int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
287 struct device_node *ep)
288{
289 if (component->driver->of_xlate_dai_id)
290 return component->driver->of_xlate_dai_id(component, ep);
291
292 return -ENOTSUPP;
293}
Kuninori Morimotoa2a34172019-07-26 13:51:31 +0900294
295int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
296 struct of_phandle_args *args,
297 const char **dai_name)
298{
299 if (component->driver->of_xlate_dai_name)
300 return component->driver->of_xlate_dai_name(component,
301 args, dai_name);
302 return -ENOTSUPP;
303}
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900304
Kuninori Morimotoc7d75b52020-06-04 17:06:22 +0900305void snd_soc_component_setup_regmap(struct snd_soc_component *component)
306{
307 int val_bytes = regmap_get_val_bytes(component->regmap);
308
309 /* Errors are legitimate for non-integer byte multiples */
310 if (val_bytes > 0)
311 component->val_bytes = val_bytes;
312}
313
314#ifdef CONFIG_REGMAP
315
316/**
317 * snd_soc_component_init_regmap() - Initialize regmap instance for the
318 * component
319 * @component: The component for which to initialize the regmap instance
320 * @regmap: The regmap instance that should be used by the component
321 *
322 * This function allows deferred assignment of the regmap instance that is
323 * associated with the component. Only use this if the regmap instance is not
324 * yet ready when the component is registered. The function must also be called
325 * before the first IO attempt of the component.
326 */
327void snd_soc_component_init_regmap(struct snd_soc_component *component,
328 struct regmap *regmap)
329{
330 component->regmap = regmap;
331 snd_soc_component_setup_regmap(component);
332}
333EXPORT_SYMBOL_GPL(snd_soc_component_init_regmap);
334
335/**
336 * snd_soc_component_exit_regmap() - De-initialize regmap instance for the
337 * component
338 * @component: The component for which to de-initialize the regmap instance
339 *
340 * Calls regmap_exit() on the regmap instance associated to the component and
341 * removes the regmap instance from the component.
342 *
343 * This function should only be used if snd_soc_component_init_regmap() was used
344 * to initialize the regmap instance.
345 */
346void snd_soc_component_exit_regmap(struct snd_soc_component *component)
347{
348 regmap_exit(component->regmap);
349 component->regmap = NULL;
350}
351EXPORT_SYMBOL_GPL(snd_soc_component_exit_regmap);
352
353#endif
354
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900355int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
356{
357 struct snd_soc_pcm_runtime *rtd = substream->private_data;
358 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900359 int i;
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900360
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900361 /* FIXME: use 1st pointer */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900362 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900363 if (component->driver->pointer)
364 return component->driver->pointer(component, substream);
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900365
366 return 0;
367}
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900368
369int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
370 unsigned int cmd, void *arg)
371{
372 struct snd_soc_pcm_runtime *rtd = substream->private_data;
373 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900374 int i;
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900375
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900376 /* FIXME: use 1st ioctl */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900377 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900378 if (component->driver->ioctl)
379 return component->driver->ioctl(component, substream,
380 cmd, arg);
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900381
382 return snd_pcm_lib_ioctl(substream, cmd, arg);
383}
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900384
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100385int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream)
386{
387 struct snd_soc_pcm_runtime *rtd = substream->private_data;
388 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900389 int i, ret;
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100390
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900391 for_each_rtd_components(rtd, i, component) {
Kuninori Morimotof1861a72020-02-28 10:48:35 +0900392 if (component->driver->sync_stop) {
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100393 ret = component->driver->sync_stop(component,
394 substream);
395 if (ret < 0)
396 return ret;
397 }
398 }
399
400 return 0;
401}
402
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900403int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
404 int channel, unsigned long pos,
405 void __user *buf, unsigned long bytes)
406{
407 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900408 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900409 int i;
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900410
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900411 /* FIXME. it returns 1st copy now */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900412 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900413 if (component->driver->copy_user)
414 return component->driver->copy_user(
415 component, substream, channel, pos, buf, bytes);
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900416
417 return -EINVAL;
418}
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900419
420struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
421 unsigned long offset)
422{
423 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900424 struct snd_soc_component *component;
425 struct page *page;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900426 int i;
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900427
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900428 /* FIXME. it returns 1st page now */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900429 for_each_rtd_components(rtd, i, component) {
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900430 if (component->driver->page) {
431 page = component->driver->page(component,
432 substream, offset);
433 if (page)
434 return page;
435 }
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900436 }
437
438 return NULL;
439}
Kuninori Morimoto205875e2019-07-26 13:52:04 +0900440
441int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
442 struct vm_area_struct *vma)
443{
444 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Kuninori Morimoto205875e2019-07-26 13:52:04 +0900445 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900446 int i;
Kuninori Morimoto205875e2019-07-26 13:52:04 +0900447
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900448 /* FIXME. it returns 1st mmap now */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900449 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900450 if (component->driver->mmap)
451 return component->driver->mmap(component,
452 substream, vma);
Kuninori Morimoto205875e2019-07-26 13:52:04 +0900453
454 return -EINVAL;
455}
Kuninori Morimoto74842912019-07-26 13:52:08 +0900456
Kuninori Morimotob2b2afb2019-11-18 10:50:32 +0900457int snd_soc_pcm_component_new(struct snd_soc_pcm_runtime *rtd)
Kuninori Morimoto74842912019-07-26 13:52:08 +0900458{
Kuninori Morimoto74842912019-07-26 13:52:08 +0900459 struct snd_soc_component *component;
460 int ret;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900461 int i;
Kuninori Morimoto74842912019-07-26 13:52:08 +0900462
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900463 for_each_rtd_components(rtd, i, component) {
Kuninori Morimotoc64bfc92019-10-02 14:30:59 +0900464 if (component->driver->pcm_construct) {
465 ret = component->driver->pcm_construct(component, rtd);
466 if (ret < 0)
467 return ret;
468 }
Kuninori Morimoto74842912019-07-26 13:52:08 +0900469 }
470
471 return 0;
472}
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900473
Kuninori Morimotob2b2afb2019-11-18 10:50:32 +0900474void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd)
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900475{
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900476 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900477 int i;
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900478
Takashi Iwai8e3366c2020-01-07 08:09:56 +0100479 if (!rtd->pcm)
480 return;
481
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900482 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoc64bfc92019-10-02 14:30:59 +0900483 if (component->driver->pcm_destruct)
Kuninori Morimotob2b2afb2019-11-18 10:50:32 +0900484 component->driver->pcm_destruct(component, rtd->pcm);
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900485}