aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/mouse
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2012-09-15 03:49:51 -0400
committerHenrik Rydberg <rydberg@euromail.se>2012-09-19 13:50:22 -0400
commit0e7269669d4cd14a49b4e5c708b8be0ba11504f7 (patch)
tree8f1316af57b6bc431208005325c37886686e0c38 /drivers/input/mouse
parentf17953abc92a7d536f4b9b9ce42cf8e07d8d3489 (diff)
Input: bcm5974 - Drop the logical dimensions
The logical scale is used to produce special finger width values to userspace, but has become an unnecessary restriction for everything else. Also, the bcm5974 trackpads are very accurate and work well without hysteresis. This patch simplifies the driver and device data by removing the logical scale, and by moving the special synaptics code out of the main path. Also add the orientation range, needed in a subsequent patch, to the device configuration. Tested-by: Benjamin Tissoires <benjamin.tissoires@enac.fr> Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
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