diff options
Diffstat (limited to 'drivers/input/misc')
-rw-r--r-- | drivers/input/misc/ad714x.c | 129 | ||||
-rw-r--r-- | drivers/input/misc/ati_remote2.c | 9 | ||||
-rw-r--r-- | drivers/input/misc/rotary_encoder.c | 119 | ||||
-rw-r--r-- | drivers/input/misc/twl4030-pwrbutton.c | 2 |
4 files changed, 124 insertions, 135 deletions
diff --git a/drivers/input/misc/ad714x.c b/drivers/input/misc/ad714x.c index c431d09e401a..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; |
@@ -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; |
diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index 9ccdb82d869a..1de58e8a1b71 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c | |||
@@ -737,14 +737,17 @@ static ssize_t ati_remote2_store_channel_mask(struct device *dev, | |||
737 | 737 | ||
738 | mutex_lock(&ati_remote2_mutex); | 738 | mutex_lock(&ati_remote2_mutex); |
739 | 739 | ||
740 | if (mask != ar2->channel_mask && !ati_remote2_setup(ar2, mask)) | 740 | if (mask != ar2->channel_mask) { |
741 | ar2->channel_mask = mask; | 741 | r = ati_remote2_setup(ar2, mask); |
742 | if (!r) | ||
743 | ar2->channel_mask = mask; | ||
744 | } | ||
742 | 745 | ||
743 | mutex_unlock(&ati_remote2_mutex); | 746 | mutex_unlock(&ati_remote2_mutex); |
744 | 747 | ||
745 | usb_autopm_put_interface(ar2->intf[0]); | 748 | usb_autopm_put_interface(ar2->intf[0]); |
746 | 749 | ||
747 | return count; | 750 | return r ? r : count; |
748 | } | 751 | } |
749 | 752 | ||
750 | static ssize_t ati_remote2_show_mode_mask(struct device *dev, | 753 | static ssize_t ati_remote2_show_mode_mask(struct device *dev, |
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 7e64d01da2be..2c8b84dd9dac 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * rotary_encoder.c | 2 | * rotary_encoder.c |
3 | * | 3 | * |
4 | * (c) 2009 Daniel Mack <daniel@caiaq.de> | 4 | * (c) 2009 Daniel Mack <daniel@caiaq.de> |
5 | * Copyright (C) 2011 Johan Hovold <jhovold@gmail.com> | ||
5 | * | 6 | * |
6 | * state machine code inspired by code from Tim Ruetz | 7 | * state machine code inspired by code from Tim Ruetz |
7 | * | 8 | * |
@@ -38,52 +39,66 @@ struct rotary_encoder { | |||
38 | 39 | ||
39 | bool armed; | 40 | bool armed; |
40 | unsigned char dir; /* 0 - clockwise, 1 - CCW */ | 41 | unsigned char dir; /* 0 - clockwise, 1 - CCW */ |
42 | |||
43 | char last_stable; | ||
41 | }; | 44 | }; |
42 | 45 | ||
43 | static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) | 46 | static int rotary_encoder_get_state(struct rotary_encoder_platform_data *pdata) |
44 | { | 47 | { |
45 | struct rotary_encoder *encoder = dev_id; | ||
46 | struct rotary_encoder_platform_data *pdata = encoder->pdata; | ||
47 | int a = !!gpio_get_value(pdata->gpio_a); | 48 | int a = !!gpio_get_value(pdata->gpio_a); |
48 | int b = !!gpio_get_value(pdata->gpio_b); | 49 | int b = !!gpio_get_value(pdata->gpio_b); |
49 | int state; | ||
50 | 50 | ||
51 | a ^= pdata->inverted_a; | 51 | a ^= pdata->inverted_a; |
52 | b ^= pdata->inverted_b; | 52 | b ^= pdata->inverted_b; |
53 | state = (a << 1) | b; | ||
54 | 53 | ||
55 | switch (state) { | 54 | return ((a << 1) | b); |
55 | } | ||
56 | 56 | ||
57 | case 0x0: | 57 | static void rotary_encoder_report_event(struct rotary_encoder *encoder) |
58 | if (!encoder->armed) | 58 | { |
59 | break; | 59 | struct rotary_encoder_platform_data *pdata = encoder->pdata; |
60 | 60 | ||
61 | if (pdata->relative_axis) { | 61 | if (pdata->relative_axis) { |
62 | input_report_rel(encoder->input, pdata->axis, | 62 | input_report_rel(encoder->input, |
63 | encoder->dir ? -1 : 1); | 63 | pdata->axis, encoder->dir ? -1 : 1); |
64 | } else { | 64 | } else { |
65 | unsigned int pos = encoder->pos; | 65 | unsigned int pos = encoder->pos; |
66 | 66 | ||
67 | if (encoder->dir) { | 67 | if (encoder->dir) { |
68 | /* turning counter-clockwise */ | 68 | /* turning counter-clockwise */ |
69 | if (pdata->rollover) | ||
70 | pos += pdata->steps; | ||
71 | if (pos) | ||
72 | pos--; | ||
73 | } else { | ||
74 | /* turning clockwise */ | ||
75 | if (pdata->rollover || pos < pdata->steps) | ||
76 | pos++; | ||
77 | } | ||
78 | if (pdata->rollover) | 69 | if (pdata->rollover) |
79 | pos %= pdata->steps; | 70 | pos += pdata->steps; |
80 | encoder->pos = pos; | 71 | if (pos) |
81 | input_report_abs(encoder->input, pdata->axis, | 72 | pos--; |
82 | encoder->pos); | 73 | } else { |
74 | /* turning clockwise */ | ||
75 | if (pdata->rollover || pos < pdata->steps) | ||
76 | pos++; | ||
83 | } | 77 | } |
84 | input_sync(encoder->input); | ||
85 | 78 | ||
86 | encoder->armed = false; | 79 | if (pdata->rollover) |
80 | pos %= pdata->steps; | ||
81 | |||
82 | encoder->pos = pos; | ||
83 | input_report_abs(encoder->input, pdata->axis, encoder->pos); | ||
84 | } | ||
85 | |||
86 | input_sync(encoder->input); | ||
87 | } | ||
88 | |||
89 | static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) | ||
90 | { | ||
91 | struct rotary_encoder *encoder = dev_id; | ||
92 | int state; | ||
93 | |||
94 | state = rotary_encoder_get_state(encoder->pdata); | ||
95 | |||
96 | switch (state) { | ||
97 | case 0x0: | ||
98 | if (encoder->armed) { | ||
99 | rotary_encoder_report_event(encoder); | ||
100 | encoder->armed = false; | ||
101 | } | ||
87 | break; | 102 | break; |
88 | 103 | ||
89 | case 0x1: | 104 | case 0x1: |
@@ -100,11 +115,37 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) | |||
100 | return IRQ_HANDLED; | 115 | return IRQ_HANDLED; |
101 | } | 116 | } |
102 | 117 | ||
118 | static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id) | ||
119 | { | ||
120 | struct rotary_encoder *encoder = dev_id; | ||
121 | int state; | ||
122 | |||
123 | state = rotary_encoder_get_state(encoder->pdata); | ||
124 | |||
125 | switch (state) { | ||
126 | case 0x00: | ||
127 | case 0x03: | ||
128 | if (state != encoder->last_stable) { | ||
129 | rotary_encoder_report_event(encoder); | ||
130 | encoder->last_stable = state; | ||
131 | } | ||
132 | break; | ||
133 | |||
134 | case 0x01: | ||
135 | case 0x02: | ||
136 | encoder->dir = (encoder->last_stable + state) & 0x01; | ||
137 | break; | ||
138 | } | ||
139 | |||
140 | return IRQ_HANDLED; | ||
141 | } | ||
142 | |||
103 | static int __devinit rotary_encoder_probe(struct platform_device *pdev) | 143 | static int __devinit rotary_encoder_probe(struct platform_device *pdev) |
104 | { | 144 | { |
105 | struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data; | 145 | struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data; |
106 | struct rotary_encoder *encoder; | 146 | struct rotary_encoder *encoder; |
107 | struct input_dev *input; | 147 | struct input_dev *input; |
148 | irq_handler_t handler; | ||
108 | int err; | 149 | int err; |
109 | 150 | ||
110 | if (!pdata) { | 151 | if (!pdata) { |
@@ -175,7 +216,14 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) | |||
175 | } | 216 | } |
176 | 217 | ||
177 | /* request the IRQs */ | 218 | /* request the IRQs */ |
178 | err = request_irq(encoder->irq_a, &rotary_encoder_irq, | 219 | if (pdata->half_period) { |
220 | handler = &rotary_encoder_half_period_irq; | ||
221 | encoder->last_stable = rotary_encoder_get_state(pdata); | ||
222 | } else { | ||
223 | handler = &rotary_encoder_irq; | ||
224 | } | ||
225 | |||
226 | err = request_irq(encoder->irq_a, handler, | ||
179 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | 227 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
180 | DRV_NAME, encoder); | 228 | DRV_NAME, encoder); |
181 | if (err) { | 229 | if (err) { |
@@ -184,7 +232,7 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) | |||
184 | goto exit_free_gpio_b; | 232 | goto exit_free_gpio_b; |
185 | } | 233 | } |
186 | 234 | ||
187 | err = request_irq(encoder->irq_b, &rotary_encoder_irq, | 235 | err = request_irq(encoder->irq_b, handler, |
188 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, | 236 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, |
189 | DRV_NAME, encoder); | 237 | DRV_NAME, encoder); |
190 | if (err) { | 238 | if (err) { |
@@ -252,6 +300,5 @@ module_exit(rotary_encoder_exit); | |||
252 | 300 | ||
253 | MODULE_ALIAS("platform:" DRV_NAME); | 301 | MODULE_ALIAS("platform:" DRV_NAME); |
254 | MODULE_DESCRIPTION("GPIO rotary encoder driver"); | 302 | MODULE_DESCRIPTION("GPIO rotary encoder driver"); |
255 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); | 303 | MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>, Johan Hovold"); |
256 | MODULE_LICENSE("GPL v2"); | 304 | MODULE_LICENSE("GPL v2"); |
257 | |||
diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c index f16972bddca4..38e4b507b94c 100644 --- a/drivers/input/misc/twl4030-pwrbutton.c +++ b/drivers/input/misc/twl4030-pwrbutton.c | |||
@@ -89,7 +89,7 @@ static int __init twl4030_pwrbutton_probe(struct platform_device *pdev) | |||
89 | return 0; | 89 | return 0; |
90 | 90 | ||
91 | free_irq: | 91 | free_irq: |
92 | free_irq(irq, NULL); | 92 | free_irq(irq, pwr); |
93 | free_input_dev: | 93 | free_input_dev: |
94 | input_free_device(pwr); | 94 | input_free_device(pwr); |
95 | return err; | 95 | return err; |