summaryrefslogtreecommitdiff
path: root/sound/soc/soc-core.c
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
committerScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
commit62b8c978ee6b8d135d9e7953221de58000dba986 (patch)
tree683b04b2e627f6710c22c151b23c8cc9a165315e /sound/soc/soc-core.c
parent78fd82238d0e5716578c326404184a27ba67fd6e (diff)
downloadlinux-fsl-qoriq-62b8c978ee6b8d135d9e7953221de58000dba986.tar.xz
Rewind v3.13-rc3+ (78fd82238d0e5716) to v3.12
Diffstat (limited to 'sound/soc/soc-core.c')
-rw-r--r--sound/soc/soc-core.c380
1 files changed, 157 insertions, 223 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index a66783e..1a38be0 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -662,8 +662,6 @@ int snd_soc_suspend(struct device *dev)
codec->cache_sync = 1;
if (codec->using_regmap)
regcache_mark_dirty(codec->control_data);
- /* deactivate pins to sleep state */
- pinctrl_pm_select_sleep_state(codec->dev);
break;
default:
dev_dbg(codec->dev,
@@ -681,9 +679,6 @@ int snd_soc_suspend(struct device *dev)
if (cpu_dai->driver->suspend && cpu_dai->driver->ac97_control)
cpu_dai->driver->suspend(cpu_dai);
-
- /* deactivate pins to sleep state */
- pinctrl_pm_select_sleep_state(cpu_dai->dev);
}
if (card->suspend_post)
@@ -812,16 +807,6 @@ int snd_soc_resume(struct device *dev)
if (list_empty(&card->codec_dev_list))
return 0;
- /* activate pins from sleep state */
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
- struct snd_soc_dai *codec_dai = card->rtd[i].codec_dai;
- if (cpu_dai->active)
- pinctrl_pm_select_default_state(cpu_dai->dev);
- if (codec_dai->active)
- pinctrl_pm_select_default_state(codec_dai->dev);
- }
-
/* AC97 devices might have other drivers hanging off them so
* need to resume immediately. Other drivers don't have that
* problem and may take a substantial amount of time to resume
@@ -1604,13 +1589,17 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num)
soc_remove_codec(codec);
}
-static int snd_soc_init_codec_cache(struct snd_soc_codec *codec)
+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;
ret = snd_soc_cache_init(codec);
if (ret < 0) {
dev_err(codec->dev,
@@ -1625,6 +1614,8 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec)
static int snd_soc_instantiate_card(struct snd_soc_card *card)
{
struct snd_soc_codec *codec;
+ struct snd_soc_codec_conf *codec_conf;
+ enum snd_soc_compress_type compress_type;
struct snd_soc_dai_link *dai_link;
int ret, i, order, dai_fmt;
@@ -1648,7 +1639,19 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
list_for_each_entry(codec, &codec_list, list) {
if (codec->cache_init)
continue;
- ret = snd_soc_init_codec_cache(codec);
+ /* by default we don't override the compress_type */
+ compress_type = 0;
+ /* 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;
+ }
+ }
+ ret = snd_soc_init_codec_cache(codec, compress_type);
if (ret < 0)
goto base_error;
}
@@ -1944,14 +1947,6 @@ int snd_soc_poweroff(struct device *dev)
snd_soc_dapm_shutdown(card);
- /* deactivate pins to sleep state */
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
- struct snd_soc_dai *codec_dai = card->rtd[i].codec_dai;
- pinctrl_pm_select_sleep_state(codec_dai->dev);
- pinctrl_pm_select_sleep_state(cpu_dai->dev);
- }
-
return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_poweroff);
@@ -2302,6 +2297,13 @@ unsigned int snd_soc_write(struct snd_soc_codec *codec,
}
EXPORT_SYMBOL_GPL(snd_soc_write);
+unsigned int snd_soc_bulk_write_raw(struct snd_soc_codec *codec,
+ unsigned int reg, const void *data, size_t len)
+{
+ return codec->bulk_write_raw(codec, reg, data, len);
+}
+EXPORT_SYMBOL_GPL(snd_soc_bulk_write_raw);
+
/**
* snd_soc_update_bits - update codec register bits
* @codec: audio codec
@@ -2574,9 +2576,8 @@ int snd_soc_info_enum_double(struct snd_kcontrol *kcontrol,
if (uinfo->value.enumerated.item > e->max - 1)
uinfo->value.enumerated.item = e->max - 1;
- strlcpy(uinfo->value.enumerated.name,
- e->texts[uinfo->value.enumerated.item],
- sizeof(uinfo->value.enumerated.name));
+ strcpy(uinfo->value.enumerated.name,
+ e->texts[uinfo->value.enumerated.item]);
return 0;
}
EXPORT_SYMBOL_GPL(snd_soc_info_enum_double);
@@ -3212,11 +3213,11 @@ int snd_soc_bytes_get(struct snd_kcontrol *kcontrol,
break;
case 2:
((u16 *)(&ucontrol->value.bytes.data))[0]
- &= cpu_to_be16(~params->mask);
+ &= ~params->mask;
break;
case 4:
((u32 *)(&ucontrol->value.bytes.data))[0]
- &= cpu_to_be32(~params->mask);
+ &= ~params->mask;
break;
default:
return -EINVAL;
@@ -3575,22 +3576,6 @@ int snd_soc_codec_set_pll(struct snd_soc_codec *codec, int pll_id, int source,
EXPORT_SYMBOL_GPL(snd_soc_codec_set_pll);
/**
- * snd_soc_dai_set_bclk_ratio - configure BCLK to sample rate ratio.
- * @dai: DAI
- * @ratio Ratio of BCLK to Sample rate.
- *
- * Configures the DAI for a preset BCLK to sample rate ratio.
- */
-int snd_soc_dai_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
-{
- if (dai->driver && dai->driver->ops->set_bclk_ratio)
- return dai->driver->ops->set_bclk_ratio(dai, ratio);
- else
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(snd_soc_dai_set_bclk_ratio);
-
-/**
* snd_soc_dai_set_fmt - configure DAI hardware audio format.
* @dai: DAI
* @fmt: SND_SOC_DAIFMT_ format value.
@@ -3790,16 +3775,6 @@ int snd_soc_register_card(struct snd_soc_card *card)
if (ret != 0)
soc_cleanup_card_debugfs(card);
- /* deactivate pins to sleep state */
- for (i = 0; i < card->num_rtd; i++) {
- struct snd_soc_dai *cpu_dai = card->rtd[i].cpu_dai;
- struct snd_soc_dai *codec_dai = card->rtd[i].codec_dai;
- if (!codec_dai->active)
- pinctrl_pm_select_sleep_state(codec_dai->dev);
- if (!cpu_dai->active)
- pinctrl_pm_select_sleep_state(cpu_dai->dev);
- }
-
return ret;
}
EXPORT_SYMBOL_GPL(snd_soc_register_card);
@@ -4045,113 +4020,6 @@ static void snd_soc_unregister_dais(struct device *dev, size_t count)
}
/**
- * 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->dai_drv = dai_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
* @platform: The platform to add
@@ -4297,6 +4165,7 @@ int snd_soc_register_codec(struct device *dev,
struct snd_soc_dai_driver *dai_drv,
int num_dai)
{
+ size_t reg_size;
struct snd_soc_codec *codec;
int ret, i;
@@ -4313,6 +4182,11 @@ int snd_soc_register_codec(struct device *dev,
goto fail_codec;
}
+ if (codec_drv->compress_type)
+ codec->compress_type = codec_drv->compress_type;
+ else
+ codec->compress_type = SND_SOC_FLAT_COMPRESSION;
+
codec->write = codec_drv->write;
codec->read = codec_drv->read;
codec->volatile_register = codec_drv->volatile_register;
@@ -4329,6 +4203,35 @@ int snd_soc_register_codec(struct device *dev,
codec->num_dai = num_dai;
mutex_init(&codec->mutex);
+ /* allocate CODEC register cache */
+ if (codec_drv->reg_cache_size && codec_drv->reg_word_size) {
+ reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size;
+ codec->reg_size = reg_size;
+ /* it is necessary to make a copy of the default register cache
+ * because in the case of using a compression type that requires
+ * the default register cache to be marked as the
+ * kernel might have freed the array by the time we initialize
+ * the cache.
+ */
+ if (codec_drv->reg_cache_default) {
+ codec->reg_def_copy = kmemdup(codec_drv->reg_cache_default,
+ reg_size, GFP_KERNEL);
+ if (!codec->reg_def_copy) {
+ ret = -ENOMEM;
+ goto fail_codec_name;
+ }
+ }
+ }
+
+ if (codec_drv->reg_access_size && codec_drv->reg_access_default) {
+ if (!codec->volatile_register)
+ codec->volatile_register = snd_soc_default_volatile_register;
+ if (!codec->readable_register)
+ codec->readable_register = snd_soc_default_readable_register;
+ if (!codec->writable_register)
+ codec->writable_register = snd_soc_default_writable_register;
+ }
+
for (i = 0; i < num_dai; i++) {
fixup_codec_formats(&dai_drv[i].playback);
fixup_codec_formats(&dai_drv[i].capture);
@@ -4338,12 +4241,10 @@ int snd_soc_register_codec(struct device *dev,
list_add(&codec->list, &codec_list);
mutex_unlock(&client_mutex);
- /* register component */
- ret = __snd_soc_register_component(dev, &codec->component,
- &codec_drv->component_driver,
- dai_drv, num_dai, false);
+ /* register any DAIs */
+ ret = snd_soc_register_dais(dev, dai_drv, num_dai);
if (ret < 0) {
- dev_err(codec->dev, "ASoC: Failed to regster component: %d\n", ret);
+ dev_err(codec->dev, "ASoC: Failed to regster DAIs: %d\n", ret);
goto fail_codec_name;
}
@@ -4378,7 +4279,7 @@ void snd_soc_unregister_codec(struct device *dev)
return;
found:
- snd_soc_unregister_component(dev);
+ snd_soc_unregister_dais(dev, codec->num_dai);
mutex_lock(&client_mutex);
list_del(&codec->list);
@@ -4387,11 +4288,98 @@ found:
dev_dbg(codec->dev, "ASoC: Unregistered codec '%s'\n", codec->name);
snd_soc_cache_exit(codec);
+ kfree(codec->reg_def_copy);
kfree(codec->name);
kfree(codec);
}
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)
@@ -4579,60 +4567,6 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
}
EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt);
-int snd_soc_of_get_dai_name(struct device_node *of_node,
- const char **dai_name)
-{
- struct snd_soc_component *pos;
- struct of_phandle_args args;
- int ret;
-
- ret = of_parse_phandle_with_args(of_node, "sound-dai",
- "#sound-dai-cells", 0, &args);
- if (ret)
- return ret;
-
- ret = -EPROBE_DEFER;
-
- mutex_lock(&client_mutex);
- list_for_each_entry(pos, &component_list, list) {
- if (pos->dev->of_node != args.np)
- continue;
-
- if (pos->driver->of_xlate_dai_name) {
- ret = pos->driver->of_xlate_dai_name(pos, &args, dai_name);
- } else {
- int id = -1;
-
- switch (args.args_count) {
- case 0:
- id = 0; /* same as dai_drv[0] */
- break;
- case 1:
- id = args.args[0];
- break;
- default:
- /* not supported */
- break;
- }
-
- if (id < 0 || id >= pos->num_dai) {
- ret = -EINVAL;
- } else {
- *dai_name = pos->dai_drv[id].name;
- ret = 0;
- }
- }
-
- break;
- }
- mutex_unlock(&client_mutex);
-
- of_node_put(args.np);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_name);
-
static int __init snd_soc_init(void)
{
#ifdef CONFIG_DEBUG_FS