An update: it works-hacked. https://github.com/giuliomoro/linux/tree/5.10-ctag-hacks
Notes first:
Workflow
Quick reload of modules: you need to unload and reload them in this order:
sudo modprobe -r snd_soc_davinci_ctag_face_2_4
sudo modprobe -r snd_soc_ad193x_spi
sudo modprobe -r snd_soc_ad193x
sudo modprobe -r snd_soc_davinci_mcasp
sudo modprobe snd_soc_davinci_mcasp
sudo modprobe snd_soc_ad193x
sudo modprobe snd_soc_ad193x_spi
sudo modprobe snd_soc_davinci_ctag_face_2_4
My current fast iteration script is as follows:
on the build machine quick-build.sh
in kernel/
is:
#!/bin/bash
. ../../scripts/config.sh && make ARCH=arm -j$(nproc) CROSS_COMPILE="${CACHED_CC}" modules
set -x
rm -rf sound/soc/{ctag,codecs,ti}/snd-*.xz
xz -k sound/soc/ti/snd-soc-davinci-mcasp.ko
xz -k sound/soc/ctag/snd-soc-davinci-ctag-face-2-4.ko
xz -k sound/soc/codecs/snd-soc-ad193x.ko
on the target I have
#!/bin/bash
set -ex
REMOTE=bui
REMOTE_PREFIX=/lfs/tmp/kernel/sound/soc/
LOCAL_PREFIX=/lib/modules/5.10.145+/kernel/sound/soc/
MOD_EXT=.ko.xz
MODULES_PATHS="ti/snd-soc-davinci-mcasp codecs/snd-soc-ad193x ctag/snd-soc-davinci-ctag-face-2-4"
#MODULES_PATHS="codecs/snd-soc-ad193x ctag/snd-soc-davinci-ctag-face-2-4"
MODULES=
for a in $MODULES_PATHS; do
MODULES="$MODULES $(basename $a)"
done
MODULES="$MODULES snd_soc_ad193x_spi"
RSYNC_LIST=
for a in $MODULES_PATHS; do
RSYNC_LIST="$RSYNC_LIST $REMOTE:$REMOTE_PREFIX/$a$MOD_EXT"
done
rsync -av $RSYNC_LIST ./
sudo modprobe -r snd_soc_davinci_ctag_face_2_4
sudo modprobe -r snd_soc_ad193x_spi
sudo modprobe -r snd_soc_ad193x
sudo modprobe -r snd_soc_davinci_mcasp
for a in $MODULES_PATHS; do
sudo cp $(basename $a)$MOD_EXT $LOCAL_PREFIX/$a$MOD_EXT
done
for a in $MODULES; do
sudo modprobe $a
done
Then from the target I can run:
ssh bui "cd /lfs/tmp/kernel/ && ./quick-build.sh" && ./deploy.sh && sleep 0.5 && aplay -D plughw:CARD=C8CH,DEV=0 ~/out.wav
(the above is mostly for my future self).
Driver and codec issues
Most of the entries in the dtb are ignored. As far as I can tell from grep
ing through sound/
, mcasp-controller-bit-delay-tx
and mcasp-controller-bit-delay-rx
from the device tree are not handled anywhere.
The AD1938 seems to mostly ignore the values in SDATA delay
(DAC Control Register0
bits 5:3, AD193X_DAC_CTRL0
) when in TDM mode. I don't see this explicitly stated in the datasheet anywhere. However it seems to be affected - at least to a certain extent - by SDATA delay
(ADC Control Register 1
bits 4:2, AD193X_ADC_CTRL1
), which makes little sense to me.
I found out experimentally that, when the DAC is set to TDM mode (and it ignores the DAC SDATA delay in AD193X_DAC_CTRL0 and with the ADC SDATA delay in AD193X_ADC_CTRL1 set to the default value of 1), it expects a data format that corresponds to what the McASP would call "data_delay = 2" ( i.e.: the word starts not at the same time as the frame clock ("data_delay = 0"), not on the first bitclock after the frame clock ("data_delay = 1"), but on the second bitclock after the frame clock ("data_delay = 2"). The data_delay
property in the McASP's XFMT register (DAVINCI_MCASP_TXFMT_REG
), however, can only be set to 0 or 1 in davinci_mcasp_set_dai_fmt()
, and it currently can only be set to 2 via a hack, or perhaps calling mcasp_set_bits()
from the driver after davinci_mcasp_set_dai_fmt()
has been called. I didn't investigate that part.
https://github.com/giuliomoro/linux/commit/dc06cf9e383d265ebb3c055ddd2ac87a8fe7e60f shows this solution (via hack), which would also break any other driver using McASP.
An alternative, which leverages the fact that somehow the DAC format is affected by the ADC format register is in https://github.com/giuliomoro/linux/commit/0bf82f6cf053d8d6bfa600e04f60d12db17dc92e. This doesn't break any core mcasp stuff, but it leverages a poorly understood undefined or undocumented behaviour. Good enough for a PoC.
Known issues
Probably a better approach is needed, but this codec behaves so weirdly that I am not sure it's worth the pain.
I noticed that with either version of the driver above, if you stop/restart the aplay enough times, you may get that the output's amplitude becomes smaller, almost half, as if it was shifted by one bit to the right, but I don't see any bit shifting on the McASP side. If you unload and reload the snd_soc_davinci_ctag_face_2_4
module at that point, the amplitude increases slightly. If you also unload and reload (in order) snd_soc_ad193x_spi
, then it goes back to normal. It may well be some issue with how the codec is handled there .. for instance: is it being reset appropriately? I didn't look at it.
You can easily reproduce the issue letting this running:
while sleep 0.1; do aplay -D plughw:CARD=C8CH,DEV=0 ~/out.wav & sleep 0.5; killall -2 aplay; done
A workaround is to always run
sudo modprobe -r snd_soc_davinci_ctag_face_2_4
sudo modprobe -r snd_soc_ad193x_spi
sudo modprobe snd_soc_ad193x_spi
sudo modprobe snd_soc_davinci_ctag_face_2_4
after opening/closing the soundcard (via aplay
or otherwise).