2 * Penmount serial touchscreen driver
4 * Copyright (c) 2006 Rick Koch <n1gp@hotmail.com>
5 * Copyright (c) 2011 John Sung <penmount.touch@gmail.com>
7 * Based on ELO driver (drivers/input/touchscreen/elo.c)
8 * Copyright (c) 2004 Vojtech Pavlik
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License version 2 as published
14 * by the Free Software Foundation.
17 #include <linux/errno.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/slab.h>
21 #include <linux/input.h>
22 #include <linux/input/mt.h>
23 #include <linux/serio.h>
24 #include <linux/init.h>
26 #define DRIVER_DESC "PenMount serial touchscreen driver"
28 MODULE_AUTHOR("Rick Koch <n1gp@hotmail.com>");
29 MODULE_AUTHOR("John Sung <penmount.touch@gmail.com>");
30 MODULE_DESCRIPTION(DRIVER_DESC
);
31 MODULE_LICENSE("GPL");
34 * Definitions & global arrays.
37 #define PM_MAX_LENGTH 6
38 #define PM_MAX_MTSLOT 16
39 #define PM_3000_MTSLOT 2
40 #define PM_6250_MTSLOT 12
48 bool active
; /* is the touch valid? */
52 * Per-touchscreen data.
56 struct input_dev
*dev
;
59 unsigned char data
[PM_MAX_LENGTH
];
61 unsigned char packetsize
;
62 unsigned char maxcontacts
;
63 struct mt_slot slots
[PM_MAX_MTSLOT
];
64 void (*parse_packet
)(struct pm
*);
68 * pm_mtevent() sends mt events and also emulates pointer movement
71 static void pm_mtevent(struct pm
*pm
, struct input_dev
*input
)
75 for (i
= 0; i
< pm
->maxcontacts
; ++i
) {
76 input_mt_slot(input
, i
);
77 input_mt_report_slot_state(input
, MT_TOOL_FINGER
,
79 if (pm
->slots
[i
].active
) {
80 input_event(input
, EV_ABS
, ABS_MT_POSITION_X
, pm
->slots
[i
].x
);
81 input_event(input
, EV_ABS
, ABS_MT_POSITION_Y
, pm
->slots
[i
].y
);
85 input_mt_report_pointer_emulation(input
, true);
90 * pm_checkpacket() checks if data packet is valid
93 static bool pm_checkpacket(unsigned char *packet
)
98 for (i
= 0; i
< 5; i
++)
101 return packet
[5] == (unsigned char)~(total
& 0xff);
104 static void pm_parse_9000(struct pm
*pm
)
106 struct input_dev
*dev
= pm
->dev
;
108 if ((pm
->data
[0] & 0x80) && pm
->packetsize
== ++pm
->idx
) {
109 input_report_abs(dev
, ABS_X
, pm
->data
[1] * 128 + pm
->data
[2]);
110 input_report_abs(dev
, ABS_Y
, pm
->data
[3] * 128 + pm
->data
[4]);
111 input_report_key(dev
, BTN_TOUCH
, !!(pm
->data
[0] & 0x40));
117 static void pm_parse_6000(struct pm
*pm
)
119 struct input_dev
*dev
= pm
->dev
;
121 if ((pm
->data
[0] & 0xbf) == 0x30 && pm
->packetsize
== ++pm
->idx
) {
122 if (pm_checkpacket(pm
->data
)) {
123 input_report_abs(dev
, ABS_X
,
124 pm
->data
[2] * 256 + pm
->data
[1]);
125 input_report_abs(dev
, ABS_Y
,
126 pm
->data
[4] * 256 + pm
->data
[3]);
127 input_report_key(dev
, BTN_TOUCH
, pm
->data
[0] & 0x40);
134 static void pm_parse_3000(struct pm
*pm
)
136 struct input_dev
*dev
= pm
->dev
;
138 if ((pm
->data
[0] & 0xce) == 0x40 && pm
->packetsize
== ++pm
->idx
) {
139 if (pm_checkpacket(pm
->data
)) {
140 int slotnum
= pm
->data
[0] & 0x0f;
141 pm
->slots
[slotnum
].active
= pm
->data
[0] & 0x30;
142 pm
->slots
[slotnum
].x
= pm
->data
[2] * 256 + pm
->data
[1];
143 pm
->slots
[slotnum
].y
= pm
->data
[4] * 256 + pm
->data
[3];
150 static void pm_parse_6250(struct pm
*pm
)
152 struct input_dev
*dev
= pm
->dev
;
154 if ((pm
->data
[0] & 0xb0) == 0x30 && pm
->packetsize
== ++pm
->idx
) {
155 if (pm_checkpacket(pm
->data
)) {
156 int slotnum
= pm
->data
[0] & 0x0f;
157 pm
->slots
[slotnum
].active
= pm
->data
[0] & 0x40;
158 pm
->slots
[slotnum
].x
= pm
->data
[2] * 256 + pm
->data
[1];
159 pm
->slots
[slotnum
].y
= pm
->data
[4] * 256 + pm
->data
[3];
166 static irqreturn_t
pm_interrupt(struct serio
*serio
,
167 unsigned char data
, unsigned int flags
)
169 struct pm
*pm
= serio_get_drvdata(serio
);
171 pm
->data
[pm
->idx
] = data
;
173 pm
->parse_packet(pm
);
179 * pm_disconnect() is the opposite of pm_connect()
182 static void pm_disconnect(struct serio
*serio
)
184 struct pm
*pm
= serio_get_drvdata(serio
);
188 input_unregister_device(pm
->dev
);
191 serio_set_drvdata(serio
, NULL
);
195 * pm_connect() is the routine that is called when someone adds a
196 * new serio device that supports PenMount protocol and registers it as
200 static int pm_connect(struct serio
*serio
, struct serio_driver
*drv
)
203 struct input_dev
*input_dev
;
207 pm
= kzalloc(sizeof(struct pm
), GFP_KERNEL
);
208 input_dev
= input_allocate_device();
209 if (!pm
|| !input_dev
) {
216 snprintf(pm
->phys
, sizeof(pm
->phys
), "%s/input0", serio
->phys
);
219 input_dev
->name
= "PenMount Serial TouchScreen";
220 input_dev
->phys
= pm
->phys
;
221 input_dev
->id
.bustype
= BUS_RS232
;
222 input_dev
->id
.vendor
= SERIO_PENMOUNT
;
223 input_dev
->id
.product
= 0;
224 input_dev
->id
.version
= 0x0100;
225 input_dev
->dev
.parent
= &serio
->dev
;
227 input_dev
->evbit
[0] = BIT_MASK(EV_KEY
) | BIT_MASK(EV_ABS
);
228 input_dev
->keybit
[BIT_WORD(BTN_TOUCH
)] = BIT_MASK(BTN_TOUCH
);
230 switch (serio
->id
.id
) {
234 pm
->parse_packet
= pm_parse_9000
;
235 input_dev
->id
.product
= 0x9000;
236 max_x
= max_y
= 0x3ff;
241 pm
->parse_packet
= pm_parse_6000
;
242 input_dev
->id
.product
= 0x6000;
243 max_x
= max_y
= 0x3ff;
248 pm
->parse_packet
= pm_parse_3000
;
249 input_dev
->id
.product
= 0x3000;
250 max_x
= max_y
= 0x7ff;
251 pm
->maxcontacts
= PM_3000_MTSLOT
;
256 pm
->parse_packet
= pm_parse_6250
;
257 input_dev
->id
.product
= 0x6250;
258 max_x
= max_y
= 0x3ff;
259 pm
->maxcontacts
= PM_6250_MTSLOT
;
263 input_set_abs_params(pm
->dev
, ABS_X
, 0, max_x
, 0, 0);
264 input_set_abs_params(pm
->dev
, ABS_Y
, 0, max_y
, 0, 0);
266 if (pm
->maxcontacts
> 1) {
267 input_mt_init_slots(pm
->dev
, pm
->maxcontacts
);
268 input_set_abs_params(pm
->dev
,
269 ABS_MT_POSITION_X
, 0, max_x
, 0, 0);
270 input_set_abs_params(pm
->dev
,
271 ABS_MT_POSITION_Y
, 0, max_y
, 0, 0);
274 serio_set_drvdata(serio
, pm
);
276 err
= serio_open(serio
, drv
);
280 err
= input_register_device(pm
->dev
);
286 fail3
: serio_close(serio
);
287 fail2
: serio_set_drvdata(serio
, NULL
);
288 fail1
: input_free_device(input_dev
);
294 * The serio driver structure.
297 static struct serio_device_id pm_serio_ids
[] = {
300 .proto
= SERIO_PENMOUNT
,
307 MODULE_DEVICE_TABLE(serio
, pm_serio_ids
);
309 static struct serio_driver pm_drv
= {
311 .name
= "serio-penmount",
313 .description
= DRIVER_DESC
,
314 .id_table
= pm_serio_ids
,
315 .interrupt
= pm_interrupt
,
316 .connect
= pm_connect
,
317 .disconnect
= pm_disconnect
,
321 * The functions for inserting/removing us as a module.
324 static int __init
pm_init(void)
326 return serio_register_driver(&pm_drv
);
329 static void __exit
pm_exit(void)
331 serio_unregister_driver(&pm_drv
);
334 module_init(pm_init
);
335 module_exit(pm_exit
);