apm-power.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Input Power Event -> APM Bridge
  3. *
  4. * Copyright (c) 2007 Richard Purdie
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. */
  11. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  12. #include <linux/module.h>
  13. #include <linux/input.h>
  14. #include <linux/slab.h>
  15. #include <linux/init.h>
  16. #include <linux/tty.h>
  17. #include <linux/delay.h>
  18. #include <linux/pm.h>
  19. #include <linux/apm-emulation.h>
  20. static void system_power_event(unsigned int keycode)
  21. {
  22. switch (keycode) {
  23. case KEY_SUSPEND:
  24. apm_queue_event(APM_USER_SUSPEND);
  25. pr_info("Requesting system suspend...\n");
  26. break;
  27. default:
  28. break;
  29. }
  30. }
  31. static void apmpower_event(struct input_handle *handle, unsigned int type,
  32. unsigned int code, int value)
  33. {
  34. /* only react on key down events */
  35. if (value != 1)
  36. return;
  37. switch (type) {
  38. case EV_PWR:
  39. system_power_event(code);
  40. break;
  41. default:
  42. break;
  43. }
  44. }
  45. static int apmpower_connect(struct input_handler *handler,
  46. struct input_dev *dev,
  47. const struct input_device_id *id)
  48. {
  49. struct input_handle *handle;
  50. int error;
  51. handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
  52. if (!handle)
  53. return -ENOMEM;
  54. handle->dev = dev;
  55. handle->handler = handler;
  56. handle->name = "apm-power";
  57. error = input_register_handle(handle);
  58. if (error) {
  59. pr_err("Failed to register input power handler, error %d\n",
  60. error);
  61. kfree(handle);
  62. return error;
  63. }
  64. error = input_open_device(handle);
  65. if (error) {
  66. pr_err("Failed to open input power device, error %d\n", error);
  67. input_unregister_handle(handle);
  68. kfree(handle);
  69. return error;
  70. }
  71. return 0;
  72. }
  73. static void apmpower_disconnect(struct input_handle *handle)
  74. {
  75. input_close_device(handle);
  76. input_unregister_handle(handle);
  77. kfree(handle);
  78. }
  79. static const struct input_device_id apmpower_ids[] = {
  80. {
  81. .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
  82. .evbit = { BIT_MASK(EV_PWR) },
  83. },
  84. { },
  85. };
  86. MODULE_DEVICE_TABLE(input, apmpower_ids);
  87. static struct input_handler apmpower_handler = {
  88. .event = apmpower_event,
  89. .connect = apmpower_connect,
  90. .disconnect = apmpower_disconnect,
  91. .name = "apm-power",
  92. .id_table = apmpower_ids,
  93. };
  94. static int __init apmpower_init(void)
  95. {
  96. return input_register_handler(&apmpower_handler);
  97. }
  98. static void __exit apmpower_exit(void)
  99. {
  100. input_unregister_handler(&apmpower_handler);
  101. }
  102. module_init(apmpower_init);
  103. module_exit(apmpower_exit);
  104. MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
  105. MODULE_DESCRIPTION("Input Power Event -> APM Bridge");
  106. MODULE_LICENSE("GPL");