summaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2014-04-01 19:13:44 +0200
committerPeter Wu <peter@lekensteyn.nl>2014-04-01 19:13:44 +0200
commite23b0ffa3af705c7d9c3cc5f8559892c7392b5d1 (patch)
tree1624bf7d2e6faa56c1dc94dbfcaed42c4b46e63d /hw
parentc1ba3a7d4ac7273891b974770196608ddf2c5d43 (diff)
downloadqemu-e23b0ffa3af705c7d9c3cc5f8559892c7392b5d1.tar.gz
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 <peter@lekensteyn.nl>
Diffstat (limited to 'hw')
-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) {