summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Dyer <nick.dyer@itdev.co.uk>2012-08-09 17:32:35 +0100
committerNick Dyer <nick.dyer@itdev.co.uk>2014-07-04 14:25:51 +0100
commitba10e0677efa4e8d6013b2bdfc29dce39fbb864c (patch)
tree8aaaa6ffe4585e5a07aae7659ce52d4466e4550f
parent495bf888c3ebd008b2383e46059a308448c09019 (diff)
downloadolio-linux-3.10-ba10e0677efa4e8d6013b2bdfc29dce39fbb864c.tar.xz
olio-linux-3.10-ba10e0677efa4e8d6013b2bdfc29dce39fbb864c.zip
Input: atmel_mxt_ts - implement support for T15 Key Array
There is a key array object in many maXTouch chips which allows some X/Y lines to be used as a key array. This patch maps them to a series of keys which may be configured in a platform data array. Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk> Acked-by: Benson Leung <bleung@chromium.org> Acked-by: Yufeng Shen <miletus@chromium.org>
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c53
-rw-r--r--include/linux/i2c/atmel_mxt_ts.h2
2 files changed, 55 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index 6aaad83f1b5..4ec1bd548f6 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -275,6 +275,7 @@ struct mxt_data {
u8 last_message_count;
u8 num_touchids;
u8 num_stylusids;
+ unsigned long t15_keystatus;
/* Cached parameters from object table */
u16 T5_address;
@@ -284,6 +285,8 @@ struct mxt_data {
u16 T7_address;
u8 T9_reportid_min;
u8 T9_reportid_max;
+ u8 T15_reportid_min;
+ u8 T15_reportid_max;
u8 T19_reportid;
u8 T42_reportid_min;
u8 T42_reportid_max;
@@ -800,6 +803,38 @@ static void mxt_proc_t9_message(struct mxt_data *data, u8 *message)
data->update_input = true;
}
+static void mxt_proc_t15_messages(struct mxt_data *data, u8 *msg)
+{
+ struct input_dev *input_dev = data->input_dev;
+ struct device *dev = &data->client->dev;
+ int key;
+ bool curr_state, new_state;
+ bool sync = false;
+ unsigned long keystates = le32_to_cpu(msg[2]);
+
+ for (key = 0; key < data->pdata->t15_num_keys; key++) {
+ curr_state = test_bit(key, &data->t15_keystatus);
+ new_state = test_bit(key, &keystates);
+
+ if (!curr_state && new_state) {
+ dev_dbg(dev, "T15 key press: %u\n", key);
+ __set_bit(key, &data->t15_keystatus);
+ input_event(input_dev, EV_KEY,
+ data->pdata->t15_keymap[key], 1);
+ sync = true;
+ } else if (curr_state && !new_state) {
+ dev_dbg(dev, "T15 key release: %u\n", key);
+ __clear_bit(key, &data->t15_keystatus);
+ input_event(input_dev, EV_KEY,
+ data->pdata->t15_keymap[key], 0);
+ sync = true;
+ }
+ }
+
+ if (sync)
+ input_sync(input_dev);
+}
+
static void mxt_proc_t42_messages(struct mxt_data *data, u8 *msg)
{
struct device *dev = &data->client->dev;
@@ -911,6 +946,9 @@ static int mxt_proc_message(struct mxt_data *data, u8 *message)
} else if (report_id >= data->T63_reportid_min
&& report_id <= data->T63_reportid_max) {
mxt_proc_t63_messages(data, message);
+ } else if (report_id >= data->T15_reportid_min
+ && report_id <= data->T15_reportid_max) {
+ mxt_proc_t15_messages(data, message);
} else {
mxt_dump_message(data, message);
}
@@ -1554,6 +1592,8 @@ static void mxt_free_object_table(struct mxt_data *data)
data->T7_address = 0;
data->T9_reportid_min = 0;
data->T9_reportid_max = 0;
+ data->T15_reportid_min = 0;
+ data->T15_reportid_max = 0;
data->T19_reportid = 0;
data->T42_reportid_min = 0;
data->T42_reportid_max = 0;
@@ -1639,6 +1679,10 @@ static int mxt_get_object_table(struct mxt_data *data)
data->num_touchids = object->num_report_ids
* mxt_obj_instances(object);
break;
+ case MXT_TOUCH_KEYARRAY_T15:
+ data->T15_reportid_min = min_id;
+ data->T15_reportid_max = max_id;
+ break;
case MXT_PROCI_TOUCHSUPPRESSION_T42:
data->T42_reportid_min = min_id;
data->T42_reportid_max = max_id;
@@ -2201,6 +2245,15 @@ static int mxt_initialize_t9_input_device(struct mxt_data *data)
0, MT_TOOL_MAX, 0, 0);
}
+ /* For T15 key array */
+ if (data->T15_reportid_min) {
+ data->t15_keystatus = 0;
+
+ for (i = 0; i < data->pdata->t15_num_keys; i++)
+ input_set_capability(input_dev, EV_KEY,
+ data->pdata->t15_keymap[i]);
+ }
+
input_set_drvdata(input_dev, data);
error = input_register_device(input_dev);
diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h
index 02bf6ea3170..b7d20924eb7 100644
--- a/include/linux/i2c/atmel_mxt_ts.h
+++ b/include/linux/i2c/atmel_mxt_ts.h
@@ -20,6 +20,8 @@ struct mxt_platform_data {
unsigned long irqflags;
u8 t19_num_keys;
const unsigned int *t19_keymap;
+ int t15_num_keys;
+ const unsigned int *t15_keymap;
};
#endif /* __LINUX_ATMEL_MXT_TS_H */