Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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