/* * Even if the kernel is built without support for Focaltech PS/2 touchpads (or * when the real driver fails to recognize the device), we still have to detect * them in order to avoid further detection attempts confusing the touchpad. * This way it at least works in PS/2 mouse compatibility mode.
*/ int focaltech_detect(struct psmouse *psmouse, bool set_properties)
{ if (!psmouse_matches_pnp_id(psmouse, focaltech_pnp_ids)) return -ENODEV;
if (set_properties) {
psmouse->vendor = "FocalTech";
psmouse->name = "Touchpad";
}
return 0;
}
#ifdef CONFIG_MOUSE_PS2_FOCALTECH
/* * Packet types - the numbers are not consecutive, so we might be missing * something here.
*/ #define FOC_TOUCH 0x3 /* bitmap of active fingers */ #define FOC_ABS 0x6 /* absolute position of one finger */ #define FOC_REL 0x9 /* relative position of 1-2 fingers */
#define FOC_MAX_FINGERS 5
/* * Current state of a single finger on the touchpad.
*/ struct focaltech_finger_state { /* The touchpad has generated a touch event for the finger */ bool active;
/* * The touchpad has sent position data for the finger. The * flag is 0 when the finger is not active, and there is a * time between the first touch event for the finger and the * following absolute position packet for the finger where the * touchpad has declared the finger to be valid, but we do not * have any valid position yet.
*/ bool valid;
/* * Absolute position (from the bottom left corner) of the * finger.
*/ unsignedint x; unsignedint y;
};
/* * Description of the current state of the touchpad hardware.
*/ struct focaltech_hw_state { /* * The touchpad tracks the positions of the fingers for us, * the array indices correspond to the finger indices returned * in the report packages.
*/ struct focaltech_finger_state fingers[FOC_MAX_FINGERS];
/* * Finger width 0-7 and 15 for a very big contact area. * 15 value stays until the finger is released. * Width is reported only in absolute packets. * Since hardware reports width only for last touching finger, * there is no need to store width for every specific finger, * so we keep only last value reported.
*/ unsignedint width;
/* True if the clickpad has been pressed. */ bool pressed;
};
/* the second byte contains a bitmap of all fingers touching the pad */ for (i = 0; i < FOC_MAX_FINGERS; i++) {
state->fingers[i].active = fingers & 0x1; if (!state->fingers[i].active) { /* * Even when the finger becomes active again, we still * will have to wait for the first valid position.
*/
state->fingers[i].valid = false;
}
fingers >>= 1;
}
}
/* * If there is an odd number of fingers, the last relative * packet only contains one finger. In this case, the second * finger index in the packet is 0 (we subtract 1 in the lines * above to create array indices, so the finger will overflow * and be above FOC_MAX_FINGERS).
*/
finger2 = ((packet[3] >> 4) & 0x7) - 1; if (finger2 < FOC_MAX_FINGERS) {
state->fingers[finger2].x += (s8)packet[4];
state->fingers[finger2].y += (s8)packet[5];
}
}
/* * Undo part of setup done for us by psmouse core since touchpad * is not a relative device.
*/
__clear_bit(EV_REL, dev->evbit);
__clear_bit(REL_X, dev->relbit);
__clear_bit(REL_Y, dev->relbit);
__clear_bit(BTN_RIGHT, dev->keybit);
__clear_bit(BTN_MIDDLE, dev->keybit);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.