Про audio кодеки Realtek/Conexant: различия между версиями

Материал из ALT Linux Wiki
(Новая страница: «По умолчанию обслуживаются драйвером ''snd_hda_intel'', иногда совместно с ''sof'' драйвером, особенно если требуется поддержка цифрового микрофона. Распространенные проблемы - не работает звук (динамики/наушники), не работает запись (микрофон встроенный/внешни...»)
 
Нет описания правки
 
(не показаны 4 промежуточные версии этого же участника)
Строка 72: Строка 72:


В остальных случаях возможно придется вносить изменения в драйверы кодеков, например, ''Conexant'':
В остальных случаях возможно придется вносить изменения в драйверы кодеков, например, ''Conexant'':
1) Клонируем исходный код ядра и ставим пакет ''kernel-headers-modules''
1) Клонируем исходный код ядра и ставим пакет ''kernel-headers-modules''
2) Переходим в директорию драйвера (''sound/pci/hda'')
2) Переходим в директорию драйвера (''sound/pci/hda'')
3) Вносим изменения в файл ''patch_conexant.c''
3) Вносим изменения в файл ''patch_conexant.c''
4) Оставляем в ''Makefile'' интересующие цели:
4) Оставляем в ''Makefile'' интересующие цели:


Строка 91: Строка 95:
</source>
</source>
7) Выгружаем модули звука, соблюдая зависимости (либо перезагружаем систему), проверяем.
7) Выгружаем модули звука, соблюдая зависимости (либо перезагружаем систему), проверяем.
== Не работает автоопределение микрофона гарнитуры на ноутбуке с кодеком Realtek ALC256 ==
Проблема следующая (''ноутбук ASUS Vivobook 15 X1504VAP''):
<source>
При подключении гарнитуры в разъем jack 3.5 источник захвата не меняется и
остается "Встроенный микрофон" (или "Internal Microphone").
Но если вручную открыть GUI утилиту pavucontrol и во вкладке "Устройства ввода"
принудительно указать "Микрофон гарнитуры" (или "Headset Microphone"), то он
активируется и исправно работает.
Если переподключить гарнитуру, то ошибка возвращается.
</source>
На первый взгляд ошибка может показаться [https://askubuntu.com/a/1391450/1873573 тривиальной] и решаемой в утилите ''hdajackretask'', упоминаемой ранее.  Однако, согласно ''dmesg'' драйвер видит микрофон гарнитуры:
<source>
snd_hda_intel 0000:00:1f.3: Codec #0 successfully probed, retry count = 0
snd_hda_codec_realtek hdaudioC0D0: autoconfig for ALC256: line_outs=1 (0x14/0x0/0x0/0x0/0x0) type:speaker
snd_hda_codec_realtek hdaudioC0D0:    speaker_outs=0 (0x0/0x0/0x0/0x0/0x0)
snd_hda_codec_realtek hdaudioC0D0:    hp_outs=1 (0x21/0x0/0x0/0x0/0x0)
snd_hda_codec_realtek hdaudioC0D0:    mono: mono_out=0x0
snd_hda_codec_realtek hdaudioC0D0:    inputs:
snd_hda_codec_realtek hdaudioC0D0:      Headset Mic=0x19
snd_hda_codec_realtek hdaudioC0D0:      Internal Mic=0x12
</source>
И любые попытки изменения конфигурации для пина ''0x19'' оказались безуспешны.
В таком случае есть смысл посмотреть на коммиты ядра, относящиеся к соответствующему
драйверу (''snd_hda_codec_realtek'') по ключевым словам "Mic", "Headset".
Например:
<source lang="sh">
$ git log -p --grep="mic\|headset" -i -- sound/pci/hda/patch_realtek.c
</source>
Смотрим описание коммитов и находим наиболее подходящий по проблеме:
<source>
ALSA: hda/realtek - Fix inactive headset mic jack
commit daf6c4681a74034d5723e2fb761e0d7f3a1ca18f upstream.
This patch adds the existing fixup to certain TF platforms implementing
the ALC274 codec with a headset jack. It fixes/activates the inactive
microphone of the headset.
</source>
В котором добавляется ''quirk'' в структуре ''alc269_fixup_tbl[]'' :
<source lang="c">
+      SND_PCI_QUIRK(0x1d05, 0x1387, "TongFang GMxIXxx", ALC2XX_FIXUP_HEADSET_MIC),
</source>
Смотрим, что делает ''quirk'', для этого ищем коммит с его первым упоминанием:
<source lang="sh">
$ git log -p -S "ALC2XX_FIXUP_HEADSET_MIC" --reverse -- sound/pci/hda/patch_realtek.c
</source>
Выдает первым этот [https://lore.kernel.org/all/1155d914c20c40569f56d36c79254879@realtek.com/ коммит] :
<source>
ALSA: hda/realtek - Fixed ASUS platform headset Mic issue
ASUS platform Headset Mic was disable by default.
Assigned verb table for Mic pin will enable it.
</source>
Похоже на нашу проблему, но в изменениях не предусмотрена подмена модели и применение квирка "на лету".  Поэтому внесем изменения в код драйвера, пересоберем и проверим:
1) Устанавливаем пакет ''kernel-headers-modules'' для целевого ядра
2) Клонируем исходный код драйвера
3) Переходим в каталог драйвера:
<source lang="sh">
$ cd sound/pci/hda/
</source>
4) Вносим изменения в файл ''patch_realtek.c:''
<source lang="c">
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -10435,6 +10435,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
  SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2),
+  SND_PCI_QUIRK(0x1043, 0x1e1f, "ASUS Vivobook 15 X1504VAP", ALC2XX_FIXUP_HEADSET_MIC),
  SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),
</source>
здесь значения '''0x1043''' и '''0x1e1f'''  берутся из данных об '''Subsystem ID''' кодека в выводе скрипта ''alsa-info.sh:''
<source>
Codec: Realtek ALC256
Vendor Id: 0x10ec0256
Subsystem Id: 0x10431e1f
</source>
5) Оставляем в ''Makefile'' интересующие цели:
''Makefile:''
<source lang="sh">
snd-hda-codec-realtek-objs :=  patch_realtek.o
obj-$(CONFIG_SND_HDA_CODEC_REALTEK) += snd-hda-codec-realtek.o
</source>
6) Собираем:
<source lang="sh">
$ make -C /lib/modules/$(uname -r)/build M=$PWD
</source>
7) Устанавливаем:
<source lang="sh">
$ sudo make -C /lib/modules/$(uname -r)/build M=$PWD modules_install
</source>
8) Перезагружаем систему (''цепочка модулей звука большая и не всегда выгрузка удачная'') и проверяем.
В данном случае этот квирк помог и автоопределение заработало корректно.
Если проблема решена, оформляем патч и [https://lore.kernel.org/all/20240905140211.937385-1-kovalev@altlinux.org/#t отправляем]  в upstream.
== Некорректная маршрутизация звука на моноблоке  HP EliteOne 1000 G2 с кодеком Conexant  CX20952 ==
Проблема следующая:
<source>
1. не работает вывод звука на встроенные динамики моноблока;
2. при подключении наушников звук выводится одновременно и на встроенные динамики моноблока, и на наушники.
</source>
На первый взгляд выглядит как последствие инверсной логики детектирования разъема. Для обратной инверсии для ''hda'' кодеков предусмотрен специальный хинт ''inv_jack_detect'', который можно переопределить в утилите ''hdajackretask'' или задать вручную, зная идентификаторы звуковой подсистемы:
<source lang="sh">
su -
cat > /lib/firmware/hda-jack-retask.fw << EOF
[codec]
0x14f151d7 0x103c83e5 0
[hints]
inv_jack_detect=yes
EOF
echo "options snd-hda-intel patch=hda-jack-retask.fw" > /etc/modprobe.d/hda-jack-retask.conf
</source>
И действительно, после перезагрузки в динамиках появляется звук, но в наушниках пропадает. Значит, проблема в конфигурации нод кодека, которая осуществляется на регистровом уровне аудио кодека, но которую нельзя решить обычными квирками/хинтами. Следовательно, убираем применение хинта и возвращаем в состояние по-умолчанию.
Обычно в таких случаях для решения проблемы не обойтись без полного набора средств для отладки, например, стенда, схемы печатной платы и даташита кодека. Но в данном случае пользователь обнаружил интересный факт:
<source>
На ПК с ОС Linux где есть проблема со звуком загружаем с другого носителя ОС Windows, далее снова загружаем с носителя ОС Linux и звук работает корректно (при выборе динамиков звук идет на динамики, при выборе/подключении наушников звук идет только в наушники) до момента выключения ПК с отключением питания (провод из розетки).
</source>
Первым делом следует проверить различие логов, сгенерированных скриптом ''alsa-info.sh''.
''diff'' между некорректным и корректным поведением звуковой подсистемы показал различие в настройках  управления пином виджета ''0x1d'':
<source>
< Pin-ctls: 0xc0: OUT HP
> Pin-ctls: 0x80: HP
</source>
Однако этот пин (''0x1d'') не конфигурируется драйвером линукс:
<source>
snd_hda_intel 0000:00:1f.3: Codec #0 successfully probed, retry count = 0
snd_hda_codec_conexant hdaudioC0D0: CX20952: BIOS auto-probing.
snd_hda_codec_conexant hdaudioC0D0: autoconfig for CX20952: line_outs=1 (0x17/0x0/0x0/0x0/0x0) type:speaker
snd_hda_codec_conexant hdaudioC0D0:    speaker_outs=0 (0x0/0x0/0x0/0x0/0x0)
snd_hda_codec_conexant hdaudioC0D0:    hp_outs=1 (0x16/0x0/0x0/0x0/0x0)
snd_hda_codec_conexant hdaudioC0D0:    mono: mono_out=0x0
snd_hda_codec_conexant hdaudioC0D0:    inputs:
snd_hda_codec_conexant hdaudioC0D0:      Internal Mic=0x1a
snd_hda_codec_conexant hdaudioC0D0:      Mic=0x19
</source>
Похожих проблем для кодеков conexant и realtek в истории коммитов нет, поэтому можно попробовать принудительно прописывать нужное значение ''0x80'' для пина ''0x1d'' при работе с конкретной печатной платой, для чего был успешно протестирован и отправлен [https://lore.kernel.org/all/20241009134248.662175-1-kovalev@altlinux.org/ патч].
В ходе обсуждения проблемы было предложено использовать кэшированный вариант функции записи, который выполняет запись только если значение поменялось. Второй  [https://lore.kernel.org/all/20241016080713.46801-1-kovalev@altlinux.org/ патч].


[[Категория:Программно-аппаратная совместимость]]
[[Категория:Программно-аппаратная совместимость]]

Текущая версия от 19:32, 21 октября 2024

По умолчанию обслуживаются драйвером snd_hda_intel, иногда совместно с sof драйвером, особенно если требуется поддержка цифрового микрофона.

Распространенные проблемы - не работает звук (динамики/наушники), не работает запись (микрофон встроенный/внешний гарнитуры). Связано это зачастую с аппаратными различиями - реализованные в коде драйверов профили и конфигурации устройств могут не соответствовать конкретной реализации аппаратной части на конкретном устройстве. Например, производители материнских плат могут использовать один и тот же аудиокодек, но реализовывать различные схемы подключения разъемов, динамиков и микрофонов. В результате, драйвер может неправильно определять, какой разъем используется для вывода или ввода звука.

В таком случае удобно использовать утилиту hdajackretask, в сети есть хорошая документация от red-soft.

Рассмотрим на реальном примере. Ноутбук Chuwi CoreBook XPro, проблемы:

- не работает звук из встроенных динамиков
- не определяется микрофон гарнитуры

Смотрим alsa-info (alsa-info.sh --no-upload --output alsa-info.txt):

!!HDA-Intel Codec information!!

Codec: Realtek ALC269VB
Vendor Id: 0x10ec0269
Subsystem Id: 0x27820232

Ищем исправление (если есть) в последней версии ядра для этой подсистемы (Subsystem Id: 0x27820232) в файле sound/pci/hda/patch_realtek.c  (для Realtek) или sound/pci/hda/patch_conexant.c (для Conexant), по ключам ID (2782 , 0232):

SND_PCI_QUIRK(0x2782, 0x0232, "CHUWI CoreBook XPro", ALC269VB_FIXUP_CHUWI_COREBOOK_XPRO),

На момент решения проблемы, этих исправлений не было, с помощью hdajackretask был подобран подходящий конфиг.

hdajackretask делает "под капотом" примерно следующее: 1) создает файл "прошивки" новой кофигурации

su -
cat > /lib/firmware/chuwi-corebook-xpro.fw <<EOF
[codec]
0x10ec0269 0x27820232 0

[pincfg]
0x12 0x90a60160
0x18 0x03a19020
0x1b 0x90170150
0x21 0x0321403f
EOF

2) сообщает звуковому драйверу путь к файлу:

su -
echo "options snd-hda-intel patch=chuwi-corebook-xpro.fw" > /etc/modprobe.d/chuwi-corebook-xpro.conf

После перезагрузки, dmesg:

[    4.844915] snd_hda_intel 0000:00:1f.3: DSP detected with PCI class/subclass/prog-if info 0x040380
[    4.845010] snd_hda_intel 0000:00:1f.3: enabling device (0000 -> 0002)
[    4.845232] snd_hda_intel 0000:00:1f.3: Applying patch firmware 'chuwi-corebook-xpro.fw'
[    4.846595] snd_hda_intel 0000:00:1f.3: bound 0000:00:02.0 (ops i915_audio_component_bind_ops [i915])
[    4.924927] snd_hda_codec_realtek hdaudioC0D0: autoconfig for ALC269VB: line_outs=2 (0x14/0x1b/0x0/0x0/0x0) type:speaker
[    4.924933] snd_hda_codec_realtek hdaudioC0D0:    speaker_outs=0 (0x0/0x0/0x0/0x0/0x0)
[    4.924935] snd_hda_codec_realtek hdaudioC0D0:    hp_outs=1 (0x21/0x0/0x0/0x0/0x0)
[    4.924936] snd_hda_codec_realtek hdaudioC0D0:    mono: mono_out=0x0
[    4.924937] snd_hda_codec_realtek hdaudioC0D0:    inputs:
[    4.924938] snd_hda_codec_realtek hdaudioC0D0:      Mic=0x18
[    4.924940] snd_hda_codec_realtek hdaudioC0D0:      Internal Mic=0x12

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

Еще, как вариант, можно подобрать модель  с похожей проблемой и проверить, например, inv-dmic если проблемы со встроенным микрофоном:

su -
echo 'options snd_hda_intel model=inv-dmic' > /etc/modprobe.d/snd-hda-intel.conf
reboot

В остальных случаях возможно придется вносить изменения в драйверы кодеков, например, Conexant:

1) Клонируем исходный код ядра и ставим пакет kernel-headers-modules

2) Переходим в директорию драйвера (sound/pci/hda)

3) Вносим изменения в файл patch_conexant.c

4) Оставляем в Makefile интересующие цели:

Makefile:

snd-hda-codec-conexant-y :=  patch_conexant.o
obj-$(CONFIG_SND_HDA_CODEC_CONEXANT) += snd-hda-codec-conexant.o

5) Собираем

make -C /lib/modules/$(uname -r)/build M=$PWD

6) Устанавливаем

sudo make -C /lib/modules/$(uname -r)/build M=$PWD modules_install

7) Выгружаем модули звука, соблюдая зависимости (либо перезагружаем систему), проверяем.

Не работает автоопределение микрофона гарнитуры на ноутбуке с кодеком Realtek ALC256

Проблема следующая (ноутбук ASUS Vivobook 15 X1504VAP):

При подключении гарнитуры в разъем jack 3.5 источник захвата не меняется и
остается "Встроенный микрофон" (или "Internal Microphone").
Но если вручную открыть GUI утилиту pavucontrol и во вкладке "Устройства ввода"
принудительно указать "Микрофон гарнитуры" (или "Headset Microphone"), то он
активируется и исправно работает.

Если переподключить гарнитуру, то ошибка возвращается.

На первый взгляд ошибка может показаться тривиальной и решаемой в утилите hdajackretask, упоминаемой ранее. Однако, согласно dmesg драйвер видит микрофон гарнитуры:

snd_hda_intel 0000:00:1f.3: Codec #0 successfully probed, retry count = 0
snd_hda_codec_realtek hdaudioC0D0: autoconfig for ALC256: line_outs=1 (0x14/0x0/0x0/0x0/0x0) type:speaker
snd_hda_codec_realtek hdaudioC0D0:    speaker_outs=0 (0x0/0x0/0x0/0x0/0x0)
snd_hda_codec_realtek hdaudioC0D0:    hp_outs=1 (0x21/0x0/0x0/0x0/0x0)
snd_hda_codec_realtek hdaudioC0D0:    mono: mono_out=0x0
snd_hda_codec_realtek hdaudioC0D0:    inputs:
snd_hda_codec_realtek hdaudioC0D0:      Headset Mic=0x19
snd_hda_codec_realtek hdaudioC0D0:      Internal Mic=0x12

И любые попытки изменения конфигурации для пина 0x19 оказались безуспешны. В таком случае есть смысл посмотреть на коммиты ядра, относящиеся к соответствующему драйверу (snd_hda_codec_realtek) по ключевым словам "Mic", "Headset".

Например:

$ git log -p --grep="mic\|headset" -i -- sound/pci/hda/patch_realtek.c

Смотрим описание коммитов и находим наиболее подходящий по проблеме:

ALSA: hda/realtek - Fix inactive headset mic jack

commit daf6c4681a74034d5723e2fb761e0d7f3a1ca18f upstream.

This patch adds the existing fixup to certain TF platforms implementing
the ALC274 codec with a headset jack. It fixes/activates the inactive
microphone of the headset.

В котором добавляется quirk в структуре alc269_fixup_tbl[] :

+       SND_PCI_QUIRK(0x1d05, 0x1387, "TongFang GMxIXxx", ALC2XX_FIXUP_HEADSET_MIC),

Смотрим, что делает quirk, для этого ищем коммит с его первым упоминанием:

$ git log -p -S "ALC2XX_FIXUP_HEADSET_MIC" --reverse -- sound/pci/hda/patch_realtek.c

Выдает первым этот коммит :

ALSA: hda/realtek - Fixed ASUS platform headset Mic issue

ASUS platform Headset Mic was disable by default.
Assigned verb table for Mic pin will enable it.

Похоже на нашу проблему, но в изменениях не предусмотрена подмена модели и применение квирка "на лету". Поэтому внесем изменения в код драйвера, пересоберем и проверим:

1) Устанавливаем пакет kernel-headers-modules для целевого ядра

2) Клонируем исходный код драйвера

3) Переходим в каталог драйвера:

$ cd sound/pci/hda/

4) Вносим изменения в файл patch_realtek.c:

--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -10435,6 +10435,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
   SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2),
+  SND_PCI_QUIRK(0x1043, 0x1e1f, "ASUS Vivobook 15 X1504VAP", ALC2XX_FIXUP_HEADSET_MIC),
   SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS),

здесь значения 0x1043 и 0x1e1f берутся из данных об Subsystem ID кодека в выводе скрипта alsa-info.sh:

Codec: Realtek ALC256
Vendor Id: 0x10ec0256
Subsystem Id: 0x10431e1f

5) Оставляем в Makefile интересующие цели:

Makefile:

snd-hda-codec-realtek-objs :=   patch_realtek.o
obj-$(CONFIG_SND_HDA_CODEC_REALTEK) += snd-hda-codec-realtek.o

6) Собираем:

$ make -C /lib/modules/$(uname -r)/build M=$PWD

7) Устанавливаем:

$ sudo make -C /lib/modules/$(uname -r)/build M=$PWD modules_install

8) Перезагружаем систему (цепочка модулей звука большая и не всегда выгрузка удачная) и проверяем.

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

Если проблема решена, оформляем патч и отправляем в upstream.

Некорректная маршрутизация звука на моноблоке HP EliteOne 1000 G2 с кодеком Conexant CX20952

Проблема следующая:

1. не работает вывод звука на встроенные динамики моноблока;
2. при подключении наушников звук выводится одновременно и на встроенные динамики моноблока, и на наушники.

На первый взгляд выглядит как последствие инверсной логики детектирования разъема. Для обратной инверсии для hda кодеков предусмотрен специальный хинт inv_jack_detect, который можно переопределить в утилите hdajackretask или задать вручную, зная идентификаторы звуковой подсистемы:

su -
cat > /lib/firmware/hda-jack-retask.fw << EOF
[codec]
0x14f151d7 0x103c83e5 0

[hints]
inv_jack_detect=yes
EOF

echo "options snd-hda-intel patch=hda-jack-retask.fw" > /etc/modprobe.d/hda-jack-retask.conf

И действительно, после перезагрузки в динамиках появляется звук, но в наушниках пропадает. Значит, проблема в конфигурации нод кодека, которая осуществляется на регистровом уровне аудио кодека, но которую нельзя решить обычными квирками/хинтами. Следовательно, убираем применение хинта и возвращаем в состояние по-умолчанию.

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

На ПК с ОС Linux где есть проблема со звуком загружаем с другого носителя ОС Windows, далее снова загружаем с носителя ОС Linux и звук работает корректно (при выборе динамиков звук идет на динамики, при выборе/подключении наушников звук идет только в наушники) до момента выключения ПК с отключением питания (провод из розетки).

Первым делом следует проверить различие логов, сгенерированных скриптом alsa-info.sh.

diff между некорректным и корректным поведением звуковой подсистемы показал различие в настройках управления пином виджета 0x1d:

< Pin-ctls: 0xc0: OUT HP
> Pin-ctls: 0x80: HP

Однако этот пин (0x1d) не конфигурируется драйвером линукс:

snd_hda_intel 0000:00:1f.3: Codec #0 successfully probed, retry count = 0
snd_hda_codec_conexant hdaudioC0D0: CX20952: BIOS auto-probing.
snd_hda_codec_conexant hdaudioC0D0: autoconfig for CX20952: line_outs=1 (0x17/0x0/0x0/0x0/0x0) type:speaker
snd_hda_codec_conexant hdaudioC0D0:    speaker_outs=0 (0x0/0x0/0x0/0x0/0x0)
snd_hda_codec_conexant hdaudioC0D0:    hp_outs=1 (0x16/0x0/0x0/0x0/0x0)
snd_hda_codec_conexant hdaudioC0D0:    mono: mono_out=0x0
snd_hda_codec_conexant hdaudioC0D0:    inputs:
snd_hda_codec_conexant hdaudioC0D0:      Internal Mic=0x1a
snd_hda_codec_conexant hdaudioC0D0:      Mic=0x19

Похожих проблем для кодеков conexant и realtek в истории коммитов нет, поэтому можно попробовать принудительно прописывать нужное значение 0x80 для пина 0x1d при работе с конкретной печатной платой, для чего был успешно протестирован и отправлен патч.

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