From patchwork Sat Jun 11 12:13:34 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: srinivas pandruvada X-Patchwork-Id: 9171031 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id CDE1F60865 for ; Sat, 11 Jun 2016 12:16:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BFD0327C0C for ; Sat, 11 Jun 2016 12:16:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B4A1E2835D; Sat, 11 Jun 2016 12:16:57 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AEAF928047 for ; Sat, 11 Jun 2016 12:16:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752017AbcFKMPH (ORCPT ); Sat, 11 Jun 2016 08:15:07 -0400 Received: from mga11.intel.com ([192.55.52.93]:31677 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751301AbcFKMOy (ORCPT ); Sat, 11 Jun 2016 08:14:54 -0400 Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by fmsmga102.fm.intel.com with ESMTP; 11 Jun 2016 05:14:51 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.26,456,1459839600"; d="scan'208";a="120099199" Received: from spandruv-mobl3.jf.intel.com ([10.254.125.55]) by fmsmga004.fm.intel.com with ESMTP; 11 Jun 2016 05:14:50 -0700 From: Srinivas Pandruvada To: jikos@kernel.org, jic23@kernel.org, benjamin.tissoires@redhat.com Cc: linux-input@vger.kernel.org, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, chaya.golan@intel.com, daniel.drubin@intel.com, A.Bhattacharya@ulg.ac.be, Srinivas Pandruvada Subject: [PATCH 1/6] Documentation: hid: Intel ISH HID document Date: Sat, 11 Jun 2016 05:13:34 -0700 Message-Id: <1465647219-7798-2-git-send-email-srinivas.pandruvada@linux.intel.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1465647219-7798-1-git-send-email-srinivas.pandruvada@linux.intel.com> References: <1465647219-7798-1-git-send-email-srinivas.pandruvada@linux.intel.com> MIME-Version: 1.0 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Document explaining ISH HID operation and implementation. Signed-off-by: Srinivas Pandruvada --- 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 +...