diff options
author | Shaun Jackman <sjackman@gmail.com> | 2006-08-05 00:27:59 -0400 |
---|---|---|
committer | Dmitry Torokhov <dtor@insightbb.com> | 2006-08-05 00:27:59 -0400 |
commit | 1ce316efb55a1497d07d518853e60a4356abceb6 (patch) | |
tree | 5b80f90e5ddc7ff36b1ce30bdbf796d8741d7bc2 /drivers/input/touchscreen/elo.c | |
parent | 6b50d8b862284929314e9ff09e5b1cce2c43d32b (diff) |
Input: elo - fix checksum calculation
Fix 10-byte protocol checksum calculation and do not discard packet early
unless it is missing lead in byte.
Signed-off-by: Shaun Jackman <sjackman@gmail.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/touchscreen/elo.c')
-rw-r--r-- | drivers/input/touchscreen/elo.c | 55 |
1 files changed, 29 insertions, 26 deletions
diff --git a/drivers/input/touchscreen/elo.c b/drivers/input/touchscreen/elo.c index b7ac016219d9..fe6e1a428674 100644 --- a/drivers/input/touchscreen/elo.c +++ b/drivers/input/touchscreen/elo.c | |||
@@ -34,7 +34,11 @@ MODULE_LICENSE("GPL"); | |||
34 | * Definitions & global arrays. | 34 | * Definitions & global arrays. |
35 | */ | 35 | */ |
36 | 36 | ||
37 | #define ELO_MAX_LENGTH 10 | 37 | #define ELO_MAX_LENGTH 10 |
38 | |||
39 | #define ELO10_LEAD_BYTE 'U' | ||
40 | |||
41 | #define ELO10_TOUCH_PACKET 'T' | ||
38 | 42 | ||
39 | /* | 43 | /* |
40 | * Per-touchscreen data. | 44 | * Per-touchscreen data. |
@@ -50,44 +54,43 @@ struct elo { | |||
50 | char phys[32]; | 54 | char phys[32]; |
51 | }; | 55 | }; |
52 | 56 | ||
53 | static void elo_process_data_10(struct elo* elo, unsigned char data, struct pt_regs *regs) | 57 | static void elo_process_data_10(struct elo *elo, unsigned char data, struct pt_regs *regs) |
54 | { | 58 | { |
55 | struct input_dev *dev = elo->dev; | 59 | struct input_dev *dev = elo->dev; |
56 | 60 | ||
57 | elo->csum += elo->data[elo->idx] = data; | 61 | elo->data[elo->idx] = data; |
58 | |||
59 | switch (elo->idx++) { | 62 | switch (elo->idx++) { |
60 | |||
61 | case 0: | 63 | case 0: |
62 | if (data != 'U') { | 64 | elo->csum = 0xaa; |
63 | elo->idx = 0; | 65 | if (data != ELO10_LEAD_BYTE) { |
64 | elo->csum = 0; | 66 | pr_debug("elo: unsynchronized data: 0x%02x\n", data); |
65 | } | ||
66 | break; | ||
67 | |||
68 | case 1: | ||
69 | if (data != 'T') { | ||
70 | elo->idx = 0; | 67 | elo->idx = 0; |
71 | elo->csum = 0; | ||
72 | } | 68 | } |
73 | break; | 69 | break; |
74 | 70 | ||
75 | case 9: | 71 | case 9: |
76 | if (elo->csum) { | ||
77 | input_regs(dev, regs); | ||
78 | input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]); | ||
79 | input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]); | ||
80 | input_report_abs(dev, ABS_PRESSURE, (elo->data[8] << 8) | elo->data[7]); | ||
81 | input_report_key(dev, BTN_TOUCH, elo->data[8] || elo->data[7]); | ||
82 | input_sync(dev); | ||
83 | } | ||
84 | elo->idx = 0; | 72 | elo->idx = 0; |
85 | elo->csum = 0; | 73 | if (data != elo->csum) { |
74 | pr_debug("elo: bad checksum: 0x%02x, expected 0x%02x\n", | ||
75 | data, elo->csum); | ||
76 | break; | ||
77 | } | ||
78 | if (elo->data[1] != ELO10_TOUCH_PACKET) { | ||
79 | pr_debug(elo: "unexpected packet: 0x%02x\n", elo->data[1]); | ||
80 | break; | ||
81 | } | ||
82 | input_regs(dev, regs); | ||
83 | input_report_abs(dev, ABS_X, (elo->data[4] << 8) | elo->data[3]); | ||
84 | input_report_abs(dev, ABS_Y, (elo->data[6] << 8) | elo->data[5]); | ||
85 | input_report_abs(dev, ABS_PRESSURE, (elo->data[8] << 8) | elo->data[7]); | ||
86 | input_report_key(dev, BTN_TOUCH, elo->data[8] || elo->data[7]); | ||
87 | input_sync(dev); | ||
86 | break; | 88 | break; |
87 | } | 89 | } |
90 | elo->csum += data; | ||
88 | } | 91 | } |
89 | 92 | ||
90 | static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_regs *regs) | 93 | static void elo_process_data_6(struct elo *elo, unsigned char data, struct pt_regs *regs) |
91 | { | 94 | { |
92 | struct input_dev *dev = elo->dev; | 95 | struct input_dev *dev = elo->dev; |
93 | 96 | ||
@@ -135,7 +138,7 @@ static void elo_process_data_6(struct elo* elo, unsigned char data, struct pt_re | |||
135 | } | 138 | } |
136 | } | 139 | } |
137 | 140 | ||
138 | static void elo_process_data_3(struct elo* elo, unsigned char data, struct pt_regs *regs) | 141 | static void elo_process_data_3(struct elo *elo, unsigned char data, struct pt_regs *regs) |
139 | { | 142 | { |
140 | struct input_dev *dev = elo->dev; | 143 | struct input_dev *dev = elo->dev; |
141 | 144 | ||
@@ -161,7 +164,7 @@ static void elo_process_data_3(struct elo* elo, unsigned char data, struct pt_re | |||
161 | static irqreturn_t elo_interrupt(struct serio *serio, | 164 | static irqreturn_t elo_interrupt(struct serio *serio, |
162 | unsigned char data, unsigned int flags, struct pt_regs *regs) | 165 | unsigned char data, unsigned int flags, struct pt_regs *regs) |
163 | { | 166 | { |
164 | struct elo* elo = serio_get_drvdata(serio); | 167 | struct elo *elo = serio_get_drvdata(serio); |
165 | 168 | ||
166 | switch(elo->id) { | 169 | switch(elo->id) { |
167 | case 0: | 170 | case 0: |