aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitris Papastamos <dp@opensource.wolfsonmicro.com>2010-12-02 16:11:06 +0000
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-12-03 16:37:32 +0000
commitfdf0f54dab8e401fd9bdd441c3fc4fa5c8837646 (patch)
treea1d33d33931964c21765042e0ba53591b9c7b7a2
parentASoC: soc-cache: Use reg_def_copy instead of reg_cache_default (diff)
downloadlinux-dev-fdf0f54dab8e401fd9bdd441c3fc4fa5c8837646.tar.xz
linux-dev-fdf0f54dab8e401fd9bdd441c3fc4fa5c8837646.zip
ASoC: soc-core: Allow machine drivers to override compress_type
This patch allows machine drivers to override the compression type provided by the codec driver. Signed-off-by: Dimitris Papastamos <dp@opensource.wolfsonmicro.com> Acked-by: Liam Girdwood <lrg@slimlogic.co.uk> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--include/sound/soc.h1
-rw-r--r--sound/soc/soc-core.c74
2 files changed, 64 insertions, 11 deletions
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 017986159d5e..7d53cc453637 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -472,6 +472,7 @@ struct snd_soc_codec {
unsigned int ac97_registered:1; /* Codec has been AC97 registered */
unsigned int ac97_created:1; /* Codec has been created by SoC */
unsigned int sysfs_registered:1; /* codec has been sysfs registered */
+ unsigned int cache_init:1; /* codec cache has been initialized */
/* codec IO */
void *control_data; /* codec control (i2c/3wire) data */
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index a95d111a6531..e9aa9ce59c06 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1730,9 +1730,36 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
}
}
+static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
+ enum snd_soc_compress_type compress_type)
+{
+ int ret;
+
+ if (codec->cache_init)
+ return 0;
+
+ /* override the compress_type if necessary */
+ if (compress_type && codec->compress_type != compress_type)
+ codec->compress_type = compress_type;
+ dev_dbg(codec->dev, "Cache compress_type for %s is %d\n",
+ codec->name, codec->compress_type);
+ ret = snd_soc_cache_init(codec);
+ if (ret < 0) {
+ dev_err(codec->dev, "Failed to set cache compression type: %d\n",
+ ret);
+ return ret;
+ }
+ codec->cache_init = 1;
+ return 0;
+}
+
+
static void snd_soc_instantiate_card(struct snd_soc_card *card)
{
struct platform_device *pdev = to_platform_device(card->dev);
+ struct snd_soc_codec *codec;
+ struct snd_soc_codec_conf *codec_conf;
+ enum snd_soc_compress_type compress_type;
int ret, i;
mutex_lock(&card->mutex);
@@ -1752,6 +1779,39 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
return;
}
+ /* initialize the register cache for each available codec */
+ list_for_each_entry(codec, &codec_list, list) {
+ if (codec->cache_init)
+ continue;
+ /* check to see if we need to override the compress_type */
+ for (i = 0; i < card->num_configs; ++i) {
+ codec_conf = &card->codec_conf[i];
+ if (!strcmp(codec->name, codec_conf->dev_name)) {
+ compress_type = codec_conf->compress_type;
+ if (compress_type && compress_type
+ != codec->compress_type)
+ break;
+ }
+ }
+ if (i == card->num_configs) {
+ /* no need to override the compress_type so
+ * go ahead and do the standard thing */
+ ret = snd_soc_init_codec_cache(codec, 0);
+ if (ret < 0) {
+ mutex_unlock(&card->mutex);
+ return;
+ }
+ continue;
+ }
+ /* override the compress_type with the one supplied in
+ * the machine driver */
+ ret = snd_soc_init_codec_cache(codec, compress_type);
+ if (ret < 0) {
+ mutex_unlock(&card->mutex);
+ return;
+ }
+ }
+
/* card bind complete so register a sound card */
ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
card->owner, 0, &card->snd_card);
@@ -3481,13 +3541,7 @@ int snd_soc_register_codec(struct device *dev,
reg_size, GFP_KERNEL);
if (!codec->reg_def_copy) {
ret = -ENOMEM;
- goto error_cache;
- }
- ret = snd_soc_cache_init(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to set cache compression type: %d\n",
- ret);
- goto error_cache;
+ goto fail;
}
}
@@ -3500,7 +3554,7 @@ int snd_soc_register_codec(struct device *dev,
if (num_dai) {
ret = snd_soc_register_dais(dev, dai_drv, num_dai);
if (ret < 0)
- goto error_dais;
+ goto fail;
}
mutex_lock(&client_mutex);
@@ -3511,9 +3565,7 @@ int snd_soc_register_codec(struct device *dev,
pr_debug("Registered codec '%s'\n", codec->name);
return 0;
-error_dais:
- snd_soc_cache_exit(codec);
-error_cache:
+fail:
kfree(codec->reg_def_copy);
codec->reg_def_copy = NULL;
kfree(codec->name);