summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolin Chen <b42378@freescale.com>2013-07-10 14:36:00 +0800
committerNicolin Chen <b42378@freescale.com>2013-07-11 18:03:31 +0800
commit65fd4e32d79a7d71702a584e0e704062aae5ca94 (patch)
tree4ab28e07ef1393c06807ee6c477fbbe8f4e24eb4
parent9b3031dcd2c020d7abfdea510fbea55a59fe5d3e (diff)
ENGR00270401 ASoC: imx-wm8962: Add parameters checking for hw_params
WM8962 doesn't support asymmetric parameters for playback and capture, so add hw_params check in machine driver to obviate some potential risks. Acked-by: Wang Shengjiu <b02247@freescale.com> Signed-off-by: Nicolin Chen <b42378@freescale.com> (cherry picked from commit 85059ec43e34662feca2c58b3a31cf93d79d00bc)
-rw-r--r--sound/soc/imx/imx-wm8962.c65
1 files changed, 61 insertions, 4 deletions
diff --git a/sound/soc/imx/imx-wm8962.c b/sound/soc/imx/imx-wm8962.c
index 8cf4bdd577de..d6ab88d7d261 100644
--- a/sound/soc/imx/imx-wm8962.c
+++ b/sound/soc/imx/imx-wm8962.c
@@ -115,6 +115,56 @@ static void imx_hifi_shutdown(struct snd_pcm_substream *substream)
return;
}
+static int check_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct imx_priv *priv = &card_priv;
+ unsigned int channels = params_channels(params);
+ unsigned int sample_rate = params_rate(params);
+ snd_pcm_format_t sample_format = params_format(params);
+
+ substream->runtime->sample_bits =
+ snd_pcm_format_physical_width(sample_format);
+ substream->runtime->rate = sample_rate;
+ substream->runtime->format = sample_format;
+ substream->runtime->channels = channels;
+
+ if (!priv->first_stream) {
+ priv->first_stream = substream;
+ } else {
+ priv->second_stream = substream;
+
+ /* Check two sample rates of two streams */
+ if (priv->first_stream->runtime->rate !=
+ priv->second_stream->runtime->rate) {
+ pr_err("\n!KEEP THE SAME SAMPLE RATE: %d!\n",
+ priv->first_stream->runtime->rate);
+ return -EINVAL;
+ }
+
+ /* Check two sample bits of two streams */
+ if (priv->first_stream->runtime->sample_bits !=
+ priv->second_stream->runtime->sample_bits) {
+ snd_pcm_format_t first_format =
+ priv->first_stream->runtime->format;
+
+ pr_err("\n!KEEP THE SAME FORMAT: %s!\n",
+ snd_pcm_format_name(first_format));
+ return -EINVAL;
+ }
+
+ /* Check two channel numbers of two streams */
+ if (priv->first_stream->runtime->channels !=
+ priv->second_stream->runtime->channels) {
+ pr_err("\n!KEEP THE SAME CHANNEL NUMBER: %d!\n",
+ priv->first_stream->runtime->channels);
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
static int imx_hifi_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
@@ -128,10 +178,17 @@ static int imx_hifi_hw_params(struct snd_pcm_substream *substream,
u32 dai_format;
unsigned int pll_out;
- if (!priv->first_stream)
- priv->first_stream = substream;
- else
- priv->second_stream = substream;
+ /*
+ * WM8962 doesn't support two substreams in different parameters
+ * (i.e. different sample rates, audio formats, channel numbers)
+ * So we here check the three parameters above of two substreams
+ * if they are running in the same time.
+ */
+ ret = check_hw_params(substream, params);
+ if (ret < 0) {
+ pr_err("Failed to match hw params: %d\n", ret);
+ return ret;
+ }
dai_format = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM;