1*f1280904SThomas Hebb=============================== 2*f1280904SThomas HebbRealtek PC Beep Hidden Register 3*f1280904SThomas Hebb=============================== 4*f1280904SThomas Hebb 5*f1280904SThomas HebbThis file documents the "PC Beep Hidden Register", which is present in certain 6*f1280904SThomas HebbRealtek HDA codecs and controls a muxer and pair of passthrough mixers that can 7*f1280904SThomas Hebbroute audio between pins but aren't themselves exposed as HDA widgets. As far 8*f1280904SThomas Hebbas I can tell, these hidden routes are designed to allow flexible PC Beep output 9*f1280904SThomas Hebbfor codecs that don't have mixer widgets in their output paths. Why it's easier 10*f1280904SThomas Hebbto hide a mixer behind an undocumented vendor register than to just expose it 11*f1280904SThomas Hebbas a widget, I have no idea. 12*f1280904SThomas Hebb 13*f1280904SThomas HebbRegister Description 14*f1280904SThomas Hebb==================== 15*f1280904SThomas Hebb 16*f1280904SThomas HebbThe register is accessed via processing coefficient 0x36 on NID 20h. Bits not 17*f1280904SThomas Hebbidentified below have no discernible effect on my machine, a Dell XPS 13 9350:: 18*f1280904SThomas Hebb 19*f1280904SThomas Hebb MSB LSB 20*f1280904SThomas Hebb +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 21*f1280904SThomas Hebb | |h|S|L| | B |R| | Known bits 22*f1280904SThomas Hebb +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 23*f1280904SThomas Hebb |0|0|1|1| 0x7 |0|0x0|1| 0x7 | Reset value 24*f1280904SThomas Hebb +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25*f1280904SThomas Hebb 26*f1280904SThomas Hebb1Ah input select (B): 2 bits 27*f1280904SThomas Hebb When zero, expose the PC Beep line (from the internal beep generator, when 28*f1280904SThomas Hebb enabled with the Set Beep Generation verb on NID 01h, or else from the 29*f1280904SThomas Hebb external PCBEEP pin) on the 1Ah pin node. When nonzero, expose the headphone 30*f1280904SThomas Hebb jack (or possibly Line In on some machines) input instead. If PC Beep is 31*f1280904SThomas Hebb selected, the 1Ah boost control has no effect. 32*f1280904SThomas Hebb 33*f1280904SThomas HebbAmplify 1Ah loopback, left (L): 1 bit 34*f1280904SThomas Hebb Amplify the left channel of 1Ah before mixing it into outputs as specified 35*f1280904SThomas Hebb by h and S bits. Does not affect the level of 1Ah exposed to other widgets. 36*f1280904SThomas Hebb 37*f1280904SThomas HebbAmplify 1Ah loopback, right (R): 1 bit 38*f1280904SThomas Hebb Amplify the right channel of 1Ah before mixing it into outputs as specified 39*f1280904SThomas Hebb by h and S bits. Does not affect the level of 1Ah exposed to other widgets. 40*f1280904SThomas Hebb 41*f1280904SThomas HebbLoopback 1Ah to 21h [active low] (h): 1 bit 42*f1280904SThomas Hebb When zero, mix 1Ah (possibly with amplification, depending on L and R bits) 43*f1280904SThomas Hebb into 21h (headphone jack on my machine). Mixed signal respects the mute 44*f1280904SThomas Hebb setting on 21h. 45*f1280904SThomas Hebb 46*f1280904SThomas HebbLoopback 1Ah to 14h (S): 1 bit 47*f1280904SThomas Hebb When one, mix 1Ah (possibly with amplification, depending on L and R bits) 48*f1280904SThomas Hebb into 14h (internal speaker on my machine). Mixed signal **ignores** the mute 49*f1280904SThomas Hebb setting on 14h and is present whenever 14h is configured as an output. 50*f1280904SThomas Hebb 51*f1280904SThomas HebbPath diagrams 52*f1280904SThomas Hebb============= 53*f1280904SThomas Hebb 54*f1280904SThomas Hebb1Ah input selection (DIV is the PC Beep divider set on NID 01h):: 55*f1280904SThomas Hebb 56*f1280904SThomas Hebb <Beep generator> <PCBEEP pin> <Headphone jack> 57*f1280904SThomas Hebb | | | 58*f1280904SThomas Hebb +--DIV--+--!DIV--+ {1Ah boost control} 59*f1280904SThomas Hebb | | 60*f1280904SThomas Hebb +--(b == 0)--+--(b != 0)--+ 61*f1280904SThomas Hebb | 62*f1280904SThomas Hebb >1Ah (Beep/Headphone Mic/Line In)< 63*f1280904SThomas Hebb 64*f1280904SThomas HebbLoopback of 1Ah to 21h/14h:: 65*f1280904SThomas Hebb 66*f1280904SThomas Hebb <1Ah (Beep/Headphone Mic/Line In)> 67*f1280904SThomas Hebb | 68*f1280904SThomas Hebb {amplify if L/R} 69*f1280904SThomas Hebb | 70*f1280904SThomas Hebb +-----!h-----+-----S-----+ 71*f1280904SThomas Hebb | | 72*f1280904SThomas Hebb {21h mute control} | 73*f1280904SThomas Hebb | | 74*f1280904SThomas Hebb >21h (Headphone)< >14h (Internal Speaker)< 75*f1280904SThomas Hebb 76*f1280904SThomas HebbBackground 77*f1280904SThomas Hebb========== 78*f1280904SThomas Hebb 79*f1280904SThomas HebbAll Realtek HDA codecs have a vendor-defined widget with node ID 20h which 80*f1280904SThomas Hebbprovides access to a bank of registers that control various codec functions. 81*f1280904SThomas HebbRegisters are read and written via the standard HDA processing coefficient 82*f1280904SThomas Hebbverbs (Set/Get Coefficient Index, Set/Get Processing Coefficient). The node is 83*f1280904SThomas Hebbnamed "Realtek Vendor Registers" in public datasheets' verb listings and, 84*f1280904SThomas Hebbapart from that, is entirely undocumented. 85*f1280904SThomas Hebb 86*f1280904SThomas HebbThis particular register, exposed at coefficient 0x36 and named in commits from 87*f1280904SThomas HebbRealtek, is of note: unlike most registers, which seem to control detailed 88*f1280904SThomas Hebbamplifier parameters not in scope of the HDA specification, it controls audio 89*f1280904SThomas Hebbrouting which could just as easily have been defined using standard HDA mixer 90*f1280904SThomas Hebband selector widgets. 91*f1280904SThomas Hebb 92*f1280904SThomas HebbSpecifically, it selects between two sources for the input pin widget with Node 93*f1280904SThomas HebbID (NID) 1Ah: the widget's signal can come either from an audio jack (on my 94*f1280904SThomas Hebblaptop, a Dell XPS 13 9350, it's the headphone jack, but comments in Realtek 95*f1280904SThomas Hebbcommits indicate that it might be a Line In on some machines) or from the PC 96*f1280904SThomas HebbBeep line (which is itself multiplexed between the codec's internal beep 97*f1280904SThomas Hebbgenerator and external PCBEEP pin, depending on if the beep generator is 98*f1280904SThomas Hebbenabled via verbs on NID 01h). Additionally, it can mix (with optional 99*f1280904SThomas Hebbamplification) that signal onto the 21h and/or 14h output pins. 100*f1280904SThomas Hebb 101*f1280904SThomas HebbThe register's reset value is 0x3717, corresponding to PC Beep on 1Ah that is 102*f1280904SThomas Hebbthen amplified and mixed into both the headphones and the speakers. Not only 103*f1280904SThomas Hebbdoes this violate the HDA specification, which says that "[a vendor defined 104*f1280904SThomas Hebbbeep input pin] connection may be maintained *only* while the Link reset 105*f1280904SThomas Hebb(**RST#**) is asserted", it means that we cannot ignore the register if we care 106*f1280904SThomas Hebbabout the input that 1Ah would otherwise expose or if the PCBEEP trace is 107*f1280904SThomas Hebbpoorly shielded and picks up chassis noise (both of which are the case on my 108*f1280904SThomas Hebbmachine). 109*f1280904SThomas Hebb 110*f1280904SThomas HebbUnfortunately, there are lots of ways to get this register configuration wrong. 111*f1280904SThomas HebbLinux, it seems, has gone through most of them. For one, the register resets 112*f1280904SThomas Hebbafter S3 suspend: judging by existing code, this isn't the case for all vendor 113*f1280904SThomas Hebbregisters, and it's led to some fixes that improve behavior on cold boot but 114*f1280904SThomas Hebbdon't last after suspend. Other fixes have successfully switched the 1Ah input 115*f1280904SThomas Hebbaway from PC Beep but have failed to disable both loopback paths. On my 116*f1280904SThomas Hebbmachine, this means that the headphone input is amplified and looped back to 117*f1280904SThomas Hebbthe headphone output, which uses the exact same pins! As you might expect, this 118*f1280904SThomas Hebbcauses terrible headphone noise, the character of which is controlled by the 119*f1280904SThomas Hebb1Ah boost control. (If you've seen instructions online to fix XPS 13 headphone 120*f1280904SThomas Hebbnoise by changing "Headphone Mic Boost" in ALSA, now you know why.) 121*f1280904SThomas Hebb 122*f1280904SThomas HebbThe information here has been obtained through black-box reverse engineering of 123*f1280904SThomas Hebbthe ALC256 codec's behavior and is not guaranteed to be correct. It likely 124*f1280904SThomas Hebbalso applies for the ALC255, ALC257, ALC235, and ALC236, since those codecs 125*f1280904SThomas Hebbseem to be close relatives of the ALC256. (They all share one initialization 126*f1280904SThomas Hebbfunction.) Additionally, other codecs like the ALC225 and ALC285 also have this 127*f1280904SThomas Hebbregister, judging by existing fixups in ``patch_realtek.c``, but specific 128*f1280904SThomas Hebbdata (e.g. node IDs, bit positions, pin mappings) for those codecs may differ 129*f1280904SThomas Hebbfrom what I've described here. 130