summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJigarkumar Kishorkumar Zala <j_zala@codeaurora.org>2015-10-27 14:32:04 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:21:20 -0700
commitd00e0ab13b8e900fb620244e3ec0e604b27f97eb (patch)
tree6ac684e82ace323166650549b394e7292b5c9db4
parent6c472a2921b6e10b163190dd3d031f223facf3a8 (diff)
input: maxim_sti: add support for multitouch protocol B
Add support for multitouch procotol B, in order to track object based ID touch activities. Change-Id: I9b6941b3fea2f5c28434793073330cd4abe9fa74 Signed-off-by: Jigarkumar Kishorkumar Zala <j_zala@codeaurora.org>
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/maxim-sti.txt3
-rw-r--r--drivers/input/touchscreen/maxim_sti.c101
2 files changed, 87 insertions, 17 deletions
diff --git a/Documentation/devicetree/bindings/input/touchscreen/maxim-sti.txt b/Documentation/devicetree/bindings/input/touchscreen/maxim-sti.txt
index 86049e6b2094..c0f29f20b5da 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/maxim-sti.txt
+++ b/Documentation/devicetree/bindings/input/touchscreen/maxim-sti.txt
@@ -19,7 +19,7 @@ Optional properties:
config defined in pin groups of interrupt and reset gpios.
"pmx_ts_suspend" : disabled configuration of pins. This should specify sleep
config defined in pin groups of interrupt and reset gpios.
-
+ - maxim_sti,mt_type_b_enabled : Boolean type. This should be used to enable type B multitouch protocol.
Example:
&spi_13 { /* BLSP1 QUP3 */
@@ -38,6 +38,7 @@ Example:
maxim_sti,touch_fusion = "/vendor/bin/touch_fusion";
maxim_sti,config_file = "/vendor/firmware/touch_fusion_panel_id_0x%04x.cfg";
maxim_sti,fw_name = "maxim_fp35.bin";
+ maxim_sti,mt_type_b_enabled;
pinctrl-names = "pmx_ts_active","pmx_ts_suspend","pmx_ts_release";
pinctrl-0 = <&ts_int_active &ts_reset_active>;
pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
diff --git a/drivers/input/touchscreen/maxim_sti.c b/drivers/input/touchscreen/maxim_sti.c
index 4fa72e34c3f0..d10f26357611 100644
--- a/drivers/input/touchscreen/maxim_sti.c
+++ b/drivers/input/touchscreen/maxim_sti.c
@@ -30,6 +30,7 @@
#include <net/genetlink.h>
#include <net/sock.h>
#include <uapi/linux/maxim_sti.h>
+#include <linux/input/mt.h>
#include <asm/byteorder.h> /* MUST include this header to get byte order */
#ifdef CONFIG_OF
#include <linux/gpio.h>
@@ -76,6 +77,7 @@ struct maxim_sti_pdata {
int (*init)(struct maxim_sti_pdata *pdata, bool init);
void (*reset)(struct maxim_sti_pdata *pdata, int value);
int (*irq)(struct maxim_sti_pdata *pdata);
+ bool mt_type_b_enabled;
};
struct dev_data;
@@ -135,6 +137,8 @@ struct dev_data {
u32 tf_status;
bool idle;
bool gesture_reset;
+ bool touch_status[INPUT_DEVICES]
+ [MAX_INPUT_EVENTS];
u16 gesture_en;
unsigned long int sysfs_update_type;
struct completion sysfs_ack_glove;
@@ -980,6 +984,9 @@ static int maxim_parse_dt(struct device *dev, struct maxim_sti_pdata *pdata)
pdata->gpio_irq = of_get_named_gpio_flags(np,
"maxim_sti,irq-gpio", 0, &flags);
+ pdata->mt_type_b_enabled =
+ of_property_read_bool(np, "maxim_sti,mt_type_b_enabled");
+
ret = of_property_read_string(np, "maxim_sti,touch_fusion", &str);
if (ret) {
dev_err(dev, "%s: unable to read touch_fusion location (%d)\n",
@@ -1108,6 +1115,22 @@ nl_callback_noop(struct sk_buff *skb, struct genl_info *info)
return 0;
}
+static void
+release_slot_events(struct dev_data *dd, bool *active_touch, int inp)
+{
+ int i;
+
+ for (i = 0; i < MAX_INPUT_EVENTS; i++) {
+ if (dd->touch_status[inp][i] == true &&
+ active_touch[i] == false) {
+ input_mt_slot(dd->input_dev[inp], i);
+ input_mt_report_slot_state(dd->input_dev[inp],
+ MT_TOOL_FINGER, 0);
+ }
+ dd->touch_status[inp][i] = active_touch[i];
+ }
+}
+
static inline bool
nl_process_driver_msg(struct dev_data *dd, u16 msg_id, void *msg)
{
@@ -1131,9 +1154,10 @@ nl_process_driver_msg(struct dev_data *dd, u16 msg_id, void *msg)
struct dr_sysfs_ack *sysfs_ack_msg;
struct dr_idle *idle_msg;
struct dr_tf_status *tf_status_msg;
- u8 i, inp;
- int ret;
+ u8 i, inp;
+ int ret, id;
u16 read_value[2] = { 0 };
+ bool active_touch[INPUT_DEVICES][MAX_INPUT_EVENTS] = { {false} };
if (dd->expect_resume_ack && msg_id != DR_DECONFIG &&
msg_id != DR_RESUME_ACK)
@@ -1294,6 +1318,19 @@ nl_process_driver_msg(struct dev_data *dd, u16 msg_id, void *msg)
__set_bit(KEY_POWER,
dd->input_dev[i]->keybit);
}
+ if (pdata->mt_type_b_enabled &&
+ input_mt_init_slots(dd->input_dev[i],
+ MAX_INPUT_EVENTS, 0)) {
+ ERROR("Error in initialising slots\n");
+ input_free_device(dd->input_dev[i]);
+ dd->input_dev[i] = NULL;
+ continue;
+ } else {
+ input_set_abs_params(dd->input_dev[i],
+ ABS_MT_TRACKING_ID, 0,
+ MAX_INPUT_EVENTS, 0, 0);
+ }
+
input_set_abs_params(dd->input_dev[i],
ABS_MT_POSITION_X, 0,
config_input_msg->x_range, 0, 0);
@@ -1302,9 +1339,7 @@ nl_process_driver_msg(struct dev_data *dd, u16 msg_id, void *msg)
config_input_msg->y_range, 0, 0);
input_set_abs_params(dd->input_dev[i],
ABS_MT_PRESSURE, 0, 0xFF, 0, 0);
- input_set_abs_params(dd->input_dev[i],
- ABS_MT_TRACKING_ID, 0,
- MAX_INPUT_EVENTS, 0, 0);
+
if (i == (INPUT_DEVICES - 1))
input_set_abs_params(dd->input_dev[i],
ABS_MT_TOOL_TYPE, 0,
@@ -1387,7 +1422,12 @@ nl_process_driver_msg(struct dev_data *dd, u16 msg_id, void *msg)
dd->eraser_active = false;
}
for (i = 0; i < INPUT_DEVICES; i++) {
- input_mt_sync(dd->input_dev[i]);
+ if (pdata->mt_type_b_enabled)
+ release_slot_events(dd,
+ active_touch[i], i);
+ else
+ input_mt_sync(dd->input_dev[i]);
+
input_sync(dd->input_dev[i]);
}
} else {
@@ -1395,15 +1435,36 @@ nl_process_driver_msg(struct dev_data *dd, u16 msg_id, void *msg)
switch (input_msg->event[i].tool_type) {
case DR_INPUT_FINGER:
inp = 0;
- input_report_abs(dd->input_dev[inp],
- ABS_MT_TOOL_TYPE,
- MT_TOOL_FINGER);
+ id = input_msg->event[i].id;
+ if (pdata->mt_type_b_enabled) {
+ input_mt_slot(
+ dd->input_dev[inp], id);
+ input_mt_report_slot_state(
+ dd->input_dev[inp],
+ MT_TOOL_FINGER, 1);
+ active_touch[inp][id] = true;
+ } else {
+ input_report_abs(
+ dd->input_dev[inp],
+ ABS_MT_TOOL_TYPE,
+ MT_TOOL_FINGER);
+ }
break;
case DR_INPUT_STYLUS:
inp = INPUT_DEVICES - 1;
- input_report_abs(dd->input_dev[inp],
- ABS_MT_TOOL_TYPE,
- MT_TOOL_PEN);
+ if (pdata->mt_type_b_enabled) {
+ input_mt_slot(
+ dd->input_dev[inp], id);
+ input_mt_report_slot_state(
+ dd->input_dev[inp],
+ MT_TOOL_PEN, 1);
+ active_touch[inp][id] = true;
+ } else {
+ input_report_abs(
+ dd->input_dev[inp],
+ ABS_MT_TOOL_TYPE,
+ MT_TOOL_PEN);
+ }
break;
case DR_INPUT_ERASER:
inp = INPUT_DEVICES - 1;
@@ -1417,9 +1478,9 @@ nl_process_driver_msg(struct dev_data *dd, u16 msg_id, void *msg)
input_msg->event[i].tool_type);
break;
}
- input_report_abs(dd->input_dev[inp],
- ABS_MT_TRACKING_ID,
- input_msg->event[i].id);
+ if (!pdata->mt_type_b_enabled)
+ input_report_abs(dd->input_dev[inp],
+ ABS_MT_TRACKING_ID, id);
input_report_abs(dd->input_dev[inp],
ABS_MT_POSITION_X,
input_msg->event[i].x);
@@ -1429,8 +1490,16 @@ nl_process_driver_msg(struct dev_data *dd, u16 msg_id, void *msg)
input_report_abs(dd->input_dev[inp],
ABS_MT_PRESSURE,
input_msg->event[i].z);
- input_mt_sync(dd->input_dev[inp]);
+ if (!pdata->mt_type_b_enabled)
+ input_mt_sync(dd->input_dev[inp]);
}
+
+ if (pdata->mt_type_b_enabled) {
+ for (i = 0; i < INPUT_DEVICES; i++)
+ release_slot_events(dd,
+ active_touch[i], i);
+ }
+
for (i = 0; i < INPUT_DEVICES; i++)
input_sync(dd->input_dev[i]);
}