ASoC: wm_adsp: Set ADSP1 clock rate to match sys clock
authorChris Rattray <crattray@opensource.wolfsonmicro.com>
Fri, 18 Jan 2013 08:43:09 +0000 (08:43 +0000)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Fri, 18 Jan 2013 08:46:28 +0000 (17:46 +0900)
Sets the ADSP1 clock rate to match the system clock
rate. To support this the codec driver provides
details of register containing the system clock
control bits.

Signed-off-by: Chris Rattray <crattray@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
sound/soc/codecs/wm_adsp.c
sound/soc/codecs/wm_adsp.h

index 5841285..9e31162 100644 (file)
 #define ADSP1_START_SHIFT                      0  /* DSP1_START */
 #define ADSP1_START_WIDTH                      1  /* DSP1_START */
 
+/*
+ * ADSP1 Control 31
+ */
+#define ADSP1_CLK_SEL_MASK                0x0007  /* CLK_SEL_ENA */
+#define ADSP1_CLK_SEL_SHIFT                    0  /* CLK_SEL_ENA */
+#define ADSP1_CLK_SEL_WIDTH                    3  /* CLK_SEL_ENA */
+
 #define ADSP2_CONTROL  0
 #define ADSP2_CLOCKING 1
 #define ADSP2_STATUS1  4
@@ -806,12 +813,38 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
        struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
        struct wm_adsp *dsp = &dsps[w->shift];
        int ret;
+       int val;
 
        switch (event) {
        case SND_SOC_DAPM_POST_PMU:
                regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
                                   ADSP1_SYS_ENA, ADSP1_SYS_ENA);
 
+               /*
+                * For simplicity set the DSP clock rate to be the
+                * SYSCLK rate rather than making it configurable.
+                */
+               if(dsp->sysclk_reg) {
+                       ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val);
+                       if (ret != 0) {
+                               adsp_err(dsp, "Failed to read SYSCLK state: %d\n",
+                               ret);
+                               return ret;
+                       }
+
+                       val = (val & dsp->sysclk_mask)
+                               >> dsp->sysclk_shift;
+
+                       ret = regmap_update_bits(dsp->regmap,
+                                                dsp->base + ADSP1_CONTROL_31,
+                                                ADSP1_CLK_SEL_MASK, val);
+                       if (ret != 0) {
+                               adsp_err(dsp, "Failed to set clock rate: %d\n",
+                                        ret);
+                               return ret;
+                       }
+               }
+
                ret = wm_adsp_load(dsp);
                if (ret != 0)
                        goto err;
index 41206d7..cb8871a 100644 (file)
@@ -40,6 +40,9 @@ struct wm_adsp {
        struct regmap *regmap;
 
        int base;
+       int sysclk_reg;
+       int sysclk_mask;
+       int sysclk_shift;
 
        struct list_head alg_regions;