apm-power.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  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. #include <linux/module.h>
  12. #include <linux/input.h>
  13. #include <linux/slab.h>
  14. #include <linux/init.h>
  15. #include <linux/tty.h>
  16. #include <linux/delay.h>
  17. #include <linux/pm.h>
  18. #include <linux/apm-emulation.h>
  19. static void system_power_event(unsigned int keycode)
  20. {
  21. switch (keycode) {
  22. case KEY_SUSPEND:
  23. apm_queue_event(APM_USER_SUSPEND);
  24. printk(KERN_INFO "apm-power: Requesting system suspend...\n");
  25. break;
  26. default:
  27. break;
  28. }
  29. }
  30. static void apmpower_event(struct input_handle *handle, unsigned int type,
  31. unsigned int code, int value)
  32. {
  33. /* only react on key down events */
  34. if (value != 1)
  35. return;
  36. switch (type) {
  37. case EV_PWR:
  38. system_power_event(code);
  39. break;
  40. default:
  41. break;
  42. }
  43. }
  44. static int apmpower_connect(struct input_handler *handler,
  45. struct input_dev *dev,
  46. const struct input_device_id *id)
  47. {
  48. struct input_handle *handle;
  49. int error;
  50. handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
  51. if (!handle)
  52. return -ENOMEM;
  53. handle->dev = dev;
  54. handle->handler = handler;
  55. handle->name = "apm-power";
  56. handler->private = handle;
  57. error = input_register_handle(handle);
  58. if (error) {
  59. printk(KERN_ERR
  60. "apm-power: Failed to register input power handler, "
  61. "error %d\n", error);
  62. kfree(handle);
  63. return error;
  64. }
  65. error = input_open_device(handle);
  66. if (error) {
  67. printk(KERN_ERR
  68. "apm-power: Failed to open input power device, "
  69. "error %d\n", error);
  70. input_unregister_handle(handle);
  71. kfree(handle);
  72. return error;
  73. }
  74. return 0;
  75. }
  76. static void apmpower_disconnect(struct input_handle *handler)
  77. {
  78. struct input_handle *handle = handler->private;
  79. input_close_device(handle);
  80. kfree(handle);
  81. }
  82. static const struct input_device_id apmpower_ids[] = {
  83. {
  84. .flags = INPUT_DEVICE_ID_MATCH_EVBIT,
  85. .evbit = { BIT_MASK(EV_PWR) },
  86. },
  87. { },
  88. };
  89. MODULE_DEVICE_TABLE(input, apmpower_ids);
  90. static struct input_handler apmpower_handler = {
  91. .event = apmpower_event,
  92. .connect = apmpower_connect,
  93. .disconnect = apmpower_disconnect,
  94. .name = "apm-power",
  95. .id_table = apmpower_ids,
  96. };
  97. static int __init apmpower_init(void)
  98. {
  99. return input_register_handler(&apmpower_handler);
  100. }
  101. static void __exit apmpower_exit(void)
  102. {
  103. input_unregister_handler(&apmpower_handler);
  104. }
  105. module_init(apmpower_init);
  106. module_exit(apmpower_exit);
  107. MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
  108. MODULE_DESCRIPTION("Input Power Event -> APM Bridge");
  109. MODULE_LICENSE("GPL");