diff options
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r-- | drivers/input/mouse/Kconfig | 61 | ||||
-rw-r--r-- | drivers/input/mouse/Makefile | 8 | ||||
-rw-r--r-- | drivers/input/mouse/alps.c | 13 | ||||
-rw-r--r-- | drivers/input/mouse/alps.h | 18 | ||||
-rw-r--r-- | drivers/input/mouse/hil_ptr.c | 97 | ||||
-rw-r--r-- | drivers/input/mouse/lifebook.c | 195 | ||||
-rw-r--r-- | drivers/input/mouse/lifebook.h | 11 | ||||
-rw-r--r-- | drivers/input/mouse/logips2pp.c | 7 | ||||
-rw-r--r-- | drivers/input/mouse/logips2pp.h | 7 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse-base.c | 50 | ||||
-rw-r--r-- | drivers/input/mouse/psmouse.h | 1 | ||||
-rw-r--r-- | drivers/input/mouse/sermouse.c | 19 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.c | 109 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.h | 18 | ||||
-rw-r--r-- | drivers/input/mouse/touchkit_ps2.c | 100 | ||||
-rw-r--r-- | drivers/input/mouse/touchkit_ps2.h | 24 | ||||
-rw-r--r-- | drivers/input/mouse/trackpoint.h | 9 | ||||
-rw-r--r-- | drivers/input/mouse/vsxxxaa.c | 3 |
18 files changed, 591 insertions, 159 deletions
diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index b40784a60aa..81dd8c7211a 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig | |||
@@ -37,6 +37,65 @@ config MOUSE_PS2 | |||
37 | To compile this driver as a module, choose M here: the | 37 | To compile this driver as a module, choose M here: the |
38 | module will be called psmouse. | 38 | module will be called psmouse. |
39 | 39 | ||
40 | config MOUSE_PS2_ALPS | ||
41 | bool "ALPS PS/2 mouse protocol extension" if EMBEDDED | ||
42 | default y | ||
43 | depends on MOUSE_PS2 | ||
44 | ---help--- | ||
45 | Say Y here if you have an ALPS PS/2 touchpad connected to | ||
46 | your system. | ||
47 | |||
48 | If unsure, say Y. | ||
49 | |||
50 | config MOUSE_PS2_LOGIPS2PP | ||
51 | bool "Logictech PS/2++ mouse protocol extension" if EMBEDDED | ||
52 | default y | ||
53 | depends on MOUSE_PS2 | ||
54 | ---help--- | ||
55 | Say Y here if you have a Logictech PS/2++ mouse connected to | ||
56 | your system. | ||
57 | |||
58 | If unsure, say Y. | ||
59 | |||
60 | config MOUSE_PS2_SYNAPTICS | ||
61 | bool "Synaptics PS/2 mouse protocol extension" if EMBEDDED | ||
62 | default y | ||
63 | depends on MOUSE_PS2 | ||
64 | ---help--- | ||
65 | Say Y here if you have a Synaptics PS/2 TouchPad connected to | ||
66 | your system. | ||
67 | |||
68 | If unsure, say Y. | ||
69 | |||
70 | config MOUSE_PS2_LIFEBOOK | ||
71 | bool "Fujitsu Lifebook PS/2 mouse protocol extension" if EMBEDDED | ||
72 | default y | ||
73 | depends on MOUSE_PS2 | ||
74 | ---help--- | ||
75 | Say Y here if you have a Fujitsu B-series Lifebook PS/2 | ||
76 | TouchScreen connected to your system. | ||
77 | |||
78 | If unsure, say Y. | ||
79 | |||
80 | config MOUSE_PS2_TRACKPOINT | ||
81 | bool "IBM Trackpoint PS/2 mouse protocol extension" if EMBEDDED | ||
82 | default y | ||
83 | depends on MOUSE_PS2 | ||
84 | ---help--- | ||
85 | Say Y here if you have an IBM Trackpoint PS/2 mouse connected | ||
86 | to your system. | ||
87 | |||
88 | If unsure, say Y. | ||
89 | |||
90 | config MOUSE_PS2_TOUCHKIT | ||
91 | bool "eGalax TouchKit PS/2 protocol extension" | ||
92 | depends on MOUSE_PS2 | ||
93 | ---help--- | ||
94 | Say Y here if you have an eGalax TouchKit PS/2 touchscreen | ||
95 | connected to your system. | ||
96 | |||
97 | If unsure, say N. | ||
98 | |||
40 | config MOUSE_SERIAL | 99 | config MOUSE_SERIAL |
41 | tristate "Serial mouse" | 100 | tristate "Serial mouse" |
42 | select SERIO | 101 | select SERIO |
@@ -129,7 +188,7 @@ config MOUSE_VSXXXAA | |||
129 | digitizer (VSXXX-AB) DEC produced. | 188 | digitizer (VSXXX-AB) DEC produced. |
130 | 189 | ||
131 | config MOUSE_HIL | 190 | config MOUSE_HIL |
132 | tristate "HIL pointers (mice etc)." | 191 | tristate "HIL pointers (mice etc)." |
133 | depends on GSC || HP300 | 192 | depends on GSC || HP300 |
134 | select HP_SDC | 193 | select HP_SDC |
135 | select HIL_MLC | 194 | select HIL_MLC |
diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index 700f61200df..6a8f622927f 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile | |||
@@ -15,4 +15,10 @@ obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o | |||
15 | obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o | 15 | obj-$(CONFIG_MOUSE_HIL) += hil_ptr.o |
16 | obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o | 16 | obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o |
17 | 17 | ||
18 | psmouse-objs := psmouse-base.o alps.o logips2pp.o synaptics.o lifebook.o trackpoint.o | 18 | psmouse-objs := psmouse-base.o synaptics.o |
19 | |||
20 | psmouse-$(CONFIG_MOUSE_PS2_ALPS) += alps.o | ||
21 | psmouse-$(CONFIG_MOUSE_PS2_LOGIPS2PP) += logips2pp.o | ||
22 | psmouse-$(CONFIG_MOUSE_PS2_LIFEBOOK) += lifebook.o | ||
23 | psmouse-$(CONFIG_MOUSE_PS2_TRACKPOINT) += trackpoint.o | ||
24 | psmouse-$(CONFIG_MOUSE_PS2_TOUCHKIT) += touchkit_ps2.o | ||
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 4e71a66fc7f..cf3e4664e72 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -424,14 +424,15 @@ int alps_init(struct psmouse *psmouse) | |||
424 | struct input_dev *dev1 = psmouse->dev, *dev2; | 424 | struct input_dev *dev1 = psmouse->dev, *dev2; |
425 | int version; | 425 | int version; |
426 | 426 | ||
427 | psmouse->private = priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); | 427 | priv = kzalloc(sizeof(struct alps_data), GFP_KERNEL); |
428 | dev2 = input_allocate_device(); | 428 | dev2 = input_allocate_device(); |
429 | if (!priv || !dev2) | 429 | if (!priv || !dev2) |
430 | goto init_fail; | 430 | goto init_fail; |
431 | 431 | ||
432 | priv->dev2 = dev2; | 432 | priv->dev2 = dev2; |
433 | 433 | ||
434 | if (!(priv->i = alps_get_model(psmouse, &version))) | 434 | priv->i = alps_get_model(psmouse, &version); |
435 | if (!priv->i) | ||
435 | goto init_fail; | 436 | goto init_fail; |
436 | 437 | ||
437 | if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) | 438 | if ((priv->i->flags & ALPS_PASS) && alps_passthrough_mode(psmouse, 1)) |
@@ -480,7 +481,8 @@ int alps_init(struct psmouse *psmouse) | |||
480 | dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y); | 481 | dev2->relbit[LONG(REL_X)] |= BIT(REL_X) | BIT(REL_Y); |
481 | dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); | 482 | dev2->keybit[LONG(BTN_LEFT)] |= BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); |
482 | 483 | ||
483 | input_register_device(priv->dev2); | 484 | if (input_register_device(priv->dev2)) |
485 | goto init_fail; | ||
484 | 486 | ||
485 | psmouse->protocol_handler = alps_process_byte; | 487 | psmouse->protocol_handler = alps_process_byte; |
486 | psmouse->poll = alps_poll; | 488 | psmouse->poll = alps_poll; |
@@ -491,9 +493,11 @@ int alps_init(struct psmouse *psmouse) | |||
491 | /* We are having trouble resyncing ALPS touchpads so disable it for now */ | 493 | /* We are having trouble resyncing ALPS touchpads so disable it for now */ |
492 | psmouse->resync_time = 0; | 494 | psmouse->resync_time = 0; |
493 | 495 | ||
496 | psmouse->private = priv; | ||
494 | return 0; | 497 | return 0; |
495 | 498 | ||
496 | init_fail: | 499 | init_fail: |
500 | psmouse_reset(psmouse); | ||
497 | input_free_device(dev2); | 501 | input_free_device(dev2); |
498 | kfree(priv); | 502 | kfree(priv); |
499 | return -1; | 503 | return -1; |
@@ -504,7 +508,8 @@ int alps_detect(struct psmouse *psmouse, int set_properties) | |||
504 | int version; | 508 | int version; |
505 | const struct alps_model_info *model; | 509 | const struct alps_model_info *model; |
506 | 510 | ||
507 | if (!(model = alps_get_model(psmouse, &version))) | 511 | model = alps_get_model(psmouse, &version); |
512 | if (!model) | ||
508 | return -1; | 513 | return -1; |
509 | 514 | ||
510 | if (set_properties) { | 515 | if (set_properties) { |
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index 69db7325a49..4bbddc99962 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h | |||
@@ -12,9 +12,6 @@ | |||
12 | #ifndef _ALPS_H | 12 | #ifndef _ALPS_H |
13 | #define _ALPS_H | 13 | #define _ALPS_H |
14 | 14 | ||
15 | int alps_detect(struct psmouse *psmouse, int set_properties); | ||
16 | int alps_init(struct psmouse *psmouse); | ||
17 | |||
18 | struct alps_model_info { | 15 | struct alps_model_info { |
19 | unsigned char signature[3]; | 16 | unsigned char signature[3]; |
20 | unsigned char byte0, mask0; | 17 | unsigned char byte0, mask0; |
@@ -23,10 +20,23 @@ struct alps_model_info { | |||
23 | 20 | ||
24 | struct alps_data { | 21 | struct alps_data { |
25 | struct input_dev *dev2; /* Relative device */ | 22 | struct input_dev *dev2; /* Relative device */ |
26 | char name[32]; /* Name */ | ||
27 | char phys[32]; /* Phys */ | 23 | char phys[32]; /* Phys */ |
28 | const struct alps_model_info *i;/* Info */ | 24 | const struct alps_model_info *i;/* Info */ |
29 | int prev_fin; /* Finger bit from previous packet */ | 25 | int prev_fin; /* Finger bit from previous packet */ |
30 | }; | 26 | }; |
31 | 27 | ||
28 | #ifdef CONFIG_MOUSE_PS2_ALPS | ||
29 | int alps_detect(struct psmouse *psmouse, int set_properties); | ||
30 | int alps_init(struct psmouse *psmouse); | ||
31 | #else | ||
32 | inline int alps_detect(struct psmouse *psmouse, int set_properties) | ||
33 | { | ||
34 | return -ENOSYS; | ||
35 | } | ||
36 | inline int alps_init(struct psmouse *psmouse) | ||
37 | { | ||
38 | return -ENOSYS; | ||
39 | } | ||
40 | #endif /* CONFIG_MOUSE_PS2_ALPS */ | ||
41 | |||
32 | #endif | 42 | #endif |
diff --git a/drivers/input/mouse/hil_ptr.c b/drivers/input/mouse/hil_ptr.c index bfb174fe323..449bf4dcbbc 100644 --- a/drivers/input/mouse/hil_ptr.c +++ b/drivers/input/mouse/hil_ptr.c | |||
@@ -88,10 +88,12 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) | |||
88 | idx = ptr->idx4/4; | 88 | idx = ptr->idx4/4; |
89 | p = data[idx - 1]; | 89 | p = data[idx - 1]; |
90 | 90 | ||
91 | if ((p & ~HIL_CMDCT_POL) == | 91 | if ((p & ~HIL_CMDCT_POL) == |
92 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) goto report; | 92 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL)) |
93 | if ((p & ~HIL_CMDCT_RPL) == | 93 | goto report; |
94 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) goto report; | 94 | if ((p & ~HIL_CMDCT_RPL) == |
95 | (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL)) | ||
96 | goto report; | ||
95 | 97 | ||
96 | /* Not a poll response. See if we are loading config records. */ | 98 | /* Not a poll response. See if we are loading config records. */ |
97 | switch (p & HIL_PKT_DATA_MASK) { | 99 | switch (p & HIL_PKT_DATA_MASK) { |
@@ -101,27 +103,32 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) | |||
101 | for (; i < HIL_PTR_MAX_LENGTH; i++) | 103 | for (; i < HIL_PTR_MAX_LENGTH; i++) |
102 | ptr->idd[i] = 0; | 104 | ptr->idd[i] = 0; |
103 | break; | 105 | break; |
106 | |||
104 | case HIL_CMD_RSC: | 107 | case HIL_CMD_RSC: |
105 | for (i = 0; i < idx; i++) | 108 | for (i = 0; i < idx; i++) |
106 | ptr->rsc[i] = ptr->data[i] & HIL_PKT_DATA_MASK; | 109 | ptr->rsc[i] = ptr->data[i] & HIL_PKT_DATA_MASK; |
107 | for (; i < HIL_PTR_MAX_LENGTH; i++) | 110 | for (; i < HIL_PTR_MAX_LENGTH; i++) |
108 | ptr->rsc[i] = 0; | 111 | ptr->rsc[i] = 0; |
109 | break; | 112 | break; |
113 | |||
110 | case HIL_CMD_EXD: | 114 | case HIL_CMD_EXD: |
111 | for (i = 0; i < idx; i++) | 115 | for (i = 0; i < idx; i++) |
112 | ptr->exd[i] = ptr->data[i] & HIL_PKT_DATA_MASK; | 116 | ptr->exd[i] = ptr->data[i] & HIL_PKT_DATA_MASK; |
113 | for (; i < HIL_PTR_MAX_LENGTH; i++) | 117 | for (; i < HIL_PTR_MAX_LENGTH; i++) |
114 | ptr->exd[i] = 0; | 118 | ptr->exd[i] = 0; |
115 | break; | 119 | break; |
120 | |||
116 | case HIL_CMD_RNM: | 121 | case HIL_CMD_RNM: |
117 | for (i = 0; i < idx; i++) | 122 | for (i = 0; i < idx; i++) |
118 | ptr->rnm[i] = ptr->data[i] & HIL_PKT_DATA_MASK; | 123 | ptr->rnm[i] = ptr->data[i] & HIL_PKT_DATA_MASK; |
119 | for (; i < HIL_PTR_MAX_LENGTH + 1; i++) | 124 | for (; i < HIL_PTR_MAX_LENGTH + 1; i++) |
120 | ptr->rnm[i] = '\0'; | 125 | ptr->rnm[i] = 0; |
121 | break; | 126 | break; |
127 | |||
122 | default: | 128 | default: |
123 | /* These occur when device isn't present */ | 129 | /* These occur when device isn't present */ |
124 | if (p == (HIL_ERR_INT | HIL_PKT_CMD)) break; | 130 | if (p == (HIL_ERR_INT | HIL_PKT_CMD)) |
131 | break; | ||
125 | /* Anything else we'd like to know about. */ | 132 | /* Anything else we'd like to know about. */ |
126 | printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); | 133 | printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p); |
127 | break; | 134 | break; |
@@ -130,7 +137,8 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) | |||
130 | 137 | ||
131 | report: | 138 | report: |
132 | if ((p & HIL_CMDCT_POL) != idx - 1) { | 139 | if ((p & HIL_CMDCT_POL) != idx - 1) { |
133 | printk(KERN_WARNING PREFIX "Malformed poll packet %x (idx = %i)\n", p, idx); | 140 | printk(KERN_WARNING PREFIX |
141 | "Malformed poll packet %x (idx = %i)\n", p, idx); | ||
134 | goto out; | 142 | goto out; |
135 | } | 143 | } |
136 | 144 | ||
@@ -139,7 +147,7 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) | |||
139 | laxis += i; | 147 | laxis += i; |
140 | 148 | ||
141 | ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */ | 149 | ax16 = ptr->idd[1] & HIL_IDD_HEADER_16BIT; /* 8 or 16bit resolution */ |
142 | absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS; | 150 | absdev = ptr->idd[1] & HIL_IDD_HEADER_ABS; |
143 | 151 | ||
144 | for (cnt = 1; i < laxis; i++) { | 152 | for (cnt = 1; i < laxis; i++) { |
145 | unsigned int lo,hi,val; | 153 | unsigned int lo,hi,val; |
@@ -157,7 +165,8 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) | |||
157 | input_report_abs(dev, ABS_X + i, val); | 165 | input_report_abs(dev, ABS_X + i, val); |
158 | } else { | 166 | } else { |
159 | val = (int) (((int8_t)lo) | ((int8_t)hi<<8)); | 167 | val = (int) (((int8_t)lo) | ((int8_t)hi<<8)); |
160 | if (i%3) val *= -1; | 168 | if (i%3) |
169 | val *= -1; | ||
161 | input_report_rel(dev, REL_X + i, val); | 170 | input_report_rel(dev, REL_X + i, val); |
162 | } | 171 | } |
163 | } | 172 | } |
@@ -168,10 +177,11 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) | |||
168 | btn = ptr->data[cnt++]; | 177 | btn = ptr->data[cnt++]; |
169 | up = btn & 1; | 178 | up = btn & 1; |
170 | btn &= 0xfe; | 179 | btn &= 0xfe; |
171 | if (btn == 0x8e) { | 180 | if (btn == 0x8e) |
172 | continue; /* TODO: proximity == touch? */ | 181 | continue; /* TODO: proximity == touch? */ |
173 | } | 182 | else |
174 | else if ((btn > 0x8c) || (btn < 0x80)) continue; | 183 | if ((btn > 0x8c) || (btn < 0x80)) |
184 | continue; | ||
175 | btn = (btn - 0x80) >> 1; | 185 | btn = (btn - 0x80) >> 1; |
176 | btn = ptr->btnmap[btn]; | 186 | btn = ptr->btnmap[btn]; |
177 | input_report_key(dev, btn, !up); | 187 | input_report_key(dev, btn, !up); |
@@ -182,14 +192,14 @@ static void hil_ptr_process_record(struct hil_ptr *ptr) | |||
182 | up(&ptr->sem); | 192 | up(&ptr->sem); |
183 | } | 193 | } |
184 | 194 | ||
185 | static void hil_ptr_process_err(struct hil_ptr *ptr) { | 195 | static void hil_ptr_process_err(struct hil_ptr *ptr) |
196 | { | ||
186 | printk(KERN_WARNING PREFIX "errored HIL packet\n"); | 197 | printk(KERN_WARNING PREFIX "errored HIL packet\n"); |
187 | ptr->idx4 = 0; | 198 | ptr->idx4 = 0; |
188 | up(&ptr->sem); | 199 | up(&ptr->sem); |
189 | return; | ||
190 | } | 200 | } |
191 | 201 | ||
192 | static irqreturn_t hil_ptr_interrupt(struct serio *serio, | 202 | static irqreturn_t hil_ptr_interrupt(struct serio *serio, |
193 | unsigned char data, unsigned int flags) | 203 | unsigned char data, unsigned int flags) |
194 | { | 204 | { |
195 | struct hil_ptr *ptr; | 205 | struct hil_ptr *ptr; |
@@ -197,29 +207,29 @@ static irqreturn_t hil_ptr_interrupt(struct serio *serio, | |||
197 | int idx; | 207 | int idx; |
198 | 208 | ||
199 | ptr = serio_get_drvdata(serio); | 209 | ptr = serio_get_drvdata(serio); |
200 | if (ptr == NULL) { | 210 | BUG_ON(ptr == NULL); |
201 | BUG(); | ||
202 | return IRQ_HANDLED; | ||
203 | } | ||
204 | 211 | ||
205 | if (ptr->idx4 >= (HIL_PTR_MAX_LENGTH * sizeof(hil_packet))) { | 212 | if (ptr->idx4 >= (HIL_PTR_MAX_LENGTH * sizeof(hil_packet))) { |
206 | hil_ptr_process_err(ptr); | 213 | hil_ptr_process_err(ptr); |
207 | return IRQ_HANDLED; | 214 | return IRQ_HANDLED; |
208 | } | 215 | } |
209 | idx = ptr->idx4/4; | 216 | idx = ptr->idx4/4; |
210 | if (!(ptr->idx4 % 4)) ptr->data[idx] = 0; | 217 | if (!(ptr->idx4 % 4)) |
218 | ptr->data[idx] = 0; | ||
211 | packet = ptr->data[idx]; | 219 | packet = ptr->data[idx]; |
212 | packet |= ((hil_packet)data) << ((3 - (ptr->idx4 % 4)) * 8); | 220 | packet |= ((hil_packet)data) << ((3 - (ptr->idx4 % 4)) * 8); |
213 | ptr->data[idx] = packet; | 221 | ptr->data[idx] = packet; |
214 | 222 | ||
215 | /* Records of N 4-byte hil_packets must terminate with a command. */ | 223 | /* Records of N 4-byte hil_packets must terminate with a command. */ |
216 | if ((++(ptr->idx4)) % 4) return IRQ_HANDLED; | 224 | if ((++(ptr->idx4)) % 4) |
225 | return IRQ_HANDLED; | ||
217 | if ((packet & 0xffff0000) != HIL_ERR_INT) { | 226 | if ((packet & 0xffff0000) != HIL_ERR_INT) { |
218 | hil_ptr_process_err(ptr); | 227 | hil_ptr_process_err(ptr); |
219 | return IRQ_HANDLED; | 228 | return IRQ_HANDLED; |
220 | } | 229 | } |
221 | if (packet & HIL_PKT_CMD) | 230 | if (packet & HIL_PKT_CMD) |
222 | hil_ptr_process_record(ptr); | 231 | hil_ptr_process_record(ptr); |
232 | |||
223 | return IRQ_HANDLED; | 233 | return IRQ_HANDLED; |
224 | } | 234 | } |
225 | 235 | ||
@@ -228,10 +238,7 @@ static void hil_ptr_disconnect(struct serio *serio) | |||
228 | struct hil_ptr *ptr; | 238 | struct hil_ptr *ptr; |
229 | 239 | ||
230 | ptr = serio_get_drvdata(serio); | 240 | ptr = serio_get_drvdata(serio); |
231 | if (ptr == NULL) { | 241 | BUG_ON(ptr == NULL); |
232 | BUG(); | ||
233 | return; | ||
234 | } | ||
235 | 242 | ||
236 | serio_close(serio); | 243 | serio_close(serio); |
237 | input_unregister_device(ptr->dev); | 244 | input_unregister_device(ptr->dev); |
@@ -241,7 +248,7 @@ static void hil_ptr_disconnect(struct serio *serio) | |||
241 | static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | 248 | static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) |
242 | { | 249 | { |
243 | struct hil_ptr *ptr; | 250 | struct hil_ptr *ptr; |
244 | char *txt; | 251 | const char *txt; |
245 | unsigned int i, naxsets, btntype; | 252 | unsigned int i, naxsets, btntype; |
246 | uint8_t did, *idd; | 253 | uint8_t did, *idd; |
247 | 254 | ||
@@ -252,42 +259,40 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | |||
252 | if (!ptr->dev) | 259 | if (!ptr->dev) |
253 | goto bail0; | 260 | goto bail0; |
254 | 261 | ||
255 | ptr->dev->private = ptr; | ||
256 | |||
257 | if (serio_open(serio, driver)) | 262 | if (serio_open(serio, driver)) |
258 | goto bail1; | 263 | goto bail1; |
259 | 264 | ||
260 | serio_set_drvdata(serio, ptr); | 265 | serio_set_drvdata(serio, ptr); |
261 | ptr->serio = serio; | 266 | ptr->serio = serio; |
262 | 267 | ||
263 | init_MUTEX_LOCKED(&(ptr->sem)); | 268 | init_MUTEX_LOCKED(&ptr->sem); |
264 | 269 | ||
265 | /* Get device info. MLC driver supplies devid/status/etc. */ | 270 | /* Get device info. MLC driver supplies devid/status/etc. */ |
266 | serio->write(serio, 0); | 271 | serio->write(serio, 0); |
267 | serio->write(serio, 0); | 272 | serio->write(serio, 0); |
268 | serio->write(serio, HIL_PKT_CMD >> 8); | 273 | serio->write(serio, HIL_PKT_CMD >> 8); |
269 | serio->write(serio, HIL_CMD_IDD); | 274 | serio->write(serio, HIL_CMD_IDD); |
270 | down(&(ptr->sem)); | 275 | down(&ptr->sem); |
271 | 276 | ||
272 | serio->write(serio, 0); | 277 | serio->write(serio, 0); |
273 | serio->write(serio, 0); | 278 | serio->write(serio, 0); |
274 | serio->write(serio, HIL_PKT_CMD >> 8); | 279 | serio->write(serio, HIL_PKT_CMD >> 8); |
275 | serio->write(serio, HIL_CMD_RSC); | 280 | serio->write(serio, HIL_CMD_RSC); |
276 | down(&(ptr->sem)); | 281 | down(&ptr->sem); |
277 | 282 | ||
278 | serio->write(serio, 0); | 283 | serio->write(serio, 0); |
279 | serio->write(serio, 0); | 284 | serio->write(serio, 0); |
280 | serio->write(serio, HIL_PKT_CMD >> 8); | 285 | serio->write(serio, HIL_PKT_CMD >> 8); |
281 | serio->write(serio, HIL_CMD_RNM); | 286 | serio->write(serio, HIL_CMD_RNM); |
282 | down(&(ptr->sem)); | 287 | down(&ptr->sem); |
283 | 288 | ||
284 | serio->write(serio, 0); | 289 | serio->write(serio, 0); |
285 | serio->write(serio, 0); | 290 | serio->write(serio, 0); |
286 | serio->write(serio, HIL_PKT_CMD >> 8); | 291 | serio->write(serio, HIL_PKT_CMD >> 8); |
287 | serio->write(serio, HIL_CMD_EXD); | 292 | serio->write(serio, HIL_CMD_EXD); |
288 | down(&(ptr->sem)); | 293 | down(&ptr->sem); |
289 | 294 | ||
290 | up(&(ptr->sem)); | 295 | up(&ptr->sem); |
291 | 296 | ||
292 | did = ptr->idd[0]; | 297 | did = ptr->idd[0]; |
293 | idd = ptr->idd + 1; | 298 | idd = ptr->idd + 1; |
@@ -301,12 +306,12 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | |||
301 | ptr->dev->evbit[0] = BIT(EV_ABS); | 306 | ptr->dev->evbit[0] = BIT(EV_ABS); |
302 | txt = "absolute"; | 307 | txt = "absolute"; |
303 | } | 308 | } |
304 | if (!ptr->dev->evbit[0]) { | 309 | if (!ptr->dev->evbit[0]) |
305 | goto bail2; | 310 | goto bail2; |
306 | } | ||
307 | 311 | ||
308 | ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd); | 312 | ptr->nbtn = HIL_IDD_NUM_BUTTONS(idd); |
309 | if (ptr->nbtn) ptr->dev->evbit[0] |= BIT(EV_KEY); | 313 | if (ptr->nbtn) |
314 | ptr->dev->evbit[0] |= BIT(EV_KEY); | ||
310 | 315 | ||
311 | naxsets = HIL_IDD_NUM_AXSETS(*idd); | 316 | naxsets = HIL_IDD_NUM_AXSETS(*idd); |
312 | ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd); | 317 | ptr->naxes = HIL_IDD_NUM_AXES_PER_SET(*idd); |
@@ -315,7 +320,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | |||
315 | did, txt); | 320 | did, txt); |
316 | printk(KERN_INFO PREFIX "HIL pointer has %i buttons and %i sets of %i axes\n", | 321 | printk(KERN_INFO PREFIX "HIL pointer has %i buttons and %i sets of %i axes\n", |
317 | ptr->nbtn, naxsets, ptr->naxes); | 322 | ptr->nbtn, naxsets, ptr->naxes); |
318 | 323 | ||
319 | btntype = BTN_MISC; | 324 | btntype = BTN_MISC; |
320 | if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET) | 325 | if ((did & HIL_IDD_DID_ABS_TABLET_MASK) == HIL_IDD_DID_ABS_TABLET) |
321 | #ifdef TABLET_SIMULATES_MOUSE | 326 | #ifdef TABLET_SIMULATES_MOUSE |
@@ -325,7 +330,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | |||
325 | #endif | 330 | #endif |
326 | if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN) | 331 | if ((did & HIL_IDD_DID_ABS_TSCREEN_MASK) == HIL_IDD_DID_ABS_TSCREEN) |
327 | btntype = BTN_TOUCH; | 332 | btntype = BTN_TOUCH; |
328 | 333 | ||
329 | if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE) | 334 | if ((did & HIL_IDD_DID_REL_MOUSE_MASK) == HIL_IDD_DID_REL_MOUSE) |
330 | btntype = BTN_MOUSE; | 335 | btntype = BTN_MOUSE; |
331 | 336 | ||
@@ -341,12 +346,10 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | |||
341 | } | 346 | } |
342 | 347 | ||
343 | if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { | 348 | if ((did & HIL_IDD_DID_TYPE_MASK) == HIL_IDD_DID_TYPE_REL) { |
344 | for (i = 0; i < ptr->naxes; i++) { | 349 | for (i = 0; i < ptr->naxes; i++) |
345 | set_bit(REL_X + i, ptr->dev->relbit); | 350 | set_bit(REL_X + i, ptr->dev->relbit); |
346 | } | 351 | for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) |
347 | for (i = 3; (i < ptr->naxes + 3) && (naxsets > 1); i++) { | ||
348 | set_bit(REL_X + i, ptr->dev->relbit); | 352 | set_bit(REL_X + i, ptr->dev->relbit); |
349 | } | ||
350 | } else { | 353 | } else { |
351 | for (i = 0; i < ptr->naxes; i++) { | 354 | for (i = 0; i < ptr->naxes; i++) { |
352 | set_bit(ABS_X + i, ptr->dev->absbit); | 355 | set_bit(ABS_X + i, ptr->dev->absbit); |
@@ -375,7 +378,7 @@ static int hil_ptr_connect(struct serio *serio, struct serio_driver *driver) | |||
375 | ptr->dev->id.vendor = PCI_VENDOR_ID_HP; | 378 | ptr->dev->id.vendor = PCI_VENDOR_ID_HP; |
376 | ptr->dev->id.product = 0x0001; /* TODO: get from ptr->rsc */ | 379 | ptr->dev->id.product = 0x0001; /* TODO: get from ptr->rsc */ |
377 | ptr->dev->id.version = 0x0100; /* TODO: get from ptr->rsc */ | 380 | ptr->dev->id.version = 0x0100; /* TODO: get from ptr->rsc */ |
378 | ptr->dev->cdev.dev = &serio->dev; | 381 | ptr->dev->dev.parent = &serio->dev; |
379 | 382 | ||
380 | input_register_device(ptr->dev); | 383 | input_register_device(ptr->dev); |
381 | printk(KERN_INFO "input: %s (%s), ID: %d\n", | 384 | printk(KERN_INFO "input: %s (%s), ID: %d\n", |
@@ -419,11 +422,11 @@ static int __init hil_ptr_init(void) | |||
419 | { | 422 | { |
420 | return serio_register_driver(&hil_ptr_serio_driver); | 423 | return serio_register_driver(&hil_ptr_serio_driver); |
421 | } | 424 | } |
422 | 425 | ||
423 | static void __exit hil_ptr_exit(void) | 426 | static void __exit hil_ptr_exit(void) |
424 | { | 427 | { |
425 | serio_unregister_driver(&hil_ptr_serio_driver); | 428 | serio_unregister_driver(&hil_ptr_serio_driver); |
426 | } | 429 | } |
427 | 430 | ||
428 | module_init(hil_ptr_init); | 431 | module_init(hil_ptr_init); |
429 | module_exit(hil_ptr_exit); | 432 | module_exit(hil_ptr_exit); |
diff --git a/drivers/input/mouse/lifebook.c b/drivers/input/mouse/lifebook.c index 29542f0631c..1740cadd959 100644 --- a/drivers/input/mouse/lifebook.c +++ b/drivers/input/mouse/lifebook.c | |||
@@ -20,6 +20,27 @@ | |||
20 | #include "psmouse.h" | 20 | #include "psmouse.h" |
21 | #include "lifebook.h" | 21 | #include "lifebook.h" |
22 | 22 | ||
23 | struct lifebook_data { | ||
24 | struct input_dev *dev2; /* Relative device */ | ||
25 | char phys[32]; | ||
26 | }; | ||
27 | |||
28 | static const char *desired_serio_phys; | ||
29 | |||
30 | static int lifebook_set_serio_phys(struct dmi_system_id *d) | ||
31 | { | ||
32 | desired_serio_phys = d->driver_data; | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | static unsigned char lifebook_use_6byte_proto; | ||
37 | |||
38 | static int lifebook_set_6byte_proto(struct dmi_system_id *d) | ||
39 | { | ||
40 | lifebook_use_6byte_proto = 1; | ||
41 | return 0; | ||
42 | } | ||
43 | |||
23 | static struct dmi_system_id lifebook_dmi_table[] = { | 44 | static struct dmi_system_id lifebook_dmi_table[] = { |
24 | { | 45 | { |
25 | .ident = "FLORA-ie 55mi", | 46 | .ident = "FLORA-ie 55mi", |
@@ -56,6 +77,24 @@ static struct dmi_system_id lifebook_dmi_table[] = { | |||
56 | .matches = { | 77 | .matches = { |
57 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"), | 78 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-18"), |
58 | }, | 79 | }, |
80 | .callback = lifebook_set_serio_phys, | ||
81 | .driver_data = "isa0060/serio3", | ||
82 | }, | ||
83 | { | ||
84 | .ident = "Panasonic CF-28", | ||
85 | .matches = { | ||
86 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), | ||
87 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-28"), | ||
88 | }, | ||
89 | .callback = lifebook_set_6byte_proto, | ||
90 | }, | ||
91 | { | ||
92 | .ident = "Panasonic CF-29", | ||
93 | .matches = { | ||
94 | DMI_MATCH(DMI_SYS_VENDOR, "Matsushita"), | ||
95 | DMI_MATCH(DMI_PRODUCT_NAME, "CF-29"), | ||
96 | }, | ||
97 | .callback = lifebook_set_6byte_proto, | ||
59 | }, | 98 | }, |
60 | { | 99 | { |
61 | .ident = "Lifebook B142", | 100 | .ident = "Lifebook B142", |
@@ -68,30 +107,70 @@ static struct dmi_system_id lifebook_dmi_table[] = { | |||
68 | 107 | ||
69 | static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) | 108 | static psmouse_ret_t lifebook_process_byte(struct psmouse *psmouse) |
70 | { | 109 | { |
110 | struct lifebook_data *priv = psmouse->private; | ||
111 | struct input_dev *dev1 = psmouse->dev; | ||
112 | struct input_dev *dev2 = priv->dev2; | ||
71 | unsigned char *packet = psmouse->packet; | 113 | unsigned char *packet = psmouse->packet; |
72 | struct input_dev *dev = psmouse->dev; | 114 | int relative_packet = packet[0] & 0x08; |
73 | 115 | ||
74 | if (psmouse->pktcnt != 3) | 116 | if (relative_packet || !lifebook_use_6byte_proto) { |
75 | return PSMOUSE_GOOD_DATA; | 117 | if (psmouse->pktcnt != 3) |
118 | return PSMOUSE_GOOD_DATA; | ||
119 | } else { | ||
120 | switch (psmouse->pktcnt) { | ||
121 | case 1: | ||
122 | return (packet[0] & 0xf8) == 0x00 ? | ||
123 | PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; | ||
124 | case 2: | ||
125 | return PSMOUSE_GOOD_DATA; | ||
126 | case 3: | ||
127 | return ((packet[2] & 0x30) << 2) == (packet[2] & 0xc0) ? | ||
128 | PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; | ||
129 | case 4: | ||
130 | return (packet[3] & 0xf8) == 0xc0 ? | ||
131 | PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; | ||
132 | case 5: | ||
133 | return (packet[4] & 0xc0) == (packet[2] & 0xc0) ? | ||
134 | PSMOUSE_GOOD_DATA : PSMOUSE_BAD_DATA; | ||
135 | case 6: | ||
136 | if (((packet[5] & 0x30) << 2) != (packet[5] & 0xc0)) | ||
137 | return PSMOUSE_BAD_DATA; | ||
138 | if ((packet[5] & 0xc0) != (packet[1] & 0xc0)) | ||
139 | return PSMOUSE_BAD_DATA; | ||
140 | break; /* report data */ | ||
141 | } | ||
142 | } | ||
76 | 143 | ||
77 | /* calculate X and Y */ | 144 | if (relative_packet) { |
78 | if ((packet[0] & 0x08) == 0x00) { | 145 | if (!dev2) |
79 | input_report_abs(dev, ABS_X, | 146 | printk(KERN_WARNING "lifebook.c: got relative packet " |
147 | "but no relative device set up\n"); | ||
148 | } else if (lifebook_use_6byte_proto) { | ||
149 | input_report_abs(dev1, ABS_X, | ||
150 | ((packet[1] & 0x3f) << 6) | (packet[2] & 0x3f)); | ||
151 | input_report_abs(dev1, ABS_Y, | ||
152 | 4096 - (((packet[4] & 0x3f) << 6) | (packet[5] & 0x3f))); | ||
153 | } else { | ||
154 | input_report_abs(dev1, ABS_X, | ||
80 | (packet[1] | ((packet[0] & 0x30) << 4))); | 155 | (packet[1] | ((packet[0] & 0x30) << 4))); |
81 | input_report_abs(dev, ABS_Y, | 156 | input_report_abs(dev1, ABS_Y, |
82 | 1024 - (packet[2] | ((packet[0] & 0xC0) << 2))); | 157 | 1024 - (packet[2] | ((packet[0] & 0xC0) << 2))); |
83 | } else { | ||
84 | input_report_rel(dev, REL_X, | ||
85 | ((packet[0] & 0x10) ? packet[1] - 256 : packet[1])); | ||
86 | input_report_rel(dev, REL_Y, | ||
87 | -(int)((packet[0] & 0x20) ? packet[2] - 256 : packet[2])); | ||
88 | } | 158 | } |
89 | 159 | ||
90 | input_report_key(dev, BTN_LEFT, packet[0] & 0x01); | 160 | input_report_key(dev1, BTN_TOUCH, packet[0] & 0x04); |
91 | input_report_key(dev, BTN_RIGHT, packet[0] & 0x02); | 161 | input_sync(dev1); |
92 | input_report_key(dev, BTN_TOUCH, packet[0] & 0x04); | ||
93 | 162 | ||
94 | input_sync(dev); | 163 | if (dev2) { |
164 | if (relative_packet) { | ||
165 | input_report_rel(dev2, REL_X, | ||
166 | ((packet[0] & 0x10) ? packet[1] - 256 : packet[1])); | ||
167 | input_report_rel(dev2, REL_Y, | ||
168 | -(int)((packet[0] & 0x20) ? packet[2] - 256 : packet[2])); | ||
169 | } | ||
170 | input_report_key(dev2, BTN_LEFT, packet[0] & 0x01); | ||
171 | input_report_key(dev2, BTN_RIGHT, packet[0] & 0x02); | ||
172 | input_sync(dev2); | ||
173 | } | ||
95 | 174 | ||
96 | return PSMOUSE_FULL_PACKET; | 175 | return PSMOUSE_FULL_PACKET; |
97 | } | 176 | } |
@@ -109,12 +188,20 @@ static int lifebook_absolute_mode(struct psmouse *psmouse) | |||
109 | you leave this call out the touchsreen will never send | 188 | you leave this call out the touchsreen will never send |
110 | absolute coordinates | 189 | absolute coordinates |
111 | */ | 190 | */ |
112 | param = 0x07; | 191 | param = lifebook_use_6byte_proto ? 0x08 : 0x07; |
113 | ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); | 192 | ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); |
114 | 193 | ||
115 | return 0; | 194 | return 0; |
116 | } | 195 | } |
117 | 196 | ||
197 | static void lifebook_relative_mode(struct psmouse *psmouse) | ||
198 | { | ||
199 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
200 | unsigned char param = 0x06; | ||
201 | |||
202 | ps2_command(ps2dev, ¶m, PSMOUSE_CMD_SETRES); | ||
203 | } | ||
204 | |||
118 | static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolution) | 205 | static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolution) |
119 | { | 206 | { |
120 | static const unsigned char params[] = { 0, 1, 2, 2, 3 }; | 207 | static const unsigned char params[] = { 0, 1, 2, 2, 3 }; |
@@ -131,6 +218,8 @@ static void lifebook_set_resolution(struct psmouse *psmouse, unsigned int resolu | |||
131 | static void lifebook_disconnect(struct psmouse *psmouse) | 218 | static void lifebook_disconnect(struct psmouse *psmouse) |
132 | { | 219 | { |
133 | psmouse_reset(psmouse); | 220 | psmouse_reset(psmouse); |
221 | kfree(psmouse->private); | ||
222 | psmouse->private = NULL; | ||
134 | } | 223 | } |
135 | 224 | ||
136 | int lifebook_detect(struct psmouse *psmouse, int set_properties) | 225 | int lifebook_detect(struct psmouse *psmouse, int set_properties) |
@@ -138,6 +227,10 @@ int lifebook_detect(struct psmouse *psmouse, int set_properties) | |||
138 | if (!dmi_check_system(lifebook_dmi_table)) | 227 | if (!dmi_check_system(lifebook_dmi_table)) |
139 | return -1; | 228 | return -1; |
140 | 229 | ||
230 | if (desired_serio_phys && | ||
231 | strcmp(psmouse->ps2dev.serio->phys, desired_serio_phys)) | ||
232 | return -1; | ||
233 | |||
141 | if (set_properties) { | 234 | if (set_properties) { |
142 | psmouse->vendor = "Fujitsu"; | 235 | psmouse->vendor = "Fujitsu"; |
143 | psmouse->name = "Lifebook TouchScreen"; | 236 | psmouse->name = "Lifebook TouchScreen"; |
@@ -146,24 +239,78 @@ int lifebook_detect(struct psmouse *psmouse, int set_properties) | |||
146 | return 0; | 239 | return 0; |
147 | } | 240 | } |
148 | 241 | ||
242 | static int lifebook_create_relative_device(struct psmouse *psmouse) | ||
243 | { | ||
244 | struct input_dev *dev2; | ||
245 | struct lifebook_data *priv; | ||
246 | int error = -ENOMEM; | ||
247 | |||
248 | priv = kzalloc(sizeof(struct lifebook_data), GFP_KERNEL); | ||
249 | dev2 = input_allocate_device(); | ||
250 | if (!priv || !dev2) | ||
251 | goto err_out; | ||
252 | |||
253 | priv->dev2 = dev2; | ||
254 | snprintf(priv->phys, sizeof(priv->phys), | ||
255 | "%s/input1", psmouse->ps2dev.serio->phys); | ||
256 | |||
257 | dev2->phys = priv->phys; | ||
258 | dev2->name = "PS/2 Touchpad"; | ||
259 | dev2->id.bustype = BUS_I8042; | ||
260 | dev2->id.vendor = 0x0002; | ||
261 | dev2->id.product = PSMOUSE_LIFEBOOK; | ||
262 | dev2->id.version = 0x0000; | ||
263 | dev2->dev.parent = &psmouse->ps2dev.serio->dev; | ||
264 | |||
265 | dev2->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); | ||
266 | dev2->relbit[LONG(REL_X)] = BIT(REL_X) | BIT(REL_Y); | ||
267 | dev2->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); | ||
268 | |||
269 | error = input_register_device(priv->dev2); | ||
270 | if (error) | ||
271 | goto err_out; | ||
272 | |||
273 | psmouse->private = priv; | ||
274 | return 0; | ||
275 | |||
276 | err_out: | ||
277 | input_free_device(dev2); | ||
278 | kfree(priv); | ||
279 | return error; | ||
280 | } | ||
281 | |||
149 | int lifebook_init(struct psmouse *psmouse) | 282 | int lifebook_init(struct psmouse *psmouse) |
150 | { | 283 | { |
151 | struct input_dev *input_dev = psmouse->dev; | 284 | struct input_dev *dev1 = psmouse->dev; |
285 | int max_coord = lifebook_use_6byte_proto ? 1024 : 4096; | ||
152 | 286 | ||
153 | if (lifebook_absolute_mode(psmouse)) | 287 | if (lifebook_absolute_mode(psmouse)) |
154 | return -1; | 288 | return -1; |
155 | 289 | ||
156 | input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY) | BIT(EV_REL); | 290 | dev1->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY); |
157 | input_dev->keybit[LONG(BTN_LEFT)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); | 291 | dev1->relbit[0] = 0; |
158 | input_dev->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); | 292 | dev1->keybit[LONG(BTN_TOUCH)] = BIT(BTN_TOUCH); |
159 | input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); | 293 | input_set_abs_params(dev1, ABS_X, 0, max_coord, 0, 0); |
160 | input_set_abs_params(input_dev, ABS_X, 0, 1024, 0, 0); | 294 | input_set_abs_params(dev1, ABS_Y, 0, max_coord, 0, 0); |
161 | input_set_abs_params(input_dev, ABS_Y, 0, 1024, 0, 0); | 295 | |
296 | if (!desired_serio_phys) { | ||
297 | if (lifebook_create_relative_device(psmouse)) { | ||
298 | lifebook_relative_mode(psmouse); | ||
299 | return -1; | ||
300 | } | ||
301 | } | ||
162 | 302 | ||
163 | psmouse->protocol_handler = lifebook_process_byte; | 303 | psmouse->protocol_handler = lifebook_process_byte; |
164 | psmouse->set_resolution = lifebook_set_resolution; | 304 | psmouse->set_resolution = lifebook_set_resolution; |
165 | psmouse->disconnect = lifebook_disconnect; | 305 | psmouse->disconnect = lifebook_disconnect; |
166 | psmouse->reconnect = lifebook_absolute_mode; | 306 | psmouse->reconnect = lifebook_absolute_mode; |
307 | |||
308 | psmouse->model = lifebook_use_6byte_proto ? 6 : 3; | ||
309 | |||
310 | /* | ||
311 | * Use packet size = 3 even when using 6-byte protocol because | ||
312 | * that's what POLL will return on Lifebooks (according to spec). | ||
313 | */ | ||
167 | psmouse->pktsize = 3; | 314 | psmouse->pktsize = 3; |
168 | 315 | ||
169 | return 0; | 316 | return 0; |
diff --git a/drivers/input/mouse/lifebook.h b/drivers/input/mouse/lifebook.h index be1c0943825..c1647cf036c 100644 --- a/drivers/input/mouse/lifebook.h +++ b/drivers/input/mouse/lifebook.h | |||
@@ -11,7 +11,18 @@ | |||
11 | #ifndef _LIFEBOOK_H | 11 | #ifndef _LIFEBOOK_H |
12 | #define _LIFEBOOK_H | 12 | #define _LIFEBOOK_H |
13 | 13 | ||
14 | #ifdef CONFIG_MOUSE_PS2_LIFEBOOK | ||
14 | int lifebook_detect(struct psmouse *psmouse, int set_properties); | 15 | int lifebook_detect(struct psmouse *psmouse, int set_properties); |
15 | int lifebook_init(struct psmouse *psmouse); | 16 | int lifebook_init(struct psmouse *psmouse); |
17 | #else | ||
18 | inline int lifebook_detect(struct psmouse *psmouse, int set_properties) | ||
19 | { | ||
20 | return -ENOSYS; | ||
21 | } | ||
22 | inline int lifebook_init(struct psmouse *psmouse) | ||
23 | { | ||
24 | return -ENOSYS; | ||
25 | } | ||
26 | #endif | ||
16 | 27 | ||
17 | #endif | 28 | #endif |
diff --git a/drivers/input/mouse/logips2pp.c b/drivers/input/mouse/logips2pp.c index d3ddea26b8c..9df74b72e6c 100644 --- a/drivers/input/mouse/logips2pp.c +++ b/drivers/input/mouse/logips2pp.c | |||
@@ -200,6 +200,7 @@ static void ps2pp_disconnect(struct psmouse *psmouse) | |||
200 | static const struct ps2pp_info *get_model_info(unsigned char model) | 200 | static const struct ps2pp_info *get_model_info(unsigned char model) |
201 | { | 201 | { |
202 | static const struct ps2pp_info ps2pp_list[] = { | 202 | static const struct ps2pp_info ps2pp_list[] = { |
203 | { 1, 0, 0 }, /* Simple 2-button mouse */ | ||
203 | { 12, 0, PS2PP_SIDE_BTN}, | 204 | { 12, 0, PS2PP_SIDE_BTN}, |
204 | { 13, 0, 0 }, | 205 | { 13, 0, 0 }, |
205 | { 15, PS2PP_KIND_MX, /* MX1000 */ | 206 | { 15, PS2PP_KIND_MX, /* MX1000 */ |
@@ -338,12 +339,12 @@ int ps2pp_init(struct psmouse *psmouse, int set_properties) | |||
338 | param[1] = 0; | 339 | param[1] = 0; |
339 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); | 340 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); |
340 | 341 | ||
341 | if (!param[1]) | ||
342 | return -1; | ||
343 | |||
344 | model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78); | 342 | model = ((param[0] >> 4) & 0x07) | ((param[0] << 3) & 0x78); |
345 | buttons = param[1]; | 343 | buttons = param[1]; |
346 | 344 | ||
345 | if (!model || !buttons) | ||
346 | return -1; | ||
347 | |||
347 | if ((model_info = get_model_info(model)) != NULL) { | 348 | if ((model_info = get_model_info(model)) != NULL) { |
348 | 349 | ||
349 | /* | 350 | /* |
diff --git a/drivers/input/mouse/logips2pp.h b/drivers/input/mouse/logips2pp.h index 64a8ec52ea6..6e5712525fd 100644 --- a/drivers/input/mouse/logips2pp.h +++ b/drivers/input/mouse/logips2pp.h | |||
@@ -11,6 +11,13 @@ | |||
11 | #ifndef _LOGIPS2PP_H | 11 | #ifndef _LOGIPS2PP_H |
12 | #define _LOGIPS2PP_H | 12 | #define _LOGIPS2PP_H |
13 | 13 | ||
14 | #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP | ||
14 | int ps2pp_init(struct psmouse *psmouse, int set_properties); | 15 | int ps2pp_init(struct psmouse *psmouse, int set_properties); |
16 | #else | ||
17 | inline int ps2pp_init(struct psmouse *psmouse, int set_properties) | ||
18 | { | ||
19 | return -ENOSYS; | ||
20 | } | ||
21 | #endif /* CONFIG_MOUSE_PS2_LOGIPS2PP */ | ||
15 | 22 | ||
16 | #endif | 23 | #endif |
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c index 0fe5869d7d4..f15f695777f 100644 --- a/drivers/input/mouse/psmouse-base.c +++ b/drivers/input/mouse/psmouse-base.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "alps.h" | 28 | #include "alps.h" |
29 | #include "lifebook.h" | 29 | #include "lifebook.h" |
30 | #include "trackpoint.h" | 30 | #include "trackpoint.h" |
31 | #include "touchkit_ps2.h" | ||
31 | 32 | ||
32 | #define DRIVER_DESC "PS/2 mouse driver" | 33 | #define DRIVER_DESC "PS/2 mouse driver" |
33 | 34 | ||
@@ -569,7 +570,9 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
569 | return PSMOUSE_THINKPS; | 570 | return PSMOUSE_THINKPS; |
570 | 571 | ||
571 | /* | 572 | /* |
572 | * Try Synaptics TouchPad | 573 | * Try Synaptics TouchPad. Note that probing is done even if Synaptics protocol |
574 | * support is disabled in config - we need to know if it is synaptics so we | ||
575 | * can reset it properly after probing for intellimouse. | ||
573 | */ | 576 | */ |
574 | if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) { | 577 | if (max_proto > PSMOUSE_PS2 && synaptics_detect(psmouse, set_properties) == 0) { |
575 | synaptics_hardware = 1; | 578 | synaptics_hardware = 1; |
@@ -605,14 +608,20 @@ static int psmouse_extensions(struct psmouse *psmouse, | |||
605 | } | 608 | } |
606 | } | 609 | } |
607 | 610 | ||
608 | if (max_proto > PSMOUSE_IMEX && genius_detect(psmouse, set_properties) == 0) | 611 | if (max_proto > PSMOUSE_IMEX) { |
609 | return PSMOUSE_GENPS; | 612 | |
613 | if (genius_detect(psmouse, set_properties) == 0) | ||
614 | return PSMOUSE_GENPS; | ||
610 | 615 | ||
611 | if (max_proto > PSMOUSE_IMEX && ps2pp_init(psmouse, set_properties) == 0) | 616 | if (ps2pp_init(psmouse, set_properties) == 0) |
612 | return PSMOUSE_PS2PP; | 617 | return PSMOUSE_PS2PP; |
613 | 618 | ||
614 | if (max_proto > PSMOUSE_IMEX && trackpoint_detect(psmouse, set_properties) == 0) | 619 | if (trackpoint_detect(psmouse, set_properties) == 0) |
615 | return PSMOUSE_TRACKPOINT; | 620 | return PSMOUSE_TRACKPOINT; |
621 | |||
622 | if (touchkit_ps2_detect(psmouse, set_properties) == 0) | ||
623 | return PSMOUSE_TOUCHKIT_PS2; | ||
624 | } | ||
616 | 625 | ||
617 | /* | 626 | /* |
618 | * Reset to defaults in case the device got confused by extended | 627 | * Reset to defaults in case the device got confused by extended |
@@ -654,12 +663,14 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
654 | .maxproto = 1, | 663 | .maxproto = 1, |
655 | .detect = ps2bare_detect, | 664 | .detect = ps2bare_detect, |
656 | }, | 665 | }, |
666 | #ifdef CONFIG_MOUSE_PS2_LOGIPS2PP | ||
657 | { | 667 | { |
658 | .type = PSMOUSE_PS2PP, | 668 | .type = PSMOUSE_PS2PP, |
659 | .name = "PS2++", | 669 | .name = "PS2++", |
660 | .alias = "logitech", | 670 | .alias = "logitech", |
661 | .detect = ps2pp_init, | 671 | .detect = ps2pp_init, |
662 | }, | 672 | }, |
673 | #endif | ||
663 | { | 674 | { |
664 | .type = PSMOUSE_THINKPS, | 675 | .type = PSMOUSE_THINKPS, |
665 | .name = "ThinkPS/2", | 676 | .name = "ThinkPS/2", |
@@ -686,6 +697,7 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
686 | .maxproto = 1, | 697 | .maxproto = 1, |
687 | .detect = im_explorer_detect, | 698 | .detect = im_explorer_detect, |
688 | }, | 699 | }, |
700 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS | ||
689 | { | 701 | { |
690 | .type = PSMOUSE_SYNAPTICS, | 702 | .type = PSMOUSE_SYNAPTICS, |
691 | .name = "SynPS/2", | 703 | .name = "SynPS/2", |
@@ -693,6 +705,8 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
693 | .detect = synaptics_detect, | 705 | .detect = synaptics_detect, |
694 | .init = synaptics_init, | 706 | .init = synaptics_init, |
695 | }, | 707 | }, |
708 | #endif | ||
709 | #ifdef CONFIG_MOUSE_PS2_ALPS | ||
696 | { | 710 | { |
697 | .type = PSMOUSE_ALPS, | 711 | .type = PSMOUSE_ALPS, |
698 | .name = "AlpsPS/2", | 712 | .name = "AlpsPS/2", |
@@ -700,18 +714,31 @@ static const struct psmouse_protocol psmouse_protocols[] = { | |||
700 | .detect = alps_detect, | 714 | .detect = alps_detect, |
701 | .init = alps_init, | 715 | .init = alps_init, |
702 | }, | 716 | }, |
717 | #endif | ||
718 | #ifdef CONFIG_MOUSE_PS2_LIFEBOOK | ||
703 | { | 719 | { |
704 | .type = PSMOUSE_LIFEBOOK, | 720 | .type = PSMOUSE_LIFEBOOK, |
705 | .name = "LBPS/2", | 721 | .name = "LBPS/2", |
706 | .alias = "lifebook", | 722 | .alias = "lifebook", |
707 | .init = lifebook_init, | 723 | .init = lifebook_init, |
708 | }, | 724 | }, |
725 | #endif | ||
726 | #ifdef CONFIG_MOUSE_PS2_TRACKPOINT | ||
709 | { | 727 | { |
710 | .type = PSMOUSE_TRACKPOINT, | 728 | .type = PSMOUSE_TRACKPOINT, |
711 | .name = "TPPS/2", | 729 | .name = "TPPS/2", |
712 | .alias = "trackpoint", | 730 | .alias = "trackpoint", |
713 | .detect = trackpoint_detect, | 731 | .detect = trackpoint_detect, |
714 | }, | 732 | }, |
733 | #endif | ||
734 | #ifdef CONFIG_MOUSE_PS2_TOUCHKIT | ||
735 | { | ||
736 | .type = PSMOUSE_TOUCHKIT_PS2, | ||
737 | .name = "touchkitPS/2", | ||
738 | .alias = "touchkit", | ||
739 | .detect = touchkit_ps2_detect, | ||
740 | }, | ||
741 | #endif | ||
715 | { | 742 | { |
716 | .type = PSMOUSE_AUTO, | 743 | .type = PSMOUSE_AUTO, |
717 | .name = "auto", | 744 | .name = "auto", |
@@ -823,12 +850,6 @@ static void psmouse_set_rate(struct psmouse *psmouse, unsigned int rate) | |||
823 | static void psmouse_initialize(struct psmouse *psmouse) | 850 | static void psmouse_initialize(struct psmouse *psmouse) |
824 | { | 851 | { |
825 | /* | 852 | /* |
826 | * We set the mouse into streaming mode. | ||
827 | */ | ||
828 | |||
829 | ps2_command(&psmouse->ps2dev, NULL, PSMOUSE_CMD_SETSTREAM); | ||
830 | |||
831 | /* | ||
832 | * We set the mouse report rate, resolution and scaling. | 853 | * We set the mouse report rate, resolution and scaling. |
833 | */ | 854 | */ |
834 | 855 | ||
@@ -1062,8 +1083,7 @@ static int psmouse_switch_protocol(struct psmouse *psmouse, const struct psmouse | |||
1062 | { | 1083 | { |
1063 | struct input_dev *input_dev = psmouse->dev; | 1084 | struct input_dev *input_dev = psmouse->dev; |
1064 | 1085 | ||
1065 | input_dev->private = psmouse; | 1086 | input_dev->dev.parent = &psmouse->ps2dev.serio->dev; |
1066 | input_dev->cdev.dev = &psmouse->ps2dev.serio->dev; | ||
1067 | 1087 | ||
1068 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); | 1088 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); |
1069 | input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); | 1089 | input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_MIDDLE) | BIT(BTN_RIGHT); |
diff --git a/drivers/input/mouse/psmouse.h b/drivers/input/mouse/psmouse.h index cf1de95b6f2..3964e8acbc5 100644 --- a/drivers/input/mouse/psmouse.h +++ b/drivers/input/mouse/psmouse.h | |||
@@ -87,6 +87,7 @@ enum psmouse_type { | |||
87 | PSMOUSE_ALPS, | 87 | PSMOUSE_ALPS, |
88 | PSMOUSE_LIFEBOOK, | 88 | PSMOUSE_LIFEBOOK, |
89 | PSMOUSE_TRACKPOINT, | 89 | PSMOUSE_TRACKPOINT, |
90 | PSMOUSE_TOUCHKIT_PS2, | ||
90 | PSMOUSE_AUTO /* This one should always be last */ | 91 | PSMOUSE_AUTO /* This one should always be last */ |
91 | }; | 92 | }; |
92 | 93 | ||
diff --git a/drivers/input/mouse/sermouse.c b/drivers/input/mouse/sermouse.c index a85d74710b4..77b8ee2b965 100644 --- a/drivers/input/mouse/sermouse.c +++ b/drivers/input/mouse/sermouse.c | |||
@@ -69,7 +69,8 @@ static void sermouse_process_msc(struct sermouse *sermouse, signed char data) | |||
69 | switch (sermouse->count) { | 69 | switch (sermouse->count) { |
70 | 70 | ||
71 | case 0: | 71 | case 0: |
72 | if ((data & 0xf8) != 0x80) return; | 72 | if ((data & 0xf8) != 0x80) |
73 | return; | ||
73 | input_report_key(dev, BTN_LEFT, !(data & 4)); | 74 | input_report_key(dev, BTN_LEFT, !(data & 4)); |
74 | input_report_key(dev, BTN_RIGHT, !(data & 1)); | 75 | input_report_key(dev, BTN_RIGHT, !(data & 1)); |
75 | input_report_key(dev, BTN_MIDDLE, !(data & 2)); | 76 | input_report_key(dev, BTN_MIDDLE, !(data & 2)); |
@@ -107,7 +108,10 @@ static void sermouse_process_ms(struct sermouse *sermouse, signed char data) | |||
107 | struct input_dev *dev = sermouse->dev; | 108 | struct input_dev *dev = sermouse->dev; |
108 | signed char *buf = sermouse->buf; | 109 | signed char *buf = sermouse->buf; |
109 | 110 | ||
110 | if (data & 0x40) sermouse->count = 0; | 111 | if (data & 0x40) |
112 | sermouse->count = 0; | ||
113 | else if (sermouse->count == 0) | ||
114 | return; | ||
111 | 115 | ||
112 | switch (sermouse->count) { | 116 | switch (sermouse->count) { |
113 | 117 | ||
@@ -169,7 +173,8 @@ static void sermouse_process_ms(struct sermouse *sermouse, signed char data) | |||
169 | 173 | ||
170 | case 5: | 174 | case 5: |
171 | case 7: /* Ignore anything besides MZ++ */ | 175 | case 7: /* Ignore anything besides MZ++ */ |
172 | if (sermouse->type != SERIO_MZPP) break; | 176 | if (sermouse->type != SERIO_MZPP) |
177 | break; | ||
173 | 178 | ||
174 | switch (buf[1]) { | 179 | switch (buf[1]) { |
175 | 180 | ||
@@ -206,13 +211,16 @@ static irqreturn_t sermouse_interrupt(struct serio *serio, | |||
206 | { | 211 | { |
207 | struct sermouse *sermouse = serio_get_drvdata(serio); | 212 | struct sermouse *sermouse = serio_get_drvdata(serio); |
208 | 213 | ||
209 | if (time_after(jiffies, sermouse->last + HZ/10)) sermouse->count = 0; | 214 | if (time_after(jiffies, sermouse->last + HZ/10)) |
215 | sermouse->count = 0; | ||
216 | |||
210 | sermouse->last = jiffies; | 217 | sermouse->last = jiffies; |
211 | 218 | ||
212 | if (sermouse->type > SERIO_SUN) | 219 | if (sermouse->type > SERIO_SUN) |
213 | sermouse_process_ms(sermouse, data); | 220 | sermouse_process_ms(sermouse, data); |
214 | else | 221 | else |
215 | sermouse_process_msc(sermouse, data); | 222 | sermouse_process_msc(sermouse, data); |
223 | |||
216 | return IRQ_HANDLED; | 224 | return IRQ_HANDLED; |
217 | } | 225 | } |
218 | 226 | ||
@@ -258,12 +266,11 @@ static int sermouse_connect(struct serio *serio, struct serio_driver *drv) | |||
258 | input_dev->id.vendor = sermouse->type; | 266 | input_dev->id.vendor = sermouse->type; |
259 | input_dev->id.product = c; | 267 | input_dev->id.product = c; |
260 | input_dev->id.version = 0x0100; | 268 | input_dev->id.version = 0x0100; |
261 | input_dev->cdev.dev = &serio->dev; | 269 | input_dev->dev.parent = &serio->dev; |
262 | 270 | ||
263 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); | 271 | input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); |
264 | input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); | 272 | input_dev->keybit[LONG(BTN_MOUSE)] = BIT(BTN_LEFT) | BIT(BTN_RIGHT); |
265 | input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); | 273 | input_dev->relbit[0] = BIT(REL_X) | BIT(REL_Y); |
266 | input_dev->private = sermouse; | ||
267 | 274 | ||
268 | if (c & 0x01) set_bit(BTN_MIDDLE, input_dev->keybit); | 275 | if (c & 0x01) set_bit(BTN_MIDDLE, input_dev->keybit); |
269 | if (c & 0x02) set_bit(BTN_SIDE, input_dev->keybit); | 276 | if (c & 0x02) set_bit(BTN_SIDE, input_dev->keybit); |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index f0f9413d762..c77788bf932 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -40,33 +40,70 @@ | |||
40 | #define YMIN_NOMINAL 1408 | 40 | #define YMIN_NOMINAL 1408 |
41 | #define YMAX_NOMINAL 4448 | 41 | #define YMAX_NOMINAL 4448 |
42 | 42 | ||
43 | |||
43 | /***************************************************************************** | 44 | /***************************************************************************** |
44 | * Synaptics communications functions | 45 | * Stuff we need even when we do not want native Synaptics support |
45 | ****************************************************************************/ | 46 | ****************************************************************************/ |
46 | 47 | ||
47 | /* | 48 | /* |
48 | * Send a command to the synpatics touchpad by special commands | 49 | * Set the synaptics touchpad mode byte by special commands |
49 | */ | 50 | */ |
50 | static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param) | 51 | static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode) |
51 | { | 52 | { |
52 | if (psmouse_sliced_command(psmouse, c)) | 53 | unsigned char param[1]; |
54 | |||
55 | if (psmouse_sliced_command(psmouse, mode)) | ||
53 | return -1; | 56 | return -1; |
54 | if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) | 57 | param[0] = SYN_PS_SET_MODE2; |
58 | if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_SETRATE)) | ||
55 | return -1; | 59 | return -1; |
56 | return 0; | 60 | return 0; |
57 | } | 61 | } |
58 | 62 | ||
63 | int synaptics_detect(struct psmouse *psmouse, int set_properties) | ||
64 | { | ||
65 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
66 | unsigned char param[4]; | ||
67 | |||
68 | param[0] = 0; | ||
69 | |||
70 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | ||
71 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | ||
72 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | ||
73 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | ||
74 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); | ||
75 | |||
76 | if (param[1] != 0x47) | ||
77 | return -ENODEV; | ||
78 | |||
79 | if (set_properties) { | ||
80 | psmouse->vendor = "Synaptics"; | ||
81 | psmouse->name = "TouchPad"; | ||
82 | } | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | void synaptics_reset(struct psmouse *psmouse) | ||
88 | { | ||
89 | /* reset touchpad back to relative mode, gestures enabled */ | ||
90 | synaptics_mode_cmd(psmouse, 0); | ||
91 | } | ||
92 | |||
93 | #ifdef CONFIG_MOUSE_PS2_SYNAPTICS | ||
94 | |||
95 | /***************************************************************************** | ||
96 | * Synaptics communications functions | ||
97 | ****************************************************************************/ | ||
98 | |||
59 | /* | 99 | /* |
60 | * Set the synaptics touchpad mode byte by special commands | 100 | * Send a command to the synpatics touchpad by special commands |
61 | */ | 101 | */ |
62 | static int synaptics_mode_cmd(struct psmouse *psmouse, unsigned char mode) | 102 | static int synaptics_send_cmd(struct psmouse *psmouse, unsigned char c, unsigned char *param) |
63 | { | 103 | { |
64 | unsigned char param[1]; | 104 | if (psmouse_sliced_command(psmouse, c)) |
65 | |||
66 | if (psmouse_sliced_command(psmouse, mode)) | ||
67 | return -1; | 105 | return -1; |
68 | param[0] = SYN_PS_SET_MODE2; | 106 | if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_GETINFO)) |
69 | if (ps2_command(&psmouse->ps2dev, param, PSMOUSE_CMD_SETRATE)) | ||
70 | return -1; | 107 | return -1; |
71 | return 0; | 108 | return 0; |
72 | } | 109 | } |
@@ -529,12 +566,6 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
529 | clear_bit(REL_Y, dev->relbit); | 566 | clear_bit(REL_Y, dev->relbit); |
530 | } | 567 | } |
531 | 568 | ||
532 | void synaptics_reset(struct psmouse *psmouse) | ||
533 | { | ||
534 | /* reset touchpad back to relative mode, gestures enabled */ | ||
535 | synaptics_mode_cmd(psmouse, 0); | ||
536 | } | ||
537 | |||
538 | static void synaptics_disconnect(struct psmouse *psmouse) | 569 | static void synaptics_disconnect(struct psmouse *psmouse) |
539 | { | 570 | { |
540 | synaptics_reset(psmouse); | 571 | synaptics_reset(psmouse); |
@@ -569,30 +600,6 @@ static int synaptics_reconnect(struct psmouse *psmouse) | |||
569 | return 0; | 600 | return 0; |
570 | } | 601 | } |
571 | 602 | ||
572 | int synaptics_detect(struct psmouse *psmouse, int set_properties) | ||
573 | { | ||
574 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
575 | unsigned char param[4]; | ||
576 | |||
577 | param[0] = 0; | ||
578 | |||
579 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | ||
580 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | ||
581 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | ||
582 | ps2_command(ps2dev, param, PSMOUSE_CMD_SETRES); | ||
583 | ps2_command(ps2dev, param, PSMOUSE_CMD_GETINFO); | ||
584 | |||
585 | if (param[1] != 0x47) | ||
586 | return -1; | ||
587 | |||
588 | if (set_properties) { | ||
589 | psmouse->vendor = "Synaptics"; | ||
590 | psmouse->name = "TouchPad"; | ||
591 | } | ||
592 | |||
593 | return 0; | ||
594 | } | ||
595 | |||
596 | #if defined(__i386__) | 603 | #if defined(__i386__) |
597 | #include <linux/dmi.h> | 604 | #include <linux/dmi.h> |
598 | static struct dmi_system_id toshiba_dmi_table[] = { | 605 | static struct dmi_system_id toshiba_dmi_table[] = { |
@@ -648,6 +655,16 @@ int synaptics_init(struct psmouse *psmouse) | |||
648 | 655 | ||
649 | set_input_params(psmouse->dev, priv); | 656 | set_input_params(psmouse->dev, priv); |
650 | 657 | ||
658 | /* | ||
659 | * Encode touchpad model so that it can be used to set | ||
660 | * input device->id.version and be visible to userspace. | ||
661 | * Because version is __u16 we have to drop something. | ||
662 | * Hardware info bits seem to be good candidates as they | ||
663 | * are documented to be for Synaptics corp. internal use. | ||
664 | */ | ||
665 | psmouse->model = ((priv->model_id & 0x00ff0000) >> 8) | | ||
666 | (priv->model_id & 0x000000ff); | ||
667 | |||
651 | psmouse->protocol_handler = synaptics_process_byte; | 668 | psmouse->protocol_handler = synaptics_process_byte; |
652 | psmouse->set_rate = synaptics_set_rate; | 669 | psmouse->set_rate = synaptics_set_rate; |
653 | psmouse->disconnect = synaptics_disconnect; | 670 | psmouse->disconnect = synaptics_disconnect; |
@@ -680,4 +697,12 @@ int synaptics_init(struct psmouse *psmouse) | |||
680 | return -1; | 697 | return -1; |
681 | } | 698 | } |
682 | 699 | ||
700 | #else /* CONFIG_MOUSE_PS2_SYNAPTICS */ | ||
701 | |||
702 | int synaptics_init(struct psmouse *psmouse) | ||
703 | { | ||
704 | return -ENOSYS; | ||
705 | } | ||
706 | |||
707 | #endif /* CONFIG_MOUSE_PS2_SYNAPTICS */ | ||
683 | 708 | ||
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 68fff1dcd7d..02aa4cf7bc7 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -9,10 +9,6 @@ | |||
9 | #ifndef _SYNAPTICS_H | 9 | #ifndef _SYNAPTICS_H |
10 | #define _SYNAPTICS_H | 10 | #define _SYNAPTICS_H |
11 | 11 | ||
12 | extern int synaptics_detect(struct psmouse *psmouse, int set_properties); | ||
13 | extern int synaptics_init(struct psmouse *psmouse); | ||
14 | extern void synaptics_reset(struct psmouse *psmouse); | ||
15 | |||
16 | /* synaptics queries */ | 12 | /* synaptics queries */ |
17 | #define SYN_QUE_IDENTIFY 0x00 | 13 | #define SYN_QUE_IDENTIFY 0x00 |
18 | #define SYN_QUE_MODES 0x01 | 14 | #define SYN_QUE_MODES 0x01 |
@@ -62,9 +58,9 @@ extern void synaptics_reset(struct psmouse *psmouse); | |||
62 | #define SYN_MODE_WMODE(m) ((m) & (1 << 0)) | 58 | #define SYN_MODE_WMODE(m) ((m) & (1 << 0)) |
63 | 59 | ||
64 | /* synaptics identify query bits */ | 60 | /* synaptics identify query bits */ |
65 | #define SYN_ID_MODEL(i) (((i) >> 4) & 0x0f) | 61 | #define SYN_ID_MODEL(i) (((i) >> 4) & 0x0f) |
66 | #define SYN_ID_MAJOR(i) ((i) & 0x0f) | 62 | #define SYN_ID_MAJOR(i) ((i) & 0x0f) |
67 | #define SYN_ID_MINOR(i) (((i) >> 16) & 0xff) | 63 | #define SYN_ID_MINOR(i) (((i) >> 16) & 0xff) |
68 | #define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47) | 64 | #define SYN_ID_IS_SYNAPTICS(i) ((((i) >> 8) & 0xff) == 0x47) |
69 | 65 | ||
70 | /* synaptics special commands */ | 66 | /* synaptics special commands */ |
@@ -98,8 +94,8 @@ struct synaptics_hw_state { | |||
98 | struct synaptics_data { | 94 | struct synaptics_data { |
99 | /* Data read from the touchpad */ | 95 | /* Data read from the touchpad */ |
100 | unsigned long int model_id; /* Model-ID */ | 96 | unsigned long int model_id; /* Model-ID */ |
101 | unsigned long int capabilities; /* Capabilities */ | 97 | unsigned long int capabilities; /* Capabilities */ |
102 | unsigned long int ext_cap; /* Extended Capabilities */ | 98 | unsigned long int ext_cap; /* Extended Capabilities */ |
103 | unsigned long int identity; /* Identification */ | 99 | unsigned long int identity; /* Identification */ |
104 | 100 | ||
105 | unsigned char pkt_type; /* packet type - old, new, etc */ | 101 | unsigned char pkt_type; /* packet type - old, new, etc */ |
@@ -107,4 +103,8 @@ struct synaptics_data { | |||
107 | int scroll; | 103 | int scroll; |
108 | }; | 104 | }; |
109 | 105 | ||
106 | int synaptics_detect(struct psmouse *psmouse, int set_properties); | ||
107 | int synaptics_init(struct psmouse *psmouse); | ||
108 | void synaptics_reset(struct psmouse *psmouse); | ||
109 | |||
110 | #endif /* _SYNAPTICS_H */ | 110 | #endif /* _SYNAPTICS_H */ |
diff --git a/drivers/input/mouse/touchkit_ps2.c b/drivers/input/mouse/touchkit_ps2.c new file mode 100644 index 00000000000..7b977fd2357 --- /dev/null +++ b/drivers/input/mouse/touchkit_ps2.c | |||
@@ -0,0 +1,100 @@ | |||
1 | /* ---------------------------------------------------------------------------- | ||
2 | * touchkit_ps2.c -- Driver for eGalax TouchKit PS/2 Touchscreens | ||
3 | * | ||
4 | * Copyright (C) 2005 by Stefan Lucke | ||
5 | * Copyright (C) 2004 by Daniel Ritz | ||
6 | * Copyright (C) by Todd E. Johnson (mtouchusb.c) | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation; either version 2 of the | ||
11 | * License, or (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, but | ||
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | * Based upon touchkitusb.c | ||
23 | * | ||
24 | * Vendor documentation is available in support section of: | ||
25 | * http://www.egalax.com.tw/ | ||
26 | */ | ||
27 | |||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/slab.h> | ||
30 | |||
31 | #include <linux/input.h> | ||
32 | #include <linux/serio.h> | ||
33 | #include <linux/libps2.h> | ||
34 | |||
35 | #include "psmouse.h" | ||
36 | #include "touchkit_ps2.h" | ||
37 | |||
38 | #define TOUCHKIT_MAX_XC 0x07ff | ||
39 | #define TOUCHKIT_MAX_YC 0x07ff | ||
40 | |||
41 | #define TOUCHKIT_CMD 0x0a | ||
42 | #define TOUCHKIT_CMD_LENGTH 1 | ||
43 | |||
44 | #define TOUCHKIT_CMD_ACTIVE 'A' | ||
45 | #define TOUCHKIT_CMD_FIRMWARE_VERSION 'D' | ||
46 | #define TOUCHKIT_CMD_CONTROLLER_TYPE 'E' | ||
47 | |||
48 | #define TOUCHKIT_SEND_PARMS(s, r, c) ((s) << 12 | (r) << 8 | (c)) | ||
49 | |||
50 | #define TOUCHKIT_GET_TOUCHED(packet) (((packet)[0]) & 0x01) | ||
51 | #define TOUCHKIT_GET_X(packet) (((packet)[1] << 7) | (packet)[2]) | ||
52 | #define TOUCHKIT_GET_Y(packet) (((packet)[3] << 7) | (packet)[4]) | ||
53 | |||
54 | static psmouse_ret_t touchkit_ps2_process_byte(struct psmouse *psmouse) | ||
55 | { | ||
56 | unsigned char *packet = psmouse->packet; | ||
57 | struct input_dev *dev = psmouse->dev; | ||
58 | |||
59 | if (psmouse->pktcnt != 5) | ||
60 | return PSMOUSE_GOOD_DATA; | ||
61 | |||
62 | input_report_abs(dev, ABS_X, TOUCHKIT_GET_X(packet)); | ||
63 | input_report_abs(dev, ABS_Y, TOUCHKIT_GET_Y(packet)); | ||
64 | input_report_key(dev, BTN_TOUCH, TOUCHKIT_GET_TOUCHED(packet)); | ||
65 | input_sync(dev); | ||
66 | |||
67 | return PSMOUSE_FULL_PACKET; | ||
68 | } | ||
69 | |||
70 | int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties) | ||
71 | { | ||
72 | struct input_dev *dev = psmouse->dev; | ||
73 | unsigned char param[3]; | ||
74 | int command; | ||
75 | |||
76 | param[0] = TOUCHKIT_CMD_LENGTH; | ||
77 | param[1] = TOUCHKIT_CMD_ACTIVE; | ||
78 | command = TOUCHKIT_SEND_PARMS(2, 3, TOUCHKIT_CMD); | ||
79 | |||
80 | if (ps2_command(&psmouse->ps2dev, param, command)) | ||
81 | return -ENODEV; | ||
82 | |||
83 | if (param[0] != TOUCHKIT_CMD || param[1] != 0x01 || | ||
84 | param[2] != TOUCHKIT_CMD_ACTIVE) | ||
85 | return -ENODEV; | ||
86 | |||
87 | if (set_properties) { | ||
88 | dev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS); | ||
89 | set_bit(BTN_TOUCH, dev->keybit); | ||
90 | input_set_abs_params(dev, ABS_X, 0, TOUCHKIT_MAX_XC, 0, 0); | ||
91 | input_set_abs_params(dev, ABS_Y, 0, TOUCHKIT_MAX_YC, 0, 0); | ||
92 | |||
93 | psmouse->vendor = "eGalax"; | ||
94 | psmouse->name = "Touchscreen"; | ||
95 | psmouse->protocol_handler = touchkit_ps2_process_byte; | ||
96 | psmouse->pktsize = 5; | ||
97 | } | ||
98 | |||
99 | return 0; | ||
100 | } | ||
diff --git a/drivers/input/mouse/touchkit_ps2.h b/drivers/input/mouse/touchkit_ps2.h new file mode 100644 index 00000000000..61e9dfd8419 --- /dev/null +++ b/drivers/input/mouse/touchkit_ps2.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* ---------------------------------------------------------------------------- | ||
2 | * touchkit_ps2.h -- Driver for eGalax TouchKit PS/2 Touchscreens | ||
3 | * | ||
4 | * Copyright (C) 2005 by Stefan Lucke | ||
5 | * Copyright (c) 2005 Vojtech Pavlik | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published by | ||
9 | * the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef _TOUCHKIT_PS2_H | ||
13 | #define _TOUCHKIT_PS2_H | ||
14 | |||
15 | #ifdef CONFIG_MOUSE_PS2_TOUCHKIT | ||
16 | int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties); | ||
17 | #else | ||
18 | inline int touchkit_ps2_detect(struct psmouse *psmouse, int set_properties) | ||
19 | { | ||
20 | return -ENOSYS; | ||
21 | } | ||
22 | #endif /* CONFIG_MOUSE_PS2_TOUCHKIT */ | ||
23 | |||
24 | #endif | ||
diff --git a/drivers/input/mouse/trackpoint.h b/drivers/input/mouse/trackpoint.h index 050298b1a09..c10a6e7d010 100644 --- a/drivers/input/mouse/trackpoint.h +++ b/drivers/input/mouse/trackpoint.h | |||
@@ -142,6 +142,13 @@ struct trackpoint_data | |||
142 | unsigned char ext_dev; | 142 | unsigned char ext_dev; |
143 | }; | 143 | }; |
144 | 144 | ||
145 | extern int trackpoint_detect(struct psmouse *psmouse, int set_properties); | 145 | #ifdef CONFIG_MOUSE_PS2_TRACKPOINT |
146 | int trackpoint_detect(struct psmouse *psmouse, int set_properties); | ||
147 | #else | ||
148 | inline int trackpoint_detect(struct psmouse *psmouse, int set_properties) | ||
149 | { | ||
150 | return -ENOSYS; | ||
151 | } | ||
152 | #endif /* CONFIG_MOUSE_PS2_TRACKPOINT */ | ||
146 | 153 | ||
147 | #endif /* _TRACKPOINT_H */ | 154 | #endif /* _TRACKPOINT_H */ |
diff --git a/drivers/input/mouse/vsxxxaa.c b/drivers/input/mouse/vsxxxaa.c index c3d64fcc858..4a321576f34 100644 --- a/drivers/input/mouse/vsxxxaa.c +++ b/drivers/input/mouse/vsxxxaa.c | |||
@@ -508,8 +508,7 @@ vsxxxaa_connect (struct serio *serio, struct serio_driver *drv) | |||
508 | input_dev->name = mouse->name; | 508 | input_dev->name = mouse->name; |
509 | input_dev->phys = mouse->phys; | 509 | input_dev->phys = mouse->phys; |
510 | input_dev->id.bustype = BUS_RS232; | 510 | input_dev->id.bustype = BUS_RS232; |
511 | input_dev->cdev.dev = &serio->dev; | 511 | input_dev->dev.parent = &serio->dev; |
512 | input_dev->private = mouse; | ||
513 | 512 | ||
514 | set_bit (EV_KEY, input_dev->evbit); /* We have buttons */ | 513 | set_bit (EV_KEY, input_dev->evbit); /* We have buttons */ |
515 | set_bit (EV_REL, input_dev->evbit); | 514 | set_bit (EV_REL, input_dev->evbit); |