audio: add soc DRC tune interface [1/3]
authorZhe Wang <Zhe.Wang@amlogic.com>
Thu, 14 Mar 2019 14:16:36 +0000 (22:16 +0800)
committerTao Zeng <tao.zeng@amlogic.com>
Mon, 25 Mar 2019 06:15:00 +0000 (23:15 -0700)
PD#SWPL-5904

Problem:
Audio DRC in SOC is out of work

Solution:
Add DRC tune interface

Verify:
Verify on X301

Change-Id: I5e8ecc6dafd7fc3805b0c3e60a6ec4c945729119
Signed-off-by: Zhe Wang <Zhe.Wang@amlogic.com>
sound/soc/amlogic/auge/effects_hw_v2.c
sound/soc/amlogic/auge/effects_hw_v2.h
sound/soc/amlogic/auge/effects_hw_v2_coeff.h
sound/soc/amlogic/auge/effects_v2.c

index 63b0f31..b5db9d6 100644 (file)
@@ -19,7 +19,6 @@
 #include "effects_hw_v2.h"
 #include "regs.h"
 #include "iomap.h"
-
 #include "tdm_hw.h"
 #include "spdif_hw.h"
 
@@ -48,60 +47,82 @@ void aed_get_ram_coeff(int add, int len, unsigned int *params)
        }
 }
 
-void aed_set_multiband_drc_coeff(int len, int *params)
+void aed_set_multiband_drc_coeff(int band, unsigned int *params)
 {
-       int band_len = len / 3, i, j;
+       int i;
        int offset = AED_MDRC_RMS_COEF10 - AED_MDRC_RMS_COEF00;
        int reg = AED_MDRC_RMS_COEF00;
 
-       for (i = 0; i < 3; i++)
-               for (j = 0; j < band_len; j++)
-                       eqdrc_write(reg + i * offset + j,
-                               params[i * band_len + j]);
-
-       eqdrc_write(AED_MDRC_THD0, 0xf6000000);
-       eqdrc_write(AED_MDRC_K0, 0x20000);
-       eqdrc_write(AED_MDRC_OFFSET0, 0x200);
-       eqdrc_write(AED_MDRC_LOW_GAIN, 0x40000);
-
-       eqdrc_write(AED_MDRC_THD1, 0xfb000000);
-       eqdrc_write(AED_MDRC_K1, 0x26666);
-       eqdrc_write(AED_MDRC_OFFSET1, 0x200);
-       eqdrc_write(AED_MDRC_MID_GAIN, 0x40000);
-
-       eqdrc_write(AED_MDRC_THD2, 0xf1000000);
-       eqdrc_write(AED_MDRC_K2, 0x2cccc);
-       eqdrc_write(AED_MDRC_OFFSET2, 0x200);
-       eqdrc_write(AED_MDRC_HIGH_GAIN, 0x40000);
+       for (i = 0; i < offset; i++) {
+               eqdrc_write(reg + band * offset + i,
+                       params[band * offset + i]);
+       }
 }
 
-void aed_set_fullband_drc_coeff(int len, int *params)
+void aed_get_multiband_drc_coeff(int band, unsigned int *params)
 {
        int i;
+       int offset = AED_MDRC_RMS_COEF10 - AED_MDRC_RMS_COEF00;
+       int reg = AED_MDRC_RMS_COEF00;
 
-       for (i = 0; i < len; i++)
-               eqdrc_write(AED_DRC_RELEASE_COEF00 + i,
-                       params[i]);
-
-       eqdrc_write(AED_DRC_RMS_COEF0, 0x34ebb);
-       eqdrc_write(AED_DRC_RMS_COEF1, 0x7cb145);
-       eqdrc_write(AED_DRC_THD0, 0xf7000000);
-       eqdrc_write(AED_DRC_THD1, 0xf6000000);
-       eqdrc_write(AED_DRC_THD2, 0xec000000);
-       eqdrc_write(AED_DRC_THD3, 0xe2000000);
-       eqdrc_write(AED_DRC_THD4, 0xce000000);
-       eqdrc_write(AED_DRC_K0, 0x20000);
-       eqdrc_write(AED_DRC_K1, 0x46666);
-       eqdrc_write(AED_DRC_K2, 0x40000);
-       eqdrc_write(AED_DRC_K3, 0x39999);
-       eqdrc_write(AED_DRC_K4, 0x33333);
-       eqdrc_write(AED_DRC_K5, 0x4cccc);
-       eqdrc_write(AED_DRC_THD_OUT0, 0xf5e66667);
-       eqdrc_write(AED_DRC_THD_OUT1, 0xebe66667);
-       eqdrc_write(AED_DRC_THD_OUT2, 0xe2e66667);
-       eqdrc_write(AED_DRC_THD_OUT3, 0xd2e66667);
-       eqdrc_write(AED_DRC_OFFSET, 0x100);
-       eqdrc_write(AED_DRC_LOOPBACK_CNTL, (144 << 0));
+       for (i = 0; i < offset; i++) {
+               *(params + band * offset + i) =
+                       eqdrc_read(reg + band * offset + i);
+       }
+}
+
+void aed_set_fullband_drc_coeff(int group, unsigned int *params)
+{
+       unsigned int *p = params;
+
+       if (group == 0) {
+               eqdrc_write(AED_DRC_RELEASE_COEF00, *p++);
+               eqdrc_write(AED_DRC_RELEASE_COEF01, *p++);
+               eqdrc_write(AED_DRC_ATTACK_COEF00, *p++);
+               eqdrc_write(AED_DRC_ATTACK_COEF01, *p++);
+               eqdrc_write(AED_DRC_THD0, *p++);
+               eqdrc_write(AED_DRC_K0, *p++);
+       } else if (group == 1) {
+               eqdrc_write(AED_DRC_RELEASE_COEF10, *p++);
+               eqdrc_write(AED_DRC_RELEASE_COEF11, *p++);
+               eqdrc_write(AED_DRC_ATTACK_COEF10, *p++);
+               eqdrc_write(AED_DRC_ATTACK_COEF11, *p++);
+               eqdrc_write(AED_DRC_THD1, *p++);
+               eqdrc_write(AED_DRC_K2, *p++);
+               eqdrc_write(AED_DRC_THD_OUT0, eqdrc_read(AED_DRC_THD1));
+       } else if (group == 2) {
+               eqdrc_write(AED_DRC_RMS_COEF0, *p++);
+               eqdrc_write(AED_DRC_RMS_COEF1, *p++);
+               eqdrc_write(AED_DRC_LOOPBACK_CNTL, *p++);
+               /*THD_OUT0 = THD1; K1 = 1.0*/
+               eqdrc_write(AED_DRC_THD_OUT0, eqdrc_read(AED_DRC_THD1));
+               eqdrc_write(AED_DRC_K1, 0x40000);
+       }
+}
+
+void aed_get_fullband_drc_coeff(int len, unsigned int *params)
+{
+       unsigned int *p = params;
+
+       *p++ = eqdrc_read(AED_DRC_RELEASE_COEF00);
+       *p++ = eqdrc_read(AED_DRC_RELEASE_COEF01);
+       *p++ = eqdrc_read(AED_DRC_ATTACK_COEF00);
+       *p++ = eqdrc_read(AED_DRC_ATTACK_COEF01);
+       *p++ = eqdrc_read(AED_DRC_THD0);
+       *p++ = eqdrc_read(AED_DRC_K0);
+
+       *p++ = eqdrc_read(AED_DRC_RELEASE_COEF10);
+       *p++ = eqdrc_read(AED_DRC_RELEASE_COEF11);
+       *p++ = eqdrc_read(AED_DRC_ATTACK_COEF10);
+       *p++ = eqdrc_read(AED_DRC_ATTACK_COEF11);
+       *p++ = eqdrc_read(AED_DRC_THD1);
+       *p++ = eqdrc_read(AED_DRC_K2);
+
+       *p++ = eqdrc_read(AED_DRC_RMS_COEF0);
+       *p++ = eqdrc_read(AED_DRC_RMS_COEF1);
+       *p++ = eqdrc_read(AED_DRC_LOOPBACK_CNTL);
+       *p++ = eqdrc_read(AED_DRC_THD_OUT0);
+       *p++ = eqdrc_read(AED_DRC_K1);
 }
 
 void aed_set_mixer_params(void)
@@ -155,22 +176,29 @@ void aed_eq_taps(unsigned int eq1_taps)
        eqdrc_update_bits(AED_EQ_TAP_CNTL, 0x1f << 5, (20 - eq1_taps) << 5);
 }
 
-void aed_multiband_drc_enable(bool enable)
+void aed_set_multiband_drc_param(void)
 {
-       eqdrc_write(AED_MDRC_CNTL,
-               (1 << 16)     |  /* mdrc_pow_sel */
-               (enable << 8) |  /* mdrc_all_en */
-               (7 << 3)      |  /* mdrc_rms_mode[2:0] */
-               (7 << 0)         /* mdrc_en[2:0] */
-       );
+       eqdrc_update_bits(AED_MDRC_CNTL,
+               (0x1 << 16) | (0x7 << 3) | (0x7 << 0),
+               (0x0 << 16) | (0x7 << 3) | (0x7 << 0));
 }
 
-void aed_fullband_drc_enable(bool enable)
+void aed_set_fullband_drc_param(int tap)
 {
-       eqdrc_write(AED_DRC_CNTL,
-               (5 << 3) |  /* drc_tap */
-               (enable << 0)   /* drc_en */
-       );
+       eqdrc_update_bits(AED_DRC_CNTL,
+               (0x7 << 3), (tap << 3));
+}
+
+void aed_set_multiband_drc_enable(bool enable)
+{
+       eqdrc_update_bits(AED_MDRC_CNTL,
+               (0x1 << 8), (enable << 8));
+}
+
+void aed_set_fullband_drc_enable(bool enable)
+{
+       eqdrc_update_bits(AED_DRC_CNTL,
+               (0x1 << 0), (enable << 0));
 }
 
 void aed_set_volume(
index f99e3b6..cfa8e0f 100644 (file)
 
 void aed_set_ram_coeff(int add, int len, unsigned int *params);
 void aed_get_ram_coeff(int add, int len, unsigned int *params);
-void aed_set_multiband_drc_coeff(int len, int *params);
-void aed_set_fullband_drc_coeff(int len, int *params);
+void aed_set_multiband_drc_coeff(int band, unsigned int *params);
+void aed_get_multiband_drc_coeff(int band, unsigned int *params);
+void aed_set_fullband_drc_coeff(int group, unsigned int *params);
+void aed_get_fullband_drc_coeff(int len, unsigned int *params);
 void aed_dc_enable(bool enable);
 void aed_nd_enable(bool enable);
 void aed_eq_enable(int idx, bool enable);
-void aed_multiband_drc_enable(bool enable);
-void aed_fullband_drc_enable(bool enable);
-void aed_set_volume(
-               unsigned int master_volume,
-               unsigned int Lch_vol,
-               unsigned int Rch_vol);
+void aed_set_fullband_drc_enable(bool enable);
+void aed_set_multiband_drc_enable(bool enable);
+void aed_set_volume(unsigned int master_volume,
+               unsigned int Lch_vol, unsigned int Rch_vol);
 void aed_set_lane_and_channels(int lane_mask, int ch_mask);
 void aed_set_ctrl(bool enable, int sel, enum frddr_dest module);
 void aed_set_format(int msb, enum ddr_types frddr_type, enum ddr_num source);
 void aed_enable(bool enable);
 void aed_set_mixer_params(void);
 void aed_eq_taps(unsigned int eq1_taps);
+void aed_set_multiband_drc_param(void);
+void aed_set_fullband_drc_param(int tap);
 
 #endif
index 02ee7e8..d0c9433 100644 (file)
  *
  */
 
-#define EQ_BAND                  20
-#define FILTER_PARAM_SIZE        5
-#define DC_CUT_FILTER_RAM_ADD    0
-#define DC_CUT_FILTER_SIZE       FILTER_PARAM_SIZE
-#define EQ_FILTER_RAM_ADD        (DC_CUT_FILTER_RAM_ADD + FILTER_PARAM_SIZE)
-#define EQ_FILTER_SIZE_CH        (EQ_BAND*FILTER_PARAM_SIZE)
-#define EQ_FILTER_SIZE           (2*EQ_FILTER_SIZE_CH)
-#define CROSSOVER_FILTER_RAM_ADD (EQ_FILTER_RAM_ADD + EQ_FILTER_SIZE)
-#define CROSSOVER_FILTER_SIZE    (4*FILTER_PARAM_SIZE)
+#ifndef __EFFECTS_HW_V2_COEFF_H__
+#define __EFFECTS_HW_V2_COEFF_H__
 
-#define FILTER_PARAM_BYTE        66 /*"0x%8.8x "*/
+#define EQ_BAND                  (20)
+#define FILTER_PARAM_SIZE        (5)
+#define DC_CUT_FILTER_RAM_ADD    (0)
+#define DC_CUT_FILTER_SIZE       (5)
+#define EQ_FILTER_RAM_ADD        (5)
+#define EQ_FILTER_SIZE_CH        (100)
+#define EQ_FILTER_SIZE           (200)
+#define CROSSOVER_FILTER_RAM_ADD (205)
+#define CROSSOVER_FILTER_SIZE    (20)
+#define CROSSOVER_FILTER_BAND    (4)
 
+#define FILTER_PARAM_BYTE        (66) /*"0x%8.8x "*/
+
+/* 20Hz, highpass filter */
 static unsigned int DC_CUT_COEFF[DC_CUT_FILTER_SIZE] = {
-       0x7fd51b, 0x30055c9, 0x7fd51b, 0x30055e6, 0x7b1673
+       0x007fc365, 0x03007935, 0x007fc365, 0x03007952, 0x007f86e7
 };
 
 static unsigned int EQ_COEFF[EQ_FILTER_SIZE] = {
@@ -80,68 +85,85 @@ static unsigned int EQ_COEFF[EQ_FILTER_SIZE] = {
        0x800000, 0x0, 0x0, 0x0, 0x0,
 };
 
-/*fiter1 fc: 120Hz; fiter2 fc: 4.5KHz*/
+/*fiter1 fc: 150Hz; fiter2 fc: 5KHz*/
 static unsigned int CROSSOVER_COEFF[CROSSOVER_FILTER_SIZE] = {
        /*low-pass filter1*/
-       0x25b,    0x4b5,         0x25b,    0x3045701, 0x7bb269,
+       0x00000319, 0x00000632, 0x00000319, 0x0304fa54, 0x007b1210,
        /*high-pass filter1*/
-       0x7dd6da, 0x304524c, 0x7dd6da, 0x3045701, 0x7bb269,
+       0x007d85ef, 0x0304f422, 0x007d85ef, 0x0304fa54, 0x007b1210,
        /*low-pass filter2*/
-       0x7f3ee,  0xfe7dc,       0x7f3ee,  0x37f9f4a, 0x20306d,
+       0x0008388a, 0x00107113, 0x0008388a, 0x0381c139, 0x001f20ee,
        /*high-pass filter2*/
-       0x482449, 0x36fb76e, 0x482449, 0x37f9f4a, 0x20306d,
+       0x004757ed, 0x03715025, 0x004757ed, 0x0381c139, 0x001f20ee,
 };
 
-#define AED_MULTIBAND_DRC_LENGTH 18
-#define AED_FULLBAND_DRC_LENGTH  24
-
-static int multiband_drc_coeff[] = {
-       0x34ebb,   /* Low SMS coeff0 */
-       0x7f54e0,  /* Low SMS coeff1 */
+#define AED_SINGLE_BAND_DRC_SIZE (10)
+#define AED_MULTIBAND_DRC_BANDS  (3)
+#define AED_MULTIBAND_DRC_SIZE   (30)
+#define MULTIBAND_DRC_PARAM_BYTE (120) /*"0x%8.8x "*/
+/*RMS:5ms, ATTACK:2ms, RELEASE:20ms*/
+static unsigned int multiband_drc_coeff[AED_MULTIBAND_DRC_SIZE] = {
+       0x34ebb,   /* Low RMS coeff0 */
+       0x7cb145,  /* Low RMS coeff1 */
        0x5188,    /* Low RELEASE coeff0 */
        0x7fae78,  /* Low RELEASE coeff1 */
        0x3263a,   /* Low ATTACK coeff0 */
        0x7cd9c6,  /* Low ATTACK coeff1 */
+       0x0,       /* Low THD0 coeff */
+       0x40000,   /* Low K0 coeff */
+       0x40000,   /* Low GAIN */
+       0x0,       /* Low OFFSET coeff*/
 
-       0x34ebb,   /* Mid */
-       0x7f54e0,
-       0x5188,
-       0x7fae78,
-       0x3263a,
-       0x7cd9c6,
+       0x34ebb,   /* Mid RMS coeff0 */
+       0x7cb145,  /* Mid RMS coeff1 */
+       0x5188,    /* Mid RELEASE coeff0 */
+       0x7fae78,  /* Mid RELEASE coeff1 */
+       0x3263a,   /* Mid ATTACK coeff0 */
+       0x7cd9c6,  /* Mid ATTACK coeff1 */
+       0x0,       /* Mid THD0 coeff */
+       0x40000,   /* Mid K0 coeff */
+       0x0,       /* Mid OFFSET coeff*/
+       0x40000,   /* Mid GAIN */
 
-       0x34ebb,   /* High */
-       0x7f54e0,
-       0x5188,
-       0x7fae78,
-       0x3263a,
-       0x7cd9c6,
+       0x34ebb,   /* High RMS coeff0 */
+       0x7cb145,  /* High RMS coeff1 */
+       0x5188,    /* High RELEASE coeff0 */
+       0x7fae78,  /* High RELEASE coeff1 */
+       0x3263a,   /* High ATTACK coeff0 */
+       0x7cd9c6,  /* High ATTACK coeff1 */
+       0x0,       /* High THD0 coeff */
+       0x40000,   /* High K0 coeff */
+       0x0,       /* High OFFSET coeff*/
+       0x40000,   /* High GAIN */
 };
 
-static int fullband_drc_coeff[] = {
-       0x5188,     /* RELEASE_COEF00 */
+#define AED_FULLBAND_DRC_SIZE        (17)
+#define AED_FULLBAND_DRC_BYTES       (70)
+#define AED_FULLBAND_DRC_OFFSET      (6)
+#define AED_FULLBAND_DRC_GROUP_SIZE  (3)
+/*K0 = 0dB; THD0 = 0; K1 = 3.0; THD1 = -70dB*/
+/*RMS:5ms, ATTACK:2ms, RELEASE:20ms*/
+/*delay: 144 sample max:255*/
+static int fullband_drc_coeff[AED_FULLBAND_DRC_SIZE] = {
+       0x5188,         /* RELEASE_COEF00 */
        0x7fae78,       /* RELEASE_COEF01 */
-       0x5188,
-       0x7fae78,
-       0x5188,
-       0x7fae78,
-       0x5188,
-       0x7fae78,
-       0x5188,
-       0x7fae78,
-       0x5188,     /* RELEASE_COEF50 */
-       0x7fae78,       /* RELEASE_COEF51 */
        0x3263a,        /* ATTACK_COEF00 */
        0x7cd9c6,       /* ATTACK_COEF01 */
-       0x3263a,
-       0x7cd9c6,
-       0x3263a,
-       0x7cd9c6,
-       0x3263a,
-       0x7cd9c6,
-       0x3263a,
-       0x7cd9c6,
-       0x3263a,        /* ATTACK_COEF50 */
-       0x7cd9c6,       /* ATTACK_COEF51 */
+       0x0,            /* THD0 */
+       0x0,            /* K0 */
+
+       0x5188,         /* RELEASE_COEF10 */
+       0x7fae78,       /* RELEASE_COEF11 */
+       0x3263a,        /* ATTACK_COEF10 */
+       0x7cd9c6,       /* ATTACK_COEF11 */
+       0xdd000000,     /* THD1 */
+       0xc0000,        /* K2 */
+
+       0x34ebb,        /* RMS coeff0 */
+       0x7cb145,       /* RMS coeff1 */
+       0x90,           /* Delay time*/
+       0xdd000000,     /* THD_OUT0 */
+       0x40000,        /* K1 */
 };
 
+#endif
index 695ca43..86a696b 100644 (file)
@@ -70,7 +70,6 @@ struct audioeffect {
        bool eq_en;
        bool multiband_drc_en;
        bool fullband_drc_en;
-       int mask_en;
 
        int lane_mask;
        int ch_mask;
@@ -175,78 +174,6 @@ static int mixer_aed_write(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
-static int mixer_aed_enable_DC(struct snd_kcontrol *kcontrol,
-       struct snd_ctl_elem_value *ucontrol)
-{
-       struct audioeffect *p_effect =  snd_kcontrol_chip(kcontrol);
-
-       p_effect->dc_en = ucontrol->value.integer.value[0];
-
-       aed_dc_enable(p_effect->dc_en);
-
-       return 0;
-}
-
-static int mixer_aed_enable_ND(struct snd_kcontrol *kcontrol,
-       struct snd_ctl_elem_value *ucontrol)
-{
-       struct audioeffect *p_effect =  snd_kcontrol_chip(kcontrol);
-
-       p_effect->nd_en = ucontrol->value.integer.value[0];
-
-       aed_nd_enable(p_effect->nd_en);
-
-       return 0;
-}
-
-static int mixer_aed_enable_EQ(struct snd_kcontrol *kcontrol,
-       struct snd_ctl_elem_value *ucontrol)
-{
-       struct audioeffect *p_effect =  snd_kcontrol_chip(kcontrol);
-
-       p_effect->eq_en = ucontrol->value.integer.value[0];
-
-       aed_eq_enable(0, p_effect->eq_en);
-
-       return 0;
-}
-
-static int mixer_aed_enable_multiband_DRC(struct snd_kcontrol *kcontrol,
-       struct snd_ctl_elem_value *ucontrol)
-{
-       struct audioeffect *p_effect =  snd_kcontrol_chip(kcontrol);
-       int *p_multiband_coeff = multiband_drc_coeff;
-       int len = ARRAY_SIZE(multiband_drc_coeff);
-
-       if (!p_effect)
-               return -EINVAL;
-
-       p_effect->multiband_drc_en = ucontrol->value.integer.value[0];
-
-       aed_set_multiband_drc_coeff(len, p_multiband_coeff);
-       aed_multiband_drc_enable(p_effect->multiband_drc_en);
-
-       return 0;
-}
-
-static int mixer_aed_enable_fullband_DRC(struct snd_kcontrol *kcontrol,
-       struct snd_ctl_elem_value *ucontrol)
-{
-       struct audioeffect *p_effect =  snd_kcontrol_chip(kcontrol);
-       int *p_fullband_coeff = fullband_drc_coeff;
-       int len = ARRAY_SIZE(fullband_drc_coeff);
-
-       if (!p_effect)
-               return -EINVAL;
-
-       p_effect->fullband_drc_en = ucontrol->value.integer.value[0];
-
-       aed_set_fullband_drc_coeff(len, p_fullband_coeff);
-       aed_fullband_drc_enable(p_effect->fullband_drc_en);
-
-       return 0;
-}
-
 static int mixer_get_EQ_params(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
@@ -294,17 +221,11 @@ static int mixer_set_EQ_params(struct snd_kcontrol *kcontrol,
        char *p_string = &tmp_string[0];
        unsigned int *p = &EQ_COEFF[0];
        int num, i, band_id;
-       void *data;
-       char *val;
+       char *val = (char *)ucontrol->value.bytes.data;
 
-       data = kmemdup(ucontrol->value.bytes.data,
-               FILTER_PARAM_BYTE, GFP_KERNEL | GFP_DMA);
-       if (!data)
+       if (!val)
                return -ENOMEM;
-
-       val = (char *)data;
        memcpy(p_string, val, FILTER_PARAM_BYTE);
-       kfree(data);
 
        num = str2int(p_string, p_data, FILTER_PARAM_BYTE);
        band_id = tmp_data[0];
@@ -334,13 +255,72 @@ static int mixer_set_EQ_params(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
+static int mixer_get_crossover_params(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       unsigned int *value = (unsigned int *)ucontrol->value.bytes.data;
+       unsigned int *p = &CROSSOVER_COEFF[0];
+       int i;
+
+       aed_get_ram_coeff(CROSSOVER_FILTER_RAM_ADD, CROSSOVER_FILTER_SIZE, p);
+
+       for (i = 0; i < CROSSOVER_FILTER_SIZE; i++)
+               *value++ = cpu_to_be32(*p++);
+
+       return 0;
+}
+
+static int mixer_set_crossover_params(struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       unsigned int tmp_data[FILTER_PARAM_SIZE + 1];
+       unsigned int *p_data = &tmp_data[0];
+       char tmp_string[FILTER_PARAM_BYTE];
+       char *p_string = &tmp_string[0];
+       unsigned int *p = &CROSSOVER_COEFF[0];
+       int num, i, band_id;
+       char *val = (char *)ucontrol->value.bytes.data;
+
+       if (!val)
+               return -ENOMEM;
+       memcpy(p_string, val, FILTER_PARAM_BYTE);
+
+       num = str2int(p_string, p_data, FILTER_PARAM_BYTE);
+       band_id = tmp_data[0];
+       if (num != (FILTER_PARAM_SIZE + 1) ||
+                       band_id >= CROSSOVER_FILTER_BAND) {
+               pr_info("Error: parma_num = %d, band_id = %d\n",
+                       num, tmp_data[0]);
+               return 0;
+       }
+
+       p_data = &tmp_data[1];
+       p = &CROSSOVER_COEFF[band_id*FILTER_PARAM_SIZE];
+       for (i = 0; i < FILTER_PARAM_SIZE; i++)
+               *p++ = *p_data++;
+
+       p = &CROSSOVER_COEFF[band_id*FILTER_PARAM_SIZE];
+       aed_set_ram_coeff((CROSSOVER_FILTER_RAM_ADD +
+               band_id*FILTER_PARAM_SIZE),
+               FILTER_PARAM_SIZE, p);
+
+       return 0;
+}
+
 static int mixer_get_multiband_DRC_params(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       int *val = (int *)ucontrol->value.bytes.data;
-       int *p = &multiband_drc_coeff[0];
+       unsigned int *value = (unsigned int *)ucontrol->value.bytes.data;
+       unsigned int *p = &multiband_drc_coeff[0];
+       int i;
 
-       memcpy(val, p, AED_MULTIBAND_DRC_LENGTH);
+       for (i = 0; i < 3; i++) {
+               aed_get_multiband_drc_coeff(i,
+                       p + i * AED_SINGLE_BAND_DRC_SIZE);
+       }
+
+       for (i = 0; i < AED_MULTIBAND_DRC_SIZE; i++)
+               *value++ = cpu_to_be32(*p++);
 
        return 0;
 }
@@ -348,19 +328,35 @@ static int mixer_get_multiband_DRC_params(struct snd_kcontrol *kcontrol,
 static int mixer_set_multiband_DRC_params(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct soc_bytes_ext *params = (void *)kcontrol->private_value;
-       void *data;
-       int *val, *p = &multiband_drc_coeff[0];
+       unsigned int tmp_data[AED_SINGLE_BAND_DRC_SIZE + 1];
+       unsigned int *p_data = &tmp_data[0];
+       char tmp_string[MULTIBAND_DRC_PARAM_BYTE];
+       char *p_string = &tmp_string[0];
+       unsigned int *p = &multiband_drc_coeff[0];
+       int num, i, band_id;
+       char *val = (char *)ucontrol->value.bytes.data;
 
-       data = kmemdup(ucontrol->value.bytes.data,
-               params->max, GFP_KERNEL | GFP_DMA);
-       if (!data)
+       if (!val)
                return -ENOMEM;
+       memcpy(p_string, val, MULTIBAND_DRC_PARAM_BYTE);
 
-       val = (int *)data;
-       memcpy(p, val, params->max / sizeof(int));
+       num = str2int(p_string, p_data, MULTIBAND_DRC_PARAM_BYTE);
+       band_id = tmp_data[0];
+       if (num != (AED_SINGLE_BAND_DRC_SIZE + 1) ||
+                       band_id >= AED_MULTIBAND_DRC_BANDS) {
+               pr_info("Error: parma_num = %d, band_id = %d\n",
+                       num, tmp_data[0]);
+               return 0;
+       }
 
-       kfree(data);
+    /*Don't update offset and gain*/
+       p_data = &tmp_data[1];
+       p = &multiband_drc_coeff[band_id*AED_SINGLE_BAND_DRC_SIZE];
+       for (i = 0; i < (AED_SINGLE_BAND_DRC_SIZE - 2) ; i++)
+               *p++ = *p_data++;
+
+       p = &multiband_drc_coeff[0];
+       aed_set_multiband_drc_coeff(band_id, p);
 
        return 0;
 }
@@ -368,10 +364,14 @@ static int mixer_set_multiband_DRC_params(struct snd_kcontrol *kcontrol,
 static int mixer_get_fullband_DRC_params(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       int *val = (int *)ucontrol->value.bytes.data;
-       int *p = &fullband_drc_coeff[0];
+       unsigned int *value = (unsigned int *)ucontrol->value.bytes.data;
+       unsigned int *p = &fullband_drc_coeff[0];
+       int i;
 
-       memcpy(val, p, AED_FULLBAND_DRC_LENGTH);
+       aed_get_fullband_drc_coeff(AED_FULLBAND_DRC_SIZE, p);
+
+       for (i = 0; i < AED_FULLBAND_DRC_SIZE; i++)
+               *value++ = cpu_to_be32(*p++);
 
        return 0;
 }
@@ -379,19 +379,34 @@ static int mixer_get_fullband_DRC_params(struct snd_kcontrol *kcontrol,
 static int mixer_set_fullband_DRC_params(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
 {
-       struct soc_bytes_ext *params = (void *)kcontrol->private_value;
-       void *data;
-       int *val, *p = &fullband_drc_coeff[0];
+       unsigned int tmp_data[AED_FULLBAND_DRC_OFFSET + 1];
+       unsigned int *p_data = &tmp_data[0];
+       char tmp_string[AED_FULLBAND_DRC_BYTES];
+       char *p_string = &tmp_string[0];
+       unsigned int *p = &fullband_drc_coeff[0];
+       int num, i, band_id;
+       char *val = (char *)ucontrol->value.bytes.data;
 
-       data = kmemdup(ucontrol->value.bytes.data,
-               params->max, GFP_KERNEL | GFP_DMA);
-       if (!data)
+       if (!val)
                return -ENOMEM;
+       memcpy(p_string, val, AED_FULLBAND_DRC_BYTES);
 
-       val = (int *)data;
-       memcpy(p, val, params->max / sizeof(int));
+       num = str2int(p_string, p_data, AED_FULLBAND_DRC_BYTES);
+       band_id = tmp_data[0];
+       if (num != (AED_FULLBAND_DRC_OFFSET + 1) ||
+                       band_id >= AED_FULLBAND_DRC_GROUP_SIZE) {
+               pr_info("Error: parma_num = %d, band_id = %d\n",
+                       num, tmp_data[0]);
+               return 0;
+       }
+
+       p_data = &tmp_data[1];
+       p = &fullband_drc_coeff[band_id*AED_FULLBAND_DRC_OFFSET];
+       for (i = 0; i < AED_FULLBAND_DRC_OFFSET; i++)
+               *p++ = *p_data++;
 
-       kfree(data);
+       p = &fullband_drc_coeff[band_id*AED_FULLBAND_DRC_OFFSET];
+       aed_set_fullband_drc_coeff(band_id, p);
 
        return 0;
 }
@@ -442,6 +457,38 @@ static int aed_module_set_enum(
        return 0;
 }
 
+static void aed_set_filter_data(void)
+{
+       int *p;
+
+       /* set default filter param*/
+       p = &DC_CUT_COEFF[0];
+       aed_set_ram_coeff(DC_CUT_FILTER_RAM_ADD, DC_CUT_FILTER_SIZE, p);
+       p = &EQ_COEFF[0];
+       aed_set_ram_coeff(EQ_FILTER_RAM_ADD, EQ_FILTER_SIZE, p);
+       p = &CROSSOVER_COEFF[0];
+       aed_set_ram_coeff(CROSSOVER_FILTER_RAM_ADD, CROSSOVER_FILTER_SIZE, p);
+
+}
+
+static void aed_set_drc_data(void)
+{
+       unsigned int *p = &multiband_drc_coeff[0];
+       int i;
+
+       /*set MDRC default value*/
+       for (i = 0; i < AED_MULTIBAND_DRC_BANDS; i++)
+               aed_set_multiband_drc_coeff(i, p);
+
+
+       /*set FDRC default value*/
+       p = &fullband_drc_coeff[0];
+       for (i = 0; i < AED_FULLBAND_DRC_GROUP_SIZE; i++) {
+               aed_set_fullband_drc_coeff(i,
+                       p + i * AED_FULLBAND_DRC_OFFSET);
+       }
+}
+
 static const DECLARE_TLV_DB_SCALE(master_vol_tlv, -12276, 12, 1);
 static const DECLARE_TLV_DB_SCALE(lr_vol_tlv, -12750, 50, 1);
 
@@ -449,36 +496,41 @@ static const struct snd_kcontrol_new snd_effect_controls[] = {
 
        SOC_SINGLE_EXT("AED DC cut enable",
                AED_DC_EN, 0, 0x1, 0,
-               mixer_aed_read, mixer_aed_enable_DC),
+               mixer_aed_read, mixer_aed_write),
 
        SOC_SINGLE_EXT("AED Noise Detect enable",
                AED_ND_CNTL, 0, 0x1, 0,
-               mixer_aed_read, mixer_aed_enable_ND),
+               mixer_aed_read, mixer_aed_write),
 
        SOC_SINGLE_EXT("AED EQ enable",
                AED_EQ_EN, 0, 0x1, 0,
-               mixer_aed_read, mixer_aed_enable_EQ),
-
-       SOC_SINGLE_EXT("AED Multi-band DRC enable",
-               AED_MDRC_CNTL, 8, 0x1, 0,
-               mixer_aed_read, mixer_aed_enable_multiband_DRC),
-
-       SOC_SINGLE_EXT("AED Full-band DRC enable",
-               AED_DRC_CNTL, 0, 0x1, 0,
-               mixer_aed_read, mixer_aed_enable_fullband_DRC),
+               mixer_aed_read, mixer_aed_write),
 
        SND_SOC_BYTES_EXT("AED EQ Parameters",
                (EQ_FILTER_SIZE_CH * 4),
                mixer_get_EQ_params,
                mixer_set_EQ_params),
 
+       SOC_SINGLE_EXT("AED Multi-band DRC enable",
+               AED_MDRC_CNTL, 8, 0x1, 0,
+               mixer_aed_read, mixer_aed_write),
+
+       SND_SOC_BYTES_EXT("AED Crossover Filter Parameters",
+               (CROSSOVER_FILTER_SIZE * 4),
+               mixer_get_crossover_params,
+               mixer_set_crossover_params),
+
        SND_SOC_BYTES_EXT("AED Multi-band DRC Parameters",
-               AED_MULTIBAND_DRC_LENGTH,
+               (AED_MULTIBAND_DRC_SIZE * 4),
                mixer_get_multiband_DRC_params,
                mixer_set_multiband_DRC_params),
 
+       SOC_SINGLE_EXT("AED Full-band DRC enable",
+               AED_DRC_CNTL, 0, 0x1, 0,
+               mixer_aed_read, mixer_aed_write),
+
        SND_SOC_BYTES_EXT("AED Full-band DRC Parameters",
-               AED_FULLBAND_DRC_LENGTH,
+               AED_FULLBAND_DRC_BYTES,
                mixer_get_fullband_DRC_params,
                mixer_set_fullband_DRC_params),
 
@@ -524,15 +576,6 @@ int card_add_effect_v2_kcontrols(struct snd_soc_card *card)
        return 0;
 }
 
-#if 0
-static const struct snd_soc_component_driver effect_component_drv = {
-       .name               = DRV_NAME,
-
-       .controls                   = snd_effect_controls,
-       .num_controls           = ARRAY_SIZE(snd_effect_controls),
-};
-#endif
-
 static struct effect_chipinfo tl1_effect_chipinfo = {
        .v2 = true,
 };
@@ -553,20 +596,6 @@ static const struct of_device_id effect_device_id[] = {
 };
 MODULE_DEVICE_TABLE(of, effect_device_id);
 
-static void aed_set_filter_data(void)
-{
-       int *p;
-
-       /* set default filter param*/
-       p = &DC_CUT_COEFF[0];
-       aed_set_ram_coeff(DC_CUT_FILTER_RAM_ADD, DC_CUT_FILTER_SIZE, p);
-       p = &EQ_COEFF[0];
-       aed_set_ram_coeff(EQ_FILTER_RAM_ADD, EQ_FILTER_SIZE, p);
-       p = &CROSSOVER_COEFF[0];
-       aed_set_ram_coeff(CROSSOVER_FILTER_RAM_ADD, CROSSOVER_FILTER_SIZE, p);
-
-}
-
 static int effect_platform_probe(struct platform_device *pdev)
 {
        struct audioeffect *p_effect;
@@ -682,6 +711,12 @@ static int effect_platform_probe(struct platform_device *pdev)
        aed_eq_taps(EQ_BAND);
        /*set default filter param*/
        aed_set_filter_data();
+       /*set multi-band drc param*/
+       aed_set_multiband_drc_param();
+       /*set multi/full-band drc data*/
+       aed_set_drc_data();
+       /*set full-band drc param, enable 2 band*/
+       aed_set_fullband_drc_param(2);
        /*set EQ/DRC module enable*/
        aml_set_aed(1, p_effect->effect_module);