Merge branches 'acpica-fixes', 'acpi-video' and 'acpi-processor'
[deliverable/linux.git] / sound / soc / fsl / fsl_asrc.c
index 9f087d4f73ed775bdfaf9bad8c562b26a657b47d..c1a0e01cb8e79e1007c4b9ef7117206e4c891882 100644 (file)
        dev_dbg(&asrc_priv->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__)
 
 /* Sample rates are aligned with that defined in pcm.h file */
-static const u8 process_option[][8][2] = {
-       /* 32kHz 44.1kHz 48kHz   64kHz   88.2kHz 96kHz   176kHz  192kHz */
-       {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},      /* 5512Hz */
-       {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},      /* 8kHz */
-       {{0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},      /* 11025Hz */
-       {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},      /* 16kHz */
-       {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},      /* 22050Hz */
-       {{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0},},      /* 32kHz */
-       {{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},},      /* 44.1kHz */
-       {{0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},},      /* 48kHz */
-       {{1, 2}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0},},      /* 64kHz */
-       {{1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},},      /* 88.2kHz */
-       {{1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},},      /* 96kHz */
-       {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},},      /* 176kHz */
-       {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},},      /* 192kHz */
+static const u8 process_option[][12][2] = {
+       /* 8kHz 11.025kHz 16kHz 22.05kHz 32kHz 44.1kHz 48kHz   64kHz   88.2kHz 96kHz   176kHz  192kHz */
+       {{0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},      /* 5512Hz */
+       {{0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},      /* 8kHz */
+       {{0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},      /* 11025Hz */
+       {{1, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},      /* 16kHz */
+       {{1, 2}, {1, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},},      /* 22050Hz */
+       {{1, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0}, {0, 0},},      /* 32kHz */
+       {{2, 2}, {2, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},},      /* 44.1kHz */
+       {{2, 2}, {2, 2}, {2, 1}, {2, 1}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0}, {0, 0},},      /* 48kHz */
+       {{2, 2}, {2, 2}, {2, 2}, {2, 1}, {1, 2}, {0, 2}, {0, 2}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 0},},      /* 64kHz */
+       {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},},      /* 88.2kHz */
+       {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},},      /* 96kHz */
+       {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},},      /* 176kHz */
+       {{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 1}, {2, 1}, {2, 1}, {2, 1}, {2, 1},},      /* 192kHz */
 };
 
 /* Corresponding to process_option */
@@ -55,7 +55,7 @@ static int supported_input_rate[] = {
 };
 
 static int supported_asrc_rate[] = {
-       32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000,
+       8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000,
 };
 
 /**
@@ -286,6 +286,13 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair)
                return -EINVAL;
        }
 
+       if ((outrate > 8000 && outrate < 30000) &&
+           (outrate/inrate > 24 || inrate/outrate > 8)) {
+               pair_err("exceed supported ratio range [1/24, 8] for \
+                               inrate/outrate: %d/%d\n", inrate, outrate);
+               return -EINVAL;
+       }
+
        /* Validate input and output clock sources */
        clk_index[IN] = clk_map[IN][config->inclk];
        clk_index[OUT] = clk_map[OUT][config->outclk];
@@ -447,7 +454,7 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
                                  struct snd_soc_dai *dai)
 {
        struct fsl_asrc *asrc_priv = snd_soc_dai_get_drvdata(dai);
-       int width = snd_pcm_format_width(params_format(params));
+       int width = params_width(params);
        struct snd_pcm_runtime *runtime = substream->runtime;
        struct fsl_asrc_pair *pair = runtime->private_data;
        unsigned int channels = params_channels(params);
@@ -859,6 +866,10 @@ static int fsl_asrc_probe(struct platform_device *pdev)
                return PTR_ERR(asrc_priv->ipg_clk);
        }
 
+       asrc_priv->spba_clk = devm_clk_get(&pdev->dev, "spba");
+       if (IS_ERR(asrc_priv->spba_clk))
+               dev_warn(&pdev->dev, "failed to get spba clock\n");
+
        for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
                sprintf(tmp, "asrck_%x", i);
                asrc_priv->asrck_clk[i] = devm_clk_get(&pdev->dev, tmp);
@@ -939,6 +950,11 @@ static int fsl_asrc_runtime_resume(struct device *dev)
        ret = clk_prepare_enable(asrc_priv->ipg_clk);
        if (ret)
                goto disable_mem_clk;
+       if (!IS_ERR(asrc_priv->spba_clk)) {
+               ret = clk_prepare_enable(asrc_priv->spba_clk);
+               if (ret)
+                       goto disable_ipg_clk;
+       }
        for (i = 0; i < ASRC_CLK_MAX_NUM; i++) {
                ret = clk_prepare_enable(asrc_priv->asrck_clk[i]);
                if (ret)
@@ -950,6 +966,9 @@ static int fsl_asrc_runtime_resume(struct device *dev)
 disable_asrck_clk:
        for (i--; i >= 0; i--)
                clk_disable_unprepare(asrc_priv->asrck_clk[i]);
+       if (!IS_ERR(asrc_priv->spba_clk))
+               clk_disable_unprepare(asrc_priv->spba_clk);
+disable_ipg_clk:
        clk_disable_unprepare(asrc_priv->ipg_clk);
 disable_mem_clk:
        clk_disable_unprepare(asrc_priv->mem_clk);
@@ -963,6 +982,8 @@ static int fsl_asrc_runtime_suspend(struct device *dev)
 
        for (i = 0; i < ASRC_CLK_MAX_NUM; i++)
                clk_disable_unprepare(asrc_priv->asrck_clk[i]);
+       if (!IS_ERR(asrc_priv->spba_clk))
+               clk_disable_unprepare(asrc_priv->spba_clk);
        clk_disable_unprepare(asrc_priv->ipg_clk);
        clk_disable_unprepare(asrc_priv->mem_clk);
 
@@ -975,6 +996,9 @@ static int fsl_asrc_suspend(struct device *dev)
 {
        struct fsl_asrc *asrc_priv = dev_get_drvdata(dev);
 
+       regmap_read(asrc_priv->regmap, REG_ASRCFG,
+                   &asrc_priv->regcache_cfg);
+
        regcache_cache_only(asrc_priv->regmap, true);
        regcache_mark_dirty(asrc_priv->regmap);
 
@@ -995,6 +1019,10 @@ static int fsl_asrc_resume(struct device *dev)
        regcache_cache_only(asrc_priv->regmap, false);
        regcache_sync(asrc_priv->regmap);
 
+       regmap_update_bits(asrc_priv->regmap, REG_ASRCFG,
+                          ASRCFG_NDPRi_ALL_MASK | ASRCFG_POSTMODi_ALL_MASK |
+                          ASRCFG_PREMODi_ALL_MASK, asrc_priv->regcache_cfg);
+
        /* Restart enabled pairs */
        regmap_update_bits(asrc_priv->regmap, REG_ASRCTR,
                           ASRCTR_ASRCEi_ALL_MASK, asrctr);
This page took 0.043262 seconds and 5 git commands to generate.