diff options
Diffstat (limited to 'drivers/input/mouse')
-rw-r--r-- | drivers/input/mouse/bcm5974.c | 255 |
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 */ |
202 | struct bcm5974_param { | 202 | struct 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 */ |
257 | static const struct bcm5974_config bcm5974_config_table[] = { | 247 | static 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) */ | 400 | static void set_abs(struct input_dev *input, unsigned int code, |
401 | static 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). */ | ||
407 | static 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 | ||
485 | static 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 */ |
502 | static int report_tp_state(struct bcm5974 *dev, int size) | 505 | static 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 | ||