audio: pdm dclk support 3.072m/1.024m/768k
authorXing Wang <xing.wang@amlogic.com>
Thu, 13 Jul 2017 12:31:44 +0000 (20:31 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Mon, 17 Jul 2017 03:53:28 +0000 (20:53 -0700)
PD#147320: audio: pdm dclk support 3.072m/1.024m/768k

Change-Id: I3904fa73fed7c91bf7f709317e211053cf4bb9b2
Signed-off-by: Xing Wang <xing.wang@amlogic.com>
sound/soc/amlogic/auge/pdm.c
sound/soc/amlogic/auge/pdm_hw.c

index 93ad66a..bb0faf4 100644 (file)
@@ -133,6 +133,37 @@ static int pdm_hcic_shift_gain_set_enum(
        return 0;
 }
 
+int pdm_dclk;
+
+static const char *const pdm_dclk_texts[] = {
+       "pdm dclk 3.072m, support 8k/16k/32k/48k",
+       "pdm dclk 1.024m, support 8k/16k",
+       "pdm dclk   768k, support 8k/16k",
+};
+
+static const struct soc_enum pdm_dclk_enum =
+       SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(pdm_dclk_texts),
+                       pdm_dclk_texts);
+
+static int pdm_dclk_get_enum(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       ucontrol->value.enumerated.item[0] = pdm_dclk;
+
+       return 0;
+}
+
+static int pdm_dclk_set_enum(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       pdm_dclk = ucontrol->value.enumerated.item[0];
+
+       return 0;
+}
+
+
 static const struct snd_kcontrol_new snd_pdm_controls[] = {
        /* which set */
        SOC_ENUM_EXT("PDM Filter Mode",
@@ -145,6 +176,13 @@ static const struct snd_kcontrol_new snd_pdm_controls[] = {
                     pdm_hcic_shift_gain_enum,
                     pdm_hcic_shift_gain_get_enum,
                     pdm_hcic_shift_gain_set_enum),
+
+
+       SOC_ENUM_EXT("pdm dclk",
+                    pdm_dclk_enum,
+                    pdm_dclk_get_enum,
+                    pdm_dclk_set_enum),
+
 };
 
 static irqreturn_t aml_pdm_isr_handler(int irq, void *data)
@@ -467,17 +505,38 @@ static int aml_pdm_dai_prepare(
                        bitwidth, runtime->channels);
 
                /* filter for pdm */
-               if (runtime->rate == 48000)
-                       osr = 64;
-               else if (runtime->rate == 32000)
-                       osr = 96;
-               else if (runtime->rate == 16000)
-                       osr = 192;
-               else if (runtime->rate == 8000)
-                       osr = 384;
-               else
-                       pr_err("Not support rate:%d\n", runtime->rate);
-
+               if (pdm_dclk == 1) {
+                       if (runtime->rate == 16000)
+                               osr = 64;
+                       else if (runtime->rate == 8000)
+                               osr = 128;
+                       else {
+                               pr_err("Not support rate:%d\n", runtime->rate);
+                               return -EINVAL;
+                       }
+               } else if (pdm_dclk == 2) {
+                       if (runtime->rate == 16000)
+                               osr = 48;
+                       else if (runtime->rate == 8000)
+                               osr = 96;
+                       else {
+                               pr_err("Not support rate:%d\n", runtime->rate);
+                               return -EINVAL;
+                       }
+               } else {
+                       if (runtime->rate == 48000)
+                               osr = 64;
+                       else if (runtime->rate == 32000)
+                               osr = 96;
+                       else if (runtime->rate == 16000)
+                               osr = 192;
+                       else if (runtime->rate == 8000)
+                               osr = 384;
+                       else {
+                               pr_err("Not support rate:%d\n", runtime->rate);
+                               return -EINVAL;
+                       }
+               }
                p_pdm->filter_mode = s_pdm_filter_mode;
                aml_pdm_filter_ctrl(osr, p_pdm->filter_mode);
        }
@@ -535,7 +594,13 @@ static int aml_pdm_dai_set_sysclk(struct snd_soc_dai *cpu_dai,
 
        clk_set_rate(p_pdm->clk_pll, pll_freq);
        clk_set_rate(p_pdm->clk_pdm_sysclk, pll_freq);
-       clk_set_rate(p_pdm->clk_pdm_dclk, pll_freq / 64);
+
+       if (pdm_dclk == 1)
+               clk_set_rate(p_pdm->clk_pdm_dclk, pll_freq / (64 * 3));
+       else if (pdm_dclk == 2)
+               clk_set_rate(p_pdm->clk_pdm_dclk, pll_freq / (64 * 4));
+       else
+               clk_set_rate(p_pdm->clk_pdm_dclk, pll_freq / 64);
 
        return 0;
 }
index 52463ef..27059cf 100644 (file)
@@ -106,8 +106,27 @@ static void aml_pdm_filters_config(int osr,
        int32_t hpf_out_factor;
        int32_t pdm_out_mode;
 
-       /* current Dclk: 3072000*/
        switch (osr) {
+       case 32:
+               hcic_dn_rate = 0x4;
+               hcic_gain        = 0x80;
+               hcic_shift       = 0xa;
+               break;
+       case 40:
+               hcic_dn_rate = 0x5;
+               hcic_gain        = 0x54;
+               hcic_shift       = 0xb;
+               break;
+       case 48:
+               hcic_dn_rate = 0x6;
+               hcic_gain        = 0x43;
+               hcic_shift       = 0xc;
+               break;
+       case 56:
+               hcic_dn_rate = 0x7;
+               hcic_gain        = 0x7d;
+               hcic_shift       = 0xe;
+               break;
        case 64:
                hcic_dn_rate = 0x0008;
                hcic_gain        = 0x80;
@@ -297,6 +316,10 @@ void aml_pdm_filter_ctrl(int osr, int mode)
        case 384:
                lpf2_coeff = lpf2_osr384;
                break;
+       case 32:
+       case 40:
+       case 48:
+       case 56:
        default:
                pr_info("default mode 1, osr 64, 48k\n");
                lpf2_coeff = lpf2_osr64;