diff options
author | Vladimir Kondratyev <wulf@FreeBSD.org> | 2017-10-19 20:28:04 +0000 |
---|---|---|
committer | Vladimir Kondratyev <wulf@FreeBSD.org> | 2017-10-19 20:28:04 +0000 |
commit | 0f1ca5355fe0e666903e15ba3cd0277166156061 (patch) | |
tree | b1c15ac63c3ea4447e73477dece01c315efb0ed5 /sys/dev/usb/usb_hid.c | |
parent | b99304f34f675d4d07bae220e70cfb36ed07a620 (diff) | |
download | src-0f1ca5355fe0e666903e15ba3cd0277166156061.tar.gz src-0f1ca5355fe0e666903e15ba3cd0277166156061.zip |
MFC r322695:
Add support for generic MS Windows 7/8/10-compatible USB HID touchscreens
found in many laptops.
Reviewed by: hps, gonzo, bcr (manpages)
Approved by: gonzo (mentor)
Differential Revision: https://reviews.freebsd.org/D12017
Notes
Notes:
svn path=/stable/11/; revision=324769
Diffstat (limited to 'sys/dev/usb/usb_hid.c')
-rw-r--r-- | sys/dev/usb/usb_hid.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/sys/dev/usb/usb_hid.c b/sys/dev/usb/usb_hid.c index fe85f0c5560c..2c045dbed442 100644 --- a/sys/dev/usb/usb_hid.c +++ b/sys/dev/usb/usb_hid.c @@ -849,6 +849,80 @@ usbd_req_get_hid_desc(struct usb_device *udev, struct mtx *mtx, } /*------------------------------------------------------------------------* + * calculate HID item resolution. unit/mm for distances, unit/rad for angles + *------------------------------------------------------------------------*/ +int32_t +hid_item_resolution(struct hid_item *hi) +{ + /* + * hid unit scaling table according to HID Usage Table Review + * Request 39 Tbl 17 http://www.usb.org/developers/hidpage/HUTRR39b.pdf + */ + static const int64_t scale[0x10][2] = { + [0x00] = { 1, 1 }, + [0x01] = { 1, 10 }, + [0x02] = { 1, 100 }, + [0x03] = { 1, 1000 }, + [0x04] = { 1, 10000 }, + [0x05] = { 1, 100000 }, + [0x06] = { 1, 1000000 }, + [0x07] = { 1, 10000000 }, + [0x08] = { 100000000, 1 }, + [0x09] = { 10000000, 1 }, + [0x0A] = { 1000000, 1 }, + [0x0B] = { 100000, 1 }, + [0x0C] = { 10000, 1 }, + [0x0D] = { 1000, 1 }, + [0x0E] = { 100, 1 }, + [0x0F] = { 10, 1 }, + }; + int64_t logical_size; + int64_t physical_size; + int64_t multiplier; + int64_t divisor; + int64_t resolution; + + switch (hi->unit) { + case HUM_CENTIMETER: + multiplier = 1; + divisor = 10; + break; + case HUM_INCH: + multiplier = 10; + divisor = 254; + break; + case HUM_RADIAN: + multiplier = 1; + divisor = 1; + break; + case HUM_DEGREE: + multiplier = 573; + divisor = 10; + break; + default: + return (0); + } + + if ((hi->logical_maximum <= hi->logical_minimum) || + (hi->physical_maximum <= hi->physical_minimum) || + (hi->unit_exponent < 0) || (hi->unit_exponent >= nitems(scale))) + return (0); + + logical_size = (int64_t)hi->logical_maximum - + (int64_t)hi->logical_minimum; + physical_size = (int64_t)hi->physical_maximum - + (int64_t)hi->physical_minimum; + /* Round to ceiling */ + resolution = logical_size * multiplier * scale[hi->unit_exponent][0] / + (physical_size * divisor * scale[hi->unit_exponent][1]); + + if (resolution > INT32_MAX) + return (0); + + return (resolution); +} + +/*------------------------------------------------------------------------* * hid_is_mouse * * This function will decide if a USB descriptor belongs to a USB mouse. |