led_ctl.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <sys/io.h>
  5. #include <time.h>
  6. #include <errno.h>
  7. #include "led_ctl.h"
  8. #define EC_CMD_PORT 0x66
  9. #define EC_DATA_PORT 0x62
  10. #define EC_OBF 0x01 // Output Buffer Full
  11. #define EC_IBF 0x02 // Input Buffer Full
  12. #define CMD_READ_RAM 0x97
  13. #define CMD_WRITE_RAM 0x98
  14. #define OFFSET_COLOR_CTL 0x01
  15. #define OFFSET_BLINK_TIME 0x02
  16. #define OFFSET_BLINK_CTL 0x03
  17. #define BIT0 (1 << 0)
  18. #define TIMEOUT_LOOPS 100000
  19. static int wait_ibf(void)
  20. {
  21. int i = 0;
  22. while (inb(EC_CMD_PORT) & EC_IBF)
  23. {
  24. if (++i > TIMEOUT_LOOPS)
  25. {
  26. fprintf(stderr, "Error: EC IBF Timeout!\n");
  27. return -1;
  28. }
  29. usleep(1);
  30. }
  31. return 0;
  32. }
  33. static int wait_obf(void)
  34. {
  35. int i = 0;
  36. while (!(inb(EC_CMD_PORT) & EC_OBF))
  37. {
  38. if (++i > TIMEOUT_LOOPS)
  39. {
  40. fprintf(stderr, "Error: EC OBF Timeout!\n");
  41. return -1;
  42. }
  43. usleep(1);
  44. }
  45. return 0;
  46. }
  47. static int ec_read_ram(uint8_t offset, uint8_t *data)
  48. {
  49. if (wait_ibf() < 0)
  50. return -1;
  51. outb(CMD_READ_RAM, EC_CMD_PORT);
  52. if (wait_ibf() < 0)
  53. return -1;
  54. outb(offset, EC_DATA_PORT);
  55. if (wait_obf() < 0)
  56. return -1;
  57. *data = inb(EC_DATA_PORT);
  58. return 0;
  59. }
  60. static int ec_write_ram(uint8_t offset, uint8_t data)
  61. {
  62. if (wait_ibf() < 0)
  63. return -1;
  64. outb(CMD_WRITE_RAM, EC_CMD_PORT);
  65. if (wait_ibf() < 0)
  66. return -1;
  67. outb(offset, EC_DATA_PORT);
  68. if (wait_ibf() < 0)
  69. return -1;
  70. outb(data, EC_DATA_PORT);
  71. return 0;
  72. }
  73. // ---------API functions---------
  74. int led_driver_init(void)
  75. {
  76. if (ioperm(EC_DATA_PORT, 1, 1))
  77. {
  78. perror("Failed to get permission for 0x62");
  79. return -1;
  80. }
  81. if (ioperm(EC_CMD_PORT, 1, 1))
  82. {
  83. perror("Failed to get permission for 0x66");
  84. return -1;
  85. }
  86. return 0;
  87. }
  88. int led_set_color(led_color_t color)
  89. {
  90. uint8_t val;
  91. if (ec_read_ram(OFFSET_COLOR_CTL, &val) < 0)
  92. return -1;
  93. if (color == LED_RED)
  94. val |= BIT0;
  95. else
  96. val &= ~BIT0;
  97. return ec_write_ram(OFFSET_COLOR_CTL, val);
  98. }
  99. int led_set_blink(int enable, uint8_t interval_unit)
  100. {
  101. uint8_t ctl;
  102. if (enable)
  103. {
  104. if (ec_write_ram(OFFSET_BLINK_TIME, interval_unit) < 0)
  105. return -1;
  106. }
  107. if (ec_read_ram(OFFSET_BLINK_CTL, &ctl) < 0)
  108. return -1;
  109. if (enable)
  110. ctl |= BIT0;
  111. else
  112. ctl &= ~BIT0;
  113. return ec_write_ram(OFFSET_BLINK_CTL, ctl);
  114. }
  115. int led_print_status(void)
  116. {
  117. uint8_t color_reg, blink_time, blink_ctl;
  118. if (ec_read_ram(OFFSET_COLOR_CTL, &color_reg) < 0)
  119. return -1;
  120. if (ec_read_ram(OFFSET_BLINK_TIME, &blink_time) < 0)
  121. return -1;
  122. if (ec_read_ram(OFFSET_BLINK_CTL, &blink_ctl) < 0)
  123. return -1;
  124. printf(" Color : %s\n", (color_reg & BIT0) ? "RED" : "GREEN");
  125. printf(" Blink : %s\n", (blink_ctl & BIT0) ? "ON" : "OFF");
  126. if (blink_ctl & BIT0)
  127. {
  128. printf(" Interval : %d ms (%d units)\n", blink_time * 100, blink_time);
  129. }
  130. return 0;
  131. }