1 /* 2 * rotary_encoder.c 3 * 4 * (c) 2009 Daniel Mack <daniel@caiaq.de> 5 * 6 * state machine code inspired by code from Tim Ruetz 7 * 8 * A generic driver for rotary encoders connected to GPIO lines. 9 * See file:Documentation/input/rotary_encoder.txt for more information 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License version 2 as 13 * published by the Free Software Foundation. 14 */ 15 16 #include <linux/kernel.h> 17 #include <linux/module.h> 18 #include <linux/init.h> 19 #include <linux/interrupt.h> 20 #include <linux/input.h> 21 #include <linux/device.h> 22 #include <linux/platform_device.h> 23 #include <linux/gpio.h> 24 #include <linux/rotary_encoder.h> 25 #include <linux/slab.h> 26 27 #define DRV_NAME "rotary-encoder" 28 29 struct rotary_encoder { 30 struct input_dev *input; 31 struct rotary_encoder_platform_data *pdata; 32 33 unsigned int axis; 34 unsigned int pos; 35 36 unsigned int irq_a; 37 unsigned int irq_b; 38 39 bool armed; 40 unsigned char dir; /* 0 - clockwise, 1 - CCW */ 41 }; 42 43 static int rotary_encoder_get_state(struct rotary_encoder_platform_data *pdata) 44 { 45 int a = !!gpio_get_value(pdata->gpio_a); 46 int b = !!gpio_get_value(pdata->gpio_b); 47 48 a ^= pdata->inverted_a; 49 b ^= pdata->inverted_b; 50 51 return ((a << 1) | b); 52 } 53 54 static void rotary_encoder_report_event(struct rotary_encoder *encoder) 55 { 56 struct rotary_encoder_platform_data *pdata = encoder->pdata; 57 58 if (pdata->relative_axis) { 59 input_report_rel(encoder->input, 60 pdata->axis, encoder->dir ? -1 : 1); 61 } else { 62 unsigned int pos = encoder->pos; 63 64 if (encoder->dir) { 65 /* turning counter-clockwise */ 66 if (pdata->rollover) 67 pos += pdata->steps; 68 if (pos) 69 pos--; 70 } else { 71 /* turning clockwise */ 72 if (pdata->rollover || pos < pdata->steps) 73 pos++; 74 } 75 76 if (pdata->rollover) 77 pos %= pdata->steps; 78 79 encoder->pos = pos; 80 input_report_abs(encoder->input, pdata->axis, encoder->pos); 81 } 82 83 input_sync(encoder->input); 84 } 85 86 static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) 87 { 88 struct rotary_encoder *encoder = dev_id; 89 int state; 90 91 state = rotary_encoder_get_state(encoder->pdata); 92 93 switch (state) { 94 case 0x0: 95 if (encoder->armed) { 96 rotary_encoder_report_event(encoder); 97 encoder->armed = false; 98 } 99 break; 100 101 case 0x1: 102 case 0x2: 103 if (encoder->armed) 104 encoder->dir = state - 1; 105 break; 106 107 case 0x3: 108 encoder->armed = true; 109 break; 110 } 111 112 return IRQ_HANDLED; 113 } 114 115 static int __devinit rotary_encoder_probe(struct platform_device *pdev) 116 { 117 struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data; 118 struct rotary_encoder *encoder; 119 struct input_dev *input; 120 int err; 121 122 if (!pdata) { 123 dev_err(&pdev->dev, "missing platform data\n"); 124 return -ENOENT; 125 } 126 127 encoder = kzalloc(sizeof(struct rotary_encoder), GFP_KERNEL); 128 input = input_allocate_device(); 129 if (!encoder || !input) { 130 dev_err(&pdev->dev, "failed to allocate memory for device\n"); 131 err = -ENOMEM; 132 goto exit_free_mem; 133 } 134 135 encoder->input = input; 136 encoder->pdata = pdata; 137 encoder->irq_a = gpio_to_irq(pdata->gpio_a); 138 encoder->irq_b = gpio_to_irq(pdata->gpio_b); 139 140 /* create and register the input driver */ 141 input->name = pdev->name; 142 input->id.bustype = BUS_HOST; 143 input->dev.parent = &pdev->dev; 144 145 if (pdata->relative_axis) { 146 input->evbit[0] = BIT_MASK(EV_REL); 147 input->relbit[0] = BIT_MASK(pdata->axis); 148 } else { 149 input->evbit[0] = BIT_MASK(EV_ABS); 150 input_set_abs_params(encoder->input, 151 pdata->axis, 0, pdata->steps, 0, 1); 152 } 153 154 err = input_register_device(input); 155 if (err) { 156 dev_err(&pdev->dev, "failed to register input device\n"); 157 goto exit_free_mem; 158 } 159 160 /* request the GPIOs */ 161 err = gpio_request(pdata->gpio_a, DRV_NAME); 162 if (err) { 163 dev_err(&pdev->dev, "unable to request GPIO %d\n", 164 pdata->gpio_a); 165 goto exit_unregister_input; 166 } 167 168 err = gpio_direction_input(pdata->gpio_a); 169 if (err) { 170 dev_err(&pdev->dev, "unable to set GPIO %d for input\n", 171 pdata->gpio_a); 172 goto exit_unregister_input; 173 } 174 175 err = gpio_request(pdata->gpio_b, DRV_NAME); 176 if (err) { 177 dev_err(&pdev->dev, "unable to request GPIO %d\n", 178 pdata->gpio_b); 179 goto exit_free_gpio_a; 180 } 181 182 err = gpio_direction_input(pdata->gpio_b); 183 if (err) { 184 dev_err(&pdev->dev, "unable to set GPIO %d for input\n", 185 pdata->gpio_b); 186 goto exit_free_gpio_a; 187 } 188 189 /* request the IRQs */ 190 err = request_irq(encoder->irq_a, &rotary_encoder_irq, 191 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 192 DRV_NAME, encoder); 193 if (err) { 194 dev_err(&pdev->dev, "unable to request IRQ %d\n", 195 encoder->irq_a); 196 goto exit_free_gpio_b; 197 } 198 199 err = request_irq(encoder->irq_b, &rotary_encoder_irq, 200 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, 201 DRV_NAME, encoder); 202 if (err) { 203 dev_err(&pdev->dev, "unable to request IRQ %d\n", 204 encoder->irq_b); 205 goto exit_free_irq_a; 206 } 207 208 platform_set_drvdata(pdev, encoder); 209 210 return 0; 211 212 exit_free_irq_a: 213 free_irq(encoder->irq_a, encoder); 214 exit_free_gpio_b: 215 gpio_free(pdata->gpio_b); 216 exit_free_gpio_a: 217 gpio_free(pdata->gpio_a); 218 exit_unregister_input: 219 input_unregister_device(input); 220 input = NULL; /* so we don't try to free it */ 221 exit_free_mem: 222 input_free_device(input); 223 kfree(encoder); 224 return err; 225 } 226 227 static int __devexit rotary_encoder_remove(struct platform_device *pdev) 228 { 229 struct rotary_encoder *encoder = platform_get_drvdata(pdev); 230 struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data; 231 232 free_irq(encoder->irq_a, encoder); 233 free_irq(encoder->irq_b, encoder); 234 gpio_free(pdata->gpio_a); 235 gpio_free(pdata->gpio_b); 236 input_unregister_device(encoder->input); 237 platform_set_drvdata(pdev, NULL); 238 kfree(encoder); 239 240 return 0; 241 } 242 243 static struct platform_driver rotary_encoder_driver = { 244 .probe = rotary_encoder_probe, 245 .remove = __devexit_p(rotary_encoder_remove), 246 .driver = { 247 .name = DRV_NAME, 248 .owner = THIS_MODULE, 249 } 250 }; 251 252 static int __init rotary_encoder_init(void) 253 { 254 return platform_driver_register(&rotary_encoder_driver); 255 } 256 257 static void __exit rotary_encoder_exit(void) 258 { 259 platform_driver_unregister(&rotary_encoder_driver); 260 } 261 262 module_init(rotary_encoder_init); 263 module_exit(rotary_encoder_exit); 264 265 MODULE_ALIAS("platform:" DRV_NAME); 266 MODULE_DESCRIPTION("GPIO rotary encoder driver"); 267 MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); 268 MODULE_LICENSE("GPL v2"); 269