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