aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc/rotary_encoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/misc/rotary_encoder.c')
-rw-r--r--drivers/input/misc/rotary_encoder.c61
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
28struct rotary_encoder { 28struct 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
38static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) 42static 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) {