From 2c9ebfadabcf95aec069a27e6469ea8674d254b0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 7 Apr 2009 18:10:13 +0100 Subject: [PATCH] --- yaml --- r: 148176 b: refs/heads/master c: 06f409d76f1d382167eb1cadde2e23a73272865d h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/include/sound/soc-dai.h | 1 + trunk/include/sound/soc.h | 6 ++++++ trunk/sound/soc/soc-core.c | 38 +++++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index f621a1b6bdc6..11053fd2c272 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6553e192d48af88184029066c30c9464516ea0b7 +refs/heads/master: 06f409d76f1d382167eb1cadde2e23a73272865d diff --git a/trunk/include/sound/soc-dai.h b/trunk/include/sound/soc-dai.h index 13676472ddfc..22b729fbbf84 100644 --- a/trunk/include/sound/soc-dai.h +++ b/trunk/include/sound/soc-dai.h @@ -208,6 +208,7 @@ struct snd_soc_dai { /* DAI capabilities */ struct snd_soc_pcm_stream capture; struct snd_soc_pcm_stream playback; + unsigned int symmetric_rates:1; /* DAI runtime info */ struct snd_pcm_runtime *runtime; diff --git a/trunk/include/sound/soc.h b/trunk/include/sound/soc.h index a40bc6f316fc..b1f2f8819fea 100644 --- a/trunk/include/sound/soc.h +++ b/trunk/include/sound/soc.h @@ -417,6 +417,12 @@ struct snd_soc_dai_link { /* codec/machine specific init - e.g. add machine controls */ int (*init)(struct snd_soc_codec *codec); + /* Symmetry requirements */ + unsigned int symmetric_rates:1; + + /* Symmetry data - only valid if symmetry is being enforced */ + unsigned int rate; + /* DAI pcm */ struct snd_pcm *pcm; }; diff --git a/trunk/sound/soc/soc-core.c b/trunk/sound/soc/soc-core.c index 99712f652d0d..dd28009f8969 100644 --- a/trunk/sound/soc/soc-core.c +++ b/trunk/sound/soc/soc-core.c @@ -113,6 +113,35 @@ static int soc_ac97_dev_register(struct snd_soc_codec *codec) } #endif +static int soc_pcm_apply_symmetry(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_device *socdev = rtd->socdev; + struct snd_soc_card *card = socdev->card; + struct snd_soc_dai_link *machine = rtd->dai; + struct snd_soc_dai *cpu_dai = machine->cpu_dai; + struct snd_soc_dai *codec_dai = machine->codec_dai; + int ret; + + if (codec_dai->symmetric_rates || cpu_dai->symmetric_rates || + machine->symmetric_rates) { + dev_dbg(card->dev, "Symmetry forces %dHz rate\n", + machine->rate); + + ret = snd_pcm_hw_constraint_minmax(substream->runtime, + SNDRV_PCM_HW_PARAM_RATE, + machine->rate, + machine->rate); + if (ret < 0) { + dev_err(card->dev, + "Unable to apply rate symmetry constraint: %d\n", ret); + return ret; + } + } + + return 0; +} + /* * Called by ALSA when a PCM substream is opened, the runtime->hw record is * then initialized and any private data can be allocated. This also calls @@ -221,6 +250,13 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) goto machine_err; } + /* Symmetry only applies if we've already got an active stream. */ + if (cpu_dai->active || codec_dai->active) { + ret = soc_pcm_apply_symmetry(substream); + if (ret != 0) + goto machine_err; + } + pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name); pr_debug("asoc: rate mask 0x%x\n", runtime->hw.rates); pr_debug("asoc: min ch %d max ch %d\n", runtime->hw.channels_min, @@ -521,6 +557,8 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream, } } + machine->rate = params_rate(params); + out: mutex_unlock(&pcm_mutex); return ret;