aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-06-17 12:20:16 -0400
committerMark Brown <broonie@linaro.org>2013-06-17 12:20:16 -0400
commit70fe99d8dbbcff8b61b613e738e9d133ed2d2b15 (patch)
treeae5c0095908c5f68d912268d97d4e962f2ab1283
parent87fd83fd3ca933dbb5bd97226c1890c7b4659c72 (diff)
parentcf1f7c6e8756646db7a0d883013cedd90eb90dd4 (diff)
Merge remote-tracking branch 'asoc/topic/core' into asoc-next
-rw-r--r--include/sound/soc-dapm.h2
-rw-r--r--sound/soc/soc-core.c106
-rw-r--r--sound/soc/soc-dapm.c47
-rw-r--r--sound/soc/soc-pcm.c91
-rw-r--r--sound/soc/soc-utils.c13
5 files changed, 123 insertions, 136 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 385c6329a967..69e8e0799d4d 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -311,6 +311,8 @@ struct device;
311#define SND_SOC_DAPM_POST_PMD 0x8 /* after widget power down */ 311#define SND_SOC_DAPM_POST_PMD 0x8 /* after widget power down */
312#define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */ 312#define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */
313#define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */ 313#define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */
314#define SND_SOC_DAPM_WILL_PMU 0x40 /* called at start of sequence */
315#define SND_SOC_DAPM_WILL_PMD 0x80 /* called at start of sequence */
314#define SND_SOC_DAPM_PRE_POST_PMD \ 316#define SND_SOC_DAPM_PRE_POST_PMD \
315 (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD) 317 (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD)
316 318
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d56bbea6e75e..4489c5b7b53a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -272,8 +272,8 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
272 codec->debugfs_codec_root = debugfs_create_dir(codec->name, 272 codec->debugfs_codec_root = debugfs_create_dir(codec->name,
273 debugfs_card_root); 273 debugfs_card_root);
274 if (!codec->debugfs_codec_root) { 274 if (!codec->debugfs_codec_root) {
275 dev_warn(codec->dev, "ASoC: Failed to create codec debugfs" 275 dev_warn(codec->dev,
276 " directory\n"); 276 "ASoC: Failed to create codec debugfs directory\n");
277 return; 277 return;
278 } 278 }
279 279
@@ -286,8 +286,8 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
286 codec->debugfs_codec_root, 286 codec->debugfs_codec_root,
287 codec, &codec_reg_fops); 287 codec, &codec_reg_fops);
288 if (!codec->debugfs_reg) 288 if (!codec->debugfs_reg)
289 dev_warn(codec->dev, "ASoC: Failed to create codec register" 289 dev_warn(codec->dev,
290 " debugfs file\n"); 290 "ASoC: Failed to create codec register debugfs file\n");
291 291
292 snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root); 292 snd_soc_dapm_debugfs_init(&codec->dapm, codec->debugfs_codec_root);
293} 293}
@@ -631,8 +631,7 @@ int snd_soc_suspend(struct device *dev)
631 */ 631 */
632 if (codec->dapm.idle_bias_off) { 632 if (codec->dapm.idle_bias_off) {
633 dev_dbg(codec->dev, 633 dev_dbg(codec->dev,
634 "ASoC: idle_bias_off CODEC on" 634 "ASoC: idle_bias_off CODEC on over suspend\n");
635 " over suspend\n");
636 break; 635 break;
637 } 636 }
638 case SND_SOC_BIAS_OFF: 637 case SND_SOC_BIAS_OFF:
@@ -643,8 +642,8 @@ int snd_soc_suspend(struct device *dev)
643 regcache_mark_dirty(codec->control_data); 642 regcache_mark_dirty(codec->control_data);
644 break; 643 break;
645 default: 644 default:
646 dev_dbg(codec->dev, "ASoC: CODEC is on" 645 dev_dbg(codec->dev,
647 " over suspend\n"); 646 "ASoC: CODEC is on over suspend\n");
648 break; 647 break;
649 } 648 }
650 } 649 }
@@ -713,8 +712,8 @@ static void soc_resume_deferred(struct work_struct *work)
713 codec->suspended = 0; 712 codec->suspended = 0;
714 break; 713 break;
715 default: 714 default:
716 dev_dbg(codec->dev, "ASoC: CODEC was on over" 715 dev_dbg(codec->dev,
717 " suspend\n"); 716 "ASoC: CODEC was on over suspend\n");
718 break; 717 break;
719 } 718 }
720 } 719 }
@@ -1110,8 +1109,8 @@ static int soc_probe_codec(struct snd_soc_card *card,
1110 } 1109 }
1111 WARN(codec->dapm.idle_bias_off && 1110 WARN(codec->dapm.idle_bias_off &&
1112 codec->dapm.bias_level != SND_SOC_BIAS_OFF, 1111 codec->dapm.bias_level != SND_SOC_BIAS_OFF,
1113 "codec %s can not start from non-off bias" 1112 "codec %s can not start from non-off bias with idle_bias_off==1\n",
1114 " with idle_bias_off==1\n", codec->name); 1113 codec->name);
1115 } 1114 }
1116 1115
1117 /* If the driver didn't set I/O up try regmap */ 1116 /* If the driver didn't set I/O up try regmap */
@@ -1582,8 +1581,9 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec,
1582 codec->compress_type = compress_type; 1581 codec->compress_type = compress_type;
1583 ret = snd_soc_cache_init(codec); 1582 ret = snd_soc_cache_init(codec);
1584 if (ret < 0) { 1583 if (ret < 0) {
1585 dev_err(codec->dev, "ASoC: Failed to set cache compression" 1584 dev_err(codec->dev,
1586 " type: %d\n", ret); 1585 "ASoC: Failed to set cache compression type: %d\n",
1586 ret);
1587 return ret; 1587 return ret;
1588 } 1588 }
1589 codec->cache_init = 1; 1589 codec->cache_init = 1;
@@ -1639,8 +1639,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1639 ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, 1639 ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
1640 card->owner, 0, &card->snd_card); 1640 card->owner, 0, &card->snd_card);
1641 if (ret < 0) { 1641 if (ret < 0) {
1642 dev_err(card->dev, "ASoC: can't create sound card for" 1642 dev_err(card->dev,
1643 " card %s: %d\n", card->name, ret); 1643 "ASoC: can't create sound card for card %s: %d\n",
1644 card->name, ret);
1644 goto base_error; 1645 goto base_error;
1645 } 1646 }
1646 card->snd_card->dev = card->dev; 1647 card->snd_card->dev = card->dev;
@@ -1815,8 +1816,8 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1815 for (i = 0; i < card->num_rtd; i++) { 1816 for (i = 0; i < card->num_rtd; i++) {
1816 ret = soc_register_ac97_dai_link(&card->rtd[i]); 1817 ret = soc_register_ac97_dai_link(&card->rtd[i]);
1817 if (ret < 0) { 1818 if (ret < 0) {
1818 dev_err(card->dev, "ASoC: failed to register AC97:" 1819 dev_err(card->dev,
1819 " %d\n", ret); 1820 "ASoC: failed to register AC97: %d\n", ret);
1820 while (--i >= 0) 1821 while (--i >= 0)
1821 soc_unregister_ac97_dai_link(card->rtd[i].codec); 1822 soc_unregister_ac97_dai_link(card->rtd[i].codec);
1822 goto probe_aux_dev_err; 1823 goto probe_aux_dev_err;
@@ -2219,29 +2220,6 @@ int snd_soc_test_bits(struct snd_soc_codec *codec, unsigned short reg,
2219EXPORT_SYMBOL_GPL(snd_soc_test_bits); 2220EXPORT_SYMBOL_GPL(snd_soc_test_bits);
2220 2221
2221/** 2222/**
2222 * snd_soc_set_runtime_hwparams - set the runtime hardware parameters
2223 * @substream: the pcm substream
2224 * @hw: the hardware parameters
2225 *
2226 * Sets the substream runtime hardware parameters.
2227 */
2228int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
2229 const struct snd_pcm_hardware *hw)
2230{
2231 struct snd_pcm_runtime *runtime = substream->runtime;
2232 runtime->hw.info = hw->info;
2233 runtime->hw.formats = hw->formats;
2234 runtime->hw.period_bytes_min = hw->period_bytes_min;
2235 runtime->hw.period_bytes_max = hw->period_bytes_max;
2236 runtime->hw.periods_min = hw->periods_min;
2237 runtime->hw.periods_max = hw->periods_max;
2238 runtime->hw.buffer_bytes_max = hw->buffer_bytes_max;
2239 runtime->hw.fifo_size = hw->fifo_size;
2240 return 0;
2241}
2242EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
2243
2244/**
2245 * snd_soc_cnew - create new control 2223 * snd_soc_cnew - create new control
2246 * @_template: control template 2224 * @_template: control template
2247 * @data: control private data 2225 * @data: control private data
@@ -2259,7 +2237,6 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
2259 struct snd_kcontrol_new template; 2237 struct snd_kcontrol_new template;
2260 struct snd_kcontrol *kcontrol; 2238 struct snd_kcontrol *kcontrol;
2261 char *name = NULL; 2239 char *name = NULL;
2262 int name_len;
2263 2240
2264 memcpy(&template, _template, sizeof(template)); 2241 memcpy(&template, _template, sizeof(template));
2265 template.index = 0; 2242 template.index = 0;
@@ -2268,13 +2245,10 @@ struct snd_kcontrol *snd_soc_cnew(const struct snd_kcontrol_new *_template,
2268 long_name = template.name; 2245 long_name = template.name;
2269 2246
2270 if (prefix) { 2247 if (prefix) {
2271 name_len = strlen(long_name) + strlen(prefix) + 2; 2248 name = kasprintf(GFP_KERNEL, "%s %s", prefix, long_name);
2272 name = kmalloc(name_len, GFP_KERNEL);
2273 if (!name) 2249 if (!name)
2274 return NULL; 2250 return NULL;
2275 2251
2276 snprintf(name, name_len, "%s %s", prefix, long_name);
2277
2278 template.name = name; 2252 template.name = name;
2279 } else { 2253 } else {
2280 template.name = long_name; 2254 template.name = long_name;
@@ -3586,14 +3560,16 @@ int snd_soc_register_card(struct snd_soc_card *card)
3586 * not both or neither. 3560 * not both or neither.
3587 */ 3561 */
3588 if (!!link->codec_name == !!link->codec_of_node) { 3562 if (!!link->codec_name == !!link->codec_of_node) {
3589 dev_err(card->dev, "ASoC: Neither/both codec" 3563 dev_err(card->dev,
3590 " name/of_node are set for %s\n", link->name); 3564 "ASoC: Neither/both codec name/of_node are set for %s\n",
3565 link->name);
3591 return -EINVAL; 3566 return -EINVAL;
3592 } 3567 }
3593 /* Codec DAI name must be specified */ 3568 /* Codec DAI name must be specified */
3594 if (!link->codec_dai_name) { 3569 if (!link->codec_dai_name) {
3595 dev_err(card->dev, "ASoC: codec_dai_name not" 3570 dev_err(card->dev,
3596 " set for %s\n", link->name); 3571 "ASoC: codec_dai_name not set for %s\n",
3572 link->name);
3597 return -EINVAL; 3573 return -EINVAL;
3598 } 3574 }
3599 3575
@@ -3602,8 +3578,9 @@ int snd_soc_register_card(struct snd_soc_card *card)
3602 * can be left unspecified, and a dummy platform will be used. 3578 * can be left unspecified, and a dummy platform will be used.
3603 */ 3579 */
3604 if (link->platform_name && link->platform_of_node) { 3580 if (link->platform_name && link->platform_of_node) {
3605 dev_err(card->dev, "ASoC: Both platform name/of_node" 3581 dev_err(card->dev,
3606 " are set for %s\n", link->name); 3582 "ASoC: Both platform name/of_node are set for %s\n",
3583 link->name);
3607 return -EINVAL; 3584 return -EINVAL;
3608 } 3585 }
3609 3586
@@ -3613,8 +3590,9 @@ int snd_soc_register_card(struct snd_soc_card *card)
3613 * name alone.. 3590 * name alone..
3614 */ 3591 */
3615 if (link->cpu_name && link->cpu_of_node) { 3592 if (link->cpu_name && link->cpu_of_node) {
3616 dev_err(card->dev, "ASoC: Neither/both " 3593 dev_err(card->dev,
3617 "cpu name/of_node are set for %s\n",link->name); 3594 "ASoC: Neither/both cpu name/of_node are set for %s\n",
3595 link->name);
3618 return -EINVAL; 3596 return -EINVAL;
3619 } 3597 }
3620 /* 3598 /*
@@ -3623,8 +3601,9 @@ int snd_soc_register_card(struct snd_soc_card *card)
3623 */ 3601 */
3624 if (!link->cpu_dai_name && 3602 if (!link->cpu_dai_name &&
3625 !(link->cpu_name || link->cpu_of_node)) { 3603 !(link->cpu_name || link->cpu_of_node)) {
3626 dev_err(card->dev, "ASoC: Neither cpu_dai_name nor " 3604 dev_err(card->dev,
3627 "cpu_name/of_node are set for %s\n", link->name); 3605 "ASoC: Neither cpu_dai_name nor cpu_name/of_node are set for %s\n",
3606 link->name);
3628 return -EINVAL; 3607 return -EINVAL;
3629 } 3608 }
3630 } 3609 }
@@ -3728,8 +3707,9 @@ static inline char *fmt_multiple_name(struct device *dev,
3728 struct snd_soc_dai_driver *dai_drv) 3707 struct snd_soc_dai_driver *dai_drv)
3729{ 3708{
3730 if (dai_drv->name == NULL) { 3709 if (dai_drv->name == NULL) {
3731 dev_err(dev, "ASoC: error - multiple DAI %s registered with" 3710 dev_err(dev,
3732 " no name\n", dev_name(dev)); 3711 "ASoC: error - multiple DAI %s registered with no name\n",
3712 dev_name(dev));
3733 return NULL; 3713 return NULL;
3734 } 3714 }
3735 3715
@@ -3859,8 +3839,9 @@ static int snd_soc_register_dais(struct device *dev,
3859 3839
3860 list_for_each_entry(codec, &codec_list, list) { 3840 list_for_each_entry(codec, &codec_list, list) {
3861 if (codec->dev == dev) { 3841 if (codec->dev == dev) {
3862 dev_dbg(dev, "ASoC: Mapped DAI %s to " 3842 dev_dbg(dev,
3863 "CODEC %s\n", dai->name, codec->name); 3843 "ASoC: Mapped DAI %s to CODEC %s\n",
3844 dai->name, codec->name);
3864 dai->codec = codec; 3845 dai->codec = codec;
3865 break; 3846 break;
3866 } 3847 }
@@ -4296,8 +4277,9 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
4296 4277
4297 num_routes = of_property_count_strings(np, propname); 4278 num_routes = of_property_count_strings(np, propname);
4298 if (num_routes < 0 || num_routes & 1) { 4279 if (num_routes < 0 || num_routes & 1) {
4299 dev_err(card->dev, "ASoC: Property '%s' does not exist or its" 4280 dev_err(card->dev,
4300 " length is not even\n", propname); 4281 "ASoC: Property '%s' does not exist or its length is not even\n",
4282 propname);
4301 return -EINVAL; 4283 return -EINVAL;
4302 } 4284 }
4303 num_routes /= 2; 4285 num_routes /= 2;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index fe2be283508b..10290c71f5b6 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -526,7 +526,6 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
526 int wlistentries; 526 int wlistentries;
527 size_t wlistsize; 527 size_t wlistsize;
528 bool wname_in_long_name, kcname_in_long_name; 528 bool wname_in_long_name, kcname_in_long_name;
529 size_t name_len;
530 char *long_name; 529 char *long_name;
531 const char *name; 530 const char *name;
532 int ret; 531 int ret;
@@ -591,25 +590,19 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
591 } 590 }
592 591
593 if (wname_in_long_name && kcname_in_long_name) { 592 if (wname_in_long_name && kcname_in_long_name) {
594 name_len = strlen(w->name) - prefix_len + 1 +
595 strlen(w->kcontrol_news[kci].name) + 1;
596
597 long_name = kmalloc(name_len, GFP_KERNEL);
598 if (long_name == NULL) {
599 kfree(wlist);
600 return -ENOMEM;
601 }
602
603 /* 593 /*
604 * The control will get a prefix from the control 594 * The control will get a prefix from the control
605 * creation process but we're also using the same 595 * creation process but we're also using the same
606 * prefix for widgets so cut the prefix off the 596 * prefix for widgets so cut the prefix off the
607 * front of the widget name. 597 * front of the widget name.
608 */ 598 */
609 snprintf(long_name, name_len, "%s %s", 599 long_name = kasprintf(GFP_KERNEL, "%s %s",
610 w->name + prefix_len, 600 w->name + prefix_len,
611 w->kcontrol_news[kci].name); 601 w->kcontrol_news[kci].name);
612 long_name[name_len - 1] = '\0'; 602 if (long_name == NULL) {
603 kfree(wlist);
604 return -ENOMEM;
605 }
613 606
614 name = long_name; 607 name = long_name;
615 } else if (wname_in_long_name) { 608 } else if (wname_in_long_name) {
@@ -1272,6 +1265,14 @@ static void dapm_seq_check_event(struct snd_soc_dapm_context *dapm,
1272 ev_name = "POST_PMD"; 1265 ev_name = "POST_PMD";
1273 power = 0; 1266 power = 0;
1274 break; 1267 break;
1268 case SND_SOC_DAPM_WILL_PMU:
1269 ev_name = "WILL_PMU";
1270 power = 1;
1271 break;
1272 case SND_SOC_DAPM_WILL_PMD:
1273 ev_name = "WILL_PMD";
1274 power = 0;
1275 break;
1275 default: 1276 default:
1276 BUG(); 1277 BUG();
1277 return; 1278 return;
@@ -1732,6 +1733,14 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1732 &async_domain); 1733 &async_domain);
1733 async_synchronize_full_domain(&async_domain); 1734 async_synchronize_full_domain(&async_domain);
1734 1735
1736 list_for_each_entry(w, &down_list, power_list) {
1737 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_WILL_PMD);
1738 }
1739
1740 list_for_each_entry(w, &up_list, power_list) {
1741 dapm_seq_check_event(dapm, w, SND_SOC_DAPM_WILL_PMU);
1742 }
1743
1735 /* Power down widgets first; try to avoid amplifying pops. */ 1744 /* Power down widgets first; try to avoid amplifying pops. */
1736 dapm_seq_run(dapm, &down_list, event, false); 1745 dapm_seq_run(dapm, &down_list, event, false);
1737 1746
@@ -3057,7 +3066,6 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
3057 const struct snd_soc_dapm_widget *widget) 3066 const struct snd_soc_dapm_widget *widget)
3058{ 3067{
3059 struct snd_soc_dapm_widget *w; 3068 struct snd_soc_dapm_widget *w;
3060 size_t name_len;
3061 int ret; 3069 int ret;
3062 3070
3063 if ((w = dapm_cnew_widget(widget)) == NULL) 3071 if ((w = dapm_cnew_widget(widget)) == NULL)
@@ -3098,19 +3106,16 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
3098 break; 3106 break;
3099 } 3107 }
3100 3108
3101 name_len = strlen(widget->name) + 1;
3102 if (dapm->codec && dapm->codec->name_prefix) 3109 if (dapm->codec && dapm->codec->name_prefix)
3103 name_len += 1 + strlen(dapm->codec->name_prefix); 3110 w->name = kasprintf(GFP_KERNEL, "%s %s",
3104 w->name = kmalloc(name_len, GFP_KERNEL); 3111 dapm->codec->name_prefix, widget->name);
3112 else
3113 w->name = kasprintf(GFP_KERNEL, "%s", widget->name);
3114
3105 if (w->name == NULL) { 3115 if (w->name == NULL) {
3106 kfree(w); 3116 kfree(w);
3107 return NULL; 3117 return NULL;
3108 } 3118 }
3109 if (dapm->codec && dapm->codec->name_prefix)
3110 snprintf((char *)w->name, name_len, "%s %s",
3111 dapm->codec->name_prefix, widget->name);
3112 else
3113 snprintf((char *)w->name, name_len, "%s", widget->name);
3114 3119
3115 switch (w->id) { 3120 switch (w->id) {
3116 case snd_soc_dapm_switch: 3121 case snd_soc_dapm_switch:
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index ccb6be4d658d..b6c640332a17 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -33,6 +33,29 @@
33 33
34#define DPCM_MAX_BE_USERS 8 34#define DPCM_MAX_BE_USERS 8
35 35
36/**
37 * snd_soc_set_runtime_hwparams - set the runtime hardware parameters
38 * @substream: the pcm substream
39 * @hw: the hardware parameters
40 *
41 * Sets the substream runtime hardware parameters.
42 */
43int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
44 const struct snd_pcm_hardware *hw)
45{
46 struct snd_pcm_runtime *runtime = substream->runtime;
47 runtime->hw.info = hw->info;
48 runtime->hw.formats = hw->formats;
49 runtime->hw.period_bytes_min = hw->period_bytes_min;
50 runtime->hw.period_bytes_max = hw->period_bytes_max;
51 runtime->hw.periods_min = hw->periods_min;
52 runtime->hw.periods_max = hw->periods_max;
53 runtime->hw.buffer_bytes_max = hw->buffer_bytes_max;
54 runtime->hw.fifo_size = hw->fifo_size;
55 return 0;
56}
57EXPORT_SYMBOL_GPL(snd_soc_set_runtime_hwparams);
58
36/* DPCM stream event, send event to FE and all active BEs. */ 59/* DPCM stream event, send event to FE and all active BEs. */
37static int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir, 60static int dpcm_dapm_stream_event(struct snd_soc_pcm_runtime *fe, int dir,
38 int event) 61 int event)
@@ -124,6 +147,26 @@ static void soc_pcm_apply_msb(struct snd_pcm_substream *substream,
124 } 147 }
125} 148}
126 149
150static void soc_pcm_init_runtime_hw(struct snd_pcm_hardware *hw,
151 struct snd_soc_pcm_stream *codec_stream,
152 struct snd_soc_pcm_stream *cpu_stream)
153{
154 hw->rate_min = max(codec_stream->rate_min, cpu_stream->rate_min);
155 hw->rate_max = max(codec_stream->rate_max, cpu_stream->rate_max);
156 hw->channels_min = max(codec_stream->channels_min,
157 cpu_stream->channels_min);
158 hw->channels_max = min(codec_stream->channels_max,
159 cpu_stream->channels_max);
160 hw->formats = codec_stream->formats & cpu_stream->formats;
161 hw->rates = codec_stream->rates & cpu_stream->rates;
162 if (codec_stream->rates
163 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
164 hw->rates |= cpu_stream->rates;
165 if (cpu_stream->rates
166 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
167 hw->rates |= codec_stream->rates;
168}
169
127/* 170/*
128 * Called by ALSA when a PCM substream is opened, the runtime->hw record is 171 * Called by ALSA when a PCM substream is opened, the runtime->hw record is
129 * then initialized and any private data can be allocated. This also calls 172 * then initialized and any private data can be allocated. This also calls
@@ -189,51 +232,11 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
189 232
190 /* Check that the codec and cpu DAIs are compatible */ 233 /* Check that the codec and cpu DAIs are compatible */
191 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 234 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
192 runtime->hw.rate_min = 235 soc_pcm_init_runtime_hw(&runtime->hw, &codec_dai_drv->playback,
193 max(codec_dai_drv->playback.rate_min, 236 &cpu_dai_drv->playback);
194 cpu_dai_drv->playback.rate_min);
195 runtime->hw.rate_max =
196 min(codec_dai_drv->playback.rate_max,
197 cpu_dai_drv->playback.rate_max);
198 runtime->hw.channels_min =
199 max(codec_dai_drv->playback.channels_min,
200 cpu_dai_drv->playback.channels_min);
201 runtime->hw.channels_max =
202 min(codec_dai_drv->playback.channels_max,
203 cpu_dai_drv->playback.channels_max);
204 runtime->hw.formats =
205 codec_dai_drv->playback.formats & cpu_dai_drv->playback.formats;
206 runtime->hw.rates =
207 codec_dai_drv->playback.rates & cpu_dai_drv->playback.rates;
208 if (codec_dai_drv->playback.rates
209 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
210 runtime->hw.rates |= cpu_dai_drv->playback.rates;
211 if (cpu_dai_drv->playback.rates
212 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
213 runtime->hw.rates |= codec_dai_drv->playback.rates;
214 } else { 237 } else {
215 runtime->hw.rate_min = 238 soc_pcm_init_runtime_hw(&runtime->hw, &codec_dai_drv->capture,
216 max(codec_dai_drv->capture.rate_min, 239 &cpu_dai_drv->capture);
217 cpu_dai_drv->capture.rate_min);
218 runtime->hw.rate_max =
219 min(codec_dai_drv->capture.rate_max,
220 cpu_dai_drv->capture.rate_max);
221 runtime->hw.channels_min =
222 max(codec_dai_drv->capture.channels_min,
223 cpu_dai_drv->capture.channels_min);
224 runtime->hw.channels_max =
225 min(codec_dai_drv->capture.channels_max,
226 cpu_dai_drv->capture.channels_max);
227 runtime->hw.formats =
228 codec_dai_drv->capture.formats & cpu_dai_drv->capture.formats;
229 runtime->hw.rates =
230 codec_dai_drv->capture.rates & cpu_dai_drv->capture.rates;
231 if (codec_dai_drv->capture.rates
232 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
233 runtime->hw.rates |= cpu_dai_drv->capture.rates;
234 if (cpu_dai_drv->capture.rates
235 & (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_CONTINUOUS))
236 runtime->hw.rates |= codec_dai_drv->capture.rates;
237 } 240 }
238 241
239 ret = -EINVAL; 242 ret = -EINVAL;
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c
index 4b3be6c3c91e..29b211e9c060 100644
--- a/sound/soc/soc-utils.c
+++ b/sound/soc/soc-utils.c
@@ -159,15 +159,10 @@ int __init snd_soc_util_init(void)
159{ 159{
160 int ret; 160 int ret;
161 161
162 soc_dummy_dev = platform_device_alloc("snd-soc-dummy", -1); 162 soc_dummy_dev =
163 if (!soc_dummy_dev) 163 platform_device_register_simple("snd-soc-dummy", -1, NULL, 0);
164 return -ENOMEM; 164 if (IS_ERR(soc_dummy_dev))
165 165 return PTR_ERR(soc_dummy_dev);
166 ret = platform_device_add(soc_dummy_dev);
167 if (ret != 0) {
168 platform_device_put(soc_dummy_dev);
169 return ret;
170 }
171 166
172 ret = platform_driver_register(&soc_dummy_driver); 167 ret = platform_driver_register(&soc_dummy_driver);
173 if (ret != 0) 168 if (ret != 0)