From e23b0ffa3af705c7d9c3cc5f8559892c7392b5d1 Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Tue, 1 Apr 2014 19:13:44 +0200 Subject: unifying: enable more features, implement some This makes the feature indices consistent with real hardware which makes it easier to compare/test against real hw. Some features are (partially) implemented per spec (0x6110 TouchMouseRawPoints; 0x2200 MousePointer). Others are guessed based on results from hw (0x2100 VerticalScrolling, 0x2120 HiresScrolling). The spec for 0x6100 TouchpadRawXY is available, but not implemented yet. It is assumed that the reprogrammable v1 and v2 features are similar to the reprogramcontrols feature (which seems to hold so far). Signed-off-by: Peter Wu --- hw/usb/hid-logitech-hidpp20.c | 111 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 98 insertions(+), 13 deletions(-) diff --git a/hw/usb/hid-logitech-hidpp20.c b/hw/usb/hid-logitech-hidpp20.c index ba9807079e..9795830628 100644 --- a/hw/usb/hid-logitech-hidpp20.c +++ b/hw/usb/hid-logitech-hidpp20.c @@ -274,6 +274,91 @@ static HIDPP20_FEATURE(feat_reprogcontrols) } } +#define feat_reprogcontrolsv2 feat_reprogcontrols +#define feat_reprogcontrolsv3 feat_reprogcontrols + +static HIDPP20_FEATURE(feat_verticalscrolling) +{ + switch (fn) { + case 0: + /* undocumented */ + params[0] = 0x05; + params[1] = 0x12; + return 2; + default: + return -HIDPP20_ERR_CODE_INVALID_FUNCTION_ID; + } +} + +static HIDPP20_FEATURE(feat_hiresscrolling) +{ + switch (fn) { + case 0: /* ?? get info() */ + params[0] = 0; /* either 0 and 1 for enabled/disabled? */ + params[1] = 0x08; /* some flags? */ + return 2; + case 1: /* ?? enableHires(bool) */ + if (params[0] > 2) { + return -HIDPP20_ERR_CODE_INVALIDARGUMENT; + } + /* retval same as get info(). Saving state not implemented */ + params[1] = 0x08; + return 2; + default: + return -HIDPP20_ERR_CODE_INVALID_FUNCTION_ID; + } +} + +static HIDPP20_FEATURE(feat_mousepointer) +{ + uint16_t sensor_dpi = 1000; + + switch (fn) { + case 0: /* sensorResolutionDPI, flags = GetMousePointerInfo() */ + params[0] = sensor_dpi >> 8; + params[1] = (uint8_t) sensor_dpi; + /* flags[1:0]: ptr accel (0 none, low, med, 3 high) */ + params[2] = 1; + return 3; + default: + return -HIDPP20_ERR_CODE_INVALID_FUNCTION_ID; + } +} + +static HIDPP20_FEATURE(feat_touchpadrawxy) +{ + return -HIDPP20_ERR_CODE_UNSUPPORTED; /* TODO STUB */ + switch (fn) { + default: + return -HIDPP20_ERR_CODE_INVALID_FUNCTION_ID; + } +} + +static HIDPP20_FEATURE(feat_touchmouserawpoints) +{ + switch (fn) { + case 0: /* GetTouchpadInfo() */ + /* NOTE: hard-coded for T400 */ + params[0] = 0x01; params[1] = 0xF7; /* X max count (dots) */ + params[2] = 0x05; params[3] = 0xE0; /* Y max count (dots) */ + params[4] = 0x04; params[5] = 0x06; /* resolution (same for X and Y) */ + params[6] = 0x01; /* origin position */ + params[7] = 0x01; /* max fingers */ + params[8] = 0x0F; /* width/height range */ + return 9; + case 1: /* mode = GetRawMode() */ + /* 0: native gestures; 1: raw filtered data; 2: raw unfiltered + native + * gestures; 3: extra raw unfiltered; 4: as 2, but with Z instead of W */ + params[0] = 0; + return 1; + case 2: /* SetRawMode(mode) */ + /* not implemented */ + return 0; + default: + return -HIDPP20_ERR_CODE_INVALID_FUNCTION_ID; + } +} + /* root feature not included! */ static const HidppFeature features_m525[] = { { 0x0001, 0, feat_featureset }, @@ -285,9 +370,9 @@ static const HidppFeature features_m525[] = { { 0x1B00, 0, feat_reprogcontrols }, { 0x1DF0, HIDPP20_FEAT_TYPE_HIDDEN, feat_unknown }, { 0x1F03, HIDPP20_FEAT_TYPE_HIDDEN, feat_unknown }, -// { 0x2100, 0, feat_verticalscrolling }, -// { 0x2120, 0, feat_hiresscrolling }, -// { 0x2200, 0, feat_mousepointer }, + { 0x2100, 0, feat_verticalscrolling }, + { 0x2120, 0, feat_hiresscrolling }, + { 0x2200, 0, feat_mousepointer }, }; static const HidppFeature features_t650[] = { @@ -300,15 +385,15 @@ static const HidppFeature features_t650[] = { { 0x1DF3, HIDPP20_FEAT_TYPE_HIDDEN | HIDPP20_FEAT_TYPE_INTERNAL, feat_unknown }, { 0x1B00, 0, feat_reprogcontrols }, { 0x1F03, HIDPP20_FEAT_TYPE_HIDDEN | HIDPP20_FEAT_TYPE_INTERNAL, feat_unknown }, -// { 0x2100, 0, feat_verticalscrolling }, -// { 0x2120, 0, feat_hiresscrolling }, -// { 0x2200, 0, feat_mousepointer }, + { 0x2100, 0, feat_verticalscrolling }, + { 0x2120, 0, feat_hiresscrolling }, + { 0x2200, 0, feat_mousepointer }, { 0x00C0, 0, feat_dfucontrol }, { 0x1E80, HIDPP20_FEAT_TYPE_HIDDEN | HIDPP20_FEAT_TYPE_INTERNAL, feat_unknown }, -// { 0x6100, 0, feat_touchpadrawxy }, + { 0x6100, 0, feat_touchpadrawxy }, { 0x1860, HIDPP20_FEAT_TYPE_HIDDEN | HIDPP20_FEAT_TYPE_INTERNAL, feat_unknown }, { 0x1E00, HIDPP20_FEAT_TYPE_HIDDEN, feat_unknown }, -// { 0x1B01, 0, feat_reprogcontrolsv2 }, + { 0x1B01, 0, feat_reprogcontrolsv2 }, { 0x1890, HIDPP20_FEAT_TYPE_HIDDEN | HIDPP20_FEAT_TYPE_INTERNAL, feat_unknown }, { 0x18E5, HIDPP20_FEAT_TYPE_HIDDEN | HIDPP20_FEAT_TYPE_INTERNAL, feat_unknown }, { 0x18A0, HIDPP20_FEAT_TYPE_HIDDEN | HIDPP20_FEAT_TYPE_INTERNAL, feat_unknown }, @@ -337,12 +422,12 @@ static const HidppFeature features_t400[] = { { 0x1E80, HIDPP20_FEAT_TYPE_HIDDEN | HIDPP20_FEAT_TYPE_INTERNAL, feat_unknown }, { 0x1F03, HIDPP20_FEAT_TYPE_HIDDEN | HIDPP20_FEAT_TYPE_INTERNAL, feat_unknown }, { 0x1F04, HIDPP20_FEAT_TYPE_HIDDEN | HIDPP20_FEAT_TYPE_INTERNAL, feat_unknown }, -// { 0x2100, 0, feat_verticalscrolling }, + { 0x2100, 0, feat_verticalscrolling }, { 0x2101, HIDPP20_FEAT_TYPE_HIDDEN, feat_unknown }, -// { 0x2120, 0, feat_hiresscrolling }, -// { 0x2200, 0, feat_mousepointer }, -// { 0x6110, HIDPP20_FEAT_TYPE_HIDDEN, feat_touchmouserawpoints }, -// { 0x1B03, 0, feat_reprogcontrolsv3 }, + { 0x2120, 0, feat_hiresscrolling }, + { 0x2200, 0, feat_mousepointer }, + { 0x6110, HIDPP20_FEAT_TYPE_HIDDEN, feat_touchmouserawpoints }, + { 0x1B03, 0, feat_reprogcontrolsv3 }, }; void hidpp20_init_features(LHidDevice *hd) { -- cgit v1.2.1