From a4a17543cee0f422b6348020d170d887f05e97fc Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Mon, 24 Mar 2014 00:00:05 +0100 Subject: unifying: implement IRoot completely Do not treat IRoot special in hidpp_process_device_hidpp20, but implement it as a generic feature using hidpp20_feature_call. This makes it easier to re-use the error reporting stuff. Signed-off-by: Peter Wu --- hw/usb/hid-logitech-hidpp20.c | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'hw/usb/hid-logitech-hidpp20.c') 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)); -- cgit v1.2.1