intel-ish-hid.txt 20 KB

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