blob: f33dda8023ec9a1e2247cbef76d7c031ee56a2ef [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 Morimoto4ff1fef2019-07-26 13:49:48 +090071int snd_soc_component_enable_pin(struct snd_soc_component *component,
72 const char *pin)
73{
74 struct snd_soc_dapm_context *dapm =
75 snd_soc_component_get_dapm(component);
76 char *full_name;
77 int ret;
78
79 if (!component->name_prefix)
80 return snd_soc_dapm_enable_pin(dapm, pin);
81
82 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
83 if (!full_name)
84 return -ENOMEM;
85
86 ret = snd_soc_dapm_enable_pin(dapm, full_name);
87 kfree(full_name);
88
89 return ret;
90}
91EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin);
92
93int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component,
94 const char *pin)
95{
96 struct snd_soc_dapm_context *dapm =
97 snd_soc_component_get_dapm(component);
98 char *full_name;
99 int ret;
100
101 if (!component->name_prefix)
102 return snd_soc_dapm_enable_pin_unlocked(dapm, pin);
103
104 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
105 if (!full_name)
106 return -ENOMEM;
107
108 ret = snd_soc_dapm_enable_pin_unlocked(dapm, full_name);
109 kfree(full_name);
110
111 return ret;
112}
113EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked);
114
115int snd_soc_component_disable_pin(struct snd_soc_component *component,
116 const char *pin)
117{
118 struct snd_soc_dapm_context *dapm =
119 snd_soc_component_get_dapm(component);
120 char *full_name;
121 int ret;
122
123 if (!component->name_prefix)
124 return snd_soc_dapm_disable_pin(dapm, pin);
125
126 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
127 if (!full_name)
128 return -ENOMEM;
129
130 ret = snd_soc_dapm_disable_pin(dapm, full_name);
131 kfree(full_name);
132
133 return ret;
134}
135EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin);
136
137int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
138 const char *pin)
139{
140 struct snd_soc_dapm_context *dapm =
141 snd_soc_component_get_dapm(component);
142 char *full_name;
143 int ret;
144
145 if (!component->name_prefix)
146 return snd_soc_dapm_disable_pin_unlocked(dapm, pin);
147
148 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
149 if (!full_name)
150 return -ENOMEM;
151
152 ret = snd_soc_dapm_disable_pin_unlocked(dapm, full_name);
153 kfree(full_name);
154
155 return ret;
156}
157EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked);
158
159int snd_soc_component_nc_pin(struct snd_soc_component *component,
160 const char *pin)
161{
162 struct snd_soc_dapm_context *dapm =
163 snd_soc_component_get_dapm(component);
164 char *full_name;
165 int ret;
166
167 if (!component->name_prefix)
168 return snd_soc_dapm_nc_pin(dapm, pin);
169
170 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
171 if (!full_name)
172 return -ENOMEM;
173
174 ret = snd_soc_dapm_nc_pin(dapm, full_name);
175 kfree(full_name);
176
177 return ret;
178}
179EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin);
180
181int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
182 const char *pin)
183{
184 struct snd_soc_dapm_context *dapm =
185 snd_soc_component_get_dapm(component);
186 char *full_name;
187 int ret;
188
189 if (!component->name_prefix)
190 return snd_soc_dapm_nc_pin_unlocked(dapm, pin);
191
192 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
193 if (!full_name)
194 return -ENOMEM;
195
196 ret = snd_soc_dapm_nc_pin_unlocked(dapm, full_name);
197 kfree(full_name);
198
199 return ret;
200}
201EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked);
202
203int snd_soc_component_get_pin_status(struct snd_soc_component *component,
204 const char *pin)
205{
206 struct snd_soc_dapm_context *dapm =
207 snd_soc_component_get_dapm(component);
208 char *full_name;
209 int ret;
210
211 if (!component->name_prefix)
212 return snd_soc_dapm_get_pin_status(dapm, pin);
213
214 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
215 if (!full_name)
216 return -ENOMEM;
217
218 ret = snd_soc_dapm_get_pin_status(dapm, full_name);
219 kfree(full_name);
220
221 return ret;
222}
223EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status);
224
225int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
226 const char *pin)
227{
228 struct snd_soc_dapm_context *dapm =
229 snd_soc_component_get_dapm(component);
230 char *full_name;
231 int ret;
232
233 if (!component->name_prefix)
234 return snd_soc_dapm_force_enable_pin(dapm, pin);
235
236 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
237 if (!full_name)
238 return -ENOMEM;
239
240 ret = snd_soc_dapm_force_enable_pin(dapm, full_name);
241 kfree(full_name);
242
243 return ret;
244}
245EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin);
246
247int snd_soc_component_force_enable_pin_unlocked(
248 struct snd_soc_component *component,
249 const char *pin)
250{
251 struct snd_soc_dapm_context *dapm =
252 snd_soc_component_get_dapm(component);
253 char *full_name;
254 int ret;
255
256 if (!component->name_prefix)
257 return snd_soc_dapm_force_enable_pin_unlocked(dapm, pin);
258
259 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
260 if (!full_name)
261 return -ENOMEM;
262
263 ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, full_name);
264 kfree(full_name);
265
266 return ret;
267}
268EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked);
269
270/**
271 * snd_soc_component_set_jack - configure component jack.
272 * @component: COMPONENTs
273 * @jack: structure to use for the jack
274 * @data: can be used if codec driver need extra data for configuring jack
275 *
276 * Configures and enables jack detection function.
277 */
278int snd_soc_component_set_jack(struct snd_soc_component *component,
279 struct snd_soc_jack *jack, void *data)
280{
281 if (component->driver->set_jack)
282 return component->driver->set_jack(component, jack, data);
283
284 return -ENOTSUPP;
285}
286EXPORT_SYMBOL_GPL(snd_soc_component_set_jack);
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900287
288int snd_soc_component_module_get(struct snd_soc_component *component,
289 int upon_open)
290{
291 if (component->driver->module_get_upon_open == !!upon_open &&
292 !try_module_get(component->dev->driver->owner))
293 return -ENODEV;
294
295 return 0;
296}
297
298void snd_soc_component_module_put(struct snd_soc_component *component,
299 int upon_open)
300{
301 if (component->driver->module_get_upon_open == !!upon_open)
302 module_put(component->dev->driver->owner);
303}
Kuninori Morimotoae2f4842019-07-26 13:50:01 +0900304
305int snd_soc_component_open(struct snd_soc_component *component,
306 struct snd_pcm_substream *substream)
307{
308 if (component->driver->ops &&
309 component->driver->ops->open)
310 return component->driver->ops->open(substream);
311
312 return 0;
313}
Kuninori Morimoto3672beb2019-07-26 13:50:07 +0900314
315int snd_soc_component_close(struct snd_soc_component *component,
316 struct snd_pcm_substream *substream)
317{
318 if (component->driver->ops &&
319 component->driver->ops->close)
320 return component->driver->ops->close(substream);
321
322 return 0;
323}
Kuninori Morimoto6d537232019-07-26 13:50:13 +0900324
325int snd_soc_component_prepare(struct snd_soc_component *component,
326 struct snd_pcm_substream *substream)
327{
328 if (component->driver->ops &&
329 component->driver->ops->prepare)
330 return component->driver->ops->prepare(substream);
331
332 return 0;
333}
Kuninori Morimoto245c5392019-07-26 13:50:19 +0900334
335int snd_soc_component_hw_params(struct snd_soc_component *component,
336 struct snd_pcm_substream *substream,
337 struct snd_pcm_hw_params *params)
338{
339 if (component->driver->ops &&
340 component->driver->ops->hw_params)
341 return component->driver->ops->hw_params(substream, params);
342
343 return 0;
344}
Kuninori Morimotoeae71362019-07-26 13:50:24 +0900345
346int snd_soc_component_hw_free(struct snd_soc_component *component,
347 struct snd_pcm_substream *substream)
348{
349 if (component->driver->ops &&
350 component->driver->ops->hw_free)
351 return component->driver->ops->hw_free(substream);
352
353 return 0;
354}
Kuninori Morimoto5693d502019-07-26 13:50:29 +0900355
356int snd_soc_component_trigger(struct snd_soc_component *component,
357 struct snd_pcm_substream *substream,
358 int cmd)
359{
360 if (component->driver->ops &&
361 component->driver->ops->trigger)
362 return component->driver->ops->trigger(substream, cmd);
363
364 return 0;
365}
Kuninori Morimoto66c51572019-07-26 13:50:34 +0900366
367void snd_soc_component_suspend(struct snd_soc_component *component)
368{
369 if (component->driver->suspend)
370 component->driver->suspend(component);
371 component->suspended = 1;
372}
Kuninori Morimoto9a840cb2019-07-26 13:51:08 +0900373
374void snd_soc_component_resume(struct snd_soc_component *component)
375{
376 if (component->driver->resume)
377 component->driver->resume(component);
378 component->suspended = 0;
379}
Kuninori Morimotoe40fadb2019-07-26 13:51:13 +0900380
381int snd_soc_component_is_suspended(struct snd_soc_component *component)
382{
383 return component->suspended;
384}
Kuninori Morimoto08e837d2019-07-26 13:51:17 +0900385
386int snd_soc_component_probe(struct snd_soc_component *component)
387{
388 if (component->driver->probe)
389 return component->driver->probe(component);
390
391 return 0;
392}
Kuninori Morimoto03b34dd2019-07-26 13:51:22 +0900393
394void snd_soc_component_remove(struct snd_soc_component *component)
395{
396 if (component->driver->remove)
397 component->driver->remove(component);
398}
Kuninori Morimoto2c7b1702019-07-26 13:51:26 +0900399
400int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
401 struct device_node *ep)
402{
403 if (component->driver->of_xlate_dai_id)
404 return component->driver->of_xlate_dai_id(component, ep);
405
406 return -ENOTSUPP;
407}
Kuninori Morimotoa2a34172019-07-26 13:51:31 +0900408
409int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
410 struct of_phandle_args *args,
411 const char **dai_name)
412{
413 if (component->driver->of_xlate_dai_name)
414 return component->driver->of_xlate_dai_name(component,
415 args, dai_name);
416 return -ENOTSUPP;
417}