Blame view

Documentation/hid/hid-transport.rst 15.6 KB
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
1
2
3
  =========================
  HID I/O Transport Drivers
  =========================
6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  
  The HID subsystem is independent of the underlying transport driver. Initially,
  only USB was supported, but other specifications adopted the HID design and
  provided new transport drivers. The kernel includes at least support for USB,
  Bluetooth, I2C and user-space I/O drivers.
  
  1) HID Bus
  ==========
  
  The HID subsystem is designed as a bus. Any I/O subsystem may provide HID
  devices and register them with the HID bus. HID core then loads generic device
  drivers on top of it. The transport drivers are responsible of raw data
  transport and device setup/management. HID core is responsible of
  report-parsing, report interpretation and the user-space API. Device specifics
  and quirks are handled by all layers depending on the quirk.
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
19
  ::
6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
   +-----------+  +-----------+            +-----------+  +-----------+
   | Device #1 |  | Device #i |            | Device #j |  | Device #k |
   +-----------+  +-----------+            +-----------+  +-----------+
            \\      //                              \\      //
          +------------+                          +------------+
          | I/O Driver |                          | I/O Driver |
          +------------+                          +------------+
                ||                                      ||
       +------------------+                    +------------------+
       | Transport Driver |                    | Transport Driver |
       +------------------+                    +------------------+
                         \___                ___/
                             \              /
                            +----------------+
                            |    HID Core    |
                            +----------------+
                             /  |        |  \
                            /   |        |   \
               ____________/    |        |    \_________________
              /                 |        |                      \
             /                  |        |                       \
   +----------------+  +-----------+  +------------------+  +------------------+
   | Generic Driver |  | MT Driver |  | Custom Driver #1 |  | Custom Driver #2 |
   +----------------+  +-----------+  +------------------+  +------------------+
  
  Example Drivers:
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
46
47
48
  
    - I/O: USB, I2C, Bluetooth-l2cap
    - Transport: USB-HID, I2C-HID, BT-HIDP
6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
  
  Everything below "HID Core" is simplified in this graph as it is only of
  interest to HID device drivers. Transport drivers do not need to know the
  specifics.
  
  1.1) Device Setup
  -----------------
  
  I/O drivers normally provide hotplug detection or device enumeration APIs to the
  transport drivers. Transport drivers use this to find any suitable HID device.
  They allocate HID device objects and register them with HID core. Transport
  drivers are not required to register themselves with HID core. HID core is never
  aware of which transport drivers are available and is not interested in it. It
  is only interested in devices.
  
  Transport drivers attach a constant "struct hid_ll_driver" object with each
  device. Once a device is registered with HID core, the callbacks provided via
  this struct are used by HID core to communicate with the device.
  
  Transport drivers are responsible of detecting device failures and unplugging.
  HID core will operate a device as long as it is registered regardless of any
  device failures. Once transport drivers detect unplug or failure events, they
  must unregister the device from HID core and HID core will stop using the
  provided callbacks.
  
  1.2) Transport Driver Requirements
  ----------------------------------
  
  The terms "asynchronous" and "synchronous" in this document describe the
  transmission behavior regarding acknowledgements. An asynchronous channel must
  not perform any synchronous operations like waiting for acknowledgements or
  verifications. Generally, HID calls operating on asynchronous channels must be
  running in atomic-context just fine.
  On the other hand, synchronous channels can be implemented by the transport
  driver in whatever way they like. They might just be the same as asynchronous
  channels, but they can also provide acknowledgement reports, automatic
  retransmission on failure, etc. in a blocking manner. If such functionality is
  required on asynchronous channels, a transport-driver must implement that via
  its own worker threads.
  
  HID core requires transport drivers to follow a given design. A Transport
  driver must provide two bi-directional I/O channels to each HID device. These
  channels must not necessarily be bi-directional in the hardware itself. A
  transport driver might just provide 4 uni-directional channels. Or it might
  multiplex all four on a single physical channel. However, in this document we
  will describe them as two bi-directional channels as they have several
  properties in common.
  
   - Interrupt Channel (intr): The intr channel is used for asynchronous data
     reports. No management commands or data acknowledgements are sent on this
     channel. Any unrequested incoming or outgoing data report must be sent on
     this channel and is never acknowledged by the remote side. Devices usually
     send their input events on this channel. Outgoing events are normally
     not send via intr, except if high throughput is required.
   - Control Channel (ctrl): The ctrl channel is used for synchronous requests and
     device management. Unrequested data input events must not be sent on this
     channel and are normally ignored. Instead, devices only send management
     events or answers to host requests on this channel.
     The control-channel is used for direct blocking queries to the device
     independent of any events on the intr-channel.
     Outgoing reports are usually sent on the ctrl channel via synchronous
     SET_REPORT requests.
  
  Communication between devices and HID core is mostly done via HID reports. A
  report can be of one of three types:
  
   - INPUT Report: Input reports provide data from device to host. This
     data may include button events, axis events, battery status or more. This
     data is generated by the device and sent to the host with or without
     requiring explicit requests. Devices can choose to send data continuously or
     only on change.
   - OUTPUT Report: Output reports change device states. They are sent from host
     to device and may include LED requests, rumble requests or more. Output
     reports are never sent from device to host, but a host can retrieve their
     current state.
     Hosts may choose to send output reports either continuously or only on
     change.
   - FEATURE Report: Feature reports are used for specific static device features
     and never reported spontaneously. A host can read and/or write them to access
     data like battery-state or device-settings.
     Feature reports are never sent without requests. A host must explicitly set
     or retrieve a feature report. This also means, feature reports are never sent
     on the intr channel as this channel is asynchronous.
  
  INPUT and OUTPUT reports can be sent as pure data reports on the intr channel.
  For INPUT reports this is the usual operational mode. But for OUTPUT reports,
  this is rarely done as OUTPUT reports are normally quite scarce. But devices are
  free to make excessive use of asynchronous OUTPUT reports (for instance, custom
  HID audio speakers make great use of it).
  
  Plain reports must not be sent on the ctrl channel, though. Instead, the ctrl
  channel provides synchronous GET/SET_REPORT requests. Plain reports are only
  allowed on the intr channel and are the only means of data there.
  
   - GET_REPORT: A GET_REPORT request has a report ID as payload and is sent
     from host to device. The device must answer with a data report for the
     requested report ID on the ctrl channel as a synchronous acknowledgement.
     Only one GET_REPORT request can be pending for each device. This restriction
     is enforced by HID core as several transport drivers don't allow multiple
     simultaneous GET_REPORT requests.
     Note that data reports which are sent as answer to a GET_REPORT request are
     not handled as generic device events. That is, if a device does not operate
     in continuous data reporting mode, an answer to GET_REPORT does not replace
     the raw data report on the intr channel on state change.
     GET_REPORT is only used by custom HID device drivers to query device state.
     Normally, HID core caches any device state so this request is not necessary
     on devices that follow the HID specs except during device initialization to
     retrieve the current state.
     GET_REPORT requests can be sent for any of the 3 report types and shall
     return the current report state of the device. However, OUTPUT reports as
     payload may be blocked by the underlying transport driver if the
     specification does not allow them.
   - SET_REPORT: A SET_REPORT request has a report ID plus data as payload. It is
     sent from host to device and a device must update it's current report state
     according to the given data. Any of the 3 report types can be used. However,
     INPUT reports as payload might be blocked by the underlying transport driver
     if the specification does not allow them.
     A device must answer with a synchronous acknowledgement. However, HID core
     does not require transport drivers to forward this acknowledgement to HID
     core.
     Same as for GET_REPORT, only one SET_REPORT can be pending at a time. This
     restriction is enforced by HID core as some transport drivers do not support
     multiple synchronous SET_REPORT requests.
  
  Other ctrl-channel requests are supported by USB-HID but are not available
  (or deprecated) in most other transport level specifications:
  
   - GET/SET_IDLE: Only used by USB-HID and I2C-HID.
   - GET/SET_PROTOCOL: Not used by HID core.
   - RESET: Used by I2C-HID, not hooked up in HID core.
   - SET_POWER: Used by I2C-HID, not hooked up in HID core.
  
  2) HID API
  ==========
  
  2.1) Initialization
  -------------------
  
  Transport drivers normally use the following procedure to register a new device
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
188
  with HID core::
6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
189
190
191
192
193
194
195
196
197
  
  	struct hid_device *hid;
  	int ret;
  
  	hid = hid_allocate_device();
  	if (IS_ERR(hid)) {
  		ret = PTR_ERR(hid);
  		goto err_<...>;
  	}
220ee02a0   Stephen Kitt   docs: stop sugges...
198
199
200
  	strscpy(hid->name, <device-name-src>, sizeof(hid->name));
  	strscpy(hid->phys, <device-phys-src>, sizeof(hid->phys));
  	strscpy(hid->uniq, <device-uniq-src>, sizeof(hid->uniq));
6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
  
  	hid->ll_driver = &custom_ll_driver;
  	hid->bus = <device-bus>;
  	hid->vendor = <device-vendor>;
  	hid->product = <device-product>;
  	hid->version = <device-version>;
  	hid->country = <device-country>;
  	hid->dev.parent = <pointer-to-parent-device>;
  	hid->driver_data = <transport-driver-data-field>;
  
  	ret = hid_add_device(hid);
  	if (ret)
  		goto err_<...>;
  
  Once hid_add_device() is entered, HID core might use the callbacks provided in
  "custom_ll_driver". Note that fields like "country" can be ignored by underlying
  transport-drivers if not supported.
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
218
  To unregister a device, use::
6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
219
220
221
222
223
224
225
226
227
228
  
  	hid_destroy_device(hid);
  
  Once hid_destroy_device() returns, HID core will no longer make use of any
  driver callbacks.
  
  2.2) hid_ll_driver operations
  -----------------------------
  
  The available HID callbacks are:
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
229
230
231
232
  
     ::
  
        int (*start) (struct hid_device *hdev)
6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
233
234
235
236
     Called from HID device drivers once they want to use the device. Transport
     drivers can choose to setup their device in this callback. However, normally
     devices are already set up before transport drivers register them to HID core
     so this is mostly only used by USB-HID.
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
237
238
239
     ::
  
        void (*stop) (struct hid_device *hdev)
6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
240
241
242
243
     Called from HID device drivers once they are done with a device. Transport
     drivers can free any buffers and deinitialize the device. But note that
     ->start() might be called again if another HID device driver is loaded on the
     device.
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
244

6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
245
246
     Transport drivers are free to ignore it and deinitialize devices after they
     destroyed them via hid_destroy_device().
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
247
248
249
     ::
  
        int (*open) (struct hid_device *hdev)
6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
250
251
252
253
254
     Called from HID device drivers once they are interested in data reports.
     Usually, while user-space didn't open any input API/etc., device drivers are
     not interested in device data and transport drivers can put devices asleep.
     However, once ->open() is called, transport drivers must be ready for I/O.
     ->open() calls are nested for each client that opens the HID device.
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
255
256
257
     ::
  
        void (*close) (struct hid_device *hdev)
6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
258
259
260
     Called from HID device drivers after ->open() was called but they are no
     longer interested in device reports. (Usually if user-space closed any input
     devices of the driver).
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
261

6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
262
263
264
     Transport drivers can put devices asleep and terminate any I/O of all
     ->open() calls have been followed by a ->close() call. However, ->start() may
     be called again if the device driver is interested in input reports again.
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
265
266
267
     ::
  
        int (*parse) (struct hid_device *hdev)
6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
268
269
270
     Called once during device setup after ->start() has been called. Transport
     drivers must read the HID report-descriptor from the device and tell HID core
     about it via hid_parse_report().
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
271
272
273
     ::
  
        int (*power) (struct hid_device *hdev, int level)
6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
274
275
     Called by HID core to give PM hints to transport drivers. Usually this is
     analogical to the ->open() and ->close() hints and redundant.
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
276
277
278
279
     ::
  
        void (*request) (struct hid_device *hdev, struct hid_report *report,
  		       int reqtype)
6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
280
281
282
     Send an HID request on the ctrl channel. "report" contains the report that
     should be sent and "reqtype" the request type. Request-type can be
     HID_REQ_SET_REPORT or HID_REQ_GET_REPORT.
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
283

6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
284
285
286
     This callback is optional. If not provided, HID core will assemble a raw
     report following the HID specs and send it via the ->raw_request() callback.
     The transport driver is free to implement this asynchronously.
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
287
288
289
     ::
  
        int (*wait) (struct hid_device *hdev)
6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
290
291
292
     Used by HID core before calling ->request() again. A transport driver can use
     it to wait for any pending requests to complete if only one request is
     allowed at a time.
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
293
294
295
296
297
     ::
  
        int (*raw_request) (struct hid_device *hdev, unsigned char reportnum,
                            __u8 *buf, size_t count, unsigned char rtype,
                            int reqtype)
6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
298
299
     Same as ->request() but provides the report as raw buffer. This request shall
     be synchronous. A transport driver must not use ->wait() to complete such
3c86726cf   Benjamin Tissoires   HID: make .raw_re...
300
301
     requests. This request is mandatory and hid core will reject the device if
     it is missing.
6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
302

cca478617   Mauro Carvalho Chehab   docs: hid: conver...
303
304
305
     ::
  
        int (*output_report) (struct hid_device *hdev, __u8 *buf, size_t len)
6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
306
307
308
309
     Send raw output report via intr channel. Used by some HID device drivers
     which require high throughput for outgoing requests on the intr channel. This
     must not cause SET_REPORT calls! This must be implemented as asynchronous
     output report on the intr channel!
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
310
311
312
     ::
  
        int (*idle) (struct hid_device *hdev, int report, int idle, int reqtype)
6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
     Perform SET/GET_IDLE request. Only used by USB-HID, do not implement!
  
  2.3) Data Path
  --------------
  
  Transport drivers are responsible of reading data from I/O devices. They must
  handle any I/O-related state-tracking themselves. HID core does not implement
  protocol handshakes or other management commands which can be required by the
  given HID transport specification.
  
  Every raw data packet read from a device must be fed into HID core via
  hid_input_report(). You must specify the channel-type (intr or ctrl) and report
  type (input/output/feature). Under normal conditions, only input reports are
  provided via this API.
  
  Responses to GET_REPORT requests via ->request() must also be provided via this
  API. Responses to ->raw_request() are synchronous and must be intercepted by the
  transport driver and not passed to hid_input_report().
  Acknowledgements to SET_REPORT requests are not of interest to HID core.
  
  ----------------------------------------------------
cca478617   Mauro Carvalho Chehab   docs: hid: conver...
334

6fad42d5f   Benjamin Tissoires   HID: Add HID tran...
335
  Written 2013, David Herrmann <dh.herrmann@gmail.com>