xref: /linux/Documentation/sound/hd-audio/realtek-pc-beep.rst (revision ead5d1f4d877e92c051e1a1ade623d0d30e71619)
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