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