diff options
author | Peter Wu <peter@lekensteyn.nl> | 2014-03-20 01:07:06 +0100 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2014-03-20 01:07:06 +0100 |
commit | dde2211bc51d61e52065788bf521e53f04259f51 (patch) | |
tree | 414f765bd9699a774ed54dba583fed49b72a75c7 /hw/usb | |
parent | 8bb0682113c25787be27334e495aa4be42c2e796 (diff) | |
download | qemu-dde2211bc51d61e52065788bf521e53f04259f51.tar.gz |
unifying: start implementing HID++ 2.0 for devices
New Hidpp20Msg type helps reading the HID++ 2.0 function format.
Implemented error responses (undocumented), and IRoot.GetProtocol().
Signed-off-by: Peter Wu <peter@lekensteyn.nl>
Diffstat (limited to 'hw/usb')
-rw-r--r-- | hw/usb/hid-logitech-dj.c | 44 | ||||
-rw-r--r-- | hw/usb/hid-logitech-dj.h | 31 |
2 files changed, 67 insertions, 8 deletions
diff --git a/hw/usb/hid-logitech-dj.c b/hw/usb/hid-logitech-dj.c index a035bc533d..caa0383bc9 100644 --- a/hw/usb/hid-logitech-dj.c +++ b/hw/usb/hid-logitech-dj.c @@ -379,14 +379,56 @@ static void hidpp_process_device_hidpp10(USBLtunifyState *s, HidppMsg *msg) } } + +/* HID++ 2.0 */ +static void hidpp20_queue_error(USBLtunifyState *s, Hidpp20Msg *func, uint8_t err) +{ + Hidpp20Msg error_report = { + .report_id = func->report_id, + .device_index = func->device_index, + .feat_index = 0xFF, + .func = func->func, + .params = { err } + }; + + hidpp_queue_output_report(s, (HidppMsg *) &error_report); +} + +/* called for HID++ 2.0 reports targeted at devices */ +static void hidpp_process_device_hidpp20(USBLtunifyState *s, HidppMsg *msg) +{ + LHidDevice *hd = &s->devices[msg->device_index - 1]; + Hidpp20Msg *func = (Hidpp20Msg *) msg; + uint8_t fn = func->func >> 4; + + if (func->feat_index == 0) { /* IRoot */ + if (fn == 1) { /* GetProtocolVersion */ + func->params_s[0] = (uint8_t) (hd->info.protocol_version >> 8); + func->params_s[1] = (uint8_t) hd->info.protocol_version; + hidpp_queue_output_report(s, msg); + } else { + hidpp20_queue_error(s, func, HIDPP20_ERR_CODE_INVALID_FUNCTION_ID); + } + return; + } + /* TODO: implement features and more functions */ +} + + static void hidpp_process_input_report(USBLtunifyState *s, HidppMsg msg) { /* receiver reports are processed earlier, elsewhere */ assert(msg.device_index != 0xFF); if (hidpp_device_available(s, msg.device_index)) { + LHidDevice *hd = &s->devices[msg.device_index - 1]; + if (msg.report_id == HIDPP_SHORT || msg.report_id == HIDPP_LONG) { - hidpp_process_device_hidpp10(s, &msg); + if (hd->info.protocol_version >= 0x0200) { + hidpp_process_device_hidpp20(s, &msg); + } else { + hidpp_process_device_hidpp10(s, &msg); + } } } else { hidpp_queue_error(s, &msg, HIDPP_ERR_RESOURCE_ERROR); diff --git a/hw/usb/hid-logitech-dj.h b/hw/usb/hid-logitech-dj.h index 04a31c95a3..6a2ca18413 100644 --- a/hw/usb/hid-logitech-dj.h +++ b/hw/usb/hid-logitech-dj.h @@ -73,6 +73,18 @@ typedef struct { typedef struct { uint8_t report_id; + const uint8_t device_index; + const uint8_t feat_index; + const uint8_t func; /* function/ASE ID | sw ID */ + union { + uint8_t params[16]; + uint8_t params_s[3]; + }; +} Hidpp20Msg; + + +typedef struct { + uint8_t report_id; uint8_t device_index; uint8_t report_type; uint8_t payload[12]; @@ -99,11 +111,7 @@ typedef struct { }; } HidppMsg; -/* information to generate an error output report */ -typedef struct { - uint8_t device_index; - uint8_t sub_id; - uint8_t address; +/* HID++ 1.0 error codes */ #define HIDPP_ERR_SUCCESS 0x00 #define HIDPP_ERR_INVALID_SUBID 0x01 #define HIDPP_ERR_INVALID_ADDRESS 0x02 @@ -117,8 +125,17 @@ typedef struct { #define HIDPP_ERR_REQUEST_UNAVAILABLE 0x0A #define HIDPP_ERR_INVALID_PARAM_VALUE 0x0B #define HIDPP_ERR_WRONG_PIN_CODE 0x0C - uint8_t error; -} HidppError; +/* HID++ 2.0 error codes */ +#define HIDPP20_ERR_CODE_NOERROR 0x00 +#define HIDPP20_ERR_CODE_UNKNOWN 0x01 +#define HIDPP20_ERR_CODE_INVALIDARGUMENT 0x02 +#define HIDPP20_ERR_CODE_OUTOFRANGE 0x03 +#define HIDPP20_ERR_CODE_HWERROR 0x04 +#define HIDPP20_ERR_CODE_LOGITECH_INTERNAL 0x05 +#define HIDPP20_ERR_CODE_INVALID_FEATURE_INDEX 0x06 +#define HIDPP20_ERR_CODE_INVALID_FUNCTION_ID 0x07 +#define HIDPP20_ERR_CODE_BUSY 0x08 +#define HIDPP20_ERR_CODE_UNSUPPORTED 0x09 /* device and receiver info */ |