aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJarkko Nikula <jhnikula@gmail.com>2010-12-06 16:27:07 +0200
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-12-06 19:14:46 +0000
commit589c3563f6476950f26b5bcc9beb1b39a7bcc644 (patch)
tree8d3d5ef20fc37e36f014fd80059bc0e9f6e42f99
parentMerge branch 'for-2.6.37' into for-2.6.38 (diff)
downloadlinux-dev-589c3563f6476950f26b5bcc9beb1b39a7bcc644.tar.xz
linux-dev-589c3563f6476950f26b5bcc9beb1b39a7bcc644.zip
ASoC: Merge common code in DAI link and auxiliary codec probing/removal
Commit 2eea392 "ASoC: Add support for optional auxiliary dailess codecs" added much of code that can be shared with DAI link codec probing/removal. Merge now this common code into new soc_probe_codec, soc_remove_codec and soc_post_component_init functions. Error prints in these functions are converted to use dev_err and to print the error code. Signed-off-by: Jarkko Nikula <jhnikula@gmail.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--sound/soc/soc-core.c284
1 files changed, 132 insertions, 152 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 17dcd56a2520..b3605a1c8c46 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1328,6 +1328,27 @@ out:
return 1;
}
+static void soc_remove_codec(struct snd_soc_codec *codec)
+{
+ int err;
+
+ if (codec->driver->remove) {
+ err = codec->driver->remove(codec);
+ if (err < 0)
+ dev_err(codec->dev,
+ "asoc: failed to remove %s: %d\n",
+ codec->name, err);
+ }
+
+ /* Make sure all DAPM widgets are freed */
+ snd_soc_dapm_free(&codec->dapm);
+
+ soc_cleanup_codec_debugfs(codec);
+ codec->probed = 0;
+ list_del(&codec->card_list);
+ module_put(codec->dev->driver->owner);
+}
+
static void soc_remove_dai_link(struct snd_soc_card *card, int num)
{
struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
@@ -1339,6 +1360,7 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
/* unregister the rtd device */
if (rtd->dev_registered) {
device_remove_file(&rtd->dev, &dev_attr_pmdown_time);
+ device_remove_file(&rtd->dev, &dev_attr_codec_reg);
device_unregister(&rtd->dev);
rtd->dev_registered = 0;
}
@@ -1367,22 +1389,8 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num)
}
/* remove the CODEC */
- if (codec && codec->probed) {
- if (codec->driver->remove) {
- err = codec->driver->remove(codec);
- if (err < 0)
- printk(KERN_ERR "asoc: failed to remove %s\n", codec->name);
- }
-
- /* Make sure all DAPM widgets are freed */
- snd_soc_dapm_free(&codec->dapm);
-
- soc_cleanup_codec_debugfs(codec);
- device_remove_file(&rtd->dev, &dev_attr_codec_reg);
- codec->probed = 0;
- list_del(&codec->card_list);
- module_put(codec->dev->driver->owner);
- }
+ if (codec && codec->probed)
+ soc_remove_codec(codec);
/* remove the cpu_dai */
if (cpu_dai && cpu_dai->probed) {
@@ -1414,8 +1422,105 @@ static void soc_set_name_prefix(struct snd_soc_card *card,
}
}
+static int soc_probe_codec(struct snd_soc_card *card,
+ struct snd_soc_codec *codec)
+{
+ int ret = 0;
+
+ codec->card = card;
+ codec->dapm.card = card;
+ soc_set_name_prefix(card, codec);
+
+ if (codec->driver->probe) {
+ ret = codec->driver->probe(codec);
+ if (ret < 0) {
+ dev_err(codec->dev,
+ "asoc: failed to probe CODEC %s: %d\n",
+ codec->name, ret);
+ return ret;
+ }
+ }
+
+ soc_init_codec_debugfs(codec);
+
+ /* mark codec as probed and add to card codec list */
+ codec->probed = 1;
+ list_add(&codec->card_list, &card->codec_dev_list);
+
+ return ret;
+}
+
static void rtd_release(struct device *dev) {}
+static int soc_post_component_init(struct snd_soc_card *card,
+ struct snd_soc_codec *codec,
+ int num, int dailess)
+{
+ struct snd_soc_dai_link *dai_link = NULL;
+ struct snd_soc_aux_dev *aux_dev = NULL;
+ struct snd_soc_pcm_runtime *rtd;
+ const char *temp, *name;
+ int ret = 0;
+
+ if (!dailess) {
+ dai_link = &card->dai_link[num];
+ rtd = &card->rtd[num];
+ name = dai_link->name;
+ } else {
+ aux_dev = &card->aux_dev[num];
+ rtd = &card->rtd_aux[num];
+ name = aux_dev->name;
+ }
+
+ /* machine controls, routes and widgets are not prefixed */
+ temp = codec->name_prefix;
+ codec->name_prefix = NULL;
+
+ /* do machine specific initialization */
+ if (!dailess && dai_link->init)
+ ret = dai_link->init(rtd);
+ else if (dailess && aux_dev->init)
+ ret = aux_dev->init(&codec->dapm);
+ if (ret < 0) {
+ dev_err(card->dev, "asoc: failed to init %s: %d\n", name, ret);
+ return ret;
+ }
+ codec->name_prefix = temp;
+
+ /* Make sure all DAPM widgets are instantiated */
+ snd_soc_dapm_new_widgets(&codec->dapm);
+ snd_soc_dapm_sync(&codec->dapm);
+
+ /* register the rtd device */
+ rtd->codec = codec;
+ rtd->card = card;
+ rtd->dev.parent = card->dev;
+ rtd->dev.release = rtd_release;
+ rtd->dev.init_name = name;
+ ret = device_register(&rtd->dev);
+ if (ret < 0) {
+ dev_err(card->dev,
+ "asoc: failed to register runtime device: %d\n", ret);
+ return ret;
+ }
+ rtd->dev_registered = 1;
+
+ /* add DAPM sysfs entries for this codec */
+ ret = snd_soc_dapm_sys_add(&rtd->dev);
+ if (ret < 0)
+ dev_err(codec->dev,
+ "asoc: failed to add codec dapm sysfs entries: %d\n",
+ ret);
+
+ /* add codec sysfs entries */
+ ret = device_create_file(&rtd->dev, &dev_attr_codec_reg);
+ if (ret < 0)
+ dev_err(codec->dev,
+ "asoc: failed to add codec sysfs files: %d\n", ret);
+
+ return 0;
+}
+
static int soc_probe_dai_link(struct snd_soc_card *card, int num)
{
struct snd_soc_dai_link *dai_link = &card->dai_link[num];
@@ -1423,17 +1528,13 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_platform *platform = rtd->platform;
struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai;
- const char *temp;
int ret;
dev_dbg(card->dev, "probe %s dai link %d\n", card->name, num);
/* config components */
codec_dai->codec = codec;
- codec->card = card;
cpu_dai->platform = platform;
- rtd->card = card;
- rtd->dev.parent = card->dev;
codec_dai->card = card;
cpu_dai->card = card;
@@ -1457,22 +1558,9 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
/* probe the CODEC */
if (!codec->probed) {
- codec->dapm.card = card;
- soc_set_name_prefix(card, codec);
- if (codec->driver->probe) {
- ret = codec->driver->probe(codec);
- if (ret < 0) {
- printk(KERN_ERR "asoc: failed to probe CODEC %s\n",
- codec->name);
- return ret;
- }
- }
-
- soc_init_codec_debugfs(codec);
-
- /* mark codec as probed and add to card codec list */
- codec->probed = 1;
- list_add(&codec->card_list, &card->codec_dev_list);
+ ret = soc_probe_codec(card, codec);
+ if (ret < 0)
+ return ret;
}
/* probe the platform */
@@ -1509,47 +1597,14 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num)
/* DAPM dai link stream work */
INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
- /* now that all clients have probed, initialise the DAI link */
- if (dai_link->init) {
- /* machine controls, routes and widgets are not prefixed */
- temp = rtd->codec->name_prefix;
- rtd->codec->name_prefix = NULL;
- ret = dai_link->init(rtd);
- if (ret < 0) {
- printk(KERN_ERR "asoc: failed to init %s\n", dai_link->stream_name);
- return ret;
- }
- rtd->codec->name_prefix = temp;
- }
-
- /* Make sure all DAPM widgets are instantiated */
- snd_soc_dapm_new_widgets(&codec->dapm);
- snd_soc_dapm_sync(&codec->dapm);
-
- /* register the rtd device */
- rtd->dev.release = rtd_release;
- rtd->dev.init_name = dai_link->name;
- ret = device_register(&rtd->dev);
- if (ret < 0) {
- printk(KERN_ERR "asoc: failed to register DAI runtime device %d\n", ret);
+ ret = soc_post_component_init(card, codec, num, 0);
+ if (ret)
return ret;
- }
- rtd->dev_registered = 1;
ret = device_create_file(&rtd->dev, &dev_attr_pmdown_time);
if (ret < 0)
printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n");
- /* add DAPM sysfs entries for this codec */
- ret = snd_soc_dapm_sys_add(&rtd->dev);
- if (ret < 0)
- printk(KERN_WARNING "asoc: failed to add codec dapm sysfs entries\n");
-
- /* add codec sysfs entries */
- ret = device_create_file(&rtd->dev, &dev_attr_codec_reg);
- if (ret < 0)
- printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
-
/* create the pcm */
ret = soc_new_pcm(rtd, num);
if (ret < 0) {
@@ -1607,9 +1662,7 @@ static void soc_unregister_ac97_dai_link(struct snd_soc_codec *codec)
static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
{
struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
- struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
struct snd_soc_codec *codec;
- const char *temp;
int ret = -ENODEV;
/* find CODEC from registered CODECs*/
@@ -1632,67 +1685,11 @@ found:
if (!try_module_get(codec->dev->driver->owner))
return -ENODEV;
- codec->card = card;
- codec->dapm.card = card;
-
- soc_set_name_prefix(card, codec);
- if (codec->driver->probe) {
- ret = codec->driver->probe(codec);
- if (ret < 0) {
- dev_err(codec->dev, "asoc: failed to probe CODEC");
- return ret;
- }
- }
-
- soc_init_codec_debugfs(codec);
-
- /* mark codec as probed and add to card codec list */
- codec->probed = 1;
- list_add(&codec->card_list, &card->codec_dev_list);
-
- /* now that all clients have probed, initialise the DAI link */
- if (aux_dev->init) {
- /* machine controls, routes and widgets are not prefixed */
- temp = codec->name_prefix;
- codec->name_prefix = NULL;
- ret = aux_dev->init(&codec->dapm);
- if (ret < 0) {
- dev_err(codec->dev,
- "asoc: failed to init %s\n", aux_dev->name);
- return ret;
- }
- codec->name_prefix = temp;
- }
-
- /* Make sure all DAPM widgets are instantiated */
- snd_soc_dapm_new_widgets(&codec->dapm);
- snd_soc_dapm_sync(&codec->dapm);
-
- /* register the rtd device */
- rtd->codec = codec;
- rtd->card = card;
- rtd->dev.parent = card->dev;
- rtd->dev.release = rtd_release;
- rtd->dev.init_name = aux_dev->name;
- ret = device_register(&rtd->dev);
- if (ret < 0) {
- dev_err(codec->dev,
- "asoc: failed to register aux runtime device %d\n",
- ret);
- return ret;
- }
- rtd->dev_registered = 1;
-
- /* add DAPM sysfs entries for this codec */
- ret = snd_soc_dapm_sys_add(&rtd->dev);
+ ret = soc_probe_codec(card, codec);
if (ret < 0)
- dev_err(codec->dev,
- "asoc: failed to add codec dapm sysfs entries\n");
+ return ret;
- /* add codec sysfs entries */
- ret = device_create_file(&rtd->dev, &dev_attr_codec_reg);
- if (ret < 0)
- dev_err(codec->dev, "asoc: failed to add codec sysfs files\n");
+ ret = soc_post_component_init(card, codec, num, 1);
out:
return ret;
@@ -1702,33 +1699,16 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
{
struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num];
struct snd_soc_codec *codec = rtd->codec;
- int err;
/* unregister the rtd device */
if (rtd->dev_registered) {
+ device_remove_file(&rtd->dev, &dev_attr_codec_reg);
device_unregister(&rtd->dev);
rtd->dev_registered = 0;
}
- /* remove the CODEC */
- if (codec && codec->probed) {
- if (codec->driver->remove) {
- err = codec->driver->remove(codec);
- if (err < 0)
- dev_err(codec->dev,
- "asoc: failed to remove %s\n",
- codec->name);
- }
-
- /* Make sure all DAPM widgets are freed */
- snd_soc_dapm_free(&codec->dapm);
-
- soc_cleanup_codec_debugfs(codec);
- device_remove_file(&rtd->dev, &dev_attr_codec_reg);
- codec->probed = 0;
- list_del(&codec->card_list);
- module_put(codec->dev->driver->owner);
- }
+ if (codec && codec->probed)
+ soc_remove_codec(codec);
}
static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,