aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r--drivers/input/mouse/alps.c2
-rw-r--r--drivers/input/mouse/bcm5974.c348
-rw-r--r--drivers/input/mouse/elantech.c4
-rw-r--r--drivers/input/mouse/sentelic.c13
-rw-r--r--drivers/input/mouse/synaptics.c64
-rw-r--r--drivers/input/mouse/synaptics.h3
-rw-r--r--drivers/input/mouse/synaptics_usb.c2
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 */
201struct bcm5974_param { 203struct 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 */
256static const struct bcm5974_config bcm5974_config_table[] = { 251static 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) */ 404static void set_abs(struct input_dev *input, unsigned int code,
400static 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). */
406static 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
480static void report_finger_data(struct input_dev *input, 460static 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
481static 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);
931err_free_bt_buffer: 889err_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);
934err_free_urb: 893err_free_urb:
935 usb_free_urb(dev->tp_urb); 894 usb_free_urb(dev->tp_urb);
936err_free_bt_urb: 895err_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 */
161static 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 */
175static 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 {
148struct synaptics_data { 149struct 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));