This mini-guide helps correct issues with internal speakers or the headphone jack outputting static and not functioning after sleep. It deprecates CodecCommander, ALC_JackFix, my JackFix script, and all other combo jack helpers by correcting the layout in AppleALC.
- Xcode
- The latest AppleALC source code tested to build cleanly
- A Codec Dump from Linux or OpenCore
- ProperTree
Issues related to speaker or headphone static, or the headphone jack not switching outputs/inputs tends to be related to EAPD and jack sense being misconfigured in your AppleALC layout. To correct this condition we need to review the codec dump to verify that your codec implementation supports both EAPD (EAPD Detect) on all of your output switches and jack sense (In Detect) on your jack microphone.
Review your codec dump to determine that both the internal and headphone output switches support EAPD. Using my codec dump as the example we can see that output switch nodes 0x14 and 0x21 support EAPD (EAPD Detect).
Node 0x14 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
Control: name="Speaker Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=Out, idx=0, ofs=0
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x00 0x00]
Pincap 0x00010014: OUT EAPD Detect
EAPD 0x2: EAPD
Pin Default 0x90170110: [Fixed] Speaker at Int N/A
Conn = Analog, Color = Unknown
DefAssociation = 0x1, Sequence = 0x0
Misc = NO_PRESENCE
Pin-ctls: 0x40: OUT
Unsolicited: tag=00, enabled=0
Power states: D0 D1 D2 D3 EPSS
Power: setting=D0, actual=D0
Connection: 1
0x02
Node 0x21 [Pin Complex] wcaps 0x40058d: Stereo Amp-Out
Control: name="Headphone Playback Switch", index=0, device=0
ControlAmp: chs=3, dir=Out, idx=0, ofs=0
Amp-Out caps: ofs=0x00, nsteps=0x00, stepsize=0x00, mute=1
Amp-Out vals: [0x00 0x00]
Pincap 0x0001001c: OUT HP EAPD Detect
EAPD 0x2: EAPD
Pin Default 0x04211020: [Jack] HP Out at Ext Right
Conn = 1/8, Color = Black
DefAssociation = 0x2, Sequence = 0x0
Pin-ctls: 0xc0: OUT HP
Unsolicited: tag=01, enabled=1
Power states: D0 D1 D2 D3 EPSS
Power: setting=D0, actual=D0
Connection: 2
0x02 0x03*
Repeat evaluating for jack sense. Using my codec dump as the example we can see that the headphone jack microphone at node 0x19 supports jack sense (IN Detect).
Node 0x19 [Pin Complex] wcaps 0x40048b: Stereo Amp-In
Control: name="Mic Boost Volume", index=0, device=0
ControlAmp: chs=3, dir=In, idx=0, ofs=0
Amp-In caps: ofs=0x00, nsteps=0x03, stepsize=0x27, mute=0
Amp-In vals: [0x00 0x00]
Pincap 0x00003724: IN Detect
Vref caps: HIZ 50 GRD 80 100
Pin Default 0x04a11040: [Jack] Mic at Ext Right
Conn = 1/8, Color = Black
DefAssociation = 0x4, Sequence = 0x0
Pin-ctls: 0x24: IN VREF_80
Unsolicited: tag=02, enabled=1
Power states: D0 D1 D2 D3 EPSS
Power: setting=D0, actual=D0
Now that you have the node information, it's time to check your layout in the AppleALC source code, and correct the verbs if necessary. The pin configuration data for all AppleALC layouts is located in the following Info.plist:
AppleALC/Resources/PinConfigs.kext/Contents/Info.plist
To open this plist, browse to AppleALC/Resources. Right click PinConfigs.kext and select Show Package Contents. Open Contents, and then open the Info.plist with ProperTree. Browse the info.plist to find your codec and layout. The configuration data that we will validate and update is stored in the ConfigData and WakeConfigData keys. AppleALC uses the ConfigData key to initialize the codec, and WakeConfigData is sent to the codec after each wake event.
Before we continue, we should talk about the pin complex. In the ConfigData and WakeConfigData above, you may notice that there are many 8 bit hexidecimal blocks of data. Each of these blocks of data is a pin complex. They represent configuration data about your codec that AppleALC sends to AppleHDA. You can decode a pin complex like this:
0 14 70C 02
│ └┬┘ └┬┘ └┬┘
│ │ │ │
│ │ │ │
│ │ │ │
│ │ │ └───── Instruction
│ │ └────── Verb
│ └─────── Node Location
└──────── Codec # (Usually 0)
In the example above you can see that AppleALC is sending an instruction of 02 to verb 70C along node 14. Verb 70C is the EAPD enable verb, and instruction 02 is enabling EAPD. Node 14 represents the internal speaker.
For this guide we will be focusing on two verbs, EAPD Enable and Pin Widget Control.
Verb | Function | Why we need it |
---|---|---|
70C | EAPD Enable | Enables the headphone jack switch |
707 | Pin Widget Control | Enables jack sense |
You can read about these verbs, and other configuration verbs in the Intel HDA specification manual.
As we can see above that after a wake, the EAPD enable verb is being enabled on the internal speaker, but not to the headphone jack. Let's look at the data to see exactly what's happening.
Since we know that the EAPD Enable verb is 70C, we can see below that it is only being sent to node 0x14. This will need to be corrected to also send the verb to node 0x21. We do not need to send a pin widget control verb to our output devices.
01471C10 01471D01 01471E13 01471F99 01470C02 02171C20 02171D10 02171E21 02171F13 01971C40 01971D11 01971EA1 01971F93
Evaluating the data below we learn that as during codec initialization, the EAPD enable verb is only being sent to node 0x14. This will also need to be corrected to send the EAPD enable verb to node 0x21. Additionally, the pin widget control verb is missing and will need to be added. The instruction we will send to the pin widget control verb is 25.
01470C02
Now that we have determined what we need to correct in our layout data, let's correct it. Using the pin complex breakdown above, create new pin complexes for your layout and add them to the appropriate keys under your codec and layout.
01471C10 01471D01 01471E13 01471F99 01470C02 02171C20 02171D10 02171E21 02171F13 02170C02 01971C40 01971D11 01971EA1 01971F93
01470C02 02170C02 01970725
Now that you've corrected the layout, it's time to build AppleALC and test it. Be sure to remove VerbStub, CodecCommander, ALCWakeFix, ComboJack, ALC Plug Fix, JackFix, and any other helper that may be installed as those helpers can clobber the fix. If you've successfully corrected the layout, let it soak for a few days of use and then consider submitting the fix to AppleALC as a pull request.
This guide helps me a lot. Thanks.