Merge branch 'pm-cpufreq'
[cascardo/linux.git] / Documentation / hid / intel-ish-hid.txt
1 Intel Integrated Sensor Hub (ISH)
2 ===============================
3
4 A sensor hub enables the ability to offload sensor polling and algorithm
5 processing to a dedicated low power co-processor. This allows the core
6 processor to go into low power modes more often, resulting in the increased
7 battery life.
8
9 There are many vendors providing external sensor hubs confirming to HID
10 Sensor usage tables, and used in several tablets, 2 in 1 convertible laptops
11 and embedded products. Linux had this support since Linux 3.9.
12
13 Intel® introduced integrated sensor hubs as a part of the SoC starting from
14 Cherry Trail and now supported on multiple generations of CPU packages. There
15 are many commercial devices already shipped with Integrated Sensor Hubs (ISH).
16 These ISH also comply to HID sensor specification, but the  difference is the
17 transport protocol used for communication. The current external sensor hubs
18 mainly use HID over i2C or USB. But ISH doesn't use either i2c or USB.
19
20 1. Overview
21
22 Using a analogy with a usbhid implementation, the ISH follows a similar model
23 for a very high speed communication:
24
25         -----------------               ----------------------
26         |    USB HID    |       -->     |    ISH HID         |
27         -----------------               ----------------------
28         -----------------               ----------------------
29         |  USB protocol |       -->     |    ISH Transport   |
30         -----------------               ----------------------
31         -----------------               ----------------------
32         |  EHCI/XHCI    |       -->     |    ISH IPC         |
33         -----------------               ----------------------
34               PCI                                PCI
35         -----------------               ----------------------
36         |Host controller|       -->     |    ISH processor   |
37         -----------------               ----------------------
38              USB Link
39         -----------------               ----------------------
40         | USB End points|       -->     |    ISH Clients     |
41         -----------------               ----------------------
42
43 Like USB protocol provides a method for device enumeration, link management
44 and user data encapsulation, the ISH also provides similar services. But it is
45 very light weight tailored to manage and communicate with ISH client
46 applications implemented in the firmware.
47
48 The ISH allows multiple sensor management applications executing in the
49 firmware. Like USB endpoints the messaging can be to/from a client. As part of
50 enumeration process, these clients are identified. These clients can be simple
51 HID sensor applications, sensor calibration application or senor firmware
52 update application.
53
54 The implementation model is similar, like USB bus, ISH transport is also
55 implemented as a bus. Each client application executing in the ISH processor
56 is registered as a device on this bus. The driver, which binds each device
57 (ISH HID driver) identifies the device type and registers with the hid core.
58
59 2. ISH Implementation: Block Diagram
60
61          ---------------------------
62         |  User Space Applications  |
63          ---------------------------
64
65 ----------------IIO ABI----------------
66          --------------------------
67         |  IIO Sensor Drivers     |
68          --------------------------
69          --------------------------
70         |        IIO core         |
71          --------------------------
72          --------------------------
73         |   HID Sensor Hub MFD    |
74          --------------------------
75          --------------------------
76         |       HID Core          |
77          --------------------------
78          --------------------------
79         |   HID over ISH Client   |
80          --------------------------
81          --------------------------
82         |   ISH Transport (ISHTP) |
83          --------------------------
84          --------------------------
85         |      IPC Drivers        |
86          --------------------------
87 OS
88 ----------------   PCI -----------------
89 Hardware + Firmware
90          ----------------------------
91         | ISH Hardware/Firmware(FW) |
92          ----------------------------
93
94 3. High level processing in above blocks
95
96 3.1 Hardware Interface
97
98 The ISH is exposed as "Non-VGA unclassified PCI device" to the host. The PCI
99 product and vendor IDs are changed from different generations of processors. So
100 the source code which enumerate drivers needs to update from generation to
101 generation.
102
103 3.2 Inter Processor Communication (IPC) driver
104 Location: drivers/hid/intel-ish-hid/ipc
105
106 The IPC message used memory mapped I/O. The registers are defined in
107 hw-ish-regs.h.
108
109 3.2.1 IPC/FW message types
110
111 There are two types of messages, one for management of link and other messages
112 are to and from transport layers.
113
114 TX and RX of Transport messages
115
116 A set of memory mapped register offers support of multi byte messages TX and
117 RX (E.g.IPC_REG_ISH2HOST_MSG, IPC_REG_HOST2ISH_MSG). The IPC layer maintains
118 internal queues to sequence messages and send them in order to the FW.
119 Optionally the caller can register handler to get notification of completion.
120 A door bell mechanism is used in messaging to trigger processing in host and
121 client firmware side. When ISH interrupt handler is called, the ISH2HOST
122 doorbell register is used by host drivers to determine that the interrupt
123 is for ISH.
124
125 Each side has 32 32-bit message registers and a 32-bit doorbell. Doorbell
126 register has the following format:
127 Bits 0..6: fragment length (7 bits are used)
128 Bits 10..13: encapsulated protocol
129 Bits 16..19: management command (for IPC management protocol)
130 Bit 31: doorbell trigger (signal H/W interrupt to the other side)
131 Other bits are reserved, should be 0.
132
133 3.2.2 Transport layer interface
134
135 To abstract HW level IPC communication, a set of callbacks are registered.
136 The transport layer uses them to send and receive messages.
137 Refer to  struct ishtp_hw_ops for callbacks.
138
139 3.3 ISH Transport layer
140 Location: drivers/hid/intel-ish-hid/ishtp/
141
142 3.3.1 A Generic Transport Layer
143
144 The transport layer is a bi-directional protocol, which defines:
145 - Set of commands to start, stop, connect, disconnect and flow control
146 (ishtp/hbm.h) for details
147 - A flow control mechanism to avoid buffer overflows
148
149 This protocol resembles bus messages described in the following document:
150 http://www.intel.com/content/dam/www/public/us/en/documents/technical-\
151 specifications/dcmi-hi-1-0-spec.pdf "Chapter 7: Bus Message Layer"
152
153 3.3.2 Connection and Flow Control Mechanism
154
155 Each FW client and a protocol is identified by an UUID. In order to communicate
156 to a FW client, a connection must be established using connect request and
157 response bus messages. If successful, a pair (host_client_id and fw_client_id)
158 will identify the connection.
159
160 Once connection is established, peers send each other flow control bus messages
161 independently. Every peer may send a message only if it has received a
162 flow-control credit before. Once it sent a message, it may not send another one
163 before receiving the next flow control credit.
164 Either side can send disconnect request bus message to end communication. Also
165 the link will be dropped if major FW reset occurs.
166
167 3.3.3 Peer to Peer data transfer
168
169 Peer to Peer data transfer can happen with or without using DMA. Depending on
170 the sensor bandwidth requirement DMA can be enabled by using module parameter
171 ishtp_use_dma under intel_ishtp.
172
173 Each side (host and FW) manages its DMA transfer memory independently. When an
174 ISHTP client from either host or FW side wants to send something, it decides
175 whether to send over IPC or over DMA; for each transfer the decision is
176 independent. The sending side sends DMA_XFER message when the message is in
177 the respective host buffer (TX when host client sends, RX when FW client
178 sends). The recipient of DMA message responds with DMA_XFER_ACK, indicating
179 the sender that the memory region for that message may be reused.
180
181 DMA initialization is started with host sending DMA_ALLOC_NOTIFY bus message
182 (that includes RX buffer) and FW responds with DMA_ALLOC_NOTIFY_ACK.
183 Additionally to DMA address communication, this sequence checks capabilities:
184 if thw host doesn't support DMA, then it won't send DMA allocation, so FW can't
185 send DMA; if FW doesn't support DMA then it won't respond with
186 DMA_ALLOC_NOTIFY_ACK, in which case host will not use DMA transfers.
187 Here ISH acts as busmaster DMA controller. Hence when host sends DMA_XFER,
188 it's request to do host->ISH DMA transfer; when FW sends DMA_XFER, it means
189 that it already did DMA and the message resides at host. Thus, DMA_XFER
190 and DMA_XFER_ACK act as ownership indicators.
191
192 At initial state all outgoing memory belongs to the sender (TX to host, RX to
193 FW), DMA_XFER transfers ownership on the region that contains ISHTP message to
194 the receiving side, DMA_XFER_ACK returns ownership to the sender. A sender
195 needs not wait for previous DMA_XFER to be ack'ed, and may send another message
196 as long as remaining continuous memory in its ownership is enough.
197 In principle, multiple DMA_XFER and DMA_XFER_ACK messages may be sent at once
198 (up to IPC MTU), thus allowing for interrupt throttling.
199 Currently, ISH FW decides to send over DMA if ISHTP message is more than 3 IPC
200 fragments and via IPC otherwise.
201
202 3.3.4 Ring Buffers
203
204 When a client initiate a connection, a ring or RX and TX buffers are allocated.
205 The size of ring can be specified by the client. HID client set 16 and 32 for
206 TX and RX buffers respectively. On send request from client, the data to be
207 sent is copied to one of the send ring buffer and scheduled to be sent using
208 bus message protocol. These buffers are required because the FW may have not
209 have processed the last message and may not have enough flow control credits
210 to send. Same thing holds true on receive side and flow control is required.
211
212 3.3.5 Host Enumeration
213
214 The host enumeration bus command allow discovery of clients present in the FW.
215 There can be multiple sensor clients and clients for calibration function.
216
217 To ease in implantation and allow independent driver handle each client
218 this transport layer takes advantage of Linux Bus driver model. Each
219 client is registered as device on the the transport bus (ishtp bus).
220
221 Enumeration sequence of messages:
222 - Host sends HOST_START_REQ_CMD, indicating that host ISHTP layer is up.
223 - FW responds with HOST_START_RES_CMD
224 - Host sends HOST_ENUM_REQ_CMD (enumerate FW clients)
225 - FW responds with HOST_ENUM_RES_CMD that includes bitmap of available FW
226 client IDs
227 - For each FW ID found in that bitmap host sends
228 HOST_CLIENT_PROPERTIES_REQ_CMD
229 - FW responds with HOST_CLIENT_PROPERTIES_RES_CMD. Properties include UUID,
230 max ISHTP message size, etc.
231 - Once host received properties for that last discovered client, it considers
232 ISHTP device fully functional (and allocates DMA buffers)
233
234 3.4 HID over ISH Client
235 Location: drivers/hid/intel-ish-hid
236
237 The ISHTP client driver is responsible for:
238 - enumerate HID devices under FW ISH client
239 - Get Report descriptor
240 - Register with HID core as a LL driver
241 - Process Get/Set feature request
242 - Get input reports
243
244 3.5 HID Sensor Hub MFD and IIO sensor drivers
245
246 The functionality in these drivers is the same as an external sensor hub.
247 Refer to
248 Documentation/hid/hid-sensor.txt for HID sensor
249 Documentation/ABI/testing/sysfs-bus-iio for IIO ABIs to user space
250
251 3.6 End to End HID transport Sequence Diagram
252
253 HID-ISH-CLN                     ISHTP                   IPC                             HW
254         |                       |                       |                               |
255         |                       |                       |-----WAKE UP------------------>|
256         |                       |                       |                               |
257         |                       |                       |-----HOST READY--------------->|
258         |                       |                       |                               |
259         |                       |                       |<----MNG_RESET_NOTIFY_ACK----- |
260         |                       |                       |                               |
261         |                       |<----ISHTP_START------ |                               |
262         |                       |                       |                               |
263         |                       |<-----------------HOST_START_RES_CMD-------------------|
264         |                       |                       |                               |
265         |                       |------------------QUERY_SUBSCRIBER-------------------->|
266         |                       |                       |                               |
267         |                       |------------------HOST_ENUM_REQ_CMD------------------->|
268         |                       |                       |                               |
269         |                       |<-----------------HOST_ENUM_RES_CMD--------------------|
270         |                       |                       |                               |
271         |                       |------------------HOST_CLIENT_PROPERTIES_REQ_CMD------>|
272         |                       |                       |                               |
273         |                       |<-----------------HOST_CLIENT_PROPERTIES_RES_CMD-------|
274         |       Create new device on in ishtp bus       |                               |
275         |                       |                       |                               |
276         |                       |------------------HOST_CLIENT_PROPERTIES_REQ_CMD------>|
277         |                       |                       |                               |
278         |                       |<-----------------HOST_CLIENT_PROPERTIES_RES_CMD-------|
279         |       Create new device on in ishtp bus       |                               |
280         |                       |                       |                               |
281         |                       |--Repeat HOST_CLIENT_PROPERTIES_REQ_CMD-till last one--|
282         |                       |                       |                               |
283      probed()
284         |----ishtp_cl_connect-->|----------------- CLIENT_CONNECT_REQ_CMD-------------->|
285         |                       |                       |                               |
286         |                       |<----------------CLIENT_CONNECT_RES_CMD----------------|
287         |                       |                       |                               |
288         |register event callback|                       |                               |
289         |                       |                       |                               |
290         |ishtp_cl_send(
291         HOSTIF_DM_ENUM_DEVICES) |----------fill ishtp_msg_hdr struct write to HW-----  >|
292         |                       |                       |                               |
293         |                       |                       |<-----IRQ(IPC_PROTOCOL_ISHTP---|
294         |                       |                       |                               |
295         |<--ENUM_DEVICE RSP-----|                       |                               |
296         |                       |                       |                               |
297 for each enumerated device
298         |ishtp_cl_send(
299         HOSTIF_GET_HID_DESCRIPTOR |----------fill ishtp_msg_hdr struct write to HW---  >|
300         |                       |                       |                               |
301         ...Response
302         |                       |                       |                               |
303 for each enumerated device
304         |ishtp_cl_send(
305         HOSTIF_GET_REPORT_DESCRIPTOR |----------fill ishtp_msg_hdr struct write to HW- >|
306         |                       |                       |                               |
307         |                       |                       |                               |
308  hid_allocate_device
309         |                       |                       |                               |
310  hid_add_device                 |                       |                               |
311         |                       |                       |                               |
312
313
314 3.7 ISH Debugging
315
316 To debug ISH, event tracing mechanism is used. To enable debug logs
317 echo 1 > /sys/kernel/debug/tracing/events/intel_ish/enable
318 cat sys/kernel/debug/tracing/trace
319
320 3.8 ISH IIO sysfs Example on Lenovo thinkpad Yoga 260
321
322 root@otcpl-ThinkPad-Yoga-260:~# tree -l /sys/bus/iio/devices/
323 /sys/bus/iio/devices/
324 ├── iio:device0 -> ../../../devices/0044:8086:22D8.0001/HID-SENSOR-200073.9.auto/iio:device0
325 │   ├── buffer
326 │   │   ├── enable
327 │   │   ├── length
328 │   │   └── watermark
329 ...
330 │   ├── in_accel_hysteresis
331 │   ├── in_accel_offset
332 │   ├── in_accel_sampling_frequency
333 │   ├── in_accel_scale
334 │   ├── in_accel_x_raw
335 │   ├── in_accel_y_raw
336 │   ├── in_accel_z_raw
337 │   ├── name
338 │   ├── scan_elements
339 │   │   ├── in_accel_x_en
340 │   │   ├── in_accel_x_index
341 │   │   ├── in_accel_x_type
342 │   │   ├── in_accel_y_en
343 │   │   ├── in_accel_y_index
344 │   │   ├── in_accel_y_type
345 │   │   ├── in_accel_z_en
346 │   │   ├── in_accel_z_index
347 │   │   └── in_accel_z_type
348 ...
349 │   │   ├── devices
350 │   │   │   │   ├── buffer
351 │   │   │   │   │   ├── enable
352 │   │   │   │   │   ├── length
353 │   │   │   │   │   └── watermark
354 │   │   │   │   ├── dev
355 │   │   │   │   ├── in_intensity_both_raw
356 │   │   │   │   ├── in_intensity_hysteresis
357 │   │   │   │   ├── in_intensity_offset
358 │   │   │   │   ├── in_intensity_sampling_frequency
359 │   │   │   │   ├── in_intensity_scale
360 │   │   │   │   ├── name
361 │   │   │   │   ├── scan_elements
362 │   │   │   │   │   ├── in_intensity_both_en
363 │   │   │   │   │   ├── in_intensity_both_index
364 │   │   │   │   │   └── in_intensity_both_type
365 │   │   │   │   ├── trigger
366 │   │   │   │   │   └── current_trigger
367 ...
368 │   │   │   │   ├── buffer
369 │   │   │   │   │   ├── enable
370 │   │   │   │   │   ├── length
371 │   │   │   │   │   └── watermark
372 │   │   │   │   ├── dev
373 │   │   │   │   ├── in_magn_hysteresis
374 │   │   │   │   ├── in_magn_offset
375 │   │   │   │   ├── in_magn_sampling_frequency
376 │   │   │   │   ├── in_magn_scale
377 │   │   │   │   ├── in_magn_x_raw
378 │   │   │   │   ├── in_magn_y_raw
379 │   │   │   │   ├── in_magn_z_raw
380 │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_raw
381 │   │   │   │   ├── in_rot_hysteresis
382 │   │   │   │   ├── in_rot_offset
383 │   │   │   │   ├── in_rot_sampling_frequency
384 │   │   │   │   ├── in_rot_scale
385 │   │   │   │   ├── name
386 ...
387 │   │   │   │   ├── scan_elements
388 │   │   │   │   │   ├── in_magn_x_en
389 │   │   │   │   │   ├── in_magn_x_index
390 │   │   │   │   │   ├── in_magn_x_type
391 │   │   │   │   │   ├── in_magn_y_en
392 │   │   │   │   │   ├── in_magn_y_index
393 │   │   │   │   │   ├── in_magn_y_type
394 │   │   │   │   │   ├── in_magn_z_en
395 │   │   │   │   │   ├── in_magn_z_index
396 │   │   │   │   │   ├── in_magn_z_type
397 │   │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_en
398 │   │   │   │   │   ├── in_rot_from_north_magnetic_tilt_comp_index
399 │   │   │   │   │   └── in_rot_from_north_magnetic_tilt_comp_type
400 │   │   │   │   ├── trigger
401 │   │   │   │   │   └── current_trigger
402 ...
403 │   │   │   │   ├── buffer
404 │   │   │   │   │   ├── enable
405 │   │   │   │   │   ├── length
406 │   │   │   │   │   └── watermark
407 │   │   │   │   ├── dev
408 │   │   │   │   ├── in_anglvel_hysteresis
409 │   │   │   │   ├── in_anglvel_offset
410 │   │   │   │   ├── in_anglvel_sampling_frequency
411 │   │   │   │   ├── in_anglvel_scale
412 │   │   │   │   ├── in_anglvel_x_raw
413 │   │   │   │   ├── in_anglvel_y_raw
414 │   │   │   │   ├── in_anglvel_z_raw
415 │   │   │   │   ├── name
416 │   │   │   │   ├── scan_elements
417 │   │   │   │   │   ├── in_anglvel_x_en
418 │   │   │   │   │   ├── in_anglvel_x_index
419 │   │   │   │   │   ├── in_anglvel_x_type
420 │   │   │   │   │   ├── in_anglvel_y_en
421 │   │   │   │   │   ├── in_anglvel_y_index
422 │   │   │   │   │   ├── in_anglvel_y_type
423 │   │   │   │   │   ├── in_anglvel_z_en
424 │   │   │   │   │   ├── in_anglvel_z_index
425 │   │   │   │   │   └── in_anglvel_z_type
426 │   │   │   │   ├── trigger
427 │   │   │   │   │   └── current_trigger
428 ...
429 │   │   │   │   ├── buffer
430 │   │   │   │   │   ├── enable
431 │   │   │   │   │   ├── length
432 │   │   │   │   │   └── watermark
433 │   │   │   │   ├── dev
434 │   │   │   │   ├── in_anglvel_hysteresis
435 │   │   │   │   ├── in_anglvel_offset
436 │   │   │   │   ├── in_anglvel_sampling_frequency
437 │   │   │   │   ├── in_anglvel_scale
438 │   │   │   │   ├── in_anglvel_x_raw
439 │   │   │   │   ├── in_anglvel_y_raw
440 │   │   │   │   ├── in_anglvel_z_raw
441 │   │   │   │   ├── name
442 │   │   │   │   ├── scan_elements
443 │   │   │   │   │   ├── in_anglvel_x_en
444 │   │   │   │   │   ├── in_anglvel_x_index
445 │   │   │   │   │   ├── in_anglvel_x_type
446 │   │   │   │   │   ├── in_anglvel_y_en
447 │   │   │   │   │   ├── in_anglvel_y_index
448 │   │   │   │   │   ├── in_anglvel_y_type
449 │   │   │   │   │   ├── in_anglvel_z_en
450 │   │   │   │   │   ├── in_anglvel_z_index
451 │   │   │   │   │   └── in_anglvel_z_type
452 │   │   │   │   ├── trigger
453 │   │   │   │   │   └── current_trigger
454 ...