From cca4786174656673f89684347e0028c88df57031 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 28 Jun 2019 09:19:59 -0300 Subject: docs: hid: convert to ReST Rename the HID documentation files to ReST, add an index for them and adjust in order to produce a nice html output via the Sphinx build system. While here, fix the sysfs example from hid-sensor.txt, that has a lot of "?" instead of the proper UTF-8 characters that are produced by the tree command. At its new index.rst, let's add a :orphan: while this is not linked to the main index.rst file, in order to avoid build warnings. Signed-off-by: Mauro Carvalho Chehab Acked-by: Benjamin Tissoires Signed-off-by: Benjamin Tissoires --- Documentation/hid/hid-alps.rst | 180 +++++++++++++ Documentation/hid/hid-alps.txt | 139 ----------- Documentation/hid/hid-sensor.rst | 242 ++++++++++++++++++ Documentation/hid/hid-sensor.txt | 224 ----------------- Documentation/hid/hid-transport.rst | 359 ++++++++++++++++++++++++++ Documentation/hid/hid-transport.txt | 317 ----------------------- Documentation/hid/hiddev.rst | 251 +++++++++++++++++++ Documentation/hid/hiddev.txt | 205 --------------- Documentation/hid/hidraw.rst | 138 ++++++++++ Documentation/hid/hidraw.txt | 119 --------- Documentation/hid/index.rst | 18 ++ Documentation/hid/intel-ish-hid.rst | 485 ++++++++++++++++++++++++++++++++++++ Documentation/hid/intel-ish-hid.txt | 454 --------------------------------- Documentation/hid/uhid.rst | 193 ++++++++++++++ Documentation/hid/uhid.txt | 187 -------------- Documentation/input/input.rst | 2 +- 16 files changed, 1867 insertions(+), 1646 deletions(-) create mode 100644 Documentation/hid/hid-alps.rst delete mode 100644 Documentation/hid/hid-alps.txt create mode 100644 Documentation/hid/hid-sensor.rst delete mode 100644 Documentation/hid/hid-sensor.txt create mode 100644 Documentation/hid/hid-transport.rst delete mode 100644 Documentation/hid/hid-transport.txt create mode 100644 Documentation/hid/hiddev.rst delete mode 100644 Documentation/hid/hiddev.txt create mode 100644 Documentation/hid/hidraw.rst delete mode 100644 Documentation/hid/hidraw.txt create mode 100644 Documentation/hid/index.rst create mode 100644 Documentation/hid/intel-ish-hid.rst delete mode 100644 Documentation/hid/intel-ish-hid.txt create mode 100644 Documentation/hid/uhid.rst delete mode 100644 Documentation/hid/uhid.txt (limited to 'Documentation') diff --git a/Documentation/hid/hid-alps.rst b/Documentation/hid/hid-alps.rst new file mode 100644 index 000000000000..e2f4c4c11e3f --- /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-alps.txt b/Documentation/hid/hid-alps.txt deleted file mode 100644 index 6b02a2447c77..000000000000 --- a/Documentation/hid/hid-alps.txt +++ /dev/null @@ -1,139 +0,0 @@ -ALPS HID Touchpad Protocol ----------------------- - -Introduction ------------- -Currently ALPS HID driver supports U1 Touchpad device. - -U1 devuce 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 000000000000..758972e34971 --- /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-sensor.txt b/Documentation/hid/hid-sensor.txt deleted file mode 100644 index b287752a31cd..000000000000 --- a/Documentation/hid/hid-sensor.txt +++ /dev/null @@ -1,224 +0,0 @@ - -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 000000000000..6f3aaa86ce7b --- /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_<...>; + } + + strlcpy(hid->name, , 127); + strlcpy(hid->phys, , 63); + strlcpy(hid->uniq, , 63); + + hid->ll_driver = &custom_ll_driver; + hid->bus = ; + hid->vendor = ; + hid->product = ; + hid->version = ; + hid->country = ; + hid->dev.parent = ; + hid->driver_data = ; + + 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 diff --git a/Documentation/hid/hid-transport.txt b/Documentation/hid/hid-transport.txt deleted file mode 100644 index 3dcba9fd4a3a..000000000000 --- a/Documentation/hid/hid-transport.txt +++ /dev/null @@ -1,317 +0,0 @@ - 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_<...>; - } - - strlcpy(hid->name, , 127); - strlcpy(hid->phys, , 63); - strlcpy(hid->uniq, , 63); - - hid->ll_driver = &custom_ll_driver; - hid->bus = ; - hid->vendor = ; - hid->product = ; - hid->version = ; - hid->country = ; - hid->dev.parent = ; - hid->driver_data = ; - - 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 diff --git a/Documentation/hid/hiddev.rst b/Documentation/hid/hiddev.rst new file mode 100644 index 000000000000..209e6ba4e019 --- /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 http://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 , 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/hiddev.txt b/Documentation/hid/hiddev.txt deleted file mode 100644 index 638448707aa2..000000000000 --- a/Documentation/hid/hiddev.txt +++ /dev/null @@ -1,205 +0,0 @@ -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 http://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 , 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 000000000000..4a4a0ba1f362 --- /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 , Signal 11 Software diff --git a/Documentation/hid/hidraw.txt b/Documentation/hid/hidraw.txt deleted file mode 100644 index c8436e354f44..000000000000 --- a/Documentation/hid/hidraw.txt +++ /dev/null @@ -1,119 +0,0 @@ - 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 , Signal 11 Software diff --git a/Documentation/hid/index.rst b/Documentation/hid/index.rst new file mode 100644 index 000000000000..af4324902622 --- /dev/null +++ b/Documentation/hid/index.rst @@ -0,0 +1,18 @@ +:orphan: + +============================= +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 000000000000..cccbf4be17d7 --- /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 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/intel-ish-hid.txt b/Documentation/hid/intel-ish-hid.txt deleted file mode 100644 index d48b21c71ddd..000000000000 --- a/Documentation/hid/intel-ish-hid.txt +++ /dev/null @@ -1,454 +0,0 @@ -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 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.txt 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 000000000000..b18cb96c885f --- /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 diff --git a/Documentation/hid/uhid.txt b/Documentation/hid/uhid.txt deleted file mode 100644 index 958fff945304..000000000000 --- a/Documentation/hid/uhid.txt +++ /dev/null @@ -1,187 +0,0 @@ - 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 diff --git a/Documentation/input/input.rst b/Documentation/input/input.rst index 47f86a4bf16c..0eb61e67a7b7 100644 --- a/Documentation/input/input.rst +++ b/Documentation/input/input.rst @@ -188,7 +188,7 @@ LCDs and many other purposes. The monitor and speaker controls should be easy to add to the hid/input interface, but for the UPSs and LCDs it doesn't make much sense. For this, -the hiddev interface was designed. See Documentation/hid/hiddev.txt +the hiddev interface was designed. See Documentation/hid/hiddev.rst for more information about it. The usage of the usbhid module is very simple, it takes no parameters, -- cgit v1.2.3-59-g8ed1b