2019-07-26 11:49:48 +07:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
//
|
|
|
|
// soc-component.c
|
|
|
|
//
|
|
|
|
// Copyright (C) 2019 Renesas Electronics Corp.
|
|
|
|
// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
|
|
|
//
|
2019-07-26 11:49:54 +07:00
|
|
|
#include <linux/module.h>
|
2019-07-26 11:49:48 +07:00
|
|
|
#include <sound/soc.h>
|
|
|
|
|
|
|
|
/**
|
|
|
|
* snd_soc_component_set_sysclk - configure COMPONENT system or master clock.
|
|
|
|
* @component: COMPONENT
|
|
|
|
* @clk_id: DAI specific clock ID
|
|
|
|
* @source: Source for the clock
|
|
|
|
* @freq: new clock frequency in Hz
|
|
|
|
* @dir: new clock direction - input/output.
|
|
|
|
*
|
|
|
|
* Configures the CODEC master (MCLK) or system (SYSCLK) clocking.
|
|
|
|
*/
|
|
|
|
int snd_soc_component_set_sysclk(struct snd_soc_component *component,
|
|
|
|
int clk_id, int source, unsigned int freq,
|
|
|
|
int dir)
|
|
|
|
{
|
|
|
|
if (component->driver->set_sysclk)
|
|
|
|
return component->driver->set_sysclk(component, clk_id, source,
|
|
|
|
freq, dir);
|
|
|
|
|
|
|
|
return -ENOTSUPP;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_component_set_sysclk);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* snd_soc_component_set_pll - configure component PLL.
|
|
|
|
* @component: COMPONENT
|
|
|
|
* @pll_id: DAI specific PLL ID
|
|
|
|
* @source: DAI specific source for the PLL
|
|
|
|
* @freq_in: PLL input clock frequency in Hz
|
|
|
|
* @freq_out: requested PLL output clock frequency in Hz
|
|
|
|
*
|
|
|
|
* Configures and enables PLL to generate output clock based on input clock.
|
|
|
|
*/
|
|
|
|
int snd_soc_component_set_pll(struct snd_soc_component *component, int pll_id,
|
|
|
|
int source, unsigned int freq_in,
|
|
|
|
unsigned int freq_out)
|
|
|
|
{
|
|
|
|
if (component->driver->set_pll)
|
|
|
|
return component->driver->set_pll(component, pll_id, source,
|
|
|
|
freq_in, freq_out);
|
|
|
|
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_component_set_pll);
|
|
|
|
|
2019-07-26 11:51:35 +07:00
|
|
|
void snd_soc_component_seq_notifier(struct snd_soc_component *component,
|
|
|
|
enum snd_soc_dapm_type type, int subseq)
|
|
|
|
{
|
|
|
|
if (component->driver->seq_notifier)
|
|
|
|
component->driver->seq_notifier(component, type, subseq);
|
|
|
|
}
|
|
|
|
|
2019-07-26 11:51:39 +07:00
|
|
|
int snd_soc_component_stream_event(struct snd_soc_component *component,
|
|
|
|
int event)
|
|
|
|
{
|
|
|
|
if (component->driver->stream_event)
|
|
|
|
return component->driver->stream_event(component, event);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-07-26 11:51:43 +07:00
|
|
|
int snd_soc_component_set_bias_level(struct snd_soc_component *component,
|
|
|
|
enum snd_soc_bias_level level)
|
|
|
|
{
|
|
|
|
if (component->driver->set_bias_level)
|
|
|
|
return component->driver->set_bias_level(component, level);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-07-26 11:49:48 +07:00
|
|
|
int snd_soc_component_enable_pin(struct snd_soc_component *component,
|
|
|
|
const char *pin)
|
|
|
|
{
|
|
|
|
struct snd_soc_dapm_context *dapm =
|
|
|
|
snd_soc_component_get_dapm(component);
|
|
|
|
char *full_name;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!component->name_prefix)
|
|
|
|
return snd_soc_dapm_enable_pin(dapm, pin);
|
|
|
|
|
|
|
|
full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
|
|
|
|
if (!full_name)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
ret = snd_soc_dapm_enable_pin(dapm, full_name);
|
|
|
|
kfree(full_name);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin);
|
|
|
|
|
|
|
|
int snd_soc_component_enable_pin_unlocked(struct snd_soc_component *component,
|
|
|
|
const char *pin)
|
|
|
|
{
|
|
|
|
struct snd_soc_dapm_context *dapm =
|
|
|
|
snd_soc_component_get_dapm(component);
|
|
|
|
char *full_name;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!component->name_prefix)
|
|
|
|
return snd_soc_dapm_enable_pin_unlocked(dapm, pin);
|
|
|
|
|
|
|
|
full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
|
|
|
|
if (!full_name)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
ret = snd_soc_dapm_enable_pin_unlocked(dapm, full_name);
|
|
|
|
kfree(full_name);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_component_enable_pin_unlocked);
|
|
|
|
|
|
|
|
int snd_soc_component_disable_pin(struct snd_soc_component *component,
|
|
|
|
const char *pin)
|
|
|
|
{
|
|
|
|
struct snd_soc_dapm_context *dapm =
|
|
|
|
snd_soc_component_get_dapm(component);
|
|
|
|
char *full_name;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!component->name_prefix)
|
|
|
|
return snd_soc_dapm_disable_pin(dapm, pin);
|
|
|
|
|
|
|
|
full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
|
|
|
|
if (!full_name)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
ret = snd_soc_dapm_disable_pin(dapm, full_name);
|
|
|
|
kfree(full_name);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin);
|
|
|
|
|
|
|
|
int snd_soc_component_disable_pin_unlocked(struct snd_soc_component *component,
|
|
|
|
const char *pin)
|
|
|
|
{
|
|
|
|
struct snd_soc_dapm_context *dapm =
|
|
|
|
snd_soc_component_get_dapm(component);
|
|
|
|
char *full_name;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!component->name_prefix)
|
|
|
|
return snd_soc_dapm_disable_pin_unlocked(dapm, pin);
|
|
|
|
|
|
|
|
full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
|
|
|
|
if (!full_name)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
ret = snd_soc_dapm_disable_pin_unlocked(dapm, full_name);
|
|
|
|
kfree(full_name);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_component_disable_pin_unlocked);
|
|
|
|
|
|
|
|
int snd_soc_component_nc_pin(struct snd_soc_component *component,
|
|
|
|
const char *pin)
|
|
|
|
{
|
|
|
|
struct snd_soc_dapm_context *dapm =
|
|
|
|
snd_soc_component_get_dapm(component);
|
|
|
|
char *full_name;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!component->name_prefix)
|
|
|
|
return snd_soc_dapm_nc_pin(dapm, pin);
|
|
|
|
|
|
|
|
full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
|
|
|
|
if (!full_name)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
ret = snd_soc_dapm_nc_pin(dapm, full_name);
|
|
|
|
kfree(full_name);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin);
|
|
|
|
|
|
|
|
int snd_soc_component_nc_pin_unlocked(struct snd_soc_component *component,
|
|
|
|
const char *pin)
|
|
|
|
{
|
|
|
|
struct snd_soc_dapm_context *dapm =
|
|
|
|
snd_soc_component_get_dapm(component);
|
|
|
|
char *full_name;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!component->name_prefix)
|
|
|
|
return snd_soc_dapm_nc_pin_unlocked(dapm, pin);
|
|
|
|
|
|
|
|
full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
|
|
|
|
if (!full_name)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
ret = snd_soc_dapm_nc_pin_unlocked(dapm, full_name);
|
|
|
|
kfree(full_name);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_component_nc_pin_unlocked);
|
|
|
|
|
|
|
|
int snd_soc_component_get_pin_status(struct snd_soc_component *component,
|
|
|
|
const char *pin)
|
|
|
|
{
|
|
|
|
struct snd_soc_dapm_context *dapm =
|
|
|
|
snd_soc_component_get_dapm(component);
|
|
|
|
char *full_name;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!component->name_prefix)
|
|
|
|
return snd_soc_dapm_get_pin_status(dapm, pin);
|
|
|
|
|
|
|
|
full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
|
|
|
|
if (!full_name)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
ret = snd_soc_dapm_get_pin_status(dapm, full_name);
|
|
|
|
kfree(full_name);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_component_get_pin_status);
|
|
|
|
|
|
|
|
int snd_soc_component_force_enable_pin(struct snd_soc_component *component,
|
|
|
|
const char *pin)
|
|
|
|
{
|
|
|
|
struct snd_soc_dapm_context *dapm =
|
|
|
|
snd_soc_component_get_dapm(component);
|
|
|
|
char *full_name;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!component->name_prefix)
|
|
|
|
return snd_soc_dapm_force_enable_pin(dapm, pin);
|
|
|
|
|
|
|
|
full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
|
|
|
|
if (!full_name)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
ret = snd_soc_dapm_force_enable_pin(dapm, full_name);
|
|
|
|
kfree(full_name);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin);
|
|
|
|
|
|
|
|
int snd_soc_component_force_enable_pin_unlocked(
|
|
|
|
struct snd_soc_component *component,
|
|
|
|
const char *pin)
|
|
|
|
{
|
|
|
|
struct snd_soc_dapm_context *dapm =
|
|
|
|
snd_soc_component_get_dapm(component);
|
|
|
|
char *full_name;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!component->name_prefix)
|
|
|
|
return snd_soc_dapm_force_enable_pin_unlocked(dapm, pin);
|
|
|
|
|
|
|
|
full_name = kasprintf(GFP_KERNEL, "%s %s", component->name_prefix, pin);
|
|
|
|
if (!full_name)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
ret = snd_soc_dapm_force_enable_pin_unlocked(dapm, full_name);
|
|
|
|
kfree(full_name);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_component_force_enable_pin_unlocked);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* snd_soc_component_set_jack - configure component jack.
|
|
|
|
* @component: COMPONENTs
|
|
|
|
* @jack: structure to use for the jack
|
|
|
|
* @data: can be used if codec driver need extra data for configuring jack
|
|
|
|
*
|
|
|
|
* Configures and enables jack detection function.
|
|
|
|
*/
|
|
|
|
int snd_soc_component_set_jack(struct snd_soc_component *component,
|
|
|
|
struct snd_soc_jack *jack, void *data)
|
|
|
|
{
|
|
|
|
if (component->driver->set_jack)
|
|
|
|
return component->driver->set_jack(component, jack, data);
|
|
|
|
|
|
|
|
return -ENOTSUPP;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(snd_soc_component_set_jack);
|
2019-07-26 11:49:54 +07:00
|
|
|
|
|
|
|
int snd_soc_component_module_get(struct snd_soc_component *component,
|
|
|
|
int upon_open)
|
|
|
|
{
|
|
|
|
if (component->driver->module_get_upon_open == !!upon_open &&
|
|
|
|
!try_module_get(component->dev->driver->owner))
|
|
|
|
return -ENODEV;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void snd_soc_component_module_put(struct snd_soc_component *component,
|
|
|
|
int upon_open)
|
|
|
|
{
|
|
|
|
if (component->driver->module_get_upon_open == !!upon_open)
|
|
|
|
module_put(component->dev->driver->owner);
|
|
|
|
}
|
2019-07-26 11:50:01 +07:00
|
|
|
|
|
|
|
int snd_soc_component_open(struct snd_soc_component *component,
|
|
|
|
struct snd_pcm_substream *substream)
|
|
|
|
{
|
ASoC: soc-core: merge snd_pcm_ops member to component driver
Current snd_soc_component_driver has snd_pcm_ops, and each driver can
have callback via it (1).
But, it is mainly created for ALSA, thus, it doesn't have "component"
as parameter for ALSA SoC (1)(2).
Thus, each callback can't know it is called for which component.
Thus, each callback currently is getting "component" by using
snd_soc_rtdcom_lookup() with driver name (3).
--- ALSA SoC ---
...
if (component->driver->ops &&
component->driver->ops->open)
(1) return component->driver->ops->open(substream);
...
--- driver ---
(2) static int xxx_open(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
(3) struct snd_soc_component *component = snd_soc_rtdcom_lookup(..);
...
}
It works today, but, will not work in the future if we support multi
CPU/Codec/Platform, because 1 rtd might have multiple components which
have same driver name.
To solve this issue, each callback needs to be called with component.
We already have many component driver callback.
This patch copies each snd_pcm_ops member under component driver,
and having "component" as parameter.
--- ALSA SoC ---
...
if (component->driver->open)
=> return component->driver->open(component, substream);
...
--- driver ---
=> static int xxx_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
...
}
*Note*
Only Intel skl-pcm has .get_time_info implementation, but ALSA SoC
framework doesn't call it so far.
To keep its implementation, this patch keeps .get_time_info,
but it is still not called.
Intel guy need to support it in the future.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87tv8raf3r.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-10-02 12:30:48 +07:00
|
|
|
if (component->driver->open)
|
|
|
|
return component->driver->open(component, substream);
|
2019-07-26 11:50:01 +07:00
|
|
|
return 0;
|
|
|
|
}
|
2019-07-26 11:50:07 +07:00
|
|
|
|
|
|
|
int snd_soc_component_close(struct snd_soc_component *component,
|
|
|
|
struct snd_pcm_substream *substream)
|
|
|
|
{
|
ASoC: soc-core: merge snd_pcm_ops member to component driver
Current snd_soc_component_driver has snd_pcm_ops, and each driver can
have callback via it (1).
But, it is mainly created for ALSA, thus, it doesn't have "component"
as parameter for ALSA SoC (1)(2).
Thus, each callback can't know it is called for which component.
Thus, each callback currently is getting "component" by using
snd_soc_rtdcom_lookup() with driver name (3).
--- ALSA SoC ---
...
if (component->driver->ops &&
component->driver->ops->open)
(1) return component->driver->ops->open(substream);
...
--- driver ---
(2) static int xxx_open(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
(3) struct snd_soc_component *component = snd_soc_rtdcom_lookup(..);
...
}
It works today, but, will not work in the future if we support multi
CPU/Codec/Platform, because 1 rtd might have multiple components which
have same driver name.
To solve this issue, each callback needs to be called with component.
We already have many component driver callback.
This patch copies each snd_pcm_ops member under component driver,
and having "component" as parameter.
--- ALSA SoC ---
...
if (component->driver->open)
=> return component->driver->open(component, substream);
...
--- driver ---
=> static int xxx_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
...
}
*Note*
Only Intel skl-pcm has .get_time_info implementation, but ALSA SoC
framework doesn't call it so far.
To keep its implementation, this patch keeps .get_time_info,
but it is still not called.
Intel guy need to support it in the future.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87tv8raf3r.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-10-02 12:30:48 +07:00
|
|
|
if (component->driver->close)
|
|
|
|
return component->driver->close(component, substream);
|
2019-07-26 11:50:07 +07:00
|
|
|
return 0;
|
|
|
|
}
|
2019-07-26 11:50:13 +07:00
|
|
|
|
|
|
|
int snd_soc_component_prepare(struct snd_soc_component *component,
|
|
|
|
struct snd_pcm_substream *substream)
|
|
|
|
{
|
ASoC: soc-core: merge snd_pcm_ops member to component driver
Current snd_soc_component_driver has snd_pcm_ops, and each driver can
have callback via it (1).
But, it is mainly created for ALSA, thus, it doesn't have "component"
as parameter for ALSA SoC (1)(2).
Thus, each callback can't know it is called for which component.
Thus, each callback currently is getting "component" by using
snd_soc_rtdcom_lookup() with driver name (3).
--- ALSA SoC ---
...
if (component->driver->ops &&
component->driver->ops->open)
(1) return component->driver->ops->open(substream);
...
--- driver ---
(2) static int xxx_open(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
(3) struct snd_soc_component *component = snd_soc_rtdcom_lookup(..);
...
}
It works today, but, will not work in the future if we support multi
CPU/Codec/Platform, because 1 rtd might have multiple components which
have same driver name.
To solve this issue, each callback needs to be called with component.
We already have many component driver callback.
This patch copies each snd_pcm_ops member under component driver,
and having "component" as parameter.
--- ALSA SoC ---
...
if (component->driver->open)
=> return component->driver->open(component, substream);
...
--- driver ---
=> static int xxx_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
...
}
*Note*
Only Intel skl-pcm has .get_time_info implementation, but ALSA SoC
framework doesn't call it so far.
To keep its implementation, this patch keeps .get_time_info,
but it is still not called.
Intel guy need to support it in the future.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87tv8raf3r.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-10-02 12:30:48 +07:00
|
|
|
if (component->driver->prepare)
|
|
|
|
return component->driver->prepare(component, substream);
|
2019-07-26 11:50:13 +07:00
|
|
|
return 0;
|
|
|
|
}
|
2019-07-26 11:50:19 +07:00
|
|
|
|
|
|
|
int snd_soc_component_hw_params(struct snd_soc_component *component,
|
|
|
|
struct snd_pcm_substream *substream,
|
|
|
|
struct snd_pcm_hw_params *params)
|
|
|
|
{
|
ASoC: soc-core: merge snd_pcm_ops member to component driver
Current snd_soc_component_driver has snd_pcm_ops, and each driver can
have callback via it (1).
But, it is mainly created for ALSA, thus, it doesn't have "component"
as parameter for ALSA SoC (1)(2).
Thus, each callback can't know it is called for which component.
Thus, each callback currently is getting "component" by using
snd_soc_rtdcom_lookup() with driver name (3).
--- ALSA SoC ---
...
if (component->driver->ops &&
component->driver->ops->open)
(1) return component->driver->ops->open(substream);
...
--- driver ---
(2) static int xxx_open(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
(3) struct snd_soc_component *component = snd_soc_rtdcom_lookup(..);
...
}
It works today, but, will not work in the future if we support multi
CPU/Codec/Platform, because 1 rtd might have multiple components which
have same driver name.
To solve this issue, each callback needs to be called with component.
We already have many component driver callback.
This patch copies each snd_pcm_ops member under component driver,
and having "component" as parameter.
--- ALSA SoC ---
...
if (component->driver->open)
=> return component->driver->open(component, substream);
...
--- driver ---
=> static int xxx_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
...
}
*Note*
Only Intel skl-pcm has .get_time_info implementation, but ALSA SoC
framework doesn't call it so far.
To keep its implementation, this patch keeps .get_time_info,
but it is still not called.
Intel guy need to support it in the future.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87tv8raf3r.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-10-02 12:30:48 +07:00
|
|
|
if (component->driver->hw_params)
|
|
|
|
return component->driver->hw_params(component,
|
|
|
|
substream, params);
|
2019-07-26 11:50:19 +07:00
|
|
|
return 0;
|
|
|
|
}
|
2019-07-26 11:50:24 +07:00
|
|
|
|
|
|
|
int snd_soc_component_hw_free(struct snd_soc_component *component,
|
|
|
|
struct snd_pcm_substream *substream)
|
|
|
|
{
|
ASoC: soc-core: merge snd_pcm_ops member to component driver
Current snd_soc_component_driver has snd_pcm_ops, and each driver can
have callback via it (1).
But, it is mainly created for ALSA, thus, it doesn't have "component"
as parameter for ALSA SoC (1)(2).
Thus, each callback can't know it is called for which component.
Thus, each callback currently is getting "component" by using
snd_soc_rtdcom_lookup() with driver name (3).
--- ALSA SoC ---
...
if (component->driver->ops &&
component->driver->ops->open)
(1) return component->driver->ops->open(substream);
...
--- driver ---
(2) static int xxx_open(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
(3) struct snd_soc_component *component = snd_soc_rtdcom_lookup(..);
...
}
It works today, but, will not work in the future if we support multi
CPU/Codec/Platform, because 1 rtd might have multiple components which
have same driver name.
To solve this issue, each callback needs to be called with component.
We already have many component driver callback.
This patch copies each snd_pcm_ops member under component driver,
and having "component" as parameter.
--- ALSA SoC ---
...
if (component->driver->open)
=> return component->driver->open(component, substream);
...
--- driver ---
=> static int xxx_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
...
}
*Note*
Only Intel skl-pcm has .get_time_info implementation, but ALSA SoC
framework doesn't call it so far.
To keep its implementation, this patch keeps .get_time_info,
but it is still not called.
Intel guy need to support it in the future.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87tv8raf3r.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-10-02 12:30:48 +07:00
|
|
|
if (component->driver->hw_free)
|
|
|
|
return component->driver->hw_free(component, substream);
|
2019-07-26 11:50:24 +07:00
|
|
|
return 0;
|
|
|
|
}
|
2019-07-26 11:50:29 +07:00
|
|
|
|
|
|
|
int snd_soc_component_trigger(struct snd_soc_component *component,
|
|
|
|
struct snd_pcm_substream *substream,
|
|
|
|
int cmd)
|
|
|
|
{
|
ASoC: soc-core: merge snd_pcm_ops member to component driver
Current snd_soc_component_driver has snd_pcm_ops, and each driver can
have callback via it (1).
But, it is mainly created for ALSA, thus, it doesn't have "component"
as parameter for ALSA SoC (1)(2).
Thus, each callback can't know it is called for which component.
Thus, each callback currently is getting "component" by using
snd_soc_rtdcom_lookup() with driver name (3).
--- ALSA SoC ---
...
if (component->driver->ops &&
component->driver->ops->open)
(1) return component->driver->ops->open(substream);
...
--- driver ---
(2) static int xxx_open(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
(3) struct snd_soc_component *component = snd_soc_rtdcom_lookup(..);
...
}
It works today, but, will not work in the future if we support multi
CPU/Codec/Platform, because 1 rtd might have multiple components which
have same driver name.
To solve this issue, each callback needs to be called with component.
We already have many component driver callback.
This patch copies each snd_pcm_ops member under component driver,
and having "component" as parameter.
--- ALSA SoC ---
...
if (component->driver->open)
=> return component->driver->open(component, substream);
...
--- driver ---
=> static int xxx_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
...
}
*Note*
Only Intel skl-pcm has .get_time_info implementation, but ALSA SoC
framework doesn't call it so far.
To keep its implementation, this patch keeps .get_time_info,
but it is still not called.
Intel guy need to support it in the future.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87tv8raf3r.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-10-02 12:30:48 +07:00
|
|
|
if (component->driver->trigger)
|
|
|
|
return component->driver->trigger(component, substream, cmd);
|
2019-07-26 11:50:29 +07:00
|
|
|
return 0;
|
|
|
|
}
|
2019-07-26 11:50:34 +07:00
|
|
|
|
|
|
|
void snd_soc_component_suspend(struct snd_soc_component *component)
|
|
|
|
{
|
|
|
|
if (component->driver->suspend)
|
|
|
|
component->driver->suspend(component);
|
|
|
|
component->suspended = 1;
|
|
|
|
}
|
2019-07-26 11:51:08 +07:00
|
|
|
|
|
|
|
void snd_soc_component_resume(struct snd_soc_component *component)
|
|
|
|
{
|
|
|
|
if (component->driver->resume)
|
|
|
|
component->driver->resume(component);
|
|
|
|
component->suspended = 0;
|
|
|
|
}
|
2019-07-26 11:51:13 +07:00
|
|
|
|
|
|
|
int snd_soc_component_is_suspended(struct snd_soc_component *component)
|
|
|
|
{
|
|
|
|
return component->suspended;
|
|
|
|
}
|
2019-07-26 11:51:17 +07:00
|
|
|
|
|
|
|
int snd_soc_component_probe(struct snd_soc_component *component)
|
|
|
|
{
|
|
|
|
if (component->driver->probe)
|
|
|
|
return component->driver->probe(component);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2019-07-26 11:51:22 +07:00
|
|
|
|
|
|
|
void snd_soc_component_remove(struct snd_soc_component *component)
|
|
|
|
{
|
|
|
|
if (component->driver->remove)
|
|
|
|
component->driver->remove(component);
|
|
|
|
}
|
2019-07-26 11:51:26 +07:00
|
|
|
|
|
|
|
int snd_soc_component_of_xlate_dai_id(struct snd_soc_component *component,
|
|
|
|
struct device_node *ep)
|
|
|
|
{
|
|
|
|
if (component->driver->of_xlate_dai_id)
|
|
|
|
return component->driver->of_xlate_dai_id(component, ep);
|
|
|
|
|
|
|
|
return -ENOTSUPP;
|
|
|
|
}
|
2019-07-26 11:51:31 +07:00
|
|
|
|
|
|
|
int snd_soc_component_of_xlate_dai_name(struct snd_soc_component *component,
|
|
|
|
struct of_phandle_args *args,
|
|
|
|
const char **dai_name)
|
|
|
|
{
|
|
|
|
if (component->driver->of_xlate_dai_name)
|
|
|
|
return component->driver->of_xlate_dai_name(component,
|
|
|
|
args, dai_name);
|
|
|
|
return -ENOTSUPP;
|
|
|
|
}
|
2019-07-26 11:51:47 +07:00
|
|
|
|
|
|
|
int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream)
|
|
|
|
{
|
|
|
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
|
|
|
struct snd_soc_component *component;
|
|
|
|
struct snd_soc_rtdcom_list *rtdcom;
|
|
|
|
|
ASoC: soc-core: add for_each_rtd_components() and replace
ALSA SoC has for_each_rtdcom() which is link list for
rtd-component which is called as rtdcom. The relationship image is like below
rtdcom rtdcom rtdcom
component component component
rtd->component_list -> list -> list -> list ...
Here, the pointer get via normal link list is rtdcom,
Thus, current for_each loop is like below, and need to get
component via rtdcom->component
for_each_rtdcom(rtd, rtdcom) {
component = rtdcom->component;
...
}
but usually, user want to get pointer from for_each_xxx is component
directly, like below.
for_each_rtd_component(rtd, rtdcom, component) {
...
}
This patch expands list_for_each_entry manually, and enable to get
component directly from for_each macro.
Because of it, the macro becoming difficult to read,
but macro itself becoming useful.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/878spm64m4.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-10-15 10:59:31 +07:00
|
|
|
/* FIXME: use 1st pointer */
|
|
|
|
for_each_rtd_components(rtd, rtdcom, component)
|
ASoC: soc-core: merge snd_pcm_ops member to component driver
Current snd_soc_component_driver has snd_pcm_ops, and each driver can
have callback via it (1).
But, it is mainly created for ALSA, thus, it doesn't have "component"
as parameter for ALSA SoC (1)(2).
Thus, each callback can't know it is called for which component.
Thus, each callback currently is getting "component" by using
snd_soc_rtdcom_lookup() with driver name (3).
--- ALSA SoC ---
...
if (component->driver->ops &&
component->driver->ops->open)
(1) return component->driver->ops->open(substream);
...
--- driver ---
(2) static int xxx_open(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
(3) struct snd_soc_component *component = snd_soc_rtdcom_lookup(..);
...
}
It works today, but, will not work in the future if we support multi
CPU/Codec/Platform, because 1 rtd might have multiple components which
have same driver name.
To solve this issue, each callback needs to be called with component.
We already have many component driver callback.
This patch copies each snd_pcm_ops member under component driver,
and having "component" as parameter.
--- ALSA SoC ---
...
if (component->driver->open)
=> return component->driver->open(component, substream);
...
--- driver ---
=> static int xxx_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
...
}
*Note*
Only Intel skl-pcm has .get_time_info implementation, but ALSA SoC
framework doesn't call it so far.
To keep its implementation, this patch keeps .get_time_info,
but it is still not called.
Intel guy need to support it in the future.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87tv8raf3r.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-10-02 12:30:48 +07:00
|
|
|
if (component->driver->pointer)
|
|
|
|
return component->driver->pointer(component, substream);
|
2019-07-26 11:51:47 +07:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2019-07-26 11:51:51 +07:00
|
|
|
|
|
|
|
int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream,
|
|
|
|
unsigned int cmd, void *arg)
|
|
|
|
{
|
|
|
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
|
|
|
struct snd_soc_component *component;
|
|
|
|
struct snd_soc_rtdcom_list *rtdcom;
|
|
|
|
|
ASoC: soc-core: add for_each_rtd_components() and replace
ALSA SoC has for_each_rtdcom() which is link list for
rtd-component which is called as rtdcom. The relationship image is like below
rtdcom rtdcom rtdcom
component component component
rtd->component_list -> list -> list -> list ...
Here, the pointer get via normal link list is rtdcom,
Thus, current for_each loop is like below, and need to get
component via rtdcom->component
for_each_rtdcom(rtd, rtdcom) {
component = rtdcom->component;
...
}
but usually, user want to get pointer from for_each_xxx is component
directly, like below.
for_each_rtd_component(rtd, rtdcom, component) {
...
}
This patch expands list_for_each_entry manually, and enable to get
component directly from for_each macro.
Because of it, the macro becoming difficult to read,
but macro itself becoming useful.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/878spm64m4.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-10-15 10:59:31 +07:00
|
|
|
/* FIXME: use 1st ioctl */
|
|
|
|
for_each_rtd_components(rtd, rtdcom, component)
|
ASoC: soc-core: merge snd_pcm_ops member to component driver
Current snd_soc_component_driver has snd_pcm_ops, and each driver can
have callback via it (1).
But, it is mainly created for ALSA, thus, it doesn't have "component"
as parameter for ALSA SoC (1)(2).
Thus, each callback can't know it is called for which component.
Thus, each callback currently is getting "component" by using
snd_soc_rtdcom_lookup() with driver name (3).
--- ALSA SoC ---
...
if (component->driver->ops &&
component->driver->ops->open)
(1) return component->driver->ops->open(substream);
...
--- driver ---
(2) static int xxx_open(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
(3) struct snd_soc_component *component = snd_soc_rtdcom_lookup(..);
...
}
It works today, but, will not work in the future if we support multi
CPU/Codec/Platform, because 1 rtd might have multiple components which
have same driver name.
To solve this issue, each callback needs to be called with component.
We already have many component driver callback.
This patch copies each snd_pcm_ops member under component driver,
and having "component" as parameter.
--- ALSA SoC ---
...
if (component->driver->open)
=> return component->driver->open(component, substream);
...
--- driver ---
=> static int xxx_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
...
}
*Note*
Only Intel skl-pcm has .get_time_info implementation, but ALSA SoC
framework doesn't call it so far.
To keep its implementation, this patch keeps .get_time_info,
but it is still not called.
Intel guy need to support it in the future.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87tv8raf3r.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-10-02 12:30:48 +07:00
|
|
|
if (component->driver->ioctl)
|
|
|
|
return component->driver->ioctl(component, substream,
|
|
|
|
cmd, arg);
|
2019-07-26 11:51:51 +07:00
|
|
|
|
|
|
|
return snd_pcm_lib_ioctl(substream, cmd, arg);
|
|
|
|
}
|
2019-07-26 11:51:56 +07:00
|
|
|
|
2019-11-22 02:07:09 +07:00
|
|
|
int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream)
|
|
|
|
{
|
|
|
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
|
|
|
struct snd_soc_component *component;
|
|
|
|
struct snd_soc_rtdcom_list *rtdcom;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
for_each_rtd_components(rtd, rtdcom, component) {
|
|
|
|
if (component->driver->ioctl) {
|
|
|
|
ret = component->driver->sync_stop(component,
|
|
|
|
substream);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-07-26 11:51:56 +07:00
|
|
|
int snd_soc_pcm_component_copy_user(struct snd_pcm_substream *substream,
|
|
|
|
int channel, unsigned long pos,
|
|
|
|
void __user *buf, unsigned long bytes)
|
|
|
|
{
|
|
|
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
|
|
|
struct snd_soc_rtdcom_list *rtdcom;
|
|
|
|
struct snd_soc_component *component;
|
|
|
|
|
ASoC: soc-core: add for_each_rtd_components() and replace
ALSA SoC has for_each_rtdcom() which is link list for
rtd-component which is called as rtdcom. The relationship image is like below
rtdcom rtdcom rtdcom
component component component
rtd->component_list -> list -> list -> list ...
Here, the pointer get via normal link list is rtdcom,
Thus, current for_each loop is like below, and need to get
component via rtdcom->component
for_each_rtdcom(rtd, rtdcom) {
component = rtdcom->component;
...
}
but usually, user want to get pointer from for_each_xxx is component
directly, like below.
for_each_rtd_component(rtd, rtdcom, component) {
...
}
This patch expands list_for_each_entry manually, and enable to get
component directly from for_each macro.
Because of it, the macro becoming difficult to read,
but macro itself becoming useful.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/878spm64m4.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-10-15 10:59:31 +07:00
|
|
|
/* FIXME. it returns 1st copy now */
|
|
|
|
for_each_rtd_components(rtd, rtdcom, component)
|
ASoC: soc-core: merge snd_pcm_ops member to component driver
Current snd_soc_component_driver has snd_pcm_ops, and each driver can
have callback via it (1).
But, it is mainly created for ALSA, thus, it doesn't have "component"
as parameter for ALSA SoC (1)(2).
Thus, each callback can't know it is called for which component.
Thus, each callback currently is getting "component" by using
snd_soc_rtdcom_lookup() with driver name (3).
--- ALSA SoC ---
...
if (component->driver->ops &&
component->driver->ops->open)
(1) return component->driver->ops->open(substream);
...
--- driver ---
(2) static int xxx_open(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
(3) struct snd_soc_component *component = snd_soc_rtdcom_lookup(..);
...
}
It works today, but, will not work in the future if we support multi
CPU/Codec/Platform, because 1 rtd might have multiple components which
have same driver name.
To solve this issue, each callback needs to be called with component.
We already have many component driver callback.
This patch copies each snd_pcm_ops member under component driver,
and having "component" as parameter.
--- ALSA SoC ---
...
if (component->driver->open)
=> return component->driver->open(component, substream);
...
--- driver ---
=> static int xxx_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
...
}
*Note*
Only Intel skl-pcm has .get_time_info implementation, but ALSA SoC
framework doesn't call it so far.
To keep its implementation, this patch keeps .get_time_info,
but it is still not called.
Intel guy need to support it in the future.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87tv8raf3r.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-10-02 12:30:48 +07:00
|
|
|
if (component->driver->copy_user)
|
|
|
|
return component->driver->copy_user(
|
|
|
|
component, substream, channel, pos, buf, bytes);
|
2019-07-26 11:51:56 +07:00
|
|
|
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2019-07-26 11:52:00 +07:00
|
|
|
|
|
|
|
struct page *snd_soc_pcm_component_page(struct snd_pcm_substream *substream,
|
|
|
|
unsigned long offset)
|
|
|
|
{
|
|
|
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
|
|
|
struct snd_soc_rtdcom_list *rtdcom;
|
|
|
|
struct snd_soc_component *component;
|
|
|
|
struct page *page;
|
|
|
|
|
ASoC: soc-core: add for_each_rtd_components() and replace
ALSA SoC has for_each_rtdcom() which is link list for
rtd-component which is called as rtdcom. The relationship image is like below
rtdcom rtdcom rtdcom
component component component
rtd->component_list -> list -> list -> list ...
Here, the pointer get via normal link list is rtdcom,
Thus, current for_each loop is like below, and need to get
component via rtdcom->component
for_each_rtdcom(rtd, rtdcom) {
component = rtdcom->component;
...
}
but usually, user want to get pointer from for_each_xxx is component
directly, like below.
for_each_rtd_component(rtd, rtdcom, component) {
...
}
This patch expands list_for_each_entry manually, and enable to get
component directly from for_each macro.
Because of it, the macro becoming difficult to read,
but macro itself becoming useful.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/878spm64m4.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-10-15 10:59:31 +07:00
|
|
|
/* FIXME. it returns 1st page now */
|
|
|
|
for_each_rtd_components(rtd, rtdcom, component) {
|
ASoC: soc-core: merge snd_pcm_ops member to component driver
Current snd_soc_component_driver has snd_pcm_ops, and each driver can
have callback via it (1).
But, it is mainly created for ALSA, thus, it doesn't have "component"
as parameter for ALSA SoC (1)(2).
Thus, each callback can't know it is called for which component.
Thus, each callback currently is getting "component" by using
snd_soc_rtdcom_lookup() with driver name (3).
--- ALSA SoC ---
...
if (component->driver->ops &&
component->driver->ops->open)
(1) return component->driver->ops->open(substream);
...
--- driver ---
(2) static int xxx_open(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
(3) struct snd_soc_component *component = snd_soc_rtdcom_lookup(..);
...
}
It works today, but, will not work in the future if we support multi
CPU/Codec/Platform, because 1 rtd might have multiple components which
have same driver name.
To solve this issue, each callback needs to be called with component.
We already have many component driver callback.
This patch copies each snd_pcm_ops member under component driver,
and having "component" as parameter.
--- ALSA SoC ---
...
if (component->driver->open)
=> return component->driver->open(component, substream);
...
--- driver ---
=> static int xxx_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
...
}
*Note*
Only Intel skl-pcm has .get_time_info implementation, but ALSA SoC
framework doesn't call it so far.
To keep its implementation, this patch keeps .get_time_info,
but it is still not called.
Intel guy need to support it in the future.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87tv8raf3r.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-10-02 12:30:48 +07:00
|
|
|
if (component->driver->page) {
|
|
|
|
page = component->driver->page(component,
|
|
|
|
substream, offset);
|
|
|
|
if (page)
|
|
|
|
return page;
|
|
|
|
}
|
2019-07-26 11:52:00 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
2019-07-26 11:52:04 +07:00
|
|
|
|
|
|
|
int snd_soc_pcm_component_mmap(struct snd_pcm_substream *substream,
|
|
|
|
struct vm_area_struct *vma)
|
|
|
|
{
|
|
|
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
|
|
|
struct snd_soc_rtdcom_list *rtdcom;
|
|
|
|
struct snd_soc_component *component;
|
|
|
|
|
ASoC: soc-core: add for_each_rtd_components() and replace
ALSA SoC has for_each_rtdcom() which is link list for
rtd-component which is called as rtdcom. The relationship image is like below
rtdcom rtdcom rtdcom
component component component
rtd->component_list -> list -> list -> list ...
Here, the pointer get via normal link list is rtdcom,
Thus, current for_each loop is like below, and need to get
component via rtdcom->component
for_each_rtdcom(rtd, rtdcom) {
component = rtdcom->component;
...
}
but usually, user want to get pointer from for_each_xxx is component
directly, like below.
for_each_rtd_component(rtd, rtdcom, component) {
...
}
This patch expands list_for_each_entry manually, and enable to get
component directly from for_each macro.
Because of it, the macro becoming difficult to read,
but macro itself becoming useful.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/878spm64m4.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-10-15 10:59:31 +07:00
|
|
|
/* FIXME. it returns 1st mmap now */
|
|
|
|
for_each_rtd_components(rtd, rtdcom, component)
|
ASoC: soc-core: merge snd_pcm_ops member to component driver
Current snd_soc_component_driver has snd_pcm_ops, and each driver can
have callback via it (1).
But, it is mainly created for ALSA, thus, it doesn't have "component"
as parameter for ALSA SoC (1)(2).
Thus, each callback can't know it is called for which component.
Thus, each callback currently is getting "component" by using
snd_soc_rtdcom_lookup() with driver name (3).
--- ALSA SoC ---
...
if (component->driver->ops &&
component->driver->ops->open)
(1) return component->driver->ops->open(substream);
...
--- driver ---
(2) static int xxx_open(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
(3) struct snd_soc_component *component = snd_soc_rtdcom_lookup(..);
...
}
It works today, but, will not work in the future if we support multi
CPU/Codec/Platform, because 1 rtd might have multiple components which
have same driver name.
To solve this issue, each callback needs to be called with component.
We already have many component driver callback.
This patch copies each snd_pcm_ops member under component driver,
and having "component" as parameter.
--- ALSA SoC ---
...
if (component->driver->open)
=> return component->driver->open(component, substream);
...
--- driver ---
=> static int xxx_open(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
...
}
*Note*
Only Intel skl-pcm has .get_time_info implementation, but ALSA SoC
framework doesn't call it so far.
To keep its implementation, this patch keeps .get_time_info,
but it is still not called.
Intel guy need to support it in the future.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87tv8raf3r.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-10-02 12:30:48 +07:00
|
|
|
if (component->driver->mmap)
|
|
|
|
return component->driver->mmap(component,
|
|
|
|
substream, vma);
|
2019-07-26 11:52:04 +07:00
|
|
|
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2019-07-26 11:52:08 +07:00
|
|
|
|
2019-11-18 08:50:32 +07:00
|
|
|
int snd_soc_pcm_component_new(struct snd_soc_pcm_runtime *rtd)
|
2019-07-26 11:52:08 +07:00
|
|
|
{
|
|
|
|
struct snd_soc_rtdcom_list *rtdcom;
|
|
|
|
struct snd_soc_component *component;
|
|
|
|
int ret;
|
|
|
|
|
ASoC: soc-core: add for_each_rtd_components() and replace
ALSA SoC has for_each_rtdcom() which is link list for
rtd-component which is called as rtdcom. The relationship image is like below
rtdcom rtdcom rtdcom
component component component
rtd->component_list -> list -> list -> list ...
Here, the pointer get via normal link list is rtdcom,
Thus, current for_each loop is like below, and need to get
component via rtdcom->component
for_each_rtdcom(rtd, rtdcom) {
component = rtdcom->component;
...
}
but usually, user want to get pointer from for_each_xxx is component
directly, like below.
for_each_rtd_component(rtd, rtdcom, component) {
...
}
This patch expands list_for_each_entry manually, and enable to get
component directly from for_each macro.
Because of it, the macro becoming difficult to read,
but macro itself becoming useful.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/878spm64m4.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-10-15 10:59:31 +07:00
|
|
|
for_each_rtd_components(rtd, rtdcom, component) {
|
2019-10-02 12:30:59 +07:00
|
|
|
if (component->driver->pcm_construct) {
|
|
|
|
ret = component->driver->pcm_construct(component, rtd);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
}
|
2019-07-26 11:52:08 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2019-07-26 11:52:12 +07:00
|
|
|
|
2019-11-18 08:50:32 +07:00
|
|
|
void snd_soc_pcm_component_free(struct snd_soc_pcm_runtime *rtd)
|
2019-07-26 11:52:12 +07:00
|
|
|
{
|
|
|
|
struct snd_soc_rtdcom_list *rtdcom;
|
|
|
|
struct snd_soc_component *component;
|
|
|
|
|
ASoC: soc-core: add for_each_rtd_components() and replace
ALSA SoC has for_each_rtdcom() which is link list for
rtd-component which is called as rtdcom. The relationship image is like below
rtdcom rtdcom rtdcom
component component component
rtd->component_list -> list -> list -> list ...
Here, the pointer get via normal link list is rtdcom,
Thus, current for_each loop is like below, and need to get
component via rtdcom->component
for_each_rtdcom(rtd, rtdcom) {
component = rtdcom->component;
...
}
but usually, user want to get pointer from for_each_xxx is component
directly, like below.
for_each_rtd_component(rtd, rtdcom, component) {
...
}
This patch expands list_for_each_entry manually, and enable to get
component directly from for_each macro.
Because of it, the macro becoming difficult to read,
but macro itself becoming useful.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/878spm64m4.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2019-10-15 10:59:31 +07:00
|
|
|
for_each_rtd_components(rtd, rtdcom, component)
|
2019-10-02 12:30:59 +07:00
|
|
|
if (component->driver->pcm_destruct)
|
2019-11-18 08:50:32 +07:00
|
|
|
component->driver->pcm_destruct(component, rtd->pcm);
|
2019-07-26 11:52:12 +07:00
|
|
|
}
|