2
0

gpio_key.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. * GPIO key
  3. *
  4. * Copyright (c) 2016 Linaro Limited
  5. *
  6. * Author: Shannon Zhao <shannon.zhao@linaro.org>
  7. *
  8. * Emulate a (human) keypress -- when the key is triggered by
  9. * setting the incoming gpio line, the outbound irq line is
  10. * raised for 100ms before being dropped again.
  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; either version 2
  14. * of the License, or (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License along
  22. * with this program; if not, see <http://www.gnu.org/licenses/>.
  23. */
  24. #include "qemu/osdep.h"
  25. #include "hw/irq.h"
  26. #include "hw/sysbus.h"
  27. #include "migration/vmstate.h"
  28. #include "qemu/module.h"
  29. #include "qemu/timer.h"
  30. #define TYPE_GPIOKEY "gpio-key"
  31. #define GPIOKEY(obj) OBJECT_CHECK(GPIOKEYState, (obj), TYPE_GPIOKEY)
  32. #define GPIO_KEY_LATENCY 100 /* 100ms */
  33. typedef struct GPIOKEYState {
  34. SysBusDevice parent_obj;
  35. QEMUTimer *timer;
  36. qemu_irq irq;
  37. } GPIOKEYState;
  38. static const VMStateDescription vmstate_gpio_key = {
  39. .name = "gpio-key",
  40. .version_id = 1,
  41. .minimum_version_id = 1,
  42. .fields = (VMStateField[]) {
  43. VMSTATE_TIMER_PTR(timer, GPIOKEYState),
  44. VMSTATE_END_OF_LIST()
  45. }
  46. };
  47. static void gpio_key_reset(DeviceState *dev)
  48. {
  49. GPIOKEYState *s = GPIOKEY(dev);
  50. timer_del(s->timer);
  51. }
  52. static void gpio_key_timer_expired(void *opaque)
  53. {
  54. GPIOKEYState *s = (GPIOKEYState *)opaque;
  55. qemu_set_irq(s->irq, 0);
  56. timer_del(s->timer);
  57. }
  58. static void gpio_key_set_irq(void *opaque, int irq, int level)
  59. {
  60. GPIOKEYState *s = (GPIOKEYState *)opaque;
  61. qemu_set_irq(s->irq, 1);
  62. timer_mod(s->timer,
  63. qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + GPIO_KEY_LATENCY);
  64. }
  65. static void gpio_key_realize(DeviceState *dev, Error **errp)
  66. {
  67. GPIOKEYState *s = GPIOKEY(dev);
  68. SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
  69. sysbus_init_irq(sbd, &s->irq);
  70. qdev_init_gpio_in(dev, gpio_key_set_irq, 1);
  71. s->timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, gpio_key_timer_expired, s);
  72. }
  73. static void gpio_key_class_init(ObjectClass *klass, void *data)
  74. {
  75. DeviceClass *dc = DEVICE_CLASS(klass);
  76. dc->realize = gpio_key_realize;
  77. dc->vmsd = &vmstate_gpio_key;
  78. dc->reset = &gpio_key_reset;
  79. }
  80. static const TypeInfo gpio_key_info = {
  81. .name = TYPE_GPIOKEY,
  82. .parent = TYPE_SYS_BUS_DEVICE,
  83. .instance_size = sizeof(GPIOKEYState),
  84. .class_init = gpio_key_class_init,
  85. };
  86. static void gpio_key_register_types(void)
  87. {
  88. type_register_static(&gpio_key_info);
  89. }
  90. type_init(gpio_key_register_types)