Hi,
A (commercial) DAC board, I use with a Raspberry Pi is plagued by clicks
and pops and I'm trying to fix it at the driver level. I have mostly
fixed it, but I could use some guidance on the problem described below.
I apologize in advance for the long read, but the situation is a bit
convoluted (or my understanding of it is).
The board (a HifiBerry DAC+ Pro) uses a PCM5122 chip which is driven by
the pcm512x codec driver, but the Pro version also includes a set of
external clocks on the board (one each for 48Khz and 44.1Khz sample
rates and multiples thereof).
There are two kinds of clicks and pops: on the one hand the board clicks
when the device is opened/closed, mostly because the pcm512x codec
driver doesn't support the digital_mute operation. These are relatively
mild clicks, which are an annoyance at most and I have a separate patch
for the pcm512x, that addresses them, which I'm currently testing and
will (hopefully) submit soon.
A separate case is a pop that's generated when the clock source is
changed. This pop is independent of the digital volume setting and very
loud. As far as I could determine, when the hw_params callback
specified in the snd_soc_dai_link struct is called, it figures out what
clock is needed for the giver sample rate and powers the appropriate
clock through a GPIO on the PCM5122. This essentially means that the
external clock source fed into the 5122 is stopped and restarted at a
different rate, potentially while the DAC chip is operating. Later the
hw_params callback defined in the pcm512x driver is called and it
reconfigure the clock dividers for the new rate. It is at this point
that the pop seems to be generated, provided that the card is not
powered down or muted. If I comment out either the clock power-up/down
in the dai_link hw_params, or the clock divider reconfiguration in the
codec's hw_params, no pop is generated.
Now, the digital_mute patch described before, also happens to fix this
loud pop. I'm not sure whether that's a happy coincidence that might
cease to be the case in the future though and was considering fixing the
pop problem separately, at its source: the clock change. One way to fix
the problem is to switch the 5122 into standby before changing the clock
source in the dai_link hw_params callback and switch it back into normal
operation afterwards. This seems to work regardless of whether
digital_mute is implemented or not, but has the following problem: The
register that's used to put the chip into/out of standby, is also used
by the pcm512x driver, in the set_bias_level operation. Since the
hw_params operation is, as far as I can tell, not atomic, I'm concerned
that race conditions may arise, causing the card to be left powered up,
when it should be off and vice-versa.
Is there some way to synchronize the use of common chip registers in the
DAI and codec drivers? Is the digital_mute somehow guaranteed to fix
the pop originating at the DAI/machine driver level (whatever the
hw_params operation in the dai_link struct is supposed to be)? Am I
perhaps missing something entirely?
Any help or guidance is welcome.
Thanks,
Dimitris
_______________________________________________
Alsa-devel mailing list
Alsa-devel@xxxxxxxxxxxxxxxx
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel