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/input/touchscreen | |
| 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/input/touchscreen')
| -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); |
