audio: add soc DRC tune interface [1/3]

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>
This commit is contained in:
Zhe Wang
2019-03-14 22:16:36 +08:00
committed by Dongjin Kim
parent a246df3d2e
commit 35d1d8035a
4 changed files with 349 additions and 262 deletions

View 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]);
for (i = 0; i < offset; i++) {
*(params + band * offset + i) =
eqdrc_read(reg + band * offset + 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));
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(

View File

@@ -21,22 +21,24 @@
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

View File

@@ -15,20 +15,25 @@
*
*/
#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

View 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;
}
kfree(data);
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++;
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);