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 804ca8701eSKuninori Morimoto static int soc_component_pin(struct snd_soc_component *component, 814ca8701eSKuninori Morimoto const char *pin, 824ca8701eSKuninori Morimoto int (*pin_func)(struct snd_soc_dapm_context *dapm, 834ca8701eSKuninori Morimoto const char *pin)) 844ff1fef1SKuninori Morimoto { 854ff1fef1SKuninori Morimoto struct snd_soc_dapm_context *dapm = 864ff1fef1SKuninori Morimoto snd_soc_component_get_dapm(component); 874ff1fef1SKuninori Morimoto char *full_name; 884ff1fef1SKuninori Morimoto int ret; 894ff1fef1SKuninori Morimoto 904ff1fef1SKuninori Morimoto if (!component->name_prefix) 914ca8701eSKuninori Morimoto return pin_func(dapm, pin); 924ff1fef1SKuninori Morimoto 934ff1fef1SKuninori Morimoto full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin); 944ff1fef1SKuninori Morimoto if (!full_name) 954ff1fef1SKuninori Morimoto return -ENOMEM; 964ff1fef1SKuninori Morimoto 974ca8701eSKuninori Morimoto ret = pin_func(dapm, full_name); 984ff1fef1SKuninori Morimoto kfree(full_name); 994ff1fef1SKuninori Morimoto 1004ff1fef1SKuninori Morimoto return ret; 1014ff1fef1SKuninori Morimoto } 1024ca8701eSKuninori Morimoto 1034ca8701eSKuninori Morimoto int snd_soc_component_enable_pin(struct snd_soc_component *component, 1044ca8701eSKuninori Morimoto const char *pin) 1054ca8701eSKuninori Morimoto { 1064ca8701eSKuninori Morimoto return soc_component_pin(component, pin, snd_soc_dapm_enable_pin); 1074ca8701eSKuninori Morimoto } 1084ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin); 1094ff1fef1SKuninori Morimoto 1104ff1fef1SKuninori Morimoto int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component, 1114ff1fef1SKuninori Morimoto const char *pin) 1124ff1fef1SKuninori Morimoto { 1134ca8701eSKuninori Morimoto return soc_component_pin(component, pin, snd_soc_dapm_enable_pin_unlocked); 1144ff1fef1SKuninori Morimoto } 1154ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked); 1164ff1fef1SKuninori Morimoto 1174ff1fef1SKuninori Morimoto int snd_soc_component_disable_pin(struct snd_soc_component *component, 1184ff1fef1SKuninori Morimoto const char *pin) 1194ff1fef1SKuninori Morimoto { 1204ca8701eSKuninori Morimoto return soc_component_pin(component, pin, snd_soc_dapm_disable_pin); 1214ff1fef1SKuninori Morimoto } 1224ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin); 1234ff1fef1SKuninori Morimoto 1244ff1fef1SKuninori Morimoto int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component, 1254ff1fef1SKuninori Morimoto const char *pin) 1264ff1fef1SKuninori Morimoto { 1274ca8701eSKuninori Morimoto return soc_component_pin(component, pin, snd_soc_dapm_disable_pin_unlocked); 1284ff1fef1SKuninori Morimoto } 1294ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked); 1304ff1fef1SKuninori Morimoto 1314ff1fef1SKuninori Morimoto int snd_soc_component_nc_pin(struct snd_soc_component *component, 1324ff1fef1SKuninori Morimoto const char *pin) 1334ff1fef1SKuninori Morimoto { 1344ca8701eSKuninori Morimoto return soc_component_pin(component, pin, snd_soc_dapm_nc_pin); 1354ff1fef1SKuninori Morimoto } 1364ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin); 1374ff1fef1SKuninori Morimoto 1384ff1fef1SKuninori Morimoto int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component, 1394ff1fef1SKuninori Morimoto const char *pin) 1404ff1fef1SKuninori Morimoto { 1414ca8701eSKuninori Morimoto return soc_component_pin(component, pin, snd_soc_dapm_nc_pin_unlocked); 1424ff1fef1SKuninori Morimoto } 1434ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked); 1444ff1fef1SKuninori Morimoto 1454ff1fef1SKuninori Morimoto int snd_soc_component_get_pin_status(struct snd_soc_component *component, 1464ff1fef1SKuninori Morimoto const char *pin) 1474ff1fef1SKuninori Morimoto { 1484ca8701eSKuninori Morimoto return soc_component_pin(component, pin, snd_soc_dapm_get_pin_status); 1494ff1fef1SKuninori Morimoto } 1504ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status); 1514ff1fef1SKuninori Morimoto 1524ff1fef1SKuninori Morimoto int snd_soc_component_force_enable_pin(struct snd_soc_component *component, 1534ff1fef1SKuninori Morimoto const char *pin) 1544ff1fef1SKuninori Morimoto { 1554ca8701eSKuninori Morimoto return soc_component_pin(component, pin, snd_soc_dapm_force_enable_pin); 1564ff1fef1SKuninori Morimoto } 1574ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin); 1584ff1fef1SKuninori Morimoto 1594ff1fef1SKuninori Morimoto int snd_soc_component_force_enable_pin_unlocked( 1604ff1fef1SKuninori Morimoto struct snd_soc_component *component, 1614ff1fef1SKuninori Morimoto const char *pin) 1624ff1fef1SKuninori Morimoto { 1634ca8701eSKuninori Morimoto return soc_component_pin(component, pin, snd_soc_dapm_force_enable_pin_unlocked); 1644ff1fef1SKuninori Morimoto } 1654ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked); 1664ff1fef1SKuninori Morimoto 1674ff1fef1SKuninori Morimoto /** 1684ff1fef1SKuninori Morimoto * snd_soc_component_set_jack - configure component jack. 1694ff1fef1SKuninori Morimoto * @component: COMPONENTs 1704ff1fef1SKuninori Morimoto * @jack: structure to use for the jack 1714ff1fef1SKuninori Morimoto * @data: can be used if codec driver need extra data for configuring jack 1724ff1fef1SKuninori Morimoto * 1734ff1fef1SKuninori Morimoto * Configures and enables jack detection function. 1744ff1fef1SKuninori Morimoto */ 1754ff1fef1SKuninori Morimoto int snd_soc_component_set_jack(struct snd_soc_component *component, 1764ff1fef1SKuninori Morimoto struct snd_soc_jack *jack, void *data) 1774ff1fef1SKuninori Morimoto { 1784ff1fef1SKuninori Morimoto if (component->driver->set_jack) 1794ff1fef1SKuninori Morimoto return component->driver->set_jack(component, jack, data); 1804ff1fef1SKuninori Morimoto 1814ff1fef1SKuninori Morimoto return -ENOTSUPP; 1824ff1fef1SKuninori Morimoto } 1834ff1fef1SKuninori Morimoto EXPORT_SYMBOL_GPL(snd_soc_component_set_jack); 1844a81e8f3SKuninori Morimoto 1854a81e8f3SKuninori Morimoto int snd_soc_component_module_get(struct snd_soc_component *component, 1864a81e8f3SKuninori Morimoto int upon_open) 1874a81e8f3SKuninori Morimoto { 1884a81e8f3SKuninori Morimoto if (component->driver->module_get_upon_open == !!upon_open && 1894a81e8f3SKuninori Morimoto !try_module_get(component->dev->driver->owner)) 1904a81e8f3SKuninori Morimoto return -ENODEV; 1914a81e8f3SKuninori Morimoto 1924a81e8f3SKuninori Morimoto return 0; 1934a81e8f3SKuninori Morimoto } 1944a81e8f3SKuninori Morimoto 1954a81e8f3SKuninori Morimoto void snd_soc_component_module_put(struct snd_soc_component *component, 1964a81e8f3SKuninori Morimoto int upon_open) 1974a81e8f3SKuninori Morimoto { 1984a81e8f3SKuninori Morimoto if (component->driver->module_get_upon_open == !!upon_open) 1994a81e8f3SKuninori Morimoto module_put(component->dev->driver->owner); 2004a81e8f3SKuninori Morimoto } 201ae2f4849SKuninori Morimoto 202ae2f4849SKuninori Morimoto int snd_soc_component_open(struct snd_soc_component *component, 203ae2f4849SKuninori Morimoto struct snd_pcm_substream *substream) 204ae2f4849SKuninori Morimoto { 205e2cb4a14SKuninori Morimoto if (component->driver->open) 206e2cb4a14SKuninori Morimoto return component->driver->open(component, substream); 207ae2f4849SKuninori Morimoto return 0; 208ae2f4849SKuninori Morimoto } 2093672beb8SKuninori Morimoto 2103672beb8SKuninori Morimoto int snd_soc_component_close(struct snd_soc_component *component, 2113672beb8SKuninori Morimoto struct snd_pcm_substream *substream) 2123672beb8SKuninori Morimoto { 213e2cb4a14SKuninori Morimoto if (component->driver->close) 214e2cb4a14SKuninori Morimoto return component->driver->close(component, substream); 2153672beb8SKuninori Morimoto return 0; 2163672beb8SKuninori Morimoto } 2176d537233SKuninori Morimoto 2186d537233SKuninori Morimoto int snd_soc_component_prepare(struct snd_soc_component *component, 2196d537233SKuninori Morimoto struct snd_pcm_substream *substream) 2206d537233SKuninori Morimoto { 221e2cb4a14SKuninori Morimoto if (component->driver->prepare) 222e2cb4a14SKuninori Morimoto return component->driver->prepare(component, substream); 2236d537233SKuninori Morimoto return 0; 2246d537233SKuninori Morimoto } 225245c539aSKuninori Morimoto 226245c539aSKuninori Morimoto int snd_soc_component_hw_params(struct snd_soc_component *component, 227245c539aSKuninori Morimoto struct snd_pcm_substream *substream, 228245c539aSKuninori Morimoto struct snd_pcm_hw_params *params) 229245c539aSKuninori Morimoto { 230e2cb4a14SKuninori Morimoto if (component->driver->hw_params) 231e2cb4a14SKuninori Morimoto return component->driver->hw_params(component, 232e2cb4a14SKuninori Morimoto substream, params); 233245c539aSKuninori Morimoto return 0; 234245c539aSKuninori Morimoto } 235eae7136aSKuninori Morimoto 236eae7136aSKuninori Morimoto int snd_soc_component_hw_free(struct snd_soc_component *component, 237eae7136aSKuninori Morimoto struct snd_pcm_substream *substream) 238eae7136aSKuninori Morimoto { 239e2cb4a14SKuninori Morimoto if (component->driver->hw_free) 240e2cb4a14SKuninori Morimoto return component->driver->hw_free(component, substream); 241eae7136aSKuninori Morimoto return 0; 242eae7136aSKuninori Morimoto } 2435693d50cSKuninori Morimoto 2445693d50cSKuninori Morimoto int snd_soc_component_trigger(struct snd_soc_component *component, 2455693d50cSKuninori Morimoto struct snd_pcm_substream *substream, 2465693d50cSKuninori Morimoto int cmd) 2475693d50cSKuninori Morimoto { 248e2cb4a14SKuninori Morimoto if (component->driver->trigger) 249e2cb4a14SKuninori Morimoto return component->driver->trigger(component, substream, cmd); 2505693d50cSKuninori Morimoto return 0; 2515693d50cSKuninori Morimoto } 25266c51573SKuninori Morimoto 25366c51573SKuninori Morimoto void snd_soc_component_suspend(struct snd_soc_component *component) 25466c51573SKuninori Morimoto { 25566c51573SKuninori Morimoto if (component->driver->suspend) 25666c51573SKuninori Morimoto component->driver->suspend(component); 25766c51573SKuninori Morimoto component->suspended = 1; 25866c51573SKuninori Morimoto } 2599a840cbaSKuninori Morimoto 2609a840cbaSKuninori Morimoto void snd_soc_component_resume(struct snd_soc_component *component) 2619a840cbaSKuninori Morimoto { 2629a840cbaSKuninori Morimoto if (component->driver->resume) 2639a840cbaSKuninori Morimoto component->driver->resume(component); 2649a840cbaSKuninori Morimoto component->suspended = 0; 2659a840cbaSKuninori Morimoto } 266e40fadbcSKuninori Morimoto 267e40fadbcSKuninori Morimoto int snd_soc_component_is_suspended(struct snd_soc_component *component) 268e40fadbcSKuninori Morimoto { 269e40fadbcSKuninori Morimoto return component->suspended; 270e40fadbcSKuninori Morimoto } 27108e837ddSKuninori Morimoto 27208e837ddSKuninori Morimoto int snd_soc_component_probe(struct snd_soc_component *component) 27308e837ddSKuninori Morimoto { 27408e837ddSKuninori Morimoto if (component->driver->probe) 27508e837ddSKuninori Morimoto return component->driver->probe(component); 27608e837ddSKuninori Morimoto 27708e837ddSKuninori Morimoto return 0; 27808e837ddSKuninori Morimoto } 27903b34dd7SKuninori Morimoto 28003b34dd7SKuninori Morimoto void snd_soc_component_remove(struct snd_soc_component *component) 28103b34dd7SKuninori Morimoto { 28203b34dd7SKuninori Morimoto if (component->driver->remove) 28303b34dd7SKuninori Morimoto component->driver->remove(component); 28403b34dd7SKuninori Morimoto } 2852c7b1704SKuninori Morimoto 2862c7b1704SKuninori Morimoto int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component, 2872c7b1704SKuninori Morimoto struct device_node *ep) 2882c7b1704SKuninori Morimoto { 2892c7b1704SKuninori Morimoto if (component->driver->of_xlate_dai_id) 2902c7b1704SKuninori Morimoto return component->driver->of_xlate_dai_id(component, ep); 2912c7b1704SKuninori Morimoto 2922c7b1704SKuninori Morimoto return -ENOTSUPP; 2932c7b1704SKuninori Morimoto } 294a2a34175SKuninori Morimoto 295a2a34175SKuninori Morimoto int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component, 296a2a34175SKuninori Morimoto struct of_phandle_args *args, 297a2a34175SKuninori Morimoto const char **dai_name) 298a2a34175SKuninori Morimoto { 299a2a34175SKuninori Morimoto if (component->driver->of_xlate_dai_name) 300a2a34175SKuninori Morimoto return component->driver->of_xlate_dai_name(component, 301a2a34175SKuninori Morimoto args, dai_name); 302a2a34175SKuninori Morimoto return -ENOTSUPP; 303a2a34175SKuninori Morimoto } 3040035e256SKuninori Morimoto 3050035e256SKuninori Morimoto int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream) 3060035e256SKuninori Morimoto { 3070035e256SKuninori Morimoto struct snd_soc_pcm_runtime *rtd = substream->private_data; 3080035e256SKuninori Morimoto struct snd_soc_component *component; 309613fb500SKuninori Morimoto int i; 3100035e256SKuninori Morimoto 3110035e256SKuninori Morimoto /* FIXME: use 1st pointer */ 312613fb500SKuninori Morimoto for_each_rtd_components(rtd, i, component) 313e2cb4a14SKuninori Morimoto if (component->driver->pointer) 314e2cb4a14SKuninori Morimoto return component->driver->pointer(component, substream); 3150035e256SKuninori Morimoto 3160035e256SKuninori Morimoto return 0; 3170035e256SKuninori Morimoto } 31896a47908SKuninori Morimoto 31996a47908SKuninori Morimoto int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream, 32096a47908SKuninori Morimoto unsigned int cmd, void *arg) 32196a47908SKuninori Morimoto { 32296a47908SKuninori Morimoto struct snd_soc_pcm_runtime *rtd = substream->private_data; 32396a47908SKuninori Morimoto struct snd_soc_component *component; 324613fb500SKuninori Morimoto int i; 32596a47908SKuninori Morimoto 32696a47908SKuninori Morimoto /* FIXME: use 1st ioctl */ 327613fb500SKuninori Morimoto for_each_rtd_components(rtd, i, component) 328e2cb4a14SKuninori Morimoto if (component->driver->ioctl) 329e2cb4a14SKuninori Morimoto return component->driver->ioctl(component, substream, 330e2cb4a14SKuninori Morimoto cmd, arg); 33196a47908SKuninori Morimoto 33296a47908SKuninori Morimoto return snd_pcm_lib_ioctl(substream, cmd, arg); 33396a47908SKuninori Morimoto } 33482d81f5cSKuninori Morimoto 3351e5ddb6bSTakashi Iwai int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream) 3361e5ddb6bSTakashi Iwai { 3371e5ddb6bSTakashi Iwai struct snd_soc_pcm_runtime *rtd = substream->private_data; 3381e5ddb6bSTakashi Iwai struct snd_soc_component *component; 339613fb500SKuninori Morimoto int i, ret; 3401e5ddb6bSTakashi Iwai 341613fb500SKuninori Morimoto for_each_rtd_components(rtd, i, component) { 342f1861a7cSKuninori Morimoto if (component->driver->sync_stop) { 3431e5ddb6bSTakashi Iwai ret = component->driver->sync_stop(component, 3441e5ddb6bSTakashi Iwai substream); 3451e5ddb6bSTakashi Iwai if (ret < 0) 3461e5ddb6bSTakashi Iwai return ret; 3471e5ddb6bSTakashi Iwai } 3481e5ddb6bSTakashi Iwai } 3491e5ddb6bSTakashi Iwai 3501e5ddb6bSTakashi Iwai return 0; 3511e5ddb6bSTakashi Iwai } 3521e5ddb6bSTakashi Iwai 35382d81f5cSKuninori Morimoto int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream, 35482d81f5cSKuninori Morimoto int channel, unsigned long pos, 35582d81f5cSKuninori Morimoto void __user *buf, unsigned long bytes) 35682d81f5cSKuninori Morimoto { 35782d81f5cSKuninori Morimoto struct snd_soc_pcm_runtime *rtd = substream->private_data; 35882d81f5cSKuninori Morimoto struct snd_soc_component *component; 359613fb500SKuninori Morimoto int i; 36082d81f5cSKuninori Morimoto 36182d81f5cSKuninori Morimoto /* FIXME. it returns 1st copy now */ 362613fb500SKuninori Morimoto for_each_rtd_components(rtd, i, component) 363e2cb4a14SKuninori Morimoto if (component->driver->copy_user) 364e2cb4a14SKuninori Morimoto return component->driver->copy_user( 365e2cb4a14SKuninori Morimoto component, substream, channel, pos, buf, bytes); 36682d81f5cSKuninori Morimoto 36782d81f5cSKuninori Morimoto return -EINVAL; 36882d81f5cSKuninori Morimoto } 3699c712e4fSKuninori Morimoto 3709c712e4fSKuninori Morimoto struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream, 3719c712e4fSKuninori Morimoto unsigned long offset) 3729c712e4fSKuninori Morimoto { 3739c712e4fSKuninori Morimoto struct snd_soc_pcm_runtime *rtd = substream->private_data; 3749c712e4fSKuninori Morimoto struct snd_soc_component *component; 3759c712e4fSKuninori Morimoto struct page *page; 376613fb500SKuninori Morimoto int i; 3779c712e4fSKuninori Morimoto 3789c712e4fSKuninori Morimoto /* FIXME. it returns 1st page now */ 379613fb500SKuninori Morimoto for_each_rtd_components(rtd, i, component) { 380e2cb4a14SKuninori Morimoto if (component->driver->page) { 381e2cb4a14SKuninori Morimoto page = component->driver->page(component, 382e2cb4a14SKuninori Morimoto substream, offset); 383e2cb4a14SKuninori Morimoto if (page) 384e2cb4a14SKuninori Morimoto return page; 385e2cb4a14SKuninori Morimoto } 3869c712e4fSKuninori Morimoto } 3879c712e4fSKuninori Morimoto 3889c712e4fSKuninori Morimoto return NULL; 3899c712e4fSKuninori Morimoto } 390205875e1SKuninori Morimoto 391205875e1SKuninori Morimoto int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream, 392205875e1SKuninori Morimoto struct vm_area_struct *vma) 393205875e1SKuninori Morimoto { 394205875e1SKuninori Morimoto struct snd_soc_pcm_runtime *rtd = substream->private_data; 395205875e1SKuninori Morimoto struct snd_soc_component *component; 396613fb500SKuninori Morimoto int i; 397205875e1SKuninori Morimoto 398205875e1SKuninori Morimoto /* FIXME. it returns 1st mmap now */ 399613fb500SKuninori Morimoto for_each_rtd_components(rtd, i, component) 400e2cb4a14SKuninori Morimoto if (component->driver->mmap) 401e2cb4a14SKuninori Morimoto return component->driver->mmap(component, 402e2cb4a14SKuninori Morimoto substream, vma); 403205875e1SKuninori Morimoto 404205875e1SKuninori Morimoto return -EINVAL; 405205875e1SKuninori Morimoto } 4067484291eSKuninori Morimoto 407b2b2afbbSKuninori Morimoto int snd_soc_pcm_component_new(struct snd_soc_pcm_runtime *rtd) 4087484291eSKuninori Morimoto { 4097484291eSKuninori Morimoto struct snd_soc_component *component; 4107484291eSKuninori Morimoto int ret; 411613fb500SKuninori Morimoto int i; 4127484291eSKuninori Morimoto 413613fb500SKuninori Morimoto for_each_rtd_components(rtd, i, component) { 414c64bfc90SKuninori Morimoto if (component->driver->pcm_construct) { 415c64bfc90SKuninori Morimoto ret = component->driver->pcm_construct(component, rtd); 416c64bfc90SKuninori Morimoto if (ret < 0) 417c64bfc90SKuninori Morimoto return ret; 418c64bfc90SKuninori Morimoto } 4197484291eSKuninori Morimoto } 4207484291eSKuninori Morimoto 4217484291eSKuninori Morimoto return 0; 4227484291eSKuninori Morimoto } 42379776da0SKuninori Morimoto 424b2b2afbbSKuninori Morimoto void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd) 42579776da0SKuninori Morimoto { 42679776da0SKuninori Morimoto struct snd_soc_component *component; 427613fb500SKuninori Morimoto int i; 42879776da0SKuninori Morimoto 4298e3366caSTakashi Iwai if (!rtd->pcm) 4308e3366caSTakashi Iwai return; 4318e3366caSTakashi Iwai 432613fb500SKuninori Morimoto for_each_rtd_components(rtd, i, component) 433c64bfc90SKuninori Morimoto if (component->driver->pcm_destruct) 434b2b2afbbSKuninori Morimoto component->driver->pcm_destruct(component, rtd->pcm); 43579776da0SKuninori Morimoto } 436