• Nikolai Kondrashov's avatar
    HID: Fix unit exponent parsing again · ad0e669b
    Nikolai Kondrashov authored
    Revert some changes done in 77463838.
    
    Revert all changes done in hidinput_calc_abs_res as it mistakingly used
    "Unit" item exponent nibbles to affect resolution value. This wasn't
    breaking resolution calculation of relevant axes of any existing
    devices, though, as they have only one dimension to their units and thus
    1 in the corresponding nible.
    
    Revert to reading "Unit Exponent" item value as a signed integer in
    hid_parser_global to fix reading specification-complying values. This
    fixes resolution calculation of devices complying to the HID standard,
    including Huion, KYE, Waltop and UC-Logic graphics tablets which have
    their report descriptors fixed by the drivers.
    
    Explanations follow.
    
    There are two "unit exponents" in HID specification and it is important
    not to mix them. One is the global "Unit Exponent" item and another is
    nibble values in the global "Unit" item. See 6.2.2.7 Global Items.
    
    The "Unit Exponent" value is just a signed integer and is used to scale
    the integer resolution unit values, so fractions can be expressed.
    
    The nibbles of "Unit" value are used to select the unit system (nibble
    0), and presence of a particular basic unit type in the unit formula and
    its *exponent* (or power, nibbles 1-6). And yes, the latter is in two
    complement and zero means absence of the unit type.
    
    Taking the representation example of (integer) joules from the
    specification:
    
    [mass(grams)][length(centimeters)^2][time(seconds)^-2] * 10^-7
    
    the "Unit Exponent" would be -7 (or 0xF9, if stored as a byte) and the
    "Unit" value would be 0xE121, signifying:
    
    Nibble  Part        Value   Meaning
    -----   ----        -----   -------
    0       System      1       SI Linear
    1       Length      2       Centimeters^2
    2       Mass        1       Grams
    3       Time        -2      Seconds^-2
    
    To give the resolution in e.g. hundredth of joules the "Unit Exponent"
    item value should have been -9.
    
    See also the examples of "Unit" values for some common units in the same
    chapter.
    
    However, there is a common misunderstanding about the "Unit Exponent"
    value encoding, where it is assumed to be stored the same as nibbles in
    "Unit" item. This is most likely due to the specification being a bit
    vague and overloading the term "unit exponent". This also was and still
    is proliferated by the official "HID Descriptor Tool", which makes this
    mistake and stores "Unit Exponent" as such. This format is also
    mentioned in books such as "USB Complete" and in Microsoft's hardware
    design guides.
    
    As a result many devices currently on the market use this encoding and
    so the driver should support them.
    Signed-off-by: default avatarNikolai Kondrashov <spbnick@gmail.com>
    Acked-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
    Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
    ad0e669b
hid-input.c 42.3 KB