blob: 7624ff5b67d3dc7fc110ca93f45cef50c230d7e6 [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
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +090011#define soc_component_ret(dai, ret) _soc_component_ret(dai, __func__, ret)
12static inline int _soc_component_ret(struct snd_soc_component *component,
13 const char *func, int ret)
14{
15 /* Positive/Zero values are not errors */
16 if (ret >= 0)
17 return ret;
18
19 /* Negative values might be errors */
20 switch (ret) {
21 case -EPROBE_DEFER:
22 case -ENOTSUPP:
23 break;
24 default:
25 dev_err(component->dev,
26 "ASoC: error at %s on %s: %d\n",
27 func, component->name, ret);
28 }
29
30 return ret;
31}
32
Kuninori Morimoto536aba12020-06-04 17:06:32 +090033int snd_soc_component_initialize(struct snd_soc_component *component,
34 const struct snd_soc_component_driver *driver,
35 struct device *dev, const char *name)
36{
37 INIT_LIST_HEAD(&component->dai_list);
38 INIT_LIST_HEAD(&component->dobj_list);
39 INIT_LIST_HEAD(&component->card_list);
40 mutex_init(&component->io_mutex);
41
42 component->name = name;
43 component->dev = dev;
44 component->driver = driver;
45
46 return 0;
47}
48
Kuninori Morimoto257c4da2020-06-04 17:07:54 +090049void snd_soc_component_set_aux(struct snd_soc_component *component,
50 struct snd_soc_aux_dev *aux)
51{
52 component->init = (aux) ? aux->init : NULL;
53}
54
55int snd_soc_component_init(struct snd_soc_component *component)
56{
57 int ret = 0;
58
59 if (component->init)
60 ret = component->init(component);
61
62 return soc_component_ret(component, ret);
63}
64
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090065/**
66 * snd_soc_component_set_sysclk - configure COMPONENT system or master clock.
67 * @component: COMPONENT
68 * @clk_id: DAI specific clock ID
69 * @source: Source for the clock
70 * @freq: new clock frequency in Hz
71 * @dir: new clock direction - input/output.
72 *
73 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
74 */
75int snd_soc_component_set_sysclk(struct snd_soc_component *component,
76 int clk_id, int source, unsigned int freq,
77 int dir)
78{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +090079 int ret = -ENOTSUPP;
80
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090081 if (component->driver->set_sysclk)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +090082 ret = component->driver->set_sysclk(component, clk_id, source,
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090083 freq, dir);
84
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +090085 return soc_component_ret(component, ret);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090086}
87EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk);
88
89/*
90 * snd_soc_component_set_pll - configure component PLL.
91 * @component: COMPONENT
92 * @pll_id: DAI specific PLL ID
93 * @source: DAI specific source for the PLL
94 * @freq_in: PLL input clock frequency in Hz
95 * @freq_out: requested PLL output clock frequency in Hz
96 *
97 * Configures and enables PLL to generate output clock based on input clock.
98 */
99int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
100 int source, unsigned int freq_in,
101 unsigned int freq_out)
102{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900103 int ret = -EINVAL;
104
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900105 if (component->driver->set_pll)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900106 ret = component->driver->set_pll(component, pll_id, source,
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900107 freq_in, freq_out);
108
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900109 return soc_component_ret(component, ret);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900110}
111EXPORT_SYMBOL_GPL(snd_soc_component_set_pll);
112
Kuninori Morimoto9d415fb2019-07-26 13:51:35 +0900113void snd_soc_component_seq_notifier(struct snd_soc_component *component,
114 enum snd_soc_dapm_type type, int subseq)
115{
116 if (component->driver->seq_notifier)
117 component->driver->seq_notifier(component, type, subseq);
118}
119
Kuninori Morimoto8e2a9902019-07-26 13:51:39 +0900120int snd_soc_component_stream_event(struct snd_soc_component *component,
121 int event)
122{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900123 int ret = 0;
Kuninori Morimoto8e2a9902019-07-26 13:51:39 +0900124
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900125 if (component->driver->stream_event)
126 ret = component->driver->stream_event(component, event);
127
128 return soc_component_ret(component, ret);
Kuninori Morimoto8e2a9902019-07-26 13:51:39 +0900129}
130
Kuninori Morimoto7951b1462019-07-26 13:51:43 +0900131int snd_soc_component_set_bias_level(struct snd_soc_component *component,
132 enum snd_soc_bias_level level)
133{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900134 int ret = 0;
Kuninori Morimoto7951b1462019-07-26 13:51:43 +0900135
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900136 if (component->driver->set_bias_level)
137 ret = component->driver->set_bias_level(component, level);
138
139 return soc_component_ret(component, ret);
Kuninori Morimoto7951b1462019-07-26 13:51:43 +0900140}
141
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900142static int soc_component_pin(struct snd_soc_component *component,
143 const char *pin,
144 int (*pin_func)(struct snd_soc_dapm_context *dapm,
145 const char *pin))
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900146{
147 struct snd_soc_dapm_context *dapm =
148 snd_soc_component_get_dapm(component);
149 char *full_name;
150 int ret;
151
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900152 if (!component->name_prefix) {
153 ret = pin_func(dapm, pin);
154 goto end;
155 }
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900156
157 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900158 if (!full_name) {
159 ret = -ENOMEM;
160 goto end;
161 }
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900162
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900163 ret = pin_func(dapm, full_name);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900164 kfree(full_name);
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900165end:
166 return soc_component_ret(component, ret);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900167}
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900168
169int snd_soc_component_enable_pin(struct snd_soc_component *component,
170 const char *pin)
171{
172 return soc_component_pin(component, pin, snd_soc_dapm_enable_pin);
173}
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900174EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin);
175
176int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component,
177 const char *pin)
178{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900179 return soc_component_pin(component, pin, snd_soc_dapm_enable_pin_unlocked);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900180}
181EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked);
182
183int snd_soc_component_disable_pin(struct snd_soc_component *component,
184 const char *pin)
185{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900186 return soc_component_pin(component, pin, snd_soc_dapm_disable_pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900187}
188EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin);
189
190int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
191 const char *pin)
192{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900193 return soc_component_pin(component, pin, snd_soc_dapm_disable_pin_unlocked);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900194}
195EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked);
196
197int snd_soc_component_nc_pin(struct snd_soc_component *component,
198 const char *pin)
199{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900200 return soc_component_pin(component, pin, snd_soc_dapm_nc_pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900201}
202EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin);
203
204int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
205 const char *pin)
206{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900207 return soc_component_pin(component, pin, snd_soc_dapm_nc_pin_unlocked);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900208}
209EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked);
210
211int snd_soc_component_get_pin_status(struct snd_soc_component *component,
212 const char *pin)
213{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900214 return soc_component_pin(component, pin, snd_soc_dapm_get_pin_status);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900215}
216EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status);
217
218int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
219 const char *pin)
220{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900221 return soc_component_pin(component, pin, snd_soc_dapm_force_enable_pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900222}
223EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin);
224
225int snd_soc_component_force_enable_pin_unlocked(
226 struct snd_soc_component *component,
227 const char *pin)
228{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900229 return soc_component_pin(component, pin, snd_soc_dapm_force_enable_pin_unlocked);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900230}
231EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked);
232
233/**
234 * snd_soc_component_set_jack - configure component jack.
235 * @component: COMPONENTs
236 * @jack: structure to use for the jack
237 * @data: can be used if codec driver need extra data for configuring jack
238 *
239 * Configures and enables jack detection function.
240 */
241int snd_soc_component_set_jack(struct snd_soc_component *component,
242 struct snd_soc_jack *jack, void *data)
243{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900244 int ret = -ENOTSUPP;
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900245
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900246 if (component->driver->set_jack)
247 ret = component->driver->set_jack(component, jack, data);
248
249 return soc_component_ret(component, ret);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900250}
251EXPORT_SYMBOL_GPL(snd_soc_component_set_jack);
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900252
253int snd_soc_component_module_get(struct snd_soc_component *component,
254 int upon_open)
255{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900256 int ret = 0;
257
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900258 if (component->driver->module_get_upon_open == !!upon_open &&
259 !try_module_get(component->dev->driver->owner))
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900260 ret = -ENODEV;
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900261
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900262 return soc_component_ret(component, ret);
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900263}
264
265void snd_soc_component_module_put(struct snd_soc_component *component,
266 int upon_open)
267{
268 if (component->driver->module_get_upon_open == !!upon_open)
269 module_put(component->dev->driver->owner);
270}
Kuninori Morimotoae2f4842019-07-26 13:50:01 +0900271
272int snd_soc_component_open(struct snd_soc_component *component,
273 struct snd_pcm_substream *substream)
274{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900275 int ret = 0;
276
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900277 if (component->driver->open)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900278 ret = component->driver->open(component, substream);
279
280 return soc_component_ret(component, ret);
Kuninori Morimotoae2f4842019-07-26 13:50:01 +0900281}
Kuninori Morimoto3672beb2019-07-26 13:50:07 +0900282
283int snd_soc_component_close(struct snd_soc_component *component,
284 struct snd_pcm_substream *substream)
285{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900286 int ret = 0;
287
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900288 if (component->driver->close)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900289 ret = component->driver->close(component, substream);
290
291 return soc_component_ret(component, ret);
Kuninori Morimoto3672beb2019-07-26 13:50:07 +0900292}
Kuninori Morimoto6d537232019-07-26 13:50:13 +0900293
Kuninori Morimoto66c51572019-07-26 13:50:34 +0900294void snd_soc_component_suspend(struct snd_soc_component *component)
295{
296 if (component->driver->suspend)
297 component->driver->suspend(component);
298 component->suspended = 1;
299}
Kuninori Morimoto9a840cb2019-07-26 13:51:08 +0900300
301void snd_soc_component_resume(struct snd_soc_component *component)
302{
303 if (component->driver->resume)
304 component->driver->resume(component);
305 component->suspended = 0;
306}
Kuninori Morimotoe40fadb2019-07-26 13:51:13 +0900307
308int snd_soc_component_is_suspended(struct snd_soc_component *component)
309{
310 return component->suspended;
311}
Kuninori Morimoto08e837d2019-07-26 13:51:17 +0900312
313int snd_soc_component_probe(struct snd_soc_component *component)
314{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900315 int ret = 0;
Kuninori Morimoto08e837d2019-07-26 13:51:17 +0900316
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900317 if (component->driver->probe)
318 ret = component->driver->probe(component);
319
320 return soc_component_ret(component, ret);
Kuninori Morimoto08e837d2019-07-26 13:51:17 +0900321}
Kuninori Morimoto03b34dd2019-07-26 13:51:22 +0900322
323void snd_soc_component_remove(struct snd_soc_component *component)
324{
325 if (component->driver->remove)
326 component->driver->remove(component);
327}
Kuninori Morimoto2c7b1702019-07-26 13:51:26 +0900328
329int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
330 struct device_node *ep)
331{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900332 int ret = -ENOTSUPP;
Kuninori Morimoto2c7b1702019-07-26 13:51:26 +0900333
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900334 if (component->driver->of_xlate_dai_id)
335 ret = component->driver->of_xlate_dai_id(component, ep);
336
337 return soc_component_ret(component, ret);
Kuninori Morimoto2c7b1702019-07-26 13:51:26 +0900338}
Kuninori Morimotoa2a34172019-07-26 13:51:31 +0900339
340int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
341 struct of_phandle_args *args,
342 const char **dai_name)
343{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900344 int ret = -ENOTSUPP;
345
Kuninori Morimotoa2a34172019-07-26 13:51:31 +0900346 if (component->driver->of_xlate_dai_name)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900347 ret = component->driver->of_xlate_dai_name(component,
348 args, dai_name);
349
350 return soc_component_ret(component, ret);
Kuninori Morimotoa2a34172019-07-26 13:51:31 +0900351}
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900352
Kuninori Morimotoc7d75b52020-06-04 17:06:22 +0900353void snd_soc_component_setup_regmap(struct snd_soc_component *component)
354{
355 int val_bytes = regmap_get_val_bytes(component->regmap);
356
357 /* Errors are legitimate for non-integer byte multiples */
358 if (val_bytes > 0)
359 component->val_bytes = val_bytes;
360}
361
362#ifdef CONFIG_REGMAP
363
364/**
365 * snd_soc_component_init_regmap() - Initialize regmap instance for the
366 * component
367 * @component: The component for which to initialize the regmap instance
368 * @regmap: The regmap instance that should be used by the component
369 *
370 * This function allows deferred assignment of the regmap instance that is
371 * associated with the component. Only use this if the regmap instance is not
372 * yet ready when the component is registered. The function must also be called
373 * before the first IO attempt of the component.
374 */
375void snd_soc_component_init_regmap(struct snd_soc_component *component,
376 struct regmap *regmap)
377{
378 component->regmap = regmap;
379 snd_soc_component_setup_regmap(component);
380}
381EXPORT_SYMBOL_GPL(snd_soc_component_init_regmap);
382
383/**
384 * snd_soc_component_exit_regmap() - De-initialize regmap instance for the
385 * component
386 * @component: The component for which to de-initialize the regmap instance
387 *
388 * Calls regmap_exit() on the regmap instance associated to the component and
389 * removes the regmap instance from the component.
390 *
391 * This function should only be used if snd_soc_component_init_regmap() was used
392 * to initialize the regmap instance.
393 */
394void snd_soc_component_exit_regmap(struct snd_soc_component *component)
395{
396 regmap_exit(component->regmap);
397 component->regmap = NULL;
398}
399EXPORT_SYMBOL_GPL(snd_soc_component_exit_regmap);
400
401#endif
402
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900403int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
404{
405 struct snd_soc_pcm_runtime *rtd = substream->private_data;
406 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900407 int i;
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900408
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900409 /* FIXME: use 1st pointer */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900410 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900411 if (component->driver->pointer)
412 return component->driver->pointer(component, substream);
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900413
414 return 0;
415}
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900416
417int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
418 unsigned int cmd, void *arg)
419{
420 struct snd_soc_pcm_runtime *rtd = substream->private_data;
421 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900422 int i;
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900423
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900424 /* FIXME: use 1st ioctl */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900425 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900426 if (component->driver->ioctl)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900427 return soc_component_ret(
428 component,
429 component->driver->ioctl(component,
430 substream, cmd, arg));
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900431
432 return snd_pcm_lib_ioctl(substream, cmd, arg);
433}
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900434
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100435int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream)
436{
437 struct snd_soc_pcm_runtime *rtd = substream->private_data;
438 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900439 int i, ret;
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100440
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900441 for_each_rtd_components(rtd, i, component) {
Kuninori Morimotof1861a72020-02-28 10:48:35 +0900442 if (component->driver->sync_stop) {
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100443 ret = component->driver->sync_stop(component,
444 substream);
445 if (ret < 0)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900446 soc_component_ret(component, ret);
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100447 }
448 }
449
450 return 0;
451}
452
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900453int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
454 int channel, unsigned long pos,
455 void __user *buf, unsigned long bytes)
456{
457 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900458 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900459 int i;
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900460
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900461 /* FIXME. it returns 1st copy now */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900462 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900463 if (component->driver->copy_user)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900464 return soc_component_ret(
465 component,
466 component->driver->copy_user(
467 component, substream, channel,
468 pos, buf, bytes));
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900469
470 return -EINVAL;
471}
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900472
473struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
474 unsigned long offset)
475{
476 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900477 struct snd_soc_component *component;
478 struct page *page;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900479 int i;
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900480
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900481 /* FIXME. it returns 1st page now */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900482 for_each_rtd_components(rtd, i, component) {
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900483 if (component->driver->page) {
484 page = component->driver->page(component,
485 substream, offset);
486 if (page)
487 return page;
488 }
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900489 }
490
491 return NULL;
492}
Kuninori Morimoto205875e2019-07-26 13:52:04 +0900493
494int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
495 struct vm_area_struct *vma)
496{
497 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Kuninori Morimoto205875e2019-07-26 13:52:04 +0900498 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900499 int i;
Kuninori Morimoto205875e2019-07-26 13:52:04 +0900500
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900501 /* FIXME. it returns 1st mmap now */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900502 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900503 if (component->driver->mmap)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900504 soc_component_ret(
505 component,
506 component->driver->mmap(component,
507 substream, vma));
Kuninori Morimoto205875e2019-07-26 13:52:04 +0900508
509 return -EINVAL;
510}
Kuninori Morimoto74842912019-07-26 13:52:08 +0900511
Kuninori Morimotob2b2afb2019-11-18 10:50:32 +0900512int snd_soc_pcm_component_new(struct snd_soc_pcm_runtime *rtd)
Kuninori Morimoto74842912019-07-26 13:52:08 +0900513{
Kuninori Morimoto74842912019-07-26 13:52:08 +0900514 struct snd_soc_component *component;
515 int ret;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900516 int i;
Kuninori Morimoto74842912019-07-26 13:52:08 +0900517
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900518 for_each_rtd_components(rtd, i, component) {
Kuninori Morimotoc64bfc92019-10-02 14:30:59 +0900519 if (component->driver->pcm_construct) {
520 ret = component->driver->pcm_construct(component, rtd);
521 if (ret < 0)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900522 soc_component_ret(component, ret);
Kuninori Morimotoc64bfc92019-10-02 14:30:59 +0900523 }
Kuninori Morimoto74842912019-07-26 13:52:08 +0900524 }
525
526 return 0;
527}
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900528
Kuninori Morimotob2b2afb2019-11-18 10:50:32 +0900529void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd)
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900530{
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900531 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900532 int i;
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900533
Takashi Iwai8e3366c2020-01-07 08:09:56 +0100534 if (!rtd->pcm)
535 return;
536
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900537 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoc64bfc92019-10-02 14:30:59 +0900538 if (component->driver->pcm_destruct)
Kuninori Morimotob2b2afb2019-11-18 10:50:32 +0900539 component->driver->pcm_destruct(component, rtd->pcm);
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900540}
Kuninori Morimoto4f395142020-06-04 17:06:58 +0900541
542int snd_soc_pcm_component_prepare(struct snd_pcm_substream *substream)
543{
544 struct snd_soc_pcm_runtime *rtd = substream->private_data;
545 struct snd_soc_component *component;
546 int i, ret;
547
548 for_each_rtd_components(rtd, i, component) {
549 if (component->driver->prepare) {
550 ret = component->driver->prepare(component, substream);
551 if (ret < 0)
552 return soc_component_ret(component, ret);
553 }
554 }
555
556 return 0;
557}
Kuninori Morimotoe1bafa82020-06-04 17:07:11 +0900558
559int snd_soc_pcm_component_hw_params(struct snd_pcm_substream *substream,
560 struct snd_pcm_hw_params *params,
561 struct snd_soc_component **last)
562{
563 struct snd_soc_pcm_runtime *rtd = substream->private_data;
564 struct snd_soc_component *component;
565 int i, ret;
566
567 for_each_rtd_components(rtd, i, component) {
568 if (component->driver->hw_params) {
569 ret = component->driver->hw_params(component,
570 substream, params);
571 if (ret < 0) {
572 *last = component;
573 return soc_component_ret(component, ret);
574 }
575 }
576 }
577
578 *last = NULL;
579 return 0;
580}
Kuninori Morimoto04751112020-06-04 17:07:24 +0900581
582void snd_soc_pcm_component_hw_free(struct snd_pcm_substream *substream,
583 struct snd_soc_component *last)
584{
585 struct snd_soc_pcm_runtime *rtd = substream->private_data;
586 struct snd_soc_component *component;
587 int i, ret;
588
589 for_each_rtd_components(rtd, i, component) {
590 if (component == last)
591 break;
592
593 if (component->driver->hw_free) {
594 ret = component->driver->hw_free(component, substream);
595 if (ret < 0)
596 soc_component_ret(component, ret);
597 }
598 }
599}
Kuninori Morimoto32fd1202020-06-04 17:07:40 +0900600
601int snd_soc_pcm_component_trigger(struct snd_pcm_substream *substream,
602 int cmd)
603{
604 struct snd_soc_pcm_runtime *rtd = substream->private_data;
605 struct snd_soc_component *component;
606 int i, ret;
607
608 for_each_rtd_components(rtd, i, component) {
609 if (component->driver->trigger) {
610 ret = component->driver->trigger(component, substream, cmd);
611 if (ret < 0)
612 return soc_component_ret(component, ret);
613 }
614 }
615
616 return 0;
617}