summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/usb/hid-logitech-dj.c12
-rw-r--r--hw/usb/hid-logitech-hidpp20.c36
2 files changed, 34 insertions, 14 deletions
diff --git a/hw/usb/hid-logitech-dj.c b/hw/usb/hid-logitech-dj.c
index 6de5fa4ba1..51be0e2410 100644
--- a/hw/usb/hid-logitech-dj.c
+++ b/hw/usb/hid-logitech-dj.c
@@ -399,20 +399,8 @@ 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;
int r;
- 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;
- }
-
r = hidpp20_feature_call(hd, func);
/* note: if r == 0, then the function is void and there is no output */
if (r > 0) {
diff --git a/hw/usb/hid-logitech-hidpp20.c b/hw/usb/hid-logitech-hidpp20.c
index be1e02df53..95393050a5 100644
--- a/hw/usb/hid-logitech-hidpp20.c
+++ b/hw/usb/hid-logitech-hidpp20.c
@@ -48,6 +48,34 @@ struct HidppFeature {
#define HIDPP20_FEATURE(name) \
int name(LHidDevice *hd, Hidpp20Msg *msg, uint8_t fn, uint8_t *params)
+static HIDPP20_FEATURE(feat_iroot)
+{
+ uint16_t feature_id;
+ unsigned i;
+ const HidppFeature *feat;
+
+ switch (fn) {
+ case 0: /* featureIndex, featureType = GetFeature(featureID) */
+ feature_id = (params[0] << 8) | params[1];
+ params[0] = params[1] = 0;
+ for (i = 0; i < hd->info.features_count; i++) {
+ feat = &hd->info.features[i];
+ if (feat->id == feature_id) {
+ params[0] = i + 1;
+ params[1] = feat->type;
+ }
+ }
+ return 2;
+ case 1: /* ping = GetFeature(pingData) or version = GetProtocolVersion() */
+ params[0] = hd->info.protocol_version >> 8;
+ params[1] = (uint8_t) hd->info.protocol_version;
+ // params[2] is not changed, that's the pingData
+ return 3;
+ default:
+ return -HIDPP20_ERR_CODE_INVALID_FUNCTION_ID;
+ }
+}
+
static HIDPP20_FEATURE(feat_featureset)
{
const HidppFeature *feat;
@@ -96,8 +124,12 @@ int hidpp20_feature_call(LHidDevice *hd, Hidpp20Msg *func)
assert(hd->info.features != NULL);
- feat = &hd->info.features[func->feat_index - 1];
- r = feat->callback(hd, func, fn, func->params);
+ if (func->feat_index == 0) { /* IRoot (dual HID++ 1.0 and HID++ 2.0) */
+ r = feat_iroot(hd, func, fn, func->params);
+ } else { /* other features */
+ feat = &hd->info.features[func->feat_index - 1];
+ r = feat->callback(hd, func, fn, func->params);
+ }
if (r > 0) {
// r are the parameters that must be kept, the others are cleared.
assert(r <= sizeof(func->params));