From 8d18fba282120a4a8e4416d1202522ffae8cad58 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sat, 15 Sep 2012 15:15:58 +0200 Subject: Input: Break out MT data Move all MT-related things to a separate place. This saves some bytes for non-mt input devices, and prepares for new MT features. Reviewed-and-tested-by: Benjamin Tissoires Tested-by: Ping Cheng Acked-by: Dmitry Torokhov Signed-off-by: Henrik Rydberg --- include/linux/input/mt.h | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'include/linux/input') diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h index f86737586e19..63458bced77d 100644 --- a/include/linux/input/mt.h +++ b/include/linux/input/mt.h @@ -23,6 +23,20 @@ struct input_mt_slot { int abs[ABS_MT_LAST - ABS_MT_FIRST + 1]; }; +/** + * struct input_mt - state of tracked contacts + * @trkid: stores MT tracking ID for the next contact + * @num_slots: number of MT slots the device uses + * @slot: MT slot currently being transmitted + * @slots: array of slots holding current values of tracked contacts + */ +struct input_mt { + int trkid; + int num_slots; + int slot; + struct input_mt_slot slots[]; +}; + static inline void input_mt_set_value(struct input_mt_slot *slot, unsigned code, int value) { @@ -38,9 +52,9 @@ static inline int input_mt_get_value(const struct input_mt_slot *slot, int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots); void input_mt_destroy_slots(struct input_dev *dev); -static inline int input_mt_new_trkid(struct input_dev *dev) +static inline int input_mt_new_trkid(struct input_mt *mt) { - return dev->trkid++ & TRKID_MAX; + return mt->trkid++ & TRKID_MAX; } static inline void input_mt_slot(struct input_dev *dev, int slot) -- cgit v1.2.3 From b4adbbefc2099476a4f1020041c99f52cf3cd67d Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sat, 11 Aug 2012 22:07:55 +0200 Subject: Input: MT - Add flags to input_mt_init_slots() Preparing to move more repeated code into the mt core, add a flags argument to the input_mt_slots_init() function. Reviewed-and-tested-by: Benjamin Tissoires Tested-by: Ping Cheng Acked-by: Dmitry Torokhov Signed-off-by: Henrik Rydberg --- include/linux/input/mt.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include/linux/input') diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h index 63458bced77d..53f5bf168ff9 100644 --- a/include/linux/input/mt.h +++ b/include/linux/input/mt.h @@ -28,12 +28,14 @@ struct input_mt_slot { * @trkid: stores MT tracking ID for the next contact * @num_slots: number of MT slots the device uses * @slot: MT slot currently being transmitted + * @flags: input_mt operation flags * @slots: array of slots holding current values of tracked contacts */ struct input_mt { int trkid; int num_slots; int slot; + unsigned int flags; struct input_mt_slot slots[]; }; @@ -49,7 +51,8 @@ static inline int input_mt_get_value(const struct input_mt_slot *slot, return slot->abs[code - ABS_MT_FIRST]; } -int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots); +int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots, + unsigned int flags); void input_mt_destroy_slots(struct input_dev *dev); static inline int input_mt_new_trkid(struct input_mt *mt) -- cgit v1.2.3 From 55e49089f4589908eb688742d2d7eff33b74ac78 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Wed, 22 Aug 2012 20:43:22 +0200 Subject: Input: MT - Handle frame synchronization in core Most MT drivers perform the same actions on frame synchronization. Some actions, like dropping unseen contacts, are also unnecessarily complex. Collect common frame synchronization tasks in a new function, input_mt_sync_frame(). Depending on the flags set, it drops unseen contacts and performs pointer emulation. With init flags and frame synchronization in place, most MT drivers can be simplified. First out are the bcm5974 and hid-multitouch drivers, following this patch. Reviewed-and-tested-by: Benjamin Tissoires Tested-by: Ping Cheng Acked-by: Dmitry Torokhov Signed-off-by: Henrik Rydberg --- include/linux/input/mt.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux/input') diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h index 53f5bf168ff9..94989189878d 100644 --- a/include/linux/input/mt.h +++ b/include/linux/input/mt.h @@ -15,12 +15,17 @@ #define TRKID_MAX 0xffff +#define INPUT_MT_POINTER 0x0001 /* pointer device, e.g. trackpad */ +#define INPUT_MT_DIRECT 0x0002 /* direct device, e.g. touchscreen */ +#define INPUT_MT_DROP_UNUSED 0x0004 /* drop contacts not seen in frame */ /** * struct input_mt_slot - represents the state of an input MT slot * @abs: holds current values of ABS_MT axes for this slot + * @frame: last frame at which input_mt_report_slot_state() was called */ struct input_mt_slot { int abs[ABS_MT_LAST - ABS_MT_FIRST + 1]; + unsigned int frame; }; /** @@ -29,6 +34,7 @@ struct input_mt_slot { * @num_slots: number of MT slots the device uses * @slot: MT slot currently being transmitted * @flags: input_mt operation flags + * @frame: increases every time input_mt_sync_frame() is called * @slots: array of slots holding current values of tracked contacts */ struct input_mt { @@ -36,6 +42,7 @@ struct input_mt { int num_slots; int slot; unsigned int flags; + unsigned int frame; struct input_mt_slot slots[]; }; @@ -81,4 +88,6 @@ void input_mt_report_slot_state(struct input_dev *dev, void input_mt_report_finger_count(struct input_dev *dev, int count); void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count); +void input_mt_sync_frame(struct input_dev *dev); + #endif -- cgit v1.2.3 From 7c1a87897c75139dec258eb03e1a24fb73385b73 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sun, 12 Aug 2012 20:47:05 +0200 Subject: Input: MT - Add in-kernel tracking With the INPUT_MT_TRACK flag set, the function input_mt_assign_slots() can be used to match a new set of contacts against the currently used slots. The algorithm used is based on Lagrange relaxation, and performs very well in practice; slower than mtdev for a few corner cases, but faster in most commonly occuring cases. Tested-by: Benjamin Tissoires Acked-by: Dmitry Torokhov Signed-off-by: Henrik Rydberg --- include/linux/input/mt.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'include/linux/input') diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h index 94989189878d..6b6f7c8e95bf 100644 --- a/include/linux/input/mt.h +++ b/include/linux/input/mt.h @@ -18,6 +18,8 @@ #define INPUT_MT_POINTER 0x0001 /* pointer device, e.g. trackpad */ #define INPUT_MT_DIRECT 0x0002 /* direct device, e.g. touchscreen */ #define INPUT_MT_DROP_UNUSED 0x0004 /* drop contacts not seen in frame */ +#define INPUT_MT_TRACK 0x0008 /* use in-kernel tracking */ + /** * struct input_mt_slot - represents the state of an input MT slot * @abs: holds current values of ABS_MT axes for this slot @@ -35,6 +37,7 @@ struct input_mt_slot { * @slot: MT slot currently being transmitted * @flags: input_mt operation flags * @frame: increases every time input_mt_sync_frame() is called + * @red: reduced cost matrix for in-kernel tracking * @slots: array of slots holding current values of tracked contacts */ struct input_mt { @@ -43,6 +46,7 @@ struct input_mt { int slot; unsigned int flags; unsigned int frame; + int *red; struct input_mt_slot slots[]; }; @@ -58,6 +62,11 @@ static inline int input_mt_get_value(const struct input_mt_slot *slot, return slot->abs[code - ABS_MT_FIRST]; } +static inline bool input_mt_is_active(const struct input_mt_slot *slot) +{ + return input_mt_get_value(slot, ABS_MT_TRACKING_ID) >= 0; +} + int input_mt_init_slots(struct input_dev *dev, unsigned int num_slots, unsigned int flags); void input_mt_destroy_slots(struct input_dev *dev); @@ -90,4 +99,16 @@ void input_mt_report_pointer_emulation(struct input_dev *dev, bool use_count); void input_mt_sync_frame(struct input_dev *dev); +/** + * struct input_mt_pos - contact position + * @x: horizontal coordinate + * @y: vertical coordinate + */ +struct input_mt_pos { + s16 x, y; +}; + +int input_mt_assign_slots(struct input_dev *dev, int *slots, + const struct input_mt_pos *pos, int num_pos); + #endif -- cgit v1.2.3 From 17a465a7f2d6ce31738a3a76591afeab165f185a Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sat, 1 Sep 2012 09:27:20 +0200 Subject: Input: MT - Get slot by key Some devices use an internal key for tracking which cannot be directly mapped to slots. This patch provides a key-to-slot mapping, which can be used by drivers of such devices. Reviewed-and-tested-by: Benjamin Tissoires Acked-by: Dmitry Torokhov Signed-off-by: Henrik Rydberg --- include/linux/input/mt.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux/input') diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h index 6b6f7c8e95bf..cc5cca774bab 100644 --- a/include/linux/input/mt.h +++ b/include/linux/input/mt.h @@ -24,10 +24,12 @@ * struct input_mt_slot - represents the state of an input MT slot * @abs: holds current values of ABS_MT axes for this slot * @frame: last frame at which input_mt_report_slot_state() was called + * @key: optional driver designation of this slot */ struct input_mt_slot { int abs[ABS_MT_LAST - ABS_MT_FIRST + 1]; unsigned int frame; + unsigned int key; }; /** @@ -111,4 +113,6 @@ struct input_mt_pos { int input_mt_assign_slots(struct input_dev *dev, int *slots, const struct input_mt_pos *pos, int num_pos); +int input_mt_get_slot_by_key(struct input_dev *dev, int key); + #endif -- cgit v1.2.3