diff options
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r-- | drivers/input/mouse/alps.c | 2 | ||||
-rw-r--r-- | drivers/input/mouse/bcm5974.c | 348 | ||||
-rw-r--r-- | drivers/input/mouse/elantech.c | 4 | ||||
-rw-r--r-- | drivers/input/mouse/sentelic.c | 13 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.c | 64 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics.h | 3 | ||||
-rw-r--r-- | drivers/input/mouse/synaptics_usb.c | 2 |
7 files changed, 233 insertions, 203 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 4a1347e91bdc..cf5af1f495ec 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -1620,7 +1620,7 @@ int alps_init(struct psmouse *psmouse) | |||
1620 | case ALPS_PROTO_V3: | 1620 | case ALPS_PROTO_V3: |
1621 | case ALPS_PROTO_V4: | 1621 | case ALPS_PROTO_V4: |
1622 | set_bit(INPUT_PROP_SEMI_MT, dev1->propbit); | 1622 | set_bit(INPUT_PROP_SEMI_MT, dev1->propbit); |
1623 | input_mt_init_slots(dev1, 2); | 1623 | input_mt_init_slots(dev1, 2, 0); |
1624 | input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, ALPS_V3_X_MAX, 0, 0); | 1624 | input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, ALPS_V3_X_MAX, 0, 0); |
1625 | input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, ALPS_V3_Y_MAX, 0, 0); | 1625 | input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, ALPS_V3_Y_MAX, 0, 0); |
1626 | 1626 | ||
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index d528c23e194f..3a78f235fa3e 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/usb/input.h> | 40 | #include <linux/usb/input.h> |
41 | #include <linux/hid.h> | 41 | #include <linux/hid.h> |
42 | #include <linux/mutex.h> | 42 | #include <linux/mutex.h> |
43 | #include <linux/input/mt.h> | ||
43 | 44 | ||
44 | #define USB_VENDOR_ID_APPLE 0x05ac | 45 | #define USB_VENDOR_ID_APPLE 0x05ac |
45 | 46 | ||
@@ -183,26 +184,26 @@ struct tp_finger { | |||
183 | __le16 abs_y; /* absolute y coodinate */ | 184 | __le16 abs_y; /* absolute y coodinate */ |
184 | __le16 rel_x; /* relative x coodinate */ | 185 | __le16 rel_x; /* relative x coodinate */ |
185 | __le16 rel_y; /* relative y coodinate */ | 186 | __le16 rel_y; /* relative y coodinate */ |
186 | __le16 size_major; /* finger size, major axis? */ | 187 | __le16 tool_major; /* tool area, major axis */ |
187 | __le16 size_minor; /* finger size, minor axis? */ | 188 | __le16 tool_minor; /* tool area, minor axis */ |
188 | __le16 orientation; /* 16384 when point, else 15 bit angle */ | 189 | __le16 orientation; /* 16384 when point, else 15 bit angle */ |
189 | __le16 force_major; /* trackpad force, major axis? */ | 190 | __le16 touch_major; /* touch area, major axis */ |
190 | __le16 force_minor; /* trackpad force, minor axis? */ | 191 | __le16 touch_minor; /* touch area, minor axis */ |
191 | __le16 unused[3]; /* zeros */ | 192 | __le16 unused[3]; /* zeros */ |
192 | __le16 multi; /* one finger: varies, more fingers: constant */ | 193 | __le16 multi; /* one finger: varies, more fingers: constant */ |
193 | } __attribute__((packed,aligned(2))); | 194 | } __attribute__((packed,aligned(2))); |
194 | 195 | ||
195 | /* trackpad finger data size, empirically at least ten fingers */ | 196 | /* trackpad finger data size, empirically at least ten fingers */ |
197 | #define MAX_FINGERS 16 | ||
196 | #define SIZEOF_FINGER sizeof(struct tp_finger) | 198 | #define SIZEOF_FINGER sizeof(struct tp_finger) |
197 | #define SIZEOF_ALL_FINGERS (16 * SIZEOF_FINGER) | 199 | #define SIZEOF_ALL_FINGERS (MAX_FINGERS * SIZEOF_FINGER) |
198 | #define MAX_FINGER_ORIENTATION 16384 | 200 | #define MAX_FINGER_ORIENTATION 16384 |
199 | 201 | ||
200 | /* device-specific parameters */ | 202 | /* device-specific parameters */ |
201 | struct bcm5974_param { | 203 | struct bcm5974_param { |
202 | int dim; /* logical dimension */ | 204 | int snratio; /* signal-to-noise ratio */ |
203 | int fuzz; /* logical noise value */ | 205 | int min; /* device minimum reading */ |
204 | int devmin; /* device minimum reading */ | 206 | int max; /* device maximum reading */ |
205 | int devmax; /* device maximum reading */ | ||
206 | }; | 207 | }; |
207 | 208 | ||
208 | /* device-specific configuration */ | 209 | /* device-specific configuration */ |
@@ -219,6 +220,7 @@ struct bcm5974_config { | |||
219 | struct bcm5974_param w; /* finger width limits */ | 220 | struct bcm5974_param w; /* finger width limits */ |
220 | struct bcm5974_param x; /* horizontal limits */ | 221 | struct bcm5974_param x; /* horizontal limits */ |
221 | struct bcm5974_param y; /* vertical limits */ | 222 | struct bcm5974_param y; /* vertical limits */ |
223 | struct bcm5974_param o; /* orientation limits */ | ||
222 | }; | 224 | }; |
223 | 225 | ||
224 | /* logical device structure */ | 226 | /* logical device structure */ |
@@ -234,23 +236,16 @@ struct bcm5974 { | |||
234 | struct bt_data *bt_data; /* button transferred data */ | 236 | struct bt_data *bt_data; /* button transferred data */ |
235 | struct urb *tp_urb; /* trackpad usb request block */ | 237 | struct urb *tp_urb; /* trackpad usb request block */ |
236 | u8 *tp_data; /* trackpad transferred data */ | 238 | u8 *tp_data; /* trackpad transferred data */ |
237 | int fingers; /* number of fingers on trackpad */ | 239 | const struct tp_finger *index[MAX_FINGERS]; /* finger index data */ |
240 | struct input_mt_pos pos[MAX_FINGERS]; /* position array */ | ||
241 | int slots[MAX_FINGERS]; /* slot assignments */ | ||
238 | }; | 242 | }; |
239 | 243 | ||
240 | /* logical dimensions */ | ||
241 | #define DIM_PRESSURE 256 /* maximum finger pressure */ | ||
242 | #define DIM_WIDTH 16 /* maximum finger width */ | ||
243 | #define DIM_X 1280 /* maximum trackpad x value */ | ||
244 | #define DIM_Y 800 /* maximum trackpad y value */ | ||
245 | |||
246 | /* logical signal quality */ | 244 | /* logical signal quality */ |
247 | #define SN_PRESSURE 45 /* pressure signal-to-noise ratio */ | 245 | #define SN_PRESSURE 45 /* pressure signal-to-noise ratio */ |
248 | #define SN_WIDTH 100 /* width signal-to-noise ratio */ | 246 | #define SN_WIDTH 25 /* width signal-to-noise ratio */ |
249 | #define SN_COORD 250 /* coordinate signal-to-noise ratio */ | 247 | #define SN_COORD 250 /* coordinate signal-to-noise ratio */ |
250 | 248 | #define SN_ORIENT 10 /* orientation signal-to-noise ratio */ | |
251 | /* pressure thresholds */ | ||
252 | #define PRESSURE_LOW (2 * DIM_PRESSURE / SN_PRESSURE) | ||
253 | #define PRESSURE_HIGH (3 * PRESSURE_LOW) | ||
254 | 249 | ||
255 | /* device constants */ | 250 | /* device constants */ |
256 | static const struct bcm5974_config bcm5974_config_table[] = { | 251 | static const struct bcm5974_config bcm5974_config_table[] = { |
@@ -261,10 +256,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
261 | 0, | 256 | 0, |
262 | 0x84, sizeof(struct bt_data), | 257 | 0x84, sizeof(struct bt_data), |
263 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, | 258 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, |
264 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, | 259 | { SN_PRESSURE, 0, 256 }, |
265 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 260 | { SN_WIDTH, 0, 2048 }, |
266 | { DIM_X, DIM_X / SN_COORD, -4824, 5342 }, | 261 | { SN_COORD, -4824, 5342 }, |
267 | { DIM_Y, DIM_Y / SN_COORD, -172, 5820 } | 262 | { SN_COORD, -172, 5820 }, |
263 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
268 | }, | 264 | }, |
269 | { | 265 | { |
270 | USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, | 266 | USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, |
@@ -273,10 +269,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
273 | 0, | 269 | 0, |
274 | 0x84, sizeof(struct bt_data), | 270 | 0x84, sizeof(struct bt_data), |
275 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, | 271 | 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, |
276 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, | 272 | { SN_PRESSURE, 0, 256 }, |
277 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 273 | { SN_WIDTH, 0, 2048 }, |
278 | { DIM_X, DIM_X / SN_COORD, -4824, 4824 }, | 274 | { SN_COORD, -4824, 4824 }, |
279 | { DIM_Y, DIM_Y / SN_COORD, -172, 4290 } | 275 | { SN_COORD, -172, 4290 }, |
276 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
280 | }, | 277 | }, |
281 | { | 278 | { |
282 | USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI, | 279 | USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI, |
@@ -285,10 +282,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
285 | HAS_INTEGRATED_BUTTON, | 282 | HAS_INTEGRATED_BUTTON, |
286 | 0x84, sizeof(struct bt_data), | 283 | 0x84, sizeof(struct bt_data), |
287 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 284 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
288 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | 285 | { SN_PRESSURE, 0, 300 }, |
289 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 286 | { SN_WIDTH, 0, 2048 }, |
290 | { DIM_X, DIM_X / SN_COORD, -4460, 5166 }, | 287 | { SN_COORD, -4460, 5166 }, |
291 | { DIM_Y, DIM_Y / SN_COORD, -75, 6700 } | 288 | { SN_COORD, -75, 6700 }, |
289 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
292 | }, | 290 | }, |
293 | { | 291 | { |
294 | USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI, | 292 | USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI, |
@@ -297,10 +295,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
297 | HAS_INTEGRATED_BUTTON, | 295 | HAS_INTEGRATED_BUTTON, |
298 | 0x84, sizeof(struct bt_data), | 296 | 0x84, sizeof(struct bt_data), |
299 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 297 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
300 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | 298 | { SN_PRESSURE, 0, 300 }, |
301 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 299 | { SN_WIDTH, 0, 2048 }, |
302 | { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, | 300 | { SN_COORD, -4620, 5140 }, |
303 | { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } | 301 | { SN_COORD, -150, 6600 }, |
302 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
304 | }, | 303 | }, |
305 | { | 304 | { |
306 | USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI, | 305 | USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI, |
@@ -309,10 +308,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
309 | HAS_INTEGRATED_BUTTON, | 308 | HAS_INTEGRATED_BUTTON, |
310 | 0x84, sizeof(struct bt_data), | 309 | 0x84, sizeof(struct bt_data), |
311 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 310 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
312 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | 311 | { SN_PRESSURE, 0, 300 }, |
313 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 312 | { SN_WIDTH, 0, 2048 }, |
314 | { DIM_X, DIM_X / SN_COORD, -4616, 5112 }, | 313 | { SN_COORD, -4616, 5112 }, |
315 | { DIM_Y, DIM_Y / SN_COORD, -142, 5234 } | 314 | { SN_COORD, -142, 5234 }, |
315 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
316 | }, | 316 | }, |
317 | { | 317 | { |
318 | USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI, | 318 | USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI, |
@@ -321,10 +321,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
321 | HAS_INTEGRATED_BUTTON, | 321 | HAS_INTEGRATED_BUTTON, |
322 | 0x84, sizeof(struct bt_data), | 322 | 0x84, sizeof(struct bt_data), |
323 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 323 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
324 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | 324 | { SN_PRESSURE, 0, 300 }, |
325 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 325 | { SN_WIDTH, 0, 2048 }, |
326 | { DIM_X, DIM_X / SN_COORD, -4415, 5050 }, | 326 | { SN_COORD, -4415, 5050 }, |
327 | { DIM_Y, DIM_Y / SN_COORD, -55, 6680 } | 327 | { SN_COORD, -55, 6680 }, |
328 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
328 | }, | 329 | }, |
329 | { | 330 | { |
330 | USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI, | 331 | USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI, |
@@ -333,10 +334,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
333 | HAS_INTEGRATED_BUTTON, | 334 | HAS_INTEGRATED_BUTTON, |
334 | 0x84, sizeof(struct bt_data), | 335 | 0x84, sizeof(struct bt_data), |
335 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 336 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
336 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | 337 | { SN_PRESSURE, 0, 300 }, |
337 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 338 | { SN_WIDTH, 0, 2048 }, |
338 | { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, | 339 | { SN_COORD, -4620, 5140 }, |
339 | { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } | 340 | { SN_COORD, -150, 6600 }, |
341 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
340 | }, | 342 | }, |
341 | { | 343 | { |
342 | USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI, | 344 | USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI, |
@@ -345,10 +347,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
345 | HAS_INTEGRATED_BUTTON, | 347 | HAS_INTEGRATED_BUTTON, |
346 | 0x84, sizeof(struct bt_data), | 348 | 0x84, sizeof(struct bt_data), |
347 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 349 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
348 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | 350 | { SN_PRESSURE, 0, 300 }, |
349 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 351 | { SN_WIDTH, 0, 2048 }, |
350 | { DIM_X, DIM_X / SN_COORD, -4750, 5280 }, | 352 | { SN_COORD, -4750, 5280 }, |
351 | { DIM_Y, DIM_Y / SN_COORD, -150, 6730 } | 353 | { SN_COORD, -150, 6730 }, |
354 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
352 | }, | 355 | }, |
353 | { | 356 | { |
354 | USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI, | 357 | USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI, |
@@ -357,10 +360,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
357 | HAS_INTEGRATED_BUTTON, | 360 | HAS_INTEGRATED_BUTTON, |
358 | 0x84, sizeof(struct bt_data), | 361 | 0x84, sizeof(struct bt_data), |
359 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 362 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
360 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | 363 | { SN_PRESSURE, 0, 300 }, |
361 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 364 | { SN_WIDTH, 0, 2048 }, |
362 | { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, | 365 | { SN_COORD, -4620, 5140 }, |
363 | { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } | 366 | { SN_COORD, -150, 6600 }, |
367 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
364 | }, | 368 | }, |
365 | { | 369 | { |
366 | USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI, | 370 | USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI, |
@@ -369,10 +373,11 @@ static const struct bcm5974_config bcm5974_config_table[] = { | |||
369 | HAS_INTEGRATED_BUTTON, | 373 | HAS_INTEGRATED_BUTTON, |
370 | 0x84, sizeof(struct bt_data), | 374 | 0x84, sizeof(struct bt_data), |
371 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, | 375 | 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, |
372 | { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, | 376 | { SN_PRESSURE, 0, 300 }, |
373 | { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, | 377 | { SN_WIDTH, 0, 2048 }, |
374 | { DIM_X, DIM_X / SN_COORD, -4750, 5280 }, | 378 | { SN_COORD, -4750, 5280 }, |
375 | { DIM_Y, DIM_Y / SN_COORD, -150, 6730 } | 379 | { SN_COORD, -150, 6730 }, |
380 | { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION } | ||
376 | }, | 381 | }, |
377 | {} | 382 | {} |
378 | }; | 383 | }; |
@@ -396,18 +401,11 @@ static inline int raw2int(__le16 x) | |||
396 | return (signed short)le16_to_cpu(x); | 401 | return (signed short)le16_to_cpu(x); |
397 | } | 402 | } |
398 | 403 | ||
399 | /* scale device data to logical dimensions (asserts devmin < devmax) */ | 404 | static void set_abs(struct input_dev *input, unsigned int code, |
400 | static inline int int2scale(const struct bcm5974_param *p, int x) | 405 | const struct bcm5974_param *p) |
401 | { | ||
402 | return x * p->dim / (p->devmax - p->devmin); | ||
403 | } | ||
404 | |||
405 | /* all logical value ranges are [0,dim). */ | ||
406 | static inline int int2bound(const struct bcm5974_param *p, int x) | ||
407 | { | 406 | { |
408 | int s = int2scale(p, x); | 407 | int fuzz = p->snratio ? (p->max - p->min) / p->snratio : 0; |
409 | 408 | input_set_abs_params(input, code, p->min, p->max, fuzz, 0); | |
410 | return clamp_val(s, 0, p->dim - 1); | ||
411 | } | 409 | } |
412 | 410 | ||
413 | /* setup which logical events to report */ | 411 | /* setup which logical events to report */ |
@@ -416,48 +414,30 @@ static void setup_events_to_report(struct input_dev *input_dev, | |||
416 | { | 414 | { |
417 | __set_bit(EV_ABS, input_dev->evbit); | 415 | __set_bit(EV_ABS, input_dev->evbit); |
418 | 416 | ||
419 | input_set_abs_params(input_dev, ABS_PRESSURE, | 417 | /* for synaptics only */ |
420 | 0, cfg->p.dim, cfg->p.fuzz, 0); | 418 | input_set_abs_params(input_dev, ABS_PRESSURE, 0, 256, 5, 0); |
421 | input_set_abs_params(input_dev, ABS_TOOL_WIDTH, | 419 | input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 0, 16, 0, 0); |
422 | 0, cfg->w.dim, cfg->w.fuzz, 0); | ||
423 | input_set_abs_params(input_dev, ABS_X, | ||
424 | 0, cfg->x.dim, cfg->x.fuzz, 0); | ||
425 | input_set_abs_params(input_dev, ABS_Y, | ||
426 | 0, cfg->y.dim, cfg->y.fuzz, 0); | ||
427 | 420 | ||
428 | /* finger touch area */ | 421 | /* finger touch area */ |
429 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, | 422 | set_abs(input_dev, ABS_MT_TOUCH_MAJOR, &cfg->w); |
430 | cfg->w.devmin, cfg->w.devmax, 0, 0); | 423 | set_abs(input_dev, ABS_MT_TOUCH_MINOR, &cfg->w); |
431 | input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR, | ||
432 | cfg->w.devmin, cfg->w.devmax, 0, 0); | ||
433 | /* finger approach area */ | 424 | /* finger approach area */ |
434 | input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, | 425 | set_abs(input_dev, ABS_MT_WIDTH_MAJOR, &cfg->w); |
435 | cfg->w.devmin, cfg->w.devmax, 0, 0); | 426 | set_abs(input_dev, ABS_MT_WIDTH_MINOR, &cfg->w); |
436 | input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR, | ||
437 | cfg->w.devmin, cfg->w.devmax, 0, 0); | ||
438 | /* finger orientation */ | 427 | /* finger orientation */ |
439 | input_set_abs_params(input_dev, ABS_MT_ORIENTATION, | 428 | set_abs(input_dev, ABS_MT_ORIENTATION, &cfg->o); |
440 | -MAX_FINGER_ORIENTATION, | ||
441 | MAX_FINGER_ORIENTATION, 0, 0); | ||
442 | /* finger position */ | 429 | /* finger position */ |
443 | input_set_abs_params(input_dev, ABS_MT_POSITION_X, | 430 | set_abs(input_dev, ABS_MT_POSITION_X, &cfg->x); |
444 | cfg->x.devmin, cfg->x.devmax, 0, 0); | 431 | set_abs(input_dev, ABS_MT_POSITION_Y, &cfg->y); |
445 | input_set_abs_params(input_dev, ABS_MT_POSITION_Y, | ||
446 | cfg->y.devmin, cfg->y.devmax, 0, 0); | ||
447 | 432 | ||
448 | __set_bit(EV_KEY, input_dev->evbit); | 433 | __set_bit(EV_KEY, input_dev->evbit); |
449 | __set_bit(BTN_TOUCH, input_dev->keybit); | ||
450 | __set_bit(BTN_TOOL_FINGER, input_dev->keybit); | ||
451 | __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); | ||
452 | __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); | ||
453 | __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); | ||
454 | __set_bit(BTN_LEFT, input_dev->keybit); | 434 | __set_bit(BTN_LEFT, input_dev->keybit); |
455 | 435 | ||
456 | __set_bit(INPUT_PROP_POINTER, input_dev->propbit); | ||
457 | if (cfg->caps & HAS_INTEGRATED_BUTTON) | 436 | if (cfg->caps & HAS_INTEGRATED_BUTTON) |
458 | __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); | 437 | __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); |
459 | 438 | ||
460 | input_set_events_per_packet(input_dev, 60); | 439 | input_mt_init_slots(input_dev, MAX_FINGERS, |
440 | INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK); | ||
461 | } | 441 | } |
462 | 442 | ||
463 | /* report button data as logical button state */ | 443 | /* report button data as logical button state */ |
@@ -477,24 +457,44 @@ static int report_bt_state(struct bcm5974 *dev, int size) | |||
477 | return 0; | 457 | return 0; |
478 | } | 458 | } |
479 | 459 | ||
480 | static void report_finger_data(struct input_dev *input, | 460 | static void report_finger_data(struct input_dev *input, int slot, |
481 | const struct bcm5974_config *cfg, | 461 | const struct input_mt_pos *pos, |
482 | const struct tp_finger *f) | 462 | const struct tp_finger *f) |
483 | { | 463 | { |
464 | input_mt_slot(input, slot); | ||
465 | input_mt_report_slot_state(input, MT_TOOL_FINGER, true); | ||
466 | |||
484 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, | 467 | input_report_abs(input, ABS_MT_TOUCH_MAJOR, |
485 | raw2int(f->force_major) << 1); | 468 | raw2int(f->touch_major) << 1); |
486 | input_report_abs(input, ABS_MT_TOUCH_MINOR, | 469 | input_report_abs(input, ABS_MT_TOUCH_MINOR, |
487 | raw2int(f->force_minor) << 1); | 470 | raw2int(f->touch_minor) << 1); |
488 | input_report_abs(input, ABS_MT_WIDTH_MAJOR, | 471 | input_report_abs(input, ABS_MT_WIDTH_MAJOR, |
489 | raw2int(f->size_major) << 1); | 472 | raw2int(f->tool_major) << 1); |
490 | input_report_abs(input, ABS_MT_WIDTH_MINOR, | 473 | input_report_abs(input, ABS_MT_WIDTH_MINOR, |
491 | raw2int(f->size_minor) << 1); | 474 | raw2int(f->tool_minor) << 1); |
492 | input_report_abs(input, ABS_MT_ORIENTATION, | 475 | input_report_abs(input, ABS_MT_ORIENTATION, |
493 | MAX_FINGER_ORIENTATION - raw2int(f->orientation)); | 476 | MAX_FINGER_ORIENTATION - raw2int(f->orientation)); |
494 | input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x)); | 477 | input_report_abs(input, ABS_MT_POSITION_X, pos->x); |
495 | input_report_abs(input, ABS_MT_POSITION_Y, | 478 | input_report_abs(input, ABS_MT_POSITION_Y, pos->y); |
496 | cfg->y.devmin + cfg->y.devmax - raw2int(f->abs_y)); | 479 | } |
497 | input_mt_sync(input); | 480 | |
481 | static void report_synaptics_data(struct input_dev *input, | ||
482 | const struct bcm5974_config *cfg, | ||
483 | const struct tp_finger *f, int raw_n) | ||
484 | { | ||
485 | int abs_p = 0, abs_w = 0; | ||
486 | |||
487 | if (raw_n) { | ||
488 | int p = raw2int(f->touch_major); | ||
489 | int w = raw2int(f->tool_major); | ||
490 | if (p > 0 && raw2int(f->origin)) { | ||
491 | abs_p = clamp_val(256 * p / cfg->p.max, 0, 255); | ||
492 | abs_w = clamp_val(16 * w / cfg->w.max, 0, 15); | ||
493 | } | ||
494 | } | ||
495 | |||
496 | input_report_abs(input, ABS_PRESSURE, abs_p); | ||
497 | input_report_abs(input, ABS_TOOL_WIDTH, abs_w); | ||
498 | } | 498 | } |
499 | 499 | ||
500 | /* report trackpad data as logical trackpad state */ | 500 | /* report trackpad data as logical trackpad state */ |
@@ -503,9 +503,7 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
503 | const struct bcm5974_config *c = &dev->cfg; | 503 | const struct bcm5974_config *c = &dev->cfg; |
504 | const struct tp_finger *f; | 504 | const struct tp_finger *f; |
505 | struct input_dev *input = dev->input; | 505 | struct input_dev *input = dev->input; |
506 | int raw_p, raw_w, raw_x, raw_y, raw_n, i; | 506 | int raw_n, i, n = 0; |
507 | int ptest, origin, ibt = 0, nmin = 0, nmax = 0; | ||
508 | int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0; | ||
509 | 507 | ||
510 | if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) | 508 | if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) |
511 | return -EIO; | 509 | return -EIO; |
@@ -514,76 +512,29 @@ static int report_tp_state(struct bcm5974 *dev, int size) | |||
514 | f = (const struct tp_finger *)(dev->tp_data + c->tp_offset); | 512 | f = (const struct tp_finger *)(dev->tp_data + c->tp_offset); |
515 | raw_n = (size - c->tp_offset) / SIZEOF_FINGER; | 513 | raw_n = (size - c->tp_offset) / SIZEOF_FINGER; |
516 | 514 | ||
517 | /* always track the first finger; when detached, start over */ | 515 | for (i = 0; i < raw_n; i++) { |
518 | if (raw_n) { | 516 | if (raw2int(f[i].touch_major) == 0) |
519 | 517 | continue; | |
520 | /* report raw trackpad data */ | 518 | dev->pos[n].x = raw2int(f[i].abs_x); |
521 | for (i = 0; i < raw_n; i++) | 519 | dev->pos[n].y = c->y.min + c->y.max - raw2int(f[i].abs_y); |
522 | report_finger_data(input, c, &f[i]); | 520 | dev->index[n++] = &f[i]; |
523 | |||
524 | raw_p = raw2int(f->force_major); | ||
525 | raw_w = raw2int(f->size_major); | ||
526 | raw_x = raw2int(f->abs_x); | ||
527 | raw_y = raw2int(f->abs_y); | ||
528 | |||
529 | dprintk(9, | ||
530 | "bcm5974: " | ||
531 | "raw: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n", | ||
532 | raw_p, raw_w, raw_x, raw_y, raw_n); | ||
533 | |||
534 | ptest = int2bound(&c->p, raw_p); | ||
535 | origin = raw2int(f->origin); | ||
536 | |||
537 | /* while tracking finger still valid, count all fingers */ | ||
538 | if (ptest > PRESSURE_LOW && origin) { | ||
539 | abs_p = ptest; | ||
540 | abs_w = int2bound(&c->w, raw_w); | ||
541 | abs_x = int2bound(&c->x, raw_x - c->x.devmin); | ||
542 | abs_y = int2bound(&c->y, c->y.devmax - raw_y); | ||
543 | while (raw_n--) { | ||
544 | ptest = int2bound(&c->p, | ||
545 | raw2int(f->force_major)); | ||
546 | if (ptest > PRESSURE_LOW) | ||
547 | nmax++; | ||
548 | if (ptest > PRESSURE_HIGH) | ||
549 | nmin++; | ||
550 | f++; | ||
551 | } | ||
552 | } | ||
553 | } | 521 | } |
554 | 522 | ||
555 | /* set the integrated button if applicable */ | 523 | input_mt_assign_slots(input, dev->slots, dev->pos, n); |
556 | if (c->tp_type == TYPE2) | ||
557 | ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); | ||
558 | |||
559 | if (dev->fingers < nmin) | ||
560 | dev->fingers = nmin; | ||
561 | if (dev->fingers > nmax) | ||
562 | dev->fingers = nmax; | ||
563 | |||
564 | input_report_key(input, BTN_TOUCH, dev->fingers > 0); | ||
565 | input_report_key(input, BTN_TOOL_FINGER, dev->fingers == 1); | ||
566 | input_report_key(input, BTN_TOOL_DOUBLETAP, dev->fingers == 2); | ||
567 | input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers == 3); | ||
568 | input_report_key(input, BTN_TOOL_QUADTAP, dev->fingers > 3); | ||
569 | |||
570 | input_report_abs(input, ABS_PRESSURE, abs_p); | ||
571 | input_report_abs(input, ABS_TOOL_WIDTH, abs_w); | ||
572 | 524 | ||
573 | if (abs_p) { | 525 | for (i = 0; i < n; i++) |
574 | input_report_abs(input, ABS_X, abs_x); | 526 | report_finger_data(input, dev->slots[i], |
575 | input_report_abs(input, ABS_Y, abs_y); | 527 | &dev->pos[i], dev->index[i]); |
576 | 528 | ||
577 | dprintk(8, | 529 | input_mt_sync_frame(input); |
578 | "bcm5974: abs: p: %+05d w: %+05d x: %+05d y: %+05d " | ||
579 | "nmin: %d nmax: %d n: %d ibt: %d\n", abs_p, abs_w, | ||
580 | abs_x, abs_y, nmin, nmax, dev->fingers, ibt); | ||
581 | 530 | ||
582 | } | 531 | report_synaptics_data(input, c, f, raw_n); |
583 | 532 | ||
584 | /* type 2 reports button events via ibt only */ | 533 | /* type 2 reports button events via ibt only */ |
585 | if (c->tp_type == TYPE2) | 534 | if (c->tp_type == TYPE2) { |
535 | int ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); | ||
586 | input_report_key(input, BTN_LEFT, ibt); | 536 | input_report_key(input, BTN_LEFT, ibt); |
537 | } | ||
587 | 538 | ||
588 | input_sync(input); | 539 | input_sync(input); |
589 | 540 | ||
@@ -742,9 +693,11 @@ static int bcm5974_start_traffic(struct bcm5974 *dev) | |||
742 | goto err_out; | 693 | goto err_out; |
743 | } | 694 | } |
744 | 695 | ||
745 | error = usb_submit_urb(dev->bt_urb, GFP_KERNEL); | 696 | if (dev->bt_urb) { |
746 | if (error) | 697 | error = usb_submit_urb(dev->bt_urb, GFP_KERNEL); |
747 | goto err_reset_mode; | 698 | if (error) |
699 | goto err_reset_mode; | ||
700 | } | ||
748 | 701 | ||
749 | error = usb_submit_urb(dev->tp_urb, GFP_KERNEL); | 702 | error = usb_submit_urb(dev->tp_urb, GFP_KERNEL); |
750 | if (error) | 703 | if (error) |
@@ -868,19 +821,23 @@ static int bcm5974_probe(struct usb_interface *iface, | |||
868 | mutex_init(&dev->pm_mutex); | 821 | mutex_init(&dev->pm_mutex); |
869 | 822 | ||
870 | /* setup urbs */ | 823 | /* setup urbs */ |
871 | dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL); | 824 | if (cfg->tp_type == TYPE1) { |
872 | if (!dev->bt_urb) | 825 | dev->bt_urb = usb_alloc_urb(0, GFP_KERNEL); |
873 | goto err_free_devs; | 826 | if (!dev->bt_urb) |
827 | goto err_free_devs; | ||
828 | } | ||
874 | 829 | ||
875 | dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL); | 830 | dev->tp_urb = usb_alloc_urb(0, GFP_KERNEL); |
876 | if (!dev->tp_urb) | 831 | if (!dev->tp_urb) |
877 | goto err_free_bt_urb; | 832 | goto err_free_bt_urb; |
878 | 833 | ||
879 | dev->bt_data = usb_alloc_coherent(dev->udev, | 834 | if (dev->bt_urb) { |
835 | dev->bt_data = usb_alloc_coherent(dev->udev, | ||
880 | dev->cfg.bt_datalen, GFP_KERNEL, | 836 | dev->cfg.bt_datalen, GFP_KERNEL, |
881 | &dev->bt_urb->transfer_dma); | 837 | &dev->bt_urb->transfer_dma); |
882 | if (!dev->bt_data) | 838 | if (!dev->bt_data) |
883 | goto err_free_urb; | 839 | goto err_free_urb; |
840 | } | ||
884 | 841 | ||
885 | dev->tp_data = usb_alloc_coherent(dev->udev, | 842 | dev->tp_data = usb_alloc_coherent(dev->udev, |
886 | dev->cfg.tp_datalen, GFP_KERNEL, | 843 | dev->cfg.tp_datalen, GFP_KERNEL, |
@@ -888,10 +845,11 @@ static int bcm5974_probe(struct usb_interface *iface, | |||
888 | if (!dev->tp_data) | 845 | if (!dev->tp_data) |
889 | goto err_free_bt_buffer; | 846 | goto err_free_bt_buffer; |
890 | 847 | ||
891 | usb_fill_int_urb(dev->bt_urb, udev, | 848 | if (dev->bt_urb) |
892 | usb_rcvintpipe(udev, cfg->bt_ep), | 849 | usb_fill_int_urb(dev->bt_urb, udev, |
893 | dev->bt_data, dev->cfg.bt_datalen, | 850 | usb_rcvintpipe(udev, cfg->bt_ep), |
894 | bcm5974_irq_button, dev, 1); | 851 | dev->bt_data, dev->cfg.bt_datalen, |
852 | bcm5974_irq_button, dev, 1); | ||
895 | 853 | ||
896 | usb_fill_int_urb(dev->tp_urb, udev, | 854 | usb_fill_int_urb(dev->tp_urb, udev, |
897 | usb_rcvintpipe(udev, cfg->tp_ep), | 855 | usb_rcvintpipe(udev, cfg->tp_ep), |
@@ -929,8 +887,9 @@ err_free_buffer: | |||
929 | usb_free_coherent(dev->udev, dev->cfg.tp_datalen, | 887 | usb_free_coherent(dev->udev, dev->cfg.tp_datalen, |
930 | dev->tp_data, dev->tp_urb->transfer_dma); | 888 | dev->tp_data, dev->tp_urb->transfer_dma); |
931 | err_free_bt_buffer: | 889 | err_free_bt_buffer: |
932 | usb_free_coherent(dev->udev, dev->cfg.bt_datalen, | 890 | if (dev->bt_urb) |
933 | dev->bt_data, dev->bt_urb->transfer_dma); | 891 | usb_free_coherent(dev->udev, dev->cfg.bt_datalen, |
892 | dev->bt_data, dev->bt_urb->transfer_dma); | ||
934 | err_free_urb: | 893 | err_free_urb: |
935 | usb_free_urb(dev->tp_urb); | 894 | usb_free_urb(dev->tp_urb); |
936 | err_free_bt_urb: | 895 | err_free_bt_urb: |
@@ -951,8 +910,9 @@ static void bcm5974_disconnect(struct usb_interface *iface) | |||
951 | input_unregister_device(dev->input); | 910 | input_unregister_device(dev->input); |
952 | usb_free_coherent(dev->udev, dev->cfg.tp_datalen, | 911 | usb_free_coherent(dev->udev, dev->cfg.tp_datalen, |
953 | dev->tp_data, dev->tp_urb->transfer_dma); | 912 | dev->tp_data, dev->tp_urb->transfer_dma); |
954 | usb_free_coherent(dev->udev, dev->cfg.bt_datalen, | 913 | if (dev->bt_urb) |
955 | dev->bt_data, dev->bt_urb->transfer_dma); | 914 | usb_free_coherent(dev->udev, dev->cfg.bt_datalen, |
915 | dev->bt_data, dev->bt_urb->transfer_dma); | ||
956 | usb_free_urb(dev->tp_urb); | 916 | usb_free_urb(dev->tp_urb); |
957 | usb_free_urb(dev->bt_urb); | 917 | usb_free_urb(dev->bt_urb); |
958 | kfree(dev); | 918 | kfree(dev); |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 479011004a11..1e8e42fb03a4 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -1004,7 +1004,7 @@ static int elantech_set_input_params(struct psmouse *psmouse) | |||
1004 | input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, | 1004 | input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, |
1005 | ETP_WMAX_V2, 0, 0); | 1005 | ETP_WMAX_V2, 0, 0); |
1006 | } | 1006 | } |
1007 | input_mt_init_slots(dev, 2); | 1007 | input_mt_init_slots(dev, 2, 0); |
1008 | input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); | 1008 | input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); |
1009 | input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); | 1009 | input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); |
1010 | break; | 1010 | break; |
@@ -1035,7 +1035,7 @@ static int elantech_set_input_params(struct psmouse *psmouse) | |||
1035 | input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, | 1035 | input_set_abs_params(dev, ABS_TOOL_WIDTH, ETP_WMIN_V2, |
1036 | ETP_WMAX_V2, 0, 0); | 1036 | ETP_WMAX_V2, 0, 0); |
1037 | /* Multitouch capable pad, up to 5 fingers. */ | 1037 | /* Multitouch capable pad, up to 5 fingers. */ |
1038 | input_mt_init_slots(dev, ETP_MAX_FINGERS); | 1038 | input_mt_init_slots(dev, ETP_MAX_FINGERS, 0); |
1039 | input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); | 1039 | input_set_abs_params(dev, ABS_MT_POSITION_X, x_min, x_max, 0, 0); |
1040 | input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); | 1040 | input_set_abs_params(dev, ABS_MT_POSITION_Y, y_min, y_max, 0, 0); |
1041 | input_abs_set_res(dev, ABS_MT_POSITION_X, x_res); | 1041 | input_abs_set_res(dev, ABS_MT_POSITION_X, x_res); |
diff --git a/drivers/input/mouse/sentelic.c b/drivers/input/mouse/sentelic.c index 3f5649f19082..e582922bacf7 100644 --- a/drivers/input/mouse/sentelic.c +++ b/drivers/input/mouse/sentelic.c | |||
@@ -721,6 +721,17 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse) | |||
721 | 721 | ||
722 | switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) { | 722 | switch (psmouse->packet[0] >> FSP_PKT_TYPE_SHIFT) { |
723 | case FSP_PKT_TYPE_ABS: | 723 | case FSP_PKT_TYPE_ABS: |
724 | |||
725 | if ((packet[0] == 0x48 || packet[0] == 0x49) && | ||
726 | packet[1] == 0 && packet[2] == 0) { | ||
727 | /* | ||
728 | * Ignore coordinate noise when finger leaving the | ||
729 | * surface, otherwise cursor may jump to upper-left | ||
730 | * corner. | ||
731 | */ | ||
732 | packet[3] &= 0xf0; | ||
733 | } | ||
734 | |||
724 | abs_x = GET_ABS_X(packet); | 735 | abs_x = GET_ABS_X(packet); |
725 | abs_y = GET_ABS_Y(packet); | 736 | abs_y = GET_ABS_Y(packet); |
726 | 737 | ||
@@ -960,7 +971,7 @@ static int fsp_set_input_params(struct psmouse *psmouse) | |||
960 | 971 | ||
961 | input_set_abs_params(dev, ABS_X, 0, abs_x, 0, 0); | 972 | input_set_abs_params(dev, ABS_X, 0, abs_x, 0, 0); |
962 | input_set_abs_params(dev, ABS_Y, 0, abs_y, 0, 0); | 973 | input_set_abs_params(dev, ABS_Y, 0, abs_y, 0, 0); |
963 | input_mt_init_slots(dev, 2); | 974 | input_mt_init_slots(dev, 2, 0); |
964 | input_set_abs_params(dev, ABS_MT_POSITION_X, 0, abs_x, 0, 0); | 975 | input_set_abs_params(dev, ABS_MT_POSITION_X, 0, abs_x, 0, 0); |
965 | input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, abs_y, 0, 0); | 976 | input_set_abs_params(dev, ABS_MT_POSITION_Y, 0, abs_y, 0, 0); |
966 | } | 977 | } |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index c703d53be3a0..37033ade79d3 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -40,11 +40,27 @@ | |||
40 | * Note that newer firmware allows querying device for maximum useable | 40 | * Note that newer firmware allows querying device for maximum useable |
41 | * coordinates. | 41 | * coordinates. |
42 | */ | 42 | */ |
43 | #define XMIN 0 | ||
44 | #define XMAX 6143 | ||
45 | #define YMIN 0 | ||
46 | #define YMAX 6143 | ||
43 | #define XMIN_NOMINAL 1472 | 47 | #define XMIN_NOMINAL 1472 |
44 | #define XMAX_NOMINAL 5472 | 48 | #define XMAX_NOMINAL 5472 |
45 | #define YMIN_NOMINAL 1408 | 49 | #define YMIN_NOMINAL 1408 |
46 | #define YMAX_NOMINAL 4448 | 50 | #define YMAX_NOMINAL 4448 |
47 | 51 | ||
52 | /* Size in bits of absolute position values reported by the hardware */ | ||
53 | #define ABS_POS_BITS 13 | ||
54 | |||
55 | /* | ||
56 | * Any position values from the hardware above the following limits are | ||
57 | * treated as "wrapped around negative" values that have been truncated to | ||
58 | * the 13-bit reporting range of the hardware. These are just reasonable | ||
59 | * guesses and can be adjusted if hardware is found that operates outside | ||
60 | * of these parameters. | ||
61 | */ | ||
62 | #define X_MAX_POSITIVE (((1 << ABS_POS_BITS) + XMAX) / 2) | ||
63 | #define Y_MAX_POSITIVE (((1 << ABS_POS_BITS) + YMAX) / 2) | ||
48 | 64 | ||
49 | /***************************************************************************** | 65 | /***************************************************************************** |
50 | * Stuff we need even when we do not want native Synaptics support | 66 | * Stuff we need even when we do not want native Synaptics support |
@@ -139,6 +155,35 @@ static int synaptics_model_id(struct psmouse *psmouse) | |||
139 | } | 155 | } |
140 | 156 | ||
141 | /* | 157 | /* |
158 | * Read the board id from the touchpad | ||
159 | * The board id is encoded in the "QUERY MODES" response | ||
160 | */ | ||
161 | static int synaptics_board_id(struct psmouse *psmouse) | ||
162 | { | ||
163 | struct synaptics_data *priv = psmouse->private; | ||
164 | unsigned char bid[3]; | ||
165 | |||
166 | if (synaptics_send_cmd(psmouse, SYN_QUE_MODES, bid)) | ||
167 | return -1; | ||
168 | priv->board_id = ((bid[0] & 0xfc) << 6) | bid[1]; | ||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | /* | ||
173 | * Read the firmware id from the touchpad | ||
174 | */ | ||
175 | static int synaptics_firmware_id(struct psmouse *psmouse) | ||
176 | { | ||
177 | struct synaptics_data *priv = psmouse->private; | ||
178 | unsigned char fwid[3]; | ||
179 | |||
180 | if (synaptics_send_cmd(psmouse, SYN_QUE_FIRMWARE_ID, fwid)) | ||
181 | return -1; | ||
182 | priv->firmware_id = (fwid[0] << 16) | (fwid[1] << 8) | fwid[2]; | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | /* | ||
142 | * Read the capability-bits from the touchpad | 187 | * Read the capability-bits from the touchpad |
143 | * see also the SYN_CAP_* macros | 188 | * see also the SYN_CAP_* macros |
144 | */ | 189 | */ |
@@ -261,6 +306,10 @@ static int synaptics_query_hardware(struct psmouse *psmouse) | |||
261 | return -1; | 306 | return -1; |
262 | if (synaptics_model_id(psmouse)) | 307 | if (synaptics_model_id(psmouse)) |
263 | return -1; | 308 | return -1; |
309 | if (synaptics_firmware_id(psmouse)) | ||
310 | return -1; | ||
311 | if (synaptics_board_id(psmouse)) | ||
312 | return -1; | ||
264 | if (synaptics_capability(psmouse)) | 313 | if (synaptics_capability(psmouse)) |
265 | return -1; | 314 | return -1; |
266 | if (synaptics_resolution(psmouse)) | 315 | if (synaptics_resolution(psmouse)) |
@@ -555,6 +604,12 @@ static int synaptics_parse_hw_state(const unsigned char buf[], | |||
555 | hw->right = (buf[0] & 0x02) ? 1 : 0; | 604 | hw->right = (buf[0] & 0x02) ? 1 : 0; |
556 | } | 605 | } |
557 | 606 | ||
607 | /* Convert wrap-around values to negative */ | ||
608 | if (hw->x > X_MAX_POSITIVE) | ||
609 | hw->x -= 1 << ABS_POS_BITS; | ||
610 | if (hw->y > Y_MAX_POSITIVE) | ||
611 | hw->y -= 1 << ABS_POS_BITS; | ||
612 | |||
558 | return 0; | 613 | return 0; |
559 | } | 614 | } |
560 | 615 | ||
@@ -1177,7 +1232,7 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
1177 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); | 1232 | input_set_abs_params(dev, ABS_PRESSURE, 0, 255, 0, 0); |
1178 | 1233 | ||
1179 | if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { | 1234 | if (SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) { |
1180 | input_mt_init_slots(dev, 2); | 1235 | input_mt_init_slots(dev, 2, 0); |
1181 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, | 1236 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, |
1182 | ABS_MT_POSITION_Y); | 1237 | ABS_MT_POSITION_Y); |
1183 | /* Image sensors can report per-contact pressure */ | 1238 | /* Image sensors can report per-contact pressure */ |
@@ -1189,7 +1244,7 @@ static void set_input_params(struct input_dev *dev, struct synaptics_data *priv) | |||
1189 | } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { | 1244 | } else if (SYN_CAP_ADV_GESTURE(priv->ext_cap_0c)) { |
1190 | /* Non-image sensors with AGM use semi-mt */ | 1245 | /* Non-image sensors with AGM use semi-mt */ |
1191 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); | 1246 | __set_bit(INPUT_PROP_SEMI_MT, dev->propbit); |
1192 | input_mt_init_slots(dev, 2); | 1247 | input_mt_init_slots(dev, 2, 0); |
1193 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, | 1248 | set_abs_position_params(dev, priv, ABS_MT_POSITION_X, |
1194 | ABS_MT_POSITION_Y); | 1249 | ABS_MT_POSITION_Y); |
1195 | } | 1250 | } |
@@ -1435,11 +1490,12 @@ static int __synaptics_init(struct psmouse *psmouse, bool absolute_mode) | |||
1435 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; | 1490 | priv->pkt_type = SYN_MODEL_NEWABS(priv->model_id) ? SYN_NEWABS : SYN_OLDABS; |
1436 | 1491 | ||
1437 | psmouse_info(psmouse, | 1492 | psmouse_info(psmouse, |
1438 | "Touchpad model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx\n", | 1493 | "Touchpad model: %ld, fw: %ld.%ld, id: %#lx, caps: %#lx/%#lx/%#lx, board id: %lu, fw id: %lu\n", |
1439 | SYN_ID_MODEL(priv->identity), | 1494 | SYN_ID_MODEL(priv->identity), |
1440 | SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), | 1495 | SYN_ID_MAJOR(priv->identity), SYN_ID_MINOR(priv->identity), |
1441 | priv->model_id, | 1496 | priv->model_id, |
1442 | priv->capabilities, priv->ext_cap, priv->ext_cap_0c); | 1497 | priv->capabilities, priv->ext_cap, priv->ext_cap_0c, |
1498 | priv->board_id, priv->firmware_id); | ||
1443 | 1499 | ||
1444 | set_input_params(psmouse->dev, priv); | 1500 | set_input_params(psmouse->dev, priv); |
1445 | 1501 | ||
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index fd26ccca13d7..e594af0b264b 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -18,6 +18,7 @@ | |||
18 | #define SYN_QUE_SERIAL_NUMBER_SUFFIX 0x07 | 18 | #define SYN_QUE_SERIAL_NUMBER_SUFFIX 0x07 |
19 | #define SYN_QUE_RESOLUTION 0x08 | 19 | #define SYN_QUE_RESOLUTION 0x08 |
20 | #define SYN_QUE_EXT_CAPAB 0x09 | 20 | #define SYN_QUE_EXT_CAPAB 0x09 |
21 | #define SYN_QUE_FIRMWARE_ID 0x0a | ||
21 | #define SYN_QUE_EXT_CAPAB_0C 0x0c | 22 | #define SYN_QUE_EXT_CAPAB_0C 0x0c |
22 | #define SYN_QUE_EXT_MAX_COORDS 0x0d | 23 | #define SYN_QUE_EXT_MAX_COORDS 0x0d |
23 | #define SYN_QUE_EXT_MIN_COORDS 0x0f | 24 | #define SYN_QUE_EXT_MIN_COORDS 0x0f |
@@ -148,6 +149,8 @@ struct synaptics_hw_state { | |||
148 | struct synaptics_data { | 149 | struct synaptics_data { |
149 | /* Data read from the touchpad */ | 150 | /* Data read from the touchpad */ |
150 | unsigned long int model_id; /* Model-ID */ | 151 | unsigned long int model_id; /* Model-ID */ |
152 | unsigned long int firmware_id; /* Firmware-ID */ | ||
153 | unsigned long int board_id; /* Board-ID */ | ||
151 | unsigned long int capabilities; /* Capabilities */ | 154 | unsigned long int capabilities; /* Capabilities */ |
152 | unsigned long int ext_cap; /* Extended Capabilities */ | 155 | unsigned long int ext_cap; /* Extended Capabilities */ |
153 | unsigned long int ext_cap_0c; /* Ext Caps from 0x0c query */ | 156 | unsigned long int ext_cap_0c; /* Ext Caps from 0x0c query */ |
diff --git a/drivers/input/mouse/synaptics_usb.c b/drivers/input/mouse/synaptics_usb.c index 3c5eaaa5d154..64cf34ea7604 100644 --- a/drivers/input/mouse/synaptics_usb.c +++ b/drivers/input/mouse/synaptics_usb.c | |||
@@ -364,7 +364,7 @@ static int synusb_probe(struct usb_interface *intf, | |||
364 | le16_to_cpu(udev->descriptor.idProduct)); | 364 | le16_to_cpu(udev->descriptor.idProduct)); |
365 | 365 | ||
366 | if (synusb->flags & SYNUSB_STICK) | 366 | if (synusb->flags & SYNUSB_STICK) |
367 | strlcat(synusb->name, " (Stick) ", sizeof(synusb->name)); | 367 | strlcat(synusb->name, " (Stick)", sizeof(synusb->name)); |
368 | 368 | ||
369 | usb_make_path(udev, synusb->phys, sizeof(synusb->phys)); | 369 | usb_make_path(udev, synusb->phys, sizeof(synusb->phys)); |
370 | strlcat(synusb->phys, "/input0", sizeof(synusb->phys)); | 370 | strlcat(synusb->phys, "/input0", sizeof(synusb->phys)); |