Rockchip · AI & Linux Hub

Экран и звук

ArmSoM Rockchip Audio: полное руководство по драйверам, настройке и отладке

Полное руководство Rockchip: SAI, I2S, PDM, ASRC, ALSA, Device Tree, запись, воспроизведение и отладка XRUN для разработчиков ArmSoM.

· ArmSoM Editorial · Rockchip source documentation · 95 мин чтения

Руководство предназначено для разработки аудио на платформах ArmSoM Rockchip, включая Sige7 / AIM7 (RK3588) и Sige5 / CM5 / AIM5 (RK3576). Выбирайте разделы по SoC, кодеку на плате или плате-носителе, схеме соединений и SDK/BSP. Возможность контроллера не означает, что интерфейс выведен на каждой плате. Оригинал охватывает Linux 4.4, 4.19, 5.10 и 6.1; сверяйте драйверы и свойства Device Tree с BSP. Измерения и примеры принадлежат Rockchip и не являются тестами ArmSoM.

Источник: Rockchip_Developer_Guide_Audio_EN.pdf, V2.4.0. Технические главы сохранены; служебные заявления, аудитория и история изменений исключены. Исправления и вопросы перечислены в редакционных замечаниях.

ArmSoM Docs · Sige7 · Sige5 · CM5

1. Обзор

1.1 Возможности аудиоподсистемы Rockchip

В этом разделе описаны возможности аудиоподсистемы платформы RK.

  Функция Возможности Описание
DAI I2S 8 каналов ввода/вывода Межмикросхемный аудиоинтерфейс
  TDM 16 каналов ввода/вывода Временное разделение каналов
  PCM 2 каналов ввода/вывода Импульсно-кодовая модуляция
  PDM 8 входных каналов Импульсно-плотностная модуляция
  DSM 2 выходных каналов Дельта-сигма-модуляция
  DCODEC 4 входных каналов / 2 выходных каналов Цифровой интерфейс кодека
  SPDIF 2 каналов ввода/вывода / 7.1 битовый поток Цифровой интерфейс Sony/Philips
  SAI 128 каналов ввода/вывода Serial Audio Interface
  ASRC 8 каналов ввода/вывода Асинхронный преобразователь частоты дискретизации
Составной DAI I2S + I2S 16 каналов ввода/вывода Например, саундбар
  I2S + PDM 16 каналов ввода/вывода Например, устройство умного дома
  TDM + TDM 32 входных каналов / 32 выходных каналов  
  TDM + PDM 24 входных каналов / 16 выходных каналов  
  SAI + SAI 256 каналов ввода/вывода и более Например, микрофонный массив
  ASRC + ASRC 40 CH Например, RK2118: 32 входных и 8 выходных каналов
  … … …
Составной кодек Массив цифровых микрофонов + аналоговый возврат Для подавления акустического эха Например, устройство умного дома
  HDMI + аналоговый выход Для нескольких потоков Например, OTT-устройство
  CARD + VAD Для автоматического распознавания речи Например, устройство умного дома
Цифровые выходы HDMI OUT 7.1 LPCM многоканальный / битовый поток Например, битовый поток Dolby/DTS без потерь
  DP 7.1 LPCM многоканальный Например, битовый поток Dolby/DTS без потерь
  Оптический выход 2 CH LPCM / 7.1 битовый поток Например, битовый поток 7.1 DD+
  DCODEC Соединение с внешней аналоговой частью e.g. RK812
  DSM Стереофонический дифференциальный выход Например, музыка через DSM на RV1126
Цифровые входы HDMI IN Вход HDMI Например, с внешней микросхемой TC358749
  HDMI ARC Обратный аудиоканал e.g. RK3308
  PDM DMICS Массив цифровых микрофонов Например, 8 всенаправленных микрофонов PDM
  I2S DMICS Массив цифровых микрофонов Например, 8 всенаправленных микрофонов I2S
  DCODEC Соединение с внешней аналоговой частью e.g. RK812
  VAD Обнаружение голосовой активности Пробуждение системы при достижении звукового порога
  SPDIF IN 2 CH LPCM Например, ARC на RK3308
Аналоговые входы/выходы Встроенные кодеки 2 каналов ввода/вывода и более 8CH IN on RK3308
  Внешние кодеки 2 каналов ввода/вывода и более e.g. RK817
Прочее ACC Программная/аппаратная компенсация аудиотактирования Например, компенсация дрейфа частоты UAC
  DLP Программный/аппаратный цифровой возврат Например, 2 микрофонных канала с цифровым возвратом
  AUPLL-IO-IN Аудио-PLL с поддержанием тактирования Например, внешний автомобильный усилитель RK2116

Рисунок 1-1. Возможности аудиоподсистемы Rockchip

1.2 DAI

В этом разделе рассмотрены цифровые аудиоинтерфейсы платформы RK.

1.2.1 SAI

1.2.1.1 Возможности контроллера SAI

Гибкая поддержка протоколов, включая I2S, DSP и TDM.

Обнаружение FSYNC ERR / LOST.

Инверсия FSYNC/SCLK.

FSYNC с произвольным коэффициентом заполнения.

Гибкая настройка временного положения DATA; шаг SFT равен половине периода SCLK.

Монофонический режим: RX позволяет выбрать слот, TX копирует монофонические данные во все слоты.

Режимы ведущего/ведомого одновременно применяются к TX и RX.

До 128 слотов на линию, в пределах ограничений тактирования: например, при 50 МГц — TDM 32 слота, 48 кГц, 32 бита.

Настраиваемая разрядность слота: 8–32 бита.

Маскирование слотов.

Полное переназначение связей между физическими линиями данных и внутренними трактами.

Режим автоматической остановки TX.

Внутренняя петля TX→RX.

Объединение нескольких SAI — Multi SAI Combined (MSC).

1.2.1.2 Поддержка SAI в микросхемах RK

В таблице перечислены SAI, доступные для подключения периферии:

SAIx Линии RX Линии TX Версия Примечание
RK1820 SAI-M0 4* 4* V4 SDI0~3 и SDO3~0 мультиплексированы
RK1820 SAI-M1/M2 4 4 V4  
RK2116 SAI0-RMIO 4 4 V5 Полное мультиплексирование матрицы IO
RK2116 SAI1/2/3-RMIO 2 2 V5  
RK2116 SAI4/5/6/7-RMIO 1 1 V5  
RK2118 SAI0/4-RMIO 4 4 V2  
RK2118 SAI1/2/3/5/6/7- RMIO 2 2 V2  
RK3528 SAI0 1 1 V1  
RK3528 SAI1 4 4 V1  
RK3506 SAI0-M0/RMIO 4 1 V2  
RK3506 SAI1-M0/RMIO 1 4 V2  
RK3506 SAI2-M0/M1 1 1 V2  
RK3506 SAI3-M0 1 1 V2  
RK3562 SAI0-M0 4* 4* V1 SDI1~3 и SDO3~1 мультиплексированы
RK3562 SAI0-M1 4 4 V1  
RK3562 SAI1-M0 4 4 V1  
RK3562 SAI1-M1 4* 4* V1 SDI1~3 и SDO3~1 мультиплексированы
RK3562 SAI2 1 1 V1  
RK3576 SAI0-M0 4 4 V1  
RK3576 SAI0-M1/M2 4* 4* V1 SDI1~3 и SDO3~1 мультиплексированы
RK3576 SAI1-M0 4* 4* V1 SDI1~3 и SDO3~1 мультиплексированы
RK3576 SAI1-M1 4 4 V1  
RK3576 SAI2-M0/M1/M2 1 1 V1  
RK3576 SAI3-M0/M1/M2/M3 1 1 V1  
RK3576 SAI4-M0/M1/M2/M3 1 1 V1  
RV1103B SAI 1 1 V3  
RV1126B SAI0-M0/M1 4* 4* V4 SDI1~3 и SDO3~1 мультиплексированы
RV1126B SAI1-M0/M1/M2 1 1 V4  
RV1126B SAI2-M0/M1 3 1 V4  

Таблица 1-2. Поддержка SAI в микросхемах RK

1.2.1.2.1 Версии SAI
Версия Описание
V1 1. Первая версия.
V2 1. Frame Sync xN (FSXN). 2. Обнаружение ошибки синхронизации кадра (FSE). 3. Обнаружение потери синхронизации (FSLOST). 4. Каскадирование SAI. 5. Автоматическое тактирование передачи. 6. Сдвиг временной позиции TX влево.
V3 1. Выбор левого/правого канала цифрового возврата, например L:MIC R:LP.
V4 1. Повышена устойчивость целостности кадров. 2. Настройка чередования FIFO. 3. Отладка данных.
V5 1. MSC V2. 2. Синхронизация фазы FSYNC с MAC.pps. 3. Синхронизация с USB или MAC через ACC. 4. Отладка данных по идентификатору канала.

Таблица 1-3. Описание версий SAI

1.2.2 ASRC

1.2.2.1 Возможности контроллера ASRC

Преобразование частоты дискретизации в диапазоне 8–384 кГц.

Отношение входной и выходной частот от 1:8 до 8:1.

Синхронизация асинхронных источников тактирования.

THD+N от −120 до −140 дБ при 24 битах.

Режим реального времени.

Файловый режим.

Низкая задержка.

Объединение нескольких ASRC.

1.2.2.2 THD+N

Испытательная схема исходного документа: AP → SAI → ASRC → SAI → AP.

1.2.2.2.1 16 бит

Ниже приведены значения THD+N в дБ для 16-битных данных. В отличие от 24 бит, целочисленное отношение частот не даёт выраженного преимущества; общий разброс невелик.

SR\RSR 8k 11.025k 12K 16K 22.05K 24K 32K 44.1K 48K 64K
8K -96.2 -96.0 -95.9 -96.0 -95.7 -95.8 -95.7 -95.6 -95.7 -95.6
11.025K -96.6 -95.9 -95.8 -95.8 -95.6 -95.6 -95.5 -95.5 -95.5 -95.5
12K -96.7 -96.0 -96.1 -95.5 -95.7 -95.5 -95.5 -95.5 -95.5 -95.5
16K -97.2 -96.5 -96.3 -95.6 -95.5 -95.5 -95.5 -95.4 -95.4 -95.4
22.05K -97.7 -97.0 -96.8 -96.2 -95.4 -95.5 -95.4 -95.3 -95.3 -95.3
24K -97.7 -97.1 -96.9 -96.3 -95.6 -95.5 -95.5 -95.3 -95.3 -95.3
32K -97.8 -97.4 -97.3 -96.7 -96.2 -96.0 -95.4 -95.3 -95.3 -95.3
44.1K -98.3 -97.7 -97.7 -97.1 -96.6 -96.5 -96.0 -95.2 -95.2 -95.2
48K -98.3 -97.7 -97.7 -97.2 -96.7 -96.6 -96.1 -95.5 -95.2 -95.3
64K -98.2 -98.0 -98.0 -97.5 -97.1 -96.9 -96.5 -96.0 -95.8 -95.3

Таблица 1-4. THD+N для 16 бит, дБ

1.2.2.2.2 24 бита

Ниже приведены значения THD+N в дБ для 24-битных данных. Наилучшие результаты получаются при целочисленном отношении частот.

SR\RSR 8k 11.025k 12K 16K 22.05K 24K 32K 44.1K 48K 64K
8K -141.3 -132.4 -133.6 -139.8 132.4 -135.0 -137.1 -132.1 -133.7 -133.1
11.025K -131.8 -140.8 -134.0 -133.0 -137.3 -131.3 -133.0 -138.2 -131.1 -132.2
12K -138.4 -131.0 -140.9 -131.5 -131.4 -129.5 -132.4 -131.1 -131.6 -131.1
16K -143.0 -130.0 -138.1 -140.0 -133.3 -134.0 -140.7 -133.0 -135.0 -133.6
22.05K -129.8 -142.9 -132.0 -131.5 -140.5 -129.5 -128.7 -140.3 -129.4 -129.8
24K -144.0 -127.3 -142.8 -136.3 -130.5 -140.7 -132.7 -129.8 -140.1 -132.6
32K -142.0 -136.5 -141.7 -141.8 -127.7 -133.8 -140.5 -132.6 -134.5 -131.7
44.1K -139.8 -144.7 -139.3 -128.6 -142.8 -132.3 -132.2 -140.5 -129.0 -129.2
48K -142.6 -122.5 -144.4 -143.3 -126.1 -142.7 -138.8 -130.2 -140.5 -137.3
64K -142.8 -141.9 -142.2 -143.0 -139.0 -139.2 -142.5 -128.5 -134.9 -140.4

Таблица 1-5. THD+N для 24 бит, дБ

1.2.2.3 Задержка

Общая задержка = фазовая задержка + задержка FIFO.

1.2.2.3.1 Фазовая задержка

RATIO = выходная частота дискретизации / входная частота дискретизации.

RATIO Фазовая задержка
RATIO <= 1 32 отсчётов при SR(input)
RATIO > 1 32 * RATIO отсчётов при SR(input)
1.2.2.3.2 Задержка FIFO

Задержка FIFO = ASRC_IN_THRESH + ASRC_OUT_THRESH.

Параметр настраивается. Текущая программная конфигурация приведена в таблице:

Порог Значение
ASRC_IN_THRESH 2
ASRC_OUT_THRESH 24
1.2.2.3.3 Пример
Пример Задержка
48k -> 16k Задержка = 32 + 2 + 24 = 58 отсчётов при 48k, 1.2ms
48k -> 48k Задержка = 32 + 2 + 24 = 58 отсчётов при 48k, 1.2ms
48k -> 96k Задержка = 32 * (96 / 48) + 2 + 24 = 90 отсчётов при 48k, 1.9ms

Примечание: для уменьшения задержки настройте задержку FIFO.

1.2.2.4 Поддержка ASRC в микросхемах RK
Микросхема ASRC Максимальная конфигурация Версия
RK2118 ASRC_8CH x 2, ASRC_4CH x 6 40 CH V1
RK3506 ASRC_4CH x 2 8 CH V1
RK3576 ASRC_4CH x 2, ASRC_2CH x 2 12 CH V1
RV1126B ASRC_2CH x 2 4 CH V1

1.2.3 I2S

В платформе RK используются два типа контроллеров: I2S и I2S-TDM. Первый поддерживает I2S и PCM, второй — I2S, PCM и TDM.

1.2.3.1 Возможности контроллера I2S

Восьмиканальный I2S: стандартный формат, левое и правое выравнивание.

Стерео PCM: early, late 1, late 2, late 3.

Режим ведущего/ведомого одновременно применяется к TX и RX.

Частоты дискретизации 8–192 кГц и 384 кГц.

Разрядность 16–32 бита.

Порядок передачи MSB/LSB.

Настройка фазы тактового сигнала.

Компенсация тактовой частоты.

Примечания:

Для 384 кГц необходим высокоточный источник тактирования: внешний сигнал на MCLK либо работа в ведомом режиме.

Монофонический PCM не поддерживается. При необходимости передавайте монофонические данные в стерео PCM, размещая полезные данные в слоте 0.

Компенсация тактирования применяется при разных источниках частоты, например в UAC, и имеет ограничения. См. раздел «Компенсация аудиотактирования».

1.2.3.2 Возможности контроллера I2S-TDM

В дополнение к возможностям I2S контроллер I2S-TDM поддерживает:

TDM PCM с 8 слотами: обычный режим и режимы левого сдвига [0–3].

TDM I2S с 8 слотами: стандартный формат, левое и правое выравнивание.

Разрядность слота 16–32 бита.

Полное переназначение физических линий и внутренних трактов.

Асинхронный TX/RX: независимые тактовые сигналы, частоты дискретизации, разрядность и протоколы.

Синхронный TX/RX с общим тактированием.

Ширина PCM FSYNC: [1–7] периодов SCLK либо один канальный блок.

Ширина I2S FSYNC: половина кадра или полный кадр.

Примечания:

Допускается только чётное число слотов.

В длиннокадровом режиме TDM I2S возможна передача 16 каналов.

В TDM используется только path-0. Если физический вывод не соответствует каналу, переназначьте его на path-0.

1.2.3.3 Поддержка I2S в микросхемах RK
Микросхема I2S I2S-TDM
PX30/RK3326 I2S1_2CH, I2S2_2CH I2S0_8CH
RK1808 I2S1 I2S0
RK3036 I2S0  
RK3066 I2S0, I2S1, I2S2  
RK312X I2S_8CH, I2S_2CH  
RK3188 I2S0  
RK3288 I2S0  
RK322X I2S0, I2S1, I2S2  
RK3308 I2S_2CH_0, I2S_2CH_1 I2S_8CH_0, I2S_8CH_1, I2S_8CH_2, I2S_8CH_3
RK3328 I2S0, I2S1, I2S2  
RK3368 I2S_8CH, I2S_2CH  
RK3399 I2S0, I2S1, I2S2  
RK3568/RK3566   I2S0_8CH, I2S1_8CH, I2S2_2CH, I2S3_2CH
RK3588 I2S2_2CH, I2S3_2CH I2S0_8CH, I2S1_8CH
RV1108 I2S0, I2S1, I2S2  
RV1126/RV1109 I2S1_2CH, I2S2_2CH I2S0_8CH

Таблица 1-6. Поддержка I2S в микросхемах RK

1.2.4 PDM

Платформа RK поддерживает цифровые микрофоны и АЦП с интерфейсом PDM. Основные возможности:

1.2.4.1 Возможности контроллера PDM

Только ведущий режим.

Массив до 8 микрофонов.

Разрядность 16–24 бита.

Частота дискретизации 8–48 кГц.

Перестановка каналов.

Фильтр высоких частот: 3,79; 60; 243; 493 Гц.

Выравнивание данных в памяти по левому или правому краю.

Полное переназначение линий данных.

Настройка фазы тактового сигнала.

Компенсация тактовой частоты.

Примечания:

Выравнивание в памяти применяется только при разрядности более 16 бит. Такие данные хранятся словами; младшие разряды по умолчанию заполняются нулями.

Компенсация тактирования для систем с разными источниками частоты, например UAC, имеет ограничения. См. раздел «Компенсация аудиотактирования».

Полное переназначение линий поддерживается начиная с RV1126: RV1126/RV1109, RK3568/RK3566 и последующие платформы из списка поддержки.

1.2.4.2 Поддержка PDM в микросхемах RK
Микросхема Название Максимум каналов Версия
PX30/RK3326 PDM 8 V2
RK1808 PDM 8 V2
RK2108 PDM 4 V3
RK3308 PDM_8CH 8 V2
RK3328 PDM 8 V1
RK3568/RK3566 PDM 8 V3
RV1126/RV1109 PDM 8 V3

Таблица 1-7. Поддержка PDM в микросхемах RK

Описание версий

Версия Описание
V1 1. Стандартный режим, тактовые частоты 2,048/2,822/3,072 МГц.
V2 1. Добавлен дробный делитель. 2. Добавлено выравнивание данных в памяти.
V3 Исправления: 1. Переполнение знакового бита при включённом HPF и амплитуде около 0 дБ. 2. Неравномерность полосы пропускания: в новой версии менее 0,1 дБ. 3. Наложение спектров. Новые функции: малопотребляющий режим с частотами 1,024/1,411/1,536 МГц и высокопроизводительный режим с частотами 4,096/5,644/6,144 МГц.

Таблица 1-8. Версии PDM

1.2.5 DCODEC

Цифровой интерфейс CODEC платформы RK соединяется с совместимым аналоговым кодеком, например RK812, образуя полноценный кодек.

В режиме DSM контроллер может напрямую управлять внешним усилителем мощности, снижая стоимость устройств с обычными требованиями к качеству звука.

Три канала АЦП.

Стереофонический ЦАП.

Асинхронный режим: частоты записи и воспроизведения могут отличаться.

Синхронный режим: частоты записи и воспроизведения должны совпадать.

Поддержка PGA и ALC.

Выход DSM с непосредственным управлением PA.

Фильтр высоких частот.

1.2.6 VAD

VAD (Voice Activity Detection) получает данные от DAI, выполняет статистический анализ и при достижении порога вызывает прерывание для пробуждения системы. Упрощённый поток данных показан на рисунке 1-1.

Иллюстрация из оригинала: 1.2.6 VAD (p. 20)

Рисунок 1-1. Поток данных RK VAD

  1. Во время сна продолжается работа DAI → VAD → SRAM. VAD непрерывно принимает данные, фильтрует и адаптивно оценивает шум, сохраняет звук в кольцевом буфере SRAM.
  1. При превышении порога VAD вызывает прерывание и будит CPU. Процессор отключает VAD, после чего поток автоматически переключается на стандартный тракт записи DAI → DMAC → DDR → CPU.
  1. CPU без разрыва добавляет данные SRAM в буфер записи. Для пользовательского приложения обработка прозрачна.
  1. После пробуждения ASR-приложение анализирует запись, например обнаруживает ключевые слова.

1.2.7 SPDIF

Платформа RK поддерживает передатчик SPDIF. RK3308 также поддерживает приёмник SPDIF.

Разрядность 16–24 бита.

Частота дискретизации до 192 кГц.

Несжатое стерео LPCM.

Сжатый звук 5.1/7.1, например DD и DD+.

Оптическое и коаксиальное соединение.

Примечание:

Для оптического вывода 192 кГц нужны компоненты, поддерживающие эту частоту.

1.3 Combo DAI

Платформа RK позволяет объединять DAI в составной Combo DAI, как показано на рисунке 1-2.

Иллюстрация из оригинала: 1.3 Combo DAI (p. 21)

Рисунок 1-2. Combo DAI

2. Разработка аудиодрайверов

В главе описаны аудиоподдержка RK, разработка драйверов и отладка.

2.1 Основные компоненты звуковой карты

Базовая структура звуковой карты приведена на рисунке 2-1.

Иллюстрация из оригинала: 2.1 Основные компоненты звуковой карты (p. 22)

Рисунок 2-1. Структура звуковой карты ALSA

DAI — цифровой аудиоинтерфейс.

MACHINE связывает DAI и кодек в звуковую карту.

DMAENGINE передаёт данные между памятью и FIFO DAI.

Обычно для добавления звуковой карты в готовый SDK достаточно перенести или написать драйвер кодека. Иногда требуется новый machine-драйвер; см. соответствующий раздел.

2.2 Список драйверов

Драйверы и их назначение перечислены ниже:

kernel/sound/soc/rockchip$ tree -I "*.o|*.h"
.
├── rockchip_asrc.c                             # asynchronous sample rate converter
├── rockchip_dlp.c                              # digital audio loopback
├── rockchip_dlp_pcm.c                          # for single dai dlp
├── rockchip_dummy_dai.c                        # used for multi-dais as channel map
├── rockchip_hdmi_analog.c                      # hdmi and codec share the same i2s
├── rockchip_hdmi.c                             # hdmi with jack det
├── rockchip_hdmi_dp.c                          # hdmi and dp share the same i2s
├── rockchip_i2s.c                              # old i2s which support i2s/pcm
├── rockchip_i2s_tdm.c                          # new i2s-tdm which support i2s/pcm/tdm
├── rockchip_multicodecs.c                      # support multi-streaming
├── rockchip_multi_dais.c                       # support combo-dais
├── rockchip_multi_dais_pcm.c                   # co-work with combo-dais
├── rockchip_pdm.c                              # pdm dai driver
├── rockchip_pdm_v2.c                           # pdmv2 dai driver
├── rockchip_sai.c                              # sai dai driver
├── rockchip_spdif.c                            # spdif tx dai driver
├── rockchip_spdifrx.c                          # spdif rx dai driver
├── rockchip_trcm.c                             # used for i2s-tdm
├── rockchip_utils.c                            # common utils
kernel/sound/soc/codecs$ tree -P "rk*.c|h*.c|d*.c"
.
├── dmic.c                                      # dmic, e.g. i2s dmics, pdm dmics
├── dummy-codec.c                               # dummy codec
├── hdmi-codec.c                                # hdmi codec driver
├── rk312x_codec.c                              # internal codec
├── rk3228_codec.c                              # internal codec
├── rk3308_codec.c                              # internal codec 8ch adc
├── rk3328_codec.c                              # internal codec
├── rk3506_codec.c                              # internal codec
├── rk3528_codec.c                              # internal codec
├── rk730.c                                     # rk730 audio codec
├── rk817_codec.c                               # codec in rk817 pmic ic
└── rk_dsm.c                                    # audio dsm

2.3 Разработка драйверов DAI

В выпущенном SDK драйверы DAI уже реализованы. Разработчику нужно настроить свойства под конкретный сценарий и включить необходимые функции.

2.3.1 SAI

2.3.1.1 Настройка формата протокола

SAI поддерживает гибкую настройку временных диаграмм:

FSYNC с произвольным коэффициентом заполнения.

Произвольный сдвиг передачи данных с шагом половина SCLK (SFT).

Инверсия FSYNC/SCLK.

Пример 1: FSYNC = 1 × SCLK; SFT = 2 × 0,5 SCLK; приём по переднему фронту, передача по заднему.

Иллюстрация из оригинала: 2.3.1.1 Настройка формата протокола (p. 23)

Рисунок 2-2. Формирование временных сигналов

Пример 2: FSYNC = 1 × SCLK; SFT = 2 × 0,5 SCLK; приём по заднему фронту, передача по переднему.

Иллюстрация из оригинала: 2.3.1.1 Настройка формата протокола (p. 24)

Рисунок 2-3. Формирование сигналов с инверсией SCLK

Все перечисленные ниже типовые форматы построены на основе этих временных диаграмм.

2.3.1.1.1 AUDIO_FMT_I2S

Иллюстрация из оригинала: 2.3.1.1.1 AUDIO_FMT_I2S (p. 24)

2.3.1.1.2 AUDIO_FMT_LEFT_J

Иллюстрация из оригинала: 2.3.1.1.2 AUDIO_FMT_LEFT_J (p. 24)

2.3.1.1.3 AUDIO_FMT_RIGHT_J

Иллюстрация из оригинала: 2.3.1.1.3 AUDIO_FMT_RIGHT_J (p. 25)

2.3.1.1.4 AUDIO_FMT_DSP_A

Иллюстрация из оригинала: 2.3.1.1.4 AUDIO_FMT_DSP_A (p. 25)

2.3.1.1.5 AUDIO_FMT_DSP_B

Иллюстрация из оригинала: 2.3.1.1.5 AUDIO_FMT_DSP_B (p. 25)

2.3.1.1.6 AUDIO_FMT_TDM_I2S

Иллюстрация из оригинала: 2.3.1.1.6 AUDIO_FMT_TDM_I2S (p. 25)

2.3.1.1.7 AUDIO_FMT_TDM_I2S_INV

Иллюстрация из оригинала: 2.3.1.1.7 AUDIO_FMT_TDM_I2S_INV (p. 26)

2.3.1.1.8 AUDIO_FMT_TDM_LEFT_J

Иллюстрация из оригинала: 2.3.1.1.8 AUDIO_FMT_TDM_LEFT_J (p. 26)

2.3.1.1.9 AUDIO_FMT_TDM_DSP_A

Иллюстрация из оригинала: 2.3.1.1.9 AUDIO_FMT_TDM_DSP_A (p. 26)

2.3.1.1.10 AUDIO_FMT_TDM_DSP_B

Иллюстрация из оригинала: 2.3.1.1.10 AUDIO_FMT_TDM_DSP_B (p. 26)

2.3.1.2 Несколько линий данных

При нескольких линиях каналы чередуются группами по два. Если используются более двух линий, а источник передаёт данные последовательно по линиям, требуется устранить чередование. Для этого можно непосредственно вызвать соответствующий API.

Ниже расположение каналов показано на примере TDM16; тот же принцип применяется к другим форматам.

2.3.1.2.1 TDM16 x 1

Иллюстрация из оригинала: 2.3.1.2.1 TDM16 x 1 (p. 27)

2.3.1.2.2 TDM16 x 2

Иллюстрация из оригинала: 2.3.1.2.2 TDM16 x 2 (p. 27)

2.3.1.2.3 TDM16 x 3

Иллюстрация из оригинала: 2.3.1.2.3 TDM16 x 3 (p. 27)

2.3.1.2.4 TDM16 x 4

Иллюстрация из оригинала: 2.3.1.2.4 TDM16 x 4 (p. 28)

2.3.1.2.5 Последовательный и чередующийся порядок

Соответствие порядков показано для TDM16 × 2 и аналогично для остальных конфигураций.

Источник передаёт каналы последовательно по линиям, а SAI принимает их с чередованием. Для получения последовательного выхода принятые данные нужно деинтерливировать.

Иллюстрация из оригинала: 2.3.1.2.5 Последовательный и чередующийся порядок (p. 28)

Рисунок 2-4. Последовательный и чередующийся порядок

CH0 CH1 CH2 CH3 CH4 CH5 CH6 CH7 CH8 CH9 CH10 CH11 CH12 CH13 CH14 CH15
CH16 CH17 CH18 CH19 CH20 CH21 CH22 CH23 CH24 CH25 CH26 CH27 CH28 CH29 CH30 CH31

Иллюстрация из оригинала: 2.3.1.2.5 Последовательный и чередующийся порядок (p. 28)

CH0 CH1 CH16 CH17 CH2 CH3 CH18 CH19 CH4 CH5 CH20 CH21 CH6 CH7 CH22 CH23
CH8 CH9 CH24 CH25 CH10 CH11 CH26 CH27 CH12 CH13 CH28 CH29 CH14 CH15 CH30 CH31

Рисунок 2-5. Устранение чередования

2.3.1.3 Объединение нескольких SAI

Несколько SAI можно объединить для увеличения числа линий.

Используется один ведущий и несколько ведомых; тактовые сигналы распределяются внутри SoC.

Интерфейсное тактирование выдаёт только ведущий SAI; учитывайте это при разводке платы.

SAI V5 объединяет аудиопотоки аппаратно; предыдущие версии выполняли объединение через DMA.

Пример: SAI0 + SAI1 + SAI2 образуют I2S 8TX.

Иллюстрация из оригинала: 2.3.1.3 Объединение нескольких SAI (p. 29)

2.3.1.4 Маска слотов

Маска SAI позволяет игнорировать данные выбранных слотов.

Пример 1: TDM16 × 1, последние два слота замаскированы.

Иллюстрация из оригинала: 2.3.1.4 Маска слотов (p. 29)

Пример 2: TDM16 × 2, последние два слота замаскированы.

Иллюстрация из оригинала: 2.3.1.4 Маска слотов (p. 29)

Примечание:

Маска одновременно действует на все линии; учитывайте это в многолинейных конфигурациях.

2.3.1.5 Разрядность слота
Свойство Значение Описание
rockchip,slot-width int Разрядность слота по умолчанию — 32 бита

Пример: слот 16 бит, типичный для Bluetooth. Свойство эквивалентно bclk-fs у I2S.

&sai0 {
        rockchip,slot-width = <16>;
};
2.3.1.6 Полное переназначение линий данных

Аппаратно можно подключиться к любой линии. Скорректируйте порядок каналов свойствами либо используйте path sel для выбора и проверки.

Свойство Значение Описание
rockchip,sai-tx-route   Порядок по умолчанию: SDO0 | SDO1 | SDO2 | SDO3
rockchip,sai-rx-route   Порядок по умолчанию: SDI0| SDI1 | SDI2 | SDI3

Пример: порядок каналов воспроизведения SDO3 | SDO2 | SDO1 | SDO0.

&sai0 {
        rockchip,sai-tx-route = <3 2 1 0>;
};
2.3.1.7 Настройка нескольких линий

Свойство используется главным образом в многолинейном TDM. Выбор и проверка также доступны через lanes sel.

Свойство Значение Описание
rockchip,tdm-tx-lanes int По умолчанию одна линия
rockchip,tdm-rx-lanes int По умолчанию одна линия

Пример: tdm-tx × 4, tdm-rx × 2.

&sai0 {
        rockchip,tdm-tx-lanes = <4>;
        rockchip,tdm-rx-lanes = <2>;
};
2.3.1.8 Время ожидания

Свойство задаёт тайм-аут ведомого режима. При пропадании внешнего тактового сигнала ASoC по умолчанию ждёт 10 с. Уменьшение времени ожидания улучшает реакцию системы; рекомендуемое значение — не меньше длительности буфера.

Свойство Значение Описание
rockchip,sai-tx-wait-time-ms int По умолчанию 10 с
rockchip,sai-rx-wait-time-ms int По умолчанию 10 с

Пример: буфер 40 мс, ожидание 50 мс.

&sai0 {
        rockchip,sai-tx-wait-time-ms = <50>;
        rockchip,sai-rx-wait-time-ms = <50>;
};
2.3.1.9 mclkout / mclkin

mclkout и mclkin используют общие выводы. Ниже показаны варианты для ведущего и ведомого SAI. Если периферии MCLK не нужен, соединение можно не выполнять.

sai mclk Описание
master out SoC выдаёт тактирование периферии
master in SAI использует внешний MCLKIN; типовой сценарий — единый источник аудиотактирования
slave out Периферия ведущая; MCLK предоставляет SoC
slave in Нет сценария применения

Пример: mclkout.

rk817_codec: codec {
        #sound-dai-cells = <0>;
        compatible = "rockchip,rk817-codec";
        clocks = <&mclkout_sai0>;
        clock-names = "mclk";
        assigned-clocks = <&mclkout_sai0>;
        assigned-clock-rates = <12288000>;
        pinctrl-names = "default";
        pinctrl-0 = <&i2s0m0_mclk>;
        hp-volume = <20>;
        spk-volume = <3>;
        mic-in-differential;
        status = "okay";
};

Пример: mclkin.

&sai0 {
        assigned-clocks = <&cru CLK_SAI0>;
        assigned-clock-parents = <&mclkin_i2s0>;
        pinctrl-0 = <&sai0_sdi
                     &sai0_sdo
                     &sai0_lrck
                     &sai0_sclk
                     &sai0_mclk>;
};
&mclkin_sai0 {
        clock-frequency = <24576000>;
        status = "okay";
};
2.3.1.10 Элементы управления

Режимы, протоколы и функции удобно просматривать и настраивать через amixer или tinymix.

# amixer  -c 0 controls
numid=34,iface=MIXER,name='SAI2 Clk Auto Switch'
numid=5,iface=MIXER,name='SAI2 Receive Mono Slot Select'
numid=6,iface=MIXER,name='SAI2 Receive Mono Switch'
numid=29,iface=MIXER,name='SAI2 Receive PATH0 Source Select'
numid=28,iface=MIXER,name='SAI2 Receive PATH1 Source Select'
numid=27,iface=MIXER,name='SAI2 Receive PATH2 Source Select'
numid=26,iface=MIXER,name='SAI2 Receive PATH3 Source Select'
numid=4,iface=MIXER,name='SAI2 Receive SDIx Select'
numid=2,iface=MIXER,name='SAI2 Receive Start Mode Sel'
numid=11,iface=MIXER,name='SAI2 SDI0 Loopback I2S LR Channel Sel'
numid=15,iface=MIXER,name='SAI2 SDI0 Loopback I2S LR Switch'
numid=19,iface=MIXER,name='SAI2 SDI0 Loopback Src Select'
numid=23,iface=MIXER,name='SAI2 SDI0 Loopback Switch'
numid=10,iface=MIXER,name='SAI2 SDI1 Loopback I2S LR Channel Sel'
numid=14,iface=MIXER,name='SAI2 SDI1 Loopback I2S LR Switch'
numid=18,iface=MIXER,name='SAI2 SDI1 Loopback Src Select'
numid=22,iface=MIXER,name='SAI2 SDI1 Loopback Switch'
numid=9,iface=MIXER,name='SAI2 SDI2 Loopback I2S LR Channel Sel'
numid=13,iface=MIXER,name='SAI2 SDI2 Loopback I2S LR Switch'
numid=17,iface=MIXER,name='SAI2 SDI2 Loopback Src Select'
numid=21,iface=MIXER,name='SAI2 SDI2 Loopback Switch'
numid=8,iface=MIXER,name='SAI2 SDI3 Loopback I2S LR Channel Sel'
numid=12,iface=MIXER,name='SAI2 SDI3 Loopback I2S LR Switch'
numid=16,iface=MIXER,name='SAI2 SDI3 Loopback Src Select'
numid=20,iface=MIXER,name='SAI2 SDI3 Loopback Switch'
numid=25,iface=MIXER,name='SAI2 Sync In Switch'
numid=24,iface=MIXER,name='SAI2 Sync Out Switch'
numid=7,iface=MIXER,name='SAI2 Transmit Mono Switch'
numid=33,iface=MIXER,name='SAI2 Transmit SDO0 Source Select'
numid=32,iface=MIXER,name='SAI2 Transmit SDO1 Source Select'
numid=31,iface=MIXER,name='SAI2 Transmit SDO2 Source Select'
numid=30,iface=MIXER,name='SAI2 Transmit SDO3 Source Select'
numid=3,iface=MIXER,name='SAI2 Transmit SDOx Select'
numid=1,iface=MIXER,name='SAI2 Transmit Start Mode Sel'
numid=35,iface=PCM,name='SAI2 PCM Read Wait Time MS'
numid=36,iface=PCM,name='SAI2 PCM Write Wait Time MS'
2.3.1.10.1 Выбор тракта: path sel

SAI передаёт данные по PATH0–3: при одной линии используется PATH0, при двух — PATH0/1 и так далее.

Между PATHx и SDx поддерживается полное переназначение. Выбирайте SDIx/SDOx для гибкой аппаратной маршрутизации.

numid=29,iface=MIXER,name='SAI2 Receive PATH0 Source Select'
numid=28,iface=MIXER,name='SAI2 Receive PATH1 Source Select'
numid=27,iface=MIXER,name='SAI2 Receive PATH2 Source Select'
numid=26,iface=MIXER,name='SAI2 Receive PATH3 Source Select'
numid=33,iface=MIXER,name='SAI2 Transmit SDO0 Source Select'
numid=32,iface=MIXER,name='SAI2 Transmit SDO1 Source Select'
numid=31,iface=MIXER,name='SAI2 Transmit SDO2 Source Select'
numid=30,iface=MIXER,name='SAI2 Transmit SDO3 Source Select'

Пример: вывод SAI2 I2S, 4 канала, через SDO2/3.

# amixer cset iface=MIXER,name='SAI2 Transmit SDO2 Source Select' "From PATH0"
numid=31,iface=MIXER,name='SAI2 Transmit SDO2 Source Select'
  ; type=ENUMERATED,access=rw------,values=1,items=4
  ; Item #0 'From PATH0'
  ; Item #1 'From PATH1'
  ; Item #2 'From PATH2'
  ; Item #3 'From PATH3'
  : values=0
# amixer cset iface=MIXER,name='SAI2 Transmit SDO3 Source Select' "From PATH1"
numid=30,iface=MIXER,name='SAI2 Transmit SDO3 Source Select'
  ; type=ENUMERATED,access=rw------,values=1,items=4
  ; Item #0 'From PATH0'
  ; Item #1 'From PATH1'
  ; Item #2 'From PATH2'
  ; Item #3 'From PATH3'
  : values=1

Пример: ввод SAI2 I2S, 2 канала, через SDI3.

# amixer cset iface=MIXER,name='SAI2 Receive PATH0 Source Select' "From SDI3"
numid=29,iface=MIXER,name='SAI2 Receive PATH0 Source Select'
  ; type=ENUMERATED,access=rw------,values=1,items=4
  ; Item #0 'From SDI0'
  ; Item #1 'From SDI1'
  ; Item #2 'From SDI2'
  ; Item #3 'From SDI3'
  : values=3
2.3.1.10.2 Выбор числа линий: lanes sel

Выберите N линий SDO и SDI. В исходном режиме Auto для I2S автоматически включается одна линия на два канала, а для TDM — только одна линия. Для многолинейного TDM задайте число линий до запуска контроллера.

numid=4,iface=MIXER,name='SAI2 Receive SDIx Select'
numid=3,iface=MIXER,name='SAI2 Transmit SDOx Select'

Пример: TDM-TX — 2 линии, TDM-RX — 4 линии.

# amixer -c 0 cset iface=MIXER,name='SAI2 Transmit SDOx Select' "SDOx2"
numid=3,iface=MIXER,name='SAI2 Transmit SDOx Select'
  ; type=ENUMERATED,access=rw------,values=1,items=5
  ; Item #0 'Auto'
  ; Item #1 'SDOx1'
  ; Item #2 'SDOx2'
  ; Item #3 'SDOx3'
  ; Item #4 'SDOx4'
  : values=2
# amixer -c 0 cset iface=MIXER,name='SAI2 Receive SDIx Select' "SDIx4"
numid=4,iface=MIXER,name='SAI2 Receive SDIx Select'
  ; type=ENUMERATED,access=rw------,values=1,items=5
  ; Item #0 'Auto'
  ; Item #1 'SDIx1'
  ; Item #2 'SDIx2'
  ; Item #3 'SDIx3'
  ; Item #4 'SDIx4'
  : values=4
2.3.1.10.3 Выбор цифрового возврата: loopback sel

Поддерживается цифровая петля на уровне линий: источником SDIx выбирается SDOx. Внешние соединения не нужны.

numid=19,iface=MIXER,name='SAI2 SDI0 Loopback Src Select'
numid=23,iface=MIXER,name='SAI2 SDI0 Loopback Switch'
numid=18,iface=MIXER,name='SAI2 SDI1 Loopback Src Select'
numid=22,iface=MIXER,name='SAI2 SDI1 Loopback Switch'
numid=17,iface=MIXER,name='SAI2 SDI2 Loopback Src Select'
numid=21,iface=MIXER,name='SAI2 SDI2 Loopback Switch'
numid=16,iface=MIXER,name='SAI2 SDI3 Loopback Src Select'
numid=20,iface=MIXER,name='SAI2 SDI3 Loopback Switch'

Пример: источником возврата SDI1 служит SDO3.

# amixer -c 0 cset iface=MIXER,name='SAI2 SDI0 Loopback Src Select' "From SDO3"
numid=19,iface=MIXER,name='SAI2 SDI0 Loopback Src Select'
  ; type=ENUMERATED,access=rw------,values=1,items=4
  ; Item #0 'From SDO0'
  ; Item #1 'From SDO1'
  ; Item #2 'From SDO2'
  ; Item #3 'From SDO3'
  : values=3

Начиная с SAI-V3 поддерживается I2S-комбинация «1 микрофон + 1 опорный канал». Совместимые микросхемы указаны в таблице SAI.

numid=11,iface=MIXER,name='SAI2 SDI0 Loopback I2S LR Channel Sel'
numid=15,iface=MIXER,name='SAI2 SDI0 Loopback I2S LR Switch'
numid=10,iface=MIXER,name='SAI2 SDI1 Loopback I2S LR Channel Sel'
numid=14,iface=MIXER,name='SAI2 SDI1 Loopback I2S LR Switch'
numid=9,iface=MIXER,name='SAI2 SDI2 Loopback I2S LR Channel Sel'
numid=13,iface=MIXER,name='SAI2 SDI2 Loopback I2S LR Switch'
numid=8,iface=MIXER,name='SAI2 SDI3 Loopback I2S LR Channel Sel'
numid=12,iface=MIXER,name='SAI2 SDI3 Loopback I2S LR Switch'

Пример: левый I2S-канал — микрофон, правый — цифровой возврат.

# amixer -c 0 cset iface=MIXER,name='SAI2 SDI0 Loopback I2S LR Channel Sel' "L:M IC R:LP"
numid=11,iface=MIXER,name='SAI2 SDI0 Loopback I2S LR Channel Sel'
  ; type=ENUMERATED,access=rw------,values=1,items=2
  ; Item #0 'L:MIC R:LP'
  ; Item #1 'L:LP R:MIC'
  : values=0

2.3.2 ASRC

ASRC включается в аудиопоток через драйвер multicodec.

2.3.2.1 Настройка звуковой карты
  1. Включите параметры CONFIG.
CONFIG_SND_SOC_ROCKCHIP_ASRC=y
  1. После успешной настройки создаются два устройства. Пример для карты 0:
Устройство звуковой карты Описание
hw:0,0 Без ASRC
hw:0,1 С ASRC

Пример 1: SAI (ведомый) → ASRC → MEM.

sai0-asrc-sound {
    compatible = "rockchip,multicodecs-card";
    rockchip,card-name = "rockchip,sai0-asrc";
    rockchip,mclk-fs = <256>;
    rockchip,format = "i2s";
    rockchip,cpu = <&sai0>;
    rockchip,asrc = <&asrc0>;
    rockchip,codec = <&dummy_codec>;
    rockchip,bitclock-master = <&dummy_codec>;
    rockchip,frame-master = <&dummy_codec>;
    rockchip,audio-routing =
        "Dummy Playback", "SAI0 Playback",
        "SAI0 Capture", "Dummy Capture",
        "SAI0 Playback", "ASRC0 Playback",
        "ASRC0 Capture", "SAI0 Capture";
};

Пример 2: SPDIFRX → ASRC → MEM.

spdifrx0-asrc-sound {
    compatible = "rockchip,multicodecs-card";
    rockchip,card-name = "spdifrx0-asrc";
    rockchip,cpu = <&spdif_rx0>;
    rockchip,asrc = <&asrc0>;
    rockchip,codec = <&dummy_codec>;
    rockchip,audio-routing =
        "Dummy Capture", "Dummy Capture",
        "ASRC0 Capture", "SPDIF_RX0 Capture";
};
2.3.2.2 Настройка ресемплинга

Установите частоту ресемплинга 48 кГц:

amixer -c 0 sset 'ASRC0 SET RESAMPLE RATE' 48000
2.3.2.3 Источники тактирования

Задайте отслеживаемые источники SRC/DST для ASRC. Допускается любая комбинация локальных и внешних источников.

Пример 1: SRC поступает от SAI0, DST — от ASRC. ASRC компенсирует рассогласование SAI0 с локальным тактированием.

amixer -c 0 sset 'ASRC0 RX LINK DAI Select' 'sai0'
amixer -c 0 sset 'ASRC0 TX LINK DAI Select' 'asrc0'

Пример 2: SRC поступает от SAI0, DST — от SAI2. ASRC компенсирует рассогласование между SAI0 и SAI2.

amixer -c 0 sset 'ASRC0 RX LINK DAI Select' 'sai0'
amixer -c 0 sset 'ASRC0 TX LINK DAI Select' 'sai2'
2.3.2.4 Запись
amixer -c 0 sset 'ASRC0 SET RESAMPLE RATE' 48000
amixer -c 0 sset 'ASRC0 RX LINK DAI Select' 'sai0'
amixer -c 0 sset 'ASRC0 TX LINK DAI Select' 'asrc0'
arecord -D hw:0,1 --period-size=1024 --buffer-size=4096 -r 48000 -c 2 -f s16_le r.wav
2.3.2.5 Воспроизведение
amixer -c 0 sset 'ASRC0 SET RESAMPLE RATE' 48000
amixer -c 0 sset 'ASRC0 RX LINK DAI Select' 'asrc0'
amixer -c 0 sset 'ASRC0 TX LINK DAI Select' 'sai0'
aplay -D hw:0,1 --period-size=1024 --buffer-size=4096 r.wav

2.3.3 I2S

2.3.3.1 Формат протокола

Machine-драйвер разбирает DTS и вызывает set_fmt для установки формата контроллера. Для Simple Card см. соответствующий раздел.

2.3.3.2 Режим ведущего/ведомого

Machine-драйвер разбирает DTS и вызывает set_fmt для выбора ведущего/ведомого режима. Для Simple Card см. соответствующий раздел.

2.3.3.3 Инверсия фазы тактирования

Machine-драйвер разбирает DTS и вызывает set_fmt для настройки инверсии тактовых сигналов. Для Simple Card см. соответствующий раздел.

2.3.3.4 Настройка bclk-fs
Свойство Значение Описание
rockchip,bclk-fs int По умолчанию BCLK равен 64 частотам дискретизации

Пример: BCLK равен 32 частотам дискретизации.

&i2s0 {
        rockchip,bclk-fs = <32>;
};
2.3.3.5 Высокоточное тактирование
Свойство Значение Описание
rockchip,mclk-calibrate boolean Высокоточное тактирование и компенсация частоты; см. раздел компенсации аудиотактирования
2.3.3.6 Время ожидания

Параметр задаёт тайм-аут ведомого режима. После потери внешнего тактового сигнала ASoC по умолчанию ждёт 10 с. Его можно сократить; рекомендуется значение не меньше длительности буфера.

Свойство Значение Описание
rockchip,i2s-tx-wait-time-ms int По умолчанию 10 с
rockchip,i2s-rx-wait-time-ms int По умолчанию 10 с

Пример: буфер 40 мс, ожидание 50 мс.

&i2s0 {
        rockchip,i2s-tx-wait-time-ms = <50>;
        rockchip,i2s-rx-wait-time-ms = <50>;
};
2.3.3.7 Прочие параметры
Свойство Значение Описание
rockchip,no-dmaengine boolean Для Multi-DAI; см. драйвер Combo DAI
rockchip,playback-only boolean Только воспроизведение
rockchip,capture-only boolean Только запись
2.3.3.8 mclkout / mclkin

mclkout и mclkin используют общие выводы. Ниже рассмотрены сочетания с ведущим/ведомым режимом I2S. Если MCLK периферии не нужен, его можно не подключать.

i2s mclk Описание
master out SoC выдаёт тактирование периферии
master in I2S использует внешний MCLKIN; типовой сценарий — единый источник аудиотактирования
slave out Периферия ведущая; MCLK предоставляет SoC
slave in Нет сценария применения

Пример: mclkout.

rk817_codec: codec {
        #sound-dai-cells = <0>;
        compatible = "rockchip,rk817-codec";
        clocks = <&mclkout_i2s0>;
        clock-names = "mclk";
        assigned-clocks = <&mclkout_i2s0>;
        assigned-clock-rates = <12288000>;
        pinctrl-names = "default";
        pinctrl-0 = <&i2s0m0_mclk>;
        hp-volume = <20>;
        spk-volume = <3>;
        mic-in-differential;
        status = "okay";
};

Пример: mclkin.

&i2s3_2ch {
        assigned-clocks = <&cru CLK_I2S3_2CH>;
        assigned-clock-parents = <&mclkin_i2s3>;
        pinctrl-0 = <&i2s3_sdi
                     &i2s3_sdo
                     &i2s3_lrck
                     &i2s3_sclk
                     &i2s3_mclk>;
};
&mclkin_i2s3 {
        clock-frequency = <24576000>;
        status = "okay";
};

Подробности: kernel/Documentation/devicetree/bindings/sound/rockchip-i2s.txt.

2.3.4 I2S-TDM

Помимо функций I2S контроллер I2S-TDM предоставляет следующие возможности.

2.3.4.1 Общие тактовые сигналы TX/RX
Свойство Значение Описание
rockchip,clk-trcm 0 TX/RX независимы и используют собственные тактовые сигналы; на IO две группы сигналов
rockchip,clk-trcm 1 TX/RX синхронны и используют общее тактирование TX; на IO только сигналы TX
rockchip,clk-trcm 2 TX/RX синхронны и используют общее тактирование RX; на IO только сигналы RX

Пример: использование общего тактирования TX.

&i2s0 {
        rockchip,clk-trcm = <1>;
};
2.3.4.2 Переназначение линий данных

Аппаратно можно подключаться к любому SDOx/SDIx; программно задаётся соответствие PATHx и SDOx/SDIx.

Свойство Значение Описание
rockchip,i2s-tx-route <int int int int> Порядок по умолчанию: SDO0 | SDO1 | SDO2 | SDO3
rockchip,i2s-rx-route <int int int int> Порядок по умолчанию: SDI0| SDI1 | SDI2 | SDI3

Пример: порядок каналов воспроизведения SDO3 | SDO2 | SDO1 | SDO0.

&i2s0 {
        rockchip,i2s-tx-route = <3 2 1 0>;
};
2.3.4.3 Полукадровый режим TDM
Свойство Значение Описание
rockchip,tdm-fsync-half-frame boolean В TDM I2S поддерживаются полукадровый и длиннокадровый форматы кадрового тактирования; по умолчанию длиннокадровый.

Пример: формат половины кадра.

&i2s0 {
        rockchip,tdm-fsync-half-frame;
};
2.3.4.4 Настройка слотов TDM

Драйвер реализует set_tdm_slot. Machine-драйвер читает свойства DTS и вызывает этот API для настройки слотов контроллера. Для Simple Card см. соответствующий раздел.

2.3.4.5 mclkout / mclkin

mclkout и mclkin используют общие выводы. Ниже показаны сочетания с ведущим/ведомым режимом I2S-TDM. Если периферии MCLK не нужен, соединение можно опустить.

i2stdm mclk Описание
master out SoC выдаёт тактирование периферии
master in I2S-TDM использует внешний MCLKIN; типовой сценарий — единый источник аудиотактирования
slave out Периферия ведущая; MCLK предоставляет SoC
slave in Нет сценария применения

Пример: mclkout.

rk817_codec: codec {
        #sound-dai-cells = <0>;
        compatible = "rockchip,rk817-codec";
        clocks = <&mclkout_i2s0>;
        clock-names = "mclk";
        assigned-clocks = <&mclkout_i2s0>;
        assigned-clock-rates = <12288000>;
        pinctrl-names = "default";
        pinctrl-0 = <&i2s0m0_mclk>;
        hp-volume = <20>;
        spk-volume = <3>;
        mic-in-differential;
        status = "okay";
};

Пример: mclkin.

&i2s0_8ch {
        assigned-clocks = <&cru CLK_I2S0_8CH_TX>, <&cru CLK_I2S0_8CH_RX>;
        assigned-clock-parents = <&mclkin_i2s0>, <&mclkin_i2s0>;
        pinctrl-0 = <&i2s0_sdi0
                     &i2s0_sdo0
                     &i2s0_lrck
                     &i2s0_sclk
                     &i2s0_mclk>;
};
&mclkin_i2s0 {
        clock-frequency = <24576000>;
        status = "okay";
};

Подробности: kernel/Documentation/devicetree/bindings/sound/rockchip,i2s-tdm.txt.

2.3.5 PDM

2.3.5.1 Переназначение линий данных

Подключение возможно к любому SDIx; программно задаётся соответствие между PATHx и SDIx.

Свойство Значение Описание
rockchip,path-map <int int int int> Порядок по умолчанию: SDI0 | SDI1 | SDI2 | SDI3

Пример: порядок каналов записи SDI3 | SDI2 | SDI1 | SDI0.

&pdm_8ch {
        rockchip,path-map = <3 2 1 0>;
};
2.3.5.2 Высокоточное тактирование
Свойство Значение Описание
rockchip,mclk-calibrate boolean Высокоточное тактирование и компенсация частоты; см. раздел компенсации аудиотактирования
2.3.5.3 Прочие параметры
Свойство Значение Описание
rockchip,no-dmaengine boolean Для Multi-DAI; см. драйвер Combo DAI

Подробности: kernel/Documentation/devicetree/bindings/sound/rockchip,pdm.txt.

2.3.6 DCODEC

2.3.6.1 Синхронное тактирование
Свойство Значение Описание
rockchip,clk-sync-mode boolean По умолчанию асинхронный режим: тактирование АЦП и ЦАП независимо.

Пример: синхронный режим с общим тактированием АЦП.

&dig_acodec {
        rockchip,clk-sync-mode;
};
2.3.6.2 Режим выхода DSM
Свойство Значение Описание
rockchip,pwm-output-mode boolean Непосредственное управление PA через RC-цепь

Пример: DSM PWM и переключение IOMUX на дифференциальный PWM-выход.

&dig_acodec {
        rockchip,pwm-output-mode;
        pinctrl-names = "default";
        pinctrl-0 = <&audiopwmoutdiff_pins>;
};

Аппаратная схема приведена ниже; в исходном тексте ссылка обозначена как рисунок 2-2.

Иллюстрация из оригинала: 2.3.6.2 Режим выхода DSM (p. 44)

Рисунок 2-6. Пример выхода DSM PWM

Дополнительные сведения:

kernel/Documentation/devicetree/bindings/sound/rockchip,codec-digital.txt

2.3.7 VAD

2.3.7.1 Источник аудиоданных
Свойство Значение Описание
rockchip,audio-src phandle Источник аудио для обнаружения речи

Источник для обнаружения речи — DAI. Доступные источники зависят от микросхемы и перечислены в таблице.

SoC Источник аудио
RK1808 I2S0, I2S1, PDM
RK3308 I2S_8CH_0, I2S_8CH_1, I2S_8CH_2, I2S_8CH_3, PDM_8CH
RK3568/RK3566 I2S1_8CH, I2S2_2CH, I2S3_2CH

Пример: VAD использует PDM_8CH на RK3308.

&vad {
        rockchip,audio-src = <&pdm_8ch>;
};
2.3.7.2 Канал обнаружения
Свойство Значение Описание
rockchip,det-channel int Канал обнаружения, по умолчанию 0

Пример: VAD анализирует канал 2 на RK3308.

&vad {
        rockchip,det-channel = <2>;
};
2.3.7.3 Режим хранения данных
Свойство Значение Описание
rockchip,mode 0 Буферизация начинается только после обнаружения речи VAD.
rockchip,mode 1 Буферизация начинается сразу после включения VAD.
rockchip,mode 2 Не буферизовать аудиоданные.

Пример: режим 1 VAD на RK3308.

&vad {
        rockchip,mode = <1>;
};

Примечание:

Для передачи полных аудиоданных приложению ASR рекомендуется Mode 1. Данные накапливаются в кольцевом буфере SRAM. После пробуждения VAD содержимое SRAM добавляется в аудиопоток; для приложения это прозрачно.

2.3.7.4 Размер буфера
Свойство Значение Описание
rockchip,buffer-time-ms int Размер буфера VAD: частота дискретизации × разрядность × число каналов × время. Для байтов учитывайте перевод бит в байты.

Пример исходного документа: буфер 100 мс, для 16 кГц, 16 бит и 8 каналов указан размер 204800 байт. Это числовое соответствие требует проверки; см. редакционные замечания.

&vad {
        rockchip,buffer-time-ms = <100>;
};

Увеличение буфера повышает задержку ASR, а объём SRAM ограничен. Выбирайте размер, обеспечивающий целостность данных на интервале от пробуждения до начала обработки приложением. Если этот интервал слишком велик, оптимизируйте его.

Подробности: kernel/Documentation/devicetree/bindings/sound/rockchip,vad.txt.

2.4 Разработка драйвера Combo DAI

2.4.1 Настройка дочерних DAI

Свойство Значение Описание
dais <phandle>… Дочерние DAI объединяются в Combo DAI. Свойство rockchip,no-dmaengine отключает привязанный DMA engine дочернего DAI; регистрацию и привязку централизованно выполняет Combo DAI.

Пример: объединение i2s_8ch_2 и pdm_8ch в Combo DAI.

&i2s_8ch_2 {
        status = "okay";
        rockchip,no-dmaengine;
};
&pdm_8ch {
        status = "okay";
        rockchip,no-dmaengine;
};
&multi-dais {
        dais = <&i2s_8ch_2>, <&pdm_8ch>;
};

2.4.2 Распределение каналов

Свойство Значение Описание
capture,channel-mapping <int …> Число каналов записи каждого объединяемого дочернего DAI
playback,channel-mapping <int …> Число каналов воспроизведения каждого объединяемого дочернего DAI

Пример: стереовоспроизведение и восьмиканальная запись — шесть микрофонов плюс два опорных канала.

&multi-dais {
        dais = <&i2s_8ch_2>, <&pdm_8ch>;
        playback,channel-mapping = <2 0>;
        capture,channel-mapping = <2 6>;
};

2.4.3 Режим ведущего/ведомого

Свойство Значение Описание
bitclock-master <int …> Источник битового тактирования: 1 означает ведущий режим, устройство выдаёт тактирование.
frame-master <int …> Источник кадрового тактирования: 1 означает ведущий режим, устройство выдаёт тактирование.

Пример 1: i2s_8ch_2 и pdm_8ch образуют восьмиканальную карту записи с цифровым возвратом и массивом микрофонов. i2s_8ch_2 может быть ведущим или ведомым; здесь он ведущий. PDM поддерживает только ведущий режим.

&multi-dais {
        dais = <&i2s_8ch_2>, <&pdm_8ch>;
        capture,channel-mapping = <2 6>;
        playback,channel-mapping = <2 0>;
        bitclock-master = <1 1>;
        frame-master = <1 1>;
};

Пример 2: два I2S образуют 16 каналов; один ведущий, другой ведомый. Аппаратно соедините источник тактирования с каждым ведомым DAI.

&multi-dais {
        dais = <&i2s_8ch_0>, <&i2s_8ch_1>;
        capture,channel-mapping = <8 8>;
        playback,channel-mapping = <8 8>;
        bitclock-master = <1 0>;
        frame-master = <1 0>;
};

Пример 3: два I2S образуют 16 каналов, оба ведомые; тактирование предоставляет ведущий кодек.

&multi-dais {
        dais = <&i2s_8ch_0>, <&i2s_8ch_1>;
        capture,channel-mapping = <8 8>;
        playback,channel-mapping = <8 8>;
        bitclock-master = <0 0>;
        frame-master = <0 0>;
};

2.4.4 Инверсия тактовых сигналов

Свойство Значение Описание
bitclock-inversion <int …> 1 — инверсия битового тактирования
frame-inversion <int …> 1 — инверсия кадрового тактирования

Пример: инверсия тактирования всех дочерних DAI.

&multi-dais {
        dais = <&i2s_8ch_0>, <&i2s_8ch_1>;
        bitclock-inversion = <1 1>;
        frame-inversion = <1 1>;
};

2.4.5 Примеры

Пример 1: RK3308, микрофонный массив PDM + стереозапись + стереовоспроизведение + обнаружение речи VAD.

multi_dais: multi-dais {
        status = "okay";
        compatible = "rockchip,multi-dais";
        dais = <&i2s_8ch_2>, <&pdm_8ch>;
        capture,channel-mapping = <2 6>;
        playback,channel-mapping = <2 0>;
        bitclock-master = <1 1>;
        frame-master = <1 1>;
        bitclock-inversion = <0 0>;
        frame-inversion = <0 0>;
        rockchip,grf = <&grf>;
};
&i2s_8ch_2 {
        status = "okay";
        rockchip,no-dmaengine;
};
&pdm_8ch {
        status = "okay";
        rockchip,no-dmaengine;
};
vad-sound {
        status = "okay";
        compatible = "rockchip,multicodecs-card";
        rockchip,card-name = "rockchip,rk3308-vad";
        rockchip,cpu = <&multi_dais>;
        rockchip,codec = <&acodec>, <&vad>;
};

Пример 2: SoundBar на RK3308, объединение I2S_8CH_0 и I2S_8CH_1 для 16-канального выхода.

&i2s_8ch_0 {
        #sound-dai-cells = <0>;
        rockchip,no-dmaengine;
};
&i2s_8ch_1 {
        #sound-dai-cells = <0>;
        rockchip,no-dmaengine;
        pinctrl-names = "default";
        pinctrl-0 = <&i2s_8ch_1_m0_sdo0
                     &i2s_8ch_1_m0_sdo1_sdi3
                     &i2s_8ch_1_m0_sdo2_sdi2
                     &i2s_8ch_1_m0_sdo3_sdi1
                     &i2s_8ch_1_m0_sdi0>;
};
i2s_16ch_dais: i2s-16ch-dais {
        compatible = "rockchip,rk3308-multi-dais", "rockchip,multi-dais";
        dais = <&i2s_8ch_0>, <&i2s_8ch_1>;
        capture,channel-mapping = <8 8>;
        playback,channel-mapping = <8 8>;
        bitclock-master = <1 0>;
        frame-master = <1 0>;
        rockchip,grf = <&grf>;
};

Подробности: kernel/Documentation/devicetree/bindings/sound/rockchip,multidais.txt.

2.5 Разработка драйвера CODEC

См. документацию звуковой подсистемы Linux: https://www.kernel.org/doc/html/latest/sound/.

2.6 Разработка machine-драйвера

В этом разделе добавление звуковой карты разобрано на практических примерах.

2.6.1 Драйвер Simple Card

Simple Card — универсальный machine-драйвер ASoC, подходящий для большинства стандартных звуковых карт.

2.6.1.1 Формат протокола
Свойство Значение Описание
simple-audio-card,format string Формат протокола
Формат Описание
i2s Стандартный I2S
right_j I2S с правым выравниванием
left_j I2S с левым выравниванием
dsp_a PCM с задержкой на 1 бит
dsp_b PCM без задержки
pdm Формат PDM

Пример: I2S с левым выравниванием.

audiopwmout_diff: audiopwmout-diff {
        compatible = "simple-audio-card";
        ....
        simple-audio-card,format = "left_j";
        simple-audio-card,cpu {
                sound-dai = <&i2s3_2ch>;
        };
        master: simple-audio-card,codec {
                sound-dai = <&dig_acodec>;
        };
};
2.6.1.2 Настройка mclk-fs
Свойство Значение Описание
simple-audio-card,mclk-fs int По умолчанию MCLK равен 256 частотам дискретизации

Пример: MCLK равен 512 частотам дискретизации.

audiopwmout_diff: audiopwmout-diff {
        compatible = "simple-audio-card";
        ....
        simple-audio-card,mclk-fs = <512>;
        simple-audio-card,cpu {
                sound-dai = <&i2s3_2ch>;
        };
        master: simple-audio-card,codec {
                sound-dai = <&dig_acodec>;
        };
};
2.6.1.3 Режим ведущего/ведомого
Свойство Значение Описание
simple-audio-card,bitclock-master phandle Источник битового тактирования, по умолчанию DAI
simple-audio-card,frame-master phandle Источник кадрового тактирования, по умолчанию DAI

Пример: DAI ведомый, CODEC ведущий.

audiopwmout_diff: audiopwmout-diff {
        compatible = "simple-audio-card";
        ....
        simple-audio-card,bitclock-master = <&master>;
        simple-audio-card,frame-master = <&master>;
        simple-audio-card,cpu {
                sound-dai = <&i2s3_2ch>;
        };
        master: simple-audio-card,codec {
                sound-dai = <&dig_acodec>;
        };
};
2.6.1.4 Инверсия тактовых сигналов
Свойство Значение Описание
simple-audio-card,bitclock-inversion boolean Инверсия битового тактирования
simple-audio-card,frame-inversion boolean Инверсия кадрового тактирования

Пример: инверсия BCLK и LRCK.

audiopwmout_diff: audiopwmout-diff {
        compatible = "simple-audio-card";
        ...
        simple-audio-card,bitclock-inversion;
        simple-audio-card,frame-inversion;
        simple-audio-card,cpu {
                sound-dai = <&i2s3_2ch>;
        };
        simple-audio-card,codec {
                sound-dai = <&dig_acodec>;
        };
};
2.6.1.5 Слоты TDM
Свойство Значение Описание
dai-tdm-slot-num int Число слотов
dai-tdm-slot-width int Разрядность слота

Пример: разрядность слота 32 бита, 8 слотов.

i2s-dmic-array {
        compatible = "simple-audio-card";
        ...
        simple-audio-card,mclk-fs = <256>;
        simple-audio-card,cpu {
                sound-dai = <&i2s_8ch_0>;
                dai-tdm-slot-num = <8>;
                dai-tdm-slot-width = <32>;
        };
        simple-audio-card,codec {
                sound-dai = <&dummy_codec>;
        };
};

Примечание: mclk-fs равно [число слотов] × [разрядность слота] либо чётному кратному этого произведения.

Подробности: kernel/Documentation/devicetree/bindings/sound/simple-card.txt.

2.6.1.6 Пример добавления звуковой карты
  1. Перенесите или напишите драйвер кодека.
sound/soc/codecs/Kconfig
sound/soc/codecs/Makefile
sound/soc/codecs/tas571x.c
sound/soc/codecs/tas571x.h
  1. Включите параметры CONFIG.
CONFIG_SND_SIMPLE_CARD
CONFIG_SND_SOC_ROCKCHIP_I2S
CONFIG_SND_SOC_ROCKCHIP_I2S_TDM
CONFIG_SND_SOC_TAS571X
  1. Добавьте узел звуковой карты в DTS.

Включите I2S-узел согласно аппаратному подключению.

&i2s_8ch_1 {
        status = "okay";
        #sound-dai-cells = <0>;
        pinctrl-names = "default";
        pinctrl-0 = <&i2s_8ch_1_m0_sclktx
                     &i2s_8ch_1_m0_lrcktx
                     &i2s_8ch_1_m0_sdo0
                     &i2s_8ch_1_m0_mclk>;
};

Добавьте узел кодека на соответствующую шину I2C или SPI.

&i2c1 {
        clock-frequency = <400000>;
        status = "okay";
        tas5731: tas5731@1a {
                #sound-dai-cells = <0>;
                compatible = "ti,tas5731";
                reg = <0x1a>;
                clocks = <&cru SCLK_I2S1_8CH_TX_OUT>;
                clock-names = "mclk";
                pinctrl-names = "default";
                pinctrl-0 = <&i2s_8ch_1_m0_mclk>;
                pdn-gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>;
                reset-gpios = <&gpio1 RK_PA1 GPIO_ACTIVE_LOW>;
        };
};

Добавьте и включите узел звуковой карты.

tas5731_sound: tas5731-sound {
        status = "okay";
        compatible = "simple-audio-card";
        simple-audio-card,format = "i2s";
        simple-audio-card,name = "rockchip,tas5731";
        simple-audio-card,mclk-fs = <256>;
        simple-audio-card,cpu {
                sound-dai = <&i2s_8ch_1>;
        };
        simple-audio-card,codec {
                sound-dai = <&tas5731>;
        };
};

Убедитесь, что карта успешно создана.

# cat /proc/asound/cards
 0 [rockchiptas5731]: rockchip_tas5731 - rockchip,tas5731

Примечание:

Для MCLK действует правило «кто использует, тот запрашивает». Если кодеку нужен внешний MCLK, его драйвер должен запрашивать и управлять этим тактированием. В примере источником служит SCLK_I2S1_8CH_TX_OUT RK3308.

2.6.2 Machine-драйвер Multi Codecs

Если Simple Card недостаточно, нужен соответствующий machine-драйвер. RK Multi Codecs используется, когда один DAI или Combo DAI связан с несколькими кодеками, как на рисунке 2-3.

Иллюстрация из оригинала: 2.6.2 Machine-драйвер Multi Codecs (p. 55)

Рисунок 2-3. Machine-драйвер Multi Codecs

2.6.2.1 Настройка DAI и кодеков
Свойство Значение Описание
rockchip,cpu phandle Устройство DAI
rockchip,codec phandle… Связанные кодеки

Пример: i2s0_8ch используется одновременно кодеком и VAD.

&sound {
        compatible = "rockchip,multicodecs-card";
        rockchip,cpu = <&i2s0_8ch>;
        rockchip,codec = <&codec>, <&vad>;
};
2.6.2.2 Формат протокола
Свойство Значение Описание
rockchip,format string Формат протокола
Формат Описание
i2s Стандартный I2S
right_j I2S с правым выравниванием
left_j I2S с левым выравниванием
dsp_a PCM с задержкой на 1 бит
dsp_b PCM без задержки
pdm pdm

Пример: I2S с левым выравниванием.

&sound {
        rockchip,format = "left_j";
};
2.6.2.3 Настройка mclk-fs
Свойство Значение Описание
rockchip,mclk-fs int По умолчанию MCLK равен 256 частотам дискретизации

Пример: MCLK равен 512 частотам дискретизации.

&sound {
        rockchip,mclk-fs = <512>;
};
2.6.2.4 Режим ведущего/ведомого
Свойство Значение Описание
rockchip,frame-master phandle Источник битового тактирования, по умолчанию DAI
rockchip,bitclock-master phandle Источник кадрового тактирования, по умолчанию DAI

Пример: DAI ведомый, CODEC ведущий.

&sound {
        compatible = "rockchip,multicodecs-card";
        rockchip,frame-master = <&codec>;
        rockchip,bitclock-master = <&codec>;
        rockchip,cpu = <&i2s0_8ch>;
        rockchip,codec = <&codec>, <&vad>;
};
2.6.2.5 Инверсия тактовых сигналов
Свойство Значение Описание
rockchip,bitclock-inversion boolean Инверсия битового тактирования
rockchip,frame-inversion boolean Инверсия кадрового тактирования

Пример: BCLK и LRCK инвертированы.

&sound {
        compatible = "rockchip,multicodecs-card";
        rockchip,bitclock-inversion;
        rockchip,frame-inversion;
        rockchip,cpu = <&i2s0_8ch>;
        rockchip,codec = <&codec>, <&vad>;
};
2.6.2.6 Настройка wait-card-locked
Свойство Значение Описание
rockchip,wait-card-locked int Перед регистрацией дождаться указанного ID карты, чтобы текущая карта получила следующий номер

Пример: bluetooth-sound должен зарегистрироваться как card1. Перед его регистрацией необходимо дождаться card0.

bluetooth_sound: bluetooth-sound {
    status = "disabled";
    compatible = "rockchip,multicodecs-card";
    rockchip,card-name = "rockchip,rk3308-pcm";
    rockchip,mclk-fs = <128>;
    rockchip,cpu = <&i2s_2ch_0>;
    rockchip,codec = <&dummy_codec>;
    rockchip,format = "dsp_b";
    rockchip,bitclock-inversion = <0>;
    rockchip,wait-card-locked = <0>;
};
2.6.2.7 Прочие параметры
Свойство Значение Описание
hp-det-gpio phandle Вывод обнаружения наушников
spk-con-gpio phandle Вывод управления усилителем динамика
hp-con-gpio phandle Вывод управления наушниками
io-channels phandle Канал АЦП для различения трёх- и четырёхконтактных наушников
poll-interval int Период опроса АЦП, по умолчанию 100 мс
keyup-threshold-microvolt int Напряжение кнопки на АЦП
play-pause-key phandle Кнопка воспроизведения/паузы
rockchip,audio-routing string Маршрутизация звуковой карты

Пример:

ADC3 различает трёх- и четырёхконтактные наушники, а также обрабатывает кнопки воспроизведения/паузы на кабеле.

Headphone соответствует LROUT1 es8388 и управляется Headphone Power на gpio1_d2.

Speaker соответствует LROUT2 es8388 и управляется Speaker Power на gpio1_d3.

LINPUT es8388 соответствует Main Mic, RINPUT — Headset Mic.

es8388_sound: es8388-sound {
    status = "okay";
    compatible = "rockchip,multicodecs-card";
    rockchip,card-name = "rockchip-es8388";
    hp-det-gpio = <&gpio1 RK_PD5 GPIO_ACTIVE_LOW>;
    io-channels = <&saradc 3>;
    io-channel-names = "adc-detect";
    keyup-threshold-microvolt = <1800000>;
    poll-interval = <100>;
    spk-con-gpio = <&gpio1 RK_PD3 GPIO_ACTIVE_HIGH>;
    hp-con-gpio = <&gpio1 RK_PD2 GPIO_ACTIVE_HIGH>;
    rockchip,format = "i2s";
    rockchip,mclk-fs = <256>;
    rockchip,cpu = <&i2s0_8ch>;
    rockchip,codec = <&es8388>;
    rockchip,audio-routing =
        "Headphone", "LOUT1",
        "Headphone", "ROUT1",
        "Speaker", "LOUT2",
        "Speaker", "ROUT2",
        "Headphone", "Headphone Power",
        "Headphone", "Headphone Power",
        "Speaker", "Speaker Power",
        "Speaker", "Speaker Power",
        "LINPUT1", "Main Mic",
        "LINPUT2", "Main Mic",
        "RINPUT1", "Headset Mic",
        "RINPUT2", "Headset Mic";
    pinctrl-names = "default";
    pinctrl-0 = <&hp_det>;
    play-pause-key {
        label = "playpause";
        linux,code = <KEY_PLAYPAUSE>;
        press-threshold-microvolt = <2000>;
    };
};

Подробности: kernel/Documentation/devicetree/bindings/sound/rockchip,multicodecs.txt.

2.6.3 HDMI Audio

В RK kernel 4.4 используются две HDMI-подсистемы: собственная RK HDMI и DRM. Им соответствуют две реализации аудио.

Начиная с RK kernel 4.19 используется только стандартная DRM.

Пример 1: настройка аудио RK HDMI на RK3399.

dw_hdmi_audio: dw-hdmi-audio {
        compatible = "rockchip,dw-hdmi-audio";
        #sound-dai-cells = <0>;
};
hdmi_sound: hdmi-sound {
        compatible = "simple-audio-card";
        simple-audio-card,format = "i2s";
        simple-audio-card,mclk-fs = <128>;
        simple-audio-card,name = "rockchip,hdmi";
        simple-audio-card,cpu {
                sound-dai = <&i2s2>;
        };
        simple-audio-card,codec {
                sound-dai = <&dw_hdmi_audio>;
        };
};

Пример 2: настройка аудио DRM HDMI на RK3399.

hdmi: hdmi@ff940000 {
        compatible = "rockchip,rk3399-dw-hdmi";
        ......
        #address-cells = <1>;
        #size-cells = <0>;
        #sound-dai-cells = <0>;
};
hdmi_sound: hdmi-sound {
        compatible = "simple-audio-card";
        simple-audio-card,format = "i2s";
        simple-audio-card,mclk-fs = <128>;
        simple-audio-card,name = "rockchip,hdmi";
        simple-audio-card,cpu {
                sound-dai = <&i2s2>;
        };
        simple-audio-card,codec {
                sound-dai = <&hdmi>;
        };
};

2.7 Компенсация аудиотактирования

Точная подстройка аудиотактирования RK устраняет рассогласование систем с разными источниками частоты — UAC, HDMI IN, Bluetooth voice и других. Диапазон подстройки: ±1000 ppm, то есть миллионных долей.

  1. Включите параметры CONFIG.
CONFIG_ROCKCHIP_CLK_COMPENSATION
  1. Добавьте частоту дробного режима PLL. Подстройка работает только в дробном режиме; частота PLL должна быть чётным кратным MCLK. Далее рассмотрены два типа платформ.

При отдельном аудио-PLL достаточно соблюсти условие чётной кратности. Например, RK3308: VPLL0 = 1179648000 Гц, VPLL1 = 903168000 Гц.

Если PLL общий для аудио и других блоков, оцените влияние подстройки на эти блоки:

a. Допустимо ли изменение ±1000 ppm? Ethernet требует точного тактирования, тогда как видеокодер не предъявляет такого же требования.

b. Если условие a выполнено, выберите подходящую дробную частоту. Например, RV1126 одновременно требует частоту видеокодера около 500 МГц и поддержку аудио 48 кГц. Подходит 491520000 Гц, то есть 491,52 МГц; единица «MHz» в английском оригинале здесь ошибочна.

Пример: перевод CPLL RV1126 на дробную частоту.

diff --git a/drivers/clk/rockchip/clk-rv1126.c b/drivers/clk/rockchip/clk-rv1126.c
index 9ba0bff..1b95aed 100644
--- a/drivers/clk/rockchip/clk-rv1126.c
+++ b/drivers/clk/rockchip/clk-rv1126.c
@@ -74,6 +74,8 @@ static struct rockchip_pll_rate_table rv1126_pll_rates[] = {
        RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
        RK3036_PLL_RATE(504000000, 1, 84, 4, 1, 1, 0),
        RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
+       RK3036_PLL_RATE(496742400, 1, 124, 6, 1, 0, 3113851),
+       RK3036_PLL_RATE(491520000, 1, 40, 2, 1, 0, 16106127),

DTS с частотой 491520000 Гц поддерживает 8, 16, 24, 48, 96 и 192 кГц.

&cru {
        assigned-clocks =
                <&pmucru CLK_RTC32K>, <&pmucru PLL_GPLL>,
                <&pmucru PCLK_PDPMU>, <&cru PLL_CPLL>,
                <&cru PLL_HPLL>, <&cru ARMCLK>,
                <&cru ACLK_PDBUS>, <&cru HCLK_PDBUS>,
                <&cru PCLK_PDBUS>, <&cru ACLK_PDPHP>,
                <&cru HCLK_PDPHP>, <&cru HCLK_PDAUDIO>,
                <&cru HCLK_PDCORE_NIU>;
        assigned-clock-rates =
                <32768>, <1188000000>,
                <100000000>, <491520000>,
                <1400000000>, <600000000>,
                <500000000>, <200000000>,
                <100000000>, <300000000>,
                <200000000>, <150000000>,
                <200000000>;
};
  1. Включите компенсацию DAI и укажите корневой PLL.

Контроллер I2S:

&i2s1_2ch {
        clocks = <&cru MCLK_I2S1>, <&cru HCLK_I2S1>, <&cru PLL_CPLL>;
        clock-names = "i2s_clk", "i2s_hclk", "i2s_clk_root";
        rockchip,mclk-calibrate;
};

Контроллер I2S-TDM:

&i2s0_8ch {
        clocks = <&cru MCLK_I2S0_TX>, <&cru MCLK_I2S0_RX>, <&cru HCLK_I2S0>,
                 <&cru MCLK_I2S0_TX_DIV>, <&cru MCLK_I2S0_RX_DIV>,
                 <&cru PLL_CPLL>, <&cru PLL_CPLL>;
        clock-names = "mclk_tx", "mclk_rx", "hclk",
                      "mclk_tx_src", "mclk_rx_src",
                      "mclk_root0", "mclk_root1";
        rockchip,mclk-calibrate;
};

Контроллер PDM:

&pdm {
        status = "okay";
        clocks = <&cru MCLK_PDM>, <&cru HCLK_PDM>, <&cru PLL_CPLL>;
        clock-names = "pdm_clk", "pdm_hclk", "pdm_clk_root";
        rockchip,mclk-calibrate;
};
  1. Проверка функции.

После включения частоту можно подстраивать через amixer.

Пример: подстройка частоты карты rk809 на RV1126.

# cat /proc/asound/cards
 0 [rockchiprk809co]: rockchip_rk809- - rockchip,rk809-codec
                      rockchip,rk809-codec
# aplay -D hw:0,0 --period-size=1024 --buffer-size=4096 -f dat /dev/zero &
Playing raw data '/dev/zero' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
# cat /sys/kernel/debug/clk/clk_summary | egrep "i2s0|cpll"
pll_cpll                          1        1        0   491519999
  cpll                            6       11        0   491519999
    mclk_i2s0_rx_div              1        1        0    12288000
      mclk_i2s0_rx_mux            1        1        0    12288000
        mclk_i2s0_rx              1        1        0    12288000
      mclk_i2s0_rx_fracdiv        0        0        0    12288000
    mclk_i2s0_tx_div              1        1        0    12288000
      mclk_i2s0_tx_mux            1        1        0    12288000
        mclk_i2s0_tx              2        2        0    12288000
          mclk_i2s0_tx_out2io     2        2        0    12288000
      mclk_i2s0_tx_fracdiv        0        0        0    12288000
# amixer contents
...
numid=3,iface=PCM,name='PCM Clk Compensation In PPM'
  ; type=INTEGER,access=rw------,values=1,min=-1000,max=1000,step=1
  : values=0
# amixer -- cset numid=3 10
numid=3,iface=PCM,name='PCM Clk Compensation In PPM'
  ; type=INTEGER,access=rw------,values=1,min=-1000,max=1000,step=1
  : values=10
# cat /sys/kernel/debug/clk/clk_summary | egrep "i2s0|cpll"
pll_cpll                          1        1        0   491524892
  cpll                            6       11        0   491524892
    mclk_i2s0_rx_div              1        1        0    12288123
      mclk_i2s0_rx_mux            1        1        0    12288123
        mclk_i2s0_rx              1        1        0    12288123
      mclk_i2s0_rx_fracdiv        0        0        0    12288123
    mclk_i2s0_tx_div              1        1        0    12288123
      mclk_i2s0_tx_mux            1        1        0    12288123
        mclk_i2s0_tx              2        2        0    12288123
          mclk_i2s0_tx_out2io     2        2        0    12288123
      mclk_i2s0_tx_fracdiv        0        0        0    12288123
# amixer -- cset numid=3 -10
numid=3,iface=PCM,name='PCM Clk Compensation In PPM'
  ; type=INTEGER,access=rw------,values=1,min=-1000,max=1000,step=1
  : values=-10
pll_cpll                          1        1        0   491515106
  cpll                            6       11        0   491515106
    mclk_i2s0_rx_div              1        1        0    12287878
      mclk_i2s0_rx_mux            1        1        0    12287878
        mclk_i2s0_rx              1        1        0    12287878
      mclk_i2s0_rx_fracdiv        0        0        0    12287878
    mclk_i2s0_tx_div              1        1        0    12287878
      mclk_i2s0_tx_mux            1        1        0    12287878
        mclk_i2s0_tx              2        2        0    12287878
          mclk_i2s0_tx_out2io     2        2        0    12287878
      mclk_i2s0_tx_fracdiv        0        0        0    12287878

2.8 DLP

Цифровой возврат аудио поддерживается для одного и нескольких DAI с контроллерами I2S/I2STDM/SAI.

2.8.1 Режимы цифрового возврата

Поддерживаются следующие режимы; список может быть расширен.

Mode List:
# amixer contents
numid=2,iface=MIXER,name='Software Digital Loopback Mode'
  ; type=ENUMERATED,access=rw------,values=1,items=7
  ; Item #0 'Disabled'
  ; Item #1 '2CH: 1 Loopback + 1 Mic'
  ; Item #2 '2CH: 1 Mic + 1 Loopback'
  ; Item #3 '2CH: 1 Mic + 1 Loopback-mixed'
  ; Item #4 '2CH: 2 Loopbacks'
  ; Item #5 '4CH: 2 Mics + 2 Loopbacks'
  ; Item #6 '4CH: 2 Mics + 1 Loopback-mixed'
  ; Item #7 "4CH: 4 Loopbacks",
  ; Item #8 "6CH: 4 Mics + 2 Loopbacks",
  ; Item #9 "6CH: 4 Mics + 1 Loopback-mixed",
  ; Item #10 "6CH: 6 Loopbacks",
  ; Item #11 "8CH: 6 Mics + 2 Loopbacks",
  ; Item #12 "8CH: 6 Mics + 1 Loopback-mixed",
  ; Item #13 "8CH: 8 Loopbacks",
  ; Item #14 "10CH: 8 Mics + 2 Loopbacks",
  ; Item #15 "10CH: 8 Mics + 1 Loopback-mixed",
  ; Item #16 "16CH: 8 Mics + 8 Loopbacks",
  : values=0

Пример: включение цифрового возврата I2S.

Enable:
CONFIG_SND_SOC_ROCKCHIP_DLP
&i2s {
    rockchip,digital-loopback;
};

2.9 Динамические каналы DMA

RK поддерживает PL330 и RKDMA. PL330 одновременно обслуживает только 8 каналов; у RKDMA этого ограничения нет.

ASoC ядра запрашивает DMA-каналы статически. Для PL330 это мешает разделять их между большим числом периферийных устройств. Поэтому предусмотрены динамический запрос и освобождение аудио-DMA.

CONFIG_SND_SOC_DYNAMIC_DMA_CHAN

2.10 PATTERN DEBUG

Воспроизведение шаблонных данных упрощает анализ временных диаграмм. При включении исходный поток заменяется фиксированной последовательностью, содержащей проверку MSB, идентификатор канала и другие признаки.

commit 0083e5a0ce9fe6654e586c9021b7b3cf90b5bf3c
Author: Sugar Zhang <sugar.zhang@rock-chips.com>
Date:   Tue Aug 13 22:09:29 2024 +0800
    ALSA: pcm: Add support for pcm pattern playback
    CONFIG_SND_PCM_PATTERN_DEBUG
    * MSB check
    * channel id
    * as much as more 0/1 stress
    PATTERN8(x)     (0xa0 | (x))
    PATTERN16(x)    (0xab00 | (x))
    PATTERN32(x)    (0xabcabc00 | (x))
    e.g. 16bit 4ch pattern:
    0xab01 0xab02 0xab03 0xab04 0xab01 ...
    This pattern is only used for IOCTL_READ/WRITE, not
    suitable for MMAP.

3. Отладка

Основные инструменты отладки и их применение.

3.1 Измерительное оборудование

3.1.1 Мультиметр

Измерьте питание и сопоставьте напряжение с документацией микросхемы. На SoC проверьте соответствие IO-домена программной конфигурации; на кодеке — питание каждого тракта.

Пример: на RV1126 EVB RK817 подключён к I2S0 и работает при 1,8 В. Мультиметр подтверждает 1,8 В, как показано на схеме питания ниже.

Иллюстрация из оригинала: 3.1.1 Мультиметр (p. 66)

Рисунок 3-1. Питание I2S IO

Соответствующий домен в DTS задаётся как 1,8 В:

&pmu_io_domains {
        status = "okay";
        ...
        vccio7-supply = <&vcc_1v8>;
};

Предупреждение: несоответствие аппаратного питания и программной настройки может вызвать сбои или повредить микросхему.

3.1.2 Осциллограф

Проверьте частоту, амплитуду, коэффициент заполнения и джиттер тактовых сигналов по спецификации протокола. Например, при питании 3,3 В амплитуда лишь 2 В может указывать на нагрузку внешнего устройства, замыкание на землю или неверную настройку напряжения. Захватите тактирование и данные, проверьте известный шаблон; для этого подходит и логический анализатор. Триггерный режим помогает поймать сбой — например, джиттер или выброс CLK в момент выпадения звука.

3.1.3 Генератор сигналов

Генератор создаёт прямоугольные, треугольные и синусоидальные сигналы. Для проверки АЦП подайте известный сигнал, например синусоиду, и сравните записанный результат с исходным, оценивая искажения и точность.

3.1.4 Анализатор AP

Аудиоанализатор проверяет характеристики АЦП/ЦАП кодека: цифровые интерфейсы, отношение сигнал/шум, гармонические искажения, динамический диапазон и другие параметры. Измерения помогают локализовать ограничения и улучшить аудиотракт.

3.2 Команды отладки

3.2.1 procfs

Успешную регистрацию звуковой карты можно проверить через /proc.

Файл cards в /proc/asound содержит список зарегистрированных звуковых карт.

Выведите его следующей командой:

# cat /proc/asound/cards
 0 [rockchiprk809co]: rockchip_rk809- - rockchip,rk809-codec
                      rockchip,rk809-codec
 7 [Loopback       ]: Loopback - Loopback
                      Loopback 1
# ls /dev/snd/
by-path    controlC7  pcmC0D0p  pcmC7D0p  pcmC7D1p
controlC0  pcmC0D0c   pcmC7D0c  pcmC7D1c  timer

При успешной регистрации в выводе будут имя и номер карты.

3.2.2 clk summary

Проверьте аудиотактирование и правильность выбранной частоты.

Пример: частота i2s0 MCLK равна 12288000 Гц, источник — CPLL.

# cat /sys/kernel/debug/clk/clk_summary | egrep "i2s0|pll"
pll_cpll                          1        1        0   500000000
  cpll                            5       10        0   500000000
    mclk_i2s0_rx_div              0        0        0   500000000
      mclk_i2s0_rx_fracdiv        0        0        0    12288000
        mclk_i2s0_rx_mux          0        0        0    12288000
          mclk_i2s0_rx            0        0        0    12288000
    mclk_i2s0_tx_div              1        1        0   500000000
      mclk_i2s0_tx_fracdiv        1        1        0    12288000
        mclk_i2s0_tx_mux          1        1        0    12288000
          mclk_i2s0_tx            1        1        0    12288000
            mclk_i2s0_tx_out2io   2        2        0    12288000

3.2.3 Регистры

3.2.3.1 Команда io

Команда io читает и изменяет регистры SoC. Сопоставьте значения с руководством микросхемы, чтобы проверить конфигурацию и состояние.

# cat /proc/iomem | grep i2s
ff800000-ff800fff : i2s@ff800000
#
# io -4 -l 0x40 0xff800000
ff800000:  7200000f 004e000f 10003f3f 00000010
ff800010:  000f0110 01f00000 00000000 00000003
ff800020:  00000000 00000000 00000000 0000001f
ff800030:  00003eff 00003eff 00000303 20150001
3.2.3.2 regmap

Чтение регистров через узел regmap:

# ls /sys/kernel/debug/regmap/
0-0020-rk817-codec
ff800000.i2s
...
# cat /sys/kernel/debug/regmap/0-0020-rk817-codec/registers
12: 03
13: f4
14: 00
15: ff
16: 00
17: 40
18: 48
19: 00
1a: 00
1b: ff
1c: 00
1d: 00
1e: 02
1f: 00
...

regmap использует кэш. Изменения, сделанные напрямую через io, могут не отражаться в regmap, если регистр не помечен volatile и кэш не отключён.

Пример: отключение кэша regmap для чтения фактических значений.

# cd /sys/kernel/debug/regmap/ff800000.i2s/
# cat registers /* dump register by regmap */
00: 7200000f
04: 004e000f
08: 10003f3f
0c: XXXXXXXX
10: 000f0010
14: 01f00000
18: XXXXXXXX
1c: 00000000
20: XXXXXXXX
24: XXXXXXXX
2c: XXXXXXXX
30: 00003eff
34: 00003eff
38: 00000303
# io -4 0xff800000 0x0  /* set 0xff800000 to 0 */
# io -4 -l 0x40 0xff800000  /* dump to check value of 0xff800000, now it's 0 */
ff800000:  00000000 004e000f 10003f3f 00000000
ff800010:  000f0010 01f00000 00000000 00000000
ff800020:  00000000 00000000 00000000 00000000
ff800030:  00003eff 00003eff 00000303 20150001
# cat registers /* dump register by regmap */
00: 7200000f    /* it's still old value */04: 004e000f
08: 10003f3f
0c: XXXXXXXX
10: 000f0010
14: 01f00000
18: XXXXXXXX
1c: 00000000
20: XXXXXXXX
24: XXXXXXXX
2c: XXXXXXXX
30: 00003eff
34: 00003eff
38: 00000303
# echo N > cache_only
[148833.374641] rockchip-i2s-tdm ff800000.i2s: debugfs cache_only=N forced: syncing cache
# echo Y > cache_bypass
[148834.760274] rockchip-i2s-tdm ff800000.i2s: debugfs cache_bypass=Y forced
# cat registers /* dump again, now it's correct */
00: 00000000
04: 004e000f
08: 10003f3f
0c: 00000000
10: 000f0010
14: 01f00000
18: 00000000
1c: 00000000
20: 00000000
24: 00000000
2c: 00000000
30: 00003eff
34: 00003eff
38: 00000303
3.2.3.3 i2c-tools

Для кодеков на I2C используйте i2c-tools: прочитайте или измените регистры и сопоставьте их с руководством кодека.

3.2.3.3.1 i2cdetect

Обнаружение устройств на шине I2C.

Usage: i2cdetect [-y] [-a] [-q|-r] I2CBUS [FIRST LAST]
       i2cdetect -F I2CBUS
       i2cdetect -l
  I2CBUS is an integer or an I2C bus name
  If provided, FIRST and LAST limit the probing range.

Пример: устройства на i2c0.

# i2cdetect -y 0
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --20: UU -- -- -- -- -- -- -- -- -- -- -- -- -- -- --30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --70: -- -- -- -- -- -- -- --
3.2.3.3.2 i2cdump

Вывод всех регистров устройства.

Usage: i2cdump [-f] [-y] [-r first-last] I2CBUS ADDRESS [MODE [BANK [BANKREG]]]
  I2CBUS is an integer or an I2C bus name
  ADDRESS is an integer (0x03 - 0x77)
  MODE is one of:
    b (byte, default)
    w (word)
    W (word on even register addresses)
    s (SMBus block)
    i (I2C block)
    c (consecutive byte)
    Append p for SMBus PEC

Пример: регистры RK817 по адресу 0x20 на i2c0; диапазон кодека — 0x12–0x4f.

# i2cdump -f -y 0 0x20 b
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00: 03 35 18 10 08 17 04 00 00 00 01 01 00 80 02 00
10: 00 00 03 f4 00 ff 00 40 48 00 00 ff 00 00 02 00
20: 00 00 00 00 ff 00 00 1f 00 99 00 00 00 00 00 03
30: 04 03 03 00 a5 02 00 00 11 03 03 00 00 e0 0f 09
40: a5 7f 04 58 2d 0c a5 00 00 00 00 0f 20 00 0f 88
50: 8c 00 01 00 01 b0 44 1e 00 60 16 6a 16 6a ff f8
60: ff f8 00 00 00 00 00 00 00 00 00 16 66 01 d7 00
70: 00 00 00 00 ff ed d6 58 16 6a ff f9 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 60 81 d5 7f fb df ca 81 d2 ff 00 00 00 00 00 00
a0: 00 00 00 00 b8 00 00 00 00 00 00 00 00 00 00 00
b0: 00 0f 0f 0f 0f ad 0e ff ff 00 64 18 18 64 12 18
c0: 64 00 00 64 62 62 64 ff ff ff ff ff 08 08 30 30
d0: 08 08 30 30 30 30 18 14 58 58 6c 6c 6c 6c 0b 33
e0: 00 00 00 55 a2 c8 c5 40 00 ff 22 03 0a 80 94 0b
f0: c0 8c a0 40 18 10 00 86 00 dc 00 ff 00 ff 60 00
3.2.3.3.3 i2cset

Изменение одного регистра.

Usage: i2cset [-f] [-y] [-m MASK] [-r] I2CBUS CHIP-ADDRESS DATA-ADDRESS [VALUE] ... [MODE]
  I2CBUS is an integer or an I2C bus name
  ADDRESS is an integer (0x03 - 0x77)
  MODE is one of:
    c (byte, no value)
    b (byte data, default)
    w (word data)
    i (I2C block data)
    s (SMBus block data)
    Append p for SMBus PEC

Пример: записать 0 в регистр 0x12.

# i2cset -f -y -r 0 0x20 0x12 0x0 b
Value 0x00 written, readback matched
3.2.3.3.4 i2cget

Чтение одного регистра.

Usage: i2cget [-f] [-y] I2CBUS CHIP-ADDRESS [DATA-ADDRESS [MODE]]
  I2CBUS is an integer or an I2C bus name
  ADDRESS is an integer (0x03 - 0x77)
  MODE is one of:
    b (read byte data, default)
    w (read word data)
    c (write byte/read byte)
    Append p for SMBus PEC

Пример: чтение регистра 0x12.

# i2cget -f -y 0 0x20 0x12 b
0x00

Дополнительные сведения см. в документации i2c-tools.

3.2.4 alsa-utils

RK Linux SDK по умолчанию включает alsa-utils.

3.2.4.1 aplay
Usage: aplay [OPTION]... [FILE]...
-h, --help              help
    --version           print current version
-l, --list-devices      list all soundcards and digital audio devices
-L, --list-pcms         list device names
-D, --device=NAME       select PCM by name
-q, --quiet             quiet mode
-t, --file-type TYPE    file type (voc, wav, raw or au)
-c, --channels=#        channels
-f, --format=FORMAT     sample format (case insensitive)
-r, --rate=#            sample rate
-d, --duration=#        interrupt after # seconds
-s, --samples=#         interrupt after # samples per channel
-M, --mmap              mmap stream
-N, --nonblock          nonblocking mode
-F, --period-time=#     distance between interrupts is # microseconds
-B, --buffer-time=#     buffer duration is # microseconds
    --period-size=#     distance between interrupts is # frames
    --buffer-size=#     buffer duration is # frames
-A, --avail-min=#       min available space for wakeup is # microseconds
-R, --start-delay=#     delay for automatic PCM start is # microseconds
                        (relative to buffer size if <= 0)
-T, --stop-delay=#      delay for automatic PCM stop is # microseconds from xrun
-v, --verbose           show PCM structure and setup (accumulative)
-V, --vumeter=TYPE      enable VU meter (TYPE: mono or stereo)
-I, --separate-channels one file for each channel
-i, --interactive       allow interactive operation from stdin
-m, --chmap=ch1,ch2,..  Give the channel map to override or follow
    --disable-resample  disable automatic rate resample
    --disable-channels  disable automatic channel conversions
    --disable-format    disable automatic format conversions
    --disable-softvol   disable software volume control (softvol)
    --test-position     test ring buffer position
    --test-coef=#       test coefficient for ring buffer position (default 8)
                        expression for validation is: coef * (buffer_size / 2)
    --test-nowait       do not wait for ring buffer - eats whole CPU
    --max-file-time=#   start another output file when the old file has recorded
                        for this many seconds
    --process-id-file   write the process ID here
    --use-strftime      apply the strftime facility to the output file name
    --dump-hw-params    dump hw_params of the device
    --fatal-errors      treat all errors as fatal

Пример: воспроизведение нулевых данных через карту 0, 48 кГц, 2 канала, 16 бит.

# aplay -D hw:0,0 --period-size=1024 --buffer-size=4096 -r 48000 -c 2 -f s16_le /dev/zero
3.2.4.2 arecord
Usage: arecord [OPTION]... [FILE]...
-h, --help              help
    --version           print current version
-l, --list-devices      list all soundcards and digital audio devices
-L, --list-pcms         list device names
-D, --device=NAME       select PCM by name
-q, --quiet             quiet mode
-t, --file-type TYPE    file type (voc, wav, raw or au)
-c, --channels=#        channels
-f, --format=FORMAT     sample format (case insensitive)
-r, --rate=#            sample rate
-d, --duration=#        interrupt after # seconds
-s, --samples=#         interrupt after # samples per channel
-M, --mmap              mmap stream
-N, --nonblock          nonblocking mode
-F, --period-time=#     distance between interrupts is # microseconds
-B, --buffer-time=#     buffer duration is # microseconds
    --period-size=#     distance between interrupts is # frames
    --buffer-size=#     buffer duration is # frames
-A, --avail-min=#       min available space for wakeup is # microseconds
-R, --start-delay=#     delay for automatic PCM start is # microseconds
                        (relative to buffer size if <= 0)
-T, --stop-delay=#      delay for automatic PCM stop is # microseconds from xrun
-v, --verbose           show PCM structure and setup (accumulative)
-V, --vumeter=TYPE      enable VU meter (TYPE: mono or stereo)
-I, --separate-channels one file for each channel
-i, --interactive       allow interactive operation from stdin
-m, --chmap=ch1,ch2,..  Give the channel map to override or follow
    --disable-resample  disable automatic rate resample
    --disable-channels  disable automatic channel conversions
    --disable-format    disable automatic format conversions
    --disable-softvol   disable software volume control (softvol)
    --test-position     test ring buffer position
    --test-coef=#       test coefficient for ring buffer position (default 8)
                        expression for validation is: coef * (buffer_size / 2)
    --test-nowait       do not wait for ring buffer - eats whole CPU
    --max-file-time=#   start another output file when the old file has recorded
                        for this many seconds
    --process-id-file   write the process ID here
    --use-strftime      apply the strftime facility to the output file name
    --dump-hw-params    dump hw_params of the device
    --fatal-errors      treat all errors as fatal

Пример: запись через карту 0, 16 кГц, 8 каналов, 32 бита.

# arecord -D hw:0,0 --period-size=1024 --buffer-size=4096 -r 16000 -c 8 -f s32_le r.wav
3.2.4.3 arecord | aplay

Соединение команд конвейером создаёт петлю записи/воспроизведения, удобную для отладки драйвера и измерений.

Пример: запись карты 0 → воспроизведение карты 1.

# arecord -D hw:0,0 --period-size=1024 --buffer-size=4096 -r 48000 -c 2 -f s16_le -t raw |
aplay -D hw:1,0 --period-size=1024 --buffer-size=4096 -r 48000 -c 2 -f s16_le -t raw
3.2.4.4 amixer

Управляйте переключателями внутренних трактов, маршрутизацией и громкостью по топологии из руководства кодека, например RK3308 на рисунке 3-2.

Иллюстрация из оригинала: 3.2.4.4 amixer (p. 75)

Рисунок 3-2. Кодек RK3308

Usage: amixer <options> [command]
Available options:
  -h,--help       this help
  -c,--card N     select the card
  -D,--device N   select the device, default 'default'
  -d,--debug      debug mode
  -n,--nocheck    do not perform range checking
  -v,--version    print version of this program
  -q,--quiet      be quiet
  -i,--inactive   show also inactive controls
  -a,--abstract L select abstraction level (none or basic)
  -s,--stdin      Read and execute commands from stdin sequentially
  -R,--raw-volume Use the raw value (default)
  -M,--mapped-volume Use the mapped volume
Available commands:
  scontrols       show all mixer simple controls
  scontents       show contents of all mixer simple controls (default command)
  sset sID P      set contents for one mixer simple control
  sget sID        get contents for one mixer simple control
  controls        show all controls for given card
  contents        show contents of all controls for given card
  cset cID P      set control contents for one control
  cget cID        get control contents for one control

Пример: просмотр элементов управления и переключение воспроизведения на SPK.

# amixer -c 0 contents
numid=1,iface=MIXER,name='Playback Path'
  ; type=ENUMERATED,access=rw------,values=1,items=11
  ; Item #0 'OFF'
  ; Item #1 'RCV'
  ; Item #2 'SPK'
  ; Item #3 'HP'
  ; Item #4 'HP_NO_MIC'
  ; Item #5 'BT'
  ; Item #6 'SPK_HP'
  ; Item #7 'RING_SPK'
  ; Item #8 'RING_HP'
  ; Item #9 'RING_HP_NO_MIC'
  ; Item #10 'RING_SPK_HP'
  : values=0
...
# amixer -c 0 cset numid=1 2
numid=1,iface=MIXER,name='Playback Path'
  ; type=ENUMERATED,access=rw------,values=1,items=11
  ; Item #0 'OFF'
  ; Item #1 'RCV'
  ; Item #2 'SPK'
  ; Item #3 'HP'
  ; Item #4 'HP_NO_MIC'
  ; Item #5 'BT'
  ; Item #6 'SPK_HP'
  ; Item #7 'RING_SPK'
  ; Item #8 'RING_HP'
  ; Item #9 'RING_HP_NO_MIC'
  ; Item #10 'RING_SPK_HP'
  : values=2
3.2.4.5 alsaloop

Маршрутизация между произвольными звуковыми картами.

Адаптивная синхронизация тактирования.

Адаптивный ресемплинг.

Перенаправление элементов управления микшера.

Usage: alsaloop [OPTION]...
-h,--help      help
-g,--config    configuration file (one line = one job specified)
-d,--daemonize daemonize the main process and use syslog for errors
-P,--pdevice   playback device
-C,--cdevice   capture device
-X,--pctl      playback ctl device
-Y,--cctl      capture ctl device
-l,--latency   requested latency in frames
-t,--tlatency  requested latency in usec (1/1000000sec)
-f,--format    sample format
-c,--channels  channels
-r,--rate      rate
-n,--resample  resample in alsa-lib
-A,--samplerate use converter (0=sincbest,1=sincmedium,2=sincfastest,
                               3=zerohold,4=linear)
-B,--buffer    buffer size in frames
-E,--period    period size in frames
-s,--seconds   duration of loop in seconds
-b,--nblock    non-block mode (very early process wakeup)
-S,--sync      sync mode(0=none,1=simple,2=captshift,3=playshift,4=samplerate,
                         5=auto)
-a,--slave     stream parameters slave mode (0=auto, 1=on, 2=off)
-T,--thread    thread number (-1 = create unique)
-m,--mixer  redirect mixer, argument is:
            SRC_SLAVE_ID(PLAYBACK)[@DST_SLAVE_ID(CAPTURE)]
-O,--ossmixer   rescan and redirect oss mixer, argument is:
            ALSA_ID@OSS_ID  (for example: "Master@VOLUME")
-e,--effect    apply an effect (bandpass filter sweep)
-v,--verbose   verbose mode (more -v means more verbose)
-w,--workaround use workaround (serialopen)
-U,--xrun      xrun profiling
-W,--wake      process wake timeout in ms
-z,--syslog    use syslog for errors
Recognized sample formats are: S8 U8 S16_LE S16_BE U16_LE U16_BE S24_LE S24_BE U24_LE U24_BE
S32_LE S32_BE U32_LE U32_BE FLOAT_LE FLOAT_BE FLOAT64_LE FLOAT64_BE IEC958_SUBFRAME_LE
IEC958_SUBFRAME_BE MU_LAW A_LAW IMA_ADPCM MPEG GSM SPECIAL S24_3LE S24_3BE U24_3LE U24_3BE
S20_3LE S20_3BE U20_3LE U20_3BE S18_3LE S18_3BE U18_3LE U18_3BE G723_24 G723_24_1B G723_40
G723_40_1B DSD_U8 DSD_U16_LE DSD_U32_LE DSD_U16_BE
Tip #1 (usable 500ms latency, good CPU usage, superb xrun prevention):
  alsaloop -t 500000
Tip #2 (superb 1ms latency, but heavy CPU usage):
  alsaloop -t 1000
Sync mode specification for capture to playback stream:
 0 or none       - do not touch the stream
 1 or simple     - add or remove samples to keep
                   both streams synchronized
 2 or captshift  - use driver for the capture device
                   (if supported) to compensate
                   the rate shift
 3 or playshift  - use driver for the playback device
                   (if supported) to compensate
                   the rate shift
 4 or samplerate - use samplerate library to do rate resampling
 5 or auto       - automatically selects the best method
                   in this order: captshift, playshift,
                   samplerate, simple

Пример: запись с карты 0 воспроизводится картой 1. Стратегия синхронизации 1 добавляет или удаляет отсчёты.

# alsaloop -C hw:0,0 -P hw:1,0 -t 10000  -A 3 -S 1 -b -v

Примечание:

Если обе карты имеют один источник частоты, например общий генератор OSC, накопленного рассогласования нет. Для UAC с тактированием ПК и локальной карты с тактированием устройства ошибка неизбежно накапливается и вызывает выпадения звука. Нужна программная компенсация — добавление/удаление отсчётов — либо аппаратная подстройка аудиочастоты.

3.2.5 tiny-alsa

RK Android SDK по умолчанию включает tiny-alsa.

3.2.5.1 tinypcminfo

Просмотр поддерживаемых частот, форматов и числа каналов карты.

Usage: tinypcminfo [-D card] [-d device]

Пример:

# tinypcminfo -D 0
Info for card 0, device 0:
PCM out:
Access: 0x000009
Format0: 0x000044
Format1: 0x000010
Format Name: S16_LE, S24_LE, S32_LE
Subformat: 0x000001
Rate: min=16000Hz max=48000Hz
Channels: min=2 max=2
Sample bits: min=16 max=32
Period size: min=4 max=65536
Period count: min=2 max=4096
PCM in:
Access: 0x000009
Format0: 0x000044
Format1: 0x000010
Format Name: S16_LE, S24_LE, S32_LE
Subformat: 0x000001
Rate: min=16000Hz max=48000Hz
Channels: min=2 max=2
Sample bits: min=16 max=32
Period size: min=4 max=65536
Period count: min=2 max=4096
3.2.5.2 tinyplay
Usage: tinyplay file.wav [-D card] [-d device] [-p period_size] [-n n_periods]

Пример: воспроизведение тестового файла 1k0.

# tinyplay /sdcard/1k0.wav -D 0 -d 0 -p 1024 -n 3
Playing sample: 2 ch, 44100 hz, 32 bit
3.2.5.3 tinycap
Usage: tinycap file.wav [-D card] [-d device] [-c channels] [-r rate] [-b bits] [-p
period_size] [-n n_periods]

Пример: запись с частотой 44,1 кГц.

# tinycap /sdcard/rec.wav -D 0 -d 0 –c 2 –r 44100 –b 16 –p 1024 –n 3
3.2.5.4 tinymix

Переключение внутренних трактов и регулировка громкости кодека; аналог amixer.

usage: tinymix [-D card]

Пример: включение тракта Mono.

# tinymix
Mixer name: 'rockchip,rt5640-codec'
Number of controls: 123
ctl     type    num    name                                    value
0       BOOL    1      Mono Playback Switch                    Off
1       INT     2      Mono DAC Playback Volume                175 175
2       BOOL    2      Speaker Channel Switch                  Off Off
3       INT     2      Speaker Playback Volume                 31 31
4       BOOL    2      HP Channel Switch                       Off Off
...
# tinymix "Mono Playback Switch" 1
Mono Playback Switch: On

3.2.6 Анализ XRUN

XRUN означает нарушение непрерывности аудиопотока. Различают underrun — нехватку данных при воспроизведении — и overrun — переполнение при записи.

Underrun возникает, если приложение не успело заполнить буфер воспроизведения: появляются паузы или тишина. Overrun возникает, если данные записи не прочитаны вовремя и часть поступающих отсчётов теряется.

ALSA в ядре Linux управляет буферами аудиопотока и обнаруживает XRUN. При исчерпании или переполнении буфера состояние передаётся драйверу и приложению для обработки и восстановления. Формулировка английского оригинала об обязательной генерации отдельного прерывания при XRUN не универсальна; конкретный механизм зависит от драйвера.

Для устойчивой работы нужны своевременная обработка с низкой задержкой и достаточной пропускной способностью, эффективная буферизация, включая предварительное заполнение и двойные буферы, а также быстрые процедуры восстановления после XRUN.

3.2.6.1 Сообщения XRUN в kmsg
  1. Включите параметры XRUN CONFIG.
CONFIG_SND_DEBUG
CONFIG_SND_PCM_XRUN_DEBUG
CONFIG_SND_VERBOSE_PROCFS

Биты отладки перечислены в таблице 3-1. Для включения всех сложите их значения.

Значение бита Описание
1 Базовая отладка: вывод XRUN в журнал ядра
2 Вывод стека для базовой отладки
4 Сопоставление позиции с jiffies — монотонным счётчиком ядра; при базовой отладке выводятся изменения

Таблица 3-1. Биты отладки XRUN

  1. Включите все биты отладки для устройства воспроизведения карты 0.
# echo 7 > /proc/asound/card0/pcm0p/xrun_debug
  1. При underrun кольцевого DMA-буфера воспроизведения появляются сообщения следующего вида:
asoc-simple-card rk809-sound: XRUN: pcmC0D0p:0
CPU: 3 PID: 657 Comm: sh Not tainted 4.19.161 #509
Hardware name: Generic DT based system
[<b010f47c>] (unwind_backtrace) from [<b010b9a8>] (show_stack+0x10/0x14)
[<b010b9a8>] (show_stack) from [<b0850b58>] (dump_stack+0x90/0xa4)
[<b0850b58>] (dump_stack) from [<b06a39c4>] (__snd_pcm_xrun+0xa0/0x114)
[<b06a39c4>] (__snd_pcm_xrun) from [<b069dac4>] (snd_pcm_stop_xrun+0x64/0x68)
[<b069dac4>] (snd_pcm_stop_xrun) from [<b0695c4c>](snd_info_text_entry_release+0x34/0x7c)
[<b0695c4c>] (snd_info_text_entry_release) from [<b02694a4>] (close_pdeo+0x54/0x100)
[<b02694a4>] (close_pdeo) from [<b02695c0>] (proc_reg_release+0x70/0x78)
[<b02695c0>] (proc_reg_release) from [<b0210ac8>] (__fput+0x88/0x1c4)
[<b0210ac8>] (__fput) from [<b01412d4>] (task_work_run+0x94/0xb4)
[<b01412d4>] (task_work_run) from [<b010b48c>] (do_work_pending+0xc8/0xd0)
[<b010b48c>] (do_work_pending) from [<b0101064>] (slow_work_pending+0xc/0x20)
3.2.6.2 XRUN и ftrace

Помимо kmsg, события трассировки XRUN показывают подробности, включая hwptr и applptr. Необходимо включить трассировку ядра. Поддерживаемые ALSA события перечислены в таблице 3-2.

Событие трассировки Описание
snd_pcm:applptr Обновление указателя приложения
snd_pcm:hw_ptr_error Ошибка указателя DMA
snd_pcm:xrun xrun
snd_pcm:hwptr Обновление указателя DMA
  1. Включите параметры FTRACE CONFIG.
CONFIG_FUNCTION_TRACER
CONFIG_FUNCTION_GRAPH_TRACER
CONFIG_STACK_TRACER
CONFIG_DYNAMIC_FTRACE
  1. Запустите воспроизведение в фоне.
# aplay -D hw:0,0 --period-size=128 --buffer-size=256 -r 48000 -f dat /dev/zero &
  1. Включите аудиособытия трассировки для анализа чтения и записи производителем и потребителем буфера.
# cd /sys/kernel/debug/tracing
# echo "snd_pcm:applptr" >> set_event
# echo "snd_pcm:hwptr" >> set_event
# echo "snd_pcm:xrun" >> set_event
# cat trace | head -20
...
178.109942: applptr: pcmC0D0p/sub0: prev=0, curr=128, avail=128, period=128, buf=256
178.109981: applptr: pcmC0D0p/sub0: prev=128, curr=256, avail=0, period=128, buf=256
178.110224: hwptr:   pcmC0D0p/sub0: POS: pos=24, old=0, base=0, period=128, buf=256
178.110234: applptr: pcmC0D0p/sub0: prev=256, curr=280, avail=0, period=128, buf=256
178.112441: hwptr:   pcmC0D0p/sub0: IRQ: pos=128, old=24, base=0, period=128, buf=256
178.112510: applptr: pcmC0D0p/sub0: prev=280, curr=384, avail=0, period=128, buf=256
178.112553: hwptr:   pcmC0D0p/sub0: POS: pos=136, old=128, base=0, period=128, buf=256
178.112556: applptr: pcmC0D0p/sub0: prev=384, curr=392, avail=0, period=128, buf=256
178.115176: hwptr:   pcmC0D0p/sub0: IRQ: pos=0, old=136, base=0, period=128, buf=256
178.115270: applptr: pcmC0D0p/sub0: prev=392, curr=512, avail=0, period=128, buf=256
178.115321: hwptr:   pcmC0D0p/sub0: POS: pos=8, old=256, base=256, period=128, buf=256
178.115327: applptr: pcmC0D0p/sub0: prev=512, curr=520, avail=0, period=128, buf=256

Подробности: kernel/Documentation/trace/*.

3.2.6.3 trace-cmd

trace-cmd — пользовательский интерфейс ftrace, упрощающий сбор трассировки. Пример:

# trace-cmd record -e snd_pcm:hwptr -e snd_pcm:applptr -e snd_pcm:xrun
# trace-cmd report

Дополнительные сведения см. в документации trace-cmd.

3.2.6.4 KernelShark

KernelShark графически отображает данные trace-cmd. См. документацию KernelShark.

3.3 Инструменты для ПК

Audacity и Audition помогают анализировать и обрабатывать звук на ПК: искать выпадения, шум, искажения и помехи постоянной частоты.

4. Частые вопросы

4.1 Поддержка аудиоинтерфейсов

См. раздел возможностей Rockchip Audio и техническое описание микросхемы.

4.2 Звуковая карта не регистрируется

Проверьте, что драйвер включён в сборку, согласно примеру добавления карты.

По kmsg определите проблемный компонент: DAI, CODEC или Machine. Например, сообщение ниже означает, что DAI не зарегистрирован.

[ 0.584114] rk-multicodecs vad-sound: ASoC: CPU DAI (null) not registered

Если проблема в DAI, проверьте наличие DMA-каналов. При их нехватке отключите другие использующие DMA модули и повторите проверку.

Если проблема в CODEC, измерьте питание и тактирование мультиметром и осциллографом, проверьте обмен I2C через i2c-tools.

4.3 Нет звука при воспроизведении

Убедитесь, что исходный файл не содержит тишину.

Воспроизведите его через aplay или tinyplay, чтобы отделить проблему приложения от проблемы ядра.

Подождите более 10 с и проверьте, не возникает ли I/O error по тайм-ауту.

Через amixer или tinymix проверьте включение тракта ЦАП и отсутствие mute.

Сверьте регистры IOMUX, DAI и CODEC с руководствами SoC и кодека.

Измерьте напряжения, тактирование и данные. Проверьте наличие цифрового потока, аналоговый сигнал у выхода кодека и уровень GPIO включения PA. Последовательно локализуйте проблемный участок.

4.4 Искажения при воспроизведении

Воспроизведите тестовый файл 1k0 через aplay или tinyplay.

Измените громкость и проверьте зависимость искажений от уровня.

Осциллографом проверьте ограничение амплитуды и другие искажения на выходе, стабильность тактирования кодека и источника.

Мультиметром проверьте питание по спецификации микросхемы.

Измените число периодов и размер DMA-буфера, сравните результат.

Последовательно проверьте узлы, способные вносить искажения.

4.5 Нет звука в записи

Подайте на кодек сигнал генератора 1 кГц.

Запишите через arecord или tinycap, чтобы отделить проблему приложения от ядра.

Подождите более 10 с и проверьте I/O error по тайм-ауту.

Через amixer или tinymix проверьте тракт АЦП и отсутствие mute.

Сверьте регистры IOMUX, DAI и CODEC с документацией.

Измерьте напряжения, тактирование, цифровые данные и аналоговый сигнал у входа кодека. Последовательно локализуйте неисправность.

4.6 Искажения при записи

Подайте на кодек сигнал генератора 1 кГц.

Запишите через arecord или tinycap; воспроизведите через петлю и измерьте осциллографом либо проанализируйте на ПК.

Изменяйте цифровое и аналоговое усиление, наблюдайте форму сигнала и сравнивайте записанные данные с тестовым источником.

Последовательно проверьте узлы, способные вносить искажения.

4.7 Слишком высокая или низкая скорость воспроизведения

Проверьте MCLK, BCLK и LRCK через clk summary.

Подтвердите точность частот осциллографом.

Запишите выходной сигнал инструментом ПК и проверьте потерю или добавление данных.

Захватите выходные данные микросхемы логическим анализатором и проверьте потерю или добавление отсчётов.

4.8 Периодические выпадения звука

Обычно возникают между системами с разными источниками тактирования: UAC, Bluetooth voice, сетевое аудио и т. п.

Причина — накопление ошибки рассогласования частот. Помогает компенсация аудиотактирования.

Ошибки обработки границ буфера также вызывают периодические выпадения и шум. Анализируйте их средствами XRUN profiling.

4.9 Шум

Шум имеет много причин. Основные способы поиска:

Проверьте точность тактирования и джиттер. Например, для HDA исходное руководство указывает предел менее 0,5 нс.

Проверьте выбросы тактового сигнала, особенно в области порогов переключения: микросхема может принять их за дополнительные фронты. Некоторые IO RK, например указанные для RV1126, имеют триггер Шмитта. Проверьте поддержку в руководстве SoC: эта функция может подавлять случайные выбросы.

Проверьте питание и землю кодека. Проникающие по ним помехи ухудшают характеристики и повышают шумовой фон.

Используйте дифференциальные цепи для подавления синфазных помех.

Проверьте разводку печатной платы и локализуйте источник помех.

4.10 XRUN

Для XRUN ядра см. раздел анализа XRUN. Дополнительные проверки:

Разделите чтение/запись и обработку звука на отдельные потоки, чтобы обмен с ядром не прерывался.

Проблемы планирования исследуйте через systrace или ftrace.

Блокировка накопителя может задерживать чтение. Для проверки воспроизводите источник без доступа к накопителю, например /dev/zero.

Проверьте точность тактирования: завышенная частота ускоряет расход данных. См. разделы о скорости воспроизведения и периодических выпадениях.

4.11 Ошибка I/O

Если запись или воспроизведение не отвечает более 10 с, журнал ядра может содержать playback/capture write error (DMA or IRQ trouble?).

Проверьте регистр FIFO COUNT контроллера DAI: не остановился ли счётчик.

Проверьте обновление DMA-прерываний через procfs: cat /proc/interrupts | grep dma.

Проверьте регистр состояния DMA-канала по смещению 0x100: не остановлен ли канал аварийно.

В ведомом режиме DAI внешнее тактирование должно непрерывно присутствовать в течение всего жизненного цикла DAI. Если это нельзя гарантировать динамически, оставьте источник постоянно включённым.

Другие статьи по теме → · Учебные маршруты →