summaryrefslogtreecommitdiffstats
path: root/Documentation/hid
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 10:05:51 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 10:05:51 +0000
commit5d1646d90e1f2cceb9f0828f4b28318cd0ec7744 (patch)
treea94efe259b9009378be6d90eb30d2b019d95c194 /Documentation/hid
parentInitial commit. (diff)
downloadlinux-upstream.tar.xz
linux-upstream.zip
Adding upstream version 5.10.209.upstream/5.10.209upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--Documentation/hid/hid-alps.rst180
-rw-r--r--Documentation/hid/hid-sensor.rst242
-rw-r--r--Documentation/hid/hid-transport.rst359
-rw-r--r--Documentation/hid/hiddev.rst251
-rw-r--r--Documentation/hid/hidraw.rst138
-rw-r--r--Documentation/hid/index.rst18
-rw-r--r--Documentation/hid/intel-ish-hid.rst485
-rw-r--r--Documentation/hid/uhid.rst193
8 files changed, 1866 insertions, 0 deletions
diff --git a/Documentation/hid/hid-alps.rst b/Documentation/hid/hid-alps.rst
new file mode 100644
index 000000000..e2f4c4c11
--- /dev/null
+++ b/Documentation/hid/hid-alps.rst
@@ -0,0 +1,180 @@
+==========================
+ALPS HID Touchpad Protocol
+==========================
+
+Introduction
+------------
+Currently ALPS HID driver supports U1 Touchpad device.
+
+U1 device basic information.
+
+========== ======
+Vender ID 0x044E
+Product ID 0x120B
+Version ID 0x0121
+========== ======
+
+
+HID Descriptor
+--------------
+
+======= ==================== ===== =======================================
+Byte Field Value Notes
+======= ==================== ===== =======================================
+0 wHIDDescLength 001E Length of HID Descriptor : 30 bytes
+2 bcdVersion 0100 Compliant with Version 1.00
+4 wReportDescLength 00B2 Report Descriptor is 178 Bytes (0x00B2)
+6 wReportDescRegister 0002 Identifier to read Report Descriptor
+8 wInputRegister 0003 Identifier to read Input Report
+10 wMaxInputLength 0053 Input Report is 80 Bytes + 2
+12 wOutputRegister 0000 Identifier to read Output Report
+14 wMaxOutputLength 0000 No Output Reports
+16 wCommandRegister 0005 Identifier for Command Register
+18 wDataRegister 0006 Identifier for Data Register
+20 wVendorID 044E Vendor ID 0x044E
+22 wProductID 120B Product ID 0x120B
+24 wVersionID 0121 Version 01.21
+26 RESERVED 0000 RESERVED
+======= ==================== ===== =======================================
+
+
+Report ID
+---------
+
+========== ================= =========================================
+ReportID-1 (Input Reports) (HIDUsage-Mouse) for TP&SP
+ReportID-2 (Input Reports) (HIDUsage-keyboard) for TP
+ReportID-3 (Input Reports) (Vendor Usage: Max 10 finger data) for TP
+ReportID-4 (Input Reports) (Vendor Usage: ON bit data) for GP
+ReportID-5 (Feature Reports) Feature Reports
+ReportID-6 (Input Reports) (Vendor Usage: StickPointer data) for SP
+ReportID-7 (Feature Reports) Flash update (Bootloader)
+========== ================= =========================================
+
+
+Data pattern
+------------
+
+===== ========== ===== =================
+Case1 ReportID_1 TP/SP Relative/Relative
+Case2 ReportID_3 TP Absolute
+ ReportID_6 SP Absolute
+===== ========== ===== =================
+
+
+Command Read/Write
+------------------
+To read/write to RAM, need to send a commands to the device.
+
+The command format is as below.
+
+DataByte(SET_REPORT)
+
+===== ======================
+Byte1 Command Byte
+Byte2 Address - Byte 0 (LSB)
+Byte3 Address - Byte 1
+Byte4 Address - Byte 2
+Byte5 Address - Byte 3 (MSB)
+Byte6 Value Byte
+Byte7 Checksum
+===== ======================
+
+Command Byte is read=0xD1/write=0xD2 .
+
+Address is read/write RAM address.
+
+Value Byte is writing data when you send the write commands.
+
+When you read RAM, there is no meaning.
+
+DataByte(GET_REPORT)
+
+===== ======================
+Byte1 Response Byte
+Byte2 Address - Byte 0 (LSB)
+Byte3 Address - Byte 1
+Byte4 Address - Byte 2
+Byte5 Address - Byte 3 (MSB)
+Byte6 Value Byte
+Byte7 Checksum
+===== ======================
+
+Read value is stored in Value Byte.
+
+
+Packet Format
+Touchpad data byte
+------------------
+
+
+======= ======= ======= ======= ======= ======= ======= ======= =====
+- b7 b6 b5 b4 b3 b2 b1 b0
+======= ======= ======= ======= ======= ======= ======= ======= =====
+1 0 0 SW6 SW5 SW4 SW3 SW2 SW1
+2 0 0 0 Fcv Fn3 Fn2 Fn1 Fn0
+3 Xa0_7 Xa0_6 Xa0_5 Xa0_4 Xa0_3 Xa0_2 Xa0_1 Xa0_0
+4 Xa0_15 Xa0_14 Xa0_13 Xa0_12 Xa0_11 Xa0_10 Xa0_9 Xa0_8
+5 Ya0_7 Ya0_6 Ya0_5 Ya0_4 Ya0_3 Ya0_2 Ya0_1 Ya0_0
+6 Ya0_15 Ya0_14 Ya0_13 Ya0_12 Ya0_11 Ya0_10 Ya0_9 Ya0_8
+7 LFB0 Zs0_6 Zs0_5 Zs0_4 Zs0_3 Zs0_2 Zs0_1 Zs0_0
+
+8 Xa1_7 Xa1_6 Xa1_5 Xa1_4 Xa1_3 Xa1_2 Xa1_1 Xa1_0
+9 Xa1_15 Xa1_14 Xa1_13 Xa1_12 Xa1_11 Xa1_10 Xa1_9 Xa1_8
+10 Ya1_7 Ya1_6 Ya1_5 Ya1_4 Ya1_3 Ya1_2 Ya1_1 Ya1_0
+11 Ya1_15 Ya1_14 Ya1_13 Ya1_12 Ya1_11 Ya1_10 Ya1_9 Ya1_8
+12 LFB1 Zs1_6 Zs1_5 Zs1_4 Zs1_3 Zs1_2 Zs1_1 Zs1_0
+
+13 Xa2_7 Xa2_6 Xa2_5 Xa2_4 Xa2_3 Xa2_2 Xa2_1 Xa2_0
+14 Xa2_15 Xa2_14 Xa2_13 Xa2_12 Xa2_11 Xa2_10 Xa2_9 Xa2_8
+15 Ya2_7 Ya2_6 Ya2_5 Ya2_4 Ya2_3 Ya2_2 Ya2_1 Ya2_0
+16 Ya2_15 Ya2_14 Ya2_13 Ya2_12 Ya2_11 Ya2_10 Ya2_9 Ya2_8
+17 LFB2 Zs2_6 Zs2_5 Zs2_4 Zs2_3 Zs2_2 Zs2_1 Zs2_0
+
+18 Xa3_7 Xa3_6 Xa3_5 Xa3_4 Xa3_3 Xa3_2 Xa3_1 Xa3_0
+19 Xa3_15 Xa3_14 Xa3_13 Xa3_12 Xa3_11 Xa3_10 Xa3_9 Xa3_8
+20 Ya3_7 Ya3_6 Ya3_5 Ya3_4 Ya3_3 Ya3_2 Ya3_1 Ya3_0
+21 Ya3_15 Ya3_14 Ya3_13 Ya3_12 Ya3_11 Ya3_10 Ya3_9 Ya3_8
+22 LFB3 Zs3_6 Zs3_5 Zs3_4 Zs3_3 Zs3_2 Zs3_1 Zs3_0
+
+23 Xa4_7 Xa4_6 Xa4_5 Xa4_4 Xa4_3 Xa4_2 Xa4_1 Xa4_0
+24 Xa4_15 Xa4_14 Xa4_13 Xa4_12 Xa4_11 Xa4_10 Xa4_9 Xa4_8
+25 Ya4_7 Ya4_6 Ya4_5 Ya4_4 Ya4_3 Ya4_2 Ya4_1 Ya4_0
+26 Ya4_15 Ya4_14 Ya4_13 Ya4_12 Ya4_11 Ya4_10 Ya4_9 Ya4_8
+27 LFB4 Zs4_6 Zs4_5 Zs4_4 Zs4_3 Zs4_2 Zs4_1 Zs4_0
+======= ======= ======= ======= ======= ======= ======= ======= =====
+
+
+SW1-SW6:
+ SW ON/OFF status
+Xan_15-0(16bit):
+ X Absolute data of the "n"th finger
+Yan_15-0(16bit):
+ Y Absolute data of the "n"th finger
+Zsn_6-0(7bit):
+ Operation area of the "n"th finger
+
+
+StickPointer data byte
+----------------------
+
+======= ======= ======= ======= ======= ======= ======= ======= =====
+- b7 b6 b5 b4 b3 b2 b1 b0
+======= ======= ======= ======= ======= ======= ======= ======= =====
+Byte1 1 1 1 0 1 SW3 SW2 SW1
+Byte2 X7 X6 X5 X4 X3 X2 X1 X0
+Byte3 X15 X14 X13 X12 X11 X10 X9 X8
+Byte4 Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
+Byte5 Y15 Y14 Y13 Y12 Y11 Y10 Y9 Y8
+Byte6 Z7 Z6 Z5 Z4 Z3 Z2 Z1 Z0
+Byte7 T&P Z14 Z13 Z12 Z11 Z10 Z9 Z8
+======= ======= ======= ======= ======= ======= ======= ======= =====
+
+SW1-SW3:
+ SW ON/OFF status
+Xn_15-0(16bit):
+ X Absolute data
+Yn_15-0(16bit):
+ Y Absolute data
+Zn_14-0(15bit):
+ Z
diff --git a/Documentation/hid/hid-sensor.rst b/Documentation/hid/hid-sensor.rst
new file mode 100644
index 000000000..758972e34
--- /dev/null
+++ b/Documentation/hid/hid-sensor.rst
@@ -0,0 +1,242 @@
+=====================
+HID Sensors Framework
+=====================
+HID sensor framework provides necessary interfaces to implement sensor drivers,
+which are connected to a sensor hub. The sensor hub is a HID device and it provides
+a report descriptor conforming to HID 1.12 sensor usage tables.
+
+Description from the HID 1.12 "HID Sensor Usages" specification:
+"Standardization of HID usages for sensors would allow (but not require) sensor
+hardware vendors to provide a consistent Plug And Play interface at the USB boundary,
+thereby enabling some operating systems to incorporate common device drivers that
+could be reused between vendors, alleviating any need for the vendors to provide
+the drivers themselves."
+
+This specification describes many usage IDs, which describe the type of sensor
+and also the individual data fields. Each sensor can have variable number of
+data fields. The length and order is specified in the report descriptor. For
+example a part of report descriptor can look like::
+
+ INPUT(1)[INPUT]
+ ..
+ Field(2)
+ Physical(0020.0073)
+ Usage(1)
+ 0020.045f
+ Logical Minimum(-32767)
+ Logical Maximum(32767)
+ Report Size(8)
+ Report Count(1)
+ Report Offset(16)
+ Flags(Variable Absolute)
+ ..
+ ..
+
+The report is indicating "sensor page (0x20)" contains an accelerometer-3D (0x73).
+This accelerometer-3D has some fields. Here for example field 2 is motion intensity
+(0x045f) with a logical minimum value of -32767 and logical maximum of 32767. The
+order of fields and length of each field is important as the input event raw
+data will use this format.
+
+
+Implementation
+==============
+
+This specification defines many different types of sensors with different sets of
+data fields. It is difficult to have a common input event to user space applications,
+for different sensors. For example an accelerometer can send X,Y and Z data, whereas
+an ambient light sensor can send illumination data.
+So the implementation has two parts:
+
+- Core hid driver
+- Individual sensor processing part (sensor drivers)
+
+Core driver
+-----------
+The core driver registers (hid-sensor-hub) registers as a HID driver. It parses
+report descriptors and identifies all the sensors present. It adds an MFD device
+with name HID-SENSOR-xxxx (where xxxx is usage id from the specification).
+
+For example:
+
+HID-SENSOR-200073 is registered for an Accelerometer 3D driver.
+
+So if any driver with this name is inserted, then the probe routine for that
+function will be called. So an accelerometer processing driver can register
+with this name and will be probed if there is an accelerometer-3D detected.
+
+The core driver provides a set of APIs which can be used by the processing
+drivers to register and get events for that usage id. Also it provides parsing
+functions, which get and set each input/feature/output report.
+
+Individual sensor processing part (sensor drivers)
+--------------------------------------------------
+
+The processing driver will use an interface provided by the core driver to parse
+the report and get the indexes of the fields and also can get events. This driver
+can use IIO interface to use the standard ABI defined for a type of sensor.
+
+
+Core driver Interface
+=====================
+
+Callback structure::
+
+ Each processing driver can use this structure to set some callbacks.
+ int (*suspend)(..): Callback when HID suspend is received
+ int (*resume)(..): Callback when HID resume is received
+ int (*capture_sample)(..): Capture a sample for one of its data fields
+ int (*send_event)(..): One complete event is received which can have
+ multiple data fields.
+
+Registration functions::
+
+ int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
+ u32 usage_id,
+ struct hid_sensor_hub_callbacks *usage_callback):
+
+Registers callbacks for an usage id. The callback functions are not allowed
+to sleep::
+
+
+ int sensor_hub_remove_callback(struct hid_sensor_hub_device *hsdev,
+ u32 usage_id):
+
+Removes callbacks for an usage id.
+
+
+Parsing function::
+
+ int sensor_hub_input_get_attribute_info(struct hid_sensor_hub_device *hsdev,
+ u8 type,
+ u32 usage_id, u32 attr_usage_id,
+ struct hid_sensor_hub_attribute_info *info);
+
+A processing driver can look for some field of interest and check if it exists
+in a report descriptor. If it exists it will store necessary information
+so that fields can be set or get individually.
+These indexes avoid searching every time and getting field index to get or set.
+
+
+Set Feature report::
+
+ int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
+ u32 field_index, s32 value);
+
+This interface is used to set a value for a field in feature report. For example
+if there is a field report_interval, which is parsed by a call to
+sensor_hub_input_get_attribute_info before, then it can directly set that
+individual field::
+
+
+ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
+ u32 field_index, s32 *value);
+
+This interface is used to get a value for a field in input report. For example
+if there is a field report_interval, which is parsed by a call to
+sensor_hub_input_get_attribute_info before, then it can directly get that
+individual field value::
+
+
+ int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
+ u32 usage_id,
+ u32 attr_usage_id, u32 report_id);
+
+This is used to get a particular field value through input reports. For example
+accelerometer wants to poll X axis value, then it can call this function with
+the usage id of X axis. HID sensors can provide events, so this is not necessary
+to poll for any field. If there is some new sample, the core driver will call
+registered callback function to process the sample.
+
+
+----------
+
+HID Custom and generic Sensors
+------------------------------
+
+
+HID Sensor specification defines two special sensor usage types. Since they
+don't represent a standard sensor, it is not possible to define using Linux IIO
+type interfaces.
+The purpose of these sensors is to extend the functionality or provide a
+way to obfuscate the data being communicated by a sensor. Without knowing the
+mapping between the data and its encapsulated form, it is difficult for
+an application/driver to determine what data is being communicated by the sensor.
+This allows some differentiating use cases, where vendor can provide applications.
+Some common use cases are debug other sensors or to provide some events like
+keyboard attached/detached or lid open/close.
+
+To allow application to utilize these sensors, here they are exported uses sysfs
+attribute groups, attributes and misc device interface.
+
+An example of this representation on sysfs::
+
+ /sys/devices/pci0000:00/INT33C2:00/i2c-0/i2c-INT33D1:00/0018:8086:09FA.0001/HID-SENSOR-2000e1.6.auto$ tree -R
+ .
+ │   ├── enable_sensor
+ │   │   ├── feature-0-200316
+ │   │   │   ├── feature-0-200316-maximum
+ │   │   │   ├── feature-0-200316-minimum
+ │   │   │   ├── feature-0-200316-name
+ │   │   │   ├── feature-0-200316-size
+ │   │   │   ├── feature-0-200316-unit-expo
+ │   │   │   ├── feature-0-200316-units
+ │   │   │   ├── feature-0-200316-value
+ │   │   ├── feature-1-200201
+ │   │   │   ├── feature-1-200201-maximum
+ │   │   │   ├── feature-1-200201-minimum
+ │   │   │   ├── feature-1-200201-name
+ │   │   │   ├── feature-1-200201-size
+ │   │   │   ├── feature-1-200201-unit-expo
+ │   │   │   ├── feature-1-200201-units
+ │   │   │   ├── feature-1-200201-value
+ │   │   ├── input-0-200201
+ │   │   │   ├── input-0-200201-maximum
+ │   │   │   ├── input-0-200201-minimum
+ │   │   │   ├── input-0-200201-name
+ │   │   │   ├── input-0-200201-size
+ │   │   │   ├── input-0-200201-unit-expo
+ │   │   │   ├── input-0-200201-units
+ │   │   │   ├── input-0-200201-value
+ │   │   ├── input-1-200202
+ │   │   │   ├── input-1-200202-maximum
+ │   │   │   ├── input-1-200202-minimum
+ │   │   │   ├── input-1-200202-name
+ │   │   │   ├── input-1-200202-size
+ │   │   │   ├── input-1-200202-unit-expo
+ │   │   │   ├── input-1-200202-units
+ │   │   │   ├── input-1-200202-value
+
+Here there is a custom sensors with four fields, two feature and two inputs.
+Each field is represented by a set of attributes. All fields except the "value"
+are read only. The value field is a RW field.
+
+Example::
+
+ /sys/bus/platform/devices/HID-SENSOR-2000e1.6.auto/feature-0-200316$ grep -r . *
+ feature-0-200316-maximum:6
+ feature-0-200316-minimum:0
+ feature-0-200316-name:property-reporting-state
+ feature-0-200316-size:1
+ feature-0-200316-unit-expo:0
+ feature-0-200316-units:25
+ feature-0-200316-value:1
+
+How to enable such sensor?
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+By default sensor can be power gated. To enable sysfs attribute "enable" can be
+used::
+
+ $ echo 1 > enable_sensor
+
+Once enabled and powered on, sensor can report value using HID reports.
+These reports are pushed using misc device interface in a FIFO order::
+
+ /dev$ tree | grep HID-SENSOR-2000e1.6.auto
+ │   │   │   ├── 10:53 -> ../HID-SENSOR-2000e1.6.auto
+ │   ├── HID-SENSOR-2000e1.6.auto
+
+Each reports can be of variable length preceded by a header. This header
+consist of a 32 bit usage id, 64 bit time stamp and 32 bit length field of raw
+data.
diff --git a/Documentation/hid/hid-transport.rst b/Documentation/hid/hid-transport.rst
new file mode 100644
index 000000000..0fe526f36
--- /dev/null
+++ b/Documentation/hid/hid-transport.rst
@@ -0,0 +1,359 @@
+=========================
+HID I/O Transport Drivers
+=========================
+
+The HID subsystem is independent of the underlying transport driver. Initially,
+only USB was supported, but other specifications adopted the HID design and
+provided new transport drivers. The kernel includes at least support for USB,
+Bluetooth, I2C and user-space I/O drivers.
+
+1) HID Bus
+==========
+
+The HID subsystem is designed as a bus. Any I/O subsystem may provide HID
+devices and register them with the HID bus. HID core then loads generic device
+drivers on top of it. The transport drivers are responsible of raw data
+transport and device setup/management. HID core is responsible of
+report-parsing, report interpretation and the user-space API. Device specifics
+and quirks are handled by all layers depending on the quirk.
+
+::
+
+ +-----------+ +-----------+ +-----------+ +-----------+
+ | Device #1 | | Device #i | | Device #j | | Device #k |
+ +-----------+ +-----------+ +-----------+ +-----------+
+ \\ // \\ //
+ +------------+ +------------+
+ | I/O Driver | | I/O Driver |
+ +------------+ +------------+
+ || ||
+ +------------------+ +------------------+
+ | Transport Driver | | Transport Driver |
+ +------------------+ +------------------+
+ \___ ___/
+ \ /
+ +----------------+
+ | HID Core |
+ +----------------+
+ / | | \
+ / | | \
+ ____________/ | | \_________________
+ / | | \
+ / | | \
+ +----------------+ +-----------+ +------------------+ +------------------+
+ | Generic Driver | | MT Driver | | Custom Driver #1 | | Custom Driver #2 |
+ +----------------+ +-----------+ +------------------+ +------------------+
+
+Example Drivers:
+
+ - I/O: USB, I2C, Bluetooth-l2cap
+ - Transport: USB-HID, I2C-HID, BT-HIDP
+
+Everything below "HID Core" is simplified in this graph as it is only of
+interest to HID device drivers. Transport drivers do not need to know the
+specifics.
+
+1.1) Device Setup
+-----------------
+
+I/O drivers normally provide hotplug detection or device enumeration APIs to the
+transport drivers. Transport drivers use this to find any suitable HID device.
+They allocate HID device objects and register them with HID core. Transport
+drivers are not required to register themselves with HID core. HID core is never
+aware of which transport drivers are available and is not interested in it. It
+is only interested in devices.
+
+Transport drivers attach a constant "struct hid_ll_driver" object with each
+device. Once a device is registered with HID core, the callbacks provided via
+this struct are used by HID core to communicate with the device.
+
+Transport drivers are responsible of detecting device failures and unplugging.
+HID core will operate a device as long as it is registered regardless of any
+device failures. Once transport drivers detect unplug or failure events, they
+must unregister the device from HID core and HID core will stop using the
+provided callbacks.
+
+1.2) Transport Driver Requirements
+----------------------------------
+
+The terms "asynchronous" and "synchronous" in this document describe the
+transmission behavior regarding acknowledgements. An asynchronous channel must
+not perform any synchronous operations like waiting for acknowledgements or
+verifications. Generally, HID calls operating on asynchronous channels must be
+running in atomic-context just fine.
+On the other hand, synchronous channels can be implemented by the transport
+driver in whatever way they like. They might just be the same as asynchronous
+channels, but they can also provide acknowledgement reports, automatic
+retransmission on failure, etc. in a blocking manner. If such functionality is
+required on asynchronous channels, a transport-driver must implement that via
+its own worker threads.
+
+HID core requires transport drivers to follow a given design. A Transport
+driver must provide two bi-directional I/O channels to each HID device. These
+channels must not necessarily be bi-directional in the hardware itself. A
+transport driver might just provide 4 uni-directional channels. Or it might
+multiplex all four on a single physical channel. However, in this document we
+will describe them as two bi-directional channels as they have several
+properties in common.
+
+ - Interrupt Channel (intr): The intr channel is used for asynchronous data
+ reports. No management commands or data acknowledgements are sent on this
+ channel. Any unrequested incoming or outgoing data report must be sent on
+ this channel and is never acknowledged by the remote side. Devices usually
+ send their input events on this channel. Outgoing events are normally
+ not send via intr, except if high throughput is required.
+ - Control Channel (ctrl): The ctrl channel is used for synchronous requests and
+ device management. Unrequested data input events must not be sent on this
+ channel and are normally ignored. Instead, devices only send management
+ events or answers to host requests on this channel.
+ The control-channel is used for direct blocking queries to the device
+ independent of any events on the intr-channel.
+ Outgoing reports are usually sent on the ctrl channel via synchronous
+ SET_REPORT requests.
+
+Communication between devices and HID core is mostly done via HID reports. A
+report can be of one of three types:
+
+ - INPUT Report: Input reports provide data from device to host. This
+ data may include button events, axis events, battery status or more. This
+ data is generated by the device and sent to the host with or without
+ requiring explicit requests. Devices can choose to send data continuously or
+ only on change.
+ - OUTPUT Report: Output reports change device states. They are sent from host
+ to device and may include LED requests, rumble requests or more. Output
+ reports are never sent from device to host, but a host can retrieve their
+ current state.
+ Hosts may choose to send output reports either continuously or only on
+ change.
+ - FEATURE Report: Feature reports are used for specific static device features
+ and never reported spontaneously. A host can read and/or write them to access
+ data like battery-state or device-settings.
+ Feature reports are never sent without requests. A host must explicitly set
+ or retrieve a feature report. This also means, feature reports are never sent
+ on the intr channel as this channel is asynchronous.
+
+INPUT and OUTPUT reports can be sent as pure data reports on the intr channel.
+For INPUT reports this is the usual operational mode. But for OUTPUT reports,
+this is rarely done as OUTPUT reports are normally quite scarce. But devices are
+free to make excessive use of asynchronous OUTPUT reports (for instance, custom
+HID audio speakers make great use of it).
+
+Plain reports must not be sent on the ctrl channel, though. Instead, the ctrl
+channel provides synchronous GET/SET_REPORT requests. Plain reports are only
+allowed on the intr channel and are the only means of data there.
+
+ - GET_REPORT: A GET_REPORT request has a report ID as payload and is sent
+ from host to device. The device must answer with a data report for the
+ requested report ID on the ctrl channel as a synchronous acknowledgement.
+ Only one GET_REPORT request can be pending for each device. This restriction
+ is enforced by HID core as several transport drivers don't allow multiple
+ simultaneous GET_REPORT requests.
+ Note that data reports which are sent as answer to a GET_REPORT request are
+ not handled as generic device events. That is, if a device does not operate
+ in continuous data reporting mode, an answer to GET_REPORT does not replace
+ the raw data report on the intr channel on state change.
+ GET_REPORT is only used by custom HID device drivers to query device state.
+ Normally, HID core caches any device state so this request is not necessary
+ on devices that follow the HID specs except during device initialization to
+ retrieve the current state.
+ GET_REPORT requests can be sent for any of the 3 report types and shall
+ return the current report state of the device. However, OUTPUT reports as
+ payload may be blocked by the underlying transport driver if the
+ specification does not allow them.
+ - SET_REPORT: A SET_REPORT request has a report ID plus data as payload. It is
+ sent from host to device and a device must update it's current report state
+ according to the given data. Any of the 3 report types can be used. However,
+ INPUT reports as payload might be blocked by the underlying transport driver
+ if the specification does not allow them.
+ A device must answer with a synchronous acknowledgement. However, HID core
+ does not require transport drivers to forward this acknowledgement to HID
+ core.
+ Same as for GET_REPORT, only one SET_REPORT can be pending at a time. This
+ restriction is enforced by HID core as some transport drivers do not support
+ multiple synchronous SET_REPORT requests.
+
+Other ctrl-channel requests are supported by USB-HID but are not available
+(or deprecated) in most other transport level specifications:
+
+ - GET/SET_IDLE: Only used by USB-HID and I2C-HID.
+ - GET/SET_PROTOCOL: Not used by HID core.
+ - RESET: Used by I2C-HID, not hooked up in HID core.
+ - SET_POWER: Used by I2C-HID, not hooked up in HID core.
+
+2) HID API
+==========
+
+2.1) Initialization
+-------------------
+
+Transport drivers normally use the following procedure to register a new device
+with HID core::
+
+ struct hid_device *hid;
+ int ret;
+
+ hid = hid_allocate_device();
+ if (IS_ERR(hid)) {
+ ret = PTR_ERR(hid);
+ goto err_<...>;
+ }
+
+ strscpy(hid->name, <device-name-src>, sizeof(hid->name));
+ strscpy(hid->phys, <device-phys-src>, sizeof(hid->phys));
+ strscpy(hid->uniq, <device-uniq-src>, sizeof(hid->uniq));
+
+ hid->ll_driver = &custom_ll_driver;
+ hid->bus = <device-bus>;
+ hid->vendor = <device-vendor>;
+ hid->product = <device-product>;
+ hid->version = <device-version>;
+ hid->country = <device-country>;
+ hid->dev.parent = <pointer-to-parent-device>;
+ hid->driver_data = <transport-driver-data-field>;
+
+ ret = hid_add_device(hid);
+ if (ret)
+ goto err_<...>;
+
+Once hid_add_device() is entered, HID core might use the callbacks provided in
+"custom_ll_driver". Note that fields like "country" can be ignored by underlying
+transport-drivers if not supported.
+
+To unregister a device, use::
+
+ hid_destroy_device(hid);
+
+Once hid_destroy_device() returns, HID core will no longer make use of any
+driver callbacks.
+
+2.2) hid_ll_driver operations
+-----------------------------
+
+The available HID callbacks are:
+
+ ::
+
+ int (*start) (struct hid_device *hdev)
+
+ Called from HID device drivers once they want to use the device. Transport
+ drivers can choose to setup their device in this callback. However, normally
+ devices are already set up before transport drivers register them to HID core
+ so this is mostly only used by USB-HID.
+
+ ::
+
+ void (*stop) (struct hid_device *hdev)
+
+ Called from HID device drivers once they are done with a device. Transport
+ drivers can free any buffers and deinitialize the device. But note that
+ ->start() might be called again if another HID device driver is loaded on the
+ device.
+
+ Transport drivers are free to ignore it and deinitialize devices after they
+ destroyed them via hid_destroy_device().
+
+ ::
+
+ int (*open) (struct hid_device *hdev)
+
+ Called from HID device drivers once they are interested in data reports.
+ Usually, while user-space didn't open any input API/etc., device drivers are
+ not interested in device data and transport drivers can put devices asleep.
+ However, once ->open() is called, transport drivers must be ready for I/O.
+ ->open() calls are nested for each client that opens the HID device.
+
+ ::
+
+ void (*close) (struct hid_device *hdev)
+
+ Called from HID device drivers after ->open() was called but they are no
+ longer interested in device reports. (Usually if user-space closed any input
+ devices of the driver).
+
+ Transport drivers can put devices asleep and terminate any I/O of all
+ ->open() calls have been followed by a ->close() call. However, ->start() may
+ be called again if the device driver is interested in input reports again.
+
+ ::
+
+ int (*parse) (struct hid_device *hdev)
+
+ Called once during device setup after ->start() has been called. Transport
+ drivers must read the HID report-descriptor from the device and tell HID core
+ about it via hid_parse_report().
+
+ ::
+
+ int (*power) (struct hid_device *hdev, int level)
+
+ Called by HID core to give PM hints to transport drivers. Usually this is
+ analogical to the ->open() and ->close() hints and redundant.
+
+ ::
+
+ void (*request) (struct hid_device *hdev, struct hid_report *report,
+ int reqtype)
+
+ Send an HID request on the ctrl channel. "report" contains the report that
+ should be sent and "reqtype" the request type. Request-type can be
+ HID_REQ_SET_REPORT or HID_REQ_GET_REPORT.
+
+ This callback is optional. If not provided, HID core will assemble a raw
+ report following the HID specs and send it via the ->raw_request() callback.
+ The transport driver is free to implement this asynchronously.
+
+ ::
+
+ int (*wait) (struct hid_device *hdev)
+
+ Used by HID core before calling ->request() again. A transport driver can use
+ it to wait for any pending requests to complete if only one request is
+ allowed at a time.
+
+ ::
+
+ int (*raw_request) (struct hid_device *hdev, unsigned char reportnum,
+ __u8 *buf, size_t count, unsigned char rtype,
+ int reqtype)
+
+ Same as ->request() but provides the report as raw buffer. This request shall
+ be synchronous. A transport driver must not use ->wait() to complete such
+ requests. This request is mandatory and hid core will reject the device if
+ it is missing.
+
+ ::
+
+ int (*output_report) (struct hid_device *hdev, __u8 *buf, size_t len)
+
+ Send raw output report via intr channel. Used by some HID device drivers
+ which require high throughput for outgoing requests on the intr channel. This
+ must not cause SET_REPORT calls! This must be implemented as asynchronous
+ output report on the intr channel!
+
+ ::
+
+ int (*idle) (struct hid_device *hdev, int report, int idle, int reqtype)
+
+ Perform SET/GET_IDLE request. Only used by USB-HID, do not implement!
+
+2.3) Data Path
+--------------
+
+Transport drivers are responsible of reading data from I/O devices. They must
+handle any I/O-related state-tracking themselves. HID core does not implement
+protocol handshakes or other management commands which can be required by the
+given HID transport specification.
+
+Every raw data packet read from a device must be fed into HID core via
+hid_input_report(). You must specify the channel-type (intr or ctrl) and report
+type (input/output/feature). Under normal conditions, only input reports are
+provided via this API.
+
+Responses to GET_REPORT requests via ->request() must also be provided via this
+API. Responses to ->raw_request() are synchronous and must be intercepted by the
+transport driver and not passed to hid_input_report().
+Acknowledgements to SET_REPORT requests are not of interest to HID core.
+
+----------------------------------------------------
+
+Written 2013, David Herrmann <dh.herrmann@gmail.com>
diff --git a/Documentation/hid/hiddev.rst b/Documentation/hid/hiddev.rst
new file mode 100644
index 000000000..9b28a97c0
--- /dev/null
+++ b/Documentation/hid/hiddev.rst
@@ -0,0 +1,251 @@
+================================================
+Care and feeding of your Human Interface Devices
+================================================
+
+Introduction
+============
+
+In addition to the normal input type HID devices, USB also uses the
+human interface device protocols for things that are not really human
+interfaces, but have similar sorts of communication needs. The two big
+examples for this are power devices (especially uninterruptable power
+supplies) and monitor control on higher end monitors.
+
+To support these disparate requirements, the Linux USB system provides
+HID events to two separate interfaces:
+* the input subsystem, which converts HID events into normal input
+device interfaces (such as keyboard, mouse and joystick) and a
+normalised event interface - see Documentation/input/input.rst
+* the hiddev interface, which provides fairly raw HID events
+
+The data flow for a HID event produced by a device is something like
+the following::
+
+ usb.c ---> hid-core.c ----> hid-input.c ----> [keyboard/mouse/joystick/event]
+ |
+ |
+ --> hiddev.c ----> POWER / MONITOR CONTROL
+
+In addition, other subsystems (apart from USB) can potentially feed
+events into the input subsystem, but these have no effect on the hid
+device interface.
+
+Using the HID Device Interface
+==============================
+
+The hiddev interface is a char interface using the normal USB major,
+with the minor numbers starting at 96 and finishing at 111. Therefore,
+you need the following commands::
+
+ mknod /dev/usb/hiddev0 c 180 96
+ mknod /dev/usb/hiddev1 c 180 97
+ mknod /dev/usb/hiddev2 c 180 98
+ mknod /dev/usb/hiddev3 c 180 99
+ mknod /dev/usb/hiddev4 c 180 100
+ mknod /dev/usb/hiddev5 c 180 101
+ mknod /dev/usb/hiddev6 c 180 102
+ mknod /dev/usb/hiddev7 c 180 103
+ mknod /dev/usb/hiddev8 c 180 104
+ mknod /dev/usb/hiddev9 c 180 105
+ mknod /dev/usb/hiddev10 c 180 106
+ mknod /dev/usb/hiddev11 c 180 107
+ mknod /dev/usb/hiddev12 c 180 108
+ mknod /dev/usb/hiddev13 c 180 109
+ mknod /dev/usb/hiddev14 c 180 110
+ mknod /dev/usb/hiddev15 c 180 111
+
+So you point your hiddev compliant user-space program at the correct
+interface for your device, and it all just works.
+
+Assuming that you have a hiddev compliant user-space program, of
+course. If you need to write one, read on.
+
+
+The HIDDEV API
+==============
+
+This description should be read in conjunction with the HID
+specification, freely available from https://www.usb.org, and
+conveniently linked of http://www.linux-usb.org.
+
+The hiddev API uses a read() interface, and a set of ioctl() calls.
+
+HID devices exchange data with the host computer using data
+bundles called "reports". Each report is divided into "fields",
+each of which can have one or more "usages". In the hid-core,
+each one of these usages has a single signed 32 bit value.
+
+read():
+-------
+
+This is the event interface. When the HID device's state changes,
+it performs an interrupt transfer containing a report which contains
+the changed value. The hid-core.c module parses the report, and
+returns to hiddev.c the individual usages that have changed within
+the report. In its basic mode, the hiddev will make these individual
+usage changes available to the reader using a struct hiddev_event::
+
+ struct hiddev_event {
+ unsigned hid;
+ signed int value;
+ };
+
+containing the HID usage identifier for the status that changed, and
+the value that it was changed to. Note that the structure is defined
+within <linux/hiddev.h>, along with some other useful #defines and
+structures. The HID usage identifier is a composite of the HID usage
+page shifted to the 16 high order bits ORed with the usage code. The
+behavior of the read() function can be modified using the HIDIOCSFLAG
+ioctl() described below.
+
+
+ioctl():
+--------
+
+This is the control interface. There are a number of controls:
+
+HIDIOCGVERSION
+ - int (read)
+
+ Gets the version code out of the hiddev driver.
+
+HIDIOCAPPLICATION
+ - (none)
+
+This ioctl call returns the HID application usage associated with the
+hid device. The third argument to ioctl() specifies which application
+index to get. This is useful when the device has more than one
+application collection. If the index is invalid (greater or equal to
+the number of application collections this device has) the ioctl
+returns -1. You can find out beforehand how many application
+collections the device has from the num_applications field from the
+hiddev_devinfo structure.
+
+HIDIOCGCOLLECTIONINFO
+ - struct hiddev_collection_info (read/write)
+
+This returns a superset of the information above, providing not only
+application collections, but all the collections the device has. It
+also returns the level the collection lives in the hierarchy.
+The user passes in a hiddev_collection_info struct with the index
+field set to the index that should be returned. The ioctl fills in
+the other fields. If the index is larger than the last collection
+index, the ioctl returns -1 and sets errno to -EINVAL.
+
+HIDIOCGDEVINFO
+ - struct hiddev_devinfo (read)
+
+Gets a hiddev_devinfo structure which describes the device.
+
+HIDIOCGSTRING
+ - struct hiddev_string_descriptor (read/write)
+
+Gets a string descriptor from the device. The caller must fill in the
+"index" field to indicate which descriptor should be returned.
+
+HIDIOCINITREPORT
+ - (none)
+
+Instructs the kernel to retrieve all input and feature report values
+from the device. At this point, all the usage structures will contain
+current values for the device, and will maintain it as the device
+changes. Note that the use of this ioctl is unnecessary in general,
+since later kernels automatically initialize the reports from the
+device at attach time.
+
+HIDIOCGNAME
+ - string (variable length)
+
+Gets the device name
+
+HIDIOCGREPORT
+ - struct hiddev_report_info (write)
+
+Instructs the kernel to get a feature or input report from the device,
+in order to selectively update the usage structures (in contrast to
+INITREPORT).
+
+HIDIOCSREPORT
+ - struct hiddev_report_info (write)
+
+Instructs the kernel to send a report to the device. This report can
+be filled in by the user through HIDIOCSUSAGE calls (below) to fill in
+individual usage values in the report before sending the report in full
+to the device.
+
+HIDIOCGREPORTINFO
+ - struct hiddev_report_info (read/write)
+
+Fills in a hiddev_report_info structure for the user. The report is
+looked up by type (input, output or feature) and id, so these fields
+must be filled in by the user. The ID can be absolute -- the actual
+report id as reported by the device -- or relative --
+HID_REPORT_ID_FIRST for the first report, and (HID_REPORT_ID_NEXT |
+report_id) for the next report after report_id. Without a-priori
+information about report ids, the right way to use this ioctl is to
+use the relative IDs above to enumerate the valid IDs. The ioctl
+returns non-zero when there is no more next ID. The real report ID is
+filled into the returned hiddev_report_info structure.
+
+HIDIOCGFIELDINFO
+ - struct hiddev_field_info (read/write)
+
+Returns the field information associated with a report in a
+hiddev_field_info structure. The user must fill in report_id and
+report_type in this structure, as above. The field_index should also
+be filled in, which should be a number from 0 and maxfield-1, as
+returned from a previous HIDIOCGREPORTINFO call.
+
+HIDIOCGUCODE
+ - struct hiddev_usage_ref (read/write)
+
+Returns the usage_code in a hiddev_usage_ref structure, given that
+given its report type, report id, field index, and index within the
+field have already been filled into the structure.
+
+HIDIOCGUSAGE
+ - struct hiddev_usage_ref (read/write)
+
+Returns the value of a usage in a hiddev_usage_ref structure. The
+usage to be retrieved can be specified as above, or the user can
+choose to fill in the report_type field and specify the report_id as
+HID_REPORT_ID_UNKNOWN. In this case, the hiddev_usage_ref will be
+filled in with the report and field information associated with this
+usage if it is found.
+
+HIDIOCSUSAGE
+ - struct hiddev_usage_ref (write)
+
+Sets the value of a usage in an output report. The user fills in
+the hiddev_usage_ref structure as above, but additionally fills in
+the value field.
+
+HIDIOGCOLLECTIONINDEX
+ - struct hiddev_usage_ref (write)
+
+Returns the collection index associated with this usage. This
+indicates where in the collection hierarchy this usage sits.
+
+HIDIOCGFLAG
+ - int (read)
+HIDIOCSFLAG
+ - int (write)
+
+These operations respectively inspect and replace the mode flags
+that influence the read() call above. The flags are as follows:
+
+ HIDDEV_FLAG_UREF
+ - read() calls will now return
+ struct hiddev_usage_ref instead of struct hiddev_event.
+ This is a larger structure, but in situations where the
+ device has more than one usage in its reports with the
+ same usage code, this mode serves to resolve such
+ ambiguity.
+
+ HIDDEV_FLAG_REPORT
+ - This flag can only be used in conjunction
+ with HIDDEV_FLAG_UREF. With this flag set, when the device
+ sends a report, a struct hiddev_usage_ref will be returned
+ to read() filled in with the report_type and report_id, but
+ with field_index set to FIELD_INDEX_NONE. This serves as
+ additional notification when the device has sent a report.
diff --git a/Documentation/hid/hidraw.rst b/Documentation/hid/hidraw.rst
new file mode 100644
index 000000000..4a4a0ba1f
--- /dev/null
+++ b/Documentation/hid/hidraw.rst
@@ -0,0 +1,138 @@
+================================================================
+HIDRAW - Raw Access to USB and Bluetooth Human Interface Devices
+================================================================
+
+The hidraw driver provides a raw interface to USB and Bluetooth Human
+Interface Devices (HIDs). It differs from hiddev in that reports sent and
+received are not parsed by the HID parser, but are sent to and received from
+the device unmodified.
+
+Hidraw should be used if the userspace application knows exactly how to
+communicate with the hardware device, and is able to construct the HID
+reports manually. This is often the case when making userspace drivers for
+custom HID devices.
+
+Hidraw is also useful for communicating with non-conformant HID devices
+which send and receive data in a way that is inconsistent with their report
+descriptors. Because hiddev parses reports which are sent and received
+through it, checking them against the device's report descriptor, such
+communication with these non-conformant devices is impossible using hiddev.
+Hidraw is the only alternative, short of writing a custom kernel driver, for
+these non-conformant devices.
+
+A benefit of hidraw is that its use by userspace applications is independent
+of the underlying hardware type. Currently, Hidraw is implemented for USB
+and Bluetooth. In the future, as new hardware bus types are developed which
+use the HID specification, hidraw will be expanded to add support for these
+new bus types.
+
+Hidraw uses a dynamic major number, meaning that udev should be relied on to
+create hidraw device nodes. Udev will typically create the device nodes
+directly under /dev (eg: /dev/hidraw0). As this location is distribution-
+and udev rule-dependent, applications should use libudev to locate hidraw
+devices attached to the system. There is a tutorial on libudev with a
+working example at:
+
+ http://www.signal11.us/oss/udev/
+
+The HIDRAW API
+---------------
+
+read()
+-------
+read() will read a queued report received from the HID device. On USB
+devices, the reports read using read() are the reports sent from the device
+on the INTERRUPT IN endpoint. By default, read() will block until there is
+a report available to be read. read() can be made non-blocking, by passing
+the O_NONBLOCK flag to open(), or by setting the O_NONBLOCK flag using
+fcntl().
+
+On a device which uses numbered reports, the first byte of the returned data
+will be the report number; the report data follows, beginning in the second
+byte. For devices which do not use numbered reports, the report data
+will begin at the first byte.
+
+write()
+-------
+The write() function will write a report to the device. For USB devices, if
+the device has an INTERRUPT OUT endpoint, the report will be sent on that
+endpoint. If it does not, the report will be sent over the control endpoint,
+using a SET_REPORT transfer.
+
+The first byte of the buffer passed to write() should be set to the report
+number. If the device does not use numbered reports, the first byte should
+be set to 0. The report data itself should begin at the second byte.
+
+ioctl()
+-------
+Hidraw supports the following ioctls:
+
+HIDIOCGRDESCSIZE:
+ Get Report Descriptor Size
+
+This ioctl will get the size of the device's report descriptor.
+
+HIDIOCGRDESC:
+ Get Report Descriptor
+
+This ioctl returns the device's report descriptor using a
+hidraw_report_descriptor struct. Make sure to set the size field of the
+hidraw_report_descriptor struct to the size returned from HIDIOCGRDESCSIZE.
+
+HIDIOCGRAWINFO:
+ Get Raw Info
+
+This ioctl will return a hidraw_devinfo struct containing the bus type, the
+vendor ID (VID), and product ID (PID) of the device. The bus type can be one
+of::
+
+ - BUS_USB
+ - BUS_HIL
+ - BUS_BLUETOOTH
+ - BUS_VIRTUAL
+
+which are defined in uapi/linux/input.h.
+
+HIDIOCGRAWNAME(len):
+ Get Raw Name
+
+This ioctl returns a string containing the vendor and product strings of
+the device. The returned string is Unicode, UTF-8 encoded.
+
+HIDIOCGRAWPHYS(len):
+ Get Physical Address
+
+This ioctl returns a string representing the physical address of the device.
+For USB devices, the string contains the physical path to the device (the
+USB controller, hubs, ports, etc). For Bluetooth devices, the string
+contains the hardware (MAC) address of the device.
+
+HIDIOCSFEATURE(len):
+ Send a Feature Report
+
+This ioctl will send a feature report to the device. Per the HID
+specification, feature reports are always sent using the control endpoint.
+Set the first byte of the supplied buffer to the report number. For devices
+which do not use numbered reports, set the first byte to 0. The report data
+begins in the second byte. Make sure to set len accordingly, to one more
+than the length of the report (to account for the report number).
+
+HIDIOCGFEATURE(len):
+ Get a Feature Report
+
+This ioctl will request a feature report from the device using the control
+endpoint. The first byte of the supplied buffer should be set to the report
+number of the requested report. For devices which do not use numbered
+reports, set the first byte to 0. The report will be returned starting at
+the first byte of the buffer (ie: the report number is not returned).
+
+Example
+-------
+In samples/, find hid-example.c, which shows examples of read(), write(),
+and all the ioctls for hidraw. The code may be used by anyone for any
+purpose, and can serve as a starting point for developing applications using
+hidraw.
+
+Document by:
+
+ Alan Ott <alan@signal11.us>, Signal 11 Software
diff --git a/Documentation/hid/index.rst b/Documentation/hid/index.rst
new file mode 100644
index 000000000..737d66dc1
--- /dev/null
+++ b/Documentation/hid/index.rst
@@ -0,0 +1,18 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=============================
+Human Interface Devices (HID)
+=============================
+
+.. toctree::
+ :maxdepth: 1
+
+ hiddev
+ hidraw
+ hid-sensor
+ hid-transport
+
+ uhid
+
+ hid-alps
+ intel-ish-hid
diff --git a/Documentation/hid/intel-ish-hid.rst b/Documentation/hid/intel-ish-hid.rst
new file mode 100644
index 000000000..d4785cf6e
--- /dev/null
+++ b/Documentation/hid/intel-ish-hid.rst
@@ -0,0 +1,485 @@
+=================================
+Intel Integrated Sensor Hub (ISH)
+=================================
+
+A sensor hub enables the ability to offload sensor polling and algorithm
+processing to a dedicated low power co-processor. This allows the core
+processor to go into low power modes more often, resulting in the increased
+battery life.
+
+There are many vendors providing external sensor hubs confirming to HID
+Sensor usage tables, and used in several tablets, 2 in 1 convertible laptops
+and embedded products. Linux had this support since Linux 3.9.
+
+Intel® introduced integrated sensor hubs as a part of the SoC starting from
+Cherry Trail and now supported on multiple generations of CPU packages. There
+are many commercial devices already shipped with Integrated Sensor Hubs (ISH).
+These ISH also comply to HID sensor specification, but the difference is the
+transport protocol used for communication. The current external sensor hubs
+mainly use HID over i2C or USB. But ISH doesn't use either i2c or USB.
+
+1. Overview
+===========
+
+Using a analogy with a usbhid implementation, the ISH follows a similar model
+for a very high speed communication::
+
+ ----------------- ----------------------
+ | USB HID | --> | ISH HID |
+ ----------------- ----------------------
+ ----------------- ----------------------
+ | USB protocol | --> | ISH Transport |
+ ----------------- ----------------------
+ ----------------- ----------------------
+ | EHCI/XHCI | --> | ISH IPC |
+ ----------------- ----------------------
+ PCI PCI
+ ----------------- ----------------------
+ |Host controller| --> | ISH processor |
+ ----------------- ----------------------
+ USB Link
+ ----------------- ----------------------
+ | USB End points| --> | ISH Clients |
+ ----------------- ----------------------
+
+Like USB protocol provides a method for device enumeration, link management
+and user data encapsulation, the ISH also provides similar services. But it is
+very light weight tailored to manage and communicate with ISH client
+applications implemented in the firmware.
+
+The ISH allows multiple sensor management applications executing in the
+firmware. Like USB endpoints the messaging can be to/from a client. As part of
+enumeration process, these clients are identified. These clients can be simple
+HID sensor applications, sensor calibration application or senor firmware
+update application.
+
+The implementation model is similar, like USB bus, ISH transport is also
+implemented as a bus. Each client application executing in the ISH processor
+is registered as a device on this bus. The driver, which binds each device
+(ISH HID driver) identifies the device type and registers with the hid core.
+
+2. ISH Implementation: Block Diagram
+====================================
+
+::
+
+ ---------------------------
+ | User Space Applications |
+ ---------------------------
+
+ ----------------IIO ABI----------------
+ --------------------------
+ | IIO Sensor Drivers |
+ --------------------------
+ --------------------------
+ | IIO core |
+ --------------------------
+ --------------------------
+ | HID Sensor Hub MFD |
+ --------------------------
+ --------------------------
+ | HID Core |
+ --------------------------
+ --------------------------
+ | HID over ISH Client |
+ --------------------------
+ --------------------------
+ | ISH Transport (ISHTP) |
+ --------------------------
+ --------------------------
+ | IPC Drivers |
+ --------------------------
+ OS
+ ---------------- PCI -----------------
+ Hardware + Firmware
+ ----------------------------
+ | ISH Hardware/Firmware(FW) |
+ ----------------------------
+
+3. High level processing in above blocks
+========================================
+
+3.1 Hardware Interface
+----------------------
+
+The ISH is exposed as "Non-VGA unclassified PCI device" to the host. The PCI
+product and vendor IDs are changed from different generations of processors. So
+the source code which enumerate drivers needs to update from generation to
+generation.
+
+3.2 Inter Processor Communication (IPC) driver
+----------------------------------------------
+
+Location: drivers/hid/intel-ish-hid/ipc
+
+The IPC message used memory mapped I/O. The registers are defined in
+hw-ish-regs.h.
+
+3.2.1 IPC/FW message types
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+There are two types of messages, one for management of link and other messages
+are to and from transport layers.
+
+TX and RX of Transport messages
+...............................
+
+A set of memory mapped register offers support of multi byte messages TX and
+RX (E.g.IPC_REG_ISH2HOST_MSG, IPC_REG_HOST2ISH_MSG). The IPC layer maintains
+internal queues to sequence messages and send them in order to the FW.
+Optionally the caller can register handler to get notification of completion.
+A door bell mechanism is used in messaging to trigger processing in host and
+client firmware side. When ISH interrupt handler is called, the ISH2HOST
+doorbell register is used by host drivers to determine that the interrupt
+is for ISH.
+
+Each side has 32 32-bit message registers and a 32-bit doorbell. Doorbell
+register has the following format:
+Bits 0..6: fragment length (7 bits are used)
+Bits 10..13: encapsulated protocol
+Bits 16..19: management command (for IPC management protocol)
+Bit 31: doorbell trigger (signal H/W interrupt to the other side)
+Other bits are reserved, should be 0.
+
+3.2.2 Transport layer interface
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To abstract HW level IPC communication, a set of callbacks are registered.
+The transport layer uses them to send and receive messages.
+Refer to struct ishtp_hw_ops for callbacks.
+
+3.3 ISH Transport layer
+-----------------------
+
+Location: drivers/hid/intel-ish-hid/ishtp/
+
+3.3.1 A Generic Transport Layer
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The transport layer is a bi-directional protocol, which defines:
+- Set of commands to start, stop, connect, disconnect and flow control
+(ishtp/hbm.h) for details
+- A flow control mechanism to avoid buffer overflows
+
+This protocol resembles bus messages described in the following document:
+http://www.intel.com/content/dam/www/public/us/en/documents/technical-\
+specifications/dcmi-hi-1-0-spec.pdf "Chapter 7: Bus Message Layer"
+
+3.3.2 Connection and Flow Control Mechanism
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Each FW client and a protocol is identified by an UUID. In order to communicate
+to a FW client, a connection must be established using connect request and
+response bus messages. If successful, a pair (host_client_id and fw_client_id)
+will identify the connection.
+
+Once connection is established, peers send each other flow control bus messages
+independently. Every peer may send a message only if it has received a
+flow-control credit before. Once it sent a message, it may not send another one
+before receiving the next flow control credit.
+Either side can send disconnect request bus message to end communication. Also
+the link will be dropped if major FW reset occurs.
+
+3.3.3 Peer to Peer data transfer
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Peer to Peer data transfer can happen with or without using DMA. Depending on
+the sensor bandwidth requirement DMA can be enabled by using module parameter
+ishtp_use_dma under intel_ishtp.
+
+Each side (host and FW) manages its DMA transfer memory independently. When an
+ISHTP client from either host or FW side wants to send something, it decides
+whether to send over IPC or over DMA; for each transfer the decision is
+independent. The sending side sends DMA_XFER message when the message is in
+the respective host buffer (TX when host client sends, RX when FW client
+sends). The recipient of DMA message responds with DMA_XFER_ACK, indicating
+the sender that the memory region for that message may be reused.
+
+DMA initialization is started with host sending DMA_ALLOC_NOTIFY bus message
+(that includes RX buffer) and FW responds with DMA_ALLOC_NOTIFY_ACK.
+Additionally to DMA address communication, this sequence checks capabilities:
+if thw host doesn't support DMA, then it won't send DMA allocation, so FW can't
+send DMA; if FW doesn't support DMA then it won't respond with
+DMA_ALLOC_NOTIFY_ACK, in which case host will not use DMA transfers.
+Here ISH acts as busmaster DMA controller. Hence when host sends DMA_XFER,
+it's request to do host->ISH DMA transfer; when FW sends DMA_XFER, it means
+that it already did DMA and the message resides at host. Thus, DMA_XFER
+and DMA_XFER_ACK act as ownership indicators.
+
+At initial state all outgoing memory belongs to the sender (TX to host, RX to
+FW), DMA_XFER transfers ownership on the region that contains ISHTP message to
+the receiving side, DMA_XFER_ACK returns ownership to the sender. A sender
+needs not wait for previous DMA_XFER to be ack'ed, and may send another message
+as long as remaining continuous memory in its ownership is enough.
+In principle, multiple DMA_XFER and DMA_XFER_ACK messages may be sent at once
+(up to IPC MTU), thus allowing for interrupt throttling.
+Currently, ISH FW decides to send over DMA if ISHTP message is more than 3 IPC
+fragments and via IPC otherwise.
+
+3.3.4 Ring Buffers
+^^^^^^^^^^^^^^^^^^
+
+When a client initiate a connection, a ring or RX and TX buffers are allocated.
+The size of ring can be specified by the client. HID client set 16 and 32 for
+TX and RX buffers respectively. On send request from client, the data to be
+sent is copied to one of the send ring buffer and scheduled to be sent using
+bus message protocol. These buffers are required because the FW may have not
+have processed the last message and may not have enough flow control credits
+to send. Same thing holds true on receive side and flow control is required.
+
+3.3.5 Host Enumeration
+^^^^^^^^^^^^^^^^^^^^^^
+
+The host enumeration bus command allow discovery of clients present in the FW.
+There can be multiple sensor clients and clients for calibration function.
+
+To ease in implantation and allow independent driver handle each client
+this transport layer takes advantage of Linux Bus driver model. Each
+client is registered as device on the transport bus (ishtp bus).
+
+Enumeration sequence of messages:
+
+- Host sends HOST_START_REQ_CMD, indicating that host ISHTP layer is up.
+- FW responds with HOST_START_RES_CMD
+- Host sends HOST_ENUM_REQ_CMD (enumerate FW clients)
+- FW responds with HOST_ENUM_RES_CMD that includes bitmap of available FW
+ client IDs
+- For each FW ID found in that bitmap host sends
+ HOST_CLIENT_PROPERTIES_REQ_CMD
+- FW responds with HOST_CLIENT_PROPERTIES_RES_CMD. Properties include UUID,
+ max ISHTP message size, etc.
+- Once host received properties for that last discovered client, it considers
+ ISHTP device fully functional (and allocates DMA buffers)
+
+3.4 HID over ISH Client
+-----------------------
+
+Location: drivers/hid/intel-ish-hid
+
+The ISHTP client driver is responsible for:
+
+- enumerate HID devices under FW ISH client
+- Get Report descriptor
+- Register with HID core as a LL driver
+- Process Get/Set feature request
+- Get input reports
+
+3.5 HID Sensor Hub MFD and IIO sensor drivers
+---------------------------------------------
+
+The functionality in these drivers is the same as an external sensor hub.
+Refer to
+Documentation/hid/hid-sensor.rst for HID sensor
+Documentation/ABI/testing/sysfs-bus-iio for IIO ABIs to user space
+
+3.6 End to End HID transport Sequence Diagram
+---------------------------------------------
+
+::
+
+ HID-ISH-CLN ISHTP IPC HW
+ | | | |
+ | | |-----WAKE UP------------------>|
+ | | | |
+ | | |-----HOST READY--------------->|
+ | | | |
+ | | |<----MNG_RESET_NOTIFY_ACK----- |
+ | | | |
+ | |<----ISHTP_START------ | |
+ | | | |
+ | |<-----------------HOST_START_RES_CMD-------------------|
+ | | | |
+ | |------------------QUERY_SUBSCRIBER-------------------->|
+ | | | |
+ | |------------------HOST_ENUM_REQ_CMD------------------->|
+ | | | |
+ | |<-----------------HOST_ENUM_RES_CMD--------------------|
+ | | | |
+ | |------------------HOST_CLIENT_PROPERTIES_REQ_CMD------>|
+ | | | |
+ | |<-----------------HOST_CLIENT_PROPERTIES_RES_CMD-------|
+ | Create new device on in ishtp bus | |
+ | | | |
+ | |------------------HOST_CLIENT_PROPERTIES_REQ_CMD------>|
+ | | | |
+ | |<-----------------HOST_CLIENT_PROPERTIES_RES_CMD-------|
+ | Create new device on in ishtp bus | |
+ | | | |
+ | |--Repeat HOST_CLIENT_PROPERTIES_REQ_CMD-till last one--|
+ | | | |
+ probed()
+ |----ishtp_cl_connect--->|----------------- CLIENT_CONNECT_REQ_CMD-------------->|
+ | | | |
+ | |<----------------CLIENT_CONNECT_RES_CMD----------------|
+ | | | |
+ |register event callback | | |
+ | | | |
+ |ishtp_cl_send(
+ HOSTIF_DM_ENUM_DEVICES) |----------fill ishtp_msg_hdr struct write to HW----- >|
+ | | | |
+ | | |<-----IRQ(IPC_PROTOCOL_ISHTP---|
+ | | | |
+ |<--ENUM_DEVICE RSP------| | |
+ | | | |
+ for each enumerated device
+ |ishtp_cl_send(
+ HOSTIF_GET_HID_DESCRIPTOR|----------fill ishtp_msg_hdr struct write to HW----- >|
+ | | | |
+ ...Response
+ | | | |
+ for each enumerated device
+ |ishtp_cl_send(
+ HOSTIF_GET_REPORT_DESCRIPTOR|--------------fill ishtp_msg_hdr struct write to HW-- >|
+ | | | |
+ | | | |
+ hid_allocate_device
+ | | | |
+ hid_add_device | | |
+ | | | |
+
+
+3.7 ISH Debugging
+-----------------
+
+To debug ISH, event tracing mechanism is used. To enable debug logs
+echo 1 > /sys/kernel/debug/tracing/events/intel_ish/enable
+cat sys/kernel/debug/tracing/trace
+
+3.8 ISH IIO sysfs Example on Lenovo thinkpad Yoga 260
+-----------------------------------------------------
+
+::
+
+ root@otcpl-ThinkPad-Yoga-260:~# tree -l /sys/bus/iio/devices/
+ /sys/bus/iio/devices/
+ ├── iio:device0 -> ../../../devices/0044:8086:22D8.0001/HID-SENSOR-200073.9.auto/iio:device0
+ │   ├── buffer
+ │   │   ├── enable
+ │   │   ├── length
+ │   │   └── watermark
+ ...
+ │   ├── in_accel_hysteresis
+ │   ├── in_accel_offset
+ │   ├── in_accel_sampling_frequency
+ │   ├── in_accel_scale
+ │   ├── in_accel_x_raw
+ │   ├── in_accel_y_raw
+ │   ├── in_accel_z_raw
+ │   ├── name
+ │   ├── scan_elements
+ │   │   ├── in_accel_x_en
+ │   │   ├── in_accel_x_index
+ │   │   ├── in_accel_x_type
+ │   │   ├── in_accel_y_en
+ │   │   ├── in_accel_y_index
+ │   │   ├── in_accel_y_type
+ │   │   ├── in_accel_z_en
+ │   │   ├── in_accel_z_index
+ │   │   └── in_accel_z_type
+ ...
+ │   │   ├── devices
+ │   │   │   │   ├── buffer
+ │   │   │   │   │   ├── enable
+ │   │   │   │   │   ├── length
+ │   │   │   │   │   └── watermark
+ │   │   │   │   ├── dev
+ │   │   │   │   ├── in_intensity_both_raw
+ │   │   │   │   ├── in_intensity_hysteresis
+ │   │   │   │   ├── in_intensity_offset
+ │   │   │   │   ├── in_intensity_sampling_frequency
+ │   │   │   │   ├── in_intensity_scale
+ │   │   │   │   ├── name
+ │   │   │   │   ├── scan_elements
+ │   │   │   │   │   ├── in_intensity_both_en
+ │   │   │   │   │   ├── in_intensity_both_index
+ │   │   │   │   │   └── in_intensity_both_type
+ │   │   │   │   ├── trigger
+ │   │   │   │   │   └── current_trigger
+ ...
+ │   │   │   │   ├── buffer
+ │   │   │   │   │   ├── enable
+ │   │   │   │   │   ├── length
+ │   │   │   │   │   └── watermark
+ │   │   │   │   ├── dev
+ │   │   │   │   ├── in_magn_hysteresis
+ │   │   │   │   ├── in_magn_offset
+ │   │   │   │   ├── in_magn_sampling_frequency
+ │   │   │   │   ├── in_magn_scale
+ │   │   │   │   ├── in_magn_x_raw
+ │   │   │   │   ├── in_magn_y_raw
+ │   │   │   │   ├── in_magn_z_raw
+ │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_raw
+ │   │   │   │   ├── in_rot_hysteresis
+ │   │   │   │   ├── in_rot_offset
+ │   │   │   │   ├── in_rot_sampling_frequency
+ │   │   │   │   ├── in_rot_scale
+ │   │   │   │   ├── name
+ ...
+ │   │   │   │   ├── scan_elements
+ │   │   │   │   │   ├── in_magn_x_en
+ │   │   │   │   │   ├── in_magn_x_index
+ │   │   │   │   │   ├── in_magn_x_type
+ │   │   │   │   │   ├── in_magn_y_en
+ │   │   │   │   │   ├── in_magn_y_index
+ │   │   │   │   │   ├── in_magn_y_type
+ │   │   │   │   │   ├── in_magn_z_en
+ │   │   │   │   │   ├── in_magn_z_index
+ │   │   │   │   │   ├── in_magn_z_type
+ │   │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_en
+ │   │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_index
+ │   │   │   │   │   └── in_rot_from_north_magnetic_tilt_comp_type
+ │   │   │   │   ├── trigger
+ │   │   │   │   │   └── current_trigger
+ ...
+ │   │   │   │   ├── buffer
+ │   │   │   │   │   ├── enable
+ │   │   │   │   │   ├── length
+ │   │   │   │   │   └── watermark
+ │   │   │   │   ├── dev
+ │   │   │   │   ├── in_anglvel_hysteresis
+ │   │   │   │   ├── in_anglvel_offset
+ │   │   │   │   ├── in_anglvel_sampling_frequency
+ │   │   │   │   ├── in_anglvel_scale
+ │   │   │   │   ├── in_anglvel_x_raw
+ │   │   │   │   ├── in_anglvel_y_raw
+ │   │   │   │   ├── in_anglvel_z_raw
+ │   │   │   │   ├── name
+ │   │   │   │   ├── scan_elements
+ │   │   │   │   │   ├── in_anglvel_x_en
+ │   │   │   │   │   ├── in_anglvel_x_index
+ │   │   │   │   │   ├── in_anglvel_x_type
+ │   │   │   │   │   ├── in_anglvel_y_en
+ │   │   │   │   │   ├── in_anglvel_y_index
+ │   │   │   │   │   ├── in_anglvel_y_type
+ │   │   │   │   │   ├── in_anglvel_z_en
+ │   │   │   │   │   ├── in_anglvel_z_index
+ │   │   │   │   │   └── in_anglvel_z_type
+ │   │   │   │   ├── trigger
+ │   │   │   │   │   └── current_trigger
+ ...
+ │   │   │   │   ├── buffer
+ │   │   │   │   │   ├── enable
+ │   │   │   │   │   ├── length
+ │   │   │   │   │   └── watermark
+ │   │   │   │   ├── dev
+ │   │   │   │   ├── in_anglvel_hysteresis
+ │   │   │   │   ├── in_anglvel_offset
+ │   │   │   │   ├── in_anglvel_sampling_frequency
+ │   │   │   │   ├── in_anglvel_scale
+ │   │   │   │   ├── in_anglvel_x_raw
+ │   │   │   │   ├── in_anglvel_y_raw
+ │   │   │   │   ├── in_anglvel_z_raw
+ │   │   │   │   ├── name
+ │   │   │   │   ├── scan_elements
+ │   │   │   │   │   ├── in_anglvel_x_en
+ │   │   │   │   │   ├── in_anglvel_x_index
+ │   │   │   │   │   ├── in_anglvel_x_type
+ │   │   │   │   │   ├── in_anglvel_y_en
+ │   │   │   │   │   ├── in_anglvel_y_index
+ │   │   │   │   │   ├── in_anglvel_y_type
+ │   │   │   │   │   ├── in_anglvel_z_en
+ │   │   │   │   │   ├── in_anglvel_z_index
+ │   │   │   │   │   └── in_anglvel_z_type
+ │   │   │   │   ├── trigger
+ │   │   │   │   │   └── current_trigger
+ ...
diff --git a/Documentation/hid/uhid.rst b/Documentation/hid/uhid.rst
new file mode 100644
index 000000000..b18cb96c8
--- /dev/null
+++ b/Documentation/hid/uhid.rst
@@ -0,0 +1,193 @@
+======================================================
+UHID - User-space I/O driver support for HID subsystem
+======================================================
+
+UHID allows user-space to implement HID transport drivers. Please see
+hid-transport.txt for an introduction into HID transport drivers. This document
+relies heavily on the definitions declared there.
+
+With UHID, a user-space transport driver can create kernel hid-devices for each
+device connected to the user-space controlled bus. The UHID API defines the I/O
+events provided from the kernel to user-space and vice versa.
+
+There is an example user-space application in ./samples/uhid/uhid-example.c
+
+The UHID API
+------------
+
+UHID is accessed through a character misc-device. The minor-number is allocated
+dynamically so you need to rely on udev (or similar) to create the device node.
+This is /dev/uhid by default.
+
+If a new device is detected by your HID I/O Driver and you want to register this
+device with the HID subsystem, then you need to open /dev/uhid once for each
+device you want to register. All further communication is done by read()'ing or
+write()'ing "struct uhid_event" objects. Non-blocking operations are supported
+by setting O_NONBLOCK::
+
+ struct uhid_event {
+ __u32 type;
+ union {
+ struct uhid_create2_req create2;
+ struct uhid_output_req output;
+ struct uhid_input2_req input2;
+ ...
+ } u;
+ };
+
+The "type" field contains the ID of the event. Depending on the ID different
+payloads are sent. You must not split a single event across multiple read()'s or
+multiple write()'s. A single event must always be sent as a whole. Furthermore,
+only a single event can be sent per read() or write(). Pending data is ignored.
+If you want to handle multiple events in a single syscall, then use vectored
+I/O with readv()/writev().
+The "type" field defines the payload. For each type, there is a
+payload-structure available in the union "u" (except for empty payloads). This
+payload contains management and/or device data.
+
+The first thing you should do is sending an UHID_CREATE2 event. This will
+register the device. UHID will respond with an UHID_START event. You can now
+start sending data to and reading data from UHID. However, unless UHID sends the
+UHID_OPEN event, the internally attached HID Device Driver has no user attached.
+That is, you might put your device asleep unless you receive the UHID_OPEN
+event. If you receive the UHID_OPEN event, you should start I/O. If the last
+user closes the HID device, you will receive an UHID_CLOSE event. This may be
+followed by an UHID_OPEN event again and so on. There is no need to perform
+reference-counting in user-space. That is, you will never receive multiple
+UHID_OPEN events without an UHID_CLOSE event. The HID subsystem performs
+ref-counting for you.
+You may decide to ignore UHID_OPEN/UHID_CLOSE, though. I/O is allowed even
+though the device may have no users.
+
+If you want to send data on the interrupt channel to the HID subsystem, you send
+an HID_INPUT2 event with your raw data payload. If the kernel wants to send data
+on the interrupt channel to the device, you will read an UHID_OUTPUT event.
+Data requests on the control channel are currently limited to GET_REPORT and
+SET_REPORT (no other data reports on the control channel are defined so far).
+Those requests are always synchronous. That means, the kernel sends
+UHID_GET_REPORT and UHID_SET_REPORT events and requires you to forward them to
+the device on the control channel. Once the device responds, you must forward
+the response via UHID_GET_REPORT_REPLY and UHID_SET_REPORT_REPLY to the kernel.
+The kernel blocks internal driver-execution during such round-trips (times out
+after a hard-coded period).
+
+If your device disconnects, you should send an UHID_DESTROY event. This will
+unregister the device. You can now send UHID_CREATE2 again to register a new
+device.
+If you close() the fd, the device is automatically unregistered and destroyed
+internally.
+
+write()
+-------
+write() allows you to modify the state of the device and feed input data into
+the kernel. The kernel will parse the event immediately and if the event ID is
+not supported, it will return -EOPNOTSUPP. If the payload is invalid, then
+-EINVAL is returned, otherwise, the amount of data that was read is returned and
+the request was handled successfully. O_NONBLOCK does not affect write() as
+writes are always handled immediately in a non-blocking fashion. Future requests
+might make use of O_NONBLOCK, though.
+
+UHID_CREATE2:
+ This creates the internal HID device. No I/O is possible until you send this
+ event to the kernel. The payload is of type struct uhid_create2_req and
+ contains information about your device. You can start I/O now.
+
+UHID_DESTROY:
+ This destroys the internal HID device. No further I/O will be accepted. There
+ may still be pending messages that you can receive with read() but no further
+ UHID_INPUT events can be sent to the kernel.
+ You can create a new device by sending UHID_CREATE2 again. There is no need to
+ reopen the character device.
+
+UHID_INPUT2:
+ You must send UHID_CREATE2 before sending input to the kernel! This event
+ contains a data-payload. This is the raw data that you read from your device
+ on the interrupt channel. The kernel will parse the HID reports.
+
+UHID_GET_REPORT_REPLY:
+ If you receive a UHID_GET_REPORT request you must answer with this request.
+ You must copy the "id" field from the request into the answer. Set the "err"
+ field to 0 if no error occurred or to EIO if an I/O error occurred.
+ If "err" is 0 then you should fill the buffer of the answer with the results
+ of the GET_REPORT request and set "size" correspondingly.
+
+UHID_SET_REPORT_REPLY:
+ This is the SET_REPORT equivalent of UHID_GET_REPORT_REPLY. Unlike GET_REPORT,
+ SET_REPORT never returns a data buffer, therefore, it's sufficient to set the
+ "id" and "err" fields correctly.
+
+read()
+------
+read() will return a queued output report. No reaction is required to any of
+them but you should handle them according to your needs.
+
+UHID_START:
+ This is sent when the HID device is started. Consider this as an answer to
+ UHID_CREATE2. This is always the first event that is sent. Note that this
+ event might not be available immediately after write(UHID_CREATE2) returns.
+ Device drivers might required delayed setups.
+ This event contains a payload of type uhid_start_req. The "dev_flags" field
+ describes special behaviors of a device. The following flags are defined:
+
+ - UHID_DEV_NUMBERED_FEATURE_REPORTS
+ - UHID_DEV_NUMBERED_OUTPUT_REPORTS
+ - UHID_DEV_NUMBERED_INPUT_REPORTS
+
+ Each of these flags defines whether a given report-type uses numbered
+ reports. If numbered reports are used for a type, all messages from
+ the kernel already have the report-number as prefix. Otherwise, no
+ prefix is added by the kernel.
+ For messages sent by user-space to the kernel, you must adjust the
+ prefixes according to these flags.
+
+UHID_STOP:
+ This is sent when the HID device is stopped. Consider this as an answer to
+ UHID_DESTROY.
+
+ If you didn't destroy your device via UHID_DESTROY, but the kernel sends an
+ UHID_STOP event, this should usually be ignored. It means that the kernel
+ reloaded/changed the device driver loaded on your HID device (or some other
+ maintenance actions happened).
+
+ You can usually ignored any UHID_STOP events safely.
+
+UHID_OPEN:
+ This is sent when the HID device is opened. That is, the data that the HID
+ device provides is read by some other process. You may ignore this event but
+ it is useful for power-management. As long as you haven't received this event
+ there is actually no other process that reads your data so there is no need to
+ send UHID_INPUT2 events to the kernel.
+
+UHID_CLOSE:
+ This is sent when there are no more processes which read the HID data. It is
+ the counterpart of UHID_OPEN and you may as well ignore this event.
+
+UHID_OUTPUT:
+ This is sent if the HID device driver wants to send raw data to the I/O
+ device on the interrupt channel. You should read the payload and forward it to
+ the device. The payload is of type "struct uhid_output_req".
+ This may be received even though you haven't received UHID_OPEN, yet.
+
+UHID_GET_REPORT:
+ This event is sent if the kernel driver wants to perform a GET_REPORT request
+ on the control channeld as described in the HID specs. The report-type and
+ report-number are available in the payload.
+ The kernel serializes GET_REPORT requests so there will never be two in
+ parallel. However, if you fail to respond with a UHID_GET_REPORT_REPLY, the
+ request might silently time out.
+ Once you read a GET_REPORT request, you shall forward it to the hid device and
+ remember the "id" field in the payload. Once your hid device responds to the
+ GET_REPORT (or if it fails), you must send a UHID_GET_REPORT_REPLY to the
+ kernel with the exact same "id" as in the request. If the request already
+ timed out, the kernel will ignore the response silently. The "id" field is
+ never re-used, so conflicts cannot happen.
+
+UHID_SET_REPORT:
+ This is the SET_REPORT equivalent of UHID_GET_REPORT. On receipt, you shall
+ send a SET_REPORT request to your hid device. Once it replies, you must tell
+ the kernel about it via UHID_SET_REPORT_REPLY.
+ The same restrictions as for UHID_GET_REPORT apply.
+
+----------------------------------------------------
+
+Written 2012, David Herrmann <dh.herrmann@gmail.com>