dai: intel: dmic: Separate fir configuration code into function

All fir filters have an identical set of registers so their definitions
were combined to simplify the code. From the dai_dmic_set_config_nhlt
function, a duplicate piece of code responsible for configuring fir was
separated into a new function.

Signed-off-by: Adrian Warecki <adrian.warecki@intel.com>
This commit is contained in:
Adrian Warecki 2023-06-19 15:01:33 +02:00 committed by Anas Nashif
commit 2452aaad50
4 changed files with 70 additions and 160 deletions

View file

@ -522,29 +522,16 @@ static void dai_dmic_gain_ramp(struct dai_intel_dmic *dmic)
CIC_CONTROL_MIC_MUTE, 0);
if (dmic->startcount == DMIC_UNMUTE_FIR) {
switch (dmic->dai_config_params.dai_index) {
case 0:
dai_dmic_update_bits(dmic, dmic_base[i] + FIR_CONTROL_A,
FIR_CONTROL_MUTE, 0);
break;
case 1:
dai_dmic_update_bits(dmic, dmic_base[i] + FIR_CONTROL_B,
FIR_CONTROL_MUTE, 0);
break;
}
}
switch (dmic->dai_config_params.dai_index) {
case 0:
val = FIELD_PREP(OUT_GAIN, gval);
dai_dmic_write(dmic, dmic_base[i] + OUT_GAIN_LEFT_A, val);
dai_dmic_write(dmic, dmic_base[i] + OUT_GAIN_RIGHT_A, val);
break;
case 1:
val = FIELD_PREP(OUT_GAIN, gval);
dai_dmic_write(dmic, dmic_base[i] + OUT_GAIN_LEFT_B, val);
dai_dmic_write(dmic, dmic_base[i] + OUT_GAIN_RIGHT_B, val);
break;
dai_dmic_update_bits(dmic, dmic_base[i] + FIR_CHANNEL_REGS_SIZE *
dmic->dai_config_params.dai_index + FIR_CONTROL,
FIR_CONTROL_MUTE, 0);
}
val = FIELD_PREP(OUT_GAIN, gval);
dai_dmic_write(dmic, dmic_base[i] + FIR_CHANNEL_REGS_SIZE *
dmic->dai_config_params.dai_index + OUT_GAIN_LEFT, val);
dai_dmic_write(dmic, dmic_base[i] + FIR_CHANNEL_REGS_SIZE *
dmic->dai_config_params.dai_index + OUT_GAIN_RIGHT, val);
}
k_spin_unlock(&dmic->lock, key);
@ -556,8 +543,7 @@ static void dai_dmic_start(struct dai_intel_dmic *dmic)
int i;
int mic_a;
int mic_b;
int fir_a;
int fir_b;
int start_fir;
/* enable port */
key = k_spin_lock(&dmic->lock);
@ -585,8 +571,7 @@ static void dai_dmic_start(struct dai_intel_dmic *dmic)
mic_a = dmic->enable[i] & 1;
mic_b = (dmic->enable[i] & 2) >> 1;
fir_a = (dmic->enable[i] > 0) ? 1 : 0;
fir_b = (dmic->enable[i] > 0) ? 1 : 0;
start_fir = dmic->enable[i] > 0;
LOG_INF("dmic_start(), pdm%d mic_a = %u, mic_b = %u", i, mic_a, mic_b);
/* If both microphones are needed start them simultaneously
@ -621,18 +606,10 @@ static void dai_dmic_start(struct dai_intel_dmic *dmic)
FIELD_PREP(MIC_CONTROL_PDM_EN_B, 1));
}
switch (dmic->dai_config_params.dai_index) {
case 0:
dai_dmic_update_bits(dmic, dmic_base[i] + FIR_CONTROL_A,
FIR_CONTROL_START,
FIELD_PREP(FIR_CONTROL_START, fir_a));
break;
case 1:
dai_dmic_update_bits(dmic, dmic_base[i] + FIR_CONTROL_B,
FIR_CONTROL_START,
FIELD_PREP(FIR_CONTROL_START, fir_b));
break;
}
dai_dmic_update_bits(dmic, dmic_base[i] + FIR_CHANNEL_REGS_SIZE *
dmic->dai_config_params.dai_index + FIR_CONTROL,
FIR_CONTROL_START,
FIELD_PREP(FIR_CONTROL_START, start_fir));
}
#ifndef CONFIG_SOC_SERIES_INTEL_ACE
@ -694,18 +671,10 @@ static void dai_dmic_stop(struct dai_intel_dmic *dmic, bool stop_is_pause)
CIC_CONTROL_SOFT_RESET |
CIC_CONTROL_MIC_MUTE);
}
switch (dmic->dai_config_params.dai_index) {
case 0:
dai_dmic_update_bits(dmic, dmic_base[i] + FIR_CONTROL_A,
FIR_CONTROL_MUTE,
FIR_CONTROL_MUTE);
break;
case 1:
dai_dmic_update_bits(dmic, dmic_base[i] + FIR_CONTROL_B,
FIR_CONTROL_MUTE,
FIR_CONTROL_MUTE);
break;
}
dai_dmic_update_bits(dmic, dmic_base[i] + FIR_CHANNEL_REGS_SIZE *
dmic->dai_config_params.dai_index + FIR_CONTROL,
FIR_CONTROL_MUTE,
FIR_CONTROL_MUTE);
}
k_spin_unlock(&dmic->lock, key);

View file

@ -51,7 +51,7 @@ static int dai_nhlt_get_clock_div(const struct dai_intel_dmic *dmic, const int p
p_clkdiv = FIELD_GET(MIC_CONTROL_PDM_CLKDIV, val) + 2;
val = dai_dmic_read(dmic, base[pdm] +
(dmic->dai_config_params.dai_index ? FIR_CONFIG_B : FIR_CONFIG_A));
FIR_CHANNEL_REGS_SIZE * dmic->dai_config_params.dai_index + FIR_CONFIG);
LOG_ERR("pdm = %d, FIR_CONFIG = 0x%08X", pdm, val);
p_mfir = FIELD_GET(FIR_CONFIG_FIR_DECIMATION, val) + 1;
@ -503,6 +503,32 @@ static void print_fir_config(const struct nhlt_pdm_ctrl_fir_cfg *fir_cfg)
LOG_DBG("OUT_GAIN_RIGHT = %08x", fir_cfg->out_gain_right);
}
static void configure_fir(struct dai_intel_dmic *dmic, const uint32_t base,
const struct nhlt_pdm_ctrl_fir_cfg *fir_cfg)
{
uint32_t val;
print_fir_config(fir_cfg);
/* Use FIR_CONFIG as such */
val = fir_cfg->fir_config;
dai_dmic_write(dmic, base + FIR_CONFIG, val);
val = fir_cfg->fir_control;
print_fir_control(val);
/* Clear START, set MUTE */
val = (val & ~FIR_CONTROL_START) | FIR_CONTROL_MUTE;
dai_dmic_write(dmic, base + FIR_CONTROL, val);
LOG_DBG("FIR_CONTROL = %08x", val);
/* Use DC_OFFSET and GAIN as such */
dai_dmic_write(dmic, base + DC_OFFSET_LEFT, fir_cfg->dc_offset_left);
dai_dmic_write(dmic, base + DC_OFFSET_RIGHT, fir_cfg->dc_offset_right);
dai_dmic_write(dmic, base + OUT_GAIN_LEFT, fir_cfg->out_gain_left);
dai_dmic_write(dmic, base + OUT_GAIN_RIGHT, fir_cfg->out_gain_right);
}
int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *bespoke_cfg)
{
struct nhlt_pdm_ctrl_cfg *pdm_cfg[DMIC_HW_CONTROLLERS_MAX];
@ -514,7 +540,6 @@ int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *bespoke_cf
uint32_t out_control[DMIC_HW_FIFOS_MAX] = {0};
uint32_t channel_ctrl_mask;
uint32_t fir_control;
uint32_t pdm_ctrl_mask;
uint32_t val;
const uint8_t *p = bespoke_cfg;
@ -650,6 +675,10 @@ int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *bespoke_cf
LOG_DBG("dmic_set_config_nhlt(): MIC_CONTROL = %08x", val);
}
configure_fir(dmic, base[n] +
FIR_CHANNEL_REGS_SIZE * dmic->dai_config_params.dai_index,
&pdm_cfg[n]->fir_config[dmic->dai_config_params.dai_index]);
/* FIR A */
fir_cfg_a[n] = &pdm_cfg[n]->fir_config[0];
val = fir_cfg_a[n]->fir_config;
@ -657,32 +686,6 @@ int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *bespoke_cf
fir_length_a = fir_length + 1; /* Need for parsing */
fir_decimation = FIELD_GET(FIR_CONFIG_FIR_DECIMATION, val);
p_mfira = fir_decimation + 1;
if (dmic->dai_config_params.dai_index == 0) {
print_fir_config(fir_cfg_a[n]);
/* Use FIR_CONFIG_A as such */
dai_dmic_write(dmic, base[n] + FIR_CONFIG_A, val);
val = fir_cfg_a[n]->fir_control;
/* Clear START, set MUTE */
fir_control = (val & ~FIR_CONTROL_START) | FIR_CONTROL_MUTE;
dai_dmic_write(dmic, base[n] + FIR_CONTROL_A, fir_control);
LOG_DBG("dmic_set_config_nhlt(): FIR_CONTROL_A = %08x", fir_control);
/* Use DC_OFFSET and GAIN as such */
val = fir_cfg_a[n]->dc_offset_left;
dai_dmic_write(dmic, base[n] + DC_OFFSET_LEFT_A, val);
val = fir_cfg_a[n]->dc_offset_right;
dai_dmic_write(dmic, base[n] + DC_OFFSET_RIGHT_A, val);
val = fir_cfg_a[n]->out_gain_left;
dai_dmic_write(dmic, base[n] + OUT_GAIN_LEFT_A, val);
val = fir_cfg_a[n]->out_gain_right;
dai_dmic_write(dmic, base[n] + OUT_GAIN_RIGHT_A, val);
}
/* FIR B */
fir_cfg_b[n] = &pdm_cfg[n]->fir_config[1];
@ -691,32 +694,6 @@ int dai_dmic_set_config_nhlt(struct dai_intel_dmic *dmic, const void *bespoke_cf
fir_length_b = fir_length + 1; /* Need for parsing */
fir_decimation = FIELD_GET(FIR_CONFIG_FIR_DECIMATION, val);
p_mfirb = fir_decimation + 1;
if (dmic->dai_config_params.dai_index == 1) {
print_fir_config(fir_cfg_b[n]);
/* Use FIR_CONFIG_B as such */
dai_dmic_write(dmic, base[n] + FIR_CONFIG_B, val);
val = fir_cfg_b[n]->fir_control;
/* Clear START, set MUTE */
fir_control = (val & ~FIR_CONTROL_START) | FIR_CONTROL_MUTE;
dai_dmic_write(dmic, base[n] + FIR_CONTROL_B, fir_control);
LOG_DBG("dmic_set_config_nhlt(): FIR_CONTROL_B = %08x", fir_control);
/* Use DC_OFFSET and GAIN as such */
val = fir_cfg_b[n]->dc_offset_left;
dai_dmic_write(dmic, base[n] + DC_OFFSET_LEFT_B, val);
val = fir_cfg_b[n]->dc_offset_right;
dai_dmic_write(dmic, base[n] + DC_OFFSET_RIGHT_B, val);
val = fir_cfg_b[n]->out_gain_left;
dai_dmic_write(dmic, base[n] + OUT_GAIN_LEFT_B, val);
val = fir_cfg_b[n]->out_gain_right;
dai_dmic_write(dmic, base[n] + OUT_GAIN_RIGHT_B, val);
}
/* Set up FIR coefficients RAM */
val = pdm_cfg[n]->reuse_fir_from_pdm;