Делаю систему на SoC Allwinner H3 и сотовом модуле SIM7600E. Связь модуля с SoC для обслуживания голосовых вызовов по PCM интерфейсу. Принимать голос с модуля получается, а передавать в модуль - нет. Запись wav, полученная только что через arecord, передаётся обратно в модуль через aplay примерно в 8 раз быстрее и звучит похоже на покорёженный звук, не как белый шум. Уже всё прогуглил вдоль и поперёк, не могу сообразить, что надо допилить для правильного воспроизведения…
ОС Armbian 5.4.33-sunxi. Драйвер для DAI переделал из стандартного драйвера для ADC/DAC AK4554 до требований модуля: один канал, 8/16 кГц (2G,3G/4G), 16 бит, MSB, формат данных в терминах linux’а DSP_A. Модуль - мастер. Модуль никаких настроек не принимает. Основные изменения драйвера такие:
static const struct snd_soc_dapm_widget simcompcm_dapm_widgets[] = {
SND_SOC_DAPM_INPUT("AIN"),
SND_SOC_DAPM_OUTPUT("AOUT"),
};
static const struct snd_soc_dapm_route simcompcm_dapm_routes[] = {
{ "Capture", NULL, "AIN" },
{ "AOUT", NULL, "Playback" },
};
static struct snd_soc_dai_driver simcompcm_dai = {
.name = "simcompcm",
.playback = {
.stream_name = "Playback",
.channels_min = 1,
.channels_max = 1,
.rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000),
.formats = SND_SOC_DAIFMT_DSP_A,
},
.capture = {
.stream_name = "Capture",
.channels_min = 1,
.channels_max = 1,
.rates = (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000),
.formats = SND_SOC_DAIFMT_DSP_A,
},
.symmetric_rates = 1,
};
Сделал оверлей для DT:
/dts-v1/;
/plugin/;
/ {
compatible = "allwinner,sun8i-h3";
fragment@0 {
target-path = "/";
__overlay__ {
simcom_codec: simcom_codec {
status = "okay";
compatible = "simcom,simcompcm";
#sound-dai-cells = <0>;
};
};
};
fragment@1 {
target = <&i2s0>;
__overlay__ {
status = "okay";
pinctrl-0 = <&i2s0_pins>;
sound-dai = <&simcom_codec>;
pinctrl-names = "default";
};
};
fragment@2 {
target-path = "/";
__overlay__ {
sound {
status = "okay";
compatible = "simple-audio-card";
simple-audio-card,name = "simcom_pcm";
simple-audio-card,mclk-fs = <256>;
simple-audio-card,format = "dsp_a";
simple-audio-card,widgets =
"Line", "Line In",
"Line", "Line Out";
simple-audio-card,routing =
"AIN", "Line In",
"Line Out", "AOUT";
simple-audio-card,bitclock-master = <&dailink0>;
simple-audio-card,frame-master = <&dailink0>;
simple-audio-card,cpu {
sound-dai = <&i2s0>;
};
dailink0: simple-audio-card,codec {
sound-dai = <&simcom_codec>;
};
};
};
};
};
Пробовал крутить это: simple-audio-card,mclk-fs = <256>; - вообще никакой реакции. Меня смущает вот это сочетание клоков модуля в даташите:
Frame cycle time: 125 us (8.0 kHz) / 62.5 us (16.0 kHz)
Bit cycle time: 488 ns (~2049 kHz) / 244 ns (~4098 kHz)
Значения в скобках я сам пересчитал из указанных спеков на диаграммы сигналов, а в общем спеке на формат PCM дают «округлённые» числа:
PCM clock rate 2048kHz / 4096 kHz
Что-то я не догоняю таких нестыковок по частотам. И ещё получается, что в один фрейм можно 16 каналов по 16 бит затолкать, а у меня один только, может выходной поток неправильно режется на фреймы, 8 семплов кладётся в один фрейм? Как этим управлять тоже не могу найти. Буду благодарен за идеи.