diff options
| -rw-r--r-- | drivers/input/misc/ad714x.c | 109 |
1 files changed, 19 insertions, 90 deletions
diff --git a/drivers/input/misc/ad714x.c b/drivers/input/misc/ad714x.c index 5f683ec2999e..c3a62c42cd28 100644 --- a/drivers/input/misc/ad714x.c +++ b/drivers/input/misc/ad714x.c | |||
| @@ -79,13 +79,7 @@ struct ad714x_slider_drv { | |||
| 79 | struct ad714x_wheel_drv { | 79 | struct ad714x_wheel_drv { |
| 80 | int abs_pos; | 80 | int abs_pos; |
| 81 | int flt_pos; | 81 | int flt_pos; |
| 82 | int pre_mean_value; | ||
| 83 | int pre_highest_stage; | 82 | int pre_highest_stage; |
| 84 | int pre_mean_value_no_offset; | ||
| 85 | int mean_value; | ||
| 86 | int mean_value_no_offset; | ||
| 87 | int pos_offset; | ||
| 88 | int pos_ratio; | ||
| 89 | int highest_stage; | 83 | int highest_stage; |
| 90 | enum ad714x_device_state state; | 84 | enum ad714x_device_state state; |
| 91 | struct input_dev *input; | 85 | struct input_dev *input; |
| @@ -404,7 +398,6 @@ static void ad714x_slider_state_machine(struct ad714x_chip *ad714x, int idx) | |||
| 404 | ad714x_slider_cal_highest_stage(ad714x, idx); | 398 | ad714x_slider_cal_highest_stage(ad714x, idx); |
| 405 | ad714x_slider_cal_abs_pos(ad714x, idx); | 399 | ad714x_slider_cal_abs_pos(ad714x, idx); |
| 406 | ad714x_slider_cal_flt_pos(ad714x, idx); | 400 | ad714x_slider_cal_flt_pos(ad714x, idx); |
| 407 | |||
| 408 | input_report_abs(sw->input, ABS_X, sw->flt_pos); | 401 | input_report_abs(sw->input, ABS_X, sw->flt_pos); |
| 409 | input_report_key(sw->input, BTN_TOUCH, 1); | 402 | input_report_key(sw->input, BTN_TOUCH, 1); |
| 410 | } else { | 403 | } else { |
| @@ -468,104 +461,41 @@ static void ad714x_wheel_cal_sensor_val(struct ad714x_chip *ad714x, int idx) | |||
| 468 | /* | 461 | /* |
| 469 | * When the scroll wheel is activated, we compute the absolute position based | 462 | * When the scroll wheel is activated, we compute the absolute position based |
| 470 | * on the sensor values. To calculate the position, we first determine the | 463 | * on the sensor values. To calculate the position, we first determine the |
| 471 | * sensor that has the greatest response among the 8 sensors that constitutes | 464 | * sensor that has the greatest response among the sensors that constitutes |
| 472 | * the scrollwheel. Then we determined the 2 sensors on either sides of the | 465 | * the scrollwheel. Then we determined the sensors on either sides of the |
| 473 | * sensor with the highest response and we apply weights to these sensors. The | 466 | * sensor with the highest response and we apply weights to these sensors. The |
| 474 | * result of this computation gives us the mean value which defined by the | 467 | * result of this computation gives us the mean value. |
| 475 | * following formula: | ||
| 476 | * For i= second_before_highest_stage to i= second_after_highest_stage | ||
| 477 | * v += Sensor response(i)*WEIGHT*(i+3) | ||
| 478 | * w += Sensor response(i) | ||
| 479 | * Mean_Value=v/w | ||
| 480 | * pos_on_scrollwheel = (Mean_Value - position_offset) / position_ratio | ||
| 481 | */ | 468 | */ |
| 482 | 469 | ||
| 483 | #define WEIGHT_FACTOR 30 | ||
| 484 | /* This constant prevents the "PositionOffset" from reaching a big value */ | ||
| 485 | #define OFFSET_POSITION_CLAMP 120 | ||
| 486 | static void ad714x_wheel_cal_abs_pos(struct ad714x_chip *ad714x, int idx) | 470 | static void ad714x_wheel_cal_abs_pos(struct ad714x_chip *ad714x, int idx) |
| 487 | { | 471 | { |
| 488 | struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx]; | 472 | struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx]; |
| 489 | struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx]; | 473 | struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx]; |
| 490 | int stage_num = hw->end_stage - hw->start_stage + 1; | 474 | int stage_num = hw->end_stage - hw->start_stage + 1; |
| 491 | int second_before, first_before, highest, first_after, second_after; | 475 | int first_before, highest, first_after; |
| 492 | int a_param, b_param; | 476 | int a_param, b_param; |
| 493 | 477 | ||
| 494 | /* Calculate Mean value */ | ||
| 495 | |||
| 496 | second_before = (sw->highest_stage + stage_num - 2) % stage_num; | ||
| 497 | first_before = (sw->highest_stage + stage_num - 1) % stage_num; | 478 | first_before = (sw->highest_stage + stage_num - 1) % stage_num; |
| 498 | highest = sw->highest_stage; | 479 | highest = sw->highest_stage; |
| 499 | first_after = (sw->highest_stage + stage_num + 1) % stage_num; | 480 | first_after = (sw->highest_stage + stage_num + 1) % stage_num; |
| 500 | second_after = (sw->highest_stage + stage_num + 2) % stage_num; | ||
| 501 | |||
| 502 | if (((sw->highest_stage - hw->start_stage) > 1) && | ||
| 503 | ((hw->end_stage - sw->highest_stage) > 1)) { | ||
| 504 | a_param = ad714x->sensor_val[second_before] * | ||
| 505 | (second_before - hw->start_stage + 3) + | ||
| 506 | ad714x->sensor_val[first_before] * | ||
| 507 | (second_before - hw->start_stage + 3) + | ||
| 508 | ad714x->sensor_val[highest] * | ||
| 509 | (second_before - hw->start_stage + 3) + | ||
| 510 | ad714x->sensor_val[first_after] * | ||
| 511 | (first_after - hw->start_stage + 3) + | ||
| 512 | ad714x->sensor_val[second_after] * | ||
| 513 | (second_after - hw->start_stage + 3); | ||
| 514 | } else { | ||
| 515 | a_param = ad714x->sensor_val[second_before] * | ||
| 516 | (second_before - hw->start_stage + 1) + | ||
| 517 | ad714x->sensor_val[first_before] * | ||
| 518 | (second_before - hw->start_stage + 2) + | ||
| 519 | ad714x->sensor_val[highest] * | ||
| 520 | (second_before - hw->start_stage + 3) + | ||
| 521 | ad714x->sensor_val[first_after] * | ||
| 522 | (first_after - hw->start_stage + 4) + | ||
| 523 | ad714x->sensor_val[second_after] * | ||
| 524 | (second_after - hw->start_stage + 5); | ||
| 525 | } | ||
| 526 | a_param *= WEIGHT_FACTOR; | ||
| 527 | 481 | ||
| 528 | b_param = ad714x->sensor_val[second_before] + | 482 | a_param = ad714x->sensor_val[highest] * |
| 483 | (highest - hw->start_stage) + | ||
| 484 | ad714x->sensor_val[first_before] * | ||
| 485 | (highest - hw->start_stage - 1) + | ||
| 486 | ad714x->sensor_val[first_after] * | ||
| 487 | (highest - hw->start_stage + 1); | ||
| 488 | b_param = ad714x->sensor_val[highest] + | ||
| 529 | ad714x->sensor_val[first_before] + | 489 | ad714x->sensor_val[first_before] + |
| 530 | ad714x->sensor_val[highest] + | 490 | ad714x->sensor_val[first_after]; |
| 531 | ad714x->sensor_val[first_after] + | 491 | |
| 532 | ad714x->sensor_val[second_after]; | 492 | sw->abs_pos = ((hw->max_coord / (hw->end_stage - hw->start_stage)) * |
| 533 | 493 | a_param) / b_param; | |
| 534 | sw->pre_mean_value = sw->mean_value; | 494 | |
| 535 | sw->mean_value = a_param / b_param; | ||
| 536 | |||
| 537 | /* Calculate the offset */ | ||
| 538 | |||
| 539 | if ((sw->pre_highest_stage == hw->end_stage) && | ||
| 540 | (sw->highest_stage == hw->start_stage)) | ||
| 541 | sw->pos_offset = sw->mean_value; | ||
| 542 | else if ((sw->pre_highest_stage == hw->start_stage) && | ||
| 543 | (sw->highest_stage == hw->end_stage)) | ||
| 544 | sw->pos_offset = sw->pre_mean_value; | ||
| 545 | |||
| 546 | if (sw->pos_offset > OFFSET_POSITION_CLAMP) | ||
| 547 | sw->pos_offset = OFFSET_POSITION_CLAMP; | ||
| 548 | |||
| 549 | /* Calculate the mean value without the offset */ | ||
| 550 | |||
| 551 | sw->pre_mean_value_no_offset = sw->mean_value_no_offset; | ||
| 552 | sw->mean_value_no_offset = sw->mean_value - sw->pos_offset; | ||
| 553 | if (sw->mean_value_no_offset < 0) | ||
| 554 | sw->mean_value_no_offset = 0; | ||
| 555 | |||
| 556 | /* Calculate ratio to scale down to NUMBER_OF_WANTED_POSITIONS */ | ||
| 557 | |||
| 558 | if ((sw->pre_highest_stage == hw->end_stage) && | ||
| 559 | (sw->highest_stage == hw->start_stage)) | ||
| 560 | sw->pos_ratio = (sw->pre_mean_value_no_offset * 100) / | ||
| 561 | hw->max_coord; | ||
| 562 | else if ((sw->pre_highest_stage == hw->start_stage) && | ||
| 563 | (sw->highest_stage == hw->end_stage)) | ||
| 564 | sw->pos_ratio = (sw->mean_value_no_offset * 100) / | ||
| 565 | hw->max_coord; | ||
| 566 | sw->abs_pos = (sw->mean_value_no_offset * 100) / sw->pos_ratio; | ||
| 567 | if (sw->abs_pos > hw->max_coord) | 495 | if (sw->abs_pos > hw->max_coord) |
| 568 | sw->abs_pos = hw->max_coord; | 496 | sw->abs_pos = hw->max_coord; |
| 497 | else if (sw->abs_pos < 0) | ||
| 498 | sw->abs_pos = 0; | ||
| 569 | } | 499 | } |
| 570 | 500 | ||
| 571 | static void ad714x_wheel_cal_flt_pos(struct ad714x_chip *ad714x, int idx) | 501 | static void ad714x_wheel_cal_flt_pos(struct ad714x_chip *ad714x, int idx) |
| @@ -639,9 +569,8 @@ static void ad714x_wheel_state_machine(struct ad714x_chip *ad714x, int idx) | |||
| 639 | ad714x_wheel_cal_highest_stage(ad714x, idx); | 569 | ad714x_wheel_cal_highest_stage(ad714x, idx); |
| 640 | ad714x_wheel_cal_abs_pos(ad714x, idx); | 570 | ad714x_wheel_cal_abs_pos(ad714x, idx); |
| 641 | ad714x_wheel_cal_flt_pos(ad714x, idx); | 571 | ad714x_wheel_cal_flt_pos(ad714x, idx); |
| 642 | |||
| 643 | input_report_abs(sw->input, ABS_WHEEL, | 572 | input_report_abs(sw->input, ABS_WHEEL, |
| 644 | sw->abs_pos); | 573 | sw->flt_pos); |
| 645 | input_report_key(sw->input, BTN_TOUCH, 1); | 574 | input_report_key(sw->input, BTN_TOUCH, 1); |
| 646 | } else { | 575 | } else { |
| 647 | /* When the user lifts off the sensor, configure | 576 | /* When the user lifts off the sensor, configure |
