blob: a08a897c52305fa9e5b2b43b5b931d66bbc0c131 [file] [log] [blame]
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +09001// SPDX-License-Identifier: GPL-2.0
2//
3// soc-component.c
4//
Kuninori Morimoto460b42d2020-06-04 17:08:03 +09005// Copyright 2009-2011 Wolfson Microelectronics PLC.
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +09006// Copyright (C) 2019 Renesas Electronics Corp.
Kuninori Morimoto460b42d2020-06-04 17:08:03 +09007//
8// Mark Brown <broonie@opensource.wolfsonmicro.com>
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +09009// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
10//
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +090011#include <linux/module.h>
Kuninori Morimoto939a5cf2020-09-28 09:01:17 +090012#include <linux/pm_runtime.h>
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090013#include <sound/soc.h>
Srinivas Kandagatla8ac9e472021-01-29 10:05:39 +000014#include <linux/bitops.h>
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090015
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +090016#define soc_component_ret(dai, ret) _soc_component_ret(dai, __func__, ret)
17static inline int _soc_component_ret(struct snd_soc_component *component,
18 const char *func, int ret)
19{
20 /* Positive/Zero values are not errors */
21 if (ret >= 0)
22 return ret;
23
24 /* Negative values might be errors */
25 switch (ret) {
26 case -EPROBE_DEFER:
27 case -ENOTSUPP:
28 break;
29 default:
30 dev_err(component->dev,
31 "ASoC: error at %s on %s: %d\n",
32 func, component->name, ret);
33 }
34
35 return ret;
36}
37
Srinivas Kandagatla1da0b982021-01-26 17:17:48 +000038static inline int soc_component_field_shift(struct snd_soc_component *component,
39 unsigned int mask)
40{
41 if (!mask) {
42 dev_err(component->dev, "ASoC: error field mask is zero for %s\n",
43 component->name);
44 return 0;
45 }
46
Srinivas Kandagatla8ac9e472021-01-29 10:05:39 +000047 return (ffs(mask) - 1);
Srinivas Kandagatla1da0b982021-01-26 17:17:48 +000048}
49
Kuninori Morimoto51aff912020-09-28 09:01:04 +090050/*
51 * We might want to check substream by using list.
52 * In such case, we can update these macros.
53 */
54#define soc_component_mark_push(component, substream, tgt) ((component)->mark_##tgt = substream)
55#define soc_component_mark_pop(component, substream, tgt) ((component)->mark_##tgt = NULL)
56#define soc_component_mark_match(component, substream, tgt) ((component)->mark_##tgt == substream)
57
Kuninori Morimoto257c4da2020-06-04 17:07:54 +090058void snd_soc_component_set_aux(struct snd_soc_component *component,
59 struct snd_soc_aux_dev *aux)
60{
61 component->init = (aux) ? aux->init : NULL;
62}
63
64int snd_soc_component_init(struct snd_soc_component *component)
65{
66 int ret = 0;
67
68 if (component->init)
69 ret = component->init(component);
70
71 return soc_component_ret(component, ret);
72}
73
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090074/**
75 * snd_soc_component_set_sysclk - configure COMPONENT system or master clock.
76 * @component: COMPONENT
77 * @clk_id: DAI specific clock ID
78 * @source: Source for the clock
79 * @freq: new clock frequency in Hz
80 * @dir: new clock direction - input/output.
81 *
82 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
83 */
84int snd_soc_component_set_sysclk(struct snd_soc_component *component,
85 int clk_id, int source, unsigned int freq,
86 int dir)
87{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +090088 int ret = -ENOTSUPP;
89
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090090 if (component->driver->set_sysclk)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +090091 ret = component->driver->set_sysclk(component, clk_id, source,
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090092 freq, dir);
93
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +090094 return soc_component_ret(component, ret);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090095}
96EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk);
97
98/*
99 * snd_soc_component_set_pll - configure component PLL.
100 * @component: COMPONENT
101 * @pll_id: DAI specific PLL ID
102 * @source: DAI specific source for the PLL
103 * @freq_in: PLL input clock frequency in Hz
104 * @freq_out: requested PLL output clock frequency in Hz
105 *
106 * Configures and enables PLL to generate output clock based on input clock.
107 */
108int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
109 int source, unsigned int freq_in,
110 unsigned int freq_out)
111{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900112 int ret = -EINVAL;
113
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900114 if (component->driver->set_pll)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900115 ret = component->driver->set_pll(component, pll_id, source,
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900116 freq_in, freq_out);
117
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900118 return soc_component_ret(component, ret);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900119}
120EXPORT_SYMBOL_GPL(snd_soc_component_set_pll);
121
Kuninori Morimoto9d415fb2019-07-26 13:51:35 +0900122void snd_soc_component_seq_notifier(struct snd_soc_component *component,
123 enum snd_soc_dapm_type type, int subseq)
124{
125 if (component->driver->seq_notifier)
126 component->driver->seq_notifier(component, type, subseq);
127}
128
Kuninori Morimoto8e2a9902019-07-26 13:51:39 +0900129int snd_soc_component_stream_event(struct snd_soc_component *component,
130 int event)
131{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900132 int ret = 0;
Kuninori Morimoto8e2a9902019-07-26 13:51:39 +0900133
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900134 if (component->driver->stream_event)
135 ret = component->driver->stream_event(component, event);
136
137 return soc_component_ret(component, ret);
Kuninori Morimoto8e2a9902019-07-26 13:51:39 +0900138}
139
Kuninori Morimoto7951b1462019-07-26 13:51:43 +0900140int snd_soc_component_set_bias_level(struct snd_soc_component *component,
141 enum snd_soc_bias_level level)
142{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900143 int ret = 0;
Kuninori Morimoto7951b1462019-07-26 13:51:43 +0900144
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900145 if (component->driver->set_bias_level)
146 ret = component->driver->set_bias_level(component, level);
147
148 return soc_component_ret(component, ret);
Kuninori Morimoto7951b1462019-07-26 13:51:43 +0900149}
150
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900151int snd_soc_component_enable_pin(struct snd_soc_component *component,
152 const char *pin)
153{
Mark Brown31428c72021-07-26 20:41:23 +0100154 struct snd_soc_dapm_context *dapm =
155 snd_soc_component_get_dapm(component);
156 return snd_soc_dapm_enable_pin(dapm, pin);
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900157}
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{
Mark Brown31428c72021-07-26 20:41:23 +0100163 struct snd_soc_dapm_context *dapm =
164 snd_soc_component_get_dapm(component);
165 return snd_soc_dapm_enable_pin_unlocked(dapm, pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900166}
167EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked);
168
169int snd_soc_component_disable_pin(struct snd_soc_component *component,
170 const char *pin)
171{
Mark Brown31428c72021-07-26 20:41:23 +0100172 struct snd_soc_dapm_context *dapm =
173 snd_soc_component_get_dapm(component);
174 return snd_soc_dapm_disable_pin(dapm, pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900175}
176EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin);
177
178int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
179 const char *pin)
180{
Mark Brown31428c72021-07-26 20:41:23 +0100181 struct snd_soc_dapm_context *dapm =
182 snd_soc_component_get_dapm(component);
183 return snd_soc_dapm_disable_pin_unlocked(dapm, pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900184}
185EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked);
186
187int snd_soc_component_nc_pin(struct snd_soc_component *component,
188 const char *pin)
189{
Mark Brown31428c72021-07-26 20:41:23 +0100190 struct snd_soc_dapm_context *dapm =
191 snd_soc_component_get_dapm(component);
192 return snd_soc_dapm_nc_pin(dapm, pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900193}
194EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin);
195
196int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
197 const char *pin)
198{
Mark Brown31428c72021-07-26 20:41:23 +0100199 struct snd_soc_dapm_context *dapm =
200 snd_soc_component_get_dapm(component);
201 return snd_soc_dapm_nc_pin_unlocked(dapm, pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900202}
203EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked);
204
205int snd_soc_component_get_pin_status(struct snd_soc_component *component,
206 const char *pin)
207{
Mark Brown31428c72021-07-26 20:41:23 +0100208 struct snd_soc_dapm_context *dapm =
209 snd_soc_component_get_dapm(component);
210 return snd_soc_dapm_get_pin_status(dapm, pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900211}
212EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status);
213
214int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
215 const char *pin)
216{
Mark Brown31428c72021-07-26 20:41:23 +0100217 struct snd_soc_dapm_context *dapm =
218 snd_soc_component_get_dapm(component);
219 return snd_soc_dapm_force_enable_pin(dapm, pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900220}
221EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin);
222
223int snd_soc_component_force_enable_pin_unlocked(
224 struct snd_soc_component *component,
225 const char *pin)
226{
Mark Brown31428c72021-07-26 20:41:23 +0100227 struct snd_soc_dapm_context *dapm =
228 snd_soc_component_get_dapm(component);
229 return snd_soc_dapm_force_enable_pin_unlocked(dapm, pin);
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,
Peter Ujfalusia739fdc2021-09-01 12:52:54 +0300254 void *mark, int upon_open)
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900255{
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
Peter Ujfalusia739fdc2021-09-01 12:52:54 +0300262 /* mark module if succeeded */
Kuninori Morimoto51aff912020-09-28 09:01:04 +0900263 if (ret == 0)
Peter Ujfalusia739fdc2021-09-01 12:52:54 +0300264 soc_component_mark_push(component, mark, module);
Kuninori Morimoto51aff912020-09-28 09:01:04 +0900265
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900266 return soc_component_ret(component, ret);
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900267}
268
269void snd_soc_component_module_put(struct snd_soc_component *component,
Peter Ujfalusia739fdc2021-09-01 12:52:54 +0300270 void *mark, int upon_open, int rollback)
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900271{
Peter Ujfalusia739fdc2021-09-01 12:52:54 +0300272 if (rollback && !soc_component_mark_match(component, mark, module))
Kuninori Morimoto51aff912020-09-28 09:01:04 +0900273 return;
274
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900275 if (component->driver->module_get_upon_open == !!upon_open)
276 module_put(component->dev->driver->owner);
Kuninori Morimoto51aff912020-09-28 09:01:04 +0900277
Peter Ujfalusia739fdc2021-09-01 12:52:54 +0300278 /* remove the mark from module */
279 soc_component_mark_pop(component, mark, module);
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900280}
Kuninori Morimotoae2f4842019-07-26 13:50:01 +0900281
282int snd_soc_component_open(struct snd_soc_component *component,
283 struct snd_pcm_substream *substream)
284{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900285 int ret = 0;
286
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900287 if (component->driver->open)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900288 ret = component->driver->open(component, substream);
289
Kuninori Morimoto51aff912020-09-28 09:01:04 +0900290 /* mark substream if succeeded */
291 if (ret == 0)
292 soc_component_mark_push(component, substream, open);
293
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900294 return soc_component_ret(component, ret);
Kuninori Morimotoae2f4842019-07-26 13:50:01 +0900295}
Kuninori Morimoto3672beb2019-07-26 13:50:07 +0900296
297int snd_soc_component_close(struct snd_soc_component *component,
Kuninori Morimoto51aff912020-09-28 09:01:04 +0900298 struct snd_pcm_substream *substream,
299 int rollback)
Kuninori Morimoto3672beb2019-07-26 13:50:07 +0900300{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900301 int ret = 0;
302
Kuninori Morimoto51aff912020-09-28 09:01:04 +0900303 if (rollback && !soc_component_mark_match(component, substream, open))
304 return 0;
305
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900306 if (component->driver->close)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900307 ret = component->driver->close(component, substream);
308
Kuninori Morimoto51aff912020-09-28 09:01:04 +0900309 /* remove marked substream */
310 soc_component_mark_pop(component, substream, open);
311
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900312 return soc_component_ret(component, ret);
Kuninori Morimoto3672beb2019-07-26 13:50:07 +0900313}
Kuninori Morimoto6d537232019-07-26 13:50:13 +0900314
Kuninori Morimoto66c51572019-07-26 13:50:34 +0900315void snd_soc_component_suspend(struct snd_soc_component *component)
316{
317 if (component->driver->suspend)
318 component->driver->suspend(component);
319 component->suspended = 1;
320}
Kuninori Morimoto9a840cb2019-07-26 13:51:08 +0900321
322void snd_soc_component_resume(struct snd_soc_component *component)
323{
324 if (component->driver->resume)
325 component->driver->resume(component);
326 component->suspended = 0;
327}
Kuninori Morimotoe40fadb2019-07-26 13:51:13 +0900328
329int snd_soc_component_is_suspended(struct snd_soc_component *component)
330{
331 return component->suspended;
332}
Kuninori Morimoto08e837d2019-07-26 13:51:17 +0900333
334int snd_soc_component_probe(struct snd_soc_component *component)
335{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900336 int ret = 0;
Kuninori Morimoto08e837d2019-07-26 13:51:17 +0900337
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900338 if (component->driver->probe)
339 ret = component->driver->probe(component);
340
341 return soc_component_ret(component, ret);
Kuninori Morimoto08e837d2019-07-26 13:51:17 +0900342}
Kuninori Morimoto03b34dd2019-07-26 13:51:22 +0900343
344void snd_soc_component_remove(struct snd_soc_component *component)
345{
346 if (component->driver->remove)
347 component->driver->remove(component);
348}
Kuninori Morimoto2c7b1702019-07-26 13:51:26 +0900349
350int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
351 struct device_node *ep)
352{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900353 int ret = -ENOTSUPP;
Kuninori Morimoto2c7b1702019-07-26 13:51:26 +0900354
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900355 if (component->driver->of_xlate_dai_id)
356 ret = component->driver->of_xlate_dai_id(component, ep);
357
358 return soc_component_ret(component, ret);
Kuninori Morimoto2c7b1702019-07-26 13:51:26 +0900359}
Kuninori Morimotoa2a34172019-07-26 13:51:31 +0900360
361int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
Krzysztof Kozlowski933f98b2021-02-21 16:30:24 +0100362 const struct of_phandle_args *args,
Kuninori Morimotoa2a34172019-07-26 13:51:31 +0900363 const char **dai_name)
364{
365 if (component->driver->of_xlate_dai_name)
Jerome Brunetcc4d8ce2020-07-23 16:20:20 +0200366 return component->driver->of_xlate_dai_name(component,
367 args, dai_name);
368 /*
369 * Don't use soc_component_ret here because we may not want to report
370 * the error just yet. If a device has more than one component, the
371 * first may not match and we don't want spam the log with this.
372 */
373 return -ENOTSUPP;
Kuninori Morimotoa2a34172019-07-26 13:51:31 +0900374}
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900375
Kuninori Morimotoc7d75b52020-06-04 17:06:22 +0900376void snd_soc_component_setup_regmap(struct snd_soc_component *component)
377{
378 int val_bytes = regmap_get_val_bytes(component->regmap);
379
380 /* Errors are legitimate for non-integer byte multiples */
381 if (val_bytes > 0)
382 component->val_bytes = val_bytes;
383}
384
385#ifdef CONFIG_REGMAP
386
387/**
388 * snd_soc_component_init_regmap() - Initialize regmap instance for the
389 * component
390 * @component: The component for which to initialize the regmap instance
391 * @regmap: The regmap instance that should be used by the component
392 *
393 * This function allows deferred assignment of the regmap instance that is
394 * associated with the component. Only use this if the regmap instance is not
395 * yet ready when the component is registered. The function must also be called
396 * before the first IO attempt of the component.
397 */
398void snd_soc_component_init_regmap(struct snd_soc_component *component,
399 struct regmap *regmap)
400{
401 component->regmap = regmap;
402 snd_soc_component_setup_regmap(component);
403}
404EXPORT_SYMBOL_GPL(snd_soc_component_init_regmap);
405
406/**
407 * snd_soc_component_exit_regmap() - De-initialize regmap instance for the
408 * component
409 * @component: The component for which to de-initialize the regmap instance
410 *
411 * Calls regmap_exit() on the regmap instance associated to the component and
412 * removes the regmap instance from the component.
413 *
414 * This function should only be used if snd_soc_component_init_regmap() was used
415 * to initialize the regmap instance.
416 */
417void snd_soc_component_exit_regmap(struct snd_soc_component *component)
418{
419 regmap_exit(component->regmap);
420 component->regmap = NULL;
421}
422EXPORT_SYMBOL_GPL(snd_soc_component_exit_regmap);
423
424#endif
425
Peter Ujfalusicd46f382021-09-01 12:52:55 +0300426int snd_soc_component_compr_open(struct snd_soc_component *component,
427 struct snd_compr_stream *cstream)
Kuninori Morimotoa4e427c2020-11-13 13:15:20 +0900428{
Peter Ujfalusicd46f382021-09-01 12:52:55 +0300429 int ret = 0;
Kuninori Morimotoa4e427c2020-11-13 13:15:20 +0900430
Peter Ujfalusicd46f382021-09-01 12:52:55 +0300431 if (component->driver->compress_ops &&
432 component->driver->compress_ops->open)
433 ret = component->driver->compress_ops->open(component, cstream);
434
435 /* mark substream if succeeded */
436 if (ret == 0)
Kuninori Morimotof94ba9a2020-11-19 08:50:09 +0900437 soc_component_mark_push(component, cstream, compr_open);
Kuninori Morimotoa4e427c2020-11-13 13:15:20 +0900438
Peter Ujfalusicd46f382021-09-01 12:52:55 +0300439 return soc_component_ret(component, ret);
Kuninori Morimotoa4e427c2020-11-13 13:15:20 +0900440}
441EXPORT_SYMBOL_GPL(snd_soc_component_compr_open);
442
Peter Ujfalusicd46f382021-09-01 12:52:55 +0300443void snd_soc_component_compr_free(struct snd_soc_component *component,
444 struct snd_compr_stream *cstream,
Kuninori Morimotof94ba9a2020-11-19 08:50:09 +0900445 int rollback)
Kuninori Morimotodbde5e212020-11-13 13:15:26 +0900446{
Peter Ujfalusicd46f382021-09-01 12:52:55 +0300447 if (rollback && !soc_component_mark_match(component, cstream, compr_open))
448 return;
Kuninori Morimotodbde5e212020-11-13 13:15:26 +0900449
Peter Ujfalusicd46f382021-09-01 12:52:55 +0300450 if (component->driver->compress_ops &&
451 component->driver->compress_ops->free)
452 component->driver->compress_ops->free(component, cstream);
Kuninori Morimotodbde5e212020-11-13 13:15:26 +0900453
Peter Ujfalusicd46f382021-09-01 12:52:55 +0300454 /* remove marked substream */
455 soc_component_mark_pop(component, cstream, compr_open);
Kuninori Morimotodbde5e212020-11-13 13:15:26 +0900456}
457EXPORT_SYMBOL_GPL(snd_soc_component_compr_free);
458
Kuninori Morimoto08aee252020-11-13 13:15:33 +0900459int snd_soc_component_compr_trigger(struct snd_compr_stream *cstream, int cmd)
460{
461 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
462 struct snd_soc_component *component;
463 int i, ret;
464
465 for_each_rtd_components(rtd, i, component) {
466 if (component->driver->compress_ops &&
467 component->driver->compress_ops->trigger) {
468 ret = component->driver->compress_ops->trigger(
469 component, cstream, cmd);
470 if (ret < 0)
471 return soc_component_ret(component, ret);
472 }
473 }
474
475 return 0;
476}
477EXPORT_SYMBOL_GPL(snd_soc_component_compr_trigger);
478
Kuninori Morimotoff08cf82020-11-13 13:15:49 +0900479int snd_soc_component_compr_set_params(struct snd_compr_stream *cstream,
480 struct snd_compr_params *params)
481{
482 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
483 struct snd_soc_component *component;
484 int i, ret;
485
486 for_each_rtd_components(rtd, i, component) {
487 if (component->driver->compress_ops &&
488 component->driver->compress_ops->set_params) {
489 ret = component->driver->compress_ops->set_params(
490 component, cstream, params);
491 if (ret < 0)
492 return soc_component_ret(component, ret);
493 }
494 }
495
496 return 0;
497}
498EXPORT_SYMBOL_GPL(snd_soc_component_compr_set_params);
499
Kuninori Morimoto77c221e2020-11-13 13:15:56 +0900500int snd_soc_component_compr_get_params(struct snd_compr_stream *cstream,
501 struct snd_codec *params)
502{
503 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
504 struct snd_soc_component *component;
505 int i, ret;
506
507 for_each_rtd_components(rtd, i, component) {
508 if (component->driver->compress_ops &&
509 component->driver->compress_ops->get_params) {
510 ret = component->driver->compress_ops->get_params(
511 component, cstream, params);
512 return soc_component_ret(component, ret);
513 }
514 }
515
516 return 0;
517}
518EXPORT_SYMBOL_GPL(snd_soc_component_compr_get_params);
519
Kuninori Morimotod67fcb22020-11-13 13:16:03 +0900520int snd_soc_component_compr_get_caps(struct snd_compr_stream *cstream,
521 struct snd_compr_caps *caps)
522{
523 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
524 struct snd_soc_component *component;
525 int i, ret = 0;
526
527 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
528
529 for_each_rtd_components(rtd, i, component) {
530 if (component->driver->compress_ops &&
531 component->driver->compress_ops->get_caps) {
532 ret = component->driver->compress_ops->get_caps(
533 component, cstream, caps);
534 break;
535 }
536 }
537
538 mutex_unlock(&rtd->card->pcm_mutex);
539
540 return soc_component_ret(component, ret);
541}
542EXPORT_SYMBOL_GPL(snd_soc_component_compr_get_caps);
543
Kuninori Morimoto0f6fe092020-11-13 13:16:11 +0900544int snd_soc_component_compr_get_codec_caps(struct snd_compr_stream *cstream,
545 struct snd_compr_codec_caps *codec)
546{
547 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
548 struct snd_soc_component *component;
549 int i, ret = 0;
550
551 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
552
553 for_each_rtd_components(rtd, i, component) {
554 if (component->driver->compress_ops &&
555 component->driver->compress_ops->get_codec_caps) {
556 ret = component->driver->compress_ops->get_codec_caps(
557 component, cstream, codec);
558 break;
559 }
560 }
561
562 mutex_unlock(&rtd->card->pcm_mutex);
563
564 return soc_component_ret(component, ret);
565}
566EXPORT_SYMBOL_GPL(snd_soc_component_compr_get_codec_caps);
567
Kuninori Morimoto0506b882020-11-13 13:16:17 +0900568int snd_soc_component_compr_ack(struct snd_compr_stream *cstream, size_t bytes)
569{
570 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
571 struct snd_soc_component *component;
572 int i, ret;
573
574 for_each_rtd_components(rtd, i, component) {
575 if (component->driver->compress_ops &&
576 component->driver->compress_ops->ack) {
577 ret = component->driver->compress_ops->ack(
578 component, cstream, bytes);
579 if (ret < 0)
580 return soc_component_ret(component, ret);
581 }
582 }
583
584 return 0;
585}
586EXPORT_SYMBOL_GPL(snd_soc_component_compr_ack);
587
Kuninori Morimoto03ecea62020-11-13 13:16:24 +0900588int snd_soc_component_compr_pointer(struct snd_compr_stream *cstream,
589 struct snd_compr_tstamp *tstamp)
590{
591 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
592 struct snd_soc_component *component;
593 int i, ret;
594
595 for_each_rtd_components(rtd, i, component) {
596 if (component->driver->compress_ops &&
597 component->driver->compress_ops->pointer) {
598 ret = component->driver->compress_ops->pointer(
599 component, cstream, tstamp);
600 return soc_component_ret(component, ret);
601 }
602 }
603
604 return 0;
605}
606EXPORT_SYMBOL_GPL(snd_soc_component_compr_pointer);
607
Kuninori Morimotob5852e62020-11-13 13:16:30 +0900608int snd_soc_component_compr_copy(struct snd_compr_stream *cstream,
609 char __user *buf, size_t count)
610{
611 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
612 struct snd_soc_component *component;
613 int i, ret = 0;
614
615 mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
616
617 for_each_rtd_components(rtd, i, component) {
618 if (component->driver->compress_ops &&
619 component->driver->compress_ops->copy) {
620 ret = component->driver->compress_ops->copy(
621 component, cstream, buf, count);
622 break;
623 }
624 }
625
626 mutex_unlock(&rtd->card->pcm_mutex);
627
628 return soc_component_ret(component, ret);
629}
630EXPORT_SYMBOL_GPL(snd_soc_component_compr_copy);
631
Kuninori Morimoto1b308fb2020-11-13 13:16:36 +0900632int snd_soc_component_compr_set_metadata(struct snd_compr_stream *cstream,
633 struct snd_compr_metadata *metadata)
634{
635 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
636 struct snd_soc_component *component;
637 int i, ret;
638
639 for_each_rtd_components(rtd, i, component) {
640 if (component->driver->compress_ops &&
641 component->driver->compress_ops->set_metadata) {
642 ret = component->driver->compress_ops->set_metadata(
643 component, cstream, metadata);
644 if (ret < 0)
645 return soc_component_ret(component, ret);
646 }
647 }
648
649 return 0;
650}
651EXPORT_SYMBOL_GPL(snd_soc_component_compr_set_metadata);
652
Kuninori Morimotobab78c22020-11-13 13:16:41 +0900653int snd_soc_component_compr_get_metadata(struct snd_compr_stream *cstream,
654 struct snd_compr_metadata *metadata)
655{
656 struct snd_soc_pcm_runtime *rtd = cstream->private_data;
657 struct snd_soc_component *component;
658 int i, ret;
659
660 for_each_rtd_components(rtd, i, component) {
661 if (component->driver->compress_ops &&
662 component->driver->compress_ops->get_metadata) {
663 ret = component->driver->compress_ops->get_metadata(
664 component, cstream, metadata);
665 return soc_component_ret(component, ret);
666 }
667 }
668
669 return 0;
670}
671EXPORT_SYMBOL_GPL(snd_soc_component_compr_get_metadata);
672
Kuninori Morimotoe8712312020-06-16 14:19:52 +0900673static unsigned int soc_component_read_no_lock(
674 struct snd_soc_component *component,
675 unsigned int reg)
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900676{
677 int ret;
Kuninori Morimotocf6e26c2020-06-16 14:19:41 +0900678 unsigned int val = 0;
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900679
680 if (component->regmap)
Kuninori Morimotocf6e26c2020-06-16 14:19:41 +0900681 ret = regmap_read(component->regmap, reg, &val);
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900682 else if (component->driver->read) {
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900683 ret = 0;
Kuninori Morimotocf6e26c2020-06-16 14:19:41 +0900684 val = component->driver->read(component, reg);
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900685 }
686 else
687 ret = -EIO;
688
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900689 if (ret < 0)
Takashi Iwaiefc913c2020-08-10 15:46:31 +0200690 return soc_component_ret(component, ret);
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900691
692 return val;
693}
Kuninori Morimotoe8712312020-06-16 14:19:52 +0900694
695/**
696 * snd_soc_component_read() - Read register value
697 * @component: Component to read from
698 * @reg: Register to read
699 *
700 * Return: read value
701 */
702unsigned int snd_soc_component_read(struct snd_soc_component *component,
703 unsigned int reg)
704{
705 unsigned int val;
706
707 mutex_lock(&component->io_mutex);
708 val = soc_component_read_no_lock(component, reg);
709 mutex_unlock(&component->io_mutex);
710
711 return val;
712}
Kuninori Morimotocf6e26c2020-06-16 14:19:41 +0900713EXPORT_SYMBOL_GPL(snd_soc_component_read);
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900714
Kuninori Morimotoe8712312020-06-16 14:19:52 +0900715static int soc_component_write_no_lock(
716 struct snd_soc_component *component,
717 unsigned int reg, unsigned int val)
718{
719 int ret = -EIO;
720
721 if (component->regmap)
722 ret = regmap_write(component->regmap, reg, val);
723 else if (component->driver->write)
724 ret = component->driver->write(component, reg, val);
725
726 return soc_component_ret(component, ret);
727}
728
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900729/**
730 * snd_soc_component_write() - Write register value
731 * @component: Component to write to
732 * @reg: Register to write
733 * @val: Value to write to the register
734 *
735 * Return: 0 on success, a negative error code otherwise.
736 */
737int snd_soc_component_write(struct snd_soc_component *component,
738 unsigned int reg, unsigned int val)
739{
Kuninori Morimotoe8712312020-06-16 14:19:52 +0900740 int ret;
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900741
Kuninori Morimotoe8712312020-06-16 14:19:52 +0900742 mutex_lock(&component->io_mutex);
743 ret = soc_component_write_no_lock(component, reg, val);
744 mutex_unlock(&component->io_mutex);
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900745
Kuninori Morimotoe8712312020-06-16 14:19:52 +0900746 return ret;
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900747}
748EXPORT_SYMBOL_GPL(snd_soc_component_write);
749
750static int snd_soc_component_update_bits_legacy(
751 struct snd_soc_component *component, unsigned int reg,
752 unsigned int mask, unsigned int val, bool *change)
753{
754 unsigned int old, new;
Kuninori Morimotocf6e26c2020-06-16 14:19:41 +0900755 int ret = 0;
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900756
757 mutex_lock(&component->io_mutex);
758
Kuninori Morimotoe8712312020-06-16 14:19:52 +0900759 old = soc_component_read_no_lock(component, reg);
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900760
761 new = (old & ~mask) | (val & mask);
762 *change = old != new;
763 if (*change)
Kuninori Morimotoe8712312020-06-16 14:19:52 +0900764 ret = soc_component_write_no_lock(component, reg, new);
Kuninori Morimotocf6e26c2020-06-16 14:19:41 +0900765
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900766 mutex_unlock(&component->io_mutex);
767
768 return soc_component_ret(component, ret);
769}
770
771/**
772 * snd_soc_component_update_bits() - Perform read/modify/write cycle
773 * @component: Component to update
774 * @reg: Register to update
775 * @mask: Mask that specifies which bits to update
776 * @val: New value for the bits specified by mask
777 *
778 * Return: 1 if the operation was successful and the value of the register
779 * changed, 0 if the operation was successful, but the value did not change.
780 * Returns a negative error code otherwise.
781 */
782int snd_soc_component_update_bits(struct snd_soc_component *component,
783 unsigned int reg, unsigned int mask, unsigned int val)
784{
785 bool change;
786 int ret;
787
788 if (component->regmap)
789 ret = regmap_update_bits_check(component->regmap, reg, mask,
790 val, &change);
791 else
792 ret = snd_soc_component_update_bits_legacy(component, reg,
793 mask, val, &change);
794
795 if (ret < 0)
796 return soc_component_ret(component, ret);
797 return change;
798}
799EXPORT_SYMBOL_GPL(snd_soc_component_update_bits);
800
801/**
802 * snd_soc_component_update_bits_async() - Perform asynchronous
803 * read/modify/write cycle
804 * @component: Component to update
805 * @reg: Register to update
806 * @mask: Mask that specifies which bits to update
807 * @val: New value for the bits specified by mask
808 *
809 * This function is similar to snd_soc_component_update_bits(), but the update
810 * operation is scheduled asynchronously. This means it may not be completed
811 * when the function returns. To make sure that all scheduled updates have been
812 * completed snd_soc_component_async_complete() must be called.
813 *
814 * Return: 1 if the operation was successful and the value of the register
815 * changed, 0 if the operation was successful, but the value did not change.
816 * Returns a negative error code otherwise.
817 */
818int snd_soc_component_update_bits_async(struct snd_soc_component *component,
819 unsigned int reg, unsigned int mask, unsigned int val)
820{
821 bool change;
822 int ret;
823
824 if (component->regmap)
825 ret = regmap_update_bits_check_async(component->regmap, reg,
826 mask, val, &change);
827 else
828 ret = snd_soc_component_update_bits_legacy(component, reg,
829 mask, val, &change);
830
831 if (ret < 0)
832 return soc_component_ret(component, ret);
833 return change;
834}
835EXPORT_SYMBOL_GPL(snd_soc_component_update_bits_async);
836
837/**
Srinivas Kandagatla1da0b982021-01-26 17:17:48 +0000838 * snd_soc_component_read_field() - Read register field value
839 * @component: Component to read from
840 * @reg: Register to read
841 * @mask: mask of the register field
842 *
843 * Return: read value of register field.
844 */
845unsigned int snd_soc_component_read_field(struct snd_soc_component *component,
846 unsigned int reg, unsigned int mask)
847{
848 unsigned int val;
849
850 val = snd_soc_component_read(component, reg);
851
852 val = (val & mask) >> soc_component_field_shift(component, mask);
853
854 return val;
855}
856EXPORT_SYMBOL_GPL(snd_soc_component_read_field);
857
858/**
859 * snd_soc_component_write_field() - write to register field
860 * @component: Component to write to
861 * @reg: Register to write
862 * @mask: mask of the register field to update
863 * @val: value of the field to write
864 *
865 * Return: 1 for change, otherwise 0.
866 */
867int snd_soc_component_write_field(struct snd_soc_component *component,
868 unsigned int reg, unsigned int mask,
869 unsigned int val)
870{
871
872 val = (val << soc_component_field_shift(component, mask)) & mask;
873
874 return snd_soc_component_update_bits(component, reg, mask, val);
875}
876EXPORT_SYMBOL_GPL(snd_soc_component_write_field);
877
878/**
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900879 * snd_soc_component_async_complete() - Ensure asynchronous I/O has completed
880 * @component: Component for which to wait
881 *
882 * This function blocks until all asynchronous I/O which has previously been
883 * scheduled using snd_soc_component_update_bits_async() has completed.
884 */
885void snd_soc_component_async_complete(struct snd_soc_component *component)
886{
887 if (component->regmap)
888 regmap_async_complete(component->regmap);
889}
890EXPORT_SYMBOL_GPL(snd_soc_component_async_complete);
891
892/**
893 * snd_soc_component_test_bits - Test register for change
894 * @component: component
895 * @reg: Register to test
896 * @mask: Mask that specifies which bits to test
897 * @value: Value to test against
898 *
899 * Tests a register with a new value and checks if the new value is
900 * different from the old value.
901 *
902 * Return: 1 for change, otherwise 0.
903 */
904int snd_soc_component_test_bits(struct snd_soc_component *component,
905 unsigned int reg, unsigned int mask, unsigned int value)
906{
907 unsigned int old, new;
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900908
Kuninori Morimotocf6e26c2020-06-16 14:19:41 +0900909 old = snd_soc_component_read(component, reg);
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900910 new = (old & ~mask) | value;
911 return old != new;
912}
913EXPORT_SYMBOL_GPL(snd_soc_component_test_bits);
914
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900915int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
916{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +0900917 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900918 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900919 int i;
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900920
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900921 /* FIXME: use 1st pointer */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900922 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900923 if (component->driver->pointer)
924 return component->driver->pointer(component, substream);
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900925
926 return 0;
927}
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900928
929int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
930 unsigned int cmd, void *arg)
931{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +0900932 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900933 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900934 int i;
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900935
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900936 /* FIXME: use 1st ioctl */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900937 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900938 if (component->driver->ioctl)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900939 return soc_component_ret(
940 component,
941 component->driver->ioctl(component,
942 substream, cmd, arg));
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900943
944 return snd_pcm_lib_ioctl(substream, cmd, arg);
945}
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900946
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100947int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream)
948{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +0900949 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100950 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900951 int i, ret;
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100952
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900953 for_each_rtd_components(rtd, i, component) {
Kuninori Morimotof1861a72020-02-28 10:48:35 +0900954 if (component->driver->sync_stop) {
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100955 ret = component->driver->sync_stop(component,
956 substream);
957 if (ret < 0)
Shengjiu Wangbe75db52020-07-16 13:07:08 +0800958 return soc_component_ret(component, ret);
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100959 }
960 }
961
962 return 0;
963}
964
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900965int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
966 int channel, unsigned long pos,
967 void __user *buf, unsigned long bytes)
968{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +0900969 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900970 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900971 int i;
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900972
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900973 /* FIXME. it returns 1st copy now */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900974 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900975 if (component->driver->copy_user)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900976 return soc_component_ret(
977 component,
978 component->driver->copy_user(
979 component, substream, channel,
980 pos, buf, bytes));
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900981
982 return -EINVAL;
983}
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900984
985struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
986 unsigned long offset)
987{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +0900988 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900989 struct snd_soc_component *component;
990 struct page *page;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900991 int i;
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900992
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900993 /* FIXME. it returns 1st page now */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900994 for_each_rtd_components(rtd, i, component) {
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900995 if (component->driver->page) {
996 page = component->driver->page(component,
997 substream, offset);
998 if (page)
999 return page;
1000 }
Kuninori Morimoto9c712e42019-07-26 13:52:00 +09001001 }
1002
1003 return NULL;
1004}
Kuninori Morimoto205875e2019-07-26 13:52:04 +09001005
1006int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
1007 struct vm_area_struct *vma)
1008{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +09001009 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Kuninori Morimoto205875e2019-07-26 13:52:04 +09001010 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +09001011 int i;
Kuninori Morimoto205875e2019-07-26 13:52:04 +09001012
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +09001013 /* FIXME. it returns 1st mmap now */
Kuninori Morimoto613fb502020-01-10 11:35:21 +09001014 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +09001015 if (component->driver->mmap)
Shengjiu Wangbe75db52020-07-16 13:07:08 +08001016 return soc_component_ret(
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +09001017 component,
1018 component->driver->mmap(component,
1019 substream, vma));
Kuninori Morimoto205875e2019-07-26 13:52:04 +09001020
1021 return -EINVAL;
1022}
Kuninori Morimoto74842912019-07-26 13:52:08 +09001023
Kuninori Morimotob2b2afb2019-11-18 10:50:32 +09001024int snd_soc_pcm_component_new(struct snd_soc_pcm_runtime *rtd)
Kuninori Morimoto74842912019-07-26 13:52:08 +09001025{
Kuninori Morimoto74842912019-07-26 13:52:08 +09001026 struct snd_soc_component *component;
1027 int ret;
Kuninori Morimoto613fb502020-01-10 11:35:21 +09001028 int i;
Kuninori Morimoto74842912019-07-26 13:52:08 +09001029
Kuninori Morimoto613fb502020-01-10 11:35:21 +09001030 for_each_rtd_components(rtd, i, component) {
Kuninori Morimotoc64bfc92019-10-02 14:30:59 +09001031 if (component->driver->pcm_construct) {
1032 ret = component->driver->pcm_construct(component, rtd);
1033 if (ret < 0)
Shengjiu Wangbe75db52020-07-16 13:07:08 +08001034 return soc_component_ret(component, ret);
Kuninori Morimotoc64bfc92019-10-02 14:30:59 +09001035 }
Kuninori Morimoto74842912019-07-26 13:52:08 +09001036 }
1037
1038 return 0;
1039}
Kuninori Morimoto79776da2019-07-26 13:52:12 +09001040
Kuninori Morimotob2b2afb2019-11-18 10:50:32 +09001041void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd)
Kuninori Morimoto79776da2019-07-26 13:52:12 +09001042{
Kuninori Morimoto79776da2019-07-26 13:52:12 +09001043 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +09001044 int i;
Kuninori Morimoto79776da2019-07-26 13:52:12 +09001045
Takashi Iwai8e3366c2020-01-07 08:09:56 +01001046 if (!rtd->pcm)
1047 return;
1048
Kuninori Morimoto613fb502020-01-10 11:35:21 +09001049 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoc64bfc92019-10-02 14:30:59 +09001050 if (component->driver->pcm_destruct)
Kuninori Morimotob2b2afb2019-11-18 10:50:32 +09001051 component->driver->pcm_destruct(component, rtd->pcm);
Kuninori Morimoto79776da2019-07-26 13:52:12 +09001052}
Kuninori Morimoto4f395142020-06-04 17:06:58 +09001053
1054int snd_soc_pcm_component_prepare(struct snd_pcm_substream *substream)
1055{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +09001056 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Kuninori Morimoto4f395142020-06-04 17:06:58 +09001057 struct snd_soc_component *component;
1058 int i, ret;
1059
1060 for_each_rtd_components(rtd, i, component) {
1061 if (component->driver->prepare) {
1062 ret = component->driver->prepare(component, substream);
1063 if (ret < 0)
1064 return soc_component_ret(component, ret);
1065 }
1066 }
1067
1068 return 0;
1069}
Kuninori Morimotoe1bafa82020-06-04 17:07:11 +09001070
1071int snd_soc_pcm_component_hw_params(struct snd_pcm_substream *substream,
Kuninori Morimoto3a36a642020-09-29 13:31:41 +09001072 struct snd_pcm_hw_params *params)
Kuninori Morimotoe1bafa82020-06-04 17:07:11 +09001073{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +09001074 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Kuninori Morimotoe1bafa82020-06-04 17:07:11 +09001075 struct snd_soc_component *component;
1076 int i, ret;
1077
1078 for_each_rtd_components(rtd, i, component) {
1079 if (component->driver->hw_params) {
1080 ret = component->driver->hw_params(component,
1081 substream, params);
Kuninori Morimoto3a36a642020-09-29 13:31:41 +09001082 if (ret < 0)
Kuninori Morimotoe1bafa82020-06-04 17:07:11 +09001083 return soc_component_ret(component, ret);
Kuninori Morimotoe1bafa82020-06-04 17:07:11 +09001084 }
Kuninori Morimoto3a36a642020-09-29 13:31:41 +09001085 /* mark substream if succeeded */
1086 soc_component_mark_push(component, substream, hw_params);
Kuninori Morimotoe1bafa82020-06-04 17:07:11 +09001087 }
1088
Kuninori Morimotoe1bafa82020-06-04 17:07:11 +09001089 return 0;
1090}
Kuninori Morimoto04751112020-06-04 17:07:24 +09001091
1092void snd_soc_pcm_component_hw_free(struct snd_pcm_substream *substream,
Kuninori Morimoto3a36a642020-09-29 13:31:41 +09001093 int rollback)
Kuninori Morimoto04751112020-06-04 17:07:24 +09001094{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +09001095 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Kuninori Morimoto04751112020-06-04 17:07:24 +09001096 struct snd_soc_component *component;
1097 int i, ret;
1098
1099 for_each_rtd_components(rtd, i, component) {
Kuninori Morimoto3a36a642020-09-29 13:31:41 +09001100 if (rollback && !soc_component_mark_match(component, substream, hw_params))
1101 continue;
Kuninori Morimoto04751112020-06-04 17:07:24 +09001102
1103 if (component->driver->hw_free) {
1104 ret = component->driver->hw_free(component, substream);
1105 if (ret < 0)
1106 soc_component_ret(component, ret);
1107 }
Kuninori Morimoto3a36a642020-09-29 13:31:41 +09001108
1109 /* remove marked substream */
1110 soc_component_mark_pop(component, substream, hw_params);
Kuninori Morimoto04751112020-06-04 17:07:24 +09001111 }
1112}
Kuninori Morimoto32fd1202020-06-04 17:07:40 +09001113
Kuninori Morimoto6374f492020-12-01 08:51:33 +09001114static int soc_component_trigger(struct snd_soc_component *component,
1115 struct snd_pcm_substream *substream,
1116 int cmd)
1117{
1118 int ret = 0;
1119
1120 if (component->driver->trigger)
1121 ret = component->driver->trigger(component, substream, cmd);
1122
1123 return soc_component_ret(component, ret);
1124}
1125
Kuninori Morimoto32fd1202020-06-04 17:07:40 +09001126int snd_soc_pcm_component_trigger(struct snd_pcm_substream *substream,
Kuninori Morimoto6374f492020-12-01 08:51:33 +09001127 int cmd, int rollback)
Kuninori Morimoto32fd1202020-06-04 17:07:40 +09001128{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +09001129 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Kuninori Morimoto32fd1202020-06-04 17:07:40 +09001130 struct snd_soc_component *component;
Kuninori Morimoto6374f492020-12-01 08:51:33 +09001131 int i, r, ret = 0;
Kuninori Morimoto32fd1202020-06-04 17:07:40 +09001132
Kuninori Morimoto6374f492020-12-01 08:51:33 +09001133 switch (cmd) {
1134 case SNDRV_PCM_TRIGGER_START:
1135 case SNDRV_PCM_TRIGGER_RESUME:
1136 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1137 for_each_rtd_components(rtd, i, component) {
1138 ret = soc_component_trigger(component, substream, cmd);
Kuninori Morimoto32fd1202020-06-04 17:07:40 +09001139 if (ret < 0)
Kuninori Morimoto6374f492020-12-01 08:51:33 +09001140 break;
1141 soc_component_mark_push(component, substream, trigger);
1142 }
1143 break;
1144 case SNDRV_PCM_TRIGGER_STOP:
1145 case SNDRV_PCM_TRIGGER_SUSPEND:
1146 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1147 for_each_rtd_components(rtd, i, component) {
1148 if (rollback && !soc_component_mark_match(component, substream, trigger))
1149 continue;
1150
1151 r = soc_component_trigger(component, substream, cmd);
1152 if (r < 0)
1153 ret = r; /* use last ret */
1154 soc_component_mark_pop(component, substream, trigger);
Kuninori Morimoto32fd1202020-06-04 17:07:40 +09001155 }
1156 }
1157
Kuninori Morimoto6374f492020-12-01 08:51:33 +09001158 return ret;
Kuninori Morimoto32fd1202020-06-04 17:07:40 +09001159}
Kuninori Morimoto939a5cf2020-09-28 09:01:17 +09001160
1161int snd_soc_pcm_component_pm_runtime_get(struct snd_soc_pcm_runtime *rtd,
1162 void *stream)
1163{
1164 struct snd_soc_component *component;
Kuninori Morimoto500b39d2021-08-16 13:56:19 +09001165 int i;
Kuninori Morimoto939a5cf2020-09-28 09:01:17 +09001166
1167 for_each_rtd_components(rtd, i, component) {
Kuninori Morimoto500b39d2021-08-16 13:56:19 +09001168 int ret = pm_runtime_get_sync(component->dev);
Kuninori Morimoto939a5cf2020-09-28 09:01:17 +09001169 if (ret < 0 && ret != -EACCES) {
1170 pm_runtime_put_noidle(component->dev);
1171 return soc_component_ret(component, ret);
1172 }
1173 /* mark stream if succeeded */
1174 soc_component_mark_push(component, stream, pm);
1175 }
1176
1177 return 0;
1178}
1179
1180void snd_soc_pcm_component_pm_runtime_put(struct snd_soc_pcm_runtime *rtd,
1181 void *stream, int rollback)
1182{
1183 struct snd_soc_component *component;
1184 int i;
1185
1186 for_each_rtd_components(rtd, i, component) {
1187 if (rollback && !soc_component_mark_match(component, stream, pm))
1188 continue;
1189
1190 pm_runtime_mark_last_busy(component->dev);
1191 pm_runtime_put_autosuspend(component->dev);
1192
1193 /* remove marked stream */
1194 soc_component_mark_pop(component, stream, pm);
1195 }
1196}
Shengjiu Wang8bdfc042021-03-12 10:38:40 +08001197
1198int snd_soc_pcm_component_ack(struct snd_pcm_substream *substream)
1199{
1200 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
1201 struct snd_soc_component *component;
1202 int i;
1203
1204 /* FIXME: use 1st pointer */
1205 for_each_rtd_components(rtd, i, component)
1206 if (component->driver->ack)
1207 return component->driver->ack(component, substream);
1208
1209 return 0;
1210}