summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2014-03-20 00:14:04 +0100
committerPeter Wu <peter@lekensteyn.nl>2014-03-20 00:14:04 +0100
commit8bb0682113c25787be27334e495aa4be42c2e796 (patch)
treeca1db177e381ba7cc3ae5101413966c17bbfb14c
parent28702c7fa5e93e5597e08014edc95b13df414936 (diff)
downloadqemu-8bb0682113c25787be27334e495aa4be42c2e796.tar.gz
unifying: version reg F1 for receiver and HID++ 1.0 devs
Signed-off-by: Peter Wu <peter@lekensteyn.nl>
-rw-r--r--hw/usb/hid-logitech-dj.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/hw/usb/hid-logitech-dj.c b/hw/usb/hid-logitech-dj.c
index dc3d9c171d..a035bc533d 100644
--- a/hw/usb/hid-logitech-dj.c
+++ b/hw/usb/hid-logitech-dj.c
@@ -124,6 +124,39 @@ static void hidpp_notif_device_connection(USBLtunifyState *s, uint8_t device_ind
hidpp_queue_output_report(s, (HidppMsg *) &msg);
}
+/* undocumented, guessed version information */
+static void hidpp_process_version_request(USBLtunifyState *s, HidppMsgShort *msg,
+ struct firmware_version *version)
+{
+ assert(msg->report_id == HIDPP_SHORT);
+ // device_index is either device or receiver
+ assert(msg->sub_id == 0x81);
+ assert(msg->address == 0xF1);
+
+ switch (msg->value[0]) {
+ case 1: /* firmware version */
+ msg->value[1] = version->fw_major;
+ msg->value[2] = version->fw_minor;
+ break;
+ case 2: /* firmware build */
+ msg->value[1] = (uint8_t) (version->fw_build >> 8);
+ msg->value[2] = (uint8_t) version->fw_build;
+ break;
+ case 4: /* bootloader version */
+ msg->value[1] = version->bl_major;
+ msg->value[2] = version->bl_minor;
+ break;
+ case 5: /* returned by receiver ?? */
+ msg->value[1] = 44;
+ msg->value[2] = 11;
+ break;
+ default:
+ hidpp_queue_error(s, (HidppMsg *) msg, HIDPP_ERR_INVALID_VALUE);
+ return;
+ }
+ hidpp_queue_output_report(s, (HidppMsg *) msg);
+}
+
static void hidpp_process_receiver_report(USBLtunifyState *s, HidppMsg *msg)
{
LHidDevice *hd;
@@ -284,6 +317,9 @@ static void hidpp_process_receiver_report(USBLtunifyState *s, HidppMsg *msg)
hidpp_queue_error(s, msg, HIDPP_ERR_INVALID_VALUE);
}
break;
+ case GET_REG(0xF1):
+ hidpp_process_version_request(s, ms, &rcvr->info.version);
+ break;
default:
/* unknown request, return error */
switch (req & ~0xFF) {
@@ -323,6 +359,9 @@ static void hidpp_process_device_hidpp10(USBLtunifyState *s, HidppMsg *msg)
memset(parms, 0, 3);
hidpp_queue_output_report(s, msg);
break;
+ case GET_REG(0xF1):
+ hidpp_process_version_request(s, &msg->hidpp_s, &hd->info.version);
+ break;
default:
/* unknown request, return error */
switch (req & ~0xFF) {
@@ -562,6 +601,7 @@ void hidpp_init(USBLtunifyState *s)
{
LHidReceiver *r = &s->receiver;
r->info.serial = 0x4c4f5354;
+ r->info.version = (struct firmware_version) { 24, 0, 18, 0, 6 };
hidpp_init_device(s, 1, DEVTYPE_KEYBOARD);
hidpp_init_device(s, 2, DEVTYPE_MOUSE);