summaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorNick Dyer <nick.dyer@itdev.co.uk>2014-07-23 21:48:13 +0200
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2014-07-23 23:42:13 +0200
commitb9b05a89721f05e2db227283ec9f7af804830b01 (patch)
tree0333028d0f8cb3bf6698e497a3c1bc5ea93f0d7e /drivers/input
parentInput: atmel_mxt_ts - decode T6 status messages (diff)
downloadlinux-b9b05a89721f05e2db227283ec9f7af804830b01.tar.xz
linux-b9b05a89721f05e2db227283ec9f7af804830b01.zip
Input: atmel_mxt_ts - split message handler into separate functions
This is in preparation for support of the T44 message count object. Also, cache T5 address to avoid lookup on every interrupt cycle. Signed-off-by: Nick Dyer <nick.dyer@itdev.co.uk> Acked-by: Benson Leung <bleung@chromium.org> Acked-by: Yufeng Shen <miletus@chromium.org> Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Diffstat (limited to 'drivers/input')
-rw-r--r--drivers/input/touchscreen/atmel_mxt_ts.c123
1 files changed, 64 insertions, 59 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index c8c6ac1d38a1..699de552a6d8 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -249,8 +249,10 @@ struct mxt_data {
u8 bootloader_addr;
u8 *msg_buf;
u8 t6_status;
+ bool update_input;
/* Cached parameters from object table */
+ u16 T5_address;
u8 T5_msg_size;
u8 T6_reportid;
u16 T6_address;
@@ -662,20 +664,6 @@ static void mxt_proc_t6_messages(struct mxt_data *data, u8 *msg)
data->t6_status = status;
}
-static int mxt_read_message(struct mxt_data *data, u8 *message)
-{
- struct mxt_object *object;
- u16 reg;
-
- object = mxt_get_object(data, MXT_GEN_MESSAGE_T5);
- if (!object)
- return -EINVAL;
-
- reg = object->start_address;
- return __mxt_read_reg(data->client, reg,
- data->T5_msg_size, message);
-}
-
static int mxt_write_object(struct mxt_data *data,
u8 type, u8 offset, u8 val)
{
@@ -713,7 +701,7 @@ static void mxt_input_sync(struct mxt_data *data)
input_sync(data->input_dev);
}
-static void mxt_input_touchevent(struct mxt_data *data, u8 *message)
+static void mxt_proc_t9_message(struct mxt_data *data, u8 *message)
{
struct device *dev = &data->client->dev;
struct input_dev *input_dev = data->input_dev;
@@ -775,50 +763,67 @@ static void mxt_input_touchevent(struct mxt_data *data, u8 *message)
/* Touch no longer active, close out slot */
input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, 0);
}
+
+ data->update_input = true;
}
-static bool mxt_is_T9_message(struct mxt_data *data, u8 *msg)
+static int mxt_proc_message(struct mxt_data *data, u8 *message)
{
- u8 id = msg[0];
- return (id >= data->T9_reportid_min && id <= data->T9_reportid_max);
+ u8 report_id = message[0];
+
+ if (report_id == MXT_RPTID_NOMSG)
+ return 0;
+
+ if (report_id == data->T6_reportid) {
+ mxt_proc_t6_messages(data, message);
+ } else if (!data->input_dev) {
+ /*
+ * Do not report events if input device
+ * is not yet registered.
+ */
+ mxt_dump_message(data, message);
+ } else if (report_id >= data->T9_reportid_min
+ && report_id <= data->T9_reportid_max) {
+ mxt_proc_t9_message(data, message);
+ } else if (report_id == data->T19_reportid) {
+ mxt_input_button(data, message);
+ data->update_input = true;
+ } else {
+ mxt_dump_message(data, message);
+ }
+
+ return 1;
}
-static irqreturn_t mxt_process_messages_until_invalid(struct mxt_data *data)
+static int mxt_read_and_process_message(struct mxt_data *data)
{
- u8 *message = &data->msg_buf[0];
struct device *dev = &data->client->dev;
- u8 reportid;
- bool update_input = false;
+ int ret;
- do {
- if (mxt_read_message(data, message)) {
- dev_err(dev, "Failed to read message\n");
- return IRQ_NONE;
- }
+ ret = __mxt_read_reg(data->client, data->T5_address,
+ data->T5_msg_size, data->msg_buf);
+ if (ret) {
+ dev_err(dev, "Error %d reading message\n", ret);
+ return ret;
+ }
- reportid = message[0];
+ return mxt_proc_message(data, data->msg_buf);
+}
- if (reportid == data->T6_reportid) {
- mxt_proc_t6_messages(data, message);
- } else if (!data->input_dev) {
- /*
- * do not report events if input device
- * is not yet registered
- */
- mxt_dump_message(data, message);
- } else if (mxt_is_T9_message(data, message)) {
- mxt_input_touchevent(data, message);
- update_input = true;
- } else if (reportid == data->T19_reportid) {
- mxt_input_button(data, message);
- update_input = true;
- } else {
- mxt_dump_message(data, message);
- }
- } while (reportid != MXT_RPTID_NOMSG);
+static irqreturn_t mxt_process_messages_until_invalid(struct mxt_data *data)
+{
+ int ret;
+
+ do {
+ ret = mxt_read_and_process_message(data);
+ if (ret < 0)
+ return IRQ_NONE;
+ } while (ret > 0);
- if (update_input)
+ if (data->update_input) {
mxt_input_sync(data);
+ data->update_input = false;
+ }
return IRQ_HANDLED;
}
@@ -1213,21 +1218,19 @@ static int mxt_make_highchg(struct mxt_data *data)
{
struct device *dev = &data->client->dev;
int count = 10;
- int error;
+ int ret;
- /* Read dummy message to make high CHG pin */
+ /* Read messages until we force an invalid */
do {
- error = mxt_read_message(data, data->msg_buf);
- if (error)
- return error;
- } while (data->msg_buf[0] != MXT_RPTID_NOMSG && --count);
-
- if (!count) {
- dev_err(dev, "CHG pin isn't cleared\n");
- return -EBUSY;
- }
+ ret = mxt_read_and_process_message(data);
+ if (ret == 0)
+ return 0;
+ else if (ret < 0)
+ return ret;
+ } while (--count);
- return 0;
+ dev_err(dev, "CHG pin isn't cleared\n");
+ return -EBUSY;
}
static int mxt_acquire_irq(struct mxt_data *data)
@@ -1266,6 +1269,7 @@ static void mxt_free_object_table(struct mxt_data *data)
data->object_table = NULL;
kfree(data->msg_buf);
data->msg_buf = NULL;
+ data->T5_address = 0;
data->T5_msg_size = 0;
data->T6_reportid = 0;
data->T7_address = 0;
@@ -1327,6 +1331,7 @@ static int mxt_get_object_table(struct mxt_data *data)
case MXT_GEN_MESSAGE_T5:
/* CRC not enabled, therefore don't read last byte */
data->T5_msg_size = mxt_obj_size(object) - 1;
+ data->T5_address = object->start_address;
case MXT_GEN_COMMAND_T6:
data->T6_reportid = min_id;
data->T6_address = object->start_address;