summaryrefslogtreecommitdiff
path: root/sound/soc/fsl/fsl_micfil.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/fsl/fsl_micfil.c')
-rw-r--r--sound/soc/fsl/fsl_micfil.c55
1 files changed, 50 insertions, 5 deletions
diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
index 7b88d52f27de..79ef4e269bc9 100644
--- a/sound/soc/fsl/fsl_micfil.c
+++ b/sound/soc/fsl/fsl_micfil.c
@@ -24,6 +24,7 @@
#include <sound/core.h>
#include "fsl_micfil.h"
+#include "fsl_utils.h"
#define MICFIL_OSR_DEFAULT 16
@@ -42,12 +43,15 @@ struct fsl_micfil {
const struct fsl_micfil_soc_data *soc;
struct clk *busclk;
struct clk *mclk;
+ struct clk *pll8k_clk;
+ struct clk *pll11k_clk;
struct snd_dmaengine_dai_dma_data dma_params_rx;
struct sdma_peripheral_config sdmacfg;
unsigned int dataline;
char name[32];
int irq[MICFIL_IRQ_LINES];
enum quality quality;
+ int dc_remover;
};
struct fsl_micfil_soc_data {
@@ -263,6 +267,27 @@ static int fsl_micfil_trigger(struct snd_pcm_substream *substream, int cmd,
return 0;
}
+static int fsl_micfil_reparent_rootclk(struct fsl_micfil *micfil, unsigned int sample_rate)
+{
+ struct device *dev = &micfil->pdev->dev;
+ u64 ratio = sample_rate;
+ struct clk *clk;
+ int ret;
+
+ /* Get root clock */
+ clk = micfil->mclk;
+
+ /* Disable clock first, for it was enabled by pm_runtime */
+ clk_disable_unprepare(clk);
+ fsl_asoc_reparent_pll_clocks(dev, clk, micfil->pll8k_clk,
+ micfil->pll11k_clk, ratio);
+ ret = clk_prepare_enable(clk);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
static int fsl_micfil_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -286,6 +311,10 @@ static int fsl_micfil_hw_params(struct snd_pcm_substream *substream,
if (ret)
return ret;
+ ret = fsl_micfil_reparent_rootclk(micfil, rate);
+ if (ret)
+ return ret;
+
ret = clk_set_rate(micfil->mclk, rate * clk_div * osr * 8);
if (ret)
return ret;
@@ -317,12 +346,25 @@ static const struct snd_soc_dai_ops fsl_micfil_dai_ops = {
static int fsl_micfil_dai_probe(struct snd_soc_dai *cpu_dai)
{
struct fsl_micfil *micfil = dev_get_drvdata(cpu_dai->dev);
- int ret;
+ struct device *dev = cpu_dai->dev;
+ unsigned int val = 0;
+ int ret, i;
- micfil->quality = QUALITY_MEDIUM;
+ micfil->quality = QUALITY_VLOW0;
- /* set default gain to max_gain */
- regmap_write(micfil->regmap, REG_MICFIL_OUT_CTRL, 0x77777777);
+ /* set default gain to 2 */
+ regmap_write(micfil->regmap, REG_MICFIL_OUT_CTRL, 0x22222222);
+
+ /* set DC Remover in bypass mode*/
+ for (i = 0; i < MICFIL_OUTPUT_CHANNELS; i++)
+ val |= MICFIL_DC_BYPASS << MICFIL_DC_CHX_SHIFT(i);
+ ret = regmap_update_bits(micfil->regmap, REG_MICFIL_DC_CTRL,
+ MICFIL_DC_CTRL_CONFIG, val);
+ if (ret) {
+ dev_err(dev, "failed to set DC Remover mode bits\n");
+ return ret;
+ }
+ micfil->dc_remover = MICFIL_DC_BYPASS;
snd_soc_dai_init_dma_data(cpu_dai, NULL,
&micfil->dma_params_rx);
@@ -353,7 +395,7 @@ static const struct snd_soc_component_driver fsl_micfil_component = {
.name = "fsl-micfil-dai",
.controls = fsl_micfil_snd_controls,
.num_controls = ARRAY_SIZE(fsl_micfil_snd_controls),
-
+ .legacy_dai_naming = 1,
};
/* REGMAP */
@@ -577,6 +619,9 @@ static int fsl_micfil_probe(struct platform_device *pdev)
return PTR_ERR(micfil->busclk);
}
+ fsl_asoc_get_pll_clocks(&pdev->dev, &micfil->pll8k_clk,
+ &micfil->pll11k_clk);
+
/* init regmap */
regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(regs))