summaryrefslogtreecommitdiff
path: root/hw/usb
diff options
context:
space:
mode:
Diffstat (limited to 'hw/usb')
-rw-r--r--hw/usb/hid-logitech-hidpp20.c111
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) {