diff options
author | John Sung <penmount.touch@gmail.com> | 2011-09-09 16:33:12 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-09-21 01:46:29 -0400 |
commit | c42e2e406ad49f320947ba044d3bbf9b05703089 (patch) | |
tree | 76044dcd6f5a8d3f5b6f1c3b2c7bc742876f2b86 /drivers | |
parent | 21ae508bab28c2b0ae8709c95a36739b6f1ae5be (diff) |
Input: penmount - add PenMount 6000 support
Add support for PenMount 6000 touch controller.
Signed-off-by: John Sung <penmount.touch@gmail.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/input/touchscreen/penmount.c | 65 |
1 files changed, 57 insertions, 8 deletions
diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c index 3342c6d8e57d..e9117adcf6df 100644 --- a/drivers/input/touchscreen/penmount.c +++ b/drivers/input/touchscreen/penmount.c | |||
@@ -33,7 +33,7 @@ MODULE_LICENSE("GPL"); | |||
33 | * Definitions & global arrays. | 33 | * Definitions & global arrays. |
34 | */ | 34 | */ |
35 | 35 | ||
36 | #define PM_MAX_LENGTH 5 | 36 | #define PM_MAX_LENGTH 6 |
37 | 37 | ||
38 | /* | 38 | /* |
39 | * Per-touchscreen data. | 39 | * Per-touchscreen data. |
@@ -45,8 +45,24 @@ struct pm { | |||
45 | int idx; | 45 | int idx; |
46 | unsigned char data[PM_MAX_LENGTH]; | 46 | unsigned char data[PM_MAX_LENGTH]; |
47 | char phys[32]; | 47 | char phys[32]; |
48 | unsigned char packetsize; | ||
48 | }; | 49 | }; |
49 | 50 | ||
51 | /* | ||
52 | * pm_checkpacket() checks if data packet is valid | ||
53 | */ | ||
54 | |||
55 | static bool pm_checkpacket(unsigned char *packet) | ||
56 | { | ||
57 | int total = 0; | ||
58 | int i; | ||
59 | |||
60 | for (i = 0; i < 5; i++) | ||
61 | total += packet[i]; | ||
62 | |||
63 | return packet[5] == (unsigned char)~(total & 0xff); | ||
64 | } | ||
65 | |||
50 | static irqreturn_t pm_interrupt(struct serio *serio, | 66 | static irqreturn_t pm_interrupt(struct serio *serio, |
51 | unsigned char data, unsigned int flags) | 67 | unsigned char data, unsigned int flags) |
52 | { | 68 | { |
@@ -55,14 +71,34 @@ static irqreturn_t pm_interrupt(struct serio *serio, | |||
55 | 71 | ||
56 | pm->data[pm->idx] = data; | 72 | pm->data[pm->idx] = data; |
57 | 73 | ||
58 | if (pm->data[0] & 0x80) { | 74 | switch (pm->dev->id.product) { |
59 | if (PM_MAX_LENGTH == ++pm->idx) { | 75 | case 0x9000: |
60 | input_report_abs(dev, ABS_X, pm->data[1] * 128 + pm->data[2]); | 76 | if (pm->data[0] & 0x80) { |
61 | input_report_abs(dev, ABS_Y, pm->data[3] * 128 + pm->data[4]); | 77 | if (pm->packetsize == ++pm->idx) { |
62 | input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40)); | 78 | input_report_abs(dev, ABS_X, pm->data[1] * 128 + pm->data[2]); |
63 | input_sync(dev); | 79 | input_report_abs(dev, ABS_Y, pm->data[3] * 128 + pm->data[4]); |
64 | pm->idx = 0; | 80 | input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40)); |
81 | input_sync(dev); | ||
82 | pm->idx = 0; | ||
83 | } | ||
84 | } | ||
85 | break; | ||
86 | |||
87 | case 0x6000: | ||
88 | if ((pm->data[0] & 0xbf) == 0x30) { | ||
89 | if (pm->packetsize == ++pm->idx) { | ||
90 | if (pm_checkpacket(pm->data)) { | ||
91 | input_report_abs(dev, ABS_X, | ||
92 | pm->data[2] * 256 + pm->data[1]); | ||
93 | input_report_abs(dev, ABS_Y, | ||
94 | pm->data[4] * 256 + pm->data[3]); | ||
95 | input_report_key(dev, BTN_TOUCH, !!(pm->data[0] & 0x40)); | ||
96 | input_sync(dev); | ||
97 | } | ||
98 | pm->idx = 0; | ||
99 | } | ||
65 | } | 100 | } |
101 | break; | ||
66 | } | 102 | } |
67 | 103 | ||
68 | return IRQ_HANDLED; | 104 | return IRQ_HANDLED; |
@@ -120,6 +156,19 @@ static int pm_connect(struct serio *serio, struct serio_driver *drv) | |||
120 | input_set_abs_params(pm->dev, ABS_X, 0, 0x3ff, 0, 0); | 156 | input_set_abs_params(pm->dev, ABS_X, 0, 0x3ff, 0, 0); |
121 | input_set_abs_params(pm->dev, ABS_Y, 0, 0x3ff, 0, 0); | 157 | input_set_abs_params(pm->dev, ABS_Y, 0, 0x3ff, 0, 0); |
122 | 158 | ||
159 | switch (serio->id.id) { | ||
160 | default: | ||
161 | case 0: | ||
162 | pm->packetsize = 5; | ||
163 | input_dev->id.product = 0x9000; | ||
164 | break; | ||
165 | |||
166 | case 1: | ||
167 | pm->packetsize = 6; | ||
168 | input_dev->id.product = 0x6000; | ||
169 | break; | ||
170 | } | ||
171 | |||
123 | serio_set_drvdata(serio, pm); | 172 | serio_set_drvdata(serio, pm); |
124 | 173 | ||
125 | err = serio_open(serio, drv); | 174 | err = serio_open(serio, drv); |