Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 36 additions & 7 deletions keyboards/system76/system76_ec.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "eeprom.h"
#include "quantum.h"
#include "raw_hid.h"
#include "thelio_io_2/config.h"
#include "version.h"
#ifdef DYNAMIC_KEYMAP_ENABLE
#include "dynamic_keymap.h"
Expand Down Expand Up @@ -48,7 +49,11 @@ enum Command {
CMD_SET_NO_INPUT = 19, // Enable/disable no input mode
CMD_SECURITY_GET = 20, // Get security state
CMD_SECURITY_SET = 21, // Set security state
CMD_FAN_TACH = 22, // Get fan tachometer
CMD_FAN_GET_RPM = 22, // Get fan rpm
CMD_FAN_GET_MODE = 23, // Get fan mode
CMD_FAN_SET_MODE = 24, // Set fan mode
CMD_CASE_REV_GET = 25, // Get case revision
CMD_CASE_REV_SET = 26, // Set case revision
};

bool input_disabled = false;
Expand Down Expand Up @@ -103,7 +108,7 @@ __attribute__((weak)) bool system76_ec_fan_set(uint8_t index, uint8_t duty) {
return false;
}

__attribute__((weak)) bool system76_ec_fan_tach(uint8_t index, uint16_t * tach) {
__attribute__((weak)) bool system76_ec_fan_get_rpm(uint8_t index, uint16_t * rpm) {
return false;
}

Expand Down Expand Up @@ -259,6 +264,20 @@ void system76_ec_rgb_layer(layer_state_t layer_state) {
}
#endif // RGB_MATRIX_CUSTOM_KB

// Read or write EEPROM data with checks for being inside System76 EC region.
bool system76_ec_case_rev(uint8_t *buf, size_t size, bool write) {
#ifdef SYSTEM76_EC_EEPROM_CASE_REV_ADDR
if (write) {
eeprom_update_block((const void *)buf, (void *)SYSTEM76_EC_EEPROM_CASE_REV_ADDR, size);
} else {
eeprom_read_block((void *)buf, (const void *)SYSTEM76_EC_EEPROM_CASE_REV_ADDR, size);
}
return true;
#endif

return false;
}

void raw_hid_receive(uint8_t *data, uint8_t length) {
// Error response by default, set to success by commands
data[1] = 1;
Expand Down Expand Up @@ -468,11 +487,11 @@ void raw_hid_receive(uint8_t *data, uint8_t length) {
input_disabled = data[2] != 0;
data[1] = 0;
} break;
case CMD_FAN_TACH: {
uint16_t tach = 0;
if (system76_ec_fan_tach(data[2], &tach)) {
data[3] = (uint8_t)tach;
data[4] = (uint8_t)(tach >> 8);
case CMD_FAN_GET_RPM: {
uint16_t rpm = 0;
if (system76_ec_fan_get_rpm(data[2], &rpm)) {
data[3] = (uint8_t)rpm;
data[4] = (uint8_t)(rpm >> 8);
data[1] = 0;
}
} break;
Expand All @@ -486,6 +505,16 @@ void raw_hid_receive(uint8_t *data, uint8_t length) {
data[1] = 0;
}
break;
case CMD_CASE_REV_GET:
if (system76_ec_case_rev(&data[2], SYSTEM76_EC_EEPROM_CASE_REV_SIZE, false)) {
data[1] = 0;
}
break;
case CMD_CASE_REV_SET:
if (system76_ec_case_rev(&data[2], SYSTEM76_EC_EEPROM_CASE_REV_SIZE, true)) {
data[1] = 0;
}
break;
}

raw_hid_send(data, length);
Expand Down
4 changes: 3 additions & 1 deletion keyboards/system76/system76_ec.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ bool system76_ec_is_unlocked(void);

bool system76_ec_fan_get(uint8_t index, uint8_t * duty);
bool system76_ec_fan_set(uint8_t index, uint8_t duty);
bool system76_ec_fan_tach(uint8_t index, uint16_t * tach);
bool system76_ec_fan_get_rpm(uint8_t index, uint16_t * tach);

bool system76_ec_led_get_mode(uint8_t layer, uint8_t * mode, uint8_t * speed);
bool system76_ec_led_set_mode(uint8_t layer, uint8_t mode, uint8_t speed);

bool system76_ec_security_get(enum SecurityState * state);
bool system76_ec_security_set(enum SecurityState state);

bool system76_ec_case_rev(uint8_t *buf, size_t size, bool write);
17 changes: 17 additions & 0 deletions keyboards/system76/thelio_io_2/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,20 @@
#define BACKLIGHT_BREATHING
#define BACKLIGHT_LEVELS 31
#define BACKLIGHT_PERIOD 1

// EEPROM {
#define EEPROM_SIZE 1024
// TODO: Refactor with new user EEPROM code (coming soon)
#define EEPROM_MAGIC 0x76EC
#define EEPROM_MAGIC_ADDR 64
// Bump this every time we change what we store
// This will automatically reset the EEPROM with defaults
// and avoid loading invalid data from the EEPROM
#define EEPROM_VERSION 0x01
#define EEPROM_VERSION_ADDR (EEPROM_MAGIC_ADDR + 2)
// } EEPROM

// System76 EC {
#define SYSTEM76_EC_EEPROM_CASE_REV_ADDR (EEPROM_VERSION_ADDR + 1)
#define SYSTEM76_EC_EEPROM_CASE_REV_SIZE 4
// } System76 EC
33 changes: 28 additions & 5 deletions keyboards/system76/thelio_io_2/thelio_io_2.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/

#include "analog.h"
#include "config.h"
#include "eeprom.h"
#include "../system76_ec.h"

#include "thelio_io_2.h"
Expand Down Expand Up @@ -186,6 +188,27 @@ void keyboard_pre_init_kb(void) {
keyboard_pre_init_user();
}

bool eeprom_is_valid(void) {
return (
eeprom_read_word(((void *)EEPROM_MAGIC_ADDR)) == EEPROM_MAGIC &&
eeprom_read_byte(((void *)EEPROM_VERSION_ADDR)) == EEPROM_VERSION
);
}
// clang-format on

void eeprom_set_valid(bool valid) {
eeprom_update_word(((void *)EEPROM_MAGIC_ADDR), valid ? EEPROM_MAGIC : 0xFFFF);
eeprom_update_byte(((void *)EEPROM_VERSION_ADDR), valid ? EEPROM_VERSION : 0xFF);
}

void matrix_init_kb(void) {
if (!eeprom_is_valid()) {
uint8_t rev[SYSTEM76_EC_EEPROM_CASE_REV_SIZE] = { 0 };
system76_ec_case_rev(rev, SYSTEM76_EC_EEPROM_CASE_REV_SIZE, true);
eeprom_set_valid(true);
}
}

void keyboard_post_init_kb(void) {
#ifdef CONSOLE_ENABLE
// Set console verbosity
Expand Down Expand Up @@ -416,19 +439,19 @@ bool system76_ec_fan_set(uint8_t index, uint8_t duty) {
return true;
}

bool system76_ec_fan_tach(uint8_t index, uint16_t * tach) {
bool system76_ec_fan_get_rpm(uint8_t index, uint16_t * rpm) {
switch (index) {
case 0:
*tach = FANOUT1.tach;
*rpm = FANOUT1.tach;
return true;
case 1:
*tach = FANOUT2.tach;
*rpm = FANOUT2.tach;
return true;
case 2:
*tach = FANOUT3.tach;
*rpm = FANOUT3.tach;
return true;
case 3:
*tach = FANOUT4.tach;
*rpm = FANOUT4.tach;
return true;
default:
return false;
Expand Down
Loading