Skip to content

Commit

Permalink
Drivers: DAI: Intel: DMIC: Program start symmetrically for PDMx
Browse files Browse the repository at this point in the history
This change is assumed to fix the random corruption of 4ch
capture for PDM1 channels 3-4 in PTL platform. There are no
solid facts behind this change but assumption that PDMx
controllers are not in sync if the start sequence for PDM1
is further away from PDM0. The PDM0 internal state may be
different from PDM1

The single for loop to handle the CIC and FIR start sequence
is split into two for loops to handle same registers update
tasks symmetrically for all stereo PDM controllers. E.g. two
PDMs for four microphones.

First loop programs the CIC_CONTROL and MIC_CONTROL registers
of the PDMx controllers. These features belong to the CIC block
in DMIC IP. Second loop programs the FIR_CONTROL registers of
the PDMx controllers.

In a stress test of 100 times repeated commands:

arecord -Dhw:0,6 -fS32_LE -r48000 -c4 -d 10 dmic_test_1.wav; \
sleep 0.5; \
arecord -Dhw:0,6 -fS32_LE -r48000 -c4 -d 10 dmic_test_2.wav; \
sleep 1

The corruption occurrence with xt-clang build was e.g. 87/200
fails in one of wav files giving 43.5% occurrence. The test was
done with Zephyr commit fe29c40
("llext: add inspection API test suite").

In a gcc build the occurrence of corruption is lower, around 6%
but it is seen that the channels 3-4 pdm1 are swapping randomly.

With this fix the corruption occurred zero times in xt-clang
and gcc builds with same 100 repeats.

Signed-off-by: Seppo Ingalsuo <[email protected]>
  • Loading branch information
singalsu committed Feb 27, 2025
1 parent 3fa0cd5 commit 326def7
Showing 1 changed file with 3 additions and 1 deletion.
4 changes: 3 additions & 1 deletion drivers/dai/intel/dmic/dmic.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,6 @@ static void dai_dmic_start(struct dai_intel_dmic *dmic)
for (i = 0; i < CONFIG_DAI_DMIC_HW_CONTROLLERS; i++) {
mic_a = dmic->enable[i] & 1;
mic_b = (dmic->enable[i] & 2) >> 1;
start_fir = dmic->enable[i] > 0;

/* If both microphones are needed start them simultaneously
* to start them in sync. The reset may be cleared for another
Expand Down Expand Up @@ -618,7 +617,10 @@ static void dai_dmic_start(struct dai_intel_dmic *dmic)
MIC_CONTROL_PDM_EN_B,
FIELD_PREP(MIC_CONTROL_PDM_EN_B, 1));
}
}

for (i = 0; i < CONFIG_DAI_DMIC_HW_CONTROLLERS; i++) {
start_fir = dmic->enable[i] > 0;
dai_dmic_update_bits(dmic, dmic_base[i] + FIR_CHANNEL_REGS_SIZE *
dmic->dai_config_params.dai_index + FIR_CONTROL,
FIR_CONTROL_START,
Expand Down

0 comments on commit 326def7

Please sign in to comment.