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