diff options
| author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2014-08-07 02:36:12 -0400 |
|---|---|---|
| committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2014-08-07 02:36:12 -0400 |
| commit | 5e2aa2ed08e2e280121dc7cf5609c87d464f12ef (patch) | |
| tree | ca7d7b1480285e3b617fecc5b41f0ce150a82c32 /drivers/input/mouse | |
| parent | f62d14a8072b9756db36ba394e2b267470a40240 (diff) | |
| parent | fc8104bc5a3f6f49d79f45f2706f79f77a9fb2ae (diff) | |
Merge branch 'next' into for-linus
Prepare first round of input updates for 3.17.
Diffstat (limited to 'drivers/input/mouse')
| -rw-r--r-- | drivers/input/mouse/alps.c | 691 | ||||
| -rw-r--r-- | drivers/input/mouse/alps.h | 60 |
2 files changed, 508 insertions, 243 deletions
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index fb15c64ffb95..a59a1a64b674 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
| @@ -99,6 +99,8 @@ static const struct alps_nibble_commands alps_v6_nibble_commands[] = { | |||
| 99 | #define ALPS_FOUR_BUTTONS 0x40 /* 4 direction button present */ | 99 | #define ALPS_FOUR_BUTTONS 0x40 /* 4 direction button present */ |
| 100 | #define ALPS_PS2_INTERLEAVED 0x80 /* 3-byte PS/2 packet interleaved with | 100 | #define ALPS_PS2_INTERLEAVED 0x80 /* 3-byte PS/2 packet interleaved with |
| 101 | 6-byte ALPS packet */ | 101 | 6-byte ALPS packet */ |
| 102 | #define ALPS_IS_RUSHMORE 0x100 /* device is a rushmore */ | ||
| 103 | #define ALPS_BUTTONPAD 0x200 /* device is a clickpad */ | ||
| 102 | 104 | ||
| 103 | static const struct alps_model_info alps_model_data[] = { | 105 | static const struct alps_model_info alps_model_data[] = { |
| 104 | { { 0x32, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */ | 106 | { { 0x32, 0x02, 0x14 }, 0x00, ALPS_PROTO_V2, 0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* Toshiba Salellite Pro M10 */ |
| @@ -281,11 +283,10 @@ static void alps_process_packet_v1_v2(struct psmouse *psmouse) | |||
| 281 | * | 283 | * |
| 282 | * The bitmaps don't have enough data to track fingers, so this function | 284 | * The bitmaps don't have enough data to track fingers, so this function |
| 283 | * only generates points representing a bounding box of at most two contacts. | 285 | * only generates points representing a bounding box of at most two contacts. |
| 284 | * These two points are returned in x1, y1, x2, and y2. | 286 | * These two points are returned in fields->mt. |
| 285 | */ | 287 | */ |
| 286 | static void alps_process_bitmap_dolphin(struct alps_data *priv, | 288 | static void alps_process_bitmap_dolphin(struct alps_data *priv, |
| 287 | struct alps_fields *fields, | 289 | struct alps_fields *fields) |
| 288 | int *x1, int *y1, int *x2, int *y2) | ||
| 289 | { | 290 | { |
| 290 | int box_middle_x, box_middle_y; | 291 | int box_middle_x, box_middle_y; |
| 291 | unsigned int x_map, y_map; | 292 | unsigned int x_map, y_map; |
| @@ -308,8 +309,6 @@ static void alps_process_bitmap_dolphin(struct alps_data *priv, | |||
| 308 | if (x_msb > priv->x_bits || y_msb > priv->y_bits) | 309 | if (x_msb > priv->x_bits || y_msb > priv->y_bits) |
| 309 | return; | 310 | return; |
| 310 | 311 | ||
| 311 | *x1 = *y1 = *x2 = *y2 = 0; | ||
| 312 | |||
| 313 | if (fields->fingers > 1) { | 312 | if (fields->fingers > 1) { |
| 314 | start_bit = priv->x_bits - x_msb; | 313 | start_bit = priv->x_bits - x_msb; |
| 315 | end_bit = priv->x_bits - x_lsb; | 314 | end_bit = priv->x_bits - x_lsb; |
| @@ -320,10 +319,35 @@ static void alps_process_bitmap_dolphin(struct alps_data *priv, | |||
| 320 | end_bit = y_msb - 1; | 319 | end_bit = y_msb - 1; |
| 321 | box_middle_y = (priv->y_max * (start_bit + end_bit)) / | 320 | box_middle_y = (priv->y_max * (start_bit + end_bit)) / |
| 322 | (2 * (priv->y_bits - 1)); | 321 | (2 * (priv->y_bits - 1)); |
| 323 | *x1 = fields->x; | 322 | fields->mt[0] = fields->st; |
| 324 | *y1 = fields->y; | 323 | fields->mt[1].x = 2 * box_middle_x - fields->mt[0].x; |
| 325 | *x2 = 2 * box_middle_x - *x1; | 324 | fields->mt[1].y = 2 * box_middle_y - fields->mt[0].y; |
| 326 | *y2 = 2 * box_middle_y - *y1; | 325 | } |
| 326 | } | ||
| 327 | |||
| 328 | static void alps_get_bitmap_points(unsigned int map, | ||
| 329 | struct alps_bitmap_point *low, | ||
| 330 | struct alps_bitmap_point *high, | ||
| 331 | int *fingers) | ||
| 332 | { | ||
| 333 | struct alps_bitmap_point *point; | ||
| 334 | int i, bit, prev_bit = 0; | ||
| 335 | |||
| 336 | point = low; | ||
| 337 | for (i = 0; map != 0; i++, map >>= 1) { | ||
| 338 | bit = map & 1; | ||
| 339 | if (bit) { | ||
| 340 | if (!prev_bit) { | ||
| 341 | point->start_bit = i; | ||
| 342 | point->num_bits = 0; | ||
| 343 | (*fingers)++; | ||
| 344 | } | ||
| 345 | point->num_bits++; | ||
| 346 | } else { | ||
| 347 | if (prev_bit) | ||
| 348 | point = high; | ||
| 349 | } | ||
| 350 | prev_bit = bit; | ||
| 327 | } | 351 | } |
| 328 | } | 352 | } |
| 329 | 353 | ||
| @@ -334,71 +358,21 @@ static void alps_process_bitmap_dolphin(struct alps_data *priv, | |||
| 334 | * | 358 | * |
| 335 | * The bitmaps don't have enough data to track fingers, so this function | 359 | * The bitmaps don't have enough data to track fingers, so this function |
| 336 | * only generates points representing a bounding box of all contacts. | 360 | * only generates points representing a bounding box of all contacts. |
| 337 | * These points are returned in x1, y1, x2, and y2 when the return value | 361 | * These points are returned in fields->mt when the return value |
| 338 | * is greater than 0. | 362 | * is greater than 0. |
| 339 | */ | 363 | */ |
| 340 | static int alps_process_bitmap(struct alps_data *priv, | 364 | static int alps_process_bitmap(struct alps_data *priv, |
| 341 | unsigned int x_map, unsigned int y_map, | 365 | struct alps_fields *fields) |
| 342 | int *x1, int *y1, int *x2, int *y2) | ||
| 343 | { | 366 | { |
| 344 | struct alps_bitmap_point { | 367 | int i, fingers_x = 0, fingers_y = 0, fingers; |
| 345 | int start_bit; | ||
| 346 | int num_bits; | ||
| 347 | }; | ||
| 348 | |||
| 349 | int fingers_x = 0, fingers_y = 0, fingers; | ||
| 350 | int i, bit, prev_bit; | ||
| 351 | struct alps_bitmap_point x_low = {0,}, x_high = {0,}; | 368 | struct alps_bitmap_point x_low = {0,}, x_high = {0,}; |
| 352 | struct alps_bitmap_point y_low = {0,}, y_high = {0,}; | 369 | struct alps_bitmap_point y_low = {0,}, y_high = {0,}; |
| 353 | struct alps_bitmap_point *point; | ||
| 354 | 370 | ||
| 355 | if (!x_map || !y_map) | 371 | if (!fields->x_map || !fields->y_map) |
| 356 | return 0; | 372 | return 0; |
| 357 | 373 | ||
| 358 | *x1 = *y1 = *x2 = *y2 = 0; | 374 | alps_get_bitmap_points(fields->x_map, &x_low, &x_high, &fingers_x); |
| 359 | 375 | alps_get_bitmap_points(fields->y_map, &y_low, &y_high, &fingers_y); | |
| 360 | prev_bit = 0; | ||
| 361 | point = &x_low; | ||
| 362 | for (i = 0; x_map != 0; i++, x_map >>= 1) { | ||
| 363 | bit = x_map & 1; | ||
| 364 | if (bit) { | ||
| 365 | if (!prev_bit) { | ||
| 366 | point->start_bit = i; | ||
| 367 | fingers_x++; | ||
| 368 | } | ||
| 369 | point->num_bits++; | ||
| 370 | } else { | ||
| 371 | if (prev_bit) | ||
| 372 | point = &x_high; | ||
| 373 | else | ||
| 374 | point->num_bits = 0; | ||
| 375 | } | ||
| 376 | prev_bit = bit; | ||
| 377 | } | ||
| 378 | |||
| 379 | /* | ||
| 380 | * y bitmap is reversed for what we need (lower positions are in | ||
| 381 | * higher bits), so we process from the top end. | ||
| 382 | */ | ||
| 383 | y_map = y_map << (sizeof(y_map) * BITS_PER_BYTE - priv->y_bits); | ||
| 384 | prev_bit = 0; | ||
| 385 | point = &y_low; | ||
| 386 | for (i = 0; y_map != 0; i++, y_map <<= 1) { | ||
| 387 | bit = y_map & (1 << (sizeof(y_map) * BITS_PER_BYTE - 1)); | ||
| 388 | if (bit) { | ||
| 389 | if (!prev_bit) { | ||
| 390 | point->start_bit = i; | ||
| 391 | fingers_y++; | ||
| 392 | } | ||
| 393 | point->num_bits++; | ||
| 394 | } else { | ||
| 395 | if (prev_bit) | ||
| 396 | point = &y_high; | ||
| 397 | else | ||
| 398 | point->num_bits = 0; | ||
| 399 | } | ||
| 400 | prev_bit = bit; | ||
| 401 | } | ||
| 402 | 376 | ||
| 403 | /* | 377 | /* |
| 404 | * Fingers can overlap, so we use the maximum count of fingers | 378 | * Fingers can overlap, so we use the maximum count of fingers |
| @@ -407,58 +381,91 @@ static int alps_process_bitmap(struct alps_data *priv, | |||
| 407 | fingers = max(fingers_x, fingers_y); | 381 | fingers = max(fingers_x, fingers_y); |
| 408 | 382 | ||
| 409 | /* | 383 | /* |
| 410 | * If total fingers is > 1 but either axis reports only a single | 384 | * If an axis reports only a single contact, we have overlapping or |
| 411 | * contact, we have overlapping or adjacent fingers. For the | 385 | * adjacent fingers. Divide the single contact between the two points. |
| 412 | * purposes of creating a bounding box, divide the single contact | ||
| 413 | * (roughly) equally between the two points. | ||
| 414 | */ | 386 | */ |
| 415 | if (fingers > 1) { | 387 | if (fingers_x == 1) { |
| 416 | if (fingers_x == 1) { | 388 | i = (x_low.num_bits - 1) / 2; |
| 417 | i = x_low.num_bits / 2; | 389 | x_low.num_bits = x_low.num_bits - i; |
| 418 | x_low.num_bits = x_low.num_bits - i; | 390 | x_high.start_bit = x_low.start_bit + i; |
| 419 | x_high.start_bit = x_low.start_bit + i; | 391 | x_high.num_bits = max(i, 1); |
| 420 | x_high.num_bits = max(i, 1); | 392 | } |
| 421 | } else if (fingers_y == 1) { | 393 | if (fingers_y == 1) { |
| 422 | i = y_low.num_bits / 2; | 394 | i = (y_low.num_bits - 1) / 2; |
| 423 | y_low.num_bits = y_low.num_bits - i; | 395 | y_low.num_bits = y_low.num_bits - i; |
| 424 | y_high.start_bit = y_low.start_bit + i; | 396 | y_high.start_bit = y_low.start_bit + i; |
| 425 | y_high.num_bits = max(i, 1); | 397 | y_high.num_bits = max(i, 1); |
| 426 | } | ||
| 427 | } | 398 | } |
| 428 | 399 | ||
| 429 | *x1 = (priv->x_max * (2 * x_low.start_bit + x_low.num_bits - 1)) / | 400 | fields->mt[0].x = |
| 430 | (2 * (priv->x_bits - 1)); | 401 | (priv->x_max * (2 * x_low.start_bit + x_low.num_bits - 1)) / |
| 431 | *y1 = (priv->y_max * (2 * y_low.start_bit + y_low.num_bits - 1)) / | 402 | (2 * (priv->x_bits - 1)); |
| 432 | (2 * (priv->y_bits - 1)); | 403 | fields->mt[0].y = |
| 433 | 404 | (priv->y_max * (2 * y_low.start_bit + y_low.num_bits - 1)) / | |
| 434 | if (fingers > 1) { | 405 | (2 * (priv->y_bits - 1)); |
| 435 | *x2 = (priv->x_max * | 406 | |
| 436 | (2 * x_high.start_bit + x_high.num_bits - 1)) / | 407 | fields->mt[1].x = |
| 437 | (2 * (priv->x_bits - 1)); | 408 | (priv->x_max * (2 * x_high.start_bit + x_high.num_bits - 1)) / |
| 438 | *y2 = (priv->y_max * | 409 | (2 * (priv->x_bits - 1)); |
| 439 | (2 * y_high.start_bit + y_high.num_bits - 1)) / | 410 | fields->mt[1].y = |
| 440 | (2 * (priv->y_bits - 1)); | 411 | (priv->y_max * (2 * y_high.start_bit + y_high.num_bits - 1)) / |
| 412 | (2 * (priv->y_bits - 1)); | ||
| 413 | |||
| 414 | /* y-bitmap order is reversed, except on rushmore */ | ||
| 415 | if (!(priv->flags & ALPS_IS_RUSHMORE)) { | ||
| 416 | fields->mt[0].y = priv->y_max - fields->mt[0].y; | ||
| 417 | fields->mt[1].y = priv->y_max - fields->mt[1].y; | ||
| 441 | } | 418 | } |
| 442 | 419 | ||
| 443 | return fingers; | 420 | return fingers; |
| 444 | } | 421 | } |
| 445 | 422 | ||
| 446 | static void alps_set_slot(struct input_dev *dev, int slot, bool active, | 423 | static void alps_set_slot(struct input_dev *dev, int slot, int x, int y) |
| 447 | int x, int y) | ||
| 448 | { | 424 | { |
| 449 | input_mt_slot(dev, slot); | 425 | input_mt_slot(dev, slot); |
| 450 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, active); | 426 | input_mt_report_slot_state(dev, MT_TOOL_FINGER, true); |
| 451 | if (active) { | 427 | input_report_abs(dev, ABS_MT_POSITION_X, x); |
| 452 | input_report_abs(dev, ABS_MT_POSITION_X, x); | 428 | input_report_abs(dev, ABS_MT_POSITION_Y, y); |
| 453 | input_report_abs(dev, ABS_MT_POSITION_Y, y); | ||
| 454 | } | ||
| 455 | } | 429 | } |
| 456 | 430 | ||
| 457 | static void alps_report_semi_mt_data(struct input_dev *dev, int num_fingers, | 431 | static void alps_report_mt_data(struct psmouse *psmouse, int n) |
| 458 | int x1, int y1, int x2, int y2) | ||
| 459 | { | 432 | { |
| 460 | alps_set_slot(dev, 0, num_fingers != 0, x1, y1); | 433 | struct alps_data *priv = psmouse->private; |
| 461 | alps_set_slot(dev, 1, num_fingers == 2, x2, y2); | 434 | struct input_dev *dev = psmouse->dev; |
| 435 | struct alps_fields *f = &priv->f; | ||
| 436 | int i, slot[MAX_TOUCHES]; | ||
| 437 | |||
| 438 | input_mt_assign_slots(dev, slot, f->mt, n); | ||
| 439 | for (i = 0; i < n; i++) | ||
| 440 | alps_set_slot(dev, slot[i], f->mt[i].x, f->mt[i].y); | ||
| 441 | |||
| 442 | input_mt_sync_frame(dev); | ||
| 443 | } | ||
| 444 | |||
| 445 | static void alps_report_semi_mt_data(struct psmouse *psmouse, int fingers) | ||
| 446 | { | ||
| 447 | struct alps_data *priv = psmouse->private; | ||
| 448 | struct input_dev *dev = psmouse->dev; | ||
| 449 | struct alps_fields *f = &priv->f; | ||
| 450 | |||
| 451 | /* Use st data when we don't have mt data */ | ||
| 452 | if (fingers < 2) { | ||
| 453 | f->mt[0].x = f->st.x; | ||
| 454 | f->mt[0].y = f->st.y; | ||
| 455 | fingers = f->pressure > 0 ? 1 : 0; | ||
| 456 | } | ||
| 457 | |||
| 458 | alps_report_mt_data(psmouse, (fingers <= 2) ? fingers : 2); | ||
| 459 | |||
| 460 | input_mt_report_finger_count(dev, fingers); | ||
| 461 | |||
| 462 | input_report_key(dev, BTN_LEFT, f->left); | ||
| 463 | input_report_key(dev, BTN_RIGHT, f->right); | ||
| 464 | input_report_key(dev, BTN_MIDDLE, f->middle); | ||
| 465 | |||
| 466 | input_report_abs(dev, ABS_PRESSURE, f->pressure); | ||
| 467 | |||
| 468 | input_sync(dev); | ||
| 462 | } | 469 | } |
| 463 | 470 | ||
| 464 | static void alps_process_trackstick_packet_v3(struct psmouse *psmouse) | 471 | static void alps_process_trackstick_packet_v3(struct psmouse *psmouse) |
| @@ -532,7 +539,7 @@ static void alps_decode_buttons_v3(struct alps_fields *f, unsigned char *p) | |||
| 532 | f->ts_middle = !!(p[3] & 0x40); | 539 | f->ts_middle = !!(p[3] & 0x40); |
| 533 | } | 540 | } |
| 534 | 541 | ||
| 535 | static void alps_decode_pinnacle(struct alps_fields *f, unsigned char *p, | 542 | static int alps_decode_pinnacle(struct alps_fields *f, unsigned char *p, |
| 536 | struct psmouse *psmouse) | 543 | struct psmouse *psmouse) |
| 537 | { | 544 | { |
| 538 | f->first_mp = !!(p[4] & 0x40); | 545 | f->first_mp = !!(p[4] & 0x40); |
| @@ -546,24 +553,31 @@ static void alps_decode_pinnacle(struct alps_fields *f, unsigned char *p, | |||
| 546 | ((p[2] & 0x7f) << 1) | | 553 | ((p[2] & 0x7f) << 1) | |
| 547 | (p[4] & 0x01); | 554 | (p[4] & 0x01); |
| 548 | 555 | ||
| 549 | f->x = ((p[1] & 0x7f) << 4) | ((p[4] & 0x30) >> 2) | | 556 | f->st.x = ((p[1] & 0x7f) << 4) | ((p[4] & 0x30) >> 2) | |
| 550 | ((p[0] & 0x30) >> 4); | 557 | ((p[0] & 0x30) >> 4); |
| 551 | f->y = ((p[2] & 0x7f) << 4) | (p[4] & 0x0f); | 558 | f->st.y = ((p[2] & 0x7f) << 4) | (p[4] & 0x0f); |
| 552 | f->z = p[5] & 0x7f; | 559 | f->pressure = p[5] & 0x7f; |
| 553 | 560 | ||
| 554 | alps_decode_buttons_v3(f, p); | 561 | alps_decode_buttons_v3(f, p); |
| 562 | |||
| 563 | return 0; | ||
| 555 | } | 564 | } |
| 556 | 565 | ||
| 557 | static void alps_decode_rushmore(struct alps_fields *f, unsigned char *p, | 566 | static int alps_decode_rushmore(struct alps_fields *f, unsigned char *p, |
| 558 | struct psmouse *psmouse) | 567 | struct psmouse *psmouse) |
| 559 | { | 568 | { |
| 560 | alps_decode_pinnacle(f, p, psmouse); | 569 | alps_decode_pinnacle(f, p, psmouse); |
| 561 | 570 | ||
| 571 | /* Rushmore's packet decode has a bit difference with Pinnacle's */ | ||
| 572 | f->is_mp = !!(p[5] & 0x40); | ||
| 573 | f->fingers = max((p[5] & 0x3), ((p[5] >> 2) & 0x3)) + 1; | ||
| 562 | f->x_map |= (p[5] & 0x10) << 11; | 574 | f->x_map |= (p[5] & 0x10) << 11; |
| 563 | f->y_map |= (p[5] & 0x20) << 6; | 575 | f->y_map |= (p[5] & 0x20) << 6; |
| 576 | |||
| 577 | return 0; | ||
| 564 | } | 578 | } |
| 565 | 579 | ||
| 566 | static void alps_decode_dolphin(struct alps_fields *f, unsigned char *p, | 580 | static int alps_decode_dolphin(struct alps_fields *f, unsigned char *p, |
| 567 | struct psmouse *psmouse) | 581 | struct psmouse *psmouse) |
| 568 | { | 582 | { |
| 569 | u64 palm_data = 0; | 583 | u64 palm_data = 0; |
| @@ -573,9 +587,9 @@ static void alps_decode_dolphin(struct alps_fields *f, unsigned char *p, | |||
| 573 | f->is_mp = !!(p[0] & 0x20); | 587 | f->is_mp = !!(p[0] & 0x20); |
| 574 | 588 | ||
| 575 | if (!f->is_mp) { | 589 | if (!f->is_mp) { |
| 576 | f->x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7)); | 590 | f->st.x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7)); |
| 577 | f->y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3)); | 591 | f->st.y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3)); |
| 578 | f->z = (p[0] & 4) ? 0 : p[5] & 0x7f; | 592 | f->pressure = (p[0] & 4) ? 0 : p[5] & 0x7f; |
| 579 | alps_decode_buttons_v3(f, p); | 593 | alps_decode_buttons_v3(f, p); |
| 580 | } else { | 594 | } else { |
| 581 | f->fingers = ((p[0] & 0x6) >> 1 | | 595 | f->fingers = ((p[0] & 0x6) >> 1 | |
| @@ -596,19 +610,21 @@ static void alps_decode_dolphin(struct alps_fields *f, unsigned char *p, | |||
| 596 | f->x_map = (palm_data >> priv->y_bits) & | 610 | f->x_map = (palm_data >> priv->y_bits) & |
| 597 | (BIT(priv->x_bits) - 1); | 611 | (BIT(priv->x_bits) - 1); |
| 598 | } | 612 | } |
| 613 | |||
| 614 | return 0; | ||
| 599 | } | 615 | } |
| 600 | 616 | ||
| 601 | static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse) | 617 | static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse) |
| 602 | { | 618 | { |
| 603 | struct alps_data *priv = psmouse->private; | 619 | struct alps_data *priv = psmouse->private; |
| 604 | unsigned char *packet = psmouse->packet; | 620 | unsigned char *packet = psmouse->packet; |
| 605 | struct input_dev *dev = psmouse->dev; | ||
| 606 | struct input_dev *dev2 = priv->dev2; | 621 | struct input_dev *dev2 = priv->dev2; |
| 607 | int x1 = 0, y1 = 0, x2 = 0, y2 = 0; | 622 | struct alps_fields *f = &priv->f; |
| 608 | int fingers = 0, bmap_fn; | 623 | int fingers = 0; |
| 609 | struct alps_fields f = {0}; | ||
| 610 | 624 | ||
| 611 | priv->decode_fields(&f, packet, psmouse); | 625 | memset(f, 0, sizeof(*f)); |
| 626 | |||
| 627 | priv->decode_fields(f, packet, psmouse); | ||
| 612 | 628 | ||
| 613 | /* | 629 | /* |
| 614 | * There's no single feature of touchpad position and bitmap packets | 630 | * There's no single feature of touchpad position and bitmap packets |
| @@ -623,22 +639,14 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse) | |||
| 623 | * packet. Check for this, and when it happens process the | 639 | * packet. Check for this, and when it happens process the |
| 624 | * position packet as usual. | 640 | * position packet as usual. |
| 625 | */ | 641 | */ |
| 626 | if (f.is_mp) { | 642 | if (f->is_mp) { |
| 627 | fingers = f.fingers; | 643 | fingers = f->fingers; |
| 628 | if (priv->proto_version == ALPS_PROTO_V3) { | 644 | if (priv->proto_version == ALPS_PROTO_V3) { |
| 629 | bmap_fn = alps_process_bitmap(priv, f.x_map, | 645 | if (alps_process_bitmap(priv, f) == 0) |
| 630 | f.y_map, &x1, &y1, | 646 | fingers = 0; /* Use st data */ |
| 631 | &x2, &y2); | ||
| 632 | |||
| 633 | /* | ||
| 634 | * We shouldn't report more than one finger if | ||
| 635 | * we don't have two coordinates. | ||
| 636 | */ | ||
| 637 | if (fingers > 1 && bmap_fn < 2) | ||
| 638 | fingers = bmap_fn; | ||
| 639 | 647 | ||
| 640 | /* Now process position packet */ | 648 | /* Now process position packet */ |
| 641 | priv->decode_fields(&f, priv->multi_data, | 649 | priv->decode_fields(f, priv->multi_data, |
| 642 | psmouse); | 650 | psmouse); |
| 643 | } else { | 651 | } else { |
| 644 | /* | 652 | /* |
| @@ -647,15 +655,14 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse) | |||
| 647 | * calculate Pt2, so we need to do position | 655 | * calculate Pt2, so we need to do position |
| 648 | * packet decode first. | 656 | * packet decode first. |
| 649 | */ | 657 | */ |
| 650 | priv->decode_fields(&f, priv->multi_data, | 658 | priv->decode_fields(f, priv->multi_data, |
| 651 | psmouse); | 659 | psmouse); |
| 652 | 660 | ||
| 653 | /* | 661 | /* |
| 654 | * Since Dolphin's finger number is reliable, | 662 | * Since Dolphin's finger number is reliable, |
| 655 | * there is no need to compare with bmap_fn. | 663 | * there is no need to compare with bmap_fn. |
| 656 | */ | 664 | */ |
| 657 | alps_process_bitmap_dolphin(priv, &f, &x1, &y1, | 665 | alps_process_bitmap_dolphin(priv, f); |
| 658 | &x2, &y2); | ||
| 659 | } | 666 | } |
| 660 | } else { | 667 | } else { |
| 661 | priv->multi_packet = 0; | 668 | priv->multi_packet = 0; |
| @@ -670,10 +677,10 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse) | |||
| 670 | * out misidentified bitmap packets, we reject anything with this | 677 | * out misidentified bitmap packets, we reject anything with this |
| 671 | * bit set. | 678 | * bit set. |
| 672 | */ | 679 | */ |
| 673 | if (f.is_mp) | 680 | if (f->is_mp) |
| 674 | return; | 681 | return; |
| 675 | 682 | ||
| 676 | if (!priv->multi_packet && f.first_mp) { | 683 | if (!priv->multi_packet && f->first_mp) { |
| 677 | priv->multi_packet = 1; | 684 | priv->multi_packet = 1; |
| 678 | memcpy(priv->multi_data, packet, sizeof(priv->multi_data)); | 685 | memcpy(priv->multi_data, packet, sizeof(priv->multi_data)); |
| 679 | return; | 686 | return; |
| @@ -687,44 +694,15 @@ static void alps_process_touchpad_packet_v3_v5(struct psmouse *psmouse) | |||
| 687 | * with x, y, and z all zero, so these seem to be flukes. | 694 | * with x, y, and z all zero, so these seem to be flukes. |
| 688 | * Ignore them. | 695 | * Ignore them. |
| 689 | */ | 696 | */ |
| 690 | if (f.x && f.y && !f.z) | 697 | if (f->st.x && f->st.y && !f->pressure) |
| 691 | return; | 698 | return; |
| 692 | 699 | ||
| 693 | /* | 700 | alps_report_semi_mt_data(psmouse, fingers); |
| 694 | * If we don't have MT data or the bitmaps were empty, we have | ||
| 695 | * to rely on ST data. | ||
| 696 | */ | ||
| 697 | if (!fingers) { | ||
| 698 | x1 = f.x; | ||
| 699 | y1 = f.y; | ||
| 700 | fingers = f.z > 0 ? 1 : 0; | ||
| 701 | } | ||
| 702 | |||
| 703 | if (f.z >= 64) | ||
| 704 | input_report_key(dev, BTN_TOUCH, 1); | ||
| 705 | else | ||
| 706 | input_report_key(dev, BTN_TOUCH, 0); | ||
| 707 | |||
| 708 | alps_report_semi_mt_data(dev, fingers, x1, y1, x2, y2); | ||
| 709 | |||
| 710 | input_mt_report_finger_count(dev, fingers); | ||
| 711 | |||
| 712 | input_report_key(dev, BTN_LEFT, f.left); | ||
| 713 | input_report_key(dev, BTN_RIGHT, f.right); | ||
| 714 | input_report_key(dev, BTN_MIDDLE, f.middle); | ||
| 715 | |||
| 716 | if (f.z > 0) { | ||
| 717 | input_report_abs(dev, ABS_X, f.x); | ||
| 718 | input_report_abs(dev, ABS_Y, f.y); | ||
| 719 | } | ||
| 720 | input_report_abs(dev, ABS_PRESSURE, f.z); | ||
| 721 | |||
| 722 | input_sync(dev); | ||
| 723 | 701 | ||
| 724 | if (!(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS)) { | 702 | if (!(priv->quirks & ALPS_QUIRK_TRACKSTICK_BUTTONS)) { |
| 725 | input_report_key(dev2, BTN_LEFT, f.ts_left); | 703 | input_report_key(dev2, BTN_LEFT, f->ts_left); |
| 726 | input_report_key(dev2, BTN_RIGHT, f.ts_right); | 704 | input_report_key(dev2, BTN_RIGHT, f->ts_right); |
| 727 | input_report_key(dev2, BTN_MIDDLE, f.ts_middle); | 705 | input_report_key(dev2, BTN_MIDDLE, f->ts_middle); |
| 728 | input_sync(dev2); | 706 | input_sync(dev2); |
| 729 | } | 707 | } |
| 730 | } | 708 | } |
| @@ -823,13 +801,8 @@ static void alps_process_packet_v4(struct psmouse *psmouse) | |||
| 823 | { | 801 | { |
| 824 | struct alps_data *priv = psmouse->private; | 802 | struct alps_data *priv = psmouse->private; |
| 825 | unsigned char *packet = psmouse->packet; | 803 | unsigned char *packet = psmouse->packet; |
| 826 | struct input_dev *dev = psmouse->dev; | 804 | struct alps_fields *f = &priv->f; |
| 827 | int offset; | 805 | int offset; |
| 828 | int x, y, z; | ||
| 829 | int left, right; | ||
| 830 | int x1, y1, x2, y2; | ||
| 831 | int fingers = 0; | ||
| 832 | unsigned int x_bitmap, y_bitmap; | ||
| 833 | 806 | ||
| 834 | /* | 807 | /* |
| 835 | * v4 has a 6-byte encoding for bitmap data, but this data is | 808 | * v4 has a 6-byte encoding for bitmap data, but this data is |
| @@ -851,71 +824,207 @@ static void alps_process_packet_v4(struct psmouse *psmouse) | |||
| 851 | if (++priv->multi_packet > 2) { | 824 | if (++priv->multi_packet > 2) { |
| 852 | priv->multi_packet = 0; | 825 | priv->multi_packet = 0; |
| 853 | 826 | ||
| 854 | x_bitmap = ((priv->multi_data[2] & 0x1f) << 10) | | 827 | f->x_map = ((priv->multi_data[2] & 0x1f) << 10) | |
| 855 | ((priv->multi_data[3] & 0x60) << 3) | | 828 | ((priv->multi_data[3] & 0x60) << 3) | |
| 856 | ((priv->multi_data[0] & 0x3f) << 2) | | 829 | ((priv->multi_data[0] & 0x3f) << 2) | |
| 857 | ((priv->multi_data[1] & 0x60) >> 5); | 830 | ((priv->multi_data[1] & 0x60) >> 5); |
| 858 | y_bitmap = ((priv->multi_data[5] & 0x01) << 10) | | 831 | f->y_map = ((priv->multi_data[5] & 0x01) << 10) | |
| 859 | ((priv->multi_data[3] & 0x1f) << 5) | | 832 | ((priv->multi_data[3] & 0x1f) << 5) | |
| 860 | (priv->multi_data[1] & 0x1f); | 833 | (priv->multi_data[1] & 0x1f); |
| 861 | 834 | ||
| 862 | fingers = alps_process_bitmap(priv, x_bitmap, y_bitmap, | 835 | f->fingers = alps_process_bitmap(priv, f); |
| 863 | &x1, &y1, &x2, &y2); | ||
| 864 | |||
| 865 | /* Store MT data.*/ | ||
| 866 | priv->fingers = fingers; | ||
| 867 | priv->x1 = x1; | ||
| 868 | priv->x2 = x2; | ||
| 869 | priv->y1 = y1; | ||
| 870 | priv->y2 = y2; | ||
| 871 | } | 836 | } |
| 872 | 837 | ||
| 873 | left = packet[4] & 0x01; | 838 | f->left = packet[4] & 0x01; |
| 874 | right = packet[4] & 0x02; | 839 | f->right = packet[4] & 0x02; |
| 875 | 840 | ||
| 876 | x = ((packet[1] & 0x7f) << 4) | ((packet[3] & 0x30) >> 2) | | 841 | f->st.x = ((packet[1] & 0x7f) << 4) | ((packet[3] & 0x30) >> 2) | |
| 877 | ((packet[0] & 0x30) >> 4); | 842 | ((packet[0] & 0x30) >> 4); |
| 878 | y = ((packet[2] & 0x7f) << 4) | (packet[3] & 0x0f); | 843 | f->st.y = ((packet[2] & 0x7f) << 4) | (packet[3] & 0x0f); |
| 879 | z = packet[5] & 0x7f; | 844 | f->pressure = packet[5] & 0x7f; |
| 880 | 845 | ||
| 881 | /* | 846 | alps_report_semi_mt_data(psmouse, f->fingers); |
| 882 | * If there were no contacts in the bitmap, use ST | 847 | } |
| 883 | * points in MT reports. | 848 | |
| 884 | * If there were two contacts or more, report MT data. | 849 | static bool alps_is_valid_package_v7(struct psmouse *psmouse) |
| 885 | */ | 850 | { |
| 886 | if (priv->fingers < 2) { | 851 | switch (psmouse->pktcnt) { |
| 887 | x1 = x; | 852 | case 3: |
| 888 | y1 = y; | 853 | return (psmouse->packet[2] & 0x40) == 0x40; |
| 889 | fingers = z > 0 ? 1 : 0; | 854 | case 4: |
| 890 | } else { | 855 | return (psmouse->packet[3] & 0x48) == 0x48; |
| 891 | fingers = priv->fingers; | 856 | case 6: |
| 892 | x1 = priv->x1; | 857 | return (psmouse->packet[5] & 0x40) == 0x00; |
| 893 | x2 = priv->x2; | ||
| 894 | y1 = priv->y1; | ||
| 895 | y2 = priv->y2; | ||
| 896 | } | 858 | } |
| 859 | return true; | ||
| 860 | } | ||
| 897 | 861 | ||
| 898 | if (z >= 64) | 862 | static unsigned char alps_get_packet_id_v7(char *byte) |
| 899 | input_report_key(dev, BTN_TOUCH, 1); | 863 | { |
| 864 | unsigned char packet_id; | ||
| 865 | |||
| 866 | if (byte[4] & 0x40) | ||
| 867 | packet_id = V7_PACKET_ID_TWO; | ||
| 868 | else if (byte[4] & 0x01) | ||
| 869 | packet_id = V7_PACKET_ID_MULTI; | ||
| 870 | else if ((byte[0] & 0x10) && !(byte[4] & 0x43)) | ||
| 871 | packet_id = V7_PACKET_ID_NEW; | ||
| 872 | else if (byte[1] == 0x00 && byte[4] == 0x00) | ||
| 873 | packet_id = V7_PACKET_ID_IDLE; | ||
| 900 | else | 874 | else |
| 901 | input_report_key(dev, BTN_TOUCH, 0); | 875 | packet_id = V7_PACKET_ID_UNKNOWN; |
| 902 | 876 | ||
| 903 | alps_report_semi_mt_data(dev, fingers, x1, y1, x2, y2); | 877 | return packet_id; |
| 878 | } | ||
| 904 | 879 | ||
| 905 | input_mt_report_finger_count(dev, fingers); | 880 | static void alps_get_finger_coordinate_v7(struct input_mt_pos *mt, |
| 881 | unsigned char *pkt, | ||
| 882 | unsigned char pkt_id) | ||
| 883 | { | ||
| 884 | mt[0].x = ((pkt[2] & 0x80) << 4); | ||
| 885 | mt[0].x |= ((pkt[2] & 0x3F) << 5); | ||
| 886 | mt[0].x |= ((pkt[3] & 0x30) >> 1); | ||
| 887 | mt[0].x |= (pkt[3] & 0x07); | ||
| 888 | mt[0].y = (pkt[1] << 3) | (pkt[0] & 0x07); | ||
| 889 | |||
| 890 | mt[1].x = ((pkt[3] & 0x80) << 4); | ||
| 891 | mt[1].x |= ((pkt[4] & 0x80) << 3); | ||
| 892 | mt[1].x |= ((pkt[4] & 0x3F) << 4); | ||
| 893 | mt[1].y = ((pkt[5] & 0x80) << 3); | ||
| 894 | mt[1].y |= ((pkt[5] & 0x3F) << 4); | ||
| 895 | |||
| 896 | switch (pkt_id) { | ||
| 897 | case V7_PACKET_ID_TWO: | ||
| 898 | mt[1].x &= ~0x000F; | ||
| 899 | mt[1].y |= 0x000F; | ||
| 900 | break; | ||
| 906 | 901 | ||
| 907 | input_report_key(dev, BTN_LEFT, left); | 902 | case V7_PACKET_ID_MULTI: |
| 908 | input_report_key(dev, BTN_RIGHT, right); | 903 | mt[1].x &= ~0x003F; |
| 904 | mt[1].y &= ~0x0020; | ||
| 905 | mt[1].y |= ((pkt[4] & 0x02) << 4); | ||
| 906 | mt[1].y |= 0x001F; | ||
| 907 | break; | ||
| 909 | 908 | ||
| 910 | if (z > 0) { | 909 | case V7_PACKET_ID_NEW: |
| 911 | input_report_abs(dev, ABS_X, x); | 910 | mt[1].x &= ~0x003F; |
| 912 | input_report_abs(dev, ABS_Y, y); | 911 | mt[1].x |= (pkt[0] & 0x20); |
| 912 | mt[1].y |= 0x000F; | ||
| 913 | break; | ||
| 913 | } | 914 | } |
| 914 | input_report_abs(dev, ABS_PRESSURE, z); | 915 | |
| 916 | mt[0].y = 0x7FF - mt[0].y; | ||
| 917 | mt[1].y = 0x7FF - mt[1].y; | ||
| 918 | } | ||
| 919 | |||
| 920 | static int alps_get_mt_count(struct input_mt_pos *mt) | ||
| 921 | { | ||
| 922 | int i; | ||
| 923 | |||
| 924 | for (i = 0; i < MAX_TOUCHES && mt[i].x != 0 && mt[i].y != 0; i++) | ||
| 925 | /* empty */; | ||
| 926 | |||
| 927 | return i; | ||
| 928 | } | ||
| 929 | |||
| 930 | static int alps_decode_packet_v7(struct alps_fields *f, | ||
| 931 | unsigned char *p, | ||
| 932 | struct psmouse *psmouse) | ||
| 933 | { | ||
| 934 | unsigned char pkt_id; | ||
| 935 | |||
| 936 | pkt_id = alps_get_packet_id_v7(p); | ||
| 937 | if (pkt_id == V7_PACKET_ID_IDLE) | ||
| 938 | return 0; | ||
| 939 | if (pkt_id == V7_PACKET_ID_UNKNOWN) | ||
| 940 | return -1; | ||
| 941 | |||
| 942 | alps_get_finger_coordinate_v7(f->mt, p, pkt_id); | ||
| 943 | |||
| 944 | if (pkt_id == V7_PACKET_ID_TWO || pkt_id == V7_PACKET_ID_MULTI) { | ||
| 945 | f->left = (p[0] & 0x80) >> 7; | ||
| 946 | f->right = (p[0] & 0x20) >> 5; | ||
| 947 | f->middle = (p[0] & 0x10) >> 4; | ||
| 948 | } | ||
| 949 | |||
| 950 | if (pkt_id == V7_PACKET_ID_TWO) | ||
| 951 | f->fingers = alps_get_mt_count(f->mt); | ||
| 952 | else if (pkt_id == V7_PACKET_ID_MULTI) | ||
| 953 | f->fingers = 3 + (p[5] & 0x03); | ||
| 954 | |||
| 955 | return 0; | ||
| 956 | } | ||
| 957 | |||
| 958 | static void alps_process_trackstick_packet_v7(struct psmouse *psmouse) | ||
| 959 | { | ||
| 960 | struct alps_data *priv = psmouse->private; | ||
| 961 | unsigned char *packet = psmouse->packet; | ||
| 962 | struct input_dev *dev2 = priv->dev2; | ||
| 963 | int x, y, z, left, right, middle; | ||
| 964 | |||
| 965 | /* | ||
| 966 | * b7 b6 b5 b4 b3 b2 b1 b0 | ||
| 967 | * Byte0 0 1 0 0 1 0 0 0 | ||
| 968 | * Byte1 1 1 * * 1 M R L | ||
| 969 | * Byte2 X7 1 X5 X4 X3 X2 X1 X0 | ||
| 970 | * Byte3 Z6 1 Y6 X6 1 Y2 Y1 Y0 | ||
| 971 | * Byte4 Y7 0 Y5 Y4 Y3 1 1 0 | ||
| 972 | * Byte5 T&P 0 Z5 Z4 Z3 Z2 Z1 Z0 | ||
| 973 | * M / R / L: Middle / Right / Left button | ||
| 974 | */ | ||
| 975 | |||
| 976 | x = ((packet[2] & 0xbf)) | ((packet[3] & 0x10) << 2); | ||
| 977 | y = (packet[3] & 0x07) | (packet[4] & 0xb8) | | ||
| 978 | ((packet[3] & 0x20) << 1); | ||
| 979 | z = (packet[5] & 0x3f) | ((packet[3] & 0x80) >> 1); | ||
| 980 | |||
| 981 | left = (packet[1] & 0x01); | ||
| 982 | right = (packet[1] & 0x02) >> 1; | ||
| 983 | middle = (packet[1] & 0x04) >> 2; | ||
| 984 | |||
| 985 | /* Divide 2 since trackpoint's speed is too fast */ | ||
| 986 | input_report_rel(dev2, REL_X, (char)x / 2); | ||
| 987 | input_report_rel(dev2, REL_Y, -((char)y / 2)); | ||
| 988 | |||
| 989 | input_report_key(dev2, BTN_LEFT, left); | ||
| 990 | input_report_key(dev2, BTN_RIGHT, right); | ||
| 991 | input_report_key(dev2, BTN_MIDDLE, middle); | ||
| 992 | |||
| 993 | input_sync(dev2); | ||
| 994 | } | ||
| 995 | |||
| 996 | static void alps_process_touchpad_packet_v7(struct psmouse *psmouse) | ||
| 997 | { | ||
| 998 | struct alps_data *priv = psmouse->private; | ||
| 999 | struct input_dev *dev = psmouse->dev; | ||
| 1000 | struct alps_fields *f = &priv->f; | ||
| 1001 | |||
| 1002 | memset(f, 0, sizeof(*f)); | ||
| 1003 | |||
| 1004 | if (priv->decode_fields(f, psmouse->packet, psmouse)) | ||
| 1005 | return; | ||
| 1006 | |||
| 1007 | alps_report_mt_data(psmouse, alps_get_mt_count(f->mt)); | ||
| 1008 | |||
| 1009 | input_mt_report_finger_count(dev, f->fingers); | ||
| 1010 | |||
| 1011 | input_report_key(dev, BTN_LEFT, f->left); | ||
| 1012 | input_report_key(dev, BTN_RIGHT, f->right); | ||
| 1013 | input_report_key(dev, BTN_MIDDLE, f->middle); | ||
| 915 | 1014 | ||
| 916 | input_sync(dev); | 1015 | input_sync(dev); |
| 917 | } | 1016 | } |
| 918 | 1017 | ||
| 1018 | static void alps_process_packet_v7(struct psmouse *psmouse) | ||
| 1019 | { | ||
| 1020 | unsigned char *packet = psmouse->packet; | ||
| 1021 | |||
| 1022 | if (packet[0] == 0x48 && (packet[4] & 0x47) == 0x06) | ||
| 1023 | alps_process_trackstick_packet_v7(psmouse); | ||
| 1024 | else | ||
| 1025 | alps_process_touchpad_packet_v7(psmouse); | ||
| 1026 | } | ||
| 1027 | |||
| 919 | static void alps_report_bare_ps2_packet(struct psmouse *psmouse, | 1028 | static void alps_report_bare_ps2_packet(struct psmouse *psmouse, |
| 920 | unsigned char packet[], | 1029 | unsigned char packet[], |
| 921 | bool report_buttons) | 1030 | bool report_buttons) |
| @@ -1080,6 +1189,14 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) | |||
| 1080 | return PSMOUSE_BAD_DATA; | 1189 | return PSMOUSE_BAD_DATA; |
| 1081 | } | 1190 | } |
| 1082 | 1191 | ||
| 1192 | if (priv->proto_version == ALPS_PROTO_V7 && | ||
| 1193 | !alps_is_valid_package_v7(psmouse)) { | ||
| 1194 | psmouse_dbg(psmouse, "refusing packet[%i] = %x\n", | ||
| 1195 | psmouse->pktcnt - 1, | ||
| 1196 | psmouse->packet[psmouse->pktcnt - 1]); | ||
| 1197 | return PSMOUSE_BAD_DATA; | ||
| 1198 | } | ||
| 1199 | |||
| 1083 | if (psmouse->pktcnt == psmouse->pktsize) { | 1200 | if (psmouse->pktcnt == psmouse->pktsize) { |
| 1084 | priv->process_packet(psmouse); | 1201 | priv->process_packet(psmouse); |
| 1085 | return PSMOUSE_FULL_PACKET; | 1202 | return PSMOUSE_FULL_PACKET; |
| @@ -1192,6 +1309,22 @@ static int alps_rpt_cmd(struct psmouse *psmouse, int init_command, | |||
| 1192 | return 0; | 1309 | return 0; |
| 1193 | } | 1310 | } |
| 1194 | 1311 | ||
| 1312 | static bool alps_check_valid_firmware_id(unsigned char id[]) | ||
| 1313 | { | ||
| 1314 | if (id[0] == 0x73) | ||
| 1315 | return true; | ||
| 1316 | |||
| 1317 | if (id[0] == 0x88 && | ||
| 1318 | (id[1] == 0x07 || | ||
| 1319 | id[1] == 0x08 || | ||
| 1320 | (id[1] & 0xf0) == 0xb0 || | ||
| 1321 | (id[1] & 0xf0) == 0xc0)) { | ||
| 1322 | return true; | ||
| 1323 | } | ||
| 1324 | |||
| 1325 | return false; | ||
| 1326 | } | ||
| 1327 | |||
| 1195 | static int alps_enter_command_mode(struct psmouse *psmouse) | 1328 | static int alps_enter_command_mode(struct psmouse *psmouse) |
| 1196 | { | 1329 | { |
| 1197 | unsigned char param[4]; | 1330 | unsigned char param[4]; |
| @@ -1201,8 +1334,7 @@ static int alps_enter_command_mode(struct psmouse *psmouse) | |||
| 1201 | return -1; | 1334 | return -1; |
| 1202 | } | 1335 | } |
| 1203 | 1336 | ||
| 1204 | if ((param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) && | 1337 | if (!alps_check_valid_firmware_id(param)) { |
| 1205 | param[0] != 0x73) { | ||
| 1206 | psmouse_dbg(psmouse, | 1338 | psmouse_dbg(psmouse, |
| 1207 | "unknown response while entering command mode\n"); | 1339 | "unknown response while entering command mode\n"); |
| 1208 | return -1; | 1340 | return -1; |
| @@ -1660,6 +1792,45 @@ error: | |||
| 1660 | return -1; | 1792 | return -1; |
| 1661 | } | 1793 | } |
| 1662 | 1794 | ||
| 1795 | static int alps_get_v3_v7_resolution(struct psmouse *psmouse, int reg_pitch) | ||
| 1796 | { | ||
| 1797 | int reg, x_pitch, y_pitch, x_electrode, y_electrode, x_phys, y_phys; | ||
| 1798 | struct alps_data *priv = psmouse->private; | ||
| 1799 | |||
| 1800 | reg = alps_command_mode_read_reg(psmouse, reg_pitch); | ||
| 1801 | if (reg < 0) | ||
| 1802 | return reg; | ||
| 1803 | |||
| 1804 | x_pitch = (char)(reg << 4) >> 4; /* sign extend lower 4 bits */ | ||
| 1805 | x_pitch = 50 + 2 * x_pitch; /* In 0.1 mm units */ | ||
| 1806 | |||
| 1807 | y_pitch = (char)reg >> 4; /* sign extend upper 4 bits */ | ||
| 1808 | y_pitch = 36 + 2 * y_pitch; /* In 0.1 mm units */ | ||
| 1809 | |||
| 1810 | reg = alps_command_mode_read_reg(psmouse, reg_pitch + 1); | ||
| 1811 | if (reg < 0) | ||
| 1812 | return reg; | ||
| 1813 | |||
| 1814 | x_electrode = (char)(reg << 4) >> 4; /* sign extend lower 4 bits */ | ||
| 1815 | x_electrode = 17 + x_electrode; | ||
| 1816 | |||
| 1817 | y_electrode = (char)reg >> 4; /* sign extend upper 4 bits */ | ||
| 1818 | y_electrode = 13 + y_electrode; | ||
| 1819 | |||
| 1820 | x_phys = x_pitch * (x_electrode - 1); /* In 0.1 mm units */ | ||
| 1821 | y_phys = y_pitch * (y_electrode - 1); /* In 0.1 mm units */ | ||
| 1822 | |||
| 1823 | priv->x_res = priv->x_max * 10 / x_phys; /* units / mm */ | ||
| 1824 | priv->y_res = priv->y_max * 10 / y_phys; /* units / mm */ | ||
| 1825 | |||
| 1826 | psmouse_dbg(psmouse, | ||
| 1827 | "pitch %dx%d num-electrodes %dx%d physical size %dx%d mm res %dx%d\n", | ||
| 1828 | x_pitch, y_pitch, x_electrode, y_electrode, | ||
| 1829 | x_phys / 10, y_phys / 10, priv->x_res, priv->y_res); | ||
| 1830 | |||
| 1831 | return 0; | ||
| 1832 | } | ||
| 1833 | |||
| 1663 | static int alps_hw_init_rushmore_v3(struct psmouse *psmouse) | 1834 | static int alps_hw_init_rushmore_v3(struct psmouse *psmouse) |
| 1664 | { | 1835 | { |
| 1665 | struct alps_data *priv = psmouse->private; | 1836 | struct alps_data *priv = psmouse->private; |
| @@ -1680,6 +1851,9 @@ static int alps_hw_init_rushmore_v3(struct psmouse *psmouse) | |||
| 1680 | alps_command_mode_write_reg(psmouse, 0xc2cb, 0x00)) | 1851 | alps_command_mode_write_reg(psmouse, 0xc2cb, 0x00)) |
| 1681 | goto error; | 1852 | goto error; |
| 1682 | 1853 | ||
| 1854 | if (alps_get_v3_v7_resolution(psmouse, 0xc2da)) | ||
| 1855 | goto error; | ||
| 1856 | |||
| 1683 | reg_val = alps_command_mode_read_reg(psmouse, 0xc2c6); | 1857 | reg_val = alps_command_mode_read_reg(psmouse, 0xc2c6); |
| 1684 | if (reg_val == -1) | 1858 | if (reg_val == -1) |
| 1685 | goto error; | 1859 | goto error; |
| @@ -1856,6 +2030,35 @@ static int alps_hw_init_dolphin_v1(struct psmouse *psmouse) | |||
| 1856 | return 0; | 2030 | return 0; |
| 1857 | } | 2031 | } |
| 1858 | 2032 | ||
| 2033 | static int alps_hw_init_v7(struct psmouse *psmouse) | ||
| 2034 | { | ||
| 2035 | struct ps2dev *ps2dev = &psmouse->ps2dev; | ||
| 2036 | int reg_val, ret = -1; | ||
| 2037 | |||
| 2038 | if (alps_enter_command_mode(psmouse) || | ||
| 2039 | alps_command_mode_read_reg(psmouse, 0xc2d9) == -1) | ||
| 2040 | goto error; | ||
| 2041 | |||
| 2042 | if (alps_get_v3_v7_resolution(psmouse, 0xc397)) | ||
| 2043 | goto error; | ||
| 2044 | |||
| 2045 | if (alps_command_mode_write_reg(psmouse, 0xc2c9, 0x64)) | ||
| 2046 | goto error; | ||
| 2047 | |||
| 2048 | reg_val = alps_command_mode_read_reg(psmouse, 0xc2c4); | ||
| 2049 | if (reg_val == -1) | ||
| 2050 | goto error; | ||
| 2051 | if (__alps_command_mode_write_reg(psmouse, reg_val | 0x02)) | ||
| 2052 | goto error; | ||
| 2053 | |||
| 2054 | alps_exit_command_mode(psmouse); | ||
| 2055 | return ps2_command(ps2dev, NULL, PSMOUSE_CMD_ENABLE); | ||
| 2056 | |||
| 2057 | error: | ||
| 2058 | alps_exit_command_mode(psmouse); | ||
| 2059 | return ret; | ||
| 2060 | } | ||
| 2061 | |||
| 1859 | static void alps_set_defaults(struct alps_data *priv) | 2062 | static void alps_set_defaults(struct alps_data *priv) |
| 1860 | { | 2063 | { |
| 1861 | priv->byte0 = 0x8f; | 2064 | priv->byte0 = 0x8f; |
| @@ -1914,6 +2117,21 @@ static void alps_set_defaults(struct alps_data *priv) | |||
| 1914 | priv->x_max = 2047; | 2117 | priv->x_max = 2047; |
| 1915 | priv->y_max = 1535; | 2118 | priv->y_max = 1535; |
| 1916 | break; | 2119 | break; |
| 2120 | case ALPS_PROTO_V7: | ||
| 2121 | priv->hw_init = alps_hw_init_v7; | ||
| 2122 | priv->process_packet = alps_process_packet_v7; | ||
| 2123 | priv->decode_fields = alps_decode_packet_v7; | ||
| 2124 | priv->set_abs_params = alps_set_abs_params_mt; | ||
| 2125 | priv->nibble_commands = alps_v3_nibble_commands; | ||
| 2126 | priv->addr_command = PSMOUSE_CMD_RESET_WRAP; | ||
| 2127 | priv->x_max = 0xfff; | ||
| 2128 | priv->y_max = 0x7ff; | ||
| 2129 | priv->byte0 = 0x48; | ||
| 2130 | priv->mask0 = 0x48; | ||
| 2131 | |||
| 2132 | if (priv->fw_ver[1] != 0xba) | ||
| 2133 | priv->flags |= ALPS_BUTTONPAD; | ||
| 2134 | break; | ||
| 1917 | } | 2135 | } |
| 1918 | } | 2136 | } |
| 1919 | 2137 | ||
| @@ -1972,6 +2190,9 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) | |||
| 1972 | alps_exit_command_mode(psmouse)) | 2190 | alps_exit_command_mode(psmouse)) |
| 1973 | return -EIO; | 2191 | return -EIO; |
| 1974 | 2192 | ||
| 2193 | /* Save the Firmware version */ | ||
| 2194 | memcpy(priv->fw_ver, ec, 3); | ||
| 2195 | |||
| 1975 | if (alps_match_table(psmouse, priv, e7, ec) == 0) { | 2196 | if (alps_match_table(psmouse, priv, e7, ec) == 0) { |
| 1976 | return 0; | 2197 | return 0; |
| 1977 | } else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 && | 2198 | } else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 && |
| @@ -1982,6 +2203,12 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) | |||
| 1982 | return -EIO; | 2203 | return -EIO; |
| 1983 | else | 2204 | else |
| 1984 | return 0; | 2205 | return 0; |
| 2206 | } else if (ec[0] == 0x88 && | ||
| 2207 | ((ec[1] & 0xf0) == 0xb0 || (ec[1] & 0xf0) == 0xc0)) { | ||
| 2208 | priv->proto_version = ALPS_PROTO_V7; | ||
| 2209 | alps_set_defaults(priv); | ||
| 2210 | |||
| 2211 | return 0; | ||
| 1985 | } else if (ec[0] == 0x88 && ec[1] == 0x08) { | 2212 | } else if (ec[0] == 0x88 && ec[1] == 0x08) { |
| 1986 | priv->proto_version = ALPS_PROTO_V3; | 2213 | priv->proto_version = ALPS_PROTO_V3; |
| 1987 | alps_set_defaults(priv); | 2214 | alps_set_defaults(priv); |
| @@ -1990,6 +2217,7 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) | |||
| 1990 | priv->decode_fields = alps_decode_rushmore; | 2217 | priv->decode_fields = alps_decode_rushmore; |
| 1991 | priv->x_bits = 16; | 2218 | priv->x_bits = 16; |
| 1992 | priv->y_bits = 12; | 2219 | priv->y_bits = 12; |
| 2220 | priv->flags |= ALPS_IS_RUSHMORE; | ||
| 1993 | 2221 | ||
| 1994 | /* hack to make addr_command, nibble_command available */ | 2222 | /* hack to make addr_command, nibble_command available */ |
| 1995 | psmouse->private = priv; | 2223 | psmouse->private = priv; |
| @@ -2044,17 +2272,21 @@ static void alps_set_abs_params_st(struct alps_data *priv, | |||
| 2044 | static void alps_set_abs_params_mt(struct alps_data *priv, | 2272 | static void alps_set_abs_params_mt(struct alps_data *priv, |
| 2045 | struct input_dev *dev1) | 2273 | struct input_dev *dev1) |
| 2046 | { | 2274 | { |
| 2047 | set_bit(INPUT_PROP_SEMI_MT, dev1->propbit); | ||
| 2048 | input_mt_init_slots(dev1, 2, 0); | ||
| 2049 | input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, priv->x_max, 0, 0); | 2275 | input_set_abs_params(dev1, ABS_MT_POSITION_X, 0, priv->x_max, 0, 0); |
| 2050 | input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, priv->y_max, 0, 0); | 2276 | input_set_abs_params(dev1, ABS_MT_POSITION_Y, 0, priv->y_max, 0, 0); |
| 2051 | 2277 | ||
| 2052 | set_bit(BTN_TOOL_DOUBLETAP, dev1->keybit); | 2278 | input_abs_set_res(dev1, ABS_MT_POSITION_X, priv->x_res); |
| 2279 | input_abs_set_res(dev1, ABS_MT_POSITION_Y, priv->y_res); | ||
| 2280 | |||
| 2281 | input_mt_init_slots(dev1, MAX_TOUCHES, INPUT_MT_POINTER | | ||
| 2282 | INPUT_MT_DROP_UNUSED | INPUT_MT_TRACK | INPUT_MT_SEMI_MT); | ||
| 2283 | |||
| 2053 | set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit); | 2284 | set_bit(BTN_TOOL_TRIPLETAP, dev1->keybit); |
| 2054 | set_bit(BTN_TOOL_QUADTAP, dev1->keybit); | 2285 | set_bit(BTN_TOOL_QUADTAP, dev1->keybit); |
| 2055 | 2286 | ||
| 2056 | input_set_abs_params(dev1, ABS_X, 0, priv->x_max, 0, 0); | 2287 | /* V7 is real multi-touch */ |
| 2057 | input_set_abs_params(dev1, ABS_Y, 0, priv->y_max, 0, 0); | 2288 | if (priv->proto_version == ALPS_PROTO_V7) |
| 2289 | clear_bit(INPUT_PROP_SEMI_MT, dev1->propbit); | ||
| 2058 | } | 2290 | } |
| 2059 | 2291 | ||
| 2060 | int alps_init(struct psmouse *psmouse) | 2292 | int alps_init(struct psmouse *psmouse) |
| @@ -2100,7 +2332,9 @@ int alps_init(struct psmouse *psmouse) | |||
| 2100 | dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS); | 2332 | dev1->evbit[BIT_WORD(EV_ABS)] |= BIT_MASK(EV_ABS); |
| 2101 | 2333 | ||
| 2102 | priv->set_abs_params(priv, dev1); | 2334 | priv->set_abs_params(priv, dev1); |
| 2103 | input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0); | 2335 | /* No pressure on V7 */ |
| 2336 | if (priv->proto_version != ALPS_PROTO_V7) | ||
| 2337 | input_set_abs_params(dev1, ABS_PRESSURE, 0, 127, 0, 0); | ||
| 2104 | 2338 | ||
| 2105 | if (priv->flags & ALPS_WHEEL) { | 2339 | if (priv->flags & ALPS_WHEEL) { |
| 2106 | dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL); | 2340 | dev1->evbit[BIT_WORD(EV_REL)] |= BIT_MASK(EV_REL); |
| @@ -2117,6 +2351,9 @@ int alps_init(struct psmouse *psmouse) | |||
| 2117 | dev1->keybit[BIT_WORD(BTN_1)] |= BIT_MASK(BTN_1); | 2351 | dev1->keybit[BIT_WORD(BTN_1)] |= BIT_MASK(BTN_1); |
| 2118 | dev1->keybit[BIT_WORD(BTN_2)] |= BIT_MASK(BTN_2); | 2352 | dev1->keybit[BIT_WORD(BTN_2)] |= BIT_MASK(BTN_2); |
| 2119 | dev1->keybit[BIT_WORD(BTN_3)] |= BIT_MASK(BTN_3); | 2353 | dev1->keybit[BIT_WORD(BTN_3)] |= BIT_MASK(BTN_3); |
| 2354 | } else if (priv->flags & ALPS_BUTTONPAD) { | ||
| 2355 | set_bit(INPUT_PROP_BUTTONPAD, dev1->propbit); | ||
| 2356 | clear_bit(BTN_RIGHT, dev1->keybit); | ||
| 2120 | } else { | 2357 | } else { |
| 2121 | dev1->keybit[BIT_WORD(BTN_MIDDLE)] |= BIT_MASK(BTN_MIDDLE); | 2358 | dev1->keybit[BIT_WORD(BTN_MIDDLE)] |= BIT_MASK(BTN_MIDDLE); |
| 2122 | } | 2359 | } |
diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index 03f88b6940c7..66240b47819a 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h | |||
| @@ -12,17 +12,39 @@ | |||
| 12 | #ifndef _ALPS_H | 12 | #ifndef _ALPS_H |
| 13 | #define _ALPS_H | 13 | #define _ALPS_H |
| 14 | 14 | ||
| 15 | #include <linux/input/mt.h> | ||
| 16 | |||
| 15 | #define ALPS_PROTO_V1 1 | 17 | #define ALPS_PROTO_V1 1 |
| 16 | #define ALPS_PROTO_V2 2 | 18 | #define ALPS_PROTO_V2 2 |
| 17 | #define ALPS_PROTO_V3 3 | 19 | #define ALPS_PROTO_V3 3 |
| 18 | #define ALPS_PROTO_V4 4 | 20 | #define ALPS_PROTO_V4 4 |
| 19 | #define ALPS_PROTO_V5 5 | 21 | #define ALPS_PROTO_V5 5 |
| 20 | #define ALPS_PROTO_V6 6 | 22 | #define ALPS_PROTO_V6 6 |
| 23 | #define ALPS_PROTO_V7 7 /* t3btl t4s */ | ||
| 24 | |||
| 25 | #define MAX_TOUCHES 2 | ||
| 21 | 26 | ||
| 22 | #define DOLPHIN_COUNT_PER_ELECTRODE 64 | 27 | #define DOLPHIN_COUNT_PER_ELECTRODE 64 |
| 23 | #define DOLPHIN_PROFILE_XOFFSET 8 /* x-electrode offset */ | 28 | #define DOLPHIN_PROFILE_XOFFSET 8 /* x-electrode offset */ |
| 24 | #define DOLPHIN_PROFILE_YOFFSET 1 /* y-electrode offset */ | 29 | #define DOLPHIN_PROFILE_YOFFSET 1 /* y-electrode offset */ |
| 25 | 30 | ||
| 31 | /* | ||
| 32 | * enum V7_PACKET_ID - defines the packet type for V7 | ||
| 33 | * V7_PACKET_ID_IDLE: There's no finger and no button activity. | ||
| 34 | * V7_PACKET_ID_TWO: There's one or two non-resting fingers on touchpad | ||
| 35 | * or there's button activities. | ||
| 36 | * V7_PACKET_ID_MULTI: There are at least three non-resting fingers. | ||
| 37 | * V7_PACKET_ID_NEW: The finger position in slot is not continues from | ||
| 38 | * previous packet. | ||
| 39 | */ | ||
| 40 | enum V7_PACKET_ID { | ||
| 41 | V7_PACKET_ID_IDLE, | ||
| 42 | V7_PACKET_ID_TWO, | ||
| 43 | V7_PACKET_ID_MULTI, | ||
| 44 | V7_PACKET_ID_NEW, | ||
| 45 | V7_PACKET_ID_UNKNOWN, | ||
| 46 | }; | ||
| 47 | |||
| 26 | /** | 48 | /** |
| 27 | * struct alps_model_info - touchpad ID table | 49 | * struct alps_model_info - touchpad ID table |
| 28 | * @signature: E7 response string to match. | 50 | * @signature: E7 response string to match. |
| @@ -46,7 +68,7 @@ struct alps_model_info { | |||
| 46 | unsigned char command_mode_resp; | 68 | unsigned char command_mode_resp; |
| 47 | unsigned char proto_version; | 69 | unsigned char proto_version; |
| 48 | unsigned char byte0, mask0; | 70 | unsigned char byte0, mask0; |
| 49 | unsigned char flags; | 71 | int flags; |
| 50 | }; | 72 | }; |
| 51 | 73 | ||
| 52 | /** | 74 | /** |
| @@ -65,14 +87,19 @@ struct alps_nibble_commands { | |||
| 65 | unsigned char data; | 87 | unsigned char data; |
| 66 | }; | 88 | }; |
| 67 | 89 | ||
| 90 | struct alps_bitmap_point { | ||
| 91 | int start_bit; | ||
| 92 | int num_bits; | ||
| 93 | }; | ||
| 94 | |||
| 68 | /** | 95 | /** |
| 69 | * struct alps_fields - decoded version of the report packet | 96 | * struct alps_fields - decoded version of the report packet |
| 70 | * @x_map: Bitmap of active X positions for MT. | 97 | * @x_map: Bitmap of active X positions for MT. |
| 71 | * @y_map: Bitmap of active Y positions for MT. | 98 | * @y_map: Bitmap of active Y positions for MT. |
| 72 | * @fingers: Number of fingers for MT. | 99 | * @fingers: Number of fingers for MT. |
| 73 | * @x: X position for ST. | 100 | * @pressure: Pressure. |
| 74 | * @y: Y position for ST. | 101 | * @st: position for ST. |
| 75 | * @z: Z position for ST. | 102 | * @mt: position for MT. |
| 76 | * @first_mp: Packet is the first of a multi-packet report. | 103 | * @first_mp: Packet is the first of a multi-packet report. |
| 77 | * @is_mp: Packet is part of a multi-packet report. | 104 | * @is_mp: Packet is part of a multi-packet report. |
| 78 | * @left: Left touchpad button is active. | 105 | * @left: Left touchpad button is active. |
| @@ -86,9 +113,11 @@ struct alps_fields { | |||
| 86 | unsigned int x_map; | 113 | unsigned int x_map; |
| 87 | unsigned int y_map; | 114 | unsigned int y_map; |
| 88 | unsigned int fingers; | 115 | unsigned int fingers; |
| 89 | unsigned int x; | 116 | |
| 90 | unsigned int y; | 117 | int pressure; |
| 91 | unsigned int z; | 118 | struct input_mt_pos st; |
| 119 | struct input_mt_pos mt[MAX_TOUCHES]; | ||
| 120 | |||
| 92 | unsigned int first_mp:1; | 121 | unsigned int first_mp:1; |
| 93 | unsigned int is_mp:1; | 122 | unsigned int is_mp:1; |
| 94 | 123 | ||
| @@ -113,6 +142,7 @@ struct alps_fields { | |||
| 113 | * known format for this model. The first byte of the report, ANDed with | 142 | * known format for this model. The first byte of the report, ANDed with |
| 114 | * mask0, should match byte0. | 143 | * mask0, should match byte0. |
| 115 | * @mask0: The mask used to check the first byte of the report. | 144 | * @mask0: The mask used to check the first byte of the report. |
| 145 | * @fw_ver: cached copy of firmware version (EC report) | ||
| 116 | * @flags: Additional device capabilities (passthrough port, trackstick, etc.). | 146 | * @flags: Additional device capabilities (passthrough port, trackstick, etc.). |
| 117 | * @x_max: Largest possible X position value. | 147 | * @x_max: Largest possible X position value. |
| 118 | * @y_max: Largest possible Y position value. | 148 | * @y_max: Largest possible Y position value. |
| @@ -125,11 +155,7 @@ struct alps_fields { | |||
| 125 | * @prev_fin: Finger bit from previous packet. | 155 | * @prev_fin: Finger bit from previous packet. |
| 126 | * @multi_packet: Multi-packet data in progress. | 156 | * @multi_packet: Multi-packet data in progress. |
| 127 | * @multi_data: Saved multi-packet data. | 157 | * @multi_data: Saved multi-packet data. |
| 128 | * @x1: First X coordinate from last MT report. | 158 | * @f: Decoded packet data fields. |
| 129 | * @x2: Second X coordinate from last MT report. | ||
| 130 | * @y1: First Y coordinate from last MT report. | ||
| 131 | * @y2: Second Y coordinate from last MT report. | ||
| 132 | * @fingers: Number of fingers from last MT report. | ||
| 133 | * @quirks: Bitmap of ALPS_QUIRK_*. | 159 | * @quirks: Bitmap of ALPS_QUIRK_*. |
| 134 | * @timer: Timer for flushing out the final report packet in the stream. | 160 | * @timer: Timer for flushing out the final report packet in the stream. |
| 135 | */ | 161 | */ |
| @@ -142,23 +168,25 @@ struct alps_data { | |||
| 142 | int addr_command; | 168 | int addr_command; |
| 143 | unsigned char proto_version; | 169 | unsigned char proto_version; |
| 144 | unsigned char byte0, mask0; | 170 | unsigned char byte0, mask0; |
| 145 | unsigned char flags; | 171 | unsigned char fw_ver[3]; |
| 172 | int flags; | ||
| 146 | int x_max; | 173 | int x_max; |
| 147 | int y_max; | 174 | int y_max; |
| 148 | int x_bits; | 175 | int x_bits; |
| 149 | int y_bits; | 176 | int y_bits; |
| 177 | unsigned int x_res; | ||
| 178 | unsigned int y_res; | ||
| 150 | 179 | ||
| 151 | int (*hw_init)(struct psmouse *psmouse); | 180 | int (*hw_init)(struct psmouse *psmouse); |
| 152 | void (*process_packet)(struct psmouse *psmouse); | 181 | void (*process_packet)(struct psmouse *psmouse); |
| 153 | void (*decode_fields)(struct alps_fields *f, unsigned char *p, | 182 | int (*decode_fields)(struct alps_fields *f, unsigned char *p, |
| 154 | struct psmouse *psmouse); | 183 | struct psmouse *psmouse); |
| 155 | void (*set_abs_params)(struct alps_data *priv, struct input_dev *dev1); | 184 | void (*set_abs_params)(struct alps_data *priv, struct input_dev *dev1); |
| 156 | 185 | ||
| 157 | int prev_fin; | 186 | int prev_fin; |
| 158 | int multi_packet; | 187 | int multi_packet; |
| 159 | unsigned char multi_data[6]; | 188 | unsigned char multi_data[6]; |
| 160 | int x1, x2, y1, y2; | 189 | struct alps_fields f; |
| 161 | int fingers; | ||
| 162 | u8 quirks; | 190 | u8 quirks; |
| 163 | struct timer_list timer; | 191 | struct timer_list timer; |
| 164 | }; | 192 | }; |
