1 /* 2 * rotary_encoder.c 3 * 4 * (c) 2009 Daniel Mack <daniel@caiaq.de> 5 * Copyright (C) 2011 Johan Hovold <jhovold@gmail.com> 6 * 7 * state machine code inspired by code from Tim Ruetz 8 * 9 * A generic driver for rotary encoders connected to GPIO lines. 10 * See file:Documentation/input/rotary-encoder.txt for more information 11 * 12 * This program is free software; you can redistribute it and/or modify 13 * it under the terms of the GNU General Public License version 2 as 14 * published by the Free Software Foundation. 15 */ 16 17 #include <linux/kernel.h> 18 #include <linux/module.h> 19 #include <linux/init.h> 20 #include <linux/interrupt.h> 21 #include <linux/input.h> 22 #include <linux/device.h> 23 #include <linux/platform_device.h> 24 #include <linux/gpio.h> 25 #include <linux/rotary_encoder.h> 26 #include <linux/slab.h> 27 28 #define DRV_NAME "rotary-encoder" 29 30 struct rotary_encoder { 31 struct input_dev *input; 32 struct rotary_encoder_platform_data *pdata; 33 34 unsigned int axis; 35 unsigned int pos; 36 37 unsigned int irq_a; 38 unsigned int irq_b; 39 40 bool armed; 41 unsigned char dir; /* 0 - clockwise, 1 - CCW */ 42 43 char last_stable; 44 }; 45 46 static int rotary_encoder_get_state(struct rotary_encoder_platform_data *pdata) 47 { 48 int a = !!gpio_get_value(pdata->gpio_a); 49 int b = !!gpio_get_value(pdata->gpio_b); 50 51 a ^= pdata->inverted_a; 52 b ^= pdata->inverted_b; 53 54 return ((a << 1) | b); 55 } 56 57 static void rotary_encoder_report_event(struct rotary_encoder *encoder) 58 { 59 struct rotary_encoder_platform_data *pdata = encoder->pdata; 60 61 if (pdata->relative_axis) { 62 input_report_rel(encoder->input, 63 pdata->axis, encoder->dir ? -1 : 1); 64 } else { 65 unsigned int pos = encoder->pos; 66 67 if (encoder->dir) { 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 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 } 102 break; 103 104 case 0x1: 105 case 0x2: 106 if (encoder->armed) 107 encoder->dir = state - 1; 108 break; 109 110 case 0x3: 111 encoder->armed = true; 112 break; 113 } 114 115 return IRQ_HANDLED; 116 } 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 143 static int __devinit rotary_encoder_probe(struct platform_device *pdev) 144 { 145 struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data; 146 struct rotary_encoder *encoder; 147 struct input_dev *input; 148 irq_handler_t handler; 149 int err; 150 151 if (!pdata) { 152 dev_err(&pdev->dev, "missing platform data\n"); 153 return -ENOENT; 154 } 155 156 encoder = kzalloc(sizeof(struct rotary_encoder), GFP_KERNEL); 157 input = input_allocate_device(); 158 if (!encoder || !input) { 159 dev_err(&pdev->dev, "failed to allocate memory for device\n"); 160 err = -ENOMEM; 161 goto exit_free_mem; 162 } 163 164 encoder->input = input; 165 encoder->pdata = pdata; 166 encoder->irq_a = gpio_to_irq(pdata->gpio_a); 167 encoder->irq_b = gpio_to_irq(pdata->gpio_b); 168 169 /* create and register the input driver */ 170 input->name = pdev->name; 171 input->id.bustype = BUS_HOST; 172 input->dev.parent = &pdev->dev; 173 174 if (pdata->relative_axis) { 175 input->evbit[0] = BIT_MASK(EV_REL); 176 input->relbit[0] = BIT_MASK(pdata->axis); 177 } else { 178 input->evbit[0] = BIT_MASK(EV_ABS); 179 input_set_abs_params(encoder->input, 180 pdata->axis, 0, pdata->steps, 0, 1); 181 } 182 183 err = input_register_device(input); 184 if (err) { 185 dev_err(&pdev->dev, "failed to register input device\n"); 186 goto exit_free_mem; 187 } 188 189 /* request the GPIOs */ 190 err = gpio_request(pdata->gpio_a, DRV_NAME); 191 if (err) { 192 dev_err(&pdev->dev, "unable to request GPIO %d\n", 193 pdata->gpio_a); 194 goto exit_unregister_input; 195 } 196 197 err = gpio_direction_input(pdata->gpio_a); 198 if (err) { 199 dev_err(&pdev->dev, "unable to set GPIO %d for input\n", 200 pdata->gpio_a); 201 goto exit_unregister_input; 202 } 203 204 err = gpio_request(pdata->gpio_b, DRV_NAME); 205 if (err) { 206 dev_err(&pdev->dev, "unable to request GPIO %d\n", 207 pdata->gpio_b); 208 goto exit_free_gpio_a; 209 } 210 211 err = gpio_direction_input(pdata->gpio_b); 212 if (err) { 213 dev_err(&pdev->dev, "unable to set GPIO %d for input\n", 214 pdata->gpio_b); 215 goto exit_free_gpio_a; 216 } 217 218 /* request the IRQs */ 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, 227 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 228 DRV_NAME, encoder); 229 if (err) { 230 dev_err(&pdev->dev, "unable to request IRQ %d\n", 231 encoder->irq_a); 232 goto exit_free_gpio_b; 233 } 234 235 err = request_irq(encoder->irq_b, handler, 236 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 237 DRV_NAME, encoder); 238 if (err) { 239 dev_err(&pdev->dev, "unable to request IRQ %d\n", 240 encoder->irq_b); 241 goto exit_free_irq_a; 242 } 243 244 platform_set_drvdata(pdev, encoder); 245 246 return 0; 247 248 exit_free_irq_a: 249 free_irq(encoder->irq_a, encoder); 250 exit_free_gpio_b: 251 gpio_free(pdata->gpio_b); 252 exit_free_gpio_a: 253 gpio_free(pdata->gpio_a); 254 exit_unregister_input: 255 input_unregister_device(input); 256 input = NULL; /* so we don't try to free it */ 257 exit_free_mem: 258 input_free_device(input); 259 kfree(encoder); 260 return err; 261 } 262 263 static int __devexit rotary_encoder_remove(struct platform_device *pdev) 264 { 265 struct rotary_encoder *encoder = platform_get_drvdata(pdev); 266 struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data; 267 268 free_irq(encoder->irq_a, encoder); 269 free_irq(encoder->irq_b, encoder); 270 gpio_free(pdata->gpio_a); 271 gpio_free(pdata->gpio_b); 272 input_unregister_device(encoder->input); 273 platform_set_drvdata(pdev, NULL); 274 kfree(encoder); 275 276 return 0; 277 } 278 279 static struct platform_driver rotary_encoder_driver = { 280 .probe = rotary_encoder_probe, 281 .remove = __devexit_p(rotary_encoder_remove), 282 .driver = { 283 .name = DRV_NAME, 284 .owner = THIS_MODULE, 285 } 286 }; 287 module_platform_driver(rotary_encoder_driver); 288 289 MODULE_ALIAS("platform:" DRV_NAME); 290 MODULE_DESCRIPTION("GPIO rotary encoder driver"); 291 MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>, Johan Hovold"); 292 MODULE_LICENSE("GPL v2"); 293