#include #include #include #include #include #include #include "led_ctl.h" #define EC_CMD_PORT 0x66 #define EC_DATA_PORT 0x62 #define EC_OBF 0x01 // Output Buffer Full #define EC_IBF 0x02 // Input Buffer Full #define CMD_READ_RAM 0x97 #define CMD_WRITE_RAM 0x98 #define OFFSET_COLOR_CTL 0x01 #define OFFSET_BLINK_TIME 0x02 #define OFFSET_BLINK_CTL 0x03 #define BIT0 (1 << 0) #define TIMEOUT_LOOPS 100000 static int wait_ibf(void) { int i = 0; while (inb(EC_CMD_PORT) & EC_IBF) { if (++i > TIMEOUT_LOOPS) { fprintf(stderr, "Error: EC IBF Timeout!\n"); return -1; } usleep(1); } return 0; } static int wait_obf(void) { int i = 0; while (!(inb(EC_CMD_PORT) & EC_OBF)) { if (++i > TIMEOUT_LOOPS) { fprintf(stderr, "Error: EC OBF Timeout!\n"); return -1; } usleep(1); } return 0; } static int ec_read_ram(uint8_t offset, uint8_t *data) { if (wait_ibf() < 0) return -1; outb(CMD_READ_RAM, EC_CMD_PORT); if (wait_ibf() < 0) return -1; outb(offset, EC_DATA_PORT); if (wait_obf() < 0) return -1; *data = inb(EC_DATA_PORT); return 0; } static int ec_write_ram(uint8_t offset, uint8_t data) { if (wait_ibf() < 0) return -1; outb(CMD_WRITE_RAM, EC_CMD_PORT); if (wait_ibf() < 0) return -1; outb(offset, EC_DATA_PORT); if (wait_ibf() < 0) return -1; outb(data, EC_DATA_PORT); return 0; } // ---------API functions--------- int led_driver_init(void) { if (ioperm(EC_DATA_PORT, 1, 1)) { perror("Failed to get permission for 0x62"); return -1; } if (ioperm(EC_CMD_PORT, 1, 1)) { perror("Failed to get permission for 0x66"); return -1; } return 0; } int led_set_color(led_color_t color) { uint8_t val; if (ec_read_ram(OFFSET_COLOR_CTL, &val) < 0) return -1; if (color == LED_RED) val |= BIT0; else val &= ~BIT0; return ec_write_ram(OFFSET_COLOR_CTL, val); } int led_set_blink(int enable, uint8_t interval_unit) { uint8_t ctl; if (enable) { if (ec_write_ram(OFFSET_BLINK_TIME, interval_unit) < 0) return -1; } if (ec_read_ram(OFFSET_BLINK_CTL, &ctl) < 0) return -1; if (enable) ctl |= BIT0; else ctl &= ~BIT0; return ec_write_ram(OFFSET_BLINK_CTL, ctl); } int led_print_status(void) { uint8_t color_reg, blink_time, blink_ctl; if (ec_read_ram(OFFSET_COLOR_CTL, &color_reg) < 0) return -1; if (ec_read_ram(OFFSET_BLINK_TIME, &blink_time) < 0) return -1; if (ec_read_ram(OFFSET_BLINK_CTL, &blink_ctl) < 0) return -1; printf(" Color : %s\n", (color_reg & BIT0) ? "RED" : "GREEN"); printf(" Blink : %s\n", (blink_ctl & BIT0) ? "ON" : "OFF"); if (blink_ctl & BIT0) { printf(" Interval : %d ms (%d units)\n", blink_time * 100, blink_time); } return 0; }