blob: c1b799f984604ecf4c7f3054ac8276e486107bf5 [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 Morimoto4ff1fef2019-07-26 13:49:48 +090012#include <sound/soc.h>
13
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +090014#define soc_component_ret(dai, ret) _soc_component_ret(dai, __func__, ret)
15static inline int _soc_component_ret(struct snd_soc_component *component,
16 const char *func, int ret)
17{
18 /* Positive/Zero values are not errors */
19 if (ret >= 0)
20 return ret;
21
22 /* Negative values might be errors */
23 switch (ret) {
24 case -EPROBE_DEFER:
25 case -ENOTSUPP:
26 break;
27 default:
28 dev_err(component->dev,
29 "ASoC: error at %s on %s: %d\n",
30 func, component->name, ret);
31 }
32
33 return ret;
34}
35
Kuninori Morimoto536aba12020-06-04 17:06:32 +090036int snd_soc_component_initialize(struct snd_soc_component *component,
37 const struct snd_soc_component_driver *driver,
38 struct device *dev, const char *name)
39{
40 INIT_LIST_HEAD(&component->dai_list);
41 INIT_LIST_HEAD(&component->dobj_list);
42 INIT_LIST_HEAD(&component->card_list);
43 mutex_init(&component->io_mutex);
44
45 component->name = name;
46 component->dev = dev;
47 component->driver = driver;
48
49 return 0;
50}
51
Kuninori Morimoto257c4da2020-06-04 17:07:54 +090052void snd_soc_component_set_aux(struct snd_soc_component *component,
53 struct snd_soc_aux_dev *aux)
54{
55 component->init = (aux) ? aux->init : NULL;
56}
57
58int snd_soc_component_init(struct snd_soc_component *component)
59{
60 int ret = 0;
61
62 if (component->init)
63 ret = component->init(component);
64
65 return soc_component_ret(component, ret);
66}
67
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090068/**
69 * snd_soc_component_set_sysclk - configure COMPONENT system or master clock.
70 * @component: COMPONENT
71 * @clk_id: DAI specific clock ID
72 * @source: Source for the clock
73 * @freq: new clock frequency in Hz
74 * @dir: new clock direction - input/output.
75 *
76 * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
77 */
78int snd_soc_component_set_sysclk(struct snd_soc_component *component,
79 int clk_id, int source, unsigned int freq,
80 int dir)
81{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +090082 int ret = -ENOTSUPP;
83
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090084 if (component->driver->set_sysclk)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +090085 ret = component->driver->set_sysclk(component, clk_id, source,
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090086 freq, dir);
87
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +090088 return soc_component_ret(component, ret);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +090089}
90EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk);
91
92/*
93 * snd_soc_component_set_pll - configure component PLL.
94 * @component: COMPONENT
95 * @pll_id: DAI specific PLL ID
96 * @source: DAI specific source for the PLL
97 * @freq_in: PLL input clock frequency in Hz
98 * @freq_out: requested PLL output clock frequency in Hz
99 *
100 * Configures and enables PLL to generate output clock based on input clock.
101 */
102int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
103 int source, unsigned int freq_in,
104 unsigned int freq_out)
105{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900106 int ret = -EINVAL;
107
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900108 if (component->driver->set_pll)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900109 ret = component->driver->set_pll(component, pll_id, source,
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900110 freq_in, freq_out);
111
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900112 return soc_component_ret(component, ret);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900113}
114EXPORT_SYMBOL_GPL(snd_soc_component_set_pll);
115
Kuninori Morimoto9d415fb2019-07-26 13:51:35 +0900116void snd_soc_component_seq_notifier(struct snd_soc_component *component,
117 enum snd_soc_dapm_type type, int subseq)
118{
119 if (component->driver->seq_notifier)
120 component->driver->seq_notifier(component, type, subseq);
121}
122
Kuninori Morimoto8e2a9902019-07-26 13:51:39 +0900123int snd_soc_component_stream_event(struct snd_soc_component *component,
124 int event)
125{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900126 int ret = 0;
Kuninori Morimoto8e2a9902019-07-26 13:51:39 +0900127
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900128 if (component->driver->stream_event)
129 ret = component->driver->stream_event(component, event);
130
131 return soc_component_ret(component, ret);
Kuninori Morimoto8e2a9902019-07-26 13:51:39 +0900132}
133
Kuninori Morimoto7951b1462019-07-26 13:51:43 +0900134int snd_soc_component_set_bias_level(struct snd_soc_component *component,
135 enum snd_soc_bias_level level)
136{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900137 int ret = 0;
Kuninori Morimoto7951b1462019-07-26 13:51:43 +0900138
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900139 if (component->driver->set_bias_level)
140 ret = component->driver->set_bias_level(component, level);
141
142 return soc_component_ret(component, ret);
Kuninori Morimoto7951b1462019-07-26 13:51:43 +0900143}
144
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900145static int soc_component_pin(struct snd_soc_component *component,
146 const char *pin,
147 int (*pin_func)(struct snd_soc_dapm_context *dapm,
148 const char *pin))
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900149{
150 struct snd_soc_dapm_context *dapm =
151 snd_soc_component_get_dapm(component);
152 char *full_name;
153 int ret;
154
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900155 if (!component->name_prefix) {
156 ret = pin_func(dapm, pin);
157 goto end;
158 }
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900159
160 full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900161 if (!full_name) {
162 ret = -ENOMEM;
163 goto end;
164 }
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900165
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900166 ret = pin_func(dapm, full_name);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900167 kfree(full_name);
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900168end:
169 return soc_component_ret(component, ret);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900170}
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900171
172int snd_soc_component_enable_pin(struct snd_soc_component *component,
173 const char *pin)
174{
175 return soc_component_pin(component, pin, snd_soc_dapm_enable_pin);
176}
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900177EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin);
178
179int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component,
180 const char *pin)
181{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900182 return soc_component_pin(component, pin, snd_soc_dapm_enable_pin_unlocked);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900183}
184EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked);
185
186int snd_soc_component_disable_pin(struct snd_soc_component *component,
187 const char *pin)
188{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900189 return soc_component_pin(component, pin, snd_soc_dapm_disable_pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900190}
191EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin);
192
193int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
194 const char *pin)
195{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900196 return soc_component_pin(component, pin, snd_soc_dapm_disable_pin_unlocked);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900197}
198EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked);
199
200int snd_soc_component_nc_pin(struct snd_soc_component *component,
201 const char *pin)
202{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900203 return soc_component_pin(component, pin, snd_soc_dapm_nc_pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900204}
205EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin);
206
207int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
208 const char *pin)
209{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900210 return soc_component_pin(component, pin, snd_soc_dapm_nc_pin_unlocked);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900211}
212EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked);
213
214int snd_soc_component_get_pin_status(struct snd_soc_component *component,
215 const char *pin)
216{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900217 return soc_component_pin(component, pin, snd_soc_dapm_get_pin_status);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900218}
219EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status);
220
221int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
222 const char *pin)
223{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900224 return soc_component_pin(component, pin, snd_soc_dapm_force_enable_pin);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900225}
226EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin);
227
228int snd_soc_component_force_enable_pin_unlocked(
229 struct snd_soc_component *component,
230 const char *pin)
231{
Kuninori Morimoto4ca87012020-06-04 17:06:11 +0900232 return soc_component_pin(component, pin, snd_soc_dapm_force_enable_pin_unlocked);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900233}
234EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked);
235
236/**
237 * snd_soc_component_set_jack - configure component jack.
238 * @component: COMPONENTs
239 * @jack: structure to use for the jack
240 * @data: can be used if codec driver need extra data for configuring jack
241 *
242 * Configures and enables jack detection function.
243 */
244int snd_soc_component_set_jack(struct snd_soc_component *component,
245 struct snd_soc_jack *jack, void *data)
246{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900247 int ret = -ENOTSUPP;
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900248
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900249 if (component->driver->set_jack)
250 ret = component->driver->set_jack(component, jack, data);
251
252 return soc_component_ret(component, ret);
Kuninori Morimoto4ff1fef2019-07-26 13:49:48 +0900253}
254EXPORT_SYMBOL_GPL(snd_soc_component_set_jack);
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900255
256int snd_soc_component_module_get(struct snd_soc_component *component,
257 int upon_open)
258{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900259 int ret = 0;
260
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900261 if (component->driver->module_get_upon_open == !!upon_open &&
262 !try_module_get(component->dev->driver->owner))
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900263 ret = -ENODEV;
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900264
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900265 return soc_component_ret(component, ret);
Kuninori Morimoto4a81e8f2019-07-26 13:49:54 +0900266}
267
268void snd_soc_component_module_put(struct snd_soc_component *component,
269 int upon_open)
270{
271 if (component->driver->module_get_upon_open == !!upon_open)
272 module_put(component->dev->driver->owner);
273}
Kuninori Morimotoae2f4842019-07-26 13:50:01 +0900274
275int snd_soc_component_open(struct snd_soc_component *component,
276 struct snd_pcm_substream *substream)
277{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900278 int ret = 0;
279
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900280 if (component->driver->open)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900281 ret = component->driver->open(component, substream);
282
283 return soc_component_ret(component, ret);
Kuninori Morimotoae2f4842019-07-26 13:50:01 +0900284}
Kuninori Morimoto3672beb2019-07-26 13:50:07 +0900285
286int snd_soc_component_close(struct snd_soc_component *component,
287 struct snd_pcm_substream *substream)
288{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900289 int ret = 0;
290
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900291 if (component->driver->close)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900292 ret = component->driver->close(component, substream);
293
294 return soc_component_ret(component, ret);
Kuninori Morimoto3672beb2019-07-26 13:50:07 +0900295}
Kuninori Morimoto6d537232019-07-26 13:50:13 +0900296
Kuninori Morimoto66c51572019-07-26 13:50:34 +0900297void snd_soc_component_suspend(struct snd_soc_component *component)
298{
299 if (component->driver->suspend)
300 component->driver->suspend(component);
301 component->suspended = 1;
302}
Kuninori Morimoto9a840cb2019-07-26 13:51:08 +0900303
304void snd_soc_component_resume(struct snd_soc_component *component)
305{
306 if (component->driver->resume)
307 component->driver->resume(component);
308 component->suspended = 0;
309}
Kuninori Morimotoe40fadb2019-07-26 13:51:13 +0900310
311int snd_soc_component_is_suspended(struct snd_soc_component *component)
312{
313 return component->suspended;
314}
Kuninori Morimoto08e837d2019-07-26 13:51:17 +0900315
316int snd_soc_component_probe(struct snd_soc_component *component)
317{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900318 int ret = 0;
Kuninori Morimoto08e837d2019-07-26 13:51:17 +0900319
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900320 if (component->driver->probe)
321 ret = component->driver->probe(component);
322
323 return soc_component_ret(component, ret);
Kuninori Morimoto08e837d2019-07-26 13:51:17 +0900324}
Kuninori Morimoto03b34dd2019-07-26 13:51:22 +0900325
326void snd_soc_component_remove(struct snd_soc_component *component)
327{
328 if (component->driver->remove)
329 component->driver->remove(component);
330}
Kuninori Morimoto2c7b1702019-07-26 13:51:26 +0900331
332int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
333 struct device_node *ep)
334{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900335 int ret = -ENOTSUPP;
Kuninori Morimoto2c7b1702019-07-26 13:51:26 +0900336
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900337 if (component->driver->of_xlate_dai_id)
338 ret = component->driver->of_xlate_dai_id(component, ep);
339
340 return soc_component_ret(component, ret);
Kuninori Morimoto2c7b1702019-07-26 13:51:26 +0900341}
Kuninori Morimotoa2a34172019-07-26 13:51:31 +0900342
343int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
344 struct of_phandle_args *args,
345 const char **dai_name)
346{
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900347 int ret = -ENOTSUPP;
348
Kuninori Morimotoa2a34172019-07-26 13:51:31 +0900349 if (component->driver->of_xlate_dai_name)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900350 ret = component->driver->of_xlate_dai_name(component,
351 args, dai_name);
352
353 return soc_component_ret(component, ret);
Kuninori Morimotoa2a34172019-07-26 13:51:31 +0900354}
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900355
Kuninori Morimotoc7d75b52020-06-04 17:06:22 +0900356void snd_soc_component_setup_regmap(struct snd_soc_component *component)
357{
358 int val_bytes = regmap_get_val_bytes(component->regmap);
359
360 /* Errors are legitimate for non-integer byte multiples */
361 if (val_bytes > 0)
362 component->val_bytes = val_bytes;
363}
364
365#ifdef CONFIG_REGMAP
366
367/**
368 * snd_soc_component_init_regmap() - Initialize regmap instance for the
369 * component
370 * @component: The component for which to initialize the regmap instance
371 * @regmap: The regmap instance that should be used by the component
372 *
373 * This function allows deferred assignment of the regmap instance that is
374 * associated with the component. Only use this if the regmap instance is not
375 * yet ready when the component is registered. The function must also be called
376 * before the first IO attempt of the component.
377 */
378void snd_soc_component_init_regmap(struct snd_soc_component *component,
379 struct regmap *regmap)
380{
381 component->regmap = regmap;
382 snd_soc_component_setup_regmap(component);
383}
384EXPORT_SYMBOL_GPL(snd_soc_component_init_regmap);
385
386/**
387 * snd_soc_component_exit_regmap() - De-initialize regmap instance for the
388 * component
389 * @component: The component for which to de-initialize the regmap instance
390 *
391 * Calls regmap_exit() on the regmap instance associated to the component and
392 * removes the regmap instance from the component.
393 *
394 * This function should only be used if snd_soc_component_init_regmap() was used
395 * to initialize the regmap instance.
396 */
397void snd_soc_component_exit_regmap(struct snd_soc_component *component)
398{
399 regmap_exit(component->regmap);
400 component->regmap = NULL;
401}
402EXPORT_SYMBOL_GPL(snd_soc_component_exit_regmap);
403
404#endif
405
Kuninori Morimotoe8712312020-06-16 14:19:52 +0900406static unsigned int soc_component_read_no_lock(
407 struct snd_soc_component *component,
408 unsigned int reg)
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900409{
410 int ret;
Kuninori Morimotocf6e26c2020-06-16 14:19:41 +0900411 unsigned int val = 0;
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900412
413 if (component->regmap)
Kuninori Morimotocf6e26c2020-06-16 14:19:41 +0900414 ret = regmap_read(component->regmap, reg, &val);
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900415 else if (component->driver->read) {
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900416 ret = 0;
Kuninori Morimotocf6e26c2020-06-16 14:19:41 +0900417 val = component->driver->read(component, reg);
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900418 }
419 else
420 ret = -EIO;
421
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900422 if (ret < 0)
Kuninori Morimotocf6e26c2020-06-16 14:19:41 +0900423 soc_component_ret(component, ret);
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900424
425 return val;
426}
Kuninori Morimotoe8712312020-06-16 14:19:52 +0900427
428/**
429 * snd_soc_component_read() - Read register value
430 * @component: Component to read from
431 * @reg: Register to read
432 *
433 * Return: read value
434 */
435unsigned int snd_soc_component_read(struct snd_soc_component *component,
436 unsigned int reg)
437{
438 unsigned int val;
439
440 mutex_lock(&component->io_mutex);
441 val = soc_component_read_no_lock(component, reg);
442 mutex_unlock(&component->io_mutex);
443
444 return val;
445}
Kuninori Morimotocf6e26c2020-06-16 14:19:41 +0900446EXPORT_SYMBOL_GPL(snd_soc_component_read);
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900447
Kuninori Morimotoe8712312020-06-16 14:19:52 +0900448static int soc_component_write_no_lock(
449 struct snd_soc_component *component,
450 unsigned int reg, unsigned int val)
451{
452 int ret = -EIO;
453
454 if (component->regmap)
455 ret = regmap_write(component->regmap, reg, val);
456 else if (component->driver->write)
457 ret = component->driver->write(component, reg, val);
458
459 return soc_component_ret(component, ret);
460}
461
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900462/**
463 * snd_soc_component_write() - Write register value
464 * @component: Component to write to
465 * @reg: Register to write
466 * @val: Value to write to the register
467 *
468 * Return: 0 on success, a negative error code otherwise.
469 */
470int snd_soc_component_write(struct snd_soc_component *component,
471 unsigned int reg, unsigned int val)
472{
Kuninori Morimotoe8712312020-06-16 14:19:52 +0900473 int ret;
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900474
Kuninori Morimotoe8712312020-06-16 14:19:52 +0900475 mutex_lock(&component->io_mutex);
476 ret = soc_component_write_no_lock(component, reg, val);
477 mutex_unlock(&component->io_mutex);
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900478
Kuninori Morimotoe8712312020-06-16 14:19:52 +0900479 return ret;
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900480}
481EXPORT_SYMBOL_GPL(snd_soc_component_write);
482
483static int snd_soc_component_update_bits_legacy(
484 struct snd_soc_component *component, unsigned int reg,
485 unsigned int mask, unsigned int val, bool *change)
486{
487 unsigned int old, new;
Kuninori Morimotocf6e26c2020-06-16 14:19:41 +0900488 int ret = 0;
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900489
490 mutex_lock(&component->io_mutex);
491
Kuninori Morimotoe8712312020-06-16 14:19:52 +0900492 old = soc_component_read_no_lock(component, reg);
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900493
494 new = (old & ~mask) | (val & mask);
495 *change = old != new;
496 if (*change)
Kuninori Morimotoe8712312020-06-16 14:19:52 +0900497 ret = soc_component_write_no_lock(component, reg, new);
Kuninori Morimotocf6e26c2020-06-16 14:19:41 +0900498
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900499 mutex_unlock(&component->io_mutex);
500
501 return soc_component_ret(component, ret);
502}
503
504/**
505 * snd_soc_component_update_bits() - Perform read/modify/write cycle
506 * @component: Component to update
507 * @reg: Register to update
508 * @mask: Mask that specifies which bits to update
509 * @val: New value for the bits specified by mask
510 *
511 * Return: 1 if the operation was successful and the value of the register
512 * changed, 0 if the operation was successful, but the value did not change.
513 * Returns a negative error code otherwise.
514 */
515int snd_soc_component_update_bits(struct snd_soc_component *component,
516 unsigned int reg, unsigned int mask, unsigned int val)
517{
518 bool change;
519 int ret;
520
521 if (component->regmap)
522 ret = regmap_update_bits_check(component->regmap, reg, mask,
523 val, &change);
524 else
525 ret = snd_soc_component_update_bits_legacy(component, reg,
526 mask, val, &change);
527
528 if (ret < 0)
529 return soc_component_ret(component, ret);
530 return change;
531}
532EXPORT_SYMBOL_GPL(snd_soc_component_update_bits);
533
534/**
535 * snd_soc_component_update_bits_async() - Perform asynchronous
536 * read/modify/write cycle
537 * @component: Component to update
538 * @reg: Register to update
539 * @mask: Mask that specifies which bits to update
540 * @val: New value for the bits specified by mask
541 *
542 * This function is similar to snd_soc_component_update_bits(), but the update
543 * operation is scheduled asynchronously. This means it may not be completed
544 * when the function returns. To make sure that all scheduled updates have been
545 * completed snd_soc_component_async_complete() must be called.
546 *
547 * Return: 1 if the operation was successful and the value of the register
548 * changed, 0 if the operation was successful, but the value did not change.
549 * Returns a negative error code otherwise.
550 */
551int snd_soc_component_update_bits_async(struct snd_soc_component *component,
552 unsigned int reg, unsigned int mask, unsigned int val)
553{
554 bool change;
555 int ret;
556
557 if (component->regmap)
558 ret = regmap_update_bits_check_async(component->regmap, reg,
559 mask, val, &change);
560 else
561 ret = snd_soc_component_update_bits_legacy(component, reg,
562 mask, val, &change);
563
564 if (ret < 0)
565 return soc_component_ret(component, ret);
566 return change;
567}
568EXPORT_SYMBOL_GPL(snd_soc_component_update_bits_async);
569
570/**
571 * snd_soc_component_async_complete() - Ensure asynchronous I/O has completed
572 * @component: Component for which to wait
573 *
574 * This function blocks until all asynchronous I/O which has previously been
575 * scheduled using snd_soc_component_update_bits_async() has completed.
576 */
577void snd_soc_component_async_complete(struct snd_soc_component *component)
578{
579 if (component->regmap)
580 regmap_async_complete(component->regmap);
581}
582EXPORT_SYMBOL_GPL(snd_soc_component_async_complete);
583
584/**
585 * snd_soc_component_test_bits - Test register for change
586 * @component: component
587 * @reg: Register to test
588 * @mask: Mask that specifies which bits to test
589 * @value: Value to test against
590 *
591 * Tests a register with a new value and checks if the new value is
592 * different from the old value.
593 *
594 * Return: 1 for change, otherwise 0.
595 */
596int snd_soc_component_test_bits(struct snd_soc_component *component,
597 unsigned int reg, unsigned int mask, unsigned int value)
598{
599 unsigned int old, new;
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900600
Kuninori Morimotocf6e26c2020-06-16 14:19:41 +0900601 old = snd_soc_component_read(component, reg);
Kuninori Morimoto460b42d2020-06-04 17:08:03 +0900602 new = (old & ~mask) | value;
603 return old != new;
604}
605EXPORT_SYMBOL_GPL(snd_soc_component_test_bits);
606
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900607int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
608{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +0900609 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900610 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900611 int i;
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900612
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900613 /* FIXME: use 1st pointer */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900614 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900615 if (component->driver->pointer)
616 return component->driver->pointer(component, substream);
Kuninori Morimoto0035e252019-07-26 13:51:47 +0900617
618 return 0;
619}
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900620
621int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
622 unsigned int cmd, void *arg)
623{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +0900624 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900625 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900626 int i;
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900627
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900628 /* FIXME: use 1st ioctl */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900629 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900630 if (component->driver->ioctl)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900631 return soc_component_ret(
632 component,
633 component->driver->ioctl(component,
634 substream, cmd, arg));
Kuninori Morimoto96a47902019-07-26 13:51:51 +0900635
636 return snd_pcm_lib_ioctl(substream, cmd, arg);
637}
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900638
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100639int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream)
640{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +0900641 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100642 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900643 int i, ret;
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100644
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900645 for_each_rtd_components(rtd, i, component) {
Kuninori Morimotof1861a72020-02-28 10:48:35 +0900646 if (component->driver->sync_stop) {
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100647 ret = component->driver->sync_stop(component,
648 substream);
649 if (ret < 0)
Shengjiu Wangbe75db52020-07-16 13:07:08 +0800650 return soc_component_ret(component, ret);
Takashi Iwai1e5ddb62019-11-21 20:07:09 +0100651 }
652 }
653
654 return 0;
655}
656
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900657int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
658 int channel, unsigned long pos,
659 void __user *buf, unsigned long bytes)
660{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +0900661 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900662 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900663 int i;
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900664
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900665 /* FIXME. it returns 1st copy now */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900666 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900667 if (component->driver->copy_user)
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900668 return soc_component_ret(
669 component,
670 component->driver->copy_user(
671 component, substream, channel,
672 pos, buf, bytes));
Kuninori Morimoto82d81f52019-07-26 13:51:56 +0900673
674 return -EINVAL;
675}
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900676
677struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
678 unsigned long offset)
679{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +0900680 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900681 struct snd_soc_component *component;
682 struct page *page;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900683 int i;
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900684
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900685 /* FIXME. it returns 1st page now */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900686 for_each_rtd_components(rtd, i, component) {
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900687 if (component->driver->page) {
688 page = component->driver->page(component,
689 substream, offset);
690 if (page)
691 return page;
692 }
Kuninori Morimoto9c712e42019-07-26 13:52:00 +0900693 }
694
695 return NULL;
696}
Kuninori Morimoto205875e2019-07-26 13:52:04 +0900697
698int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
699 struct vm_area_struct *vma)
700{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +0900701 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Kuninori Morimoto205875e2019-07-26 13:52:04 +0900702 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900703 int i;
Kuninori Morimoto205875e2019-07-26 13:52:04 +0900704
Kuninori Morimoto2b544dd2019-10-15 12:59:31 +0900705 /* FIXME. it returns 1st mmap now */
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900706 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoe2cb4a12019-10-02 14:30:48 +0900707 if (component->driver->mmap)
Shengjiu Wangbe75db52020-07-16 13:07:08 +0800708 return soc_component_ret(
Kuninori Morimotoe2329ee2020-06-04 17:06:41 +0900709 component,
710 component->driver->mmap(component,
711 substream, vma));
Kuninori Morimoto205875e2019-07-26 13:52:04 +0900712
713 return -EINVAL;
714}
Kuninori Morimoto74842912019-07-26 13:52:08 +0900715
Kuninori Morimotob2b2afb2019-11-18 10:50:32 +0900716int snd_soc_pcm_component_new(struct snd_soc_pcm_runtime *rtd)
Kuninori Morimoto74842912019-07-26 13:52:08 +0900717{
Kuninori Morimoto74842912019-07-26 13:52:08 +0900718 struct snd_soc_component *component;
719 int ret;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900720 int i;
Kuninori Morimoto74842912019-07-26 13:52:08 +0900721
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900722 for_each_rtd_components(rtd, i, component) {
Kuninori Morimotoc64bfc92019-10-02 14:30:59 +0900723 if (component->driver->pcm_construct) {
724 ret = component->driver->pcm_construct(component, rtd);
725 if (ret < 0)
Shengjiu Wangbe75db52020-07-16 13:07:08 +0800726 return soc_component_ret(component, ret);
Kuninori Morimotoc64bfc92019-10-02 14:30:59 +0900727 }
Kuninori Morimoto74842912019-07-26 13:52:08 +0900728 }
729
730 return 0;
731}
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900732
Kuninori Morimotob2b2afb2019-11-18 10:50:32 +0900733void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd)
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900734{
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900735 struct snd_soc_component *component;
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900736 int i;
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900737
Takashi Iwai8e3366c2020-01-07 08:09:56 +0100738 if (!rtd->pcm)
739 return;
740
Kuninori Morimoto613fb502020-01-10 11:35:21 +0900741 for_each_rtd_components(rtd, i, component)
Kuninori Morimotoc64bfc92019-10-02 14:30:59 +0900742 if (component->driver->pcm_destruct)
Kuninori Morimotob2b2afb2019-11-18 10:50:32 +0900743 component->driver->pcm_destruct(component, rtd->pcm);
Kuninori Morimoto79776da2019-07-26 13:52:12 +0900744}
Kuninori Morimoto4f395142020-06-04 17:06:58 +0900745
746int snd_soc_pcm_component_prepare(struct snd_pcm_substream *substream)
747{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +0900748 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Kuninori Morimoto4f395142020-06-04 17:06:58 +0900749 struct snd_soc_component *component;
750 int i, ret;
751
752 for_each_rtd_components(rtd, i, component) {
753 if (component->driver->prepare) {
754 ret = component->driver->prepare(component, substream);
755 if (ret < 0)
756 return soc_component_ret(component, ret);
757 }
758 }
759
760 return 0;
761}
Kuninori Morimotoe1bafa82020-06-04 17:07:11 +0900762
763int snd_soc_pcm_component_hw_params(struct snd_pcm_substream *substream,
764 struct snd_pcm_hw_params *params,
765 struct snd_soc_component **last)
766{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +0900767 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Kuninori Morimotoe1bafa82020-06-04 17:07:11 +0900768 struct snd_soc_component *component;
769 int i, ret;
770
771 for_each_rtd_components(rtd, i, component) {
772 if (component->driver->hw_params) {
773 ret = component->driver->hw_params(component,
774 substream, params);
775 if (ret < 0) {
776 *last = component;
777 return soc_component_ret(component, ret);
778 }
779 }
780 }
781
782 *last = NULL;
783 return 0;
784}
Kuninori Morimoto04751112020-06-04 17:07:24 +0900785
786void snd_soc_pcm_component_hw_free(struct snd_pcm_substream *substream,
787 struct snd_soc_component *last)
788{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +0900789 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Kuninori Morimoto04751112020-06-04 17:07:24 +0900790 struct snd_soc_component *component;
791 int i, ret;
792
793 for_each_rtd_components(rtd, i, component) {
794 if (component == last)
795 break;
796
797 if (component->driver->hw_free) {
798 ret = component->driver->hw_free(component, substream);
799 if (ret < 0)
800 soc_component_ret(component, ret);
801 }
802 }
803}
Kuninori Morimoto32fd1202020-06-04 17:07:40 +0900804
805int snd_soc_pcm_component_trigger(struct snd_pcm_substream *substream,
806 int cmd)
807{
Kuninori Morimoto0ceef682020-07-20 10:17:39 +0900808 struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
Kuninori Morimoto32fd1202020-06-04 17:07:40 +0900809 struct snd_soc_component *component;
810 int i, ret;
811
812 for_each_rtd_components(rtd, i, component) {
813 if (component->driver->trigger) {
814 ret = component->driver->trigger(component, substream, cmd);
815 if (ret < 0)
816 return soc_component_ret(component, ret);
817 }
818 }
819
820 return 0;
821}