rotary_encoder.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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. #include <linux/kernel.h>
  16. #include <linux/module.h>
  17. #include <linux/init.h>
  18. #include <linux/interrupt.h>
  19. #include <linux/input.h>
  20. #include <linux/device.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/gpio.h>
  23. #include <linux/rotary_encoder.h>
  24. #define DRV_NAME "rotary-encoder"
  25. struct rotary_encoder {
  26. unsigned int irq_a;
  27. unsigned int irq_b;
  28. unsigned int pos;
  29. unsigned int armed;
  30. unsigned int dir;
  31. struct input_dev *input;
  32. struct rotary_encoder_platform_data *pdata;
  33. };
  34. static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
  35. {
  36. struct rotary_encoder *encoder = dev_id;
  37. struct rotary_encoder_platform_data *pdata = encoder->pdata;
  38. int a = !!gpio_get_value(pdata->gpio_a);
  39. int b = !!gpio_get_value(pdata->gpio_b);
  40. int state;
  41. a ^= pdata->inverted_a;
  42. b ^= pdata->inverted_b;
  43. state = (a << 1) | b;
  44. switch (state) {
  45. case 0x0:
  46. if (!encoder->armed)
  47. break;
  48. if (encoder->dir) {
  49. /* turning counter-clockwise */
  50. encoder->pos += pdata->steps;
  51. encoder->pos--;
  52. encoder->pos %= pdata->steps;
  53. } else {
  54. /* turning clockwise */
  55. encoder->pos++;
  56. encoder->pos %= pdata->steps;
  57. }
  58. input_report_abs(encoder->input, pdata->axis, encoder->pos);
  59. input_sync(encoder->input);
  60. encoder->armed = 0;
  61. break;
  62. case 0x1:
  63. case 0x2:
  64. if (encoder->armed)
  65. encoder->dir = state - 1;
  66. break;
  67. case 0x3:
  68. encoder->armed = 1;
  69. break;
  70. }
  71. return IRQ_HANDLED;
  72. }
  73. static int __devinit rotary_encoder_probe(struct platform_device *pdev)
  74. {
  75. struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data;
  76. struct rotary_encoder *encoder;
  77. struct input_dev *input;
  78. int err;
  79. if (!pdata || !pdata->steps) {
  80. dev_err(&pdev->dev, "invalid platform data\n");
  81. return -ENOENT;
  82. }
  83. encoder = kzalloc(sizeof(struct rotary_encoder), GFP_KERNEL);
  84. input = input_allocate_device();
  85. if (!encoder || !input) {
  86. dev_err(&pdev->dev, "failed to allocate memory for device\n");
  87. err = -ENOMEM;
  88. goto exit_free_mem;
  89. }
  90. encoder->input = input;
  91. encoder->pdata = pdata;
  92. encoder->irq_a = gpio_to_irq(pdata->gpio_a);
  93. encoder->irq_b = gpio_to_irq(pdata->gpio_b);
  94. /* create and register the input driver */
  95. input->name = pdev->name;
  96. input->id.bustype = BUS_HOST;
  97. input->dev.parent = &pdev->dev;
  98. input->evbit[0] = BIT_MASK(EV_ABS);
  99. input_set_abs_params(encoder->input,
  100. pdata->axis, 0, pdata->steps, 0, 1);
  101. err = input_register_device(input);
  102. if (err) {
  103. dev_err(&pdev->dev, "failed to register input device\n");
  104. goto exit_free_mem;
  105. }
  106. /* request the GPIOs */
  107. err = gpio_request(pdata->gpio_a, DRV_NAME);
  108. if (err) {
  109. dev_err(&pdev->dev, "unable to request GPIO %d\n",
  110. pdata->gpio_a);
  111. goto exit_unregister_input;
  112. }
  113. err = gpio_request(pdata->gpio_b, DRV_NAME);
  114. if (err) {
  115. dev_err(&pdev->dev, "unable to request GPIO %d\n",
  116. pdata->gpio_b);
  117. goto exit_free_gpio_a;
  118. }
  119. /* request the IRQs */
  120. err = request_irq(encoder->irq_a, &rotary_encoder_irq,
  121. IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
  122. DRV_NAME, encoder);
  123. if (err) {
  124. dev_err(&pdev->dev, "unable to request IRQ %d\n",
  125. encoder->irq_a);
  126. goto exit_free_gpio_b;
  127. }
  128. err = request_irq(encoder->irq_b, &rotary_encoder_irq,
  129. IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE,
  130. DRV_NAME, encoder);
  131. if (err) {
  132. dev_err(&pdev->dev, "unable to request IRQ %d\n",
  133. encoder->irq_b);
  134. goto exit_free_irq_a;
  135. }
  136. platform_set_drvdata(pdev, encoder);
  137. return 0;
  138. exit_free_irq_a:
  139. free_irq(encoder->irq_a, encoder);
  140. exit_free_gpio_b:
  141. gpio_free(pdata->gpio_b);
  142. exit_free_gpio_a:
  143. gpio_free(pdata->gpio_a);
  144. exit_unregister_input:
  145. input_unregister_device(input);
  146. input = NULL; /* so we don't try to free it */
  147. exit_free_mem:
  148. input_free_device(input);
  149. kfree(encoder);
  150. return err;
  151. }
  152. static int __devexit rotary_encoder_remove(struct platform_device *pdev)
  153. {
  154. struct rotary_encoder *encoder = platform_get_drvdata(pdev);
  155. struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data;
  156. free_irq(encoder->irq_a, encoder);
  157. free_irq(encoder->irq_b, encoder);
  158. gpio_free(pdata->gpio_a);
  159. gpio_free(pdata->gpio_b);
  160. input_unregister_device(encoder->input);
  161. platform_set_drvdata(pdev, NULL);
  162. kfree(encoder);
  163. return 0;
  164. }
  165. static struct platform_driver rotary_encoder_driver = {
  166. .probe = rotary_encoder_probe,
  167. .remove = __devexit_p(rotary_encoder_remove),
  168. .driver = {
  169. .name = DRV_NAME,
  170. .owner = THIS_MODULE,
  171. }
  172. };
  173. static int __init rotary_encoder_init(void)
  174. {
  175. return platform_driver_register(&rotary_encoder_driver);
  176. }
  177. static void __exit rotary_encoder_exit(void)
  178. {
  179. platform_driver_unregister(&rotary_encoder_driver);
  180. }
  181. module_init(rotary_encoder_init);
  182. module_exit(rotary_encoder_exit);
  183. MODULE_ALIAS("platform:" DRV_NAME);
  184. MODULE_DESCRIPTION("GPIO rotary encoder driver");
  185. MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
  186. MODULE_LICENSE("GPL v2");