diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-05-25 19:41:21 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-05-25 19:41:21 -0400 |
commit | ae1d3b974e091b5fc9008bd41bcbdaac68110b62 (patch) | |
tree | 82e50a66925ced79f59ed4504f6e073ef55edee3 /drivers/input/misc/ad714x.c | |
parent | 586893ebc42943008010b4c210cfc9167df615e5 (diff) | |
parent | 7a2207a0e1142a9b214b323e43ab2ecc592e5b0e (diff) |
Merge branch 'for-rmk' of git://github.com/at91linux/linux-2.6-at91 into devel-stable
Diffstat (limited to 'drivers/input/misc/ad714x.c')
-rw-r--r-- | drivers/input/misc/ad714x.c | 129 |
1 files changed, 34 insertions, 95 deletions
diff --git a/drivers/input/misc/ad714x.c b/drivers/input/misc/ad714x.c index c431d09e401..c3a62c42cd2 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; |
@@ -158,10 +152,10 @@ static void ad714x_use_com_int(struct ad714x_chip *ad714x, | |||
158 | unsigned short data; | 152 | unsigned short data; |
159 | unsigned short mask; | 153 | unsigned short mask; |
160 | 154 | ||
161 | mask = ((1 << (end_stage + 1)) - 1) - (1 << start_stage); | 155 | mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1); |
162 | 156 | ||
163 | ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data); | 157 | ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data); |
164 | data |= 1 << start_stage; | 158 | data |= 1 << end_stage; |
165 | ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data); | 159 | ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data); |
166 | 160 | ||
167 | ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data); | 161 | ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data); |
@@ -175,10 +169,10 @@ static void ad714x_use_thr_int(struct ad714x_chip *ad714x, | |||
175 | unsigned short data; | 169 | unsigned short data; |
176 | unsigned short mask; | 170 | unsigned short mask; |
177 | 171 | ||
178 | mask = ((1 << (end_stage + 1)) - 1) - (1 << start_stage); | 172 | mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1); |
179 | 173 | ||
180 | ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data); | 174 | ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data); |
181 | data &= ~(1 << start_stage); | 175 | data &= ~(1 << end_stage); |
182 | ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data); | 176 | ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data); |
183 | 177 | ||
184 | ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data); | 178 | ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data); |
@@ -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 |
@@ -1149,6 +1078,8 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, | |||
1149 | input[alloc_idx]->id.bustype = bus_type; | 1078 | input[alloc_idx]->id.bustype = bus_type; |
1150 | input[alloc_idx]->id.product = ad714x->product; | 1079 | input[alloc_idx]->id.product = ad714x->product; |
1151 | input[alloc_idx]->id.version = ad714x->version; | 1080 | input[alloc_idx]->id.version = ad714x->version; |
1081 | input[alloc_idx]->name = "ad714x_captouch_slider"; | ||
1082 | input[alloc_idx]->dev.parent = dev; | ||
1152 | 1083 | ||
1153 | error = input_register_device(input[alloc_idx]); | 1084 | error = input_register_device(input[alloc_idx]); |
1154 | if (error) | 1085 | if (error) |
@@ -1179,6 +1110,8 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, | |||
1179 | input[alloc_idx]->id.bustype = bus_type; | 1110 | input[alloc_idx]->id.bustype = bus_type; |
1180 | input[alloc_idx]->id.product = ad714x->product; | 1111 | input[alloc_idx]->id.product = ad714x->product; |
1181 | input[alloc_idx]->id.version = ad714x->version; | 1112 | input[alloc_idx]->id.version = ad714x->version; |
1113 | input[alloc_idx]->name = "ad714x_captouch_wheel"; | ||
1114 | input[alloc_idx]->dev.parent = dev; | ||
1182 | 1115 | ||
1183 | error = input_register_device(input[alloc_idx]); | 1116 | error = input_register_device(input[alloc_idx]); |
1184 | if (error) | 1117 | if (error) |
@@ -1212,6 +1145,8 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, | |||
1212 | input[alloc_idx]->id.bustype = bus_type; | 1145 | input[alloc_idx]->id.bustype = bus_type; |
1213 | input[alloc_idx]->id.product = ad714x->product; | 1146 | input[alloc_idx]->id.product = ad714x->product; |
1214 | input[alloc_idx]->id.version = ad714x->version; | 1147 | input[alloc_idx]->id.version = ad714x->version; |
1148 | input[alloc_idx]->name = "ad714x_captouch_pad"; | ||
1149 | input[alloc_idx]->dev.parent = dev; | ||
1215 | 1150 | ||
1216 | error = input_register_device(input[alloc_idx]); | 1151 | error = input_register_device(input[alloc_idx]); |
1217 | if (error) | 1152 | if (error) |
@@ -1240,6 +1175,8 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, | |||
1240 | input[alloc_idx]->id.bustype = bus_type; | 1175 | input[alloc_idx]->id.bustype = bus_type; |
1241 | input[alloc_idx]->id.product = ad714x->product; | 1176 | input[alloc_idx]->id.product = ad714x->product; |
1242 | input[alloc_idx]->id.version = ad714x->version; | 1177 | input[alloc_idx]->id.version = ad714x->version; |
1178 | input[alloc_idx]->name = "ad714x_captouch_button"; | ||
1179 | input[alloc_idx]->dev.parent = dev; | ||
1243 | 1180 | ||
1244 | error = input_register_device(input[alloc_idx]); | 1181 | error = input_register_device(input[alloc_idx]); |
1245 | if (error) | 1182 | if (error) |
@@ -1249,7 +1186,9 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, | |||
1249 | } | 1186 | } |
1250 | 1187 | ||
1251 | error = request_threaded_irq(ad714x->irq, NULL, ad714x_interrupt_thread, | 1188 | error = request_threaded_irq(ad714x->irq, NULL, ad714x_interrupt_thread, |
1252 | IRQF_TRIGGER_FALLING, "ad714x_captouch", ad714x); | 1189 | plat_data->irqflags ? |
1190 | plat_data->irqflags : IRQF_TRIGGER_FALLING, | ||
1191 | "ad714x_captouch", ad714x); | ||
1253 | if (error) { | 1192 | if (error) { |
1254 | dev_err(dev, "can't allocate irq %d\n", ad714x->irq); | 1193 | dev_err(dev, "can't allocate irq %d\n", ad714x->irq); |
1255 | goto err_unreg_dev; | 1194 | goto err_unreg_dev; |