xref: /openbmc/linux/sound/soc/soc-component.c (revision cc4d8ceb)
14ff1fef1SKuninori Morimoto // SPDX-License-Identifier: GPL-2.0
24ff1fef1SKuninori Morimoto //
34ff1fef1SKuninori Morimoto // soc-component.c
44ff1fef1SKuninori Morimoto //
5460b42d1SKuninori Morimoto // Copyright 2009-2011 Wolfson Microelectronics PLC.
64ff1fef1SKuninori Morimoto // Copyright (C) 2019 Renesas Electronics Corp.
7460b42d1SKuninori Morimoto //
8460b42d1SKuninori Morimoto // Mark Brown <broonie@opensource.wolfsonmicro.com>
94ff1fef1SKuninori Morimoto // Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
104ff1fef1SKuninori Morimoto //
114a81e8f3SKuninori Morimoto #include <linux/module.h>
124ff1fef1SKuninori Morimoto #include <sound/soc.h>
134ff1fef1SKuninori Morimoto 
14e2329eebSKuninori Morimoto #define soc_component_ret(dai, ret) _soc_component_ret(dai, __func__, ret)
15e2329eebSKuninori Morimoto static inline int _soc_component_ret(struct snd_soc_component *component,
16e2329eebSKuninori Morimoto 				     const char *func, int ret)
17e2329eebSKuninori Morimoto {
18e2329eebSKuninori Morimoto 	/* Positive/Zero values are not errors */
19e2329eebSKuninori Morimoto 	if (ret >= 0)
20e2329eebSKuninori Morimoto 		return ret;
21e2329eebSKuninori Morimoto 
22e2329eebSKuninori Morimoto 	/* Negative values might be errors */
23e2329eebSKuninori Morimoto 	switch (ret) {
24e2329eebSKuninori Morimoto 	case -EPROBE_DEFER:
25e2329eebSKuninori Morimoto 	case -ENOTSUPP:
26e2329eebSKuninori Morimoto 		break;
27e2329eebSKuninori Morimoto 	default:
28e2329eebSKuninori Morimoto 		dev_err(component->dev,
29e2329eebSKuninori Morimoto 			"ASoC: error at %s on %s: %d\n",
30e2329eebSKuninori Morimoto 			func, component->name, ret);
31e2329eebSKuninori Morimoto 	}
32e2329eebSKuninori Morimoto 
33e2329eebSKuninori Morimoto 	return ret;
34e2329eebSKuninori Morimoto }
35e2329eebSKuninori Morimoto 
36536aba1dSKuninori Morimoto int snd_soc_component_initialize(struct snd_soc_component *component,
37536aba1dSKuninori Morimoto 				 const struct snd_soc_component_driver *driver,
38536aba1dSKuninori Morimoto 				 struct device *dev, const char *name)
39536aba1dSKuninori Morimoto {
40536aba1dSKuninori Morimoto 	INIT_LIST_HEAD(&component->dai_list);
41536aba1dSKuninori Morimoto 	INIT_LIST_HEAD(&component->dobj_list);
42536aba1dSKuninori Morimoto 	INIT_LIST_HEAD(&component->card_list);
43536aba1dSKuninori Morimoto 	mutex_init(&component->io_mutex);
44536aba1dSKuninori Morimoto 
45536aba1dSKuninori Morimoto 	component->name		= name;
46536aba1dSKuninori Morimoto 	component->dev		= dev;
47536aba1dSKuninori Morimoto 	component->driver	= driver;
48536aba1dSKuninori Morimoto 
49536aba1dSKuninori Morimoto 	return 0;
50536aba1dSKuninori Morimoto }
51536aba1dSKuninori Morimoto 
52257c4dacSKuninori Morimoto void snd_soc_component_set_aux(struct snd_soc_component *component,
53257c4dacSKuninori Morimoto 			       struct snd_soc_aux_dev *aux)
54257c4dacSKuninori Morimoto {
55257c4dacSKuninori Morimoto 	component->init = (aux) ? aux->init : NULL;
56257c4dacSKuninori Morimoto }
57257c4dacSKuninori Morimoto 
58257c4dacSKuninori Morimoto int snd_soc_component_init(struct snd_soc_component *component)
59257c4dacSKuninori Morimoto {
60257c4dacSKuninori Morimoto 	int ret = 0;
61257c4dacSKuninori Morimoto 
62257c4dacSKuninori Morimoto 	if (component->init)
63257c4dacSKuninori Morimoto 		ret = component->init(component);
64257c4dacSKuninori Morimoto 
65257c4dacSKuninori Morimoto 	return soc_component_ret(component, ret);
66257c4dacSKuninori Morimoto }
67257c4dacSKuninori Morimoto 
684ff1fef1SKuninori Morimoto /**
694ff1fef1SKuninori Morimoto  * snd_soc_component_set_sysclk - configure COMPONENT system or master clock.
704ff1fef1SKuninori Morimoto  * @component: COMPONENT
714ff1fef1SKuninori Morimoto  * @clk_id: DAI specific clock ID
724ff1fef1SKuninori Morimoto  * @source: Source for the clock
734ff1fef1SKuninori Morimoto  * @freq: new clock frequency in Hz
744ff1fef1SKuninori Morimoto  * @dir: new clock direction - input/output.
754ff1fef1SKuninori Morimoto  *
764ff1fef1SKuninori Morimoto  * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
774ff1fef1SKuninori Morimoto  */
784ff1fef1SKuninori Morimoto int snd_soc_component_set_sysclk(struct snd_soc_component *component,
794ff1fef1SKuninori Morimoto 				 int clk_id, int source, unsigned int freq,
804ff1fef1SKuninori Morimoto 				 int dir)
814ff1fef1SKuninori Morimoto {
82e2329eebSKuninori Morimoto 	int ret = -ENOTSUPP;
83e2329eebSKuninori Morimoto 
844ff1fef1SKuninori Morimoto 	if (component->driver->set_sysclk)
85e2329eebSKuninori Morimoto 		ret = component->driver->set_sysclk(component, clk_id, source,
864ff1fef1SKuninori Morimoto 						     freq, dir);
874ff1fef1SKuninori Morimoto 
88e2329eebSKuninori Morimoto 	return soc_component_ret(component, ret);
894ff1fef1SKuninori Morimoto }
904ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk);
914ff1fef1SKuninori Morimoto 
924ff1fef1SKuninori Morimoto /*
934ff1fef1SKuninori Morimoto  * snd_soc_component_set_pll - configure component PLL.
944ff1fef1SKuninori Morimoto  * @component: COMPONENT
954ff1fef1SKuninori Morimoto  * @pll_id: DAI specific PLL ID
964ff1fef1SKuninori Morimoto  * @source: DAI specific source for the PLL
974ff1fef1SKuninori Morimoto  * @freq_in: PLL input clock frequency in Hz
984ff1fef1SKuninori Morimoto  * @freq_out: requested PLL output clock frequency in Hz
994ff1fef1SKuninori Morimoto  *
1004ff1fef1SKuninori Morimoto  * Configures and enables PLL to generate output clock based on input clock.
1014ff1fef1SKuninori Morimoto  */
1024ff1fef1SKuninori Morimoto int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
1034ff1fef1SKuninori Morimoto 			      int source, unsigned int freq_in,
1044ff1fef1SKuninori Morimoto 			      unsigned int freq_out)
1054ff1fef1SKuninori Morimoto {
106e2329eebSKuninori Morimoto 	int ret = -EINVAL;
107e2329eebSKuninori Morimoto 
1084ff1fef1SKuninori Morimoto 	if (component->driver->set_pll)
109e2329eebSKuninori Morimoto 		ret = component->driver->set_pll(component, pll_id, source,
1104ff1fef1SKuninori Morimoto 						  freq_in, freq_out);
1114ff1fef1SKuninori Morimoto 
112e2329eebSKuninori Morimoto 	return soc_component_ret(component, ret);
1134ff1fef1SKuninori Morimoto }
1144ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_set_pll);
1154ff1fef1SKuninori Morimoto 
1169d415fbfSKuninori Morimoto void snd_soc_component_seq_notifier(struct snd_soc_component *component,
1179d415fbfSKuninori Morimoto 				    enum snd_soc_dapm_type type, int subseq)
1189d415fbfSKuninori Morimoto {
1199d415fbfSKuninori Morimoto 	if (component->driver->seq_notifier)
1209d415fbfSKuninori Morimoto 		component->driver->seq_notifier(component, type, subseq);
1219d415fbfSKuninori Morimoto }
1229d415fbfSKuninori Morimoto 
1238e2a990dSKuninori Morimoto int snd_soc_component_stream_event(struct snd_soc_component *component,
1248e2a990dSKuninori Morimoto 				   int event)
1258e2a990dSKuninori Morimoto {
126e2329eebSKuninori Morimoto 	int ret = 0;
1278e2a990dSKuninori Morimoto 
128e2329eebSKuninori Morimoto 	if (component->driver->stream_event)
129e2329eebSKuninori Morimoto 		ret = component->driver->stream_event(component, event);
130e2329eebSKuninori Morimoto 
131e2329eebSKuninori Morimoto 	return soc_component_ret(component, ret);
1328e2a990dSKuninori Morimoto }
1338e2a990dSKuninori Morimoto 
1347951b146SKuninori Morimoto int snd_soc_component_set_bias_level(struct snd_soc_component *component,
1357951b146SKuninori Morimoto 				     enum snd_soc_bias_level level)
1367951b146SKuninori Morimoto {
137e2329eebSKuninori Morimoto 	int ret = 0;
1387951b146SKuninori Morimoto 
139e2329eebSKuninori Morimoto 	if (component->driver->set_bias_level)
140e2329eebSKuninori Morimoto 		ret = component->driver->set_bias_level(component, level);
141e2329eebSKuninori Morimoto 
142e2329eebSKuninori Morimoto 	return soc_component_ret(component, ret);
1437951b146SKuninori Morimoto }
1447951b146SKuninori Morimoto 
1454ca8701eSKuninori Morimoto static int soc_component_pin(struct snd_soc_component *component,
1464ca8701eSKuninori Morimoto 			     const char *pin,
1474ca8701eSKuninori Morimoto 			     int (*pin_func)(struct snd_soc_dapm_context *dapm,
1484ca8701eSKuninori Morimoto 					     const char *pin))
1494ff1fef1SKuninori Morimoto {
1504ff1fef1SKuninori Morimoto 	struct snd_soc_dapm_context *dapm =
1514ff1fef1SKuninori Morimoto 		snd_soc_component_get_dapm(component);
1524ff1fef1SKuninori Morimoto 	char *full_name;
1534ff1fef1SKuninori Morimoto 	int ret;
1544ff1fef1SKuninori Morimoto 
155e2329eebSKuninori Morimoto 	if (!component->name_prefix) {
156e2329eebSKuninori Morimoto 		ret = pin_func(dapm, pin);
157e2329eebSKuninori Morimoto 		goto end;
158e2329eebSKuninori Morimoto 	}
1594ff1fef1SKuninori Morimoto 
1604ff1fef1SKuninori Morimoto 	full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
161e2329eebSKuninori Morimoto 	if (!full_name) {
162e2329eebSKuninori Morimoto 		ret = -ENOMEM;
163e2329eebSKuninori Morimoto 		goto end;
164e2329eebSKuninori Morimoto 	}
1654ff1fef1SKuninori Morimoto 
1664ca8701eSKuninori Morimoto 	ret = pin_func(dapm, full_name);
1674ff1fef1SKuninori Morimoto 	kfree(full_name);
168e2329eebSKuninori Morimoto end:
169e2329eebSKuninori Morimoto 	return soc_component_ret(component, ret);
1704ff1fef1SKuninori Morimoto }
1714ca8701eSKuninori Morimoto 
1724ca8701eSKuninori Morimoto int snd_soc_component_enable_pin(struct snd_soc_component *component,
1734ca8701eSKuninori Morimoto 				 const char *pin)
1744ca8701eSKuninori Morimoto {
1754ca8701eSKuninori Morimoto 	return soc_component_pin(component, pin, snd_soc_dapm_enable_pin);
1764ca8701eSKuninori Morimoto }
1774ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin);
1784ff1fef1SKuninori Morimoto 
1794ff1fef1SKuninori Morimoto int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component,
1804ff1fef1SKuninori Morimoto 					  const char *pin)
1814ff1fef1SKuninori Morimoto {
1824ca8701eSKuninori Morimoto 	return soc_component_pin(component, pin, snd_soc_dapm_enable_pin_unlocked);
1834ff1fef1SKuninori Morimoto }
1844ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked);
1854ff1fef1SKuninori Morimoto 
1864ff1fef1SKuninori Morimoto int snd_soc_component_disable_pin(struct snd_soc_component *component,
1874ff1fef1SKuninori Morimoto 				  const char *pin)
1884ff1fef1SKuninori Morimoto {
1894ca8701eSKuninori Morimoto 	return soc_component_pin(component, pin, snd_soc_dapm_disable_pin);
1904ff1fef1SKuninori Morimoto }
1914ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin);
1924ff1fef1SKuninori Morimoto 
1934ff1fef1SKuninori Morimoto int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
1944ff1fef1SKuninori Morimoto 					   const char *pin)
1954ff1fef1SKuninori Morimoto {
1964ca8701eSKuninori Morimoto 	return soc_component_pin(component, pin, snd_soc_dapm_disable_pin_unlocked);
1974ff1fef1SKuninori Morimoto }
1984ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked);
1994ff1fef1SKuninori Morimoto 
2004ff1fef1SKuninori Morimoto int snd_soc_component_nc_pin(struct snd_soc_component *component,
2014ff1fef1SKuninori Morimoto 			     const char *pin)
2024ff1fef1SKuninori Morimoto {
2034ca8701eSKuninori Morimoto 	return soc_component_pin(component, pin, snd_soc_dapm_nc_pin);
2044ff1fef1SKuninori Morimoto }
2054ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin);
2064ff1fef1SKuninori Morimoto 
2074ff1fef1SKuninori Morimoto int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
2084ff1fef1SKuninori Morimoto 				      const char *pin)
2094ff1fef1SKuninori Morimoto {
2104ca8701eSKuninori Morimoto 	return soc_component_pin(component, pin, snd_soc_dapm_nc_pin_unlocked);
2114ff1fef1SKuninori Morimoto }
2124ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked);
2134ff1fef1SKuninori Morimoto 
2144ff1fef1SKuninori Morimoto int snd_soc_component_get_pin_status(struct snd_soc_component *component,
2154ff1fef1SKuninori Morimoto 				     const char *pin)
2164ff1fef1SKuninori Morimoto {
2174ca8701eSKuninori Morimoto 	return soc_component_pin(component, pin, snd_soc_dapm_get_pin_status);
2184ff1fef1SKuninori Morimoto }
2194ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status);
2204ff1fef1SKuninori Morimoto 
2214ff1fef1SKuninori Morimoto int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
2224ff1fef1SKuninori Morimoto 				       const char *pin)
2234ff1fef1SKuninori Morimoto {
2244ca8701eSKuninori Morimoto 	return soc_component_pin(component, pin, snd_soc_dapm_force_enable_pin);
2254ff1fef1SKuninori Morimoto }
2264ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin);
2274ff1fef1SKuninori Morimoto 
2284ff1fef1SKuninori Morimoto int snd_soc_component_force_enable_pin_unlocked(
2294ff1fef1SKuninori Morimoto 	struct snd_soc_component *component,
2304ff1fef1SKuninori Morimoto 	const char *pin)
2314ff1fef1SKuninori Morimoto {
2324ca8701eSKuninori Morimoto 	return soc_component_pin(component, pin, snd_soc_dapm_force_enable_pin_unlocked);
2334ff1fef1SKuninori Morimoto }
2344ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked);
2354ff1fef1SKuninori Morimoto 
2364ff1fef1SKuninori Morimoto /**
2374ff1fef1SKuninori Morimoto  * snd_soc_component_set_jack - configure component jack.
2384ff1fef1SKuninori Morimoto  * @component: COMPONENTs
2394ff1fef1SKuninori Morimoto  * @jack: structure to use for the jack
2404ff1fef1SKuninori Morimoto  * @data: can be used if codec driver need extra data for configuring jack
2414ff1fef1SKuninori Morimoto  *
2424ff1fef1SKuninori Morimoto  * Configures and enables jack detection function.
2434ff1fef1SKuninori Morimoto  */
2444ff1fef1SKuninori Morimoto int snd_soc_component_set_jack(struct snd_soc_component *component,
2454ff1fef1SKuninori Morimoto 			       struct snd_soc_jack *jack, void *data)
2464ff1fef1SKuninori Morimoto {
247e2329eebSKuninori Morimoto 	int ret = -ENOTSUPP;
2484ff1fef1SKuninori Morimoto 
249e2329eebSKuninori Morimoto 	if (component->driver->set_jack)
250e2329eebSKuninori Morimoto 		ret = component->driver->set_jack(component, jack, data);
251e2329eebSKuninori Morimoto 
252e2329eebSKuninori Morimoto 	return soc_component_ret(component, ret);
2534ff1fef1SKuninori Morimoto }
2544ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_set_jack);
2554a81e8f3SKuninori Morimoto 
2564a81e8f3SKuninori Morimoto int snd_soc_component_module_get(struct snd_soc_component *component,
2574a81e8f3SKuninori Morimoto 				 int upon_open)
2584a81e8f3SKuninori Morimoto {
259e2329eebSKuninori Morimoto 	int ret = 0;
260e2329eebSKuninori Morimoto 
2614a81e8f3SKuninori Morimoto 	if (component->driver->module_get_upon_open == !!upon_open &&
2624a81e8f3SKuninori Morimoto 	    !try_module_get(component->dev->driver->owner))
263e2329eebSKuninori Morimoto 		ret = -ENODEV;
2644a81e8f3SKuninori Morimoto 
265e2329eebSKuninori Morimoto 	return soc_component_ret(component, ret);
2664a81e8f3SKuninori Morimoto }
2674a81e8f3SKuninori Morimoto 
2684a81e8f3SKuninori Morimoto void snd_soc_component_module_put(struct snd_soc_component *component,
2694a81e8f3SKuninori Morimoto 				  int upon_open)
2704a81e8f3SKuninori Morimoto {
2714a81e8f3SKuninori Morimoto 	if (component->driver->module_get_upon_open == !!upon_open)
2724a81e8f3SKuninori Morimoto 		module_put(component->dev->driver->owner);
2734a81e8f3SKuninori Morimoto }
274ae2f4849SKuninori Morimoto 
275ae2f4849SKuninori Morimoto int snd_soc_component_open(struct snd_soc_component *component,
276ae2f4849SKuninori Morimoto 			   struct snd_pcm_substream *substream)
277ae2f4849SKuninori Morimoto {
278e2329eebSKuninori Morimoto 	int ret = 0;
279e2329eebSKuninori Morimoto 
280e2cb4a14SKuninori Morimoto 	if (component->driver->open)
281e2329eebSKuninori Morimoto 		ret = component->driver->open(component, substream);
282e2329eebSKuninori Morimoto 
283e2329eebSKuninori Morimoto 	return soc_component_ret(component, ret);
284ae2f4849SKuninori Morimoto }
2853672beb8SKuninori Morimoto 
2863672beb8SKuninori Morimoto int snd_soc_component_close(struct snd_soc_component *component,
2873672beb8SKuninori Morimoto 			    struct snd_pcm_substream *substream)
2883672beb8SKuninori Morimoto {
289e2329eebSKuninori Morimoto 	int ret = 0;
290e2329eebSKuninori Morimoto 
291e2cb4a14SKuninori Morimoto 	if (component->driver->close)
292e2329eebSKuninori Morimoto 		ret = component->driver->close(component, substream);
293e2329eebSKuninori Morimoto 
294e2329eebSKuninori Morimoto 	return soc_component_ret(component, ret);
2953672beb8SKuninori Morimoto }
2966d537233SKuninori Morimoto 
29766c51573SKuninori Morimoto void snd_soc_component_suspend(struct snd_soc_component *component)
29866c51573SKuninori Morimoto {
29966c51573SKuninori Morimoto 	if (component->driver->suspend)
30066c51573SKuninori Morimoto 		component->driver->suspend(component);
30166c51573SKuninori Morimoto 	component->suspended = 1;
30266c51573SKuninori Morimoto }
3039a840cbaSKuninori Morimoto 
3049a840cbaSKuninori Morimoto void snd_soc_component_resume(struct snd_soc_component *component)
3059a840cbaSKuninori Morimoto {
3069a840cbaSKuninori Morimoto 	if (component->driver->resume)
3079a840cbaSKuninori Morimoto 		component->driver->resume(component);
3089a840cbaSKuninori Morimoto 	component->suspended = 0;
3099a840cbaSKuninori Morimoto }
310e40fadbcSKuninori Morimoto 
311e40fadbcSKuninori Morimoto int snd_soc_component_is_suspended(struct snd_soc_component *component)
312e40fadbcSKuninori Morimoto {
313e40fadbcSKuninori Morimoto 	return component->suspended;
314e40fadbcSKuninori Morimoto }
31508e837ddSKuninori Morimoto 
31608e837ddSKuninori Morimoto int snd_soc_component_probe(struct snd_soc_component *component)
31708e837ddSKuninori Morimoto {
318e2329eebSKuninori Morimoto 	int ret = 0;
31908e837ddSKuninori Morimoto 
320e2329eebSKuninori Morimoto 	if (component->driver->probe)
321e2329eebSKuninori Morimoto 		ret = component->driver->probe(component);
322e2329eebSKuninori Morimoto 
323e2329eebSKuninori Morimoto 	return soc_component_ret(component, ret);
32408e837ddSKuninori Morimoto }
32503b34dd7SKuninori Morimoto 
32603b34dd7SKuninori Morimoto void snd_soc_component_remove(struct snd_soc_component *component)
32703b34dd7SKuninori Morimoto {
32803b34dd7SKuninori Morimoto 	if (component->driver->remove)
32903b34dd7SKuninori Morimoto 		component->driver->remove(component);
33003b34dd7SKuninori Morimoto }
3312c7b1704SKuninori Morimoto 
3322c7b1704SKuninori Morimoto int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
3332c7b1704SKuninori Morimoto 				      struct device_node *ep)
3342c7b1704SKuninori Morimoto {
335e2329eebSKuninori Morimoto 	int ret = -ENOTSUPP;
3362c7b1704SKuninori Morimoto 
337e2329eebSKuninori Morimoto 	if (component->driver->of_xlate_dai_id)
338e2329eebSKuninori Morimoto 		ret = component->driver->of_xlate_dai_id(component, ep);
339e2329eebSKuninori Morimoto 
340e2329eebSKuninori Morimoto 	return soc_component_ret(component, ret);
3412c7b1704SKuninori Morimoto }
342a2a34175SKuninori Morimoto 
343a2a34175SKuninori Morimoto int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
344a2a34175SKuninori Morimoto 					struct of_phandle_args *args,
345a2a34175SKuninori Morimoto 					const char **dai_name)
346a2a34175SKuninori Morimoto {
347a2a34175SKuninori Morimoto 	if (component->driver->of_xlate_dai_name)
348cc4d8cebSJerome Brunet 		return component->driver->of_xlate_dai_name(component,
349a2a34175SKuninori Morimoto 							    args, dai_name);
350cc4d8cebSJerome Brunet 	/*
351cc4d8cebSJerome Brunet 	 * Don't use soc_component_ret here because we may not want to report
352cc4d8cebSJerome Brunet 	 * the error just yet. If a device has more than one component, the
353cc4d8cebSJerome Brunet 	 * first may not match and we don't want spam the log with this.
354cc4d8cebSJerome Brunet 	 */
355cc4d8cebSJerome Brunet 	return -ENOTSUPP;
356a2a34175SKuninori Morimoto }
3570035e256SKuninori Morimoto 
358c7d75b59SKuninori Morimoto void snd_soc_component_setup_regmap(struct snd_soc_component *component)
359c7d75b59SKuninori Morimoto {
360c7d75b59SKuninori Morimoto 	int val_bytes = regmap_get_val_bytes(component->regmap);
361c7d75b59SKuninori Morimoto 
362c7d75b59SKuninori Morimoto 	/* Errors are legitimate for non-integer byte multiples */
363c7d75b59SKuninori Morimoto 	if (val_bytes > 0)
364c7d75b59SKuninori Morimoto 		component->val_bytes = val_bytes;
365c7d75b59SKuninori Morimoto }
366c7d75b59SKuninori Morimoto 
367c7d75b59SKuninori Morimoto #ifdef CONFIG_REGMAP
368c7d75b59SKuninori Morimoto 
369c7d75b59SKuninori Morimoto /**
370c7d75b59SKuninori Morimoto  * snd_soc_component_init_regmap() - Initialize regmap instance for the
371c7d75b59SKuninori Morimoto  *                                   component
372c7d75b59SKuninori Morimoto  * @component: The component for which to initialize the regmap instance
373c7d75b59SKuninori Morimoto  * @regmap: The regmap instance that should be used by the component
374c7d75b59SKuninori Morimoto  *
375c7d75b59SKuninori Morimoto  * This function allows deferred assignment of the regmap instance that is
376c7d75b59SKuninori Morimoto  * associated with the component. Only use this if the regmap instance is not
377c7d75b59SKuninori Morimoto  * yet ready when the component is registered. The function must also be called
378c7d75b59SKuninori Morimoto  * before the first IO attempt of the component.
379c7d75b59SKuninori Morimoto  */
380c7d75b59SKuninori Morimoto void snd_soc_component_init_regmap(struct snd_soc_component *component,
381c7d75b59SKuninori Morimoto 				   struct regmap *regmap)
382c7d75b59SKuninori Morimoto {
383c7d75b59SKuninori Morimoto 	component->regmap = regmap;
384c7d75b59SKuninori Morimoto 	snd_soc_component_setup_regmap(component);
385c7d75b59SKuninori Morimoto }
386c7d75b59SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_init_regmap);
387c7d75b59SKuninori Morimoto 
388c7d75b59SKuninori Morimoto /**
389c7d75b59SKuninori Morimoto  * snd_soc_component_exit_regmap() - De-initialize regmap instance for the
390c7d75b59SKuninori Morimoto  *                                   component
391c7d75b59SKuninori Morimoto  * @component: The component for which to de-initialize the regmap instance
392c7d75b59SKuninori Morimoto  *
393c7d75b59SKuninori Morimoto  * Calls regmap_exit() on the regmap instance associated to the component and
394c7d75b59SKuninori Morimoto  * removes the regmap instance from the component.
395c7d75b59SKuninori Morimoto  *
396c7d75b59SKuninori Morimoto  * This function should only be used if snd_soc_component_init_regmap() was used
397c7d75b59SKuninori Morimoto  * to initialize the regmap instance.
398c7d75b59SKuninori Morimoto  */
399c7d75b59SKuninori Morimoto void snd_soc_component_exit_regmap(struct snd_soc_component *component)
400c7d75b59SKuninori Morimoto {
401c7d75b59SKuninori Morimoto 	regmap_exit(component->regmap);
402c7d75b59SKuninori Morimoto 	component->regmap = NULL;
403c7d75b59SKuninori Morimoto }
404c7d75b59SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_exit_regmap);
405c7d75b59SKuninori Morimoto 
406c7d75b59SKuninori Morimoto #endif
407c7d75b59SKuninori Morimoto 
408e8712315SKuninori Morimoto static unsigned int soc_component_read_no_lock(
409e8712315SKuninori Morimoto 	struct snd_soc_component *component,
410cf6e26c7SKuninori Morimoto 	unsigned int reg)
411460b42d1SKuninori Morimoto {
412460b42d1SKuninori Morimoto 	int ret;
413cf6e26c7SKuninori Morimoto 	unsigned int val = 0;
414460b42d1SKuninori Morimoto 
415460b42d1SKuninori Morimoto 	if (component->regmap)
416cf6e26c7SKuninori Morimoto 		ret = regmap_read(component->regmap, reg, &val);
417460b42d1SKuninori Morimoto 	else if (component->driver->read) {
418460b42d1SKuninori Morimoto 		ret = 0;
419cf6e26c7SKuninori Morimoto 		val = component->driver->read(component, reg);
420460b42d1SKuninori Morimoto 	}
421460b42d1SKuninori Morimoto 	else
422460b42d1SKuninori Morimoto 		ret = -EIO;
423460b42d1SKuninori Morimoto 
424460b42d1SKuninori Morimoto 	if (ret < 0)
425cf6e26c7SKuninori Morimoto 		soc_component_ret(component, ret);
426460b42d1SKuninori Morimoto 
427460b42d1SKuninori Morimoto 	return val;
428460b42d1SKuninori Morimoto }
429e8712315SKuninori Morimoto 
430e8712315SKuninori Morimoto /**
431e8712315SKuninori Morimoto  * snd_soc_component_read() - Read register value
432e8712315SKuninori Morimoto  * @component: Component to read from
433e8712315SKuninori Morimoto  * @reg: Register to read
434e8712315SKuninori Morimoto  *
435e8712315SKuninori Morimoto  * Return: read value
436e8712315SKuninori Morimoto  */
437e8712315SKuninori Morimoto unsigned int snd_soc_component_read(struct snd_soc_component *component,
438e8712315SKuninori Morimoto 				    unsigned int reg)
439e8712315SKuninori Morimoto {
440e8712315SKuninori Morimoto 	unsigned int val;
441e8712315SKuninori Morimoto 
442e8712315SKuninori Morimoto 	mutex_lock(&component->io_mutex);
443e8712315SKuninori Morimoto 	val = soc_component_read_no_lock(component, reg);
444e8712315SKuninori Morimoto 	mutex_unlock(&component->io_mutex);
445e8712315SKuninori Morimoto 
446e8712315SKuninori Morimoto 	return val;
447e8712315SKuninori Morimoto }
448cf6e26c7SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_read);
449460b42d1SKuninori Morimoto 
450e8712315SKuninori Morimoto static int soc_component_write_no_lock(
451e8712315SKuninori Morimoto 	struct snd_soc_component *component,
452e8712315SKuninori Morimoto 	unsigned int reg, unsigned int val)
453e8712315SKuninori Morimoto {
454e8712315SKuninori Morimoto 	int ret = -EIO;
455e8712315SKuninori Morimoto 
456e8712315SKuninori Morimoto 	if (component->regmap)
457e8712315SKuninori Morimoto 		ret = regmap_write(component->regmap, reg, val);
458e8712315SKuninori Morimoto 	else if (component->driver->write)
459e8712315SKuninori Morimoto 		ret = component->driver->write(component, reg, val);
460e8712315SKuninori Morimoto 
461e8712315SKuninori Morimoto 	return soc_component_ret(component, ret);
462e8712315SKuninori Morimoto }
463e8712315SKuninori Morimoto 
464460b42d1SKuninori Morimoto /**
465460b42d1SKuninori Morimoto  * snd_soc_component_write() - Write register value
466460b42d1SKuninori Morimoto  * @component: Component to write to
467460b42d1SKuninori Morimoto  * @reg: Register to write
468460b42d1SKuninori Morimoto  * @val: Value to write to the register
469460b42d1SKuninori Morimoto  *
470460b42d1SKuninori Morimoto  * Return: 0 on success, a negative error code otherwise.
471460b42d1SKuninori Morimoto  */
472460b42d1SKuninori Morimoto int snd_soc_component_write(struct snd_soc_component *component,
473460b42d1SKuninori Morimoto 			    unsigned int reg, unsigned int val)
474460b42d1SKuninori Morimoto {
475e8712315SKuninori Morimoto 	int ret;
476460b42d1SKuninori Morimoto 
477e8712315SKuninori Morimoto 	mutex_lock(&component->io_mutex);
478e8712315SKuninori Morimoto 	ret = soc_component_write_no_lock(component, reg, val);
479e8712315SKuninori Morimoto 	mutex_unlock(&component->io_mutex);
480460b42d1SKuninori Morimoto 
481e8712315SKuninori Morimoto 	return ret;
482460b42d1SKuninori Morimoto }
483460b42d1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_write);
484460b42d1SKuninori Morimoto 
485460b42d1SKuninori Morimoto static int snd_soc_component_update_bits_legacy(
486460b42d1SKuninori Morimoto 	struct snd_soc_component *component, unsigned int reg,
487460b42d1SKuninori Morimoto 	unsigned int mask, unsigned int val, bool *change)
488460b42d1SKuninori Morimoto {
489460b42d1SKuninori Morimoto 	unsigned int old, new;
490cf6e26c7SKuninori Morimoto 	int ret = 0;
491460b42d1SKuninori Morimoto 
492460b42d1SKuninori Morimoto 	mutex_lock(&component->io_mutex);
493460b42d1SKuninori Morimoto 
494e8712315SKuninori Morimoto 	old = soc_component_read_no_lock(component, reg);
495460b42d1SKuninori Morimoto 
496460b42d1SKuninori Morimoto 	new = (old & ~mask) | (val & mask);
497460b42d1SKuninori Morimoto 	*change = old != new;
498460b42d1SKuninori Morimoto 	if (*change)
499e8712315SKuninori Morimoto 		ret = soc_component_write_no_lock(component, reg, new);
500cf6e26c7SKuninori Morimoto 
501460b42d1SKuninori Morimoto 	mutex_unlock(&component->io_mutex);
502460b42d1SKuninori Morimoto 
503460b42d1SKuninori Morimoto 	return soc_component_ret(component, ret);
504460b42d1SKuninori Morimoto }
505460b42d1SKuninori Morimoto 
506460b42d1SKuninori Morimoto /**
507460b42d1SKuninori Morimoto  * snd_soc_component_update_bits() - Perform read/modify/write cycle
508460b42d1SKuninori Morimoto  * @component: Component to update
509460b42d1SKuninori Morimoto  * @reg: Register to update
510460b42d1SKuninori Morimoto  * @mask: Mask that specifies which bits to update
511460b42d1SKuninori Morimoto  * @val: New value for the bits specified by mask
512460b42d1SKuninori Morimoto  *
513460b42d1SKuninori Morimoto  * Return: 1 if the operation was successful and the value of the register
514460b42d1SKuninori Morimoto  * changed, 0 if the operation was successful, but the value did not change.
515460b42d1SKuninori Morimoto  * Returns a negative error code otherwise.
516460b42d1SKuninori Morimoto  */
517460b42d1SKuninori Morimoto int snd_soc_component_update_bits(struct snd_soc_component *component,
518460b42d1SKuninori Morimoto 				  unsigned int reg, unsigned int mask, unsigned int val)
519460b42d1SKuninori Morimoto {
520460b42d1SKuninori Morimoto 	bool change;
521460b42d1SKuninori Morimoto 	int ret;
522460b42d1SKuninori Morimoto 
523460b42d1SKuninori Morimoto 	if (component->regmap)
524460b42d1SKuninori Morimoto 		ret = regmap_update_bits_check(component->regmap, reg, mask,
525460b42d1SKuninori Morimoto 					       val, &change);
526460b42d1SKuninori Morimoto 	else
527460b42d1SKuninori Morimoto 		ret = snd_soc_component_update_bits_legacy(component, reg,
528460b42d1SKuninori Morimoto 							   mask, val, &change);
529460b42d1SKuninori Morimoto 
530460b42d1SKuninori Morimoto 	if (ret < 0)
531460b42d1SKuninori Morimoto 		return soc_component_ret(component, ret);
532460b42d1SKuninori Morimoto 	return change;
533460b42d1SKuninori Morimoto }
534460b42d1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_update_bits);
535460b42d1SKuninori Morimoto 
536460b42d1SKuninori Morimoto /**
537460b42d1SKuninori Morimoto  * snd_soc_component_update_bits_async() - Perform asynchronous
538460b42d1SKuninori Morimoto  *  read/modify/write cycle
539460b42d1SKuninori Morimoto  * @component: Component to update
540460b42d1SKuninori Morimoto  * @reg: Register to update
541460b42d1SKuninori Morimoto  * @mask: Mask that specifies which bits to update
542460b42d1SKuninori Morimoto  * @val: New value for the bits specified by mask
543460b42d1SKuninori Morimoto  *
544460b42d1SKuninori Morimoto  * This function is similar to snd_soc_component_update_bits(), but the update
545460b42d1SKuninori Morimoto  * operation is scheduled asynchronously. This means it may not be completed
546460b42d1SKuninori Morimoto  * when the function returns. To make sure that all scheduled updates have been
547460b42d1SKuninori Morimoto  * completed snd_soc_component_async_complete() must be called.
548460b42d1SKuninori Morimoto  *
549460b42d1SKuninori Morimoto  * Return: 1 if the operation was successful and the value of the register
550460b42d1SKuninori Morimoto  * changed, 0 if the operation was successful, but the value did not change.
551460b42d1SKuninori Morimoto  * Returns a negative error code otherwise.
552460b42d1SKuninori Morimoto  */
553460b42d1SKuninori Morimoto int snd_soc_component_update_bits_async(struct snd_soc_component *component,
554460b42d1SKuninori Morimoto 					unsigned int reg, unsigned int mask, unsigned int val)
555460b42d1SKuninori Morimoto {
556460b42d1SKuninori Morimoto 	bool change;
557460b42d1SKuninori Morimoto 	int ret;
558460b42d1SKuninori Morimoto 
559460b42d1SKuninori Morimoto 	if (component->regmap)
560460b42d1SKuninori Morimoto 		ret = regmap_update_bits_check_async(component->regmap, reg,
561460b42d1SKuninori Morimoto 						     mask, val, &change);
562460b42d1SKuninori Morimoto 	else
563460b42d1SKuninori Morimoto 		ret = snd_soc_component_update_bits_legacy(component, reg,
564460b42d1SKuninori Morimoto 							   mask, val, &change);
565460b42d1SKuninori Morimoto 
566460b42d1SKuninori Morimoto 	if (ret < 0)
567460b42d1SKuninori Morimoto 		return soc_component_ret(component, ret);
568460b42d1SKuninori Morimoto 	return change;
569460b42d1SKuninori Morimoto }
570460b42d1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_update_bits_async);
571460b42d1SKuninori Morimoto 
572460b42d1SKuninori Morimoto /**
573460b42d1SKuninori Morimoto  * snd_soc_component_async_complete() - Ensure asynchronous I/O has completed
574460b42d1SKuninori Morimoto  * @component: Component for which to wait
575460b42d1SKuninori Morimoto  *
576460b42d1SKuninori Morimoto  * This function blocks until all asynchronous I/O which has previously been
577460b42d1SKuninori Morimoto  * scheduled using snd_soc_component_update_bits_async() has completed.
578460b42d1SKuninori Morimoto  */
579460b42d1SKuninori Morimoto void snd_soc_component_async_complete(struct snd_soc_component *component)
580460b42d1SKuninori Morimoto {
581460b42d1SKuninori Morimoto 	if (component->regmap)
582460b42d1SKuninori Morimoto 		regmap_async_complete(component->regmap);
583460b42d1SKuninori Morimoto }
584460b42d1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_async_complete);
585460b42d1SKuninori Morimoto 
586460b42d1SKuninori Morimoto /**
587460b42d1SKuninori Morimoto  * snd_soc_component_test_bits - Test register for change
588460b42d1SKuninori Morimoto  * @component: component
589460b42d1SKuninori Morimoto  * @reg: Register to test
590460b42d1SKuninori Morimoto  * @mask: Mask that specifies which bits to test
591460b42d1SKuninori Morimoto  * @value: Value to test against
592460b42d1SKuninori Morimoto  *
593460b42d1SKuninori Morimoto  * Tests a register with a new value and checks if the new value is
594460b42d1SKuninori Morimoto  * different from the old value.
595460b42d1SKuninori Morimoto  *
596460b42d1SKuninori Morimoto  * Return: 1 for change, otherwise 0.
597460b42d1SKuninori Morimoto  */
598460b42d1SKuninori Morimoto int snd_soc_component_test_bits(struct snd_soc_component *component,
599460b42d1SKuninori Morimoto 				unsigned int reg, unsigned int mask, unsigned int value)
600460b42d1SKuninori Morimoto {
601460b42d1SKuninori Morimoto 	unsigned int old, new;
602460b42d1SKuninori Morimoto 
603cf6e26c7SKuninori Morimoto 	old = snd_soc_component_read(component, reg);
604460b42d1SKuninori Morimoto 	new = (old & ~mask) | value;
605460b42d1SKuninori Morimoto 	return old != new;
606460b42d1SKuninori Morimoto }
607460b42d1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_test_bits);
608460b42d1SKuninori Morimoto 
6090035e256SKuninori Morimoto int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
6100035e256SKuninori Morimoto {
6110ceef681SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
6120035e256SKuninori Morimoto 	struct snd_soc_component *component;
613613fb500SKuninori Morimoto 	int i;
6140035e256SKuninori Morimoto 
6150035e256SKuninori Morimoto 	/* FIXME: use 1st pointer */
616613fb500SKuninori Morimoto 	for_each_rtd_components(rtd, i, component)
617e2cb4a14SKuninori Morimoto 		if (component->driver->pointer)
618e2cb4a14SKuninori Morimoto 			return component->driver->pointer(component, substream);
6190035e256SKuninori Morimoto 
6200035e256SKuninori Morimoto 	return 0;
6210035e256SKuninori Morimoto }
62296a47908SKuninori Morimoto 
62396a47908SKuninori Morimoto int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
62496a47908SKuninori Morimoto 				unsigned int cmd, void *arg)
62596a47908SKuninori Morimoto {
6260ceef681SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
62796a47908SKuninori Morimoto 	struct snd_soc_component *component;
628613fb500SKuninori Morimoto 	int i;
62996a47908SKuninori Morimoto 
63096a47908SKuninori Morimoto 	/* FIXME: use 1st ioctl */
631613fb500SKuninori Morimoto 	for_each_rtd_components(rtd, i, component)
632e2cb4a14SKuninori Morimoto 		if (component->driver->ioctl)
633e2329eebSKuninori Morimoto 			return soc_component_ret(
634e2329eebSKuninori Morimoto 				component,
635e2329eebSKuninori Morimoto 				component->driver->ioctl(component,
636e2329eebSKuninori Morimoto 							 substream, cmd, arg));
63796a47908SKuninori Morimoto 
63896a47908SKuninori Morimoto 	return snd_pcm_lib_ioctl(substream, cmd, arg);
63996a47908SKuninori Morimoto }
64082d81f5cSKuninori Morimoto 
6411e5ddb6bSTakashi Iwai int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream)
6421e5ddb6bSTakashi Iwai {
6430ceef681SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
6441e5ddb6bSTakashi Iwai 	struct snd_soc_component *component;
645613fb500SKuninori Morimoto 	int i, ret;
6461e5ddb6bSTakashi Iwai 
647613fb500SKuninori Morimoto 	for_each_rtd_components(rtd, i, component) {
648f1861a7cSKuninori Morimoto 		if (component->driver->sync_stop) {
6491e5ddb6bSTakashi Iwai 			ret = component->driver->sync_stop(component,
6501e5ddb6bSTakashi Iwai 							   substream);
6511e5ddb6bSTakashi Iwai 			if (ret < 0)
652be75db57SShengjiu Wang 				return soc_component_ret(component, ret);
6531e5ddb6bSTakashi Iwai 		}
6541e5ddb6bSTakashi Iwai 	}
6551e5ddb6bSTakashi Iwai 
6561e5ddb6bSTakashi Iwai 	return 0;
6571e5ddb6bSTakashi Iwai }
6581e5ddb6bSTakashi Iwai 
65982d81f5cSKuninori Morimoto int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
66082d81f5cSKuninori Morimoto 				    int channel, unsigned long pos,
66182d81f5cSKuninori Morimoto 				    void __user *buf, unsigned long bytes)
66282d81f5cSKuninori Morimoto {
6630ceef681SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
66482d81f5cSKuninori Morimoto 	struct snd_soc_component *component;
665613fb500SKuninori Morimoto 	int i;
66682d81f5cSKuninori Morimoto 
66782d81f5cSKuninori Morimoto 	/* FIXME. it returns 1st copy now */
668613fb500SKuninori Morimoto 	for_each_rtd_components(rtd, i, component)
669e2cb4a14SKuninori Morimoto 		if (component->driver->copy_user)
670e2329eebSKuninori Morimoto 			return soc_component_ret(
671e2329eebSKuninori Morimoto 				component,
672e2329eebSKuninori Morimoto 				component->driver->copy_user(
673e2329eebSKuninori Morimoto 					component, substream, channel,
674e2329eebSKuninori Morimoto 					pos, buf, bytes));
67582d81f5cSKuninori Morimoto 
67682d81f5cSKuninori Morimoto 	return -EINVAL;
67782d81f5cSKuninori Morimoto }
6789c712e4fSKuninori Morimoto 
6799c712e4fSKuninori Morimoto struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
6809c712e4fSKuninori Morimoto 					unsigned long offset)
6819c712e4fSKuninori Morimoto {
6820ceef681SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
6839c712e4fSKuninori Morimoto 	struct snd_soc_component *component;
6849c712e4fSKuninori Morimoto 	struct page *page;
685613fb500SKuninori Morimoto 	int i;
6869c712e4fSKuninori Morimoto 
6879c712e4fSKuninori Morimoto 	/* FIXME. it returns 1st page now */
688613fb500SKuninori Morimoto 	for_each_rtd_components(rtd, i, component) {
689e2cb4a14SKuninori Morimoto 		if (component->driver->page) {
690e2cb4a14SKuninori Morimoto 			page = component->driver->page(component,
691e2cb4a14SKuninori Morimoto 						       substream, offset);
692e2cb4a14SKuninori Morimoto 			if (page)
693e2cb4a14SKuninori Morimoto 				return page;
694e2cb4a14SKuninori Morimoto 		}
6959c712e4fSKuninori Morimoto 	}
6969c712e4fSKuninori Morimoto 
6979c712e4fSKuninori Morimoto 	return NULL;
6989c712e4fSKuninori Morimoto }
699205875e1SKuninori Morimoto 
700205875e1SKuninori Morimoto int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
701205875e1SKuninori Morimoto 			       struct vm_area_struct *vma)
702205875e1SKuninori Morimoto {
7030ceef681SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
704205875e1SKuninori Morimoto 	struct snd_soc_component *component;
705613fb500SKuninori Morimoto 	int i;
706205875e1SKuninori Morimoto 
707205875e1SKuninori Morimoto 	/* FIXME. it returns 1st mmap now */
708613fb500SKuninori Morimoto 	for_each_rtd_components(rtd, i, component)
709e2cb4a14SKuninori Morimoto 		if (component->driver->mmap)
710be75db57SShengjiu Wang 			return soc_component_ret(
711e2329eebSKuninori Morimoto 				component,
712e2329eebSKuninori Morimoto 				component->driver->mmap(component,
713e2329eebSKuninori Morimoto 							substream, vma));
714205875e1SKuninori Morimoto 
715205875e1SKuninori Morimoto 	return -EINVAL;
716205875e1SKuninori Morimoto }
7177484291eSKuninori Morimoto 
718b2b2afbbSKuninori Morimoto int snd_soc_pcm_component_new(struct snd_soc_pcm_runtime *rtd)
7197484291eSKuninori Morimoto {
7207484291eSKuninori Morimoto 	struct snd_soc_component *component;
7217484291eSKuninori Morimoto 	int ret;
722613fb500SKuninori Morimoto 	int i;
7237484291eSKuninori Morimoto 
724613fb500SKuninori Morimoto 	for_each_rtd_components(rtd, i, component) {
725c64bfc90SKuninori Morimoto 		if (component->driver->pcm_construct) {
726c64bfc90SKuninori Morimoto 			ret = component->driver->pcm_construct(component, rtd);
727c64bfc90SKuninori Morimoto 			if (ret < 0)
728be75db57SShengjiu Wang 				return soc_component_ret(component, ret);
729c64bfc90SKuninori Morimoto 		}
7307484291eSKuninori Morimoto 	}
7317484291eSKuninori Morimoto 
7327484291eSKuninori Morimoto 	return 0;
7337484291eSKuninori Morimoto }
73479776da0SKuninori Morimoto 
735b2b2afbbSKuninori Morimoto void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd)
73679776da0SKuninori Morimoto {
73779776da0SKuninori Morimoto 	struct snd_soc_component *component;
738613fb500SKuninori Morimoto 	int i;
73979776da0SKuninori Morimoto 
7408e3366caSTakashi Iwai 	if (!rtd->pcm)
7418e3366caSTakashi Iwai 		return;
7428e3366caSTakashi Iwai 
743613fb500SKuninori Morimoto 	for_each_rtd_components(rtd, i, component)
744c64bfc90SKuninori Morimoto 		if (component->driver->pcm_destruct)
745b2b2afbbSKuninori Morimoto 			component->driver->pcm_destruct(component, rtd->pcm);
74679776da0SKuninori Morimoto }
7474f39514fSKuninori Morimoto 
7484f39514fSKuninori Morimoto int snd_soc_pcm_component_prepare(struct snd_pcm_substream *substream)
7494f39514fSKuninori Morimoto {
7500ceef681SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
7514f39514fSKuninori Morimoto 	struct snd_soc_component *component;
7524f39514fSKuninori Morimoto 	int i, ret;
7534f39514fSKuninori Morimoto 
7544f39514fSKuninori Morimoto 	for_each_rtd_components(rtd, i, component) {
7554f39514fSKuninori Morimoto 		if (component->driver->prepare) {
7564f39514fSKuninori Morimoto 			ret = component->driver->prepare(component, substream);
7574f39514fSKuninori Morimoto 			if (ret < 0)
7584f39514fSKuninori Morimoto 				return soc_component_ret(component, ret);
7594f39514fSKuninori Morimoto 		}
7604f39514fSKuninori Morimoto 	}
7614f39514fSKuninori Morimoto 
7624f39514fSKuninori Morimoto 	return 0;
7634f39514fSKuninori Morimoto }
764e1bafa82SKuninori Morimoto 
765e1bafa82SKuninori Morimoto int snd_soc_pcm_component_hw_params(struct snd_pcm_substream *substream,
766e1bafa82SKuninori Morimoto 				    struct snd_pcm_hw_params *params,
767e1bafa82SKuninori Morimoto 				    struct snd_soc_component **last)
768e1bafa82SKuninori Morimoto {
7690ceef681SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
770e1bafa82SKuninori Morimoto 	struct snd_soc_component *component;
771e1bafa82SKuninori Morimoto 	int i, ret;
772e1bafa82SKuninori Morimoto 
773e1bafa82SKuninori Morimoto 	for_each_rtd_components(rtd, i, component) {
774e1bafa82SKuninori Morimoto 		if (component->driver->hw_params) {
775e1bafa82SKuninori Morimoto 			ret = component->driver->hw_params(component,
776e1bafa82SKuninori Morimoto 							   substream, params);
777e1bafa82SKuninori Morimoto 			if (ret < 0) {
778e1bafa82SKuninori Morimoto 				*last = component;
779e1bafa82SKuninori Morimoto 				return soc_component_ret(component, ret);
780e1bafa82SKuninori Morimoto 			}
781e1bafa82SKuninori Morimoto 		}
782e1bafa82SKuninori Morimoto 	}
783e1bafa82SKuninori Morimoto 
784e1bafa82SKuninori Morimoto 	*last = NULL;
785e1bafa82SKuninori Morimoto 	return 0;
786e1bafa82SKuninori Morimoto }
78704751119SKuninori Morimoto 
78804751119SKuninori Morimoto void snd_soc_pcm_component_hw_free(struct snd_pcm_substream *substream,
78904751119SKuninori Morimoto 				   struct snd_soc_component *last)
79004751119SKuninori Morimoto {
7910ceef681SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
79204751119SKuninori Morimoto 	struct snd_soc_component *component;
79304751119SKuninori Morimoto 	int i, ret;
79404751119SKuninori Morimoto 
79504751119SKuninori Morimoto 	for_each_rtd_components(rtd, i, component) {
79604751119SKuninori Morimoto 		if (component == last)
79704751119SKuninori Morimoto 			break;
79804751119SKuninori Morimoto 
79904751119SKuninori Morimoto 		if (component->driver->hw_free) {
80004751119SKuninori Morimoto 			ret = component->driver->hw_free(component, substream);
80104751119SKuninori Morimoto 			if (ret < 0)
80204751119SKuninori Morimoto 				soc_component_ret(component, ret);
80304751119SKuninori Morimoto 		}
80404751119SKuninori Morimoto 	}
80504751119SKuninori Morimoto }
80632fd1204SKuninori Morimoto 
80732fd1204SKuninori Morimoto int snd_soc_pcm_component_trigger(struct snd_pcm_substream *substream,
80832fd1204SKuninori Morimoto 				  int cmd)
80932fd1204SKuninori Morimoto {
8100ceef681SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
81132fd1204SKuninori Morimoto 	struct snd_soc_component *component;
81232fd1204SKuninori Morimoto 	int i, ret;
81332fd1204SKuninori Morimoto 
81432fd1204SKuninori Morimoto 	for_each_rtd_components(rtd, i, component) {
81532fd1204SKuninori Morimoto 		if (component->driver->trigger) {
81632fd1204SKuninori Morimoto 			ret = component->driver->trigger(component, substream, cmd);
81732fd1204SKuninori Morimoto 			if (ret < 0)
81832fd1204SKuninori Morimoto 				return soc_component_ret(component, ret);
81932fd1204SKuninori Morimoto 		}
82032fd1204SKuninori Morimoto 	}
82132fd1204SKuninori Morimoto 
82232fd1204SKuninori Morimoto 	return 0;
82332fd1204SKuninori Morimoto }
824