xref: /openbmc/linux/sound/soc/soc-component.c (revision 1e5ddb6b)
14ff1fef1SKuninori Morimoto // SPDX-License-Identifier: GPL-2.0
24ff1fef1SKuninori Morimoto //
34ff1fef1SKuninori Morimoto // soc-component.c
44ff1fef1SKuninori Morimoto //
54ff1fef1SKuninori Morimoto // Copyright (C) 2019 Renesas Electronics Corp.
64ff1fef1SKuninori Morimoto // Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
74ff1fef1SKuninori Morimoto //
84a81e8f3SKuninori Morimoto #include <linux/module.h>
94ff1fef1SKuninori Morimoto #include <sound/soc.h>
104ff1fef1SKuninori Morimoto 
114ff1fef1SKuninori Morimoto /**
124ff1fef1SKuninori Morimoto  * snd_soc_component_set_sysclk - configure COMPONENT system or master clock.
134ff1fef1SKuninori Morimoto  * @component: COMPONENT
144ff1fef1SKuninori Morimoto  * @clk_id: DAI specific clock ID
154ff1fef1SKuninori Morimoto  * @source: Source for the clock
164ff1fef1SKuninori Morimoto  * @freq: new clock frequency in Hz
174ff1fef1SKuninori Morimoto  * @dir: new clock direction - input/output.
184ff1fef1SKuninori Morimoto  *
194ff1fef1SKuninori Morimoto  * Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
204ff1fef1SKuninori Morimoto  */
214ff1fef1SKuninori Morimoto int snd_soc_component_set_sysclk(struct snd_soc_component *component,
224ff1fef1SKuninori Morimoto 				 int clk_id, int source, unsigned int freq,
234ff1fef1SKuninori Morimoto 				 int dir)
244ff1fef1SKuninori Morimoto {
254ff1fef1SKuninori Morimoto 	if (component->driver->set_sysclk)
264ff1fef1SKuninori Morimoto 		return component->driver->set_sysclk(component, clk_id, source,
274ff1fef1SKuninori Morimoto 						     freq, dir);
284ff1fef1SKuninori Morimoto 
294ff1fef1SKuninori Morimoto 	return -ENOTSUPP;
304ff1fef1SKuninori Morimoto }
314ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk);
324ff1fef1SKuninori Morimoto 
334ff1fef1SKuninori Morimoto /*
344ff1fef1SKuninori Morimoto  * snd_soc_component_set_pll - configure component PLL.
354ff1fef1SKuninori Morimoto  * @component: COMPONENT
364ff1fef1SKuninori Morimoto  * @pll_id: DAI specific PLL ID
374ff1fef1SKuninori Morimoto  * @source: DAI specific source for the PLL
384ff1fef1SKuninori Morimoto  * @freq_in: PLL input clock frequency in Hz
394ff1fef1SKuninori Morimoto  * @freq_out: requested PLL output clock frequency in Hz
404ff1fef1SKuninori Morimoto  *
414ff1fef1SKuninori Morimoto  * Configures and enables PLL to generate output clock based on input clock.
424ff1fef1SKuninori Morimoto  */
434ff1fef1SKuninori Morimoto int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
444ff1fef1SKuninori Morimoto 			      int source, unsigned int freq_in,
454ff1fef1SKuninori Morimoto 			      unsigned int freq_out)
464ff1fef1SKuninori Morimoto {
474ff1fef1SKuninori Morimoto 	if (component->driver->set_pll)
484ff1fef1SKuninori Morimoto 		return component->driver->set_pll(component, pll_id, source,
494ff1fef1SKuninori Morimoto 						  freq_in, freq_out);
504ff1fef1SKuninori Morimoto 
514ff1fef1SKuninori Morimoto 	return -EINVAL;
524ff1fef1SKuninori Morimoto }
534ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_set_pll);
544ff1fef1SKuninori Morimoto 
559d415fbfSKuninori Morimoto void snd_soc_component_seq_notifier(struct snd_soc_component *component,
569d415fbfSKuninori Morimoto 				    enum snd_soc_dapm_type type, int subseq)
579d415fbfSKuninori Morimoto {
589d415fbfSKuninori Morimoto 	if (component->driver->seq_notifier)
599d415fbfSKuninori Morimoto 		component->driver->seq_notifier(component, type, subseq);
609d415fbfSKuninori Morimoto }
619d415fbfSKuninori Morimoto 
628e2a990dSKuninori Morimoto int snd_soc_component_stream_event(struct snd_soc_component *component,
638e2a990dSKuninori Morimoto 				   int event)
648e2a990dSKuninori Morimoto {
658e2a990dSKuninori Morimoto 	if (component->driver->stream_event)
668e2a990dSKuninori Morimoto 		return component->driver->stream_event(component, event);
678e2a990dSKuninori Morimoto 
688e2a990dSKuninori Morimoto 	return 0;
698e2a990dSKuninori Morimoto }
708e2a990dSKuninori Morimoto 
717951b146SKuninori Morimoto int snd_soc_component_set_bias_level(struct snd_soc_component *component,
727951b146SKuninori Morimoto 				     enum snd_soc_bias_level level)
737951b146SKuninori Morimoto {
747951b146SKuninori Morimoto 	if (component->driver->set_bias_level)
757951b146SKuninori Morimoto 		return component->driver->set_bias_level(component, level);
767951b146SKuninori Morimoto 
777951b146SKuninori Morimoto 	return 0;
787951b146SKuninori Morimoto }
797951b146SKuninori Morimoto 
804ff1fef1SKuninori Morimoto int snd_soc_component_enable_pin(struct snd_soc_component *component,
814ff1fef1SKuninori Morimoto 				 const char *pin)
824ff1fef1SKuninori Morimoto {
834ff1fef1SKuninori Morimoto 	struct snd_soc_dapm_context *dapm =
844ff1fef1SKuninori Morimoto 		snd_soc_component_get_dapm(component);
854ff1fef1SKuninori Morimoto 	char *full_name;
864ff1fef1SKuninori Morimoto 	int ret;
874ff1fef1SKuninori Morimoto 
884ff1fef1SKuninori Morimoto 	if (!component->name_prefix)
894ff1fef1SKuninori Morimoto 		return snd_soc_dapm_enable_pin(dapm, pin);
904ff1fef1SKuninori Morimoto 
914ff1fef1SKuninori Morimoto 	full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
924ff1fef1SKuninori Morimoto 	if (!full_name)
934ff1fef1SKuninori Morimoto 		return -ENOMEM;
944ff1fef1SKuninori Morimoto 
954ff1fef1SKuninori Morimoto 	ret = snd_soc_dapm_enable_pin(dapm, full_name);
964ff1fef1SKuninori Morimoto 	kfree(full_name);
974ff1fef1SKuninori Morimoto 
984ff1fef1SKuninori Morimoto 	return ret;
994ff1fef1SKuninori Morimoto }
1004ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin);
1014ff1fef1SKuninori Morimoto 
1024ff1fef1SKuninori Morimoto int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component,
1034ff1fef1SKuninori Morimoto 					  const char *pin)
1044ff1fef1SKuninori Morimoto {
1054ff1fef1SKuninori Morimoto 	struct snd_soc_dapm_context *dapm =
1064ff1fef1SKuninori Morimoto 		snd_soc_component_get_dapm(component);
1074ff1fef1SKuninori Morimoto 	char *full_name;
1084ff1fef1SKuninori Morimoto 	int ret;
1094ff1fef1SKuninori Morimoto 
1104ff1fef1SKuninori Morimoto 	if (!component->name_prefix)
1114ff1fef1SKuninori Morimoto 		return snd_soc_dapm_enable_pin_unlocked(dapm, pin);
1124ff1fef1SKuninori Morimoto 
1134ff1fef1SKuninori Morimoto 	full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
1144ff1fef1SKuninori Morimoto 	if (!full_name)
1154ff1fef1SKuninori Morimoto 		return -ENOMEM;
1164ff1fef1SKuninori Morimoto 
1174ff1fef1SKuninori Morimoto 	ret = snd_soc_dapm_enable_pin_unlocked(dapm, full_name);
1184ff1fef1SKuninori Morimoto 	kfree(full_name);
1194ff1fef1SKuninori Morimoto 
1204ff1fef1SKuninori Morimoto 	return ret;
1214ff1fef1SKuninori Morimoto }
1224ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked);
1234ff1fef1SKuninori Morimoto 
1244ff1fef1SKuninori Morimoto int snd_soc_component_disable_pin(struct snd_soc_component *component,
1254ff1fef1SKuninori Morimoto 				  const char *pin)
1264ff1fef1SKuninori Morimoto {
1274ff1fef1SKuninori Morimoto 	struct snd_soc_dapm_context *dapm =
1284ff1fef1SKuninori Morimoto 		snd_soc_component_get_dapm(component);
1294ff1fef1SKuninori Morimoto 	char *full_name;
1304ff1fef1SKuninori Morimoto 	int ret;
1314ff1fef1SKuninori Morimoto 
1324ff1fef1SKuninori Morimoto 	if (!component->name_prefix)
1334ff1fef1SKuninori Morimoto 		return snd_soc_dapm_disable_pin(dapm, pin);
1344ff1fef1SKuninori Morimoto 
1354ff1fef1SKuninori Morimoto 	full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
1364ff1fef1SKuninori Morimoto 	if (!full_name)
1374ff1fef1SKuninori Morimoto 		return -ENOMEM;
1384ff1fef1SKuninori Morimoto 
1394ff1fef1SKuninori Morimoto 	ret = snd_soc_dapm_disable_pin(dapm, full_name);
1404ff1fef1SKuninori Morimoto 	kfree(full_name);
1414ff1fef1SKuninori Morimoto 
1424ff1fef1SKuninori Morimoto 	return ret;
1434ff1fef1SKuninori Morimoto }
1444ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin);
1454ff1fef1SKuninori Morimoto 
1464ff1fef1SKuninori Morimoto int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
1474ff1fef1SKuninori Morimoto 					   const char *pin)
1484ff1fef1SKuninori Morimoto {
1494ff1fef1SKuninori Morimoto 	struct snd_soc_dapm_context *dapm =
1504ff1fef1SKuninori Morimoto 		snd_soc_component_get_dapm(component);
1514ff1fef1SKuninori Morimoto 	char *full_name;
1524ff1fef1SKuninori Morimoto 	int ret;
1534ff1fef1SKuninori Morimoto 
1544ff1fef1SKuninori Morimoto 	if (!component->name_prefix)
1554ff1fef1SKuninori Morimoto 		return snd_soc_dapm_disable_pin_unlocked(dapm, pin);
1564ff1fef1SKuninori Morimoto 
1574ff1fef1SKuninori Morimoto 	full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
1584ff1fef1SKuninori Morimoto 	if (!full_name)
1594ff1fef1SKuninori Morimoto 		return -ENOMEM;
1604ff1fef1SKuninori Morimoto 
1614ff1fef1SKuninori Morimoto 	ret = snd_soc_dapm_disable_pin_unlocked(dapm, full_name);
1624ff1fef1SKuninori Morimoto 	kfree(full_name);
1634ff1fef1SKuninori Morimoto 
1644ff1fef1SKuninori Morimoto 	return ret;
1654ff1fef1SKuninori Morimoto }
1664ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked);
1674ff1fef1SKuninori Morimoto 
1684ff1fef1SKuninori Morimoto int snd_soc_component_nc_pin(struct snd_soc_component *component,
1694ff1fef1SKuninori Morimoto 			     const char *pin)
1704ff1fef1SKuninori Morimoto {
1714ff1fef1SKuninori Morimoto 	struct snd_soc_dapm_context *dapm =
1724ff1fef1SKuninori Morimoto 		snd_soc_component_get_dapm(component);
1734ff1fef1SKuninori Morimoto 	char *full_name;
1744ff1fef1SKuninori Morimoto 	int ret;
1754ff1fef1SKuninori Morimoto 
1764ff1fef1SKuninori Morimoto 	if (!component->name_prefix)
1774ff1fef1SKuninori Morimoto 		return snd_soc_dapm_nc_pin(dapm, pin);
1784ff1fef1SKuninori Morimoto 
1794ff1fef1SKuninori Morimoto 	full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
1804ff1fef1SKuninori Morimoto 	if (!full_name)
1814ff1fef1SKuninori Morimoto 		return -ENOMEM;
1824ff1fef1SKuninori Morimoto 
1834ff1fef1SKuninori Morimoto 	ret = snd_soc_dapm_nc_pin(dapm, full_name);
1844ff1fef1SKuninori Morimoto 	kfree(full_name);
1854ff1fef1SKuninori Morimoto 
1864ff1fef1SKuninori Morimoto 	return ret;
1874ff1fef1SKuninori Morimoto }
1884ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin);
1894ff1fef1SKuninori Morimoto 
1904ff1fef1SKuninori Morimoto int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
1914ff1fef1SKuninori Morimoto 				      const char *pin)
1924ff1fef1SKuninori Morimoto {
1934ff1fef1SKuninori Morimoto 	struct snd_soc_dapm_context *dapm =
1944ff1fef1SKuninori Morimoto 		snd_soc_component_get_dapm(component);
1954ff1fef1SKuninori Morimoto 	char *full_name;
1964ff1fef1SKuninori Morimoto 	int ret;
1974ff1fef1SKuninori Morimoto 
1984ff1fef1SKuninori Morimoto 	if (!component->name_prefix)
1994ff1fef1SKuninori Morimoto 		return snd_soc_dapm_nc_pin_unlocked(dapm, pin);
2004ff1fef1SKuninori Morimoto 
2014ff1fef1SKuninori Morimoto 	full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
2024ff1fef1SKuninori Morimoto 	if (!full_name)
2034ff1fef1SKuninori Morimoto 		return -ENOMEM;
2044ff1fef1SKuninori Morimoto 
2054ff1fef1SKuninori Morimoto 	ret = snd_soc_dapm_nc_pin_unlocked(dapm, full_name);
2064ff1fef1SKuninori Morimoto 	kfree(full_name);
2074ff1fef1SKuninori Morimoto 
2084ff1fef1SKuninori Morimoto 	return ret;
2094ff1fef1SKuninori Morimoto }
2104ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked);
2114ff1fef1SKuninori Morimoto 
2124ff1fef1SKuninori Morimoto int snd_soc_component_get_pin_status(struct snd_soc_component *component,
2134ff1fef1SKuninori Morimoto 				     const char *pin)
2144ff1fef1SKuninori Morimoto {
2154ff1fef1SKuninori Morimoto 	struct snd_soc_dapm_context *dapm =
2164ff1fef1SKuninori Morimoto 		snd_soc_component_get_dapm(component);
2174ff1fef1SKuninori Morimoto 	char *full_name;
2184ff1fef1SKuninori Morimoto 	int ret;
2194ff1fef1SKuninori Morimoto 
2204ff1fef1SKuninori Morimoto 	if (!component->name_prefix)
2214ff1fef1SKuninori Morimoto 		return snd_soc_dapm_get_pin_status(dapm, pin);
2224ff1fef1SKuninori Morimoto 
2234ff1fef1SKuninori Morimoto 	full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
2244ff1fef1SKuninori Morimoto 	if (!full_name)
2254ff1fef1SKuninori Morimoto 		return -ENOMEM;
2264ff1fef1SKuninori Morimoto 
2274ff1fef1SKuninori Morimoto 	ret = snd_soc_dapm_get_pin_status(dapm, full_name);
2284ff1fef1SKuninori Morimoto 	kfree(full_name);
2294ff1fef1SKuninori Morimoto 
2304ff1fef1SKuninori Morimoto 	return ret;
2314ff1fef1SKuninori Morimoto }
2324ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status);
2334ff1fef1SKuninori Morimoto 
2344ff1fef1SKuninori Morimoto int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
2354ff1fef1SKuninori Morimoto 				       const char *pin)
2364ff1fef1SKuninori Morimoto {
2374ff1fef1SKuninori Morimoto 	struct snd_soc_dapm_context *dapm =
2384ff1fef1SKuninori Morimoto 		snd_soc_component_get_dapm(component);
2394ff1fef1SKuninori Morimoto 	char *full_name;
2404ff1fef1SKuninori Morimoto 	int ret;
2414ff1fef1SKuninori Morimoto 
2424ff1fef1SKuninori Morimoto 	if (!component->name_prefix)
2434ff1fef1SKuninori Morimoto 		return snd_soc_dapm_force_enable_pin(dapm, pin);
2444ff1fef1SKuninori Morimoto 
2454ff1fef1SKuninori Morimoto 	full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
2464ff1fef1SKuninori Morimoto 	if (!full_name)
2474ff1fef1SKuninori Morimoto 		return -ENOMEM;
2484ff1fef1SKuninori Morimoto 
2494ff1fef1SKuninori Morimoto 	ret = snd_soc_dapm_force_enable_pin(dapm, full_name);
2504ff1fef1SKuninori Morimoto 	kfree(full_name);
2514ff1fef1SKuninori Morimoto 
2524ff1fef1SKuninori Morimoto 	return ret;
2534ff1fef1SKuninori Morimoto }
2544ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin);
2554ff1fef1SKuninori Morimoto 
2564ff1fef1SKuninori Morimoto int snd_soc_component_force_enable_pin_unlocked(
2574ff1fef1SKuninori Morimoto 	struct snd_soc_component *component,
2584ff1fef1SKuninori Morimoto 	const char *pin)
2594ff1fef1SKuninori Morimoto {
2604ff1fef1SKuninori Morimoto 	struct snd_soc_dapm_context *dapm =
2614ff1fef1SKuninori Morimoto 		snd_soc_component_get_dapm(component);
2624ff1fef1SKuninori Morimoto 	char *full_name;
2634ff1fef1SKuninori Morimoto 	int ret;
2644ff1fef1SKuninori Morimoto 
2654ff1fef1SKuninori Morimoto 	if (!component->name_prefix)
2664ff1fef1SKuninori Morimoto 		return snd_soc_dapm_force_enable_pin_unlocked(dapm, pin);
2674ff1fef1SKuninori Morimoto 
2684ff1fef1SKuninori Morimoto 	full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
2694ff1fef1SKuninori Morimoto 	if (!full_name)
2704ff1fef1SKuninori Morimoto 		return -ENOMEM;
2714ff1fef1SKuninori Morimoto 
2724ff1fef1SKuninori Morimoto 	ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, full_name);
2734ff1fef1SKuninori Morimoto 	kfree(full_name);
2744ff1fef1SKuninori Morimoto 
2754ff1fef1SKuninori Morimoto 	return ret;
2764ff1fef1SKuninori Morimoto }
2774ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked);
2784ff1fef1SKuninori Morimoto 
2794ff1fef1SKuninori Morimoto /**
2804ff1fef1SKuninori Morimoto  * snd_soc_component_set_jack - configure component jack.
2814ff1fef1SKuninori Morimoto  * @component: COMPONENTs
2824ff1fef1SKuninori Morimoto  * @jack: structure to use for the jack
2834ff1fef1SKuninori Morimoto  * @data: can be used if codec driver need extra data for configuring jack
2844ff1fef1SKuninori Morimoto  *
2854ff1fef1SKuninori Morimoto  * Configures and enables jack detection function.
2864ff1fef1SKuninori Morimoto  */
2874ff1fef1SKuninori Morimoto int snd_soc_component_set_jack(struct snd_soc_component *component,
2884ff1fef1SKuninori Morimoto 			       struct snd_soc_jack *jack, void *data)
2894ff1fef1SKuninori Morimoto {
2904ff1fef1SKuninori Morimoto 	if (component->driver->set_jack)
2914ff1fef1SKuninori Morimoto 		return component->driver->set_jack(component, jack, data);
2924ff1fef1SKuninori Morimoto 
2934ff1fef1SKuninori Morimoto 	return -ENOTSUPP;
2944ff1fef1SKuninori Morimoto }
2954ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_set_jack);
2964a81e8f3SKuninori Morimoto 
2974a81e8f3SKuninori Morimoto int snd_soc_component_module_get(struct snd_soc_component *component,
2984a81e8f3SKuninori Morimoto 				 int upon_open)
2994a81e8f3SKuninori Morimoto {
3004a81e8f3SKuninori Morimoto 	if (component->driver->module_get_upon_open == !!upon_open &&
3014a81e8f3SKuninori Morimoto 	    !try_module_get(component->dev->driver->owner))
3024a81e8f3SKuninori Morimoto 		return -ENODEV;
3034a81e8f3SKuninori Morimoto 
3044a81e8f3SKuninori Morimoto 	return 0;
3054a81e8f3SKuninori Morimoto }
3064a81e8f3SKuninori Morimoto 
3074a81e8f3SKuninori Morimoto void snd_soc_component_module_put(struct snd_soc_component *component,
3084a81e8f3SKuninori Morimoto 				  int upon_open)
3094a81e8f3SKuninori Morimoto {
3104a81e8f3SKuninori Morimoto 	if (component->driver->module_get_upon_open == !!upon_open)
3114a81e8f3SKuninori Morimoto 		module_put(component->dev->driver->owner);
3124a81e8f3SKuninori Morimoto }
313ae2f4849SKuninori Morimoto 
314ae2f4849SKuninori Morimoto int snd_soc_component_open(struct snd_soc_component *component,
315ae2f4849SKuninori Morimoto 			   struct snd_pcm_substream *substream)
316ae2f4849SKuninori Morimoto {
317e2cb4a14SKuninori Morimoto 	if (component->driver->open)
318e2cb4a14SKuninori Morimoto 		return component->driver->open(component, substream);
319ae2f4849SKuninori Morimoto 	return 0;
320ae2f4849SKuninori Morimoto }
3213672beb8SKuninori Morimoto 
3223672beb8SKuninori Morimoto int snd_soc_component_close(struct snd_soc_component *component,
3233672beb8SKuninori Morimoto 			    struct snd_pcm_substream *substream)
3243672beb8SKuninori Morimoto {
325e2cb4a14SKuninori Morimoto 	if (component->driver->close)
326e2cb4a14SKuninori Morimoto 		return component->driver->close(component, substream);
3273672beb8SKuninori Morimoto 	return 0;
3283672beb8SKuninori Morimoto }
3296d537233SKuninori Morimoto 
3306d537233SKuninori Morimoto int snd_soc_component_prepare(struct snd_soc_component *component,
3316d537233SKuninori Morimoto 			      struct snd_pcm_substream *substream)
3326d537233SKuninori Morimoto {
333e2cb4a14SKuninori Morimoto 	if (component->driver->prepare)
334e2cb4a14SKuninori Morimoto 		return component->driver->prepare(component, substream);
3356d537233SKuninori Morimoto 	return 0;
3366d537233SKuninori Morimoto }
337245c539aSKuninori Morimoto 
338245c539aSKuninori Morimoto int snd_soc_component_hw_params(struct snd_soc_component *component,
339245c539aSKuninori Morimoto 				struct snd_pcm_substream *substream,
340245c539aSKuninori Morimoto 				struct snd_pcm_hw_params *params)
341245c539aSKuninori Morimoto {
342e2cb4a14SKuninori Morimoto 	if (component->driver->hw_params)
343e2cb4a14SKuninori Morimoto 		return component->driver->hw_params(component,
344e2cb4a14SKuninori Morimoto 						    substream, params);
345245c539aSKuninori Morimoto 	return 0;
346245c539aSKuninori Morimoto }
347eae7136aSKuninori Morimoto 
348eae7136aSKuninori Morimoto int snd_soc_component_hw_free(struct snd_soc_component *component,
349eae7136aSKuninori Morimoto 			       struct snd_pcm_substream *substream)
350eae7136aSKuninori Morimoto {
351e2cb4a14SKuninori Morimoto 	if (component->driver->hw_free)
352e2cb4a14SKuninori Morimoto 		return component->driver->hw_free(component, substream);
353eae7136aSKuninori Morimoto 	return 0;
354eae7136aSKuninori Morimoto }
3555693d50cSKuninori Morimoto 
3565693d50cSKuninori Morimoto int snd_soc_component_trigger(struct snd_soc_component *component,
3575693d50cSKuninori Morimoto 			      struct snd_pcm_substream *substream,
3585693d50cSKuninori Morimoto 			      int cmd)
3595693d50cSKuninori Morimoto {
360e2cb4a14SKuninori Morimoto 	if (component->driver->trigger)
361e2cb4a14SKuninori Morimoto 		return component->driver->trigger(component, substream, cmd);
3625693d50cSKuninori Morimoto 	return 0;
3635693d50cSKuninori Morimoto }
36466c51573SKuninori Morimoto 
36566c51573SKuninori Morimoto void snd_soc_component_suspend(struct snd_soc_component *component)
36666c51573SKuninori Morimoto {
36766c51573SKuninori Morimoto 	if (component->driver->suspend)
36866c51573SKuninori Morimoto 		component->driver->suspend(component);
36966c51573SKuninori Morimoto 	component->suspended = 1;
37066c51573SKuninori Morimoto }
3719a840cbaSKuninori Morimoto 
3729a840cbaSKuninori Morimoto void snd_soc_component_resume(struct snd_soc_component *component)
3739a840cbaSKuninori Morimoto {
3749a840cbaSKuninori Morimoto 	if (component->driver->resume)
3759a840cbaSKuninori Morimoto 		component->driver->resume(component);
3769a840cbaSKuninori Morimoto 	component->suspended = 0;
3779a840cbaSKuninori Morimoto }
378e40fadbcSKuninori Morimoto 
379e40fadbcSKuninori Morimoto int snd_soc_component_is_suspended(struct snd_soc_component *component)
380e40fadbcSKuninori Morimoto {
381e40fadbcSKuninori Morimoto 	return component->suspended;
382e40fadbcSKuninori Morimoto }
38308e837ddSKuninori Morimoto 
38408e837ddSKuninori Morimoto int snd_soc_component_probe(struct snd_soc_component *component)
38508e837ddSKuninori Morimoto {
38608e837ddSKuninori Morimoto 	if (component->driver->probe)
38708e837ddSKuninori Morimoto 		return component->driver->probe(component);
38808e837ddSKuninori Morimoto 
38908e837ddSKuninori Morimoto 	return 0;
39008e837ddSKuninori Morimoto }
39103b34dd7SKuninori Morimoto 
39203b34dd7SKuninori Morimoto void snd_soc_component_remove(struct snd_soc_component *component)
39303b34dd7SKuninori Morimoto {
39403b34dd7SKuninori Morimoto 	if (component->driver->remove)
39503b34dd7SKuninori Morimoto 		component->driver->remove(component);
39603b34dd7SKuninori Morimoto }
3972c7b1704SKuninori Morimoto 
3982c7b1704SKuninori Morimoto int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
3992c7b1704SKuninori Morimoto 				      struct device_node *ep)
4002c7b1704SKuninori Morimoto {
4012c7b1704SKuninori Morimoto 	if (component->driver->of_xlate_dai_id)
4022c7b1704SKuninori Morimoto 		return component->driver->of_xlate_dai_id(component, ep);
4032c7b1704SKuninori Morimoto 
4042c7b1704SKuninori Morimoto 	return -ENOTSUPP;
4052c7b1704SKuninori Morimoto }
406a2a34175SKuninori Morimoto 
407a2a34175SKuninori Morimoto int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
408a2a34175SKuninori Morimoto 					struct of_phandle_args *args,
409a2a34175SKuninori Morimoto 					const char **dai_name)
410a2a34175SKuninori Morimoto {
411a2a34175SKuninori Morimoto 	if (component->driver->of_xlate_dai_name)
412a2a34175SKuninori Morimoto 		return component->driver->of_xlate_dai_name(component,
413a2a34175SKuninori Morimoto 						     args, dai_name);
414a2a34175SKuninori Morimoto 	return -ENOTSUPP;
415a2a34175SKuninori Morimoto }
4160035e256SKuninori Morimoto 
4170035e256SKuninori Morimoto int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
4180035e256SKuninori Morimoto {
4190035e256SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
4200035e256SKuninori Morimoto 	struct snd_soc_component *component;
4210035e256SKuninori Morimoto 	struct snd_soc_rtdcom_list *rtdcom;
4220035e256SKuninori Morimoto 
4230035e256SKuninori Morimoto 	/* FIXME: use 1st pointer */
4242b544dd7SKuninori Morimoto 	for_each_rtd_components(rtd, rtdcom, component)
425e2cb4a14SKuninori Morimoto 		if (component->driver->pointer)
426e2cb4a14SKuninori Morimoto 			return component->driver->pointer(component, substream);
4270035e256SKuninori Morimoto 
4280035e256SKuninori Morimoto 	return 0;
4290035e256SKuninori Morimoto }
43096a47908SKuninori Morimoto 
43196a47908SKuninori Morimoto int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
43296a47908SKuninori Morimoto 				unsigned int cmd, void *arg)
43396a47908SKuninori Morimoto {
43496a47908SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
43596a47908SKuninori Morimoto 	struct snd_soc_component *component;
43696a47908SKuninori Morimoto 	struct snd_soc_rtdcom_list *rtdcom;
43796a47908SKuninori Morimoto 
43896a47908SKuninori Morimoto 	/* FIXME: use 1st ioctl */
4392b544dd7SKuninori Morimoto 	for_each_rtd_components(rtd, rtdcom, component)
440e2cb4a14SKuninori Morimoto 		if (component->driver->ioctl)
441e2cb4a14SKuninori Morimoto 			return component->driver->ioctl(component, substream,
442e2cb4a14SKuninori Morimoto 							cmd, arg);
44396a47908SKuninori Morimoto 
44496a47908SKuninori Morimoto 	return snd_pcm_lib_ioctl(substream, cmd, arg);
44596a47908SKuninori Morimoto }
44682d81f5cSKuninori Morimoto 
4471e5ddb6bSTakashi Iwai int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream)
4481e5ddb6bSTakashi Iwai {
4491e5ddb6bSTakashi Iwai 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
4501e5ddb6bSTakashi Iwai 	struct snd_soc_component *component;
4511e5ddb6bSTakashi Iwai 	struct snd_soc_rtdcom_list *rtdcom;
4521e5ddb6bSTakashi Iwai 	int ret;
4531e5ddb6bSTakashi Iwai 
4541e5ddb6bSTakashi Iwai 	for_each_rtd_components(rtd, rtdcom, component) {
4551e5ddb6bSTakashi Iwai 		if (component->driver->ioctl) {
4561e5ddb6bSTakashi Iwai 			ret = component->driver->sync_stop(component,
4571e5ddb6bSTakashi Iwai 							   substream);
4581e5ddb6bSTakashi Iwai 			if (ret < 0)
4591e5ddb6bSTakashi Iwai 				return ret;
4601e5ddb6bSTakashi Iwai 		}
4611e5ddb6bSTakashi Iwai 	}
4621e5ddb6bSTakashi Iwai 
4631e5ddb6bSTakashi Iwai 	return 0;
4641e5ddb6bSTakashi Iwai }
4651e5ddb6bSTakashi Iwai 
46682d81f5cSKuninori Morimoto int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
46782d81f5cSKuninori Morimoto 				    int channel, unsigned long pos,
46882d81f5cSKuninori Morimoto 				    void __user *buf, unsigned long bytes)
46982d81f5cSKuninori Morimoto {
47082d81f5cSKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
47182d81f5cSKuninori Morimoto 	struct snd_soc_rtdcom_list *rtdcom;
47282d81f5cSKuninori Morimoto 	struct snd_soc_component *component;
47382d81f5cSKuninori Morimoto 
47482d81f5cSKuninori Morimoto 	/* FIXME. it returns 1st copy now */
4752b544dd7SKuninori Morimoto 	for_each_rtd_components(rtd, rtdcom, component)
476e2cb4a14SKuninori Morimoto 		if (component->driver->copy_user)
477e2cb4a14SKuninori Morimoto 			return component->driver->copy_user(
478e2cb4a14SKuninori Morimoto 				component, substream, channel, pos, buf, bytes);
47982d81f5cSKuninori Morimoto 
48082d81f5cSKuninori Morimoto 	return -EINVAL;
48182d81f5cSKuninori Morimoto }
4829c712e4fSKuninori Morimoto 
4839c712e4fSKuninori Morimoto struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
4849c712e4fSKuninori Morimoto 					unsigned long offset)
4859c712e4fSKuninori Morimoto {
4869c712e4fSKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
4879c712e4fSKuninori Morimoto 	struct snd_soc_rtdcom_list *rtdcom;
4889c712e4fSKuninori Morimoto 	struct snd_soc_component *component;
4899c712e4fSKuninori Morimoto 	struct page *page;
4909c712e4fSKuninori Morimoto 
4919c712e4fSKuninori Morimoto 	/* FIXME. it returns 1st page now */
4922b544dd7SKuninori Morimoto 	for_each_rtd_components(rtd, rtdcom, component) {
493e2cb4a14SKuninori Morimoto 		if (component->driver->page) {
494e2cb4a14SKuninori Morimoto 			page = component->driver->page(component,
495e2cb4a14SKuninori Morimoto 						       substream, offset);
496e2cb4a14SKuninori Morimoto 			if (page)
497e2cb4a14SKuninori Morimoto 				return page;
498e2cb4a14SKuninori Morimoto 		}
4999c712e4fSKuninori Morimoto 	}
5009c712e4fSKuninori Morimoto 
5019c712e4fSKuninori Morimoto 	return NULL;
5029c712e4fSKuninori Morimoto }
503205875e1SKuninori Morimoto 
504205875e1SKuninori Morimoto int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
505205875e1SKuninori Morimoto 			       struct vm_area_struct *vma)
506205875e1SKuninori Morimoto {
507205875e1SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
508205875e1SKuninori Morimoto 	struct snd_soc_rtdcom_list *rtdcom;
509205875e1SKuninori Morimoto 	struct snd_soc_component *component;
510205875e1SKuninori Morimoto 
511205875e1SKuninori Morimoto 	/* FIXME. it returns 1st mmap now */
5122b544dd7SKuninori Morimoto 	for_each_rtd_components(rtd, rtdcom, component)
513e2cb4a14SKuninori Morimoto 		if (component->driver->mmap)
514e2cb4a14SKuninori Morimoto 			return component->driver->mmap(component,
515e2cb4a14SKuninori Morimoto 						       substream, vma);
516205875e1SKuninori Morimoto 
517205875e1SKuninori Morimoto 	return -EINVAL;
518205875e1SKuninori Morimoto }
5197484291eSKuninori Morimoto 
5207484291eSKuninori Morimoto int snd_soc_pcm_component_new(struct snd_pcm *pcm)
5217484291eSKuninori Morimoto {
5227484291eSKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = pcm->private_data;
5237484291eSKuninori Morimoto 	struct snd_soc_rtdcom_list *rtdcom;
5247484291eSKuninori Morimoto 	struct snd_soc_component *component;
5257484291eSKuninori Morimoto 	int ret;
5267484291eSKuninori Morimoto 
5272b544dd7SKuninori Morimoto 	for_each_rtd_components(rtd, rtdcom, component) {
528c64bfc90SKuninori Morimoto 		if (component->driver->pcm_construct) {
529c64bfc90SKuninori Morimoto 			ret = component->driver->pcm_construct(component, rtd);
530c64bfc90SKuninori Morimoto 			if (ret < 0)
531c64bfc90SKuninori Morimoto 				return ret;
532c64bfc90SKuninori Morimoto 		}
5337484291eSKuninori Morimoto 	}
5347484291eSKuninori Morimoto 
5357484291eSKuninori Morimoto 	return 0;
5367484291eSKuninori Morimoto }
53779776da0SKuninori Morimoto 
53879776da0SKuninori Morimoto void snd_soc_pcm_component_free(struct snd_pcm *pcm)
53979776da0SKuninori Morimoto {
54079776da0SKuninori Morimoto 	struct snd_soc_pcm_runtime *rtd = pcm->private_data;
54179776da0SKuninori Morimoto 	struct snd_soc_rtdcom_list *rtdcom;
54279776da0SKuninori Morimoto 	struct snd_soc_component *component;
54379776da0SKuninori Morimoto 
5442b544dd7SKuninori Morimoto 	for_each_rtd_components(rtd, rtdcom, component)
545c64bfc90SKuninori Morimoto 		if (component->driver->pcm_destruct)
546c64bfc90SKuninori Morimoto 			component->driver->pcm_destruct(component, pcm);
54779776da0SKuninori Morimoto }
548