suspend.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /* TODO */
  2. #include <ch.h>
  3. #include <hal.h>
  4. #include "matrix.h"
  5. #include "action.h"
  6. #include "action_util.h"
  7. #include "mousekey.h"
  8. #include "host.h"
  9. #include "suspend.h"
  10. #include "led.h"
  11. #include "wait.h"
  12. #ifdef BACKLIGHT_ENABLE
  13. # include "backlight.h"
  14. #endif
  15. #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
  16. # include "rgblight.h"
  17. #endif
  18. /** \brief suspend idle
  19. *
  20. * FIXME: needs doc
  21. */
  22. void suspend_idle(uint8_t time) {
  23. // TODO: this is not used anywhere - what units is 'time' in?
  24. wait_ms(time);
  25. }
  26. /** \brief Run keyboard level Power down
  27. *
  28. * FIXME: needs doc
  29. */
  30. __attribute__((weak)) void suspend_power_down_user(void) {}
  31. /** \brief Run keyboard level Power down
  32. *
  33. * FIXME: needs doc
  34. */
  35. __attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); }
  36. /** \brief suspend power down
  37. *
  38. * FIXME: needs doc
  39. */
  40. void suspend_power_down(void) {
  41. #ifdef BACKLIGHT_ENABLE
  42. backlight_set(0);
  43. #endif
  44. // Turn off LED indicators
  45. uint8_t leds_off = 0;
  46. #if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
  47. if (is_backlight_enabled()) {
  48. // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off
  49. leds_off |= (1 << USB_LED_CAPS_LOCK);
  50. }
  51. #endif
  52. led_set(leds_off);
  53. // TODO: figure out what to power down and how
  54. // shouldn't power down TPM/FTM if we want a breathing LED
  55. // also shouldn't power down USB
  56. #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
  57. rgblight_suspend();
  58. #endif
  59. suspend_power_down_kb();
  60. // on AVR, this enables the watchdog for 15ms (max), and goes to
  61. // SLEEP_MODE_PWR_DOWN
  62. wait_ms(17);
  63. }
  64. /** \brief suspend wakeup condition
  65. *
  66. * FIXME: needs doc
  67. */
  68. __attribute__((weak)) void matrix_power_up(void) {}
  69. __attribute__((weak)) void matrix_power_down(void) {}
  70. bool suspend_wakeup_condition(void) {
  71. matrix_power_up();
  72. matrix_scan();
  73. matrix_power_down();
  74. for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
  75. if (matrix_get_row(r)) return true;
  76. }
  77. return false;
  78. }
  79. /** \brief run user level code immediately after wakeup
  80. *
  81. * FIXME: needs doc
  82. */
  83. __attribute__((weak)) void suspend_wakeup_init_user(void) {}
  84. /** \brief run keyboard level code immediately after wakeup
  85. *
  86. * FIXME: needs doc
  87. */
  88. __attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); }
  89. /** \brief suspend wakeup condition
  90. *
  91. * run immediately after wakeup
  92. * FIXME: needs doc
  93. */
  94. void suspend_wakeup_init(void) {
  95. // clear keyboard state
  96. // need to do it manually, because we're running from ISR
  97. // and clear_keyboard() calls print
  98. // so only clear the variables in memory
  99. // the reports will be sent from main.c afterwards
  100. // or if the PC asks for GET_REPORT
  101. clear_mods();
  102. clear_weak_mods();
  103. clear_keys();
  104. #ifdef MOUSEKEY_ENABLE
  105. mousekey_clear();
  106. #endif /* MOUSEKEY_ENABLE */
  107. #ifdef EXTRAKEY_ENABLE
  108. host_system_send(0);
  109. host_consumer_send(0);
  110. #endif /* EXTRAKEY_ENABLE */
  111. #ifdef BACKLIGHT_ENABLE
  112. backlight_init();
  113. #endif /* BACKLIGHT_ENABLE */
  114. led_set(host_keyboard_leds());
  115. #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
  116. rgblight_wakeup();
  117. #endif
  118. suspend_wakeup_init_kb();
  119. }