aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r--drivers/input/mouse/bcm5974.c255
1 files changed, 111 insertions, 144 deletions
diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c
index 2de974ce56b2..e8cfb3864181 100644
--- a/drivers/input/mouse/bcm5974.c
+++ b/drivers/input/mouse/bcm5974.c
@@ -200,10 +200,9 @@ struct tp_finger {
200 200
201/* device-specific parameters */ 201/* device-specific parameters */
202struct bcm5974_param { 202struct bcm5974_param {
203 int dim; /* logical dimension */ 203 int snratio; /* signal-to-noise ratio */
204 int fuzz; /* logical noise value */ 204 int min; /* device minimum reading */
205 int devmin; /* device minimum reading */ 205 int max; /* device maximum reading */
206 int devmax; /* device maximum reading */
207}; 206};
208 207
209/* device-specific configuration */ 208/* device-specific configuration */
@@ -220,6 +219,7 @@ struct bcm5974_config {
220 struct bcm5974_param w; /* finger width limits */ 219 struct bcm5974_param w; /* finger width limits */
221 struct bcm5974_param x; /* horizontal limits */ 220 struct bcm5974_param x; /* horizontal limits */
222 struct bcm5974_param y; /* vertical limits */ 221 struct bcm5974_param y; /* vertical limits */
222 struct bcm5974_param o; /* orientation limits */
223}; 223};
224 224
225/* logical device structure */ 225/* logical device structure */
@@ -235,23 +235,13 @@ struct bcm5974 {
235 struct bt_data *bt_data; /* button transferred data */ 235 struct bt_data *bt_data; /* button transferred data */
236 struct urb *tp_urb; /* trackpad usb request block */ 236 struct urb *tp_urb; /* trackpad usb request block */
237 u8 *tp_data; /* trackpad transferred data */ 237 u8 *tp_data; /* trackpad transferred data */
238 int fingers; /* number of fingers on trackpad */
239}; 238};
240 239
241/* logical dimensions */
242#define DIM_PRESSURE 256 /* maximum finger pressure */
243#define DIM_WIDTH 16 /* maximum finger width */
244#define DIM_X 1280 /* maximum trackpad x value */
245#define DIM_Y 800 /* maximum trackpad y value */
246
247/* logical signal quality */ 240/* logical signal quality */
248#define SN_PRESSURE 45 /* pressure signal-to-noise ratio */ 241#define SN_PRESSURE 45 /* pressure signal-to-noise ratio */
249#define SN_WIDTH 100 /* width signal-to-noise ratio */ 242#define SN_WIDTH 100 /* width signal-to-noise ratio */
250#define SN_COORD 250 /* coordinate signal-to-noise ratio */ 243#define SN_COORD 250 /* coordinate signal-to-noise ratio */
251 244#define SN_ORIENT 10 /* orientation signal-to-noise ratio */
252/* pressure thresholds */
253#define PRESSURE_LOW (2 * DIM_PRESSURE / SN_PRESSURE)
254#define PRESSURE_HIGH (3 * PRESSURE_LOW)
255 245
256/* device constants */ 246/* device constants */
257static const struct bcm5974_config bcm5974_config_table[] = { 247static const struct bcm5974_config bcm5974_config_table[] = {
@@ -262,10 +252,11 @@ static const struct bcm5974_config bcm5974_config_table[] = {
262 0, 252 0,
263 0x84, sizeof(struct bt_data), 253 0x84, sizeof(struct bt_data),
264 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, 254 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS,
265 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, 255 { SN_PRESSURE, 0, 256 },
266 { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, 256 { SN_WIDTH, 0, 2048 },
267 { DIM_X, DIM_X / SN_COORD, -4824, 5342 }, 257 { SN_COORD, -4824, 5342 },
268 { DIM_Y, DIM_Y / SN_COORD, -172, 5820 } 258 { SN_COORD, -172, 5820 },
259 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
269 }, 260 },
270 { 261 {
271 USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI, 262 USB_DEVICE_ID_APPLE_WELLSPRING2_ANSI,
@@ -274,10 +265,11 @@ static const struct bcm5974_config bcm5974_config_table[] = {
274 0, 265 0,
275 0x84, sizeof(struct bt_data), 266 0x84, sizeof(struct bt_data),
276 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS, 267 0x81, TYPE1, FINGER_TYPE1, FINGER_TYPE1 + SIZEOF_ALL_FINGERS,
277 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 256 }, 268 { SN_PRESSURE, 0, 256 },
278 { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, 269 { SN_WIDTH, 0, 2048 },
279 { DIM_X, DIM_X / SN_COORD, -4824, 4824 }, 270 { SN_COORD, -4824, 4824 },
280 { DIM_Y, DIM_Y / SN_COORD, -172, 4290 } 271 { SN_COORD, -172, 4290 },
272 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
281 }, 273 },
282 { 274 {
283 USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI, 275 USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI,
@@ -286,10 +278,11 @@ static const struct bcm5974_config bcm5974_config_table[] = {
286 HAS_INTEGRATED_BUTTON, 278 HAS_INTEGRATED_BUTTON,
287 0x84, sizeof(struct bt_data), 279 0x84, sizeof(struct bt_data),
288 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, 280 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
289 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, 281 { SN_PRESSURE, 0, 300 },
290 { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, 282 { SN_WIDTH, 0, 2048 },
291 { DIM_X, DIM_X / SN_COORD, -4460, 5166 }, 283 { SN_COORD, -4460, 5166 },
292 { DIM_Y, DIM_Y / SN_COORD, -75, 6700 } 284 { SN_COORD, -75, 6700 },
285 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
293 }, 286 },
294 { 287 {
295 USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI, 288 USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI,
@@ -298,10 +291,11 @@ static const struct bcm5974_config bcm5974_config_table[] = {
298 HAS_INTEGRATED_BUTTON, 291 HAS_INTEGRATED_BUTTON,
299 0x84, sizeof(struct bt_data), 292 0x84, sizeof(struct bt_data),
300 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, 293 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
301 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, 294 { SN_PRESSURE, 0, 300 },
302 { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, 295 { SN_WIDTH, 0, 2048 },
303 { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, 296 { SN_COORD, -4620, 5140 },
304 { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } 297 { SN_COORD, -150, 6600 },
298 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
305 }, 299 },
306 { 300 {
307 USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI, 301 USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI,
@@ -310,10 +304,11 @@ static const struct bcm5974_config bcm5974_config_table[] = {
310 HAS_INTEGRATED_BUTTON, 304 HAS_INTEGRATED_BUTTON,
311 0x84, sizeof(struct bt_data), 305 0x84, sizeof(struct bt_data),
312 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, 306 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
313 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, 307 { SN_PRESSURE, 0, 300 },
314 { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, 308 { SN_WIDTH, 0, 2048 },
315 { DIM_X, DIM_X / SN_COORD, -4616, 5112 }, 309 { SN_COORD, -4616, 5112 },
316 { DIM_Y, DIM_Y / SN_COORD, -142, 5234 } 310 { SN_COORD, -142, 5234 },
311 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
317 }, 312 },
318 { 313 {
319 USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI, 314 USB_DEVICE_ID_APPLE_WELLSPRING5_ANSI,
@@ -322,10 +317,11 @@ static const struct bcm5974_config bcm5974_config_table[] = {
322 HAS_INTEGRATED_BUTTON, 317 HAS_INTEGRATED_BUTTON,
323 0x84, sizeof(struct bt_data), 318 0x84, sizeof(struct bt_data),
324 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, 319 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
325 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, 320 { SN_PRESSURE, 0, 300 },
326 { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, 321 { SN_WIDTH, 0, 2048 },
327 { DIM_X, DIM_X / SN_COORD, -4415, 5050 }, 322 { SN_COORD, -4415, 5050 },
328 { DIM_Y, DIM_Y / SN_COORD, -55, 6680 } 323 { SN_COORD, -55, 6680 },
324 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
329 }, 325 },
330 { 326 {
331 USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI, 327 USB_DEVICE_ID_APPLE_WELLSPRING6_ANSI,
@@ -334,10 +330,11 @@ static const struct bcm5974_config bcm5974_config_table[] = {
334 HAS_INTEGRATED_BUTTON, 330 HAS_INTEGRATED_BUTTON,
335 0x84, sizeof(struct bt_data), 331 0x84, sizeof(struct bt_data),
336 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, 332 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
337 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, 333 { SN_PRESSURE, 0, 300 },
338 { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, 334 { SN_WIDTH, 0, 2048 },
339 { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, 335 { SN_COORD, -4620, 5140 },
340 { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } 336 { SN_COORD, -150, 6600 },
337 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
341 }, 338 },
342 { 339 {
343 USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI, 340 USB_DEVICE_ID_APPLE_WELLSPRING5A_ANSI,
@@ -346,10 +343,11 @@ static const struct bcm5974_config bcm5974_config_table[] = {
346 HAS_INTEGRATED_BUTTON, 343 HAS_INTEGRATED_BUTTON,
347 0x84, sizeof(struct bt_data), 344 0x84, sizeof(struct bt_data),
348 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, 345 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
349 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, 346 { SN_PRESSURE, 0, 300 },
350 { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, 347 { SN_WIDTH, 0, 2048 },
351 { DIM_X, DIM_X / SN_COORD, -4750, 5280 }, 348 { SN_COORD, -4750, 5280 },
352 { DIM_Y, DIM_Y / SN_COORD, -150, 6730 } 349 { SN_COORD, -150, 6730 },
350 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
353 }, 351 },
354 { 352 {
355 USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI, 353 USB_DEVICE_ID_APPLE_WELLSPRING6A_ANSI,
@@ -358,10 +356,11 @@ static const struct bcm5974_config bcm5974_config_table[] = {
358 HAS_INTEGRATED_BUTTON, 356 HAS_INTEGRATED_BUTTON,
359 0x84, sizeof(struct bt_data), 357 0x84, sizeof(struct bt_data),
360 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, 358 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
361 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, 359 { SN_PRESSURE, 0, 300 },
362 { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, 360 { SN_WIDTH, 0, 2048 },
363 { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, 361 { SN_COORD, -4620, 5140 },
364 { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } 362 { SN_COORD, -150, 6600 },
363 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
365 }, 364 },
366 { 365 {
367 USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI, 366 USB_DEVICE_ID_APPLE_WELLSPRING7_ANSI,
@@ -370,10 +369,11 @@ static const struct bcm5974_config bcm5974_config_table[] = {
370 HAS_INTEGRATED_BUTTON, 369 HAS_INTEGRATED_BUTTON,
371 0x84, sizeof(struct bt_data), 370 0x84, sizeof(struct bt_data),
372 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, 371 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS,
373 { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, 372 { SN_PRESSURE, 0, 300 },
374 { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, 373 { SN_WIDTH, 0, 2048 },
375 { DIM_X, DIM_X / SN_COORD, -4750, 5280 }, 374 { SN_COORD, -4750, 5280 },
376 { DIM_Y, DIM_Y / SN_COORD, -150, 6730 } 375 { SN_COORD, -150, 6730 },
376 { SN_ORIENT, -MAX_FINGER_ORIENTATION, MAX_FINGER_ORIENTATION }
377 }, 377 },
378 {} 378 {}
379}; 379};
@@ -397,18 +397,11 @@ static inline int raw2int(__le16 x)
397 return (signed short)le16_to_cpu(x); 397 return (signed short)le16_to_cpu(x);
398} 398}
399 399
400/* scale device data to logical dimensions (asserts devmin < devmax) */ 400static void set_abs(struct input_dev *input, unsigned int code,
401static inline int int2scale(const struct bcm5974_param *p, int x) 401 const struct bcm5974_param *p)
402{ 402{
403 return x * p->dim / (p->devmax - p->devmin); 403 int fuzz = p->snratio ? (p->max - p->min) / p->snratio : 0;
404} 404 input_set_abs_params(input, code, p->min, p->max, fuzz, 0);
405
406/* all logical value ranges are [0,dim). */
407static inline int int2bound(const struct bcm5974_param *p, int x)
408{
409 int s = int2scale(p, x);
410
411 return clamp_val(s, 0, p->dim - 1);
412} 405}
413 406
414/* setup which logical events to report */ 407/* setup which logical events to report */
@@ -417,34 +410,25 @@ static void setup_events_to_report(struct input_dev *input_dev,
417{ 410{
418 __set_bit(EV_ABS, input_dev->evbit); 411 __set_bit(EV_ABS, input_dev->evbit);
419 412
420 input_set_abs_params(input_dev, ABS_PRESSURE, 413 /* for synaptics only */
421 0, cfg->p.dim, cfg->p.fuzz, 0); 414 input_set_abs_params(input_dev, ABS_PRESSURE, 0, 256, 5, 0);
422 input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 415 input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 0, 16, 0, 0);
423 0, cfg->w.dim, cfg->w.fuzz, 0); 416
424 input_set_abs_params(input_dev, ABS_X, 417 /* pointer emulation */
425 0, cfg->x.dim, cfg->x.fuzz, 0); 418 set_abs(input_dev, ABS_X, &cfg->x);
426 input_set_abs_params(input_dev, ABS_Y, 419 set_abs(input_dev, ABS_Y, &cfg->y);
427 0, cfg->y.dim, cfg->y.fuzz, 0);
428 420
429 /* finger touch area */ 421 /* finger touch area */
430 input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 422 set_abs(input_dev, ABS_MT_TOUCH_MAJOR, &cfg->w);
431 cfg->w.devmin, cfg->w.devmax, 0, 0); 423 set_abs(input_dev, ABS_MT_TOUCH_MINOR, &cfg->w);
432 input_set_abs_params(input_dev, ABS_MT_TOUCH_MINOR,
433 cfg->w.devmin, cfg->w.devmax, 0, 0);
434 /* finger approach area */ 424 /* finger approach area */
435 input_set_abs_params(input_dev, ABS_MT_WIDTH_MAJOR, 425 set_abs(input_dev, ABS_MT_WIDTH_MAJOR, &cfg->w);
436 cfg->w.devmin, cfg->w.devmax, 0, 0); 426 set_abs(input_dev, ABS_MT_WIDTH_MINOR, &cfg->w);
437 input_set_abs_params(input_dev, ABS_MT_WIDTH_MINOR,
438 cfg->w.devmin, cfg->w.devmax, 0, 0);
439 /* finger orientation */ 427 /* finger orientation */
440 input_set_abs_params(input_dev, ABS_MT_ORIENTATION, 428 set_abs(input_dev, ABS_MT_ORIENTATION, &cfg->o);
441 -MAX_FINGER_ORIENTATION,
442 MAX_FINGER_ORIENTATION, 0, 0);
443 /* finger position */ 429 /* finger position */
444 input_set_abs_params(input_dev, ABS_MT_POSITION_X, 430 set_abs(input_dev, ABS_MT_POSITION_X, &cfg->x);
445 cfg->x.devmin, cfg->x.devmax, 0, 0); 431 set_abs(input_dev, ABS_MT_POSITION_Y, &cfg->y);
446 input_set_abs_params(input_dev, ABS_MT_POSITION_Y,
447 cfg->y.devmin, cfg->y.devmax, 0, 0);
448 432
449 __set_bit(EV_KEY, input_dev->evbit); 433 __set_bit(EV_KEY, input_dev->evbit);
450 __set_bit(BTN_TOUCH, input_dev->keybit); 434 __set_bit(BTN_TOUCH, input_dev->keybit);
@@ -494,19 +478,37 @@ static void report_finger_data(struct input_dev *input,
494 MAX_FINGER_ORIENTATION - raw2int(f->orientation)); 478 MAX_FINGER_ORIENTATION - raw2int(f->orientation));
495 input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x)); 479 input_report_abs(input, ABS_MT_POSITION_X, raw2int(f->abs_x));
496 input_report_abs(input, ABS_MT_POSITION_Y, 480 input_report_abs(input, ABS_MT_POSITION_Y,
497 cfg->y.devmin + cfg->y.devmax - raw2int(f->abs_y)); 481 cfg->y.min + cfg->y.max - raw2int(f->abs_y));
498 input_mt_sync(input); 482 input_mt_sync(input);
499} 483}
500 484
485static void report_synaptics_data(struct input_dev *input,
486 const struct bcm5974_config *cfg,
487 const struct tp_finger *f, int raw_n)
488{
489 int abs_p = 0, abs_w = 0;
490
491 if (raw_n) {
492 int p = raw2int(f->touch_major);
493 int w = raw2int(f->tool_major);
494 if (p > 0 && raw2int(f->origin)) {
495 abs_p = clamp_val(256 * p / cfg->p.max, 0, 255);
496 abs_w = clamp_val(16 * w / cfg->w.max, 0, 15);
497 }
498 }
499
500 input_report_abs(input, ABS_PRESSURE, abs_p);
501 input_report_abs(input, ABS_TOOL_WIDTH, abs_w);
502}
503
501/* report trackpad data as logical trackpad state */ 504/* report trackpad data as logical trackpad state */
502static int report_tp_state(struct bcm5974 *dev, int size) 505static int report_tp_state(struct bcm5974 *dev, int size)
503{ 506{
504 const struct bcm5974_config *c = &dev->cfg; 507 const struct bcm5974_config *c = &dev->cfg;
505 const struct tp_finger *f; 508 const struct tp_finger *f;
506 struct input_dev *input = dev->input; 509 struct input_dev *input = dev->input;
507 int raw_p, raw_w, raw_x, raw_y, raw_n, i; 510 int raw_n, i;
508 int ptest, origin, ibt = 0, nmin = 0, nmax = 0; 511 int abs_x = 0, abs_y = 0, n = 0;
509 int abs_p = 0, abs_w = 0, abs_x = 0, abs_y = 0;
510 512
511 if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0) 513 if (size < c->tp_offset || (size - c->tp_offset) % SIZEOF_FINGER != 0)
512 return -EIO; 514 return -EIO;
@@ -522,69 +524,34 @@ static int report_tp_state(struct bcm5974 *dev, int size)
522 for (i = 0; i < raw_n; i++) 524 for (i = 0; i < raw_n; i++)
523 report_finger_data(input, c, &f[i]); 525 report_finger_data(input, c, &f[i]);
524 526
525 raw_p = raw2int(f->touch_major);
526 raw_w = raw2int(f->tool_major);
527 raw_x = raw2int(f->abs_x);
528 raw_y = raw2int(f->abs_y);
529
530 dprintk(9,
531 "bcm5974: "
532 "raw: p: %+05d w: %+05d x: %+05d y: %+05d n: %d\n",
533 raw_p, raw_w, raw_x, raw_y, raw_n);
534
535 ptest = int2bound(&c->p, raw_p);
536 origin = raw2int(f->origin);
537
538 /* while tracking finger still valid, count all fingers */ 527 /* while tracking finger still valid, count all fingers */
539 if (ptest > PRESSURE_LOW && origin) { 528 if (raw2int(f->touch_major) > 0 && raw2int(f->origin)) {
540 abs_p = ptest; 529 abs_x = raw2int(f->abs_x);
541 abs_w = int2bound(&c->w, raw_w); 530 abs_y = c->y.min + c->y.max - raw2int(f->abs_y);
542 abs_x = int2bound(&c->x, raw_x - c->x.devmin); 531 for (i = 0; i < raw_n; i++)
543 abs_y = int2bound(&c->y, c->y.devmax - raw_y); 532 if (raw2int(f[i].touch_major) > 0)
544 while (raw_n--) { 533 n++;
545 ptest = int2bound(&c->p,
546 raw2int(f->touch_major));
547 if (ptest > PRESSURE_LOW)
548 nmax++;
549 if (ptest > PRESSURE_HIGH)
550 nmin++;
551 f++;
552 }
553 } 534 }
554 } 535 }
555 536
556 /* set the integrated button if applicable */ 537 input_report_key(input, BTN_TOUCH, n > 0);
557 if (c->tp_type == TYPE2) 538 input_report_key(input, BTN_TOOL_FINGER, n == 1);
558 ibt = raw2int(dev->tp_data[BUTTON_TYPE2]); 539 input_report_key(input, BTN_TOOL_DOUBLETAP, n == 2);
559 540 input_report_key(input, BTN_TOOL_TRIPLETAP, n == 3);
560 if (dev->fingers < nmin) 541 input_report_key(input, BTN_TOOL_QUADTAP, n > 3);
561 dev->fingers = nmin;
562 if (dev->fingers > nmax)
563 dev->fingers = nmax;
564 542
565 input_report_key(input, BTN_TOUCH, dev->fingers > 0); 543 report_synaptics_data(input, c, f, raw_n);
566 input_report_key(input, BTN_TOOL_FINGER, dev->fingers == 1);
567 input_report_key(input, BTN_TOOL_DOUBLETAP, dev->fingers == 2);
568 input_report_key(input, BTN_TOOL_TRIPLETAP, dev->fingers == 3);
569 input_report_key(input, BTN_TOOL_QUADTAP, dev->fingers > 3);
570 544
571 input_report_abs(input, ABS_PRESSURE, abs_p); 545 if (n > 0) {
572 input_report_abs(input, ABS_TOOL_WIDTH, abs_w);
573
574 if (abs_p) {
575 input_report_abs(input, ABS_X, abs_x); 546 input_report_abs(input, ABS_X, abs_x);
576 input_report_abs(input, ABS_Y, abs_y); 547 input_report_abs(input, ABS_Y, abs_y);
577
578 dprintk(8,
579 "bcm5974: abs: p: %+05d w: %+05d x: %+05d y: %+05d "
580 "nmin: %d nmax: %d n: %d ibt: %d\n", abs_p, abs_w,
581 abs_x, abs_y, nmin, nmax, dev->fingers, ibt);
582
583 } 548 }
584 549
585 /* type 2 reports button events via ibt only */ 550 /* type 2 reports button events via ibt only */
586 if (c->tp_type == TYPE2) 551 if (c->tp_type == TYPE2) {
552 int ibt = raw2int(dev->tp_data[BUTTON_TYPE2]);
587 input_report_key(input, BTN_LEFT, ibt); 553 input_report_key(input, BTN_LEFT, ibt);
554 }
588 555
589 input_sync(input); 556 input_sync(input);
590 557