diff options
Diffstat (limited to 'drivers/input/touchscreen/atmel_mxt_ts.c')
-rw-r--r-- | drivers/input/touchscreen/atmel_mxt_ts.c | 92 |
1 files changed, 62 insertions, 30 deletions
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 4012436633b..1e61387c73c 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <linux/firmware.h> | 17 | #include <linux/firmware.h> |
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
19 | #include <linux/i2c/atmel_mxt_ts.h> | 19 | #include <linux/i2c/atmel_mxt_ts.h> |
20 | #include <linux/input.h> | 20 | #include <linux/input/mt.h> |
21 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | 23 | ||
@@ -196,9 +196,12 @@ | |||
196 | #define MXT_PRESS (1 << 6) | 196 | #define MXT_PRESS (1 << 6) |
197 | #define MXT_DETECT (1 << 7) | 197 | #define MXT_DETECT (1 << 7) |
198 | 198 | ||
199 | /* Touch orient bits */ | ||
200 | #define MXT_XY_SWITCH (1 << 0) | ||
201 | #define MXT_X_INVERT (1 << 1) | ||
202 | #define MXT_Y_INVERT (1 << 2) | ||
203 | |||
199 | /* Touchscreen absolute values */ | 204 | /* Touchscreen absolute values */ |
200 | #define MXT_MAX_XC 0x3ff | ||
201 | #define MXT_MAX_YC 0x3ff | ||
202 | #define MXT_MAX_AREA 0xff | 205 | #define MXT_MAX_AREA 0xff |
203 | 206 | ||
204 | #define MXT_MAX_FINGER 10 | 207 | #define MXT_MAX_FINGER 10 |
@@ -246,6 +249,8 @@ struct mxt_data { | |||
246 | struct mxt_info info; | 249 | struct mxt_info info; |
247 | struct mxt_finger finger[MXT_MAX_FINGER]; | 250 | struct mxt_finger finger[MXT_MAX_FINGER]; |
248 | unsigned int irq; | 251 | unsigned int irq; |
252 | unsigned int max_x; | ||
253 | unsigned int max_y; | ||
249 | }; | 254 | }; |
250 | 255 | ||
251 | static bool mxt_object_readable(unsigned int type) | 256 | static bool mxt_object_readable(unsigned int type) |
@@ -499,19 +504,21 @@ static void mxt_input_report(struct mxt_data *data, int single_id) | |||
499 | if (!finger[id].status) | 504 | if (!finger[id].status) |
500 | continue; | 505 | continue; |
501 | 506 | ||
502 | input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, | 507 | input_mt_slot(input_dev, id); |
503 | finger[id].status != MXT_RELEASE ? | 508 | input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, |
504 | finger[id].area : 0); | 509 | finger[id].status != MXT_RELEASE); |
505 | input_report_abs(input_dev, ABS_MT_POSITION_X, | ||
506 | finger[id].x); | ||
507 | input_report_abs(input_dev, ABS_MT_POSITION_Y, | ||
508 | finger[id].y); | ||
509 | input_mt_sync(input_dev); | ||
510 | 510 | ||
511 | if (finger[id].status == MXT_RELEASE) | 511 | if (finger[id].status != MXT_RELEASE) { |
512 | finger[id].status = 0; | ||
513 | else | ||
514 | finger_num++; | 512 | finger_num++; |
513 | input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR, | ||
514 | finger[id].area); | ||
515 | input_report_abs(input_dev, ABS_MT_POSITION_X, | ||
516 | finger[id].x); | ||
517 | input_report_abs(input_dev, ABS_MT_POSITION_Y, | ||
518 | finger[id].y); | ||
519 | } else { | ||
520 | finger[id].status = 0; | ||
521 | } | ||
515 | } | 522 | } |
516 | 523 | ||
517 | input_report_key(input_dev, BTN_TOUCH, finger_num > 0); | 524 | input_report_key(input_dev, BTN_TOUCH, finger_num > 0); |
@@ -549,8 +556,13 @@ static void mxt_input_touchevent(struct mxt_data *data, | |||
549 | if (!(status & (MXT_PRESS | MXT_MOVE))) | 556 | if (!(status & (MXT_PRESS | MXT_MOVE))) |
550 | return; | 557 | return; |
551 | 558 | ||
552 | x = (message->message[1] << 2) | ((message->message[3] & ~0x3f) >> 6); | 559 | x = (message->message[1] << 4) | ((message->message[3] >> 4) & 0xf); |
553 | y = (message->message[2] << 2) | ((message->message[3] & ~0xf3) >> 2); | 560 | y = (message->message[2] << 4) | ((message->message[3] & 0xf)); |
561 | if (data->max_x < 1024) | ||
562 | x = x >> 2; | ||
563 | if (data->max_y < 1024) | ||
564 | y = y >> 2; | ||
565 | |||
554 | area = message->message[4]; | 566 | area = message->message[4]; |
555 | 567 | ||
556 | dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id, | 568 | dev_dbg(dev, "[%d] %s x: %d, y: %d, area: %d\n", id, |
@@ -804,10 +816,6 @@ static int mxt_initialize(struct mxt_data *data) | |||
804 | if (error) | 816 | if (error) |
805 | return error; | 817 | return error; |
806 | 818 | ||
807 | error = mxt_make_highchg(data); | ||
808 | if (error) | ||
809 | return error; | ||
810 | |||
811 | mxt_handle_pdata(data); | 819 | mxt_handle_pdata(data); |
812 | 820 | ||
813 | /* Backup to memory */ | 821 | /* Backup to memory */ |
@@ -845,6 +853,20 @@ static int mxt_initialize(struct mxt_data *data) | |||
845 | return 0; | 853 | return 0; |
846 | } | 854 | } |
847 | 855 | ||
856 | static void mxt_calc_resolution(struct mxt_data *data) | ||
857 | { | ||
858 | unsigned int max_x = data->pdata->x_size - 1; | ||
859 | unsigned int max_y = data->pdata->y_size - 1; | ||
860 | |||
861 | if (data->pdata->orient & MXT_XY_SWITCH) { | ||
862 | data->max_x = max_y; | ||
863 | data->max_y = max_x; | ||
864 | } else { | ||
865 | data->max_x = max_x; | ||
866 | data->max_y = max_y; | ||
867 | } | ||
868 | } | ||
869 | |||
848 | static ssize_t mxt_object_show(struct device *dev, | 870 | static ssize_t mxt_object_show(struct device *dev, |
849 | struct device_attribute *attr, char *buf) | 871 | struct device_attribute *attr, char *buf) |
850 | { | 872 | { |
@@ -981,6 +1003,10 @@ static ssize_t mxt_update_fw_store(struct device *dev, | |||
981 | 1003 | ||
982 | enable_irq(data->irq); | 1004 | enable_irq(data->irq); |
983 | 1005 | ||
1006 | error = mxt_make_highchg(data); | ||
1007 | if (error) | ||
1008 | return error; | ||
1009 | |||
984 | return count; | 1010 | return count; |
985 | } | 1011 | } |
986 | 1012 | ||
@@ -1052,31 +1078,33 @@ static int __devinit mxt_probe(struct i2c_client *client, | |||
1052 | input_dev->open = mxt_input_open; | 1078 | input_dev->open = mxt_input_open; |
1053 | input_dev->close = mxt_input_close; | 1079 | input_dev->close = mxt_input_close; |
1054 | 1080 | ||
1081 | data->client = client; | ||
1082 | data->input_dev = input_dev; | ||
1083 | data->pdata = pdata; | ||
1084 | data->irq = client->irq; | ||
1085 | |||
1086 | mxt_calc_resolution(data); | ||
1087 | |||
1055 | __set_bit(EV_ABS, input_dev->evbit); | 1088 | __set_bit(EV_ABS, input_dev->evbit); |
1056 | __set_bit(EV_KEY, input_dev->evbit); | 1089 | __set_bit(EV_KEY, input_dev->evbit); |
1057 | __set_bit(BTN_TOUCH, input_dev->keybit); | 1090 | __set_bit(BTN_TOUCH, input_dev->keybit); |
1058 | 1091 | ||
1059 | /* For single touch */ | 1092 | /* For single touch */ |
1060 | input_set_abs_params(input_dev, ABS_X, | 1093 | input_set_abs_params(input_dev, ABS_X, |
1061 | 0, MXT_MAX_XC, 0, 0); | 1094 | 0, data->max_x, 0, 0); |
1062 | input_set_abs_params(input_dev, ABS_Y, | 1095 | input_set_abs_params(input_dev, ABS_Y, |
1063 | 0, MXT_MAX_YC, 0, 0); | 1096 | 0, data->max_y, 0, 0); |
1064 | 1097 | ||
1065 | /* For multi touch */ | 1098 | /* For multi touch */ |
1099 | input_mt_init_slots(input_dev, MXT_MAX_FINGER); | ||
1066 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | 1100 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, |
1067 | 0, MXT_MAX_AREA, 0, 0); | 1101 | 0, MXT_MAX_AREA, 0, 0); |
1068 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | 1102 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, |
1069 | 0, MXT_MAX_XC, 0, 0); | 1103 | 0, data->max_x, 0, 0); |
1070 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | 1104 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, |
1071 | 0, MXT_MAX_YC, 0, 0); | 1105 | 0, data->max_y, 0, 0); |
1072 | 1106 | ||
1073 | input_set_drvdata(input_dev, data); | 1107 | input_set_drvdata(input_dev, data); |
1074 | |||
1075 | data->client = client; | ||
1076 | data->input_dev = input_dev; | ||
1077 | data->pdata = pdata; | ||
1078 | data->irq = client->irq; | ||
1079 | |||
1080 | i2c_set_clientdata(client, data); | 1108 | i2c_set_clientdata(client, data); |
1081 | 1109 | ||
1082 | error = mxt_initialize(data); | 1110 | error = mxt_initialize(data); |
@@ -1090,6 +1118,10 @@ static int __devinit mxt_probe(struct i2c_client *client, | |||
1090 | goto err_free_object; | 1118 | goto err_free_object; |
1091 | } | 1119 | } |
1092 | 1120 | ||
1121 | error = mxt_make_highchg(data); | ||
1122 | if (error) | ||
1123 | goto err_free_irq; | ||
1124 | |||
1093 | error = input_register_device(input_dev); | 1125 | error = input_register_device(input_dev); |
1094 | if (error) | 1126 | if (error) |
1095 | goto err_free_irq; | 1127 | goto err_free_irq; |