blob: 150b02be0219354e796f007d3c3ea31a79323b20 [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 Morimoto4ff1fef2019-07-26 13:49:48 +090049/**
50 * snd_soc_component_set_sysclk - configure COMPONENT system or master clock.
51 * @component: COMPONENT
52 * @clk_id: DAI specific clock ID
53 * @source: Source for the clock
54 * @freq: new clock frequency in Hz
55 * @dir: new clock direction - input/output.
56 *
57 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
58 */
59int snd_soc_component_set_sysclk(struct snd_soc_component *component,
60 int clk_id, int source, unsigned int freq,
61 int dir)
62{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +090063 int ret = -ENOTSUPP;
64
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090065 if (component->driver->set_sysclk)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +090066 ret = component->driver->set_sysclk(component, clk_id, source,
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090067 freq, dir);
68
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +090069 return soc_component_ret(component, ret);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090070}
71EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk);
72
73/*
74 * snd_soc_component_set_pll - configure component PLL.
75 * @component: COMPONENT
76 * @pll_id: DAI specific PLL ID
77 * @source: DAI specific source for the PLL
78 * @freq_in: PLL input clock frequency in Hz
79 * @freq_out: requested PLL output clock frequency in Hz
80 *
81 * Configures and enables PLL to generate output clock based on input clock.
82 */
83int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
84 int source, unsigned int freq_in,
85 unsigned int freq_out)
86{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +090087 int ret = -EINVAL;
88
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090089 if (component->driver->set_pll)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +090090 ret = component->driver->set_pll(component, pll_id, source,
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090091 freq_in, freq_out);
92
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +090093 return soc_component_ret(component, ret);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090094}
95EXPORT_SYMBOL_GPL(snd_soc_component_set_pll);
96
Kuninori Morimoto9d415fb2019-07-26 13:51:35 +090097void snd_soc_component_seq_notifier(struct snd_soc_component *component,
98 enum snd_soc_dapm_type type, int subseq)
99{
100 if (component->driver->seq_notifier)
101 component->driver->seq_notifier(component, type, subseq);
102}
103
Kuninori Morimoto8e2a9902019-07-26 13:51:39 +0900104int snd_soc_component_stream_event(struct snd_soc_component *component,
105 int event)
106{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900107 int ret = 0;
Kuninori Morimoto8e2a9902019-07-26 13:51:39 +0900108
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900109 if (component->driver->stream_event)
110 ret = component->driver->stream_event(component, event);
111
112 return soc_component_ret(component, ret);
Kuninori Morimoto8e2a9902019-07-26 13:51:39 +0900113}
114
Kuninori Morimoto7951b1462019-07-26 13:51:43 +0900115int snd_soc_component_set_bias_level(struct snd_soc_component *component,
116 enum snd_soc_bias_level level)
117{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900118 int ret = 0;
Kuninori Morimoto7951b1462019-07-26 13:51:43 +0900119
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900120 if (component->driver->set_bias_level)
121 ret = component->driver->set_bias_level(component, level);
122
123 return soc_component_ret(component, ret);
Kuninori Morimoto7951b1462019-07-26 13:51:43 +0900124}
125
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900126static int soc_component_pin(struct snd_soc_component *component,
127 const char *pin,
128 int (*pin_func)(struct snd_soc_dapm_context *dapm,
129 const char *pin))
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900130{
131 struct snd_soc_dapm_context *dapm =
132 snd_soc_component_get_dapm(component);
133 char *full_name;
134 int ret;
135
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900136 if (!component->name_prefix) {
137 ret = pin_func(dapm, pin);
138 goto end;
139 }
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900140
141 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900142 if (!full_name) {
143 ret = -ENOMEM;
144 goto end;
145 }
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900146
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900147 ret = pin_func(dapm, full_name);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900148 kfree(full_name);
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900149end:
150 return soc_component_ret(component, ret);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900151}
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900152
153int snd_soc_component_enable_pin(struct snd_soc_component *component,
154 const char *pin)
155{
156 return soc_component_pin(component, pin, snd_soc_dapm_enable_pin);
157}
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900158EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin);
159
160int snd_soc_component_enable_pin_unlocked(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_enable_pin_unlocked);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900164}
165EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked);
166
167int snd_soc_component_disable_pin(struct snd_soc_component *component,
168 const char *pin)
169{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900170 return soc_component_pin(component, pin, snd_soc_dapm_disable_pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900171}
172EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin);
173
174int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
175 const char *pin)
176{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900177 return soc_component_pin(component, pin, snd_soc_dapm_disable_pin_unlocked);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900178}
179EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked);
180
181int snd_soc_component_nc_pin(struct snd_soc_component *component,
182 const char *pin)
183{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900184 return soc_component_pin(component, pin, snd_soc_dapm_nc_pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900185}
186EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin);
187
188int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
189 const char *pin)
190{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900191 return soc_component_pin(component, pin, snd_soc_dapm_nc_pin_unlocked);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900192}
193EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked);
194
195int snd_soc_component_get_pin_status(struct snd_soc_component *component,
196 const char *pin)
197{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900198 return soc_component_pin(component, pin, snd_soc_dapm_get_pin_status);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900199}
200EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status);
201
202int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
203 const char *pin)
204{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900205 return soc_component_pin(component, pin, snd_soc_dapm_force_enable_pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900206}
207EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin);
208
209int snd_soc_component_force_enable_pin_unlocked(
210 struct snd_soc_component *component,
211 const char *pin)
212{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900213 return soc_component_pin(component, pin, snd_soc_dapm_force_enable_pin_unlocked);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900214}
215EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked);
216
217/**
218 * snd_soc_component_set_jack - configure component jack.
219 * @component: COMPONENTs
220 * @jack: structure to use for the jack
221 * @data: can be used if codec driver need extra data for configuring jack
222 *
223 * Configures and enables jack detection function.
224 */
225int snd_soc_component_set_jack(struct snd_soc_component *component,
226 struct snd_soc_jack *jack, void *data)
227{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900228 int ret = -ENOTSUPP;
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900229
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900230 if (component->driver->set_jack)
231 ret = component->driver->set_jack(component, jack, data);
232
233 return soc_component_ret(component, ret);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900234}
235EXPORT_SYMBOL_GPL(snd_soc_component_set_jack);
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900236
237int snd_soc_component_module_get(struct snd_soc_component *component,
238 int upon_open)
239{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900240 int ret = 0;
241
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900242 if (component->driver->module_get_upon_open == !!upon_open &&
243 !try_module_get(component->dev->driver->owner))
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900244 ret = -ENODEV;
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900245
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900246 return soc_component_ret(component, ret);
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900247}
248
249void snd_soc_component_module_put(struct snd_soc_component *component,
250 int upon_open)
251{
252 if (component->driver->module_get_upon_open == !!upon_open)
253 module_put(component->dev->driver->owner);
254}
Kuninori Morimotoae2f4842019-07-26 13:50:01 +0900255
256int snd_soc_component_open(struct snd_soc_component *component,
257 struct snd_pcm_substream *substream)
258{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900259 int ret = 0;
260
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900261 if (component->driver->open)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900262 ret = component->driver->open(component, substream);
263
264 return soc_component_ret(component, ret);
Kuninori Morimotoae2f4842019-07-26 13:50:01 +0900265}
Kuninori Morimoto3672beb2019-07-26 13:50:07 +0900266
267int snd_soc_component_close(struct snd_soc_component *component,
268 struct snd_pcm_substream *substream)
269{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900270 int ret = 0;
271
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900272 if (component->driver->close)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900273 ret = component->driver->close(component, substream);
274
275 return soc_component_ret(component, ret);
Kuninori Morimoto3672beb2019-07-26 13:50:07 +0900276}
Kuninori Morimoto6d537232019-07-26 13:50:13 +0900277
Kuninori Morimoto66c51572019-07-26 13:50:34 +0900278void snd_soc_component_suspend(struct snd_soc_component *component)
279{
280 if (component->driver->suspend)
281 component->driver->suspend(component);
282 component->suspended = 1;
283}
Kuninori Morimoto9a840cb2019-07-26 13:51:08 +0900284
285void snd_soc_component_resume(struct snd_soc_component *component)
286{
287 if (component->driver->resume)
288 component->driver->resume(component);
289 component->suspended = 0;
290}
Kuninori Morimotoe40fadb2019-07-26 13:51:13 +0900291
292int snd_soc_component_is_suspended(struct snd_soc_component *component)
293{
294 return component->suspended;
295}
Kuninori Morimoto08e837d2019-07-26 13:51:17 +0900296
297int snd_soc_component_probe(struct snd_soc_component *component)
298{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900299 int ret = 0;
Kuninori Morimoto08e837d2019-07-26 13:51:17 +0900300
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900301 if (component->driver->probe)
302 ret = component->driver->probe(component);
303
304 return soc_component_ret(component, ret);
Kuninori Morimoto08e837d2019-07-26 13:51:17 +0900305}
Kuninori Morimoto03b34dd2019-07-26 13:51:22 +0900306
307void snd_soc_component_remove(struct snd_soc_component *component)
308{
309 if (component->driver->remove)
310 component->driver->remove(component);
311}
Kuninori Morimoto2c7b1702019-07-26 13:51:26 +0900312
313int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
314 struct device_node *ep)
315{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900316 int ret = -ENOTSUPP;
Kuninori Morimoto2c7b1702019-07-26 13:51:26 +0900317
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900318 if (component->driver->of_xlate_dai_id)
319 ret = component->driver->of_xlate_dai_id(component, ep);
320
321 return soc_component_ret(component, ret);
Kuninori Morimoto2c7b1702019-07-26 13:51:26 +0900322}
Kuninori Morimotoa2a34172019-07-26 13:51:31 +0900323
324int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
325 struct of_phandle_args *args,
326 const char **dai_name)
327{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900328 int ret = -ENOTSUPP;
329
Kuninori Morimotoa2a34172019-07-26 13:51:31 +0900330 if (component->driver->of_xlate_dai_name)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900331 ret = component->driver->of_xlate_dai_name(component,
332 args, dai_name);
333
334 return soc_component_ret(component, ret);
Kuninori Morimotoa2a34172019-07-26 13:51:31 +0900335}
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900336
Kuninori Morimotoc7d75b52020-06-04 17:06:22 +0900337void snd_soc_component_setup_regmap(struct snd_soc_component *component)
338{
339 int val_bytes = regmap_get_val_bytes(component->regmap);
340
341 /* Errors are legitimate for non-integer byte multiples */
342 if (val_bytes > 0)
343 component->val_bytes = val_bytes;
344}
345
346#ifdef CONFIG_REGMAP
347
348/**
349 * snd_soc_component_init_regmap() - Initialize regmap instance for the
350 * component
351 * @component: The component for which to initialize the regmap instance
352 * @regmap: The regmap instance that should be used by the component
353 *
354 * This function allows deferred assignment of the regmap instance that is
355 * associated with the component. Only use this if the regmap instance is not
356 * yet ready when the component is registered. The function must also be called
357 * before the first IO attempt of the component.
358 */
359void snd_soc_component_init_regmap(struct snd_soc_component *component,
360 struct regmap *regmap)
361{
362 component->regmap = regmap;
363 snd_soc_component_setup_regmap(component);
364}
365EXPORT_SYMBOL_GPL(snd_soc_component_init_regmap);
366
367/**
368 * snd_soc_component_exit_regmap() - De-initialize regmap instance for the
369 * component
370 * @component: The component for which to de-initialize the regmap instance
371 *
372 * Calls regmap_exit() on the regmap instance associated to the component and
373 * removes the regmap instance from the component.
374 *
375 * This function should only be used if snd_soc_component_init_regmap() was used
376 * to initialize the regmap instance.
377 */
378void snd_soc_component_exit_regmap(struct snd_soc_component *component)
379{
380 regmap_exit(component->regmap);
381 component->regmap = NULL;
382}
383EXPORT_SYMBOL_GPL(snd_soc_component_exit_regmap);
384
385#endif
386
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900387int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
388{
389 struct snd_soc_pcm_runtime *rtd = substream->private_data;
390 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900391 int i;
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900392
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900393 /* FIXME: use 1st pointer */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900394 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900395 if (component->driver->pointer)
396 return component->driver->pointer(component, substream);
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900397
398 return 0;
399}
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900400
401int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
402 unsigned int cmd, void *arg)
403{
404 struct snd_soc_pcm_runtime *rtd = substream->private_data;
405 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900406 int i;
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900407
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900408 /* FIXME: use 1st ioctl */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900409 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900410 if (component->driver->ioctl)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900411 return soc_component_ret(
412 component,
413 component->driver->ioctl(component,
414 substream, cmd, arg));
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900415
416 return snd_pcm_lib_ioctl(substream, cmd, arg);
417}
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900418
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100419int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream)
420{
421 struct snd_soc_pcm_runtime *rtd = substream->private_data;
422 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900423 int i, ret;
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100424
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900425 for_each_rtd_components(rtd, i, component) {
Kuninori Morimotof1861a72020-02-28 10:48:35 +0900426 if (component->driver->sync_stop) {
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100427 ret = component->driver->sync_stop(component,
428 substream);
429 if (ret < 0)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900430 soc_component_ret(component, ret);
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100431 }
432 }
433
434 return 0;
435}
436
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900437int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
438 int channel, unsigned long pos,
439 void __user *buf, unsigned long bytes)
440{
441 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900442 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900443 int i;
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900444
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900445 /* FIXME. it returns 1st copy now */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900446 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900447 if (component->driver->copy_user)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900448 return soc_component_ret(
449 component,
450 component->driver->copy_user(
451 component, substream, channel,
452 pos, buf, bytes));
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900453
454 return -EINVAL;
455}
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900456
457struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
458 unsigned long offset)
459{
460 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900461 struct snd_soc_component *component;
462 struct page *page;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900463 int i;
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900464
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900465 /* FIXME. it returns 1st page now */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900466 for_each_rtd_components(rtd, i, component) {
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900467 if (component->driver->page) {
468 page = component->driver->page(component,
469 substream, offset);
470 if (page)
471 return page;
472 }
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900473 }
474
475 return NULL;
476}
Kuninori Morimoto205875e2019-07-26 13:52:04 +0900477
478int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
479 struct vm_area_struct *vma)
480{
481 struct snd_soc_pcm_runtime *rtd = substream->private_data;
Kuninori Morimoto205875e2019-07-26 13:52:04 +0900482 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900483 int i;
Kuninori Morimoto205875e2019-07-26 13:52:04 +0900484
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900485 /* FIXME. it returns 1st mmap now */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900486 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900487 if (component->driver->mmap)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900488 soc_component_ret(
489 component,
490 component->driver->mmap(component,
491 substream, vma));
Kuninori Morimoto205875e2019-07-26 13:52:04 +0900492
493 return -EINVAL;
494}
Kuninori Morimoto74842912019-07-26 13:52:08 +0900495
Kuninori Morimotob2b2afb2019-11-18 10:50:32 +0900496int snd_soc_pcm_component_new(struct snd_soc_pcm_runtime *rtd)
Kuninori Morimoto74842912019-07-26 13:52:08 +0900497{
Kuninori Morimoto74842912019-07-26 13:52:08 +0900498 struct snd_soc_component *component;
499 int ret;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900500 int i;
Kuninori Morimoto74842912019-07-26 13:52:08 +0900501
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900502 for_each_rtd_components(rtd, i, component) {
Kuninori Morimotoc64bfc92019-10-02 14:30:59 +0900503 if (component->driver->pcm_construct) {
504 ret = component->driver->pcm_construct(component, rtd);
505 if (ret < 0)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900506 soc_component_ret(component, ret);
Kuninori Morimotoc64bfc92019-10-02 14:30:59 +0900507 }
Kuninori Morimoto74842912019-07-26 13:52:08 +0900508 }
509
510 return 0;
511}
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900512
Kuninori Morimotob2b2afb2019-11-18 10:50:32 +0900513void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd)
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900514{
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900515 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900516 int i;
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900517
Takashi Iwai8e3366c2020-01-07 08:09:56 +0100518 if (!rtd->pcm)
519 return;
520
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900521 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoc64bfc92019-10-02 14:30:59 +0900522 if (component->driver->pcm_destruct)
Kuninori Morimotob2b2afb2019-11-18 10:50:32 +0900523 component->driver->pcm_destruct(component, rtd->pcm);
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900524}
Kuninori Morimoto4f395142020-06-04 17:06:58 +0900525
526int snd_soc_pcm_component_prepare(struct snd_pcm_substream *substream)
527{
528 struct snd_soc_pcm_runtime *rtd = substream->private_data;
529 struct snd_soc_component *component;
530 int i, ret;
531
532 for_each_rtd_components(rtd, i, component) {
533 if (component->driver->prepare) {
534 ret = component->driver->prepare(component, substream);
535 if (ret < 0)
536 return soc_component_ret(component, ret);
537 }
538 }
539
540 return 0;
541}
Kuninori Morimotoe1bafa82020-06-04 17:07:11 +0900542
543int snd_soc_pcm_component_hw_params(struct snd_pcm_substream *substream,
544 struct snd_pcm_hw_params *params,
545 struct snd_soc_component **last)
546{
547 struct snd_soc_pcm_runtime *rtd = substream->private_data;
548 struct snd_soc_component *component;
549 int i, ret;
550
551 for_each_rtd_components(rtd, i, component) {
552 if (component->driver->hw_params) {
553 ret = component->driver->hw_params(component,
554 substream, params);
555 if (ret < 0) {
556 *last = component;
557 return soc_component_ret(component, ret);
558 }
559 }
560 }
561
562 *last = NULL;
563 return 0;
564}
Kuninori Morimoto04751112020-06-04 17:07:24 +0900565
566void snd_soc_pcm_component_hw_free(struct snd_pcm_substream *substream,
567 struct snd_soc_component *last)
568{
569 struct snd_soc_pcm_runtime *rtd = substream->private_data;
570 struct snd_soc_component *component;
571 int i, ret;
572
573 for_each_rtd_components(rtd, i, component) {
574 if (component == last)
575 break;
576
577 if (component->driver->hw_free) {
578 ret = component->driver->hw_free(component, substream);
579 if (ret < 0)
580 soc_component_ret(component, ret);
581 }
582 }
583}
Kuninori Morimoto32fd1202020-06-04 17:07:40 +0900584
585int snd_soc_pcm_component_trigger(struct snd_pcm_substream *substream,
586 int cmd)
587{
588 struct snd_soc_pcm_runtime *rtd = substream->private_data;
589 struct snd_soc_component *component;
590 int i, ret;
591
592 for_each_rtd_components(rtd, i, component) {
593 if (component->driver->trigger) {
594 ret = component->driver->trigger(component, substream, cmd);
595 if (ret < 0)
596 return soc_component_ret(component, ret);
597 }
598 }
599
600 return 0;
601}