Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

intel_adsp: dmic: Refactoring of blob parsing function #60172

Merged
merged 10 commits into from
Sep 4, 2023
Merged
138 changes: 46 additions & 92 deletions drivers/dai/intel/dmic/dmic.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,12 @@ static inline void dai_dmic_set_sync_period(uint32_t period, const struct dai_in
base + DMICSYNC_OFFSET);
sys_write32(sys_read32(base + DMICSYNC_OFFSET) | DMICSYNC_SYNCPU,
base + DMICSYNC_OFFSET);
while (sys_read32(base + DMICSYNC_OFFSET) & DMICSYNC_SYNCPU) {
k_sleep(K_USEC(100));

if (!WAIT_FOR((sys_read32(base + DMICSYNC_OFFSET) & DMICSYNC_SYNCPU) == 0, 1000,
k_sleep(K_USEC(100)))) {
LOG_ERR("poll timeout");
}

sys_write32(sys_read32(base + DMICSYNC_OFFSET) | DMICSYNC_CMDSYNC,
base + DMICSYNC_OFFSET);
#else /* All other CAVS and ACE platforms */
Expand Down Expand Up @@ -218,9 +221,11 @@ static void dmic_sync_trigger(const struct dai_intel_dmic *dmic)

sys_write32(sys_read32(base + DMICSYNC_OFFSET) |
DMICSYNC_SYNCGO, base + DMICSYNC_OFFSET);

/* waiting for CMDSYNC bit clearing */
while (sys_read32(base + DMICSYNC_OFFSET) & DMICSYNC_CMDSYNC) {
k_sleep(K_USEC(100));
if (!WAIT_FOR((sys_read32(base + DMICSYNC_OFFSET) & DMICSYNC_CMDSYNC) == 0,
1000, k_sleep(K_USEC(100)))) {
LOG_ERR("poll timeout");
}
}

Expand All @@ -233,22 +238,22 @@ static void dmic_sync_trigger(const struct dai_intel_dmic *dmic) {}

#endif /* CONFIG_DAI_DMIC_HAS_MULTIPLE_LINE_SYNC */

static void dai_dmic_start_fifo_packers(struct dai_intel_dmic *dmic, int fifo_index)
{

/* Start FIFO packers and clear FIFO initialize bits */
dai_dmic_update_bits(dmic, fifo_index * PDM_CHANNEL_REGS_SIZE + OUTCONTROL,
OUTCONTROL_SIP | OUTCONTROL_FINIT,
OUTCONTROL_SIP);
}

static void dai_dmic_stop_fifo_packers(struct dai_intel_dmic *dmic,
int fifo_index)
{
/* Stop FIFO packers and set FIFO initialize bits */
switch (fifo_index) {
case 0:
dai_dmic_update_bits(dmic, OUTCONTROL0,
OUTCONTROL_SIP | OUTCONTROL_FINIT,
OUTCONTROL_FINIT);
break;
case 1:
dai_dmic_update_bits(dmic, OUTCONTROL1,
OUTCONTROL_SIP | OUTCONTROL_FINIT,
OUTCONTROL_FINIT);
break;
}
dai_dmic_update_bits(dmic, fifo_index * PDM_CHANNEL_REGS_SIZE + OUTCONTROL,
OUTCONTROL_SIP | OUTCONTROL_FINIT,
OUTCONTROL_FINIT);
}

/* On DMIC IRQ event trace the status register that contains the status and
Expand All @@ -261,19 +266,19 @@ static void dai_dmic_irq_handler(const void *data)
uint32_t val1;

/* Trace OUTSTAT0 register */
val0 = dai_dmic_read(dmic, OUTSTAT0);
val1 = dai_dmic_read(dmic, OUTSTAT1);
val0 = dai_dmic_read(dmic, OUTSTAT);
val1 = dai_dmic_read(dmic, OUTSTAT + PDM_CHANNEL_REGS_SIZE);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is a code improvement. Are you sure?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Introduction of the PDM_CHANNEL_REGS_SIZE allows to remove a few switches, so I think this is an improvement.

LOG_DBG("dmic_irq_handler(), OUTSTAT0 = 0x%x, OUTSTAT1 = 0x%x", val0, val1);

if (val0 & OUTSTAT_ROR) {
LOG_ERR("dmic_irq_handler(): full fifo A or PDM overrun");
dai_dmic_write(dmic, OUTSTAT0, val0);
dai_dmic_write(dmic, OUTSTAT, val0);
dai_dmic_stop_fifo_packers(dmic, 0);
}

if (val1 & OUTSTAT_ROR) {
LOG_ERR("dmic_irq_handler(): full fifo B or PDM overrun");
dai_dmic_write(dmic, OUTSTAT1, val1);
dai_dmic_write(dmic, OUTSTAT + PDM_CHANNEL_REGS_SIZE, val1);
dai_dmic_stop_fifo_packers(dmic, 1);
}
}
Expand Down Expand Up @@ -517,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);
Expand All @@ -551,12 +543,11 @@ 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);
LOG_DBG("dmic_start()");
LOG_DBG("dmic_start(), dai_index = %d", dmic->dai_config_params.dai_index);
dmic->startcount = 0;

/* Compute unmute ramp gain update coefficient. */
Expand All @@ -567,27 +558,7 @@ static void dai_dmic_start(struct dai_intel_dmic *dmic)

dai_dmic_sync_prepare(dmic);

switch (dmic->dai_config_params.dai_index) {
case 0:
LOG_INF("dmic_start(), dmic->fifo_a");
/* Clear FIFO A initialize, Enable interrupts to DSP,
* Start FIFO A packer.
*/
dai_dmic_update_bits(
dmic,
OUTCONTROL0,
OUTCONTROL_FINIT | OUTCONTROL_SIP,
OUTCONTROL_SIP);
break;
case 1:
LOG_INF("dmic_start(), dmic->fifo_b");
/* Clear FIFO B initialize, Enable interrupts to DSP,
* Start FIFO B packer.
*/
dai_dmic_update_bits(dmic, OUTCONTROL1,
OUTCONTROL_FINIT | OUTCONTROL_SIP,
OUTCONTROL_SIP);
}
dai_dmic_start_fifo_packers(dmic, dmic->dai_config_params.dai_index);

for (i = 0; i < CONFIG_DAI_DMIC_HW_CONTROLLERS; i++) {
#ifdef CONFIG_SOC_SERIES_INTEL_ACE
Expand All @@ -600,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
Expand Down Expand Up @@ -636,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
Expand Down Expand Up @@ -709,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);
Expand Down
50 changes: 0 additions & 50 deletions drivers/dai/intel/dmic/dmic.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,56 +133,6 @@
#define DMA_HANDSHAKE_DMIC_CH0 0
#define DMA_HANDSHAKE_DMIC_CH1 1

/* For NHLT DMIC configuration parsing */
#define DMIC_HW_CONTROLLERS_MAX 4
#define DMIC_HW_FIFOS_MAX 2

struct nhlt_dmic_gateway_attributes {
uint32_t dw;
};

struct nhlt_dmic_ts_group {
uint32_t ts_group[4];
};

struct nhlt_dmic_clock_on_delay {
uint32_t clock_on_delay;
};

struct nhlt_dmic_channel_ctrl_mask {
uint8_t channel_ctrl_mask;
uint8_t clock_source;
uint16_t rsvd;
};

struct nhlt_pdm_ctrl_mask {
uint32_t pdm_ctrl_mask;
};

struct nhlt_pdm_ctrl_cfg {
uint32_t cic_control;
uint32_t cic_config;
uint32_t reserved0;
uint32_t mic_control;
uint32_t pdm_sdw_map;
uint32_t reuse_fir_from_pdm;
uint32_t reserved1[2];
};

struct nhlt_pdm_ctrl_fir_cfg {
uint32_t fir_control;
uint32_t fir_config;
int32_t dc_offset_left;
int32_t dc_offset_right;
int32_t out_gain_left;
int32_t out_gain_right;
uint32_t reserved[2];
};

struct nhlt_pdm_fir_coeffs {
int32_t fir_coeffs[0];
};

enum dai_dmic_frame_format {
DAI_DMIC_FRAME_S16_LE = 0,
DAI_DMIC_FRAME_S24_4LE,
Expand Down
Loading