Der Ärger mit dem Ton
Version vom 29.09.2009
Mikrofon funktioniert nicht
Aktueller Hinweis
Seit ich auf Kernelversion 2.6.31.1 umgestiegen bin, funktioniert der Ton problemlos. Erkannt wird nurnoch der ALC888 Codec, d.h. es treten keine Probleme mehr mit den Mixerelementen auf. Lädt man das Modul nun mit folgenden Parametern, schalten die Notebooklautsprecher korrekt ab, sobald ein Kopfhörer eingesteckt wird:Seeschlange:~# modprobe snd-hda-intel enable_msi=1 model=laptop
Vorwort
Ich bin seit Jahren eingefleischter Linuxfan, benutzte dafür jedoch häufig nur ältere Hardware. So dass sich viele Probleme durch updaten von Kernel oder Userspace lösen ließen oder sich im Internet viele hilfreiche Ansätze fanden. Nach dem Kauf eines neuen Notebooks verzweifelte ich jedoch bereits beim Einrichten der Soundkarte - ein Problem, dass mich kurz vor die Windowsinstallation trieb. So weit ist es glücklicherweise nicht gekommen, obwohl das Ergebnis auch heute noch nicht so ist, wie ich es mir wünschen würde.Vorab sei gesagt, dass ich mich hier nicht auf die Einrichtung eines Surroundsystems beziehe, sondern nur eine Audioausgabe auf Notebooklautsprechern und Kopfhörern wünsche. Funktioniert die Lautstärkeregelung auch noch, bin ich zufrieden. Das Kompilieren eines eigenen Kernels ist nicht schwierig, allerdings erfordet es ein gewisses Verständnis über die eingesetzte Distribution. Viele Distributionen verwenden extrem verpatchte Kernel, damit es beim Hochfahren schön bunt ist oder (wenigstens sinnvoll) die Installation auf jedem System funktioniert. Man sollte sich also vor der Arbeit am Kernel sicher sein, dass man über die Quellcodes des aktuell eingesetzten Kernels verfügt. Ansonsten kann es im schlimmsten Fall dazu führen, dass das System nicht mehr hochfährt. Für erfahrene Anwender stellt sich kein Problem dar, für Einsteiger ist es Grund für eine Neuinstallation.
Kernel kompilieren - Teil 1
Die erste große Frage war natürlich, welche Hardware im Notebook verbaut ist. Dies lässt sich relativ leicht feststellen:michael@Seeschlange:~$ lspci | grep Audio 00:1b.0 Audio device: Intel Corporation 82801H (ICH8 Family) HD Audio Controller (rev 04) michael@Seeschlange:~$
Also eine Intel HD Karte, die sich im Kernel unter Device Drivers -> Sound -> Advanced Linux Sound Architecture -> PCI devices -> Intel HD Audio finden lässt. Sicherheitshalber werden erstmal alle Codecs mitkompiliert. Nachdem kompilieren des Kernels mit make modules && make modules_installlässt sich das frische Modul hoffentlich einbinden. Hier stieß ich auf mein erstes Problem:
Seeschlange:~# modprobe snd-hda-intel Seeschlange:~# dmesg | tail ACPI: PCI Interrupt 0000:00:1b.0[A] -> GSI 22 (level, low) -> IRQ 22 PCI: Setting latency timer of device 0000:00:1b.0 to 64 hda_codec: Unknown model for ALC883, trying auto-probe from BIOS... hda_codec: Unknown model for ALC268, trying auto-probe from BIOS... hda_codec: Cannot set up configuration from BIOS. Using base mode...SPDIF already defined ACPI: PCI interrupt for device 0000:00:1b.0 disabled HDA Intel: probe of 0000:00:1b.0 failed with error -16Seeschlange:~#Das Modul wurde also erfolgreich geladen, konnte die Soundkarte jedoch nicht aktivieren. Nach einigem Probieren fand ich dann die Lösung: Der Treiber sollte theoretisch selbstständig erkennen, welche Hardware vorhanden ist, funktioniert das, so wie hier, nicht, kann man ihm mit einem Parameter auf die Sprünge helfen:
Seeschlange:~# rmmod snd-hda-intel; modprobe snd-hda-intel model=medion Seeschlange:~# dmesg | tail ACPI: PCI Interrupt 0000:00:1b.0[A] -> GSI 22 (level, low) -> IRQ 22 PCI: Setting latency timer of device 0000:00:1b.0 to 64 hda_codec: Unknown model for ALC268, trying auto-probe from BIOS... hda_codec: Cannot set up configuration from BIOS. Using base mode...Seeschlange:~#Das sieht schon etwas besser aus, allerdings ging es noch besser:
Seeschlange:~# rmmod snd-hda-intel; modprobe snd-hda-intel model=acer Seeschlange:~# dmesg | tail ACPI: PCI Interrupt 0000:00:1b.0[A] -> GSI 22 (level, low) -> IRQ 22 PCI: Setting latency timer of device 0000:00:1b.0 to 64 Seeschlange:~#Keine Fehlermeldungen mehr, die Karte scheint richtig "erkannt" wurden zu sein und der Kernel scheint sie zu akzeptieren - Hübsch! Letztendlich ist Ausprobieren angesagt. Eine vollständige Auflistung der unterstützten Modelle findet man in der Kerneldokumentation (häufig /usr/src/linux/Documentation/sound/alsa/ALSA-Configuration.txt) im Abschnitt "Module snd-hda-intel". Hat man die perfekte Einstellung gefunden, sollte dies dem System dauerhaft beigebracht werden - das ist jedoch von Distribution zu Distribution anders realisierbar. Unter Debian und vielen anderen, ist es mit einem
Seeschlange:~# echo options snd-hda-intel model=acer > /etc/modprobe.d/snd-hda-intel-myoptionsbereits getan. Wer Glück hat, kann die Soundkarte benutzen. Diverse Googleergebnisse zeigen jedoch, dass es häufig nicht ganz so einfach ist...
Kernel kompilieren - Teil 2
...denn aktuelle Soundkarten verfügen über mehrere Soundchips, mit teilweise gleichen Bezeichnungen und damit kann das ALSA-System momentan noch nicht umgehen. Ob dieses Problem besteht, zeigt ein sehr einfacher Versuch:michael@Seeschlange:~$ alsamixer ALSA lib simple_none.c:1591:(simple_add1) helem (MIXER,'Headphone Playback Switch',0,2,0) appears twice or more alsamixer: function snd_mixer_load failed: Invalid argumentErscheint dieser oder ein ähnlicher Fehler, ist man betroffen und ab hier helfen leider keine Parameter oder (zum heutigen Stand der Dinge) Updates. Der Fehler wird auf Grund oben beschriebener Sachlage verursacht und liegt in den ALSA-Bibliotheken. Da es jedoch einfacher ist den Kernel zu patchen (ein großer Vorteil von Linux gegenüber Windows), gehe ich den einfachsten Weg: (den schließlich soll das Notebook ja endlich mal ein Tönchen ausspucken) Erstmal sollte man sich darüber bewusst werden, welchen Codec die Soundkarte verwendet. Dies ist mit
michael@Seeschlange:~$ cat /proc/asound/Intel/codec#?|grep Codec Codec: Realtek ALC888 Codec: Realtek ALC268 michael@Seeschlange:~$schnell gemacht. In meinem Fall handelt es sich um die Realtekcodecs ALC888 und ALC268. Ausgehend von der Fehlermeldung des alsamixers scheinen beide ein Mixerelement anzubieten, dass sich "Headphone Playback Switch" nennt. Das Problem ist erkannt, die Ursache gefunden, nun geht's an die Lösung: Dazu muss in einem Editor die Datei /usr/src/linux/sound/pci/hda/patch_realtek.c geöffnet und in ihr die Zeichenkette "Headphone Playback Switch" gesucht werden (je nach Codechersteller ist natürlich eine andere Datei in diesem Verzeichnis zu wählen). Erfahrungsgemäß kommt diese Zeichenkette viele Male vor, ist jedoch nur einmal für das Problem verantwortlich. Die Datei, es handelt sich übrigens um Quellcode der Programmiersprache C, ist in mehrere Blöcke unterteilt. Diese Blöcke orientieren sich im Allgemeinen an den diversen Codecs. Findet man die gesuchte Zeichenkette, sollte also sichergestellt werden, dass wenige Zeilen darüber die Codecbezeichnung (Liebe C-Programmierer, bitte schlagt mich nicht, für diese schlechte Beschreibung) steht - ansonsten macht man sich unnötige Arbeit. In meinem Fall, sieht es so aus:
static struct snd_kcontrol_new alc268_base_mixer[] = { /* output mixer control */ HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), HDA_CODEC_VOLUME("Line In Boost", 0x1a, 0, HDA_INPUT), { } };In der roten Zeile ist die Codecbezeichnung versteckt, in der gelben liegt die problematische Bezeichnung. In dieser Zeile muss auch "Headphone Playback Switch" durch etwas anderes, z.B. "Kopfhoererschalter" ersetzt werden. Das war's! Datei speichern und schließen und das Kernelmodul erneut mittels
Seeschlange:/usr/src/linux# rm sound/pci/hda/patch_realtek.o Seeschlange:/usr/src/linux# make modules && make modules_install Seeschlange:/usr/src/linux# rmmod snd-hda-intel; modprobe snd-hda-intel Seeschlange:/usr/src/linux#kompilieren und neu laden. Die Wahrscheinlichkeit, dass der Alsamixer sofort startet ist gering, da in den meisten Fällen mehrere Mixerelemente umbenannt werden müssen. Wird exakt das gleiche Element angezeigt, wie das eben veränderte, so erfolgte die Änderung an der falschen Stelle. Einfach nochmal suchen und notfalls alle Vorkommen ändern! Das Ändern der Zeichenketten hat normalerweise keine Auswirkungen auf die Systemstabilität. Idealerweise sollten trotzdem nur sowenig Zeichenketten geändert werden, wie irgendwie möglich.
(Mein) Offenes Problem
Leider ist das Soundprojekt auf meinem Notebook noch nicht abgeschlossen. Wenn ich im Mixer "Headphones" aktiviere, so liegt auf dem Kopfhöreranschluss meines Notebooks ein entsprechendes Signal an. Dabei handelt es sich um eine exakte Kopie des Signals der Frontlautsprecher. Damit könnte ich leben, allerdings schalten diese nicht ab, wenn Kopfhörer eingesteckt sind und das Setzten des Stummschalters für die Frontlautsprecher des Notebooks lässt gleichzeitig die Kopfhörer verstummen. Die Codecs der zwei Soundchips weisen darauf hin, dass mein Notebook viel mehr kann. Theoretisch sollte es nicht nur möglich sein die Frontlautsprecher abzuschalten, sondern auch individuelle Inhalte auf Notebook und Kopfhörer zu verteilen. Damit wäre 7.1er Surround möglich.michael@Seeschlange:~$ aplay -l **** List of PLAYBACK Hardware Devices **** card 0: Intel [HDA Intel], device 0: ALC883 Analog [ALC883 Analog] Subdevices: 1/1 Subdevice #0: subdevice #0 card 0: Intel [HDA Intel], device 5: ALC268 Analog [ALC268 Analog] Subdevices: 1/1 Subdevice #0: subdevice #0 michael@Seeschlange:~$Findet beide Devices, allerdings bleibt die Ausgabe auf hw:0,5 stumm. Für die Lösung des Problems fehlt mir zur Zeit noch das genaue Verständnis der eingesetzten Codecs und der Funktionsweise von ALSA. Für Hinweise wäre ich dankbar! Die Lösung wird dann natürlich an dieser Stelle veröffentlicht!
Interna