diff options
Diffstat (limited to 'drivers/input/misc/rotary_encoder.c')
| -rw-r--r-- | drivers/input/misc/rotary_encoder.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 5bb3ab51b8c6..c806fbf1e174 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c | |||
| @@ -26,13 +26,17 @@ | |||
| 26 | #define DRV_NAME "rotary-encoder" | 26 | #define DRV_NAME "rotary-encoder" |
| 27 | 27 | ||
| 28 | struct rotary_encoder { | 28 | struct rotary_encoder { |
| 29 | unsigned int irq_a; | ||
| 30 | unsigned int irq_b; | ||
| 31 | unsigned int pos; | ||
| 32 | unsigned int armed; | ||
| 33 | unsigned int dir; | ||
| 34 | struct input_dev *input; | 29 | struct input_dev *input; |
| 35 | struct rotary_encoder_platform_data *pdata; | 30 | struct rotary_encoder_platform_data *pdata; |
| 31 | |||
| 32 | unsigned int axis; | ||
| 33 | unsigned int pos; | ||
| 34 | |||
| 35 | unsigned int irq_a; | ||
| 36 | unsigned int irq_b; | ||
| 37 | |||
| 38 | bool armed; | ||
| 39 | unsigned char dir; /* 0 - clockwise, 1 - CCW */ | ||
| 36 | }; | 40 | }; |
| 37 | 41 | ||
| 38 | static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) | 42 | static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) |
| @@ -53,21 +57,32 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) | |||
| 53 | if (!encoder->armed) | 57 | if (!encoder->armed) |
| 54 | break; | 58 | break; |
| 55 | 59 | ||
| 56 | if (encoder->dir) { | 60 | if (pdata->relative_axis) { |
| 57 | /* turning counter-clockwise */ | 61 | input_report_rel(encoder->input, pdata->axis, |
| 58 | encoder->pos += pdata->steps; | 62 | encoder->dir ? -1 : 1); |
| 59 | encoder->pos--; | ||
| 60 | encoder->pos %= pdata->steps; | ||
| 61 | } else { | 63 | } else { |
| 62 | /* turning clockwise */ | 64 | unsigned int pos = encoder->pos; |
| 63 | encoder->pos++; | 65 | |
| 64 | encoder->pos %= pdata->steps; | 66 | if (encoder->dir) { |
| 67 | /* turning counter-clockwise */ | ||
| 68 | if (pdata->rollover) | ||
| 69 | pos += pdata->steps; | ||
| 70 | if (pos) | ||
| 71 | pos--; | ||
| 72 | } else { | ||
| 73 | /* turning clockwise */ | ||
| 74 | if (pdata->rollover || pos < pdata->steps) | ||
| 75 | pos++; | ||
| 76 | } | ||
| 77 | if (pdata->rollover) | ||
| 78 | pos %= pdata->steps; | ||
| 79 | encoder->pos = pos; | ||
| 80 | input_report_abs(encoder->input, pdata->axis, | ||
| 81 | encoder->pos); | ||
| 65 | } | 82 | } |
| 66 | |||
| 67 | input_report_abs(encoder->input, pdata->axis, encoder->pos); | ||
| 68 | input_sync(encoder->input); | 83 | input_sync(encoder->input); |
| 69 | 84 | ||
| 70 | encoder->armed = 0; | 85 | encoder->armed = false; |
| 71 | break; | 86 | break; |
| 72 | 87 | ||
| 73 | case 0x1: | 88 | case 0x1: |
| @@ -77,7 +92,7 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) | |||
| 77 | break; | 92 | break; |
| 78 | 93 | ||
| 79 | case 0x3: | 94 | case 0x3: |
| 80 | encoder->armed = 1; | 95 | encoder->armed = true; |
| 81 | break; | 96 | break; |
| 82 | } | 97 | } |
| 83 | 98 | ||
| @@ -113,9 +128,15 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) | |||
| 113 | input->name = pdev->name; | 128 | input->name = pdev->name; |
| 114 | input->id.bustype = BUS_HOST; | 129 | input->id.bustype = BUS_HOST; |
| 115 | input->dev.parent = &pdev->dev; | 130 | input->dev.parent = &pdev->dev; |
| 116 | input->evbit[0] = BIT_MASK(EV_ABS); | 131 | |
| 117 | input_set_abs_params(encoder->input, | 132 | if (pdata->relative_axis) { |
| 118 | pdata->axis, 0, pdata->steps, 0, 1); | 133 | input->evbit[0] = BIT_MASK(EV_REL); |
| 134 | input->relbit[0] = BIT_MASK(pdata->axis); | ||
| 135 | } else { | ||
| 136 | input->evbit[0] = BIT_MASK(EV_ABS); | ||
| 137 | input_set_abs_params(encoder->input, | ||
| 138 | pdata->axis, 0, pdata->steps, 0, 1); | ||
| 139 | } | ||
| 119 | 140 | ||
| 120 | err = input_register_device(input); | 141 | err = input_register_device(input); |
| 121 | if (err) { | 142 | if (err) { |
