提交 d191bd8d 编写于 作者: K Kuninori Morimoto 提交者: Mark Brown

ASoC: snd_soc_codec includes snd_soc_component

Codec includes component by this patch,
and component moved to upside of codec
to avoid extra declaration.
Codec dai will be registered via component
by this patch.

Current component register function
is used for cpu, and it is using
dai/dais functions properly to keep
existing cpu dai name.

And now, it will be used from codec also.
But codec driver had been used dais function only
even though it was single dai.
This patch adds new flag which can selects
dai/dais function on component register
function to keep existing codec dai name.
Signed-off-by: NKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: NMark Brown <broonie@linaro.org>
上级 272b98c6
......@@ -670,6 +670,21 @@ struct snd_soc_cache_ops {
int (*sync)(struct snd_soc_codec *codec);
};
/* component interface */
struct snd_soc_component_driver {
const char *name;
};
struct snd_soc_component {
const char *name;
int id;
int num_dai;
struct device *dev;
struct list_head list;
const struct snd_soc_component_driver *driver;
};
/* SoC Audio Codec device */
struct snd_soc_codec {
const char *name;
......@@ -715,6 +730,9 @@ struct snd_soc_codec {
struct mutex cache_rw_mutex;
int val_bytes;
/* component */
struct snd_soc_component component;
/* dapm */
struct snd_soc_dapm_context dapm;
unsigned int ignore_pmdown_time:1; /* pmdown_time is ignored at stop */
......@@ -733,6 +751,7 @@ struct snd_soc_codec_driver {
int (*remove)(struct snd_soc_codec *);
int (*suspend)(struct snd_soc_codec *);
int (*resume)(struct snd_soc_codec *);
struct snd_soc_component_driver component_driver;
/* Default control and setup, added after probe() is run */
const struct snd_kcontrol_new *controls;
......@@ -849,20 +868,6 @@ struct snd_soc_platform {
#endif
};
struct snd_soc_component_driver {
const char *name;
};
struct snd_soc_component {
const char *name;
int id;
int num_dai;
struct device *dev;
struct list_head list;
const struct snd_soc_component_driver *driver;
};
struct snd_soc_dai_link {
/* config - must be set by machine driver */
const char *name; /* Codec name */
......
......@@ -4020,6 +4020,112 @@ static void snd_soc_unregister_dais(struct device *dev, size_t count)
snd_soc_unregister_dai(dev);
}
/**
* snd_soc_register_component - Register a component with the ASoC core
*
*/
static int
__snd_soc_register_component(struct device *dev,
struct snd_soc_component *cmpnt,
const struct snd_soc_component_driver *cmpnt_drv,
struct snd_soc_dai_driver *dai_drv,
int num_dai, bool allow_single_dai)
{
int ret;
dev_dbg(dev, "component register %s\n", dev_name(dev));
if (!cmpnt) {
dev_err(dev, "ASoC: Failed to connecting component\n");
return -ENOMEM;
}
cmpnt->name = fmt_single_name(dev, &cmpnt->id);
if (!cmpnt->name) {
dev_err(dev, "ASoC: Failed to simplifying name\n");
return -ENOMEM;
}
cmpnt->dev = dev;
cmpnt->driver = cmpnt_drv;
cmpnt->num_dai = num_dai;
/*
* snd_soc_register_dai() uses fmt_single_name(), and
* snd_soc_register_dais() uses fmt_multiple_name()
* for dai->name which is used for name based matching
*
* this function is used from cpu/codec.
* allow_single_dai flag can ignore "codec" driver reworking
* since it had been used snd_soc_register_dais(),
*/
if ((1 == num_dai) && allow_single_dai)
ret = snd_soc_register_dai(dev, dai_drv);
else
ret = snd_soc_register_dais(dev, dai_drv, num_dai);
if (ret < 0) {
dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret);
goto error_component_name;
}
mutex_lock(&client_mutex);
list_add(&cmpnt->list, &component_list);
mutex_unlock(&client_mutex);
dev_dbg(cmpnt->dev, "ASoC: Registered component '%s'\n", cmpnt->name);
return ret;
error_component_name:
kfree(cmpnt->name);
return ret;
}
int snd_soc_register_component(struct device *dev,
const struct snd_soc_component_driver *cmpnt_drv,
struct snd_soc_dai_driver *dai_drv,
int num_dai)
{
struct snd_soc_component *cmpnt;
cmpnt = devm_kzalloc(dev, sizeof(*cmpnt), GFP_KERNEL);
if (!cmpnt) {
dev_err(dev, "ASoC: Failed to allocate memory\n");
return -ENOMEM;
}
return __snd_soc_register_component(dev, cmpnt, cmpnt_drv,
dai_drv, num_dai, true);
}
EXPORT_SYMBOL_GPL(snd_soc_register_component);
/**
* snd_soc_unregister_component - Unregister a component from the ASoC core
*
*/
void snd_soc_unregister_component(struct device *dev)
{
struct snd_soc_component *cmpnt;
list_for_each_entry(cmpnt, &component_list, list) {
if (dev == cmpnt->dev)
goto found;
}
return;
found:
snd_soc_unregister_dais(dev, cmpnt->num_dai);
mutex_lock(&client_mutex);
list_del(&cmpnt->list);
mutex_unlock(&client_mutex);
dev_dbg(dev, "ASoC: Unregistered component '%s'\n", cmpnt->name);
kfree(cmpnt->name);
}
EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
/**
* snd_soc_add_platform - Add a platform to the ASoC core
* @dev: The parent device for the platform
......@@ -4242,10 +4348,12 @@ int snd_soc_register_codec(struct device *dev,
list_add(&codec->list, &codec_list);
mutex_unlock(&client_mutex);
/* register any DAIs */
ret = snd_soc_register_dais(dev, dai_drv, num_dai);
/* register component */
ret = __snd_soc_register_component(dev, &codec->component,
&codec_drv->component_driver,
dai_drv, num_dai, false);
if (ret < 0) {
dev_err(codec->dev, "ASoC: Failed to regster DAIs: %d\n", ret);
dev_err(codec->dev, "ASoC: Failed to regster component: %d\n", ret);
goto fail_codec_name;
}
......@@ -4280,7 +4388,7 @@ void snd_soc_unregister_codec(struct device *dev)
return;
found:
snd_soc_unregister_dais(dev, codec->num_dai);
snd_soc_unregister_component(dev);
mutex_lock(&client_mutex);
list_del(&codec->list);
......@@ -4295,92 +4403,6 @@ void snd_soc_unregister_codec(struct device *dev)
}
EXPORT_SYMBOL_GPL(snd_soc_unregister_codec);
/**
* snd_soc_register_component - Register a component with the ASoC core
*
*/
int snd_soc_register_component(struct device *dev,
const struct snd_soc_component_driver *cmpnt_drv,
struct snd_soc_dai_driver *dai_drv,
int num_dai)
{
struct snd_soc_component *cmpnt;
int ret;
dev_dbg(dev, "component register %s\n", dev_name(dev));
cmpnt = devm_kzalloc(dev, sizeof(*cmpnt), GFP_KERNEL);
if (!cmpnt) {
dev_err(dev, "ASoC: Failed to allocate memory\n");
return -ENOMEM;
}
cmpnt->name = fmt_single_name(dev, &cmpnt->id);
if (!cmpnt->name) {
dev_err(dev, "ASoC: Failed to simplifying name\n");
return -ENOMEM;
}
cmpnt->dev = dev;
cmpnt->driver = cmpnt_drv;
cmpnt->num_dai = num_dai;
/*
* snd_soc_register_dai() uses fmt_single_name(), and
* snd_soc_register_dais() uses fmt_multiple_name()
* for dai->name which is used for name based matching
*/
if (1 == num_dai)
ret = snd_soc_register_dai(dev, dai_drv);
else
ret = snd_soc_register_dais(dev, dai_drv, num_dai);
if (ret < 0) {
dev_err(dev, "ASoC: Failed to regster DAIs: %d\n", ret);
goto error_component_name;
}
mutex_lock(&client_mutex);
list_add(&cmpnt->list, &component_list);
mutex_unlock(&client_mutex);
dev_dbg(cmpnt->dev, "ASoC: Registered component '%s'\n", cmpnt->name);
return ret;
error_component_name:
kfree(cmpnt->name);
return ret;
}
EXPORT_SYMBOL_GPL(snd_soc_register_component);
/**
* snd_soc_unregister_component - Unregister a component from the ASoC core
*
*/
void snd_soc_unregister_component(struct device *dev)
{
struct snd_soc_component *cmpnt;
list_for_each_entry(cmpnt, &component_list, list) {
if (dev == cmpnt->dev)
goto found;
}
return;
found:
snd_soc_unregister_dais(dev, cmpnt->num_dai);
mutex_lock(&client_mutex);
list_del(&cmpnt->list);
mutex_unlock(&client_mutex);
dev_dbg(dev, "ASoC: Unregistered component '%s'\n", cmpnt->name);
kfree(cmpnt->name);
}
EXPORT_SYMBOL_GPL(snd_soc_unregister_component);
/* Retrieve a card's name from device tree */
int snd_soc_of_parse_card_name(struct snd_soc_card *card,
const char *propname)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册