[PATCH 1/6] Documentation: hid: Intel ISH HID document

From: Srinivas Pandruvada
Date: Sat Jun 11 2016 - 08:15:14 EST


Document explaining ISH HID operation and implementation.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada@xxxxxxxxxxxxxxx>
---
Documentation/hid/intel-ish-hid.txt | 417 ++++++++++++++++++++++++++++++++++++
1 file changed, 417 insertions(+)
create mode 100644 Documentation/hid/intel-ish-hid.txt

diff --git a/Documentation/hid/intel-ish-hid.txt b/Documentation/hid/intel-ish-hid.txt
new file mode 100644
index 0000000..2de0ab5
--- /dev/null
+++ b/Documentation/hid/intel-ish-hid.txt
@@ -0,0 +1,417 @@
+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.
+
+This document provides an overview of transport protocol and how it is
+implemented.
+
+
+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) |
+ ----------------------------
+
+------------------------------------------
+
+High level processing in above blocks:
+
+---
+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.
+
+---
+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.
+
+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.
+
+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.
+
+---
+ISH Transport layer
+Location: drivers/hid/intel-ish-hid/ishtp/
+
+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
+Chater 7: Bus Message Layer
+
+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 FC credit.
+Either side can send disconnect request bus message to end communication. Also
+the link will be dropped if major FW reset occurs.
+
+Peer to Peer data transfer
+The host allocates TX and RX buffers. 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. Host right now never decides to send over DMA
+because at this time there is no streaming case for larger messages.
+
+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
+processed last message and may not have enough flow control credits to send.
+Same thing holds true on receive side and flow control is required.
+
+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)
+
+---
+HID over ISH Client
+Location: drivers/hid/intel-ish-hid
+
+This implanted as ISHTP client driver, which
+- 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
+
+----
+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
+
+----
+
+========================================================================================
+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---|
+ | | | |
+ | |<------------ DMA_XFER---------------------------------|
+ |<--ENUM_DEVICE RSP-----| | |
+ | |------------ DMA_XFER_ACK----------------------------->|
+ | | | |
+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 | | |
+ | | | |
+
+
+========================================================================================
+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
+
+========================================================================================
+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
+...
--
2.5.5