Back to home page

OSCL-LXR

 
 

    


0001 =================================
0002 Intel Integrated Sensor Hub (ISH)
0003 =================================
0004 
0005 A sensor hub enables the ability to offload sensor polling and algorithm
0006 processing to a dedicated low power co-processor. This allows the core
0007 processor to go into low power modes more often, resulting in increased
0008 battery life.
0009 
0010 There are many vendors providing external sensor hubs conforming to HID
0011 Sensor usage tables. These may be found in tablets, 2-in-1 convertible laptops
0012 and embedded products. Linux has had this support since Linux 3.9.
0013 
0014 Intel® introduced integrated sensor hubs as a part of the SoC starting from
0015 Cherry Trail and now supported on multiple generations of CPU packages. There
0016 are many commercial devices already shipped with Integrated Sensor Hubs (ISH).
0017 These ISH also comply to HID sensor specification, but the difference is the
0018 transport protocol used for communication. The current external sensor hubs
0019 mainly use HID over I2C or USB. But ISH doesn't use either I2C or USB.
0020 
0021 1. Overview
0022 ===========
0023 
0024 Using a analogy with a usbhid implementation, the ISH follows a similar model
0025 for a very high speed communication::
0026 
0027         -----------------               ----------------------
0028         |    USB HID    |       -->     |    ISH HID         |
0029         -----------------               ----------------------
0030         -----------------               ----------------------
0031         |  USB protocol |       -->     |    ISH Transport   |
0032         -----------------               ----------------------
0033         -----------------               ----------------------
0034         |  EHCI/XHCI    |       -->     |    ISH IPC         |
0035         -----------------               ----------------------
0036               PCI                                PCI
0037         -----------------               ----------------------
0038         |Host controller|       -->     |    ISH processor   |
0039         -----------------               ----------------------
0040              USB Link
0041         -----------------               ----------------------
0042         | USB End points|       -->     |    ISH Clients     |
0043         -----------------               ----------------------
0044 
0045 Like USB protocol provides a method for device enumeration, link management
0046 and user data encapsulation, the ISH also provides similar services. But it is
0047 very light weight tailored to manage and communicate with ISH client
0048 applications implemented in the firmware.
0049 
0050 The ISH allows multiple sensor management applications executing in the
0051 firmware. Like USB endpoints the messaging can be to/from a client. As part of
0052 enumeration process, these clients are identified. These clients can be simple
0053 HID sensor applications, sensor calibration applications or sensor firmware
0054 update applications.
0055 
0056 The implementation model is similar, like USB bus, ISH transport is also
0057 implemented as a bus. Each client application executing in the ISH processor
0058 is registered as a device on this bus. The driver, which binds each device
0059 (ISH HID driver) identifies the device type and registers with the HID core.
0060 
0061 2. ISH Implementation: Block Diagram
0062 ====================================
0063 
0064 ::
0065 
0066          ---------------------------
0067         |  User Space Applications  |
0068          ---------------------------
0069 
0070   ----------------IIO ABI----------------
0071          --------------------------
0072         |  IIO Sensor Drivers     |
0073          --------------------------
0074          --------------------------
0075         |        IIO core         |
0076          --------------------------
0077          --------------------------
0078         |   HID Sensor Hub MFD    |
0079          --------------------------
0080          --------------------------
0081         |       HID Core          |
0082          --------------------------
0083          --------------------------
0084         |   HID over ISH Client   |
0085          --------------------------
0086          --------------------------
0087         |   ISH Transport (ISHTP) |
0088          --------------------------
0089          --------------------------
0090         |      IPC Drivers        |
0091          --------------------------
0092   OS
0093   ---------------- PCI -----------------
0094   Hardware + Firmware
0095          ----------------------------
0096         | ISH Hardware/Firmware(FW) |
0097          ----------------------------
0098 
0099 3. High level processing in above blocks
0100 ========================================
0101 
0102 3.1 Hardware Interface
0103 ----------------------
0104 
0105 The ISH is exposed as "Non-VGA unclassified PCI device" to the host. The PCI
0106 product and vendor IDs are changed from different generations of processors. So
0107 the source code which enumerates drivers needs to update from generation to
0108 generation.
0109 
0110 3.2 Inter Processor Communication (IPC) driver
0111 ----------------------------------------------
0112 
0113 Location: drivers/hid/intel-ish-hid/ipc
0114 
0115 The IPC message uses memory mapped I/O. The registers are defined in
0116 hw-ish-regs.h.
0117 
0118 3.2.1 IPC/FW message types
0119 ^^^^^^^^^^^^^^^^^^^^^^^^^^
0120 
0121 There are two types of messages, one for management of link and another for
0122 messages to and from transport layers.
0123 
0124 TX and RX of Transport messages
0125 ...............................
0126 
0127 A set of memory mapped register offers support of multi-byte messages TX and
0128 RX (e.g. IPC_REG_ISH2HOST_MSG, IPC_REG_HOST2ISH_MSG). The IPC layer maintains
0129 internal queues to sequence messages and send them in order to the firmware.
0130 Optionally the caller can register handler to get notification of completion.
0131 A doorbell mechanism is used in messaging to trigger processing in host and
0132 client firmware side. When ISH interrupt handler is called, the ISH2HOST
0133 doorbell register is used by host drivers to determine that the interrupt
0134 is for ISH.
0135 
0136 Each side has 32 32-bit message registers and a 32-bit doorbell. Doorbell
0137 register has the following format::
0138 
0139   Bits 0..6: fragment length (7 bits are used)
0140   Bits 10..13: encapsulated protocol
0141   Bits 16..19: management command (for IPC management protocol)
0142   Bit 31: doorbell trigger (signal H/W interrupt to the other side)
0143   Other bits are reserved, should be 0.
0144 
0145 3.2.2 Transport layer interface
0146 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0147 
0148 To abstract HW level IPC communication, a set of callbacks is registered.
0149 The transport layer uses them to send and receive messages.
0150 Refer to struct ishtp_hw_ops for callbacks.
0151 
0152 3.3 ISH Transport layer
0153 -----------------------
0154 
0155 Location: drivers/hid/intel-ish-hid/ishtp/
0156 
0157 3.3.1 A Generic Transport Layer
0158 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0159 
0160 The transport layer is a bi-directional protocol, which defines:
0161 - Set of commands to start, stop, connect, disconnect and flow control
0162 (see ishtp/hbm.h for details)
0163 - A flow control mechanism to avoid buffer overflows
0164 
0165 This protocol resembles bus messages described in the following document:
0166 http://www.intel.com/content/dam/www/public/us/en/documents/technical-\
0167 specifications/dcmi-hi-1-0-spec.pdf "Chapter 7: Bus Message Layer"
0168 
0169 3.3.2 Connection and Flow Control Mechanism
0170 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0171 
0172 Each FW client and a protocol is identified by a UUID. In order to communicate
0173 to a FW client, a connection must be established using connect request and
0174 response bus messages. If successful, a pair (host_client_id and fw_client_id)
0175 will identify the connection.
0176 
0177 Once connection is established, peers send each other flow control bus messages
0178 independently. Every peer may send a message only if it has received a
0179 flow-control credit before. Once it has sent a message, it may not send another one
0180 before receiving the next flow control credit.
0181 Either side can send disconnect request bus message to end communication. Also
0182 the link will be dropped if major FW reset occurs.
0183 
0184 3.3.3 Peer to Peer data transfer
0185 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0186 
0187 Peer to Peer data transfer can happen with or without using DMA. Depending on
0188 the sensor bandwidth requirement DMA can be enabled by using module parameter
0189 ishtp_use_dma under intel_ishtp.
0190 
0191 Each side (host and FW) manages its DMA transfer memory independently. When an
0192 ISHTP client from either host or FW side wants to send something, it decides
0193 whether to send over IPC or over DMA; for each transfer the decision is
0194 independent. The sending side sends DMA_XFER message when the message is in
0195 the respective host buffer (TX when host client sends, RX when FW client
0196 sends). The recipient of DMA message responds with DMA_XFER_ACK, indicating
0197 the sender that the memory region for that message may be reused.
0198 
0199 DMA initialization is started with host sending DMA_ALLOC_NOTIFY bus message
0200 (that includes RX buffer) and FW responds with DMA_ALLOC_NOTIFY_ACK.
0201 Additionally to DMA address communication, this sequence checks capabilities:
0202 if thw host doesn't support DMA, then it won't send DMA allocation, so FW can't
0203 send DMA; if FW doesn't support DMA then it won't respond with
0204 DMA_ALLOC_NOTIFY_ACK, in which case host will not use DMA transfers.
0205 Here ISH acts as busmaster DMA controller. Hence when host sends DMA_XFER,
0206 it's request to do host->ISH DMA transfer; when FW sends DMA_XFER, it means
0207 that it already did DMA and the message resides at host. Thus, DMA_XFER
0208 and DMA_XFER_ACK act as ownership indicators.
0209 
0210 At initial state all outgoing memory belongs to the sender (TX to host, RX to
0211 FW), DMA_XFER transfers ownership on the region that contains ISHTP message to
0212 the receiving side, DMA_XFER_ACK returns ownership to the sender. A sender
0213 need not wait for previous DMA_XFER to be ack'ed, and may send another message
0214 as long as remaining continuous memory in its ownership is enough.
0215 In principle, multiple DMA_XFER and DMA_XFER_ACK messages may be sent at once
0216 (up to IPC MTU), thus allowing for interrupt throttling.
0217 Currently, ISH FW decides to send over DMA if ISHTP message is more than 3 IPC
0218 fragments and via IPC otherwise.
0219 
0220 3.3.4 Ring Buffers
0221 ^^^^^^^^^^^^^^^^^^
0222 
0223 When a client initiates a connection, a ring of RX and TX buffers is allocated.
0224 The size of ring can be specified by the client. HID client sets 16 and 32 for
0225 TX and RX buffers respectively. On send request from client, the data to be
0226 sent is copied to one of the send ring buffer and scheduled to be sent using
0227 bus message protocol. These buffers are required because the FW may have not
0228 have processed the last message and may not have enough flow control credits
0229 to send. Same thing holds true on receive side and flow control is required.
0230 
0231 3.3.5 Host Enumeration
0232 ^^^^^^^^^^^^^^^^^^^^^^
0233 
0234 The host enumeration bus command allows discovery of clients present in the FW.
0235 There can be multiple sensor clients and clients for calibration function.
0236 
0237 To ease implementation and allow independent drivers to handle each client,
0238 this transport layer takes advantage of Linux Bus driver model. Each
0239 client is registered as device on the transport bus (ishtp bus).
0240 
0241 Enumeration sequence of messages:
0242 
0243 - Host sends HOST_START_REQ_CMD, indicating that host ISHTP layer is up.
0244 - FW responds with HOST_START_RES_CMD
0245 - Host sends HOST_ENUM_REQ_CMD (enumerate FW clients)
0246 - FW responds with HOST_ENUM_RES_CMD that includes bitmap of available FW
0247   client IDs
0248 - For each FW ID found in that bitmap host sends
0249   HOST_CLIENT_PROPERTIES_REQ_CMD
0250 - FW responds with HOST_CLIENT_PROPERTIES_RES_CMD. Properties include UUID,
0251   max ISHTP message size, etc.
0252 - Once host received properties for that last discovered client, it considers
0253   ISHTP device fully functional (and allocates DMA buffers)
0254 
0255 3.4 HID over ISH Client
0256 -----------------------
0257 
0258 Location: drivers/hid/intel-ish-hid
0259 
0260 The ISHTP client driver is responsible for:
0261 
0262 - enumerate HID devices under FW ISH client
0263 - Get Report descriptor
0264 - Register with HID core as a LL driver
0265 - Process Get/Set feature request
0266 - Get input reports
0267 
0268 3.5 HID Sensor Hub MFD and IIO sensor drivers
0269 ---------------------------------------------
0270 
0271 The functionality in these drivers is the same as an external sensor hub.
0272 Refer to
0273 Documentation/hid/hid-sensor.rst for HID sensor
0274 Documentation/ABI/testing/sysfs-bus-iio for IIO ABIs to user space.
0275 
0276 3.6 End to End HID transport Sequence Diagram
0277 ---------------------------------------------
0278 
0279 ::
0280 
0281   HID-ISH-CLN                    ISHTP                    IPC                             HW
0282           |                        |                       |                               |
0283           |                        |                       |-----WAKE UP------------------>|
0284           |                        |                       |                               |
0285           |                        |                       |-----HOST READY--------------->|
0286           |                        |                       |                               |
0287           |                        |                       |<----MNG_RESET_NOTIFY_ACK----- |
0288           |                        |                       |                               |
0289           |                        |<----ISHTP_START------ |                               |
0290           |                        |                       |                               |
0291           |                        |<-----------------HOST_START_RES_CMD-------------------|
0292           |                        |                       |                               |
0293           |                        |------------------QUERY_SUBSCRIBER-------------------->|
0294           |                        |                       |                               |
0295           |                        |------------------HOST_ENUM_REQ_CMD------------------->|
0296           |                        |                       |                               |
0297           |                        |<-----------------HOST_ENUM_RES_CMD--------------------|
0298           |                        |                       |                               |
0299           |                        |------------------HOST_CLIENT_PROPERTIES_REQ_CMD------>|
0300           |                        |                       |                               |
0301           |                        |<-----------------HOST_CLIENT_PROPERTIES_RES_CMD-------|
0302           |       Create new device on in ishtp bus        |                               |
0303           |                        |                       |                               |
0304           |                        |------------------HOST_CLIENT_PROPERTIES_REQ_CMD------>|
0305           |                        |                       |                               |
0306           |                        |<-----------------HOST_CLIENT_PROPERTIES_RES_CMD-------|
0307           |       Create new device on in ishtp bus        |                               |
0308           |                        |                       |                               |
0309           |                        |--Repeat HOST_CLIENT_PROPERTIES_REQ_CMD-till last one--|
0310           |                        |                       |                               |
0311        probed()
0312           |----ishtp_cl_connect--->|----------------- CLIENT_CONNECT_REQ_CMD-------------->|
0313           |                        |                       |                               |
0314           |                        |<----------------CLIENT_CONNECT_RES_CMD----------------|
0315           |                        |                       |                               |
0316           |register event callback |                       |                               |
0317           |                        |                       |                               |
0318           |ishtp_cl_send(
0319           HOSTIF_DM_ENUM_DEVICES)  |----------fill ishtp_msg_hdr struct write to HW-----  >|
0320           |                        |                       |                               |
0321           |                        |                       |<-----IRQ(IPC_PROTOCOL_ISHTP---|
0322           |                        |                       |                               |
0323           |<--ENUM_DEVICE RSP------|                       |                               |
0324           |                        |                       |                               |
0325   for each enumerated device
0326           |ishtp_cl_send(
0327           HOSTIF_GET_HID_DESCRIPTOR|----------fill ishtp_msg_hdr struct write to HW-----  >|
0328           |                        |                       |                               |
0329           ...Response
0330           |                        |                       |                               |
0331   for each enumerated device
0332           |ishtp_cl_send(
0333        HOSTIF_GET_REPORT_DESCRIPTOR|--------------fill ishtp_msg_hdr struct write to HW-- >|
0334           |                        |                       |                               |
0335           |                        |                       |                               |
0336    hid_allocate_device
0337           |                        |                       |                               |
0338    hid_add_device                  |                       |                               |
0339           |                        |                       |                               |
0340 
0341 
0342 3.7 ISH Debugging
0343 -----------------
0344 
0345 To debug ISH, event tracing mechanism is used. To enable debug logs::
0346 
0347   echo 1 > /sys/kernel/debug/tracing/events/intel_ish/enable
0348   cat /sys/kernel/debug/tracing/trace
0349 
0350 3.8 ISH IIO sysfs Example on Lenovo thinkpad Yoga 260
0351 -----------------------------------------------------
0352 
0353 ::
0354 
0355   root@otcpl-ThinkPad-Yoga-260:~# tree -l /sys/bus/iio/devices/
0356   /sys/bus/iio/devices/
0357   ├── iio:device0 -> ../../../devices/0044:8086:22D8.0001/HID-SENSOR-200073.9.auto/iio:device0
0358   │   ├── buffer
0359   │   │   ├── enable
0360   │   │   ├── length
0361   │   │   └── watermark
0362   ...
0363   │   ├── in_accel_hysteresis
0364   │   ├── in_accel_offset
0365   │   ├── in_accel_sampling_frequency
0366   │   ├── in_accel_scale
0367   │   ├── in_accel_x_raw
0368   │   ├── in_accel_y_raw
0369   │   ├── in_accel_z_raw
0370   │   ├── name
0371   │   ├── scan_elements
0372   │   │   ├── in_accel_x_en
0373   │   │   ├── in_accel_x_index
0374   │   │   ├── in_accel_x_type
0375   │   │   ├── in_accel_y_en
0376   │   │   ├── in_accel_y_index
0377   │   │   ├── in_accel_y_type
0378   │   │   ├── in_accel_z_en
0379   │   │   ├── in_accel_z_index
0380   │   │   └── in_accel_z_type
0381   ...
0382   │   │   ├── devices
0383   │   │   │   │   ├── buffer
0384   │   │   │   │   │   ├── enable
0385   │   │   │   │   │   ├── length
0386   │   │   │   │   │   └── watermark
0387   │   │   │   │   ├── dev
0388   │   │   │   │   ├── in_intensity_both_raw
0389   │   │   │   │   ├── in_intensity_hysteresis
0390   │   │   │   │   ├── in_intensity_offset
0391   │   │   │   │   ├── in_intensity_sampling_frequency
0392   │   │   │   │   ├── in_intensity_scale
0393   │   │   │   │   ├── name
0394   │   │   │   │   ├── scan_elements
0395   │   │   │   │   │   ├── in_intensity_both_en
0396   │   │   │   │   │   ├── in_intensity_both_index
0397   │   │   │   │   │   └── in_intensity_both_type
0398   │   │   │   │   ├── trigger
0399   │   │   │   │   │   └── current_trigger
0400   ...
0401   │   │   │   │   ├── buffer
0402   │   │   │   │   │   ├── enable
0403   │   │   │   │   │   ├── length
0404   │   │   │   │   │   └── watermark
0405   │   │   │   │   ├── dev
0406   │   │   │   │   ├── in_magn_hysteresis
0407   │   │   │   │   ├── in_magn_offset
0408   │   │   │   │   ├── in_magn_sampling_frequency
0409   │   │   │   │   ├── in_magn_scale
0410   │   │   │   │   ├── in_magn_x_raw
0411   │   │   │   │   ├── in_magn_y_raw
0412   │   │   │   │   ├── in_magn_z_raw
0413   │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_raw
0414   │   │   │   │   ├── in_rot_hysteresis
0415   │   │   │   │   ├── in_rot_offset
0416   │   │   │   │   ├── in_rot_sampling_frequency
0417   │   │   │   │   ├── in_rot_scale
0418   │   │   │   │   ├── name
0419   ...
0420   │   │   │   │   ├── scan_elements
0421   │   │   │   │   │   ├── in_magn_x_en
0422   │   │   │   │   │   ├── in_magn_x_index
0423   │   │   │   │   │   ├── in_magn_x_type
0424   │   │   │   │   │   ├── in_magn_y_en
0425   │   │   │   │   │   ├── in_magn_y_index
0426   │   │   │   │   │   ├── in_magn_y_type
0427   │   │   │   │   │   ├── in_magn_z_en
0428   │   │   │   │   │   ├── in_magn_z_index
0429   │   │   │   │   │   ├── in_magn_z_type
0430   │   │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_en
0431   │   │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_index
0432   │   │   │   │   │   └── in_rot_from_north_magnetic_tilt_comp_type
0433   │   │   │   │   ├── trigger
0434   │   │   │   │   │   └── current_trigger
0435   ...
0436   │   │   │   │   ├── buffer
0437   │   │   │   │   │   ├── enable
0438   │   │   │   │   │   ├── length
0439   │   │   │   │   │   └── watermark
0440   │   │   │   │   ├── dev
0441   │   │   │   │   ├── in_anglvel_hysteresis
0442   │   │   │   │   ├── in_anglvel_offset
0443   │   │   │   │   ├── in_anglvel_sampling_frequency
0444   │   │   │   │   ├── in_anglvel_scale
0445   │   │   │   │   ├── in_anglvel_x_raw
0446   │   │   │   │   ├── in_anglvel_y_raw
0447   │   │   │   │   ├── in_anglvel_z_raw
0448   │   │   │   │   ├── name
0449   │   │   │   │   ├── scan_elements
0450   │   │   │   │   │   ├── in_anglvel_x_en
0451   │   │   │   │   │   ├── in_anglvel_x_index
0452   │   │   │   │   │   ├── in_anglvel_x_type
0453   │   │   │   │   │   ├── in_anglvel_y_en
0454   │   │   │   │   │   ├── in_anglvel_y_index
0455   │   │   │   │   │   ├── in_anglvel_y_type
0456   │   │   │   │   │   ├── in_anglvel_z_en
0457   │   │   │   │   │   ├── in_anglvel_z_index
0458   │   │   │   │   │   └── in_anglvel_z_type
0459   │   │   │   │   ├── trigger
0460   │   │   │   │   │   └── current_trigger
0461   ...
0462   │   │   │   │   ├── buffer
0463   │   │   │   │   │   ├── enable
0464   │   │   │   │   │   ├── length
0465   │   │   │   │   │   └── watermark
0466   │   │   │   │   ├── dev
0467   │   │   │   │   ├── in_anglvel_hysteresis
0468   │   │   │   │   ├── in_anglvel_offset
0469   │   │   │   │   ├── in_anglvel_sampling_frequency
0470   │   │   │   │   ├── in_anglvel_scale
0471   │   │   │   │   ├── in_anglvel_x_raw
0472   │   │   │   │   ├── in_anglvel_y_raw
0473   │   │   │   │   ├── in_anglvel_z_raw
0474   │   │   │   │   ├── name
0475   │   │   │   │   ├── scan_elements
0476   │   │   │   │   │   ├── in_anglvel_x_en
0477   │   │   │   │   │   ├── in_anglvel_x_index
0478   │   │   │   │   │   ├── in_anglvel_x_type
0479   │   │   │   │   │   ├── in_anglvel_y_en
0480   │   │   │   │   │   ├── in_anglvel_y_index
0481   │   │   │   │   │   ├── in_anglvel_y_type
0482   │   │   │   │   │   ├── in_anglvel_z_en
0483   │   │   │   │   │   ├── in_anglvel_z_index
0484   │   │   │   │   │   └── in_anglvel_z_type
0485   │   │   │   │   ├── trigger
0486   │   │   │   │   │   └── current_trigger
0487   ...