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