15 #include <linux/input.h>
16 #include <linux/serio.h>
19 #include <linux/slab.h>
29 static bool lifebook_present;
31 static const char *desired_serio_phys;
35 desired_serio_phys =
"isa0060/serio3";
39 static bool lifebook_use_6byte_proto;
43 lifebook_use_6byte_proto =
true;
95 .callback = lifebook_limit_serio3,
103 .callback = lifebook_set_6byte_proto,
111 .callback = lifebook_set_6byte_proto,
118 .callback = lifebook_set_6byte_proto,
137 struct input_dev *dev1 = psmouse->
dev;
138 struct input_dev *dev2 = priv ? priv->
dev2 :
NULL;
140 bool relative_packet = packet[0] & 0x08;
142 if (relative_packet || !lifebook_use_6byte_proto) {
146 switch (psmouse->
pktcnt) {
148 return (packet[0] & 0xf8) == 0x00 ?
153 return ((packet[2] & 0x30) << 2) == (packet[2] & 0xc0) ?
156 return (packet[3] & 0xf8) == 0xc0 ?
159 return (packet[4] & 0xc0) == (packet[2] & 0xc0) ?
162 if (((packet[5] & 0x30) << 2) != (packet[5] & 0xc0))
164 if ((packet[5] & 0xc0) != (packet[1] & 0xc0))
170 if (relative_packet) {
173 "got relative packet but no relative device set up\n");
175 if (lifebook_use_6byte_proto) {
176 input_report_abs(dev1,
ABS_X,
177 ((packet[1] & 0x3f) << 6) | (packet[2] & 0x3f));
178 input_report_abs(dev1,
ABS_Y,
179 4096 - (((packet[4] & 0x3f) << 6) | (packet[5] & 0x3f)));
181 input_report_abs(dev1,
ABS_X,
182 (packet[1] | ((packet[0] & 0x30) << 4)));
183 input_report_abs(dev1,
ABS_Y,
184 1024 - (packet[2] | ((packet[0] & 0xC0) << 2)));
186 input_report_key(dev1,
BTN_TOUCH, packet[0] & 0x04);
191 if (relative_packet) {
192 input_report_rel(dev2,
REL_X,
193 ((packet[0] & 0x10) ? packet[1] - 256 : packet[1]));
194 input_report_rel(dev2,
REL_Y,
195 -(
int)((packet[0] & 0x20) ? packet[2] - 256 : packet[2]));
197 input_report_key(dev2,
BTN_LEFT, packet[0] & 0x01);
198 input_report_key(dev2,
BTN_RIGHT, packet[0] & 0x02);
205 static int lifebook_absolute_mode(
struct psmouse *psmouse)
218 param = lifebook_use_6byte_proto ? 0x08 : 0x07;
224 static void lifebook_relative_mode(
struct psmouse *psmouse)
226 struct ps2dev *ps2dev = &psmouse->
ps2dev;
227 unsigned char param = 0x06;
232 static void lifebook_set_resolution(
struct psmouse *psmouse,
unsigned int resolution)
234 static const unsigned char params[] = { 0, 1, 2, 2, 3 };
237 if (resolution == 0 || resolution > 400)
240 p = params[resolution / 100];
245 static void lifebook_disconnect(
struct psmouse *psmouse)
251 input_unregister_device(priv->
dev2);
259 if (!lifebook_present)
262 if (desired_serio_phys &&
263 strcmp(psmouse->
ps2dev.serio->phys, desired_serio_phys))
266 if (set_properties) {
267 psmouse->
vendor =
"Fujitsu";
268 psmouse->
name =
"Lifebook TouchScreen";
274 static int lifebook_create_relative_device(
struct psmouse *psmouse)
276 struct input_dev *dev2;
281 dev2 = input_allocate_device();
287 "%s/input1", psmouse->
ps2dev.serio->phys);
289 dev2->phys = priv->
phys;
290 dev2->name =
"PS/2 Touchpad";
292 dev2->id.vendor = 0x0002;
294 dev2->id.version = 0x0000;
295 dev2->dev.parent = &psmouse->
ps2dev.serio->dev;
302 error = input_register_device(priv->
dev2);
310 input_free_device(dev2);
317 struct input_dev *dev1 = psmouse->
dev;
318 int max_coord = lifebook_use_6byte_proto ? 4096 : 1024;
320 if (lifebook_absolute_mode(psmouse))
327 input_set_abs_params(dev1,
ABS_X, 0, max_coord, 0, 0);
328 input_set_abs_params(dev1,
ABS_Y, 0, max_coord, 0, 0);
330 if (!desired_serio_phys) {
331 if (lifebook_create_relative_device(psmouse)) {
332 lifebook_relative_mode(psmouse);
340 psmouse->
reconnect = lifebook_absolute_mode;
342 psmouse->
model = lifebook_use_6byte_proto ? 6 : 3;