diff options
Diffstat (limited to 'hw/usb')
-rw-r--r-- | hw/usb/hid-logitech-hidpp20.c | 111 |
1 files 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) { |