Hi On Wed, Jan 29, 2014 at 4:28 PM, Frank Praznik <frank.praznik@xxxxxxxxx> wrote: > Add David Herrmann's documentation for the new low-level HID transport driver > functions. > > Signed-off-by: Frank Praznik <frank.praznik@xxxxxxxxx> If you copy code, you really should keep the signed-off-by chain. A signed-off-by in kernel context means that you either wrote the code or have permission to copy it. See here: http://developercertificate.org/ (which is a public copy of the kernel's signed-off-by practice). If you copy code unchanged, it's common practice to even keep the "Author" field via "git commit --author", but that's optional. Anyhow, patch is good, thanks for picking it up! Signed-off-by: David Herrmann <dh.herrmann@xxxxxxxxx> Putting Benjamin on CC as he reviewed the patch last time and might have some more comments (or his final reviewed-by). Thanks! David > --- > > Sorry, I forgot to include this in the original patch set. > > Documentation/hid/hid-transport.txt | 324 ++++++++++++++++++++++++++++++++++++ > 1 file changed, 324 insertions(+) > create mode 100644 Documentation/hid/hid-transport.txt > > diff --git a/Documentation/hid/hid-transport.txt b/Documentation/hid/hid-transport.txt > new file mode 100644 > index 0000000..14b1c18 > --- /dev/null > +++ b/Documentation/hid/hid-transport.txt > @@ -0,0 +1,324 @@ > + HID I/O Transport Drivers > + =========================== > + > +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. > + > + +-----------+ +-----------+ +-----------+ +-----------+ > + | 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: > + I/O: USB, I2C, Bluetooth-l2cap > + Transport: USB-HID, I2C-HID, BT-HIDP > + > +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 > +with HID core: > + > + struct hid_device *hid; > + int ret; > + > + hid = hid_allocate_device(); > + if (IS_ERR(hid)) { > + ret = PTR_ERR(hid); > + goto err_<...>; > + } > + > + strlcpy(hid->name, <device-name-src>, 127); > + strlcpy(hid->phys, <device-phys-src>, 63); > + strlcpy(hid->uniq, <device-uniq-src>, 63); > + > + 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. > + > +To unregister a device, use: > + > + 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: > + - int (*start) (struct hid_device *hdev) > + 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. > + > + - void (*stop) (struct hid_device *hdev) > + 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. > + Transport drivers are free to ignore it and deinitialize devices after they > + destroyed them via hid_destroy_device(). > + > + - int (*open) (struct hid_device *hdev) > + 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. > + > + - void (*close) (struct hid_device *hdev) > + 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). > + 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. > + > + - int (*parse) (struct hid_device *hdev) > + 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(). > + > + - int (*power) (struct hid_device *hdev, int level) > + Called by HID core to give PM hints to transport drivers. Usually this is > + analogical to the ->open() and ->close() hints and redundant. > + > + - void (*request) (struct hid_device *hdev, struct hid_report *report, > + int reqtype) > + 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. > + 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. > + > + - int (*wait) (struct hid_device *hdev) > + 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. > + > + - int (*raw_request) (struct hid_device *hdev, unsigned char reportnum, > + __u8 *buf, size_t count, unsigned char rtype, > + int reqtype) > + 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 > + requests. > + > + - int (*output_report) (struct hid_device *hdev, __u8 *buf, size_t len) > + 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! > + > + - int (*hidinput_input_event) (struct input_dev *idev, unsigned int type, > + unsigned int code, int value) > + Obsolete callback used by logitech converters. It is called when userspace > + writes input events to the input device (eg., EV_LED). A driver can use this > + callback to convert it into an output report and send it to the device. If > + this callback is not provided, HID core will use ->request() or > + ->raw_request() respectively. > + > + - int (*idle) (struct hid_device *hdev, int report, int idle, int reqtype) > + 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. > + > +---------------------------------------------------- > +Written 2013, David Herrmann <dh.herrmann@xxxxxxxxx> > -- > 1.8.3.2 > -- To unsubscribe from this list: send the line "unsubscribe linux-input" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html