diff --git a/src/board/system76/addw2/board.c b/src/board/system76/addw2/board.c index 02c1358..5c3375d 100644 --- a/src/board/system76/addw2/board.c +++ b/src/board/system76/addw2/board.c @@ -27,7 +27,9 @@ void board_init(void) { void board_event(void) { if (main_cycle == 0) { - if (gpio_get(&ACIN_N)) { + bool acin = !gpio_get(&ACIN_N); + gpio_set(&AC_PRESENT, acin); + if (acin) { // Discharging (no AC adapter) gpio_set(&LED_BAT_CHG, false); gpio_set(&LED_BAT_FULL, false); @@ -45,7 +47,7 @@ void board_event(void) { if (power_state == POWER_STATE_S0 || power_state == POWER_STATE_S3 || power_state == POWER_STATE_DS3) { // System is on - } else if (gpio_get(&ACIN_N)) { + } else if (!acin) { // Power off VDD3 if system should be off gpio_set(&XLP_OUT, 0); } diff --git a/src/board/system76/addw2/gpio.c b/src/board/system76/addw2/gpio.c index 397998f..a76073a 100644 --- a/src/board/system76/addw2/gpio.c +++ b/src/board/system76/addw2/gpio.c @@ -94,12 +94,12 @@ void gpio_init() { // SMD_VGA_THERM GPCRC2 = GPIO_ALT; // KB-SO16 - GPCRC3 = 0x04; + GPCRC3 = GPIO_IN; // CNVI_DET#_EC GPCRC4 = GPIO_IN | GPIO_UP; // KB-SO17 - GPCRC5 = 0x04; - // PM_PWEROK + GPCRC5 = GPIO_IN; + // PM_PWROK GPCRC6 = GPIO_OUT; // LED_ACIN GPCRC7 = GPIO_OUT | GPIO_UP; diff --git a/src/board/system76/common/power.c b/src/board/system76/common/power.c index 316ba70..d286408 100644 --- a/src/board/system76/common/power.c +++ b/src/board/system76/common/power.c @@ -9,8 +9,14 @@ #include #include -// Platform does not currently support Deep Sx -#define DEEP_SX 0 +#ifndef DEEP_SX + // Platform does not currently support Deep Sx + #define DEEP_SX 0 +#endif + +#ifndef HAVE_EC_EN + #define HAVE_EC_EN 1 +#endif #ifndef HAVE_PCH_DPWROK_EC #define HAVE_PCH_DPWROK_EC 1 @@ -32,6 +38,10 @@ #define HAVE_SUS_PWR_ACK 1 #endif +#ifndef HAVE_VA_EC_EN + #define HAVE_VA_EC_EN 1 +#endif + extern uint8_t main_cycle; // VccRTC stable (55%) to RTCRST# high @@ -91,15 +101,13 @@ enum PowerState calculate_power_state(void) { return POWER_STATE_S5; } -#if DEEP_SX - if (gpio_get(&PCH_DPWROK_EC)) { - return POWER_STATE_DS5; +#if HAVE_PCH_DPWROK_EC && DEEP_SX + if (!gpio_get(&PCH_DPWROK_EC)) { + return POWER_STATE_DEFAULT; } +#endif // HAVE_PCH_DPWROK_EC && DEEP_SX - return POWER_STATE_DEFAULT; -#else return POWER_STATE_DS5; -#endif } void update_power_state(void) { @@ -179,9 +187,11 @@ void power_on_s5(void) { // TODO: Must have SL_SUS# set high by PCH +#if HAVE_VA_EC_EN // Enable VCCPRIM_* planes - must be enabled prior to USB power in order to // avoid leakage gpio_set(&VA_EC_EN, true); +#endif // HAVE_VA_EC_EN tPCH06; // Enable VDD5 @@ -196,8 +206,10 @@ void power_on_s5(void) { // Wait for PCH stability tPCH18; +#if HAVE_EC_EN // Allow processor to control SUSB# and SUSC# gpio_set(&EC_EN, true); +#endif // HAVE_EC_EN // Extra wait - TODO remove delay_ms(200); @@ -207,9 +219,11 @@ void power_on_s5(void) { // See Figure 12-25 in Whiskey Lake Platform Design Guide // TODO - rail timing graph +#if HAVE_VA_EC_EN // Enable VCCPRIM_* planes - must be enabled prior to USB power in order to // avoid leakage gpio_set(&VA_EC_EN, true); +#endif // HAVE_VA_EC_EN tPCH06; // Enable VDD5 @@ -232,8 +246,10 @@ void power_on_s5(void) { // Wait for PCH stability tPCH18; +#if HAVE_EC_EN // Allow processor to control SUSB# and SUSC# gpio_set(&EC_EN, true); +#endif // HAVE_EC_EN // Wait for SUSPWRDNACK validity tPLT01; @@ -259,8 +275,10 @@ void power_off_s5(void) { // De-assert PCH_PWROK gpio_set(&PM_PWROK, false); +#if HAVE_EC_EN // Block processor from controlling SUSB# and SUSC# gpio_set(&EC_EN, false); +#endif // HAVE_EC_EN // De-assert RSMRST# gpio_set(&EC_RSMRST_N, false); @@ -269,8 +287,10 @@ void power_off_s5(void) { gpio_set(&DD_ON, false); tPCH12; +#if HAVE_VA_EC_EN // Disable VCCPRIM_* planes gpio_set(&VA_EC_EN, false); +#endif // HAVE_VA_EC_EN #if HAVE_PCH_DPWROK_EC // De-assert DSW_PWROK @@ -361,9 +381,6 @@ void power_event(void) { // Update power state before determining actions update_power_state(); -#if DEEP_SX - //TODO -#else // DEEP_SX // If system power is good static bool pg_last = false; bool pg_new = gpio_get(&ALL_SYS_PWRGD); @@ -477,5 +494,4 @@ void power_event(void) { last_time = time; } } -#endif // DEEP_SX } diff --git a/src/board/system76/gaze15/acpi.c b/src/board/system76/gaze15/acpi.c new file mode 100644 index 0000000..06f5844 --- /dev/null +++ b/src/board/system76/gaze15/acpi.c @@ -0,0 +1,161 @@ +#include +#include +#include +#include +#include +#include +#include + +extern uint8_t sci_extra; + +uint8_t ecos = 0; + +static uint8_t fcmd = 0; +static uint8_t fdat = 0; +static uint8_t fbuf[4] = { 0, 0, 0, 0 }; + +void fcommand(void) { + switch (fcmd) { + // Keyboard backlight + case 0xCA: + switch (fdat) { + // Set LED color + case 0x03: + kbled_set_color( + ((uint32_t)fbuf[0]) | + ((uint32_t)fbuf[1] << 16) | + ((uint32_t)fbuf[2] << 8) + ); + break; + // Set LED brightness + case 0x06: + kbled_set(fbuf[0]); + break; + } + break; + } +} + +uint8_t acpi_read(uint8_t addr) { + uint8_t data = 0; + + #define ACPI_8(K, V) \ + case (K): \ + data = (uint8_t)(V); \ + break + + #define ACPI_16(K, V) \ + ACPI_8(K, V); \ + ACPI_8((K) + 1, (V) >> 8) + + #define ACPI_32(K, V) \ + ACPI_16(K, V); \ + ACPI_16((K) + 2, (V) >> 16) + + switch (addr) { + // Lid state and other flags + case 0x03: + if (gpio_get(&LID_SW_N)) { + // Lid is open + data |= 1 << 0; + } + if (lid_wake) { + data |= 1 << 2; + } + break; + + // Handle AC adapter and battery present + case 0x10: + if (!gpio_get(&ACIN_N)) { + // AC adapter connected + data |= 1 << 0; + } + // BAT0 always connected - TODO + data |= 1 << 2; + break; + + ACPI_16(0x16, battery_design_capacity); + ACPI_16(0x1A, battery_full_capacity); + ACPI_16(0x22, battery_design_voltage); + + case 0x26: + // If AC adapter connected + if (!gpio_get(&ACIN_N)) { + // And battery is not fully charged + if (!(battery_status & 0x0020)) { + // Battery is charging + data |= 1 << 1; + } + } + break; + + ACPI_16(0x2A, battery_current); + ACPI_16(0x2E, battery_remaining_capacity); + ACPI_16(0x32, battery_voltage); + + ACPI_8(0x68, ecos); + + ACPI_8(0xCC, sci_extra); + + // Airplane mode LED + case 0xD9: + if (!gpio_get(&LED_AIRPLANE_N)) { + data |= (1 << 6); + } + break; + + // Set size of flash (from old firmware) + ACPI_8 (0xE5, 0x80); + + ACPI_8 (0xF8, fcmd); + ACPI_8 (0xF9, fdat); + ACPI_8 (0xFA, fbuf[0]); + ACPI_8 (0xFB, fbuf[1]); + ACPI_8 (0xFC, fbuf[2]); + ACPI_8 (0xFD, fbuf[3]); + } + + DEBUG("acpi_read %02X = %02X\n", addr, data); + return data; +} + + +void acpi_write(uint8_t addr, uint8_t data) { + DEBUG("acpi_write %02X = %02X\n", addr, data); + + switch (addr) { + // Lid state and other flags + case 0x03: + lid_wake = (bool)(data & (1 << 2)); + break; + + case 0x68: + ecos = data; + break; + + // Airplane mode LED + case 0xD9: + gpio_set(&LED_AIRPLANE_N, !(bool)(data & (1 << 6))); + break; + + case 0xF8: + fcmd = data; + fcommand(); + break; + case 0xF9: + fdat = data; + break; + case 0xFA: + fbuf[0] = data; + break; + case 0xFB: + fbuf[1] = data; + break; + case 0xFC: + fbuf[2] = data; + break; + case 0xFD: + fbuf[3] = data; + break; + } +} diff --git a/src/board/system76/gaze15/board.c b/src/board/system76/gaze15/board.c new file mode 100644 index 0000000..35c3e08 --- /dev/null +++ b/src/board/system76/gaze15/board.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +extern uint8_t main_cycle; + +void board_init(void) { + // Allow backlight to be turned on + gpio_set(&BKL_EN, true); + // Enable camera + gpio_set(&CCD_EN, true); + // Enable wireless + gpio_set(&BT_EN, true); + gpio_set(&WLAN_EN, true); + gpio_set(&WLAN_PWR_EN, true); + // Assert SMI#, SCI#, and SWI# + gpio_set(&SCI_N, true); + gpio_set(&SMI_N, true); + gpio_set(&SWI_N, true); + + dgpu_init(); +} + +void board_event(void) { + if (main_cycle == 0) { + bool acin = !gpio_get(&ACIN_N); + gpio_set(&AC_PRESENT, acin); + if (acin) { + // Discharging (no AC adapter) + gpio_set(&LED_BAT_CHG, false); + gpio_set(&LED_BAT_FULL, false); + } else if (battery_status & 0x0020) { + // Fully charged + // TODO: turn off charger + gpio_set(&LED_BAT_CHG, false); + gpio_set(&LED_BAT_FULL, true); + } else { + // Charging + // TODO: detect no battery connected + gpio_set(&LED_BAT_CHG, true); + gpio_set(&LED_BAT_FULL, false); + } + + if (power_state == POWER_STATE_S0 || power_state == POWER_STATE_S3 || power_state == POWER_STATE_DS3) { + // System is on + } else if (!acin) { + // Power off VDD3 if system should be off + gpio_set(&XLP_OUT, 0); + } + + static uint32_t last_time = 0; + uint32_t time = time_get(); + // Only run the following once a second + if (last_time > time || (time - last_time) >= 1000) { + last_time = time; + + // Updates discrete GPU fan status and temps + dgpu_event(); + } + } +} diff --git a/src/board/system76/gaze15/board.mk b/src/board/system76/gaze15/board.mk new file mode 100644 index 0000000..d92fc57 --- /dev/null +++ b/src/board/system76/gaze15/board.mk @@ -0,0 +1,38 @@ +EC=it5570e + +# Add keymap to src +KEYMAP?=default +SRC+=$(BOARD_DIR)/keymap/$(KEYMAP).c + +# Set log level +# 0 - NONE +# 1 - ERROR +# 2 - WARN +# 3 - INFO +# 4 - DEBUG +# 5 - TRACE +CFLAGS+=-DLEVEL=4 + +# Enable I2C debug on 0x76 +#CFLAGS+=-DI2C_DEBUGGER=0x76 + +# Set discrete GPU I2C bus +CFLAGS+=-DI2C_DGPU=I2C_1 + +# Set battery I2C bus +CFLAGS+=-DI2C_SMBUS=I2C_4 + +# Set touchpad PS2 bus +CFLAGS+=-DPS2_TOUCHPAD=PS2_3 + +# Set smart charger parameters +CFLAGS+=\ + -DCHARGER_CHARGE_CURRENT=1536 \ + -DCHARGER_CHARGE_VOLTAGE=16800 \ + -DCHARGER_INPUT_CURRENT=9230 + +# Enable debug logging over keyboard parallel port +#CFLAGS+=-DPARPORT_DEBUG + +# Add system76 common code +include src/board/system76/common/common.mk diff --git a/src/board/system76/gaze15/dgpu.c b/src/board/system76/gaze15/dgpu.c new file mode 100644 index 0000000..bc033a7 --- /dev/null +++ b/src/board/system76/gaze15/dgpu.c @@ -0,0 +1,144 @@ +#include +#include + +#include +#include +#include +#include +#include +#include + +// Fan speed is the lowest requested over HEATUP seconds +#define HEATUP 10 + +// Fan speed is the highest HEATUP speed over COOLDOWN seconds +#define COOLDOWN 10 + +// Interpolate duty cycle +#define INTERPOLATE 0 + +int16_t dgpu_temp = 0; +uint8_t dgpu_duty = 0; + +#define DGPU_TEMP(X) ((int16_t)(X)) +#define PWM_DUTY(X) ((uint8_t)(((((uint16_t)(X)) * 255) + 99) / 100)) + +struct FanPoint { + int16_t temp; + uint8_t duty; +}; + +#define FAN_POINT(T, D) { .temp = DGPU_TEMP(T), .duty = PWM_DUTY(D) } + +// Fan curve with temperature in degrees C, duty cycle in percent +static struct FanPoint __code FAN_POINTS[] = { + FAN_POINT(70, 40), + FAN_POINT(75, 50), + FAN_POINT(80, 60), + FAN_POINT(85, 65), + FAN_POINT(90, 65) +}; + +// Get duty cycle based on temperature, adapted from +// https://github.com/pop-os/system76-power/blob/master/src/fan.rs +static uint8_t fan_duty(int16_t temp) { + for (int i = 0; i < ARRAY_SIZE(FAN_POINTS); i++) { + const struct FanPoint * cur = &FAN_POINTS[i]; + + // If exactly the current temp, return the current duty + if (temp == cur->temp) { + return cur->duty; + } else if (temp < cur->temp) { + // If lower than first temp, return 0% + if (i == 0) { + return PWM_DUTY(0); + } else { + const struct FanPoint * prev = &FAN_POINTS[i - 1]; + +#if INTERPOLATE + // If in between current temp and previous temp, interpolate + if (temp > prev->temp) { + int16_t dtemp = (cur->temp - prev->temp); + int16_t dduty = ((int16_t)cur->duty) - ((int16_t)prev->duty); + return (uint8_t)( + ((int16_t)prev->duty) + + ((temp - prev->temp) * dduty) / dtemp + ); + } +#else // INTERPOLATE + return prev->duty; +#endif // INTERPOLATE + } + } + } + + // If no point is found, return 100% + return PWM_DUTY(100); +} + +static uint8_t fan_heatup(uint8_t duty) { + static uint8_t history[HEATUP] = { 0 }; + uint8_t lowest = duty; + + int i; + for (i = 0; (i + 1) < ARRAY_SIZE(history); i++) { + uint8_t value = history[i + 1]; + if (value < lowest) { + lowest = value; + } + history[i] = value; + } + history[i] = duty; + + return lowest; +} + +static uint8_t fan_cooldown(uint8_t duty) { + static uint8_t history[COOLDOWN] = { 0 }; + uint8_t highest = duty; + + int i; + for (i = 0; (i + 1) < ARRAY_SIZE(history); i++) { + uint8_t value = history[i + 1]; + if (value > highest) { + highest = value; + } + history[i] = value; + } + history[i] = duty; + + return highest; +} + +void dgpu_init(void) { + // Set up for i2c usage + i2c_reset(&I2C_DGPU, true); +} + +void dgpu_event(void) { + if (power_state == POWER_STATE_S0 && gpio_get(&DGPU_PWR_EN)) { + // Use I2CS if in S0 state + int8_t rlts; + int res = i2c_get(&I2C_DGPU, 0x4F, 0x00, &rlts, 1); + if (res == 1) { + dgpu_temp = (int16_t)rlts; + dgpu_duty = fan_duty(dgpu_temp); + } else { + DEBUG("DGPU temp error: %d\n", res); + // Default to 50% if there is an error + dgpu_temp = 0; + dgpu_duty = PWM_DUTY(50); + } + } else { + // Turn fan off if not in S0 state or GPU power not on + dgpu_temp = 0; + dgpu_duty = PWM_DUTY(0); + } + + uint8_t heatup_duty = fan_heatup(dgpu_duty); + uint8_t cooldown_duty = fan_cooldown(heatup_duty); + if (cooldown_duty != DCR4) { + DCR4 = cooldown_duty; + DEBUG("DGPU temp=%d = %d\n", dgpu_temp, cooldown_duty); + } +} diff --git a/src/board/system76/gaze15/gpio.c b/src/board/system76/gaze15/gpio.c new file mode 100644 index 0000000..e1e9e4c --- /dev/null +++ b/src/board/system76/gaze15/gpio.c @@ -0,0 +1,267 @@ +#include +#include + +struct Gpio __code ACIN_N = GPIO(B, 0); +struct Gpio __code AC_PRESENT = GPIO(E, 1); +struct Gpio __code ALL_SYS_PWRGD = GPIO(C, 0); +struct Gpio __code BKL_EN = GPIO(H, 2); +struct Gpio __code BT_EN = GPIO(F, 3); +struct Gpio __code BUF_PLT_RST_N = GPIO(D, 2); +struct Gpio __code CCD_EN = GPIO(D, 1); +struct Gpio __code DD_ON = GPIO(E, 4); +struct Gpio __code DGPU_PWR_EN = GPIO(J, 2); +struct Gpio __code EC_RSMRST_N = GPIO(E, 5); +struct Gpio __code LED_ACIN = GPIO(C, 7); +struct Gpio __code LED_AIRPLANE_N = GPIO(H, 7); +struct Gpio __code LED_BAT_CHG = GPIO(H, 5); +struct Gpio __code LED_BAT_FULL = GPIO(J, 0); +struct Gpio __code LED_PWR = GPIO(D, 0); +struct Gpio __code LID_SW_N = GPIO(B, 1); +struct Gpio __code PM_PWROK = GPIO(C, 6); +struct Gpio __code PWR_BTN_N = GPIO(D, 5); +struct Gpio __code PWR_SW_N = GPIO(B, 3); +struct Gpio __code SCI_N = GPIO(D, 3); +struct Gpio __code SMI_N = GPIO(D, 4); +struct Gpio __code SUSB_N_PCH = GPIO(H, 6); +struct Gpio __code SUSC_N_PCH = GPIO(H, 1); +struct Gpio __code SUSWARN_N = GPIO(H, 0); +struct Gpio __code SUS_PWR_ACK = GPIO(F, 7); +struct Gpio __code SWI_N = GPIO(B, 5); +struct Gpio __code VA_EC_EN = GPIO(J, 4); // Mistakenly labelled SLP_SUS# +struct Gpio __code WLAN_EN = GPIO(G, 1); +struct Gpio __code WLAN_PWR_EN = GPIO(A, 3); +struct Gpio __code XLP_OUT = GPIO(B, 4); + +void gpio_init() { + // Enable LPC reset on GPD2 + GCR = 0x04; + // Enable SMBus channel 4 + GCR15 = (1 << 4); + // Set GPF2 and GPF3 to 3.3V + GCR20 = 0; + + // Set GPIO data + GPDRA = 0x00; + GPDRB = 0x58; + GPDRC = 0x00; + GPDRD = 0x38; + GPDRE = 0x00; + GPDRF = 0x40; + GPDRG = 0x00; + GPDRH = 0x80; + GPDRI = 0x00; + GPDRJ = 0x00; + + // Set GPIO control + // EC_PWM_PIN_24 + GPCRA0 = GPIO_ALT; + // KBC_BEEP + GPCRA1 = GPIO_ALT; + // CPU_FAN + GPCRA2 = GPIO_ALT; + // WLAN_PWR_EN + GPCRA3 = GPIO_OUT | GPIO_UP; + // VGA_FAN + GPCRA4 = GPIO_ALT; + // EC_PWM_LEDKB_R + GPCRA5 = GPIO_ALT; + // EC_PWM_LEDKB_G + GPCRA6 = GPIO_ALT; + // EC_PWM_LEDKB_B + GPCRA7 = GPIO_ALT; + // AC_IN# + GPCRB0 = GPIO_IN | GPIO_UP; + // LID_SW# + GPCRB1 = GPIO_IN | GPIO_UP; + // LAN_WAKEUP# + GPCRB2 = GPIO_IN | GPIO_UP; + // PWR_SW# + GPCRB3 = GPIO_IN; + // XLP_OUT + GPCRB4 = GPIO_OUT; + // SWI# + GPCRB5 = GPIO_OUT | GPIO_UP; + // H_PROCHOT_EC + GPCRB6 = GPIO_OUT | GPIO_UP; + // + GPCRB7 = GPIO_IN; + // ALL_SYS_PWRGD + GPCRC0 = GPIO_IN; + // SMC_VGA_THERM + GPCRC1 = GPIO_ALT; + // SMD_VGA_THERM + GPCRC2 = GPIO_ALT; + // KB-SO16 + GPCRC3 = GPIO_IN; + // CNVI_DET#_EC + GPCRC4 = GPIO_IN | GPIO_UP; + // KB-SO17 + GPCRC5 = GPIO_IN; + // PM_PWROK + GPCRC6 = GPIO_OUT; + // LED_ACIN + GPCRC7 = GPIO_OUT | GPIO_UP; + // LED_PWR + GPCRD0 = GPIO_OUT | GPIO_UP; + // CCD_EN + GPCRD1 = GPIO_OUT | GPIO_UP; + // BUF_PLT_RST# + GPCRD2 = GPIO_ALT; + // SCI# + GPCRD3 = GPIO_IN; + // SMI# + GPCRD4 = GPIO_IN; + // PWR_BTN# + GPCRD5 = GPIO_OUT | GPIO_UP; + // CPU_FANSEN + GPCRD6 = GPIO_ALT; + // VGA_FANSEN + GPCRD7 = GPIO_ALT; + // SMC_BAT + GPCRE0 = GPIO_ALT; + // AC_PRESENT + GPCRE1 = GPIO_OUT | GPIO_UP; + // RGBKB-DET# + GPCRE2 = GPIO_IN | GPIO_UP; + // NC + GPCRE3 = GPIO_IN; + // DD_ON + GPCRE4 = GPIO_OUT | GPIO_DOWN; + // EC_RSMRST# + GPCRE5 = GPIO_OUT; + // SB_KBCRST# + GPCRE6 = GPIO_IN; + // SMD_BAT + GPCRE7 = GPIO_ALT; + // 80CLK + GPCRF0 = GPIO_IN; + // USB_CHARGE_EN + GPCRF1 = GPIO_OUT | GPIO_UP; + // 3IN1 + GPCRF2 = GPIO_IN | GPIO_UP; + // BT_EN + GPCRF3 = GPIO_OUT | GPIO_UP; + // TP_CLK + GPCRF4 = GPIO_ALT; + // TP_DATA + GPCRF5 = GPIO_ALT; + // EC_PECI + GPCRF6 = GPIO_ALT; + // SUS_PWR_ACK# + GPCRF7 = GPIO_IN; + // dGPU_GPIO8_OVERT + GPCRG0 = GPIO_IN | GPIO_UP; + // WLAN_EN + GPCRG1 = GPIO_OUT | GPIO_UP; + // AUTO_LOAD_PWR + GPCRG2 = GPIO_OUT; + // ALSPI_CE# + GPCRG3 = GPIO_ALT; + // ALSPI_MSI + GPCRG4 = GPIO_ALT; + // ALSPI_MSO + GPCRG5 = GPIO_ALT; + // H_PROCHOT#_EC + GPCRG6 = GPIO_OUT | GPIO_UP; + // ALSPI_SCLK + GPCRG7 = GPIO_ALT; + // SUS_WARN# + GPCRH0 = GPIO_IN; + // SUSC# + GPCRH1 = GPIO_IN; + // BKL_EN + GPCRH2 = GPIO_OUT | GPIO_UP; + // LIGHT_KB_DET# + GPCRH3 = GPIO_IN; + // d_GPIO9_ALERT_FAN + GPCRH4 = GPIO_IN | GPIO_UP; + // LED_BAT_CHG + GPCRH5 = GPIO_OUT | GPIO_UP; + // SUSB# + GPCRH6 = GPIO_IN; + // AIRPLAN_LED# + GPCRH7 = GPIO_OUT | GPIO_UP; + // BAT_DET + GPCRI0 = GPIO_ALT; + // BAT_VOLT + GPCRI1 = GPIO_ALT; + // ME_WE + GPCRI2 = GPIO_OUT; + // THERM_VOLT + GPCRI3 = GPIO_ALT; + // TOTAL_CUR + GPCRI4 = GPIO_ALT; + // PERKB_ID#_R + GPCRI5 = GPIO_IN; + // PERKB_ID2#_R + GPCRI6 = GPIO_IN; + // MODEL_ID + GPCRI7 = GPIO_IN; + // LED_BAT_FULL + GPCRJ0 = GPIO_OUT | GPIO_UP; + // KBC_MUTE# + GPCRJ1 = GPIO_IN; + // DGPU_PWR_EN + GPCRJ2 = GPIO_IN; + // GC6_FB_EN_PCH + GPCRJ3 = GPIO_IN; + // SLP_SUS# + GPCRJ4 = GPIO_OUT; + // VBATT_BOOST# + GPCRJ5 = GPIO_OUT; + // EC_GPIO + GPCRJ6 = GPIO_OUT; + // PERKB-DET#_R + GPCRJ7 = GPIO_IN | GPIO_UP; + // LPC_AD0 + GPCRM0 = GPIO_ALT; + // LPC_AD1 + GPCRM1 = GPIO_ALT; + // LPC_AD2 + GPCRM2 = GPIO_ALT; + // LPC_AD3 + GPCRM3 = GPIO_ALT; + // PCLK_KBC + GPCRM4 = GPIO_ALT; + // LPC_FRAME# + GPCRM5 = GPIO_ALT; + // SERIRQ + GPCRM6 = GPIO_ALT; +} + +#if GPIO_DEBUG +void gpio_debug_bank( + char * bank, + uint8_t data, + uint8_t mirror, + uint8_t pot, + volatile uint8_t * control +) { + for(char i = 0; i < 8; i++) { + DEBUG( + "%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n", + bank, + i, + (data >> i) & 1, + (mirror >> i) & 1, + (pot >> i) & 1, + *(control + i) + ); + } +} + +void gpio_debug(void) { + #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) + bank(A); + bank(B); + bank(C); + bank(D); + bank(E); + bank(F); + bank(G); + bank(H); + bank(I); + bank(J); + #undef bank +} +#endif diff --git a/src/board/system76/gaze15/include/board/dgpu.h b/src/board/system76/gaze15/include/board/dgpu.h new file mode 100644 index 0000000..ffe4f3a --- /dev/null +++ b/src/board/system76/gaze15/include/board/dgpu.h @@ -0,0 +1,7 @@ +#ifndef _BOARD_DGPU_H +#define _BOARD_DGPU_H + +void dgpu_init(void); +void dgpu_event(void); + +#endif // _BOARD_DGPU_H diff --git a/src/board/system76/gaze15/include/board/gpio.h b/src/board/system76/gaze15/include/board/gpio.h new file mode 100644 index 0000000..cf568aa --- /dev/null +++ b/src/board/system76/gaze15/include/board/gpio.h @@ -0,0 +1,50 @@ +#ifndef _BOARD_GPIO_H +#define _BOARD_GPIO_H + +#include + +#define GPIO_ALT 0x00 +#define GPIO_IN 0x80 +#define GPIO_OUT 0x40 +#define GPIO_UP 0x04 +#define GPIO_DOWN 0x02 + +void gpio_init(void); +void gpio_debug(void); + +extern struct Gpio __code ACIN_N; +extern struct Gpio __code AC_PRESENT; +extern struct Gpio __code ALL_SYS_PWRGD; +extern struct Gpio __code BKL_EN; +extern struct Gpio __code BT_EN; +extern struct Gpio __code BUF_PLT_RST_N; +extern struct Gpio __code CCD_EN; +extern struct Gpio __code DD_ON; +extern struct Gpio __code DGPU_PWR_EN; +#define HAVE_EC_EN 0 +extern struct Gpio __code EC_RSMRST_N; +extern struct Gpio __code LED_ACIN; +extern struct Gpio __code LED_AIRPLANE_N; +extern struct Gpio __code LED_BAT_CHG; +extern struct Gpio __code LED_BAT_FULL; +extern struct Gpio __code LED_PWR; +extern struct Gpio __code LID_SW_N; +#define HAVE_PCH_DPWROK_EC 0 +#define HAVE_PCH_PWROK_EC 0 +extern struct Gpio __code PM_PWROK; +extern struct Gpio __code PWR_BTN_N; +extern struct Gpio __code PWR_SW_N; +extern struct Gpio __code SCI_N; +#define HAVE_SLP_SUS_N 0 +extern struct Gpio __code SMI_N; +extern struct Gpio __code SUSB_N_PCH; +extern struct Gpio __code SUSC_N_PCH; +extern struct Gpio __code SUSWARN_N; +extern struct Gpio __code SUS_PWR_ACK; +extern struct Gpio __code SWI_N; +extern struct Gpio __code VA_EC_EN; +extern struct Gpio __code WLAN_EN; +extern struct Gpio __code WLAN_PWR_EN; +extern struct Gpio __code XLP_OUT; + +#endif // _BOARD_GPIO_H diff --git a/src/board/system76/gaze15/include/board/kbled.h b/src/board/system76/gaze15/include/board/kbled.h new file mode 100644 index 0000000..895542c --- /dev/null +++ b/src/board/system76/gaze15/include/board/kbled.h @@ -0,0 +1,12 @@ +#ifndef _BOARD_KBLED_H +#define _BOARD_KBLED_H + +#include + +void kbled_init(void); +void kbled_reset(void); +uint8_t kbled_get(void); +void kbled_set(uint8_t level); +void kbled_set_color(uint32_t color); + +#endif // _BOARD_KBLED_H diff --git a/src/board/system76/gaze15/include/board/keymap.h b/src/board/system76/gaze15/include/board/keymap.h new file mode 100644 index 0000000..eacd404 --- /dev/null +++ b/src/board/system76/gaze15/include/board/keymap.h @@ -0,0 +1,50 @@ +#ifndef _BOARD_KEYMAP_H +#define _BOARD_KEYMAP_H + +#include + +#define ___ 0 + +// Conversion of physical layout to keyboard matrix +#define LAYOUT( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, K0F, K0G, K0H, K0I, K0J, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, K1F, K1G, K1H, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, K2F, K2G, K2H, \ + K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, K3F, \ + K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B, K4C, K4D, K4E, K4F, K4G, \ + K50, K51, K52, K53, K54, K55, K56, K57, K58, K59, K5A, K5B, K5C \ +) { \ + { ___, ___, ___, ___, ___, ___, K50, K57 }, \ + { ___, ___, ___, ___, ___, ___, K53, K55 }, \ + { ___, ___, ___, ___, ___, ___, K40, K4B }, \ + { K52, ___, ___, ___, ___, ___, ___, K54 }, \ + { K41, K1H, ___, K2F, K4E, ___, ___, ___ }, \ + { K0I, K22, ___, ___, K1E, K3D, K3F, K30 }, \ + { K0J, K1B, K23, K39, ___, ___, K47, ___ }, \ + { K38, K26, K1A, K24, ___, K3A, K20, K00 }, \ + { K5B, K37, K2C, K19, K25, K07, K18, K01 }, \ + { K5C, K34, K36, K02, ___, K4G, K3B, K45 }, \ + { K1F, K48, ___, K2B, K32, K08, K06, K12 }, \ + { K1G, K49, K17, K33, ___, ___, K11, K2A }, \ + { K2D, ___, K31, K4A, ___, K03, K28, K16 }, \ + { ___, K44, K0D, K09, K46, K29, K15, K05 }, \ + { K21, K0A, K2E, K04, K3E, K0E, K0F, K14 }, \ + { K56, K42, K3C, K2H, K27, K2G, K13, K1D }, \ + { K0H, K0G, K43, K4C, K59, K10, K0B, K0C }, \ + { K35, K1C, K4F, K51, K4D, K58, K5A, ___ } \ +} + +// Keymap output pins +#define KM_OUT 18 +// Keymap input pins +#define KM_IN 8 +// Keymap layers (normal, Fn) +#define KM_LAY 2 + +// Keymap +extern uint16_t __code KEYMAP[KM_LAY][KM_OUT][KM_IN]; + +// Get a keycode from the keymap +uint16_t keymap(int output, int input, int layer); + +#endif // _BOARD_KEYMAP_H diff --git a/src/board/system76/gaze15/kbled.c b/src/board/system76/gaze15/kbled.c new file mode 100644 index 0000000..abacb2a --- /dev/null +++ b/src/board/system76/gaze15/kbled.c @@ -0,0 +1,34 @@ +#include +#include + +void kbled_init(void) { + //TODO: enable PWMs + kbled_reset(); +} + +void kbled_reset(void) { + // Set brightness and color + kbled_set_color(0xFFFFFF); + kbled_set(0x00); +} + +uint8_t kbled_get(void) { + // Get PWM for power + return DCR0; +} + +void kbled_set(uint8_t level) { + // Set PWM for power + DCR0 = level; +} + +void kbled_set_color(uint32_t color) { + // Set PWM for blue component + DCR7 = (uint8_t)(color); + + // Set PWM for green component + DCR6 = (uint8_t)(color >> 8); + + // Set PWM for red component + DCR5 = (uint8_t)(color >> 16); +} diff --git a/src/board/system76/gaze15/keymap/default.c b/src/board/system76/gaze15/keymap/default.c new file mode 100644 index 0000000..65d46ce --- /dev/null +++ b/src/board/system76/gaze15/keymap/default.c @@ -0,0 +1,22 @@ +// Default layout + +#include + +uint16_t __code KEYMAP[KM_LAY][KM_OUT][KM_IN] = { +LAYOUT( + K_ESC, K_F1, K_F2, K_F3, K_F4, K_F5, K_F6, K_F7, K_F8, K_F9, K_F10, K_F11, K_F12, K_PRINT_SCREEN, K_INSERT, K_DEL, K_HOME, K_END, K_PGUP, K_PGDN, + K_TICK, K_1, K_2, K_3, K_4, K_5, K_6, K_7, K_8, K_9, K_0, K_MINUS, K_EQUALS, K_BKSP, K_NUM_LOCK, K_NUM_SLASH, K_NUM_ASTERISK, K_NUM_MINUS, + K_TAB, K_Q, K_W, K_E, K_R, K_T, K_Y, K_U, K_I, K_O, K_P, K_BRACE_OPEN, K_BRACE_CLOSE, K_BACKSLASH, K_NUM_7, K_NUM_8, K_NUM_9, K_NUM_PLUS, + K_CAPS, K_A, K_S, K_D, K_F, K_G, K_H, K_J, K_K, K_L, K_SEMICOLON, K_QUOTE, K_ENTER, K_NUM_4, K_NUM_5, K_NUM_6, + K_LEFT_SHIFT, K_Z, K_X, K_C, K_V, K_B, K_N, K_M, K_COMMA, K_PERIOD, K_SLASH, K_RIGHT_SHIFT, K_UP, K_NUM_1, K_NUM_2, K_NUM_3, K_NUM_ENTER, + K_LEFT_CTRL, KT_FN, K_LEFT_SUPER, K_LEFT_ALT, K_SPACE, K_RIGHT_ALT, K_APP, K_RIGHT_CTRL, K_LEFT, K_DOWN, K_RIGHT, K_NUM_0, K_NUM_PERIOD +), +LAYOUT( + K_ESC, K_TOUCHPAD, KT_SCI | SCI_DISPLAY_TOGGLE, K_MUTE, K_F4, K_VOLUME_DOWN, K_VOLUME_UP, K_DISPLAY_MODE, KT_SCI | SCI_BRIGHTNESS_DOWN, KT_SCI | SCI_BRIGHTNESS_UP, KT_SCI | SCI_CAMERA_TOGGLE, KT_SCI | SCI_AIRPLANE_MODE, KT_SCI | SCI_SUSPEND, K_PRINT_SCREEN, K_INSERT, K_DEL, K_HOME, K_END, K_PGUP, K_PGDN, + K_PLAY_PAUSE, K_1, K_2, K_3, K_4, K_5, K_6, K_7, K_8, K_9, K_0, K_MINUS, K_EQUALS, K_BKSP, K_NUM_LOCK, KT_SCI_EXTRA | SCI_EXTRA_KBD_COLOR, KT_SCI_EXTRA | SCI_EXTRA_KBD_TOGGLE, KT_SCI_EXTRA | SCI_EXTRA_KBD_DOWN, + K_TAB, K_Q, K_W, K_E, K_R, K_T, K_Y, K_U, K_I, K_O, K_P, K_BRACE_OPEN, K_BRACE_CLOSE, K_BACKSLASH, K_NUM_7, K_NUM_8, K_NUM_9, KT_SCI_EXTRA | SCI_EXTRA_KBD_UP, + K_CAPS, K_A, K_S, K_D, K_F, K_G, K_H, K_J, K_K, K_L, K_SEMICOLON, K_QUOTE, K_ENTER, K_NUM_4, K_NUM_5, K_NUM_6, + K_LEFT_SHIFT, K_Z, K_X, K_C, K_V, K_B, K_N, K_M, K_COMMA, K_PERIOD, K_SLASH, K_RIGHT_SHIFT, K_UP, K_NUM_1, K_NUM_2, K_NUM_3, K_NUM_ENTER, + K_LEFT_CTRL, KT_FN, K_LEFT_SUPER, K_LEFT_ALT, K_SPACE, K_RIGHT_ALT, K_APP, K_RIGHT_CTRL, K_LEFT, K_DOWN, K_RIGHT, K_NUM_0, K_NUM_PERIOD +) +}; diff --git a/src/board/system76/gaze15/keymap/jeremy.c b/src/board/system76/gaze15/keymap/jeremy.c new file mode 100644 index 0000000..2d19a63 --- /dev/null +++ b/src/board/system76/gaze15/keymap/jeremy.c @@ -0,0 +1,22 @@ +// Default layout + +#include + +uint16_t __code KEYMAP[KM_LAY][KM_OUT][KM_IN] = { +LAYOUT( + K_ESC, K_F1, K_F2, K_F3, K_F4, K_F5, K_F6, K_F7, K_F8, K_F9, K_F10, K_F11, K_F12, K_PRINT_SCREEN, K_INSERT, K_DEL, K_HOME, K_END, K_PGUP, K_PGDN, + K_TICK, K_1, K_2, K_3, K_4, K_5, K_6, K_7, K_8, K_9, K_0, K_MINUS, K_EQUALS, K_BKSP, K_NUM_LOCK, K_NUM_SLASH, K_NUM_ASTERISK, K_NUM_MINUS, + K_TAB, K_Q, K_W, K_E, K_R, K_T, K_Y, K_U, K_I, K_O, K_P, K_BRACE_OPEN, K_BRACE_CLOSE, K_BACKSLASH, K_NUM_7, K_NUM_8, K_NUM_9, K_NUM_PLUS, + KT_FN, K_A, K_S, K_D, K_F, K_G, K_H, K_J, K_K, K_L, K_SEMICOLON, K_QUOTE, K_ENTER, K_NUM_4, K_NUM_5, K_NUM_6, + K_LEFT_SHIFT, K_Z, K_X, K_C, K_V, K_B, K_N, K_M, K_COMMA, K_PERIOD, K_SLASH, K_RIGHT_SHIFT, K_UP, K_NUM_1, K_NUM_2, K_NUM_3, K_NUM_ENTER, + K_LEFT_CTRL, KT_FN, K_LEFT_ALT, K_LEFT_SUPER, K_SPACE, KT_FN, K_RIGHT_ALT, K_RIGHT_CTRL, K_LEFT, K_DOWN, K_RIGHT, K_NUM_0, K_NUM_PERIOD +), +LAYOUT( + K_ESC, K_TOUCHPAD, KT_SCI | SCI_DISPLAY_TOGGLE, K_MUTE, K_F4, K_VOLUME_DOWN, K_VOLUME_UP, K_DISPLAY_MODE, KT_SCI | SCI_BRIGHTNESS_DOWN, KT_SCI | SCI_BRIGHTNESS_UP, KT_SCI | SCI_CAMERA_TOGGLE, KT_SCI | SCI_AIRPLANE_MODE, KT_SCI | SCI_SUSPEND, K_PRINT_SCREEN, K_INSERT, K_DEL, K_HOME, K_END, K_PGUP, K_PGDN, + K_PLAY_PAUSE, K_1, K_2, K_3, K_4, K_5, K_6, K_7, K_8, K_9, K_0, K_MINUS, K_EQUALS, K_DEL, K_NUM_LOCK, KT_SCI_EXTRA | SCI_EXTRA_KBD_COLOR, KT_SCI_EXTRA | SCI_EXTRA_KBD_TOGGLE, KT_SCI_EXTRA | SCI_EXTRA_KBD_DOWN, + K_TAB, K_Q, K_W, K_E, K_R, K_T, K_Y, K_PGUP, K_HOME, K_PGDN, K_P, K_BRACE_OPEN, K_BRACE_CLOSE, K_BACKSLASH, K_NUM_7, K_NUM_8, K_NUM_9, KT_SCI_EXTRA | SCI_EXTRA_KBD_UP, + KT_FN, K_A, K_S, K_D, K_F, K_G, K_LEFT, K_DOWN, K_UP, K_RIGHT, K_BKSP, K_DEL, K_ENTER, K_NUM_4, K_NUM_5, K_NUM_6, + K_LEFT_SHIFT, K_Z, K_X, K_C, K_V, K_B, K_END, K_M, K_COMMA, K_PERIOD, K_SLASH, K_RIGHT_SHIFT, K_UP, K_NUM_1, K_NUM_2, K_NUM_3, K_NUM_ENTER, + K_LEFT_CTRL, KT_FN, K_LEFT_ALT, K_LEFT_SUPER, K_ESC, KT_FN, K_RIGHT_ALT, K_RIGHT_CTRL, K_LEFT, K_DOWN, K_RIGHT, K_NUM_0, K_NUM_PERIOD +) +}; diff --git a/src/board/system76/gaze15/scratch.c b/src/board/system76/gaze15/scratch.c new file mode 100644 index 0000000..225d2ff --- /dev/null +++ b/src/board/system76/gaze15/scratch.c @@ -0,0 +1,40 @@ +#include <8051.h> +#include + +#include +#include +#include + +// Include scratch ROM +uint8_t __code __at(SCRATCH_OFFSET) scratch_rom[] = { + #include +}; + +// SCAR0 is stored in processor cache, not in xram +volatile uint8_t __xdata __at(0x1040) SCAR0L; +volatile uint8_t __xdata __at(0x1041) SCAR0M; +volatile uint8_t __xdata __at(0x1042) SCAR0H; + +// Enter or exit scratch ROM +void scratch_trampoline(void) { + // Set fans to 100% + DCR2 = 0xFF; + DCR4 = 0xFF; + + //TODO: Clear keyboard presses + + // Start watchdog timer + smfi_watchdog(); + + // Disable interrupts + EA = 0; + + // Use DMA mapping to copy flash data + SCAR0H = 0x80; + SCAR0L = (uint8_t)(SCRATCH_OFFSET); + SCAR0M = (uint8_t)(SCRATCH_OFFSET >> 8); + SCAR0H = 0; + + // Jump to scratch reset function + __asm__("ljmp " xstr(SCRATCH_OFFSET)); +} diff --git a/src/board/system76/oryp6/acpi.c b/src/board/system76/oryp6/acpi.c new file mode 100644 index 0000000..a79ee1f --- /dev/null +++ b/src/board/system76/oryp6/acpi.c @@ -0,0 +1,149 @@ +#include +#include +#include +#include +#include +#include +#include + +extern uint8_t sci_extra; + +uint8_t ecos = 0; + +static uint8_t fcmd = 0; +static uint8_t fdat = 0; +static uint8_t fbuf[4] = { 0, 0, 0, 0 }; + +void fcommand(void) { + switch (fcmd) { + // Keyboard backlight + case 0xCA: + switch (fdat) { + // Set LED color + case 0x03: + kbled_set_color( + ((uint32_t)fbuf[0]) | + ((uint32_t)fbuf[1] << 16) | + ((uint32_t)fbuf[2] << 8) + ); + break; + // Set LED brightness + case 0x06: + kbled_set(fbuf[0]); + break; + } + break; + } +} + +uint8_t acpi_read(uint8_t addr) { + uint8_t data = 0; + + #define ACPI_8(K, V) \ + case (K): \ + data = (uint8_t)(V); \ + break + + #define ACPI_16(K, V) \ + ACPI_8(K, V); \ + ACPI_8((K) + 1, (V) >> 8) + + #define ACPI_32(K, V) \ + ACPI_16(K, V); \ + ACPI_16((K) + 2, (V) >> 16) + + switch (addr) { + // Lid state and other flags + case 0x03: + if (gpio_get(&LID_SW_N)) { + // Lid is open + data |= 1 << 0; + } + if (lid_wake) { + data |= 1 << 2; + } + break; + + // Handle AC adapter and battery present + case 0x10: + if (!gpio_get(&ACIN_N)) { + // AC adapter connected + data |= 1 << 0; + } + // BAT0 always connected - TODO + data |= 1 << 2; + break; + + ACPI_16(0x16, battery_design_capacity); + ACPI_16(0x1A, battery_full_capacity); + ACPI_16(0x22, battery_design_voltage); + + case 0x26: + // If AC adapter connected + if (!gpio_get(&ACIN_N)) { + // And battery is not fully charged + if (!(battery_status & 0x0020)) { + // Battery is charging + data |= 1 << 1; + } + } + break; + + ACPI_16(0x2A, battery_current); + ACPI_16(0x2E, battery_remaining_capacity); + ACPI_16(0x32, battery_voltage); + + ACPI_8(0x68, ecos); + + ACPI_8(0xCC, sci_extra); + + // Set size of flash (from old firmware) + ACPI_8 (0xE5, 0x80); + + ACPI_8 (0xF8, fcmd); + ACPI_8 (0xF9, fdat); + ACPI_8 (0xFA, fbuf[0]); + ACPI_8 (0xFB, fbuf[1]); + ACPI_8 (0xFC, fbuf[2]); + ACPI_8 (0xFD, fbuf[3]); + } + + DEBUG("acpi_read %02X = %02X\n", addr, data); + return data; +} + + +void acpi_write(uint8_t addr, uint8_t data) { + DEBUG("acpi_write %02X = %02X\n", addr, data); + + switch (addr) { + // Lid state and other flags + case 0x03: + lid_wake = (bool)(data & (1 << 2)); + break; + + case 0x68: + ecos = data; + break; + + case 0xF8: + fcmd = data; + fcommand(); + break; + case 0xF9: + fdat = data; + break; + case 0xFA: + fbuf[0] = data; + break; + case 0xFB: + fbuf[1] = data; + break; + case 0xFC: + fbuf[2] = data; + break; + case 0xFD: + fbuf[3] = data; + break; + } +} diff --git a/src/board/system76/oryp6/board.c b/src/board/system76/oryp6/board.c new file mode 100644 index 0000000..8da9045 --- /dev/null +++ b/src/board/system76/oryp6/board.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +extern uint8_t main_cycle; + +void board_init(void) { + // Allow CPU to boot + gpio_set(&SB_KBCRST_N, true); + // Allow backlight to be turned on + gpio_set(&BKL_EN, true); + // Enable camera + gpio_set(&CCD_EN, true); + // Enable wireless + gpio_set(&BT_EN, true); + gpio_set(&WLAN_EN, true); + gpio_set(&WLAN_PWR_EN, true); + // Assert SMI#, SCI#, and SWI# + gpio_set(&SCI_N, true); + gpio_set(&SMI_N, true); + gpio_set(&SWI_N, true); + + dgpu_init(); +} + +void board_event(void) { + if (main_cycle == 0) { + bool acin = !gpio_get(&ACIN_N); + gpio_set(&AC_PRESENT, acin); + if (acin) { + // Discharging (no AC adapter) + gpio_set(&LED_BAT_CHG, false); + gpio_set(&LED_BAT_FULL, false); + } else if (battery_status & 0x0020) { + // Fully charged + // TODO: turn off charger + gpio_set(&LED_BAT_CHG, false); + gpio_set(&LED_BAT_FULL, true); + } else { + // Charging + // TODO: detect no battery connected + gpio_set(&LED_BAT_CHG, true); + gpio_set(&LED_BAT_FULL, false); + } + + if (power_state == POWER_STATE_S0 || power_state == POWER_STATE_S3 || power_state == POWER_STATE_DS3) { + // System is on + } else if (!acin) { + // Power off VDD3 if system should be off + gpio_set(&XLP_OUT, 0); + } + + static uint32_t last_time = 0; + uint32_t time = time_get(); + // Only run the following once a second + if (last_time > time || (time - last_time) >= 1000) { + last_time = time; + + // Updates discrete GPU fan status and temps + dgpu_event(); + } + } +} diff --git a/src/board/system76/oryp6/board.mk b/src/board/system76/oryp6/board.mk new file mode 100644 index 0000000..0fa8921 --- /dev/null +++ b/src/board/system76/oryp6/board.mk @@ -0,0 +1,38 @@ +EC=it5570e + +# Add keymap to src +KEYMAP?=default +SRC+=$(BOARD_DIR)/keymap/$(KEYMAP).c + +# Set log level +# 0 - NONE +# 1 - ERROR +# 2 - WARN +# 3 - INFO +# 4 - DEBUG +# 5 - TRACE +CFLAGS+=-DLEVEL=4 + +# Enable I2C debug on 0x76 +#CFLAGS+=-DI2C_DEBUGGER=0x76 + +# Set discrete GPU I2C bus +CFLAGS+=-DI2C_DGPU=I2C_1 + +# Set battery I2C bus +CFLAGS+=-DI2C_SMBUS=I2C_4 + +# Set touchpad PS2 bus +CFLAGS+=-DPS2_TOUCHPAD=PS2_3 + +# Set smart charger parameters +CFLAGS+=\ + -DCHARGER_CHARGE_CURRENT=1536 \ + -DCHARGER_CHARGE_VOLTAGE=16800 \ + -DCHARGER_INPUT_CURRENT=13050 + +# Enable debug logging over keyboard parallel port +#CFLAGS+=-DPARPORT_DEBUG + +# Add system76 common code +include src/board/system76/common/common.mk diff --git a/src/board/system76/oryp6/dgpu.c b/src/board/system76/oryp6/dgpu.c new file mode 100644 index 0000000..bc033a7 --- /dev/null +++ b/src/board/system76/oryp6/dgpu.c @@ -0,0 +1,144 @@ +#include +#include + +#include +#include +#include +#include +#include +#include + +// Fan speed is the lowest requested over HEATUP seconds +#define HEATUP 10 + +// Fan speed is the highest HEATUP speed over COOLDOWN seconds +#define COOLDOWN 10 + +// Interpolate duty cycle +#define INTERPOLATE 0 + +int16_t dgpu_temp = 0; +uint8_t dgpu_duty = 0; + +#define DGPU_TEMP(X) ((int16_t)(X)) +#define PWM_DUTY(X) ((uint8_t)(((((uint16_t)(X)) * 255) + 99) / 100)) + +struct FanPoint { + int16_t temp; + uint8_t duty; +}; + +#define FAN_POINT(T, D) { .temp = DGPU_TEMP(T), .duty = PWM_DUTY(D) } + +// Fan curve with temperature in degrees C, duty cycle in percent +static struct FanPoint __code FAN_POINTS[] = { + FAN_POINT(70, 40), + FAN_POINT(75, 50), + FAN_POINT(80, 60), + FAN_POINT(85, 65), + FAN_POINT(90, 65) +}; + +// Get duty cycle based on temperature, adapted from +// https://github.com/pop-os/system76-power/blob/master/src/fan.rs +static uint8_t fan_duty(int16_t temp) { + for (int i = 0; i < ARRAY_SIZE(FAN_POINTS); i++) { + const struct FanPoint * cur = &FAN_POINTS[i]; + + // If exactly the current temp, return the current duty + if (temp == cur->temp) { + return cur->duty; + } else if (temp < cur->temp) { + // If lower than first temp, return 0% + if (i == 0) { + return PWM_DUTY(0); + } else { + const struct FanPoint * prev = &FAN_POINTS[i - 1]; + +#if INTERPOLATE + // If in between current temp and previous temp, interpolate + if (temp > prev->temp) { + int16_t dtemp = (cur->temp - prev->temp); + int16_t dduty = ((int16_t)cur->duty) - ((int16_t)prev->duty); + return (uint8_t)( + ((int16_t)prev->duty) + + ((temp - prev->temp) * dduty) / dtemp + ); + } +#else // INTERPOLATE + return prev->duty; +#endif // INTERPOLATE + } + } + } + + // If no point is found, return 100% + return PWM_DUTY(100); +} + +static uint8_t fan_heatup(uint8_t duty) { + static uint8_t history[HEATUP] = { 0 }; + uint8_t lowest = duty; + + int i; + for (i = 0; (i + 1) < ARRAY_SIZE(history); i++) { + uint8_t value = history[i + 1]; + if (value < lowest) { + lowest = value; + } + history[i] = value; + } + history[i] = duty; + + return lowest; +} + +static uint8_t fan_cooldown(uint8_t duty) { + static uint8_t history[COOLDOWN] = { 0 }; + uint8_t highest = duty; + + int i; + for (i = 0; (i + 1) < ARRAY_SIZE(history); i++) { + uint8_t value = history[i + 1]; + if (value > highest) { + highest = value; + } + history[i] = value; + } + history[i] = duty; + + return highest; +} + +void dgpu_init(void) { + // Set up for i2c usage + i2c_reset(&I2C_DGPU, true); +} + +void dgpu_event(void) { + if (power_state == POWER_STATE_S0 && gpio_get(&DGPU_PWR_EN)) { + // Use I2CS if in S0 state + int8_t rlts; + int res = i2c_get(&I2C_DGPU, 0x4F, 0x00, &rlts, 1); + if (res == 1) { + dgpu_temp = (int16_t)rlts; + dgpu_duty = fan_duty(dgpu_temp); + } else { + DEBUG("DGPU temp error: %d\n", res); + // Default to 50% if there is an error + dgpu_temp = 0; + dgpu_duty = PWM_DUTY(50); + } + } else { + // Turn fan off if not in S0 state or GPU power not on + dgpu_temp = 0; + dgpu_duty = PWM_DUTY(0); + } + + uint8_t heatup_duty = fan_heatup(dgpu_duty); + uint8_t cooldown_duty = fan_cooldown(heatup_duty); + if (cooldown_duty != DCR4) { + DCR4 = cooldown_duty; + DEBUG("DGPU temp=%d = %d\n", dgpu_temp, cooldown_duty); + } +} diff --git a/src/board/system76/oryp6/gpio.c b/src/board/system76/oryp6/gpio.c new file mode 100644 index 0000000..f3776a0 --- /dev/null +++ b/src/board/system76/oryp6/gpio.c @@ -0,0 +1,266 @@ +#include +#include + +struct Gpio __code ACIN_N = GPIO(B, 0); +struct Gpio __code AC_PRESENT = GPIO(E, 1); +struct Gpio __code ALL_SYS_PWRGD = GPIO(C, 0); +struct Gpio __code BKL_EN = GPIO(H, 2); +struct Gpio __code BT_EN = GPIO(F, 3); +struct Gpio __code BUF_PLT_RST_N = GPIO(D, 2); +struct Gpio __code CCD_EN = GPIO(D, 1); +struct Gpio __code DD_ON = GPIO(E, 4); +struct Gpio __code DGPU_PWR_EN = GPIO(F, 7); +struct Gpio __code EC_EN = GPIO(B, 6); // renamed to SUSBC_EN +struct Gpio __code EC_RSMRST_N = GPIO(E, 5); +struct Gpio __code LED_ACIN = GPIO(C, 7); +struct Gpio __code LED_BAT_CHG = GPIO(H, 5); +struct Gpio __code LED_BAT_FULL = GPIO(J, 0); +struct Gpio __code LED_PWR = GPIO(D, 0); +struct Gpio __code LID_SW_N = GPIO(B, 1); +struct Gpio __code PM_PWROK = GPIO(C, 6); +struct Gpio __code PWR_BTN_N = GPIO(D, 5); +struct Gpio __code PWR_SW_N = GPIO(B, 3); +struct Gpio __code SB_KBCRST_N = GPIO(E, 6); +struct Gpio __code SCI_N = GPIO(D, 3); +struct Gpio __code SMI_N = GPIO(D, 4); +struct Gpio __code SUSB_N_PCH = GPIO(H, 6); +struct Gpio __code SUSC_N_PCH = GPIO(H, 1); +struct Gpio __code SWI_N = GPIO(B, 5); +struct Gpio __code VA_EC_EN = GPIO(J, 4); // renamed to EC_SLP_SUS# +struct Gpio __code WLAN_EN = GPIO(G, 1); +struct Gpio __code WLAN_PWR_EN = GPIO(A, 3); +struct Gpio __code XLP_OUT = GPIO(B, 4); + +void gpio_init() { + // Enable LPC reset on GPD2 + GCR = 0x04; + // Enable SMBus channel 4 + GCR15 = (1 << 4); + // Set GPF2 and GPF3 to 3.3V + GCR20 = 0; + + // Set GPIO data + GPDRA = 0x00; + GPDRB = 0x18; + GPDRC = 0x00; + GPDRD = 0x38; + GPDRE = 0x08; + GPDRF = 0x40; + GPDRG = 0x40; + GPDRH = 0x00; + GPDRI = 0x00; + GPDRJ = 0x00; + + // Set GPIO control + // EC_PWM_PIN_24 + GPCRA0 = GPIO_ALT; + // KBC_BEEP + GPCRA1 = GPIO_ALT; + // CPU_FAN + GPCRA2 = GPIO_ALT; + // WLAN_PWR_EN + GPCRA3 = GPIO_OUT | GPIO_UP; + // VGA_FAN + GPCRA4 = GPIO_ALT; + // EC_PWM_LEDKB_R + GPCRA5 = GPIO_ALT; + // EC_PWM_LEDKB_G + GPCRA6 = GPIO_ALT; + // EC_PWM_LEDKB_B + GPCRA7 = GPIO_ALT; + // AC_IN# + GPCRB0 = GPIO_IN | GPIO_UP; + // LID_SW# + GPCRB1 = GPIO_IN | GPIO_UP; + // LAN_WAKEUP# + GPCRB2 = GPIO_IN | GPIO_UP; + // PWR_SW# + GPCRB3 = GPIO_IN; + // XLP_OUT + GPCRB4 = GPIO_OUT; + // SWI# + GPCRB5 = GPIO_OUT | GPIO_UP; + // SUSBC_EN# + GPCRB6 = GPIO_OUT | GPIO_UP; + // + GPCRB7 = GPIO_IN; + // ALL_SYS_PWRGD + GPCRC0 = GPIO_IN; + // SMC_VGA_THERM + GPCRC1 = GPIO_ALT; + // SMD_VGA_THERM + GPCRC2 = GPIO_ALT; + // KB-SO16 + GPCRC3 = GPIO_IN; + // CNVI_DET# + GPCRC4 = GPIO_IN | GPIO_UP; + // KB-SO17 + GPCRC5 = GPIO_IN; + // PM_PWROK + GPCRC6 = GPIO_OUT; + // LED_ACIN + GPCRC7 = GPIO_OUT | GPIO_UP; + // LED_PWR + GPCRD0 = GPIO_OUT | GPIO_UP; + // CCD_EN + GPCRD1 = GPIO_OUT | GPIO_UP; + // BUF_PLT_RST# + GPCRD2 = GPIO_ALT; + // SCI# + GPCRD3 = GPIO_IN; + // SMI# + GPCRD4 = GPIO_IN; + // PWR_BTN# + GPCRD5 = GPIO_OUT | GPIO_UP; + // CPU_FANSEN + GPCRD6 = GPIO_ALT; + // VGA_FANSEN + GPCRD7 = GPIO_ALT; + // SMC_BAT + GPCRE0 = GPIO_ALT; + // AC_PRESENT + GPCRE1 = GPIO_OUT | GPIO_DOWN; + // PERKB_DET# + GPCRE2 = GPIO_IN | GPIO_UP; + // USB_PWR_EN# + GPCRE3 = GPIO_OUT | GPIO_UP; + // DD_ON + GPCRE4 = GPIO_OUT | GPIO_DOWN; + // EC_RSMRST# + GPCRE5 = GPIO_OUT; + // SB_KBCRST# + GPCRE6 = GPIO_OUT | GPIO_UP; + // SMD_BAT + GPCRE7 = GPIO_ALT; + // 80CLK + GPCRF0 = GPIO_IN; + // USB_CHARGE_EN + GPCRF1 = GPIO_OUT | GPIO_UP; + // 3IN1 + GPCRF2 = GPIO_IN | GPIO_UP; + // BT_EN + GPCRF3 = GPIO_OUT | GPIO_UP; + // TP_CLK + GPCRF4 = GPIO_ALT; + // TP_DATA + GPCRF5 = GPIO_ALT; + // EC_PECI + GPCRF6 = GPIO_ALT; + // DGPU_PWR_EN + GPCRF7 = GPIO_IN; + //TODO NV_POWER_IC_EN + GPCRG0 = GPIO_OUT | GPIO_UP; + // WLAN_EN + GPCRG1 = GPIO_OUT | GPIO_UP; + // AUTO_LOAD_PWR + GPCRG2 = GPIO_OUT; + // ALSPI_CE# + GPCRG3 = GPIO_ALT; + // ALSPI_MSI + GPCRG4 = GPIO_ALT; + // ALSPI_MSO + GPCRG5 = GPIO_ALT; + // H_PROCHOT#_EC + GPCRG6 = GPIO_OUT | GPIO_UP; + // ALSPI_SCLK + GPCRG7 = GPIO_ALT; + // PM_CLKRUN# + GPCRH0 = GPIO_ALT; + // SUSC#_PCH + GPCRH1 = GPIO_IN; + // BKL_EN + GPCRH2 = GPIO_OUT | GPIO_UP; + // dGPU_GPIO8_OVERT + GPCRH3 = GPIO_IN | GPIO_UP; + // PCIE_WAKE# + GPCRH4 = GPIO_IN; + // LED_BAT_CHG + GPCRH5 = GPIO_OUT | GPIO_UP; + // SUSB#_PCH + GPCRH6 = GPIO_IN; + // VCCIO_3P3_PWRGATE + GPCRH7 = GPIO_IN; + // BAT_DET + GPCRI0 = GPIO_ALT; + // BAT_VOLT + GPCRI1 = GPIO_ALT; + // ME_WE + GPCRI2 = GPIO_OUT; + // THERM_VOLT + GPCRI3 = GPIO_ALT; + // TOTAL_CUR + GPCRI4 = GPIO_ALT; + //TODO EC_AMP_EN + GPCRI5 = GPIO_OUT; + // SLP_S0# + GPCRI6 = GPIO_IN; + // MODEL_ID + GPCRI7 = GPIO_IN; + // LED_BAT_FULL + GPCRJ0 = GPIO_OUT | GPIO_UP; + // KBC_MUTE# + GPCRJ1 = GPIO_IN; + // NC + GPCRJ2 = GPIO_IN | GPIO_UP; + // RGBKB-DET# + GPCRJ3 = GPIO_IN | GPIO_UP; + // EC_SLP_SUS# + GPCRJ4 = GPIO_OUT; + // VBATT_BOOST# + GPCRJ5 = GPIO_OUT; + // SLP_S5# + GPCRJ6 = GPIO_IN; + // GC6_FB_EN_PCH + GPCRJ7 = GPIO_IN; + // LPC_AD0 + GPCRM0 = GPIO_ALT; + // LPC_AD1 + GPCRM1 = GPIO_ALT; + // LPC_AD2 + GPCRM2 = GPIO_ALT; + // LPC_AD3 + GPCRM3 = GPIO_ALT; + // PCLK_KBC + GPCRM4 = GPIO_ALT; + // LPC_FRAME# + GPCRM5 = GPIO_ALT; + // SERIRQ + GPCRM6 = GPIO_ALT; +} + +#if GPIO_DEBUG +void gpio_debug_bank( + char * bank, + uint8_t data, + uint8_t mirror, + uint8_t pot, + volatile uint8_t * control +) { + for(char i = 0; i < 8; i++) { + DEBUG( + "%s%d:\n\tdata %d\n\tmirror %d\n\tpot %d\n\tcontrol %02X\n", + bank, + i, + (data >> i) & 1, + (mirror >> i) & 1, + (pot >> i) & 1, + *(control + i) + ); + } +} + +void gpio_debug(void) { + #define bank(BANK) gpio_debug_bank(#BANK, GPDR ## BANK, GPDMR ## BANK, GPOT ## BANK, &GPCR ## BANK ## 0) + bank(A); + bank(B); + bank(C); + bank(D); + bank(E); + bank(F); + bank(G); + bank(H); + bank(I); + bank(J); + #undef bank +} +#endif diff --git a/src/board/system76/oryp6/include/board/dgpu.h b/src/board/system76/oryp6/include/board/dgpu.h new file mode 100644 index 0000000..ffe4f3a --- /dev/null +++ b/src/board/system76/oryp6/include/board/dgpu.h @@ -0,0 +1,7 @@ +#ifndef _BOARD_DGPU_H +#define _BOARD_DGPU_H + +void dgpu_init(void); +void dgpu_event(void); + +#endif // _BOARD_DGPU_H diff --git a/src/board/system76/oryp6/include/board/gpio.h b/src/board/system76/oryp6/include/board/gpio.h new file mode 100644 index 0000000..6dc483d --- /dev/null +++ b/src/board/system76/oryp6/include/board/gpio.h @@ -0,0 +1,51 @@ +#ifndef _BOARD_GPIO_H +#define _BOARD_GPIO_H + +#include + +#define GPIO_ALT 0x00 +#define GPIO_IN 0x80 +#define GPIO_OUT 0x40 +#define GPIO_UP 0x04 +#define GPIO_DOWN 0x02 + +void gpio_init(void); +void gpio_debug(void); + +extern struct Gpio __code ACIN_N; +extern struct Gpio __code AC_PRESENT; +extern struct Gpio __code ALL_SYS_PWRGD; +extern struct Gpio __code BKL_EN; +extern struct Gpio __code BT_EN; +extern struct Gpio __code BUF_PLT_RST_N; +extern struct Gpio __code CCD_EN; +extern struct Gpio __code DD_ON; +extern struct Gpio __code DGPU_PWR_EN; +extern struct Gpio __code EC_EN; +extern struct Gpio __code EC_RSMRST_N; +extern struct Gpio __code LED_ACIN; +extern struct Gpio __code LED_AIRPLANE_N; +extern struct Gpio __code LED_BAT_CHG; +extern struct Gpio __code LED_BAT_FULL; +extern struct Gpio __code LED_PWR; +extern struct Gpio __code LID_SW_N; +#define HAVE_PCH_DPWROK_EC 0 +#define HAVE_PCH_PWROK_EC 0 +extern struct Gpio __code PM_PWROK; +extern struct Gpio __code PWR_BTN_N; +extern struct Gpio __code PWR_SW_N; +extern struct Gpio __code SB_KBCRST_N; +extern struct Gpio __code SCI_N; +#define HAVE_SLP_SUS_N 0 +extern struct Gpio __code SMI_N; +extern struct Gpio __code SUSB_N_PCH; +extern struct Gpio __code SUSC_N_PCH; +#define HAVE_SUSWARN_N 0 +#define HAVE_SUS_PWR_ACK 0 +extern struct Gpio __code SWI_N; +extern struct Gpio __code VA_EC_EN; +extern struct Gpio __code WLAN_EN; +extern struct Gpio __code WLAN_PWR_EN; +extern struct Gpio __code XLP_OUT; + +#endif // _BOARD_GPIO_H diff --git a/src/board/system76/oryp6/include/board/kbled.h b/src/board/system76/oryp6/include/board/kbled.h new file mode 100644 index 0000000..895542c --- /dev/null +++ b/src/board/system76/oryp6/include/board/kbled.h @@ -0,0 +1,12 @@ +#ifndef _BOARD_KBLED_H +#define _BOARD_KBLED_H + +#include + +void kbled_init(void); +void kbled_reset(void); +uint8_t kbled_get(void); +void kbled_set(uint8_t level); +void kbled_set_color(uint32_t color); + +#endif // _BOARD_KBLED_H diff --git a/src/board/system76/oryp6/include/board/keymap.h b/src/board/system76/oryp6/include/board/keymap.h new file mode 100644 index 0000000..eacd404 --- /dev/null +++ b/src/board/system76/oryp6/include/board/keymap.h @@ -0,0 +1,50 @@ +#ifndef _BOARD_KEYMAP_H +#define _BOARD_KEYMAP_H + +#include + +#define ___ 0 + +// Conversion of physical layout to keyboard matrix +#define LAYOUT( \ + K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, K0F, K0G, K0H, K0I, K0J, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, K1F, K1G, K1H, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, K2F, K2G, K2H, \ + K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D, K3E, K3F, \ + K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B, K4C, K4D, K4E, K4F, K4G, \ + K50, K51, K52, K53, K54, K55, K56, K57, K58, K59, K5A, K5B, K5C \ +) { \ + { ___, ___, ___, ___, ___, ___, K50, K57 }, \ + { ___, ___, ___, ___, ___, ___, K53, K55 }, \ + { ___, ___, ___, ___, ___, ___, K40, K4B }, \ + { K52, ___, ___, ___, ___, ___, ___, K54 }, \ + { K41, K1H, ___, K2F, K4E, ___, ___, ___ }, \ + { K0I, K22, ___, ___, K1E, K3D, K3F, K30 }, \ + { K0J, K1B, K23, K39, ___, ___, K47, ___ }, \ + { K38, K26, K1A, K24, ___, K3A, K20, K00 }, \ + { K5B, K37, K2C, K19, K25, K07, K18, K01 }, \ + { K5C, K34, K36, K02, ___, K4G, K3B, K45 }, \ + { K1F, K48, ___, K2B, K32, K08, K06, K12 }, \ + { K1G, K49, K17, K33, ___, ___, K11, K2A }, \ + { K2D, ___, K31, K4A, ___, K03, K28, K16 }, \ + { ___, K44, K0D, K09, K46, K29, K15, K05 }, \ + { K21, K0A, K2E, K04, K3E, K0E, K0F, K14 }, \ + { K56, K42, K3C, K2H, K27, K2G, K13, K1D }, \ + { K0H, K0G, K43, K4C, K59, K10, K0B, K0C }, \ + { K35, K1C, K4F, K51, K4D, K58, K5A, ___ } \ +} + +// Keymap output pins +#define KM_OUT 18 +// Keymap input pins +#define KM_IN 8 +// Keymap layers (normal, Fn) +#define KM_LAY 2 + +// Keymap +extern uint16_t __code KEYMAP[KM_LAY][KM_OUT][KM_IN]; + +// Get a keycode from the keymap +uint16_t keymap(int output, int input, int layer); + +#endif // _BOARD_KEYMAP_H diff --git a/src/board/system76/oryp6/kbled.c b/src/board/system76/oryp6/kbled.c new file mode 100644 index 0000000..abacb2a --- /dev/null +++ b/src/board/system76/oryp6/kbled.c @@ -0,0 +1,34 @@ +#include +#include + +void kbled_init(void) { + //TODO: enable PWMs + kbled_reset(); +} + +void kbled_reset(void) { + // Set brightness and color + kbled_set_color(0xFFFFFF); + kbled_set(0x00); +} + +uint8_t kbled_get(void) { + // Get PWM for power + return DCR0; +} + +void kbled_set(uint8_t level) { + // Set PWM for power + DCR0 = level; +} + +void kbled_set_color(uint32_t color) { + // Set PWM for blue component + DCR7 = (uint8_t)(color); + + // Set PWM for green component + DCR6 = (uint8_t)(color >> 8); + + // Set PWM for red component + DCR5 = (uint8_t)(color >> 16); +} diff --git a/src/board/system76/oryp6/keymap/default.c b/src/board/system76/oryp6/keymap/default.c new file mode 100644 index 0000000..65d46ce --- /dev/null +++ b/src/board/system76/oryp6/keymap/default.c @@ -0,0 +1,22 @@ +// Default layout + +#include + +uint16_t __code KEYMAP[KM_LAY][KM_OUT][KM_IN] = { +LAYOUT( + K_ESC, K_F1, K_F2, K_F3, K_F4, K_F5, K_F6, K_F7, K_F8, K_F9, K_F10, K_F11, K_F12, K_PRINT_SCREEN, K_INSERT, K_DEL, K_HOME, K_END, K_PGUP, K_PGDN, + K_TICK, K_1, K_2, K_3, K_4, K_5, K_6, K_7, K_8, K_9, K_0, K_MINUS, K_EQUALS, K_BKSP, K_NUM_LOCK, K_NUM_SLASH, K_NUM_ASTERISK, K_NUM_MINUS, + K_TAB, K_Q, K_W, K_E, K_R, K_T, K_Y, K_U, K_I, K_O, K_P, K_BRACE_OPEN, K_BRACE_CLOSE, K_BACKSLASH, K_NUM_7, K_NUM_8, K_NUM_9, K_NUM_PLUS, + K_CAPS, K_A, K_S, K_D, K_F, K_G, K_H, K_J, K_K, K_L, K_SEMICOLON, K_QUOTE, K_ENTER, K_NUM_4, K_NUM_5, K_NUM_6, + K_LEFT_SHIFT, K_Z, K_X, K_C, K_V, K_B, K_N, K_M, K_COMMA, K_PERIOD, K_SLASH, K_RIGHT_SHIFT, K_UP, K_NUM_1, K_NUM_2, K_NUM_3, K_NUM_ENTER, + K_LEFT_CTRL, KT_FN, K_LEFT_SUPER, K_LEFT_ALT, K_SPACE, K_RIGHT_ALT, K_APP, K_RIGHT_CTRL, K_LEFT, K_DOWN, K_RIGHT, K_NUM_0, K_NUM_PERIOD +), +LAYOUT( + K_ESC, K_TOUCHPAD, KT_SCI | SCI_DISPLAY_TOGGLE, K_MUTE, K_F4, K_VOLUME_DOWN, K_VOLUME_UP, K_DISPLAY_MODE, KT_SCI | SCI_BRIGHTNESS_DOWN, KT_SCI | SCI_BRIGHTNESS_UP, KT_SCI | SCI_CAMERA_TOGGLE, KT_SCI | SCI_AIRPLANE_MODE, KT_SCI | SCI_SUSPEND, K_PRINT_SCREEN, K_INSERT, K_DEL, K_HOME, K_END, K_PGUP, K_PGDN, + K_PLAY_PAUSE, K_1, K_2, K_3, K_4, K_5, K_6, K_7, K_8, K_9, K_0, K_MINUS, K_EQUALS, K_BKSP, K_NUM_LOCK, KT_SCI_EXTRA | SCI_EXTRA_KBD_COLOR, KT_SCI_EXTRA | SCI_EXTRA_KBD_TOGGLE, KT_SCI_EXTRA | SCI_EXTRA_KBD_DOWN, + K_TAB, K_Q, K_W, K_E, K_R, K_T, K_Y, K_U, K_I, K_O, K_P, K_BRACE_OPEN, K_BRACE_CLOSE, K_BACKSLASH, K_NUM_7, K_NUM_8, K_NUM_9, KT_SCI_EXTRA | SCI_EXTRA_KBD_UP, + K_CAPS, K_A, K_S, K_D, K_F, K_G, K_H, K_J, K_K, K_L, K_SEMICOLON, K_QUOTE, K_ENTER, K_NUM_4, K_NUM_5, K_NUM_6, + K_LEFT_SHIFT, K_Z, K_X, K_C, K_V, K_B, K_N, K_M, K_COMMA, K_PERIOD, K_SLASH, K_RIGHT_SHIFT, K_UP, K_NUM_1, K_NUM_2, K_NUM_3, K_NUM_ENTER, + K_LEFT_CTRL, KT_FN, K_LEFT_SUPER, K_LEFT_ALT, K_SPACE, K_RIGHT_ALT, K_APP, K_RIGHT_CTRL, K_LEFT, K_DOWN, K_RIGHT, K_NUM_0, K_NUM_PERIOD +) +}; diff --git a/src/board/system76/oryp6/keymap/jeremy.c b/src/board/system76/oryp6/keymap/jeremy.c new file mode 100644 index 0000000..2d19a63 --- /dev/null +++ b/src/board/system76/oryp6/keymap/jeremy.c @@ -0,0 +1,22 @@ +// Default layout + +#include + +uint16_t __code KEYMAP[KM_LAY][KM_OUT][KM_IN] = { +LAYOUT( + K_ESC, K_F1, K_F2, K_F3, K_F4, K_F5, K_F6, K_F7, K_F8, K_F9, K_F10, K_F11, K_F12, K_PRINT_SCREEN, K_INSERT, K_DEL, K_HOME, K_END, K_PGUP, K_PGDN, + K_TICK, K_1, K_2, K_3, K_4, K_5, K_6, K_7, K_8, K_9, K_0, K_MINUS, K_EQUALS, K_BKSP, K_NUM_LOCK, K_NUM_SLASH, K_NUM_ASTERISK, K_NUM_MINUS, + K_TAB, K_Q, K_W, K_E, K_R, K_T, K_Y, K_U, K_I, K_O, K_P, K_BRACE_OPEN, K_BRACE_CLOSE, K_BACKSLASH, K_NUM_7, K_NUM_8, K_NUM_9, K_NUM_PLUS, + KT_FN, K_A, K_S, K_D, K_F, K_G, K_H, K_J, K_K, K_L, K_SEMICOLON, K_QUOTE, K_ENTER, K_NUM_4, K_NUM_5, K_NUM_6, + K_LEFT_SHIFT, K_Z, K_X, K_C, K_V, K_B, K_N, K_M, K_COMMA, K_PERIOD, K_SLASH, K_RIGHT_SHIFT, K_UP, K_NUM_1, K_NUM_2, K_NUM_3, K_NUM_ENTER, + K_LEFT_CTRL, KT_FN, K_LEFT_ALT, K_LEFT_SUPER, K_SPACE, KT_FN, K_RIGHT_ALT, K_RIGHT_CTRL, K_LEFT, K_DOWN, K_RIGHT, K_NUM_0, K_NUM_PERIOD +), +LAYOUT( + K_ESC, K_TOUCHPAD, KT_SCI | SCI_DISPLAY_TOGGLE, K_MUTE, K_F4, K_VOLUME_DOWN, K_VOLUME_UP, K_DISPLAY_MODE, KT_SCI | SCI_BRIGHTNESS_DOWN, KT_SCI | SCI_BRIGHTNESS_UP, KT_SCI | SCI_CAMERA_TOGGLE, KT_SCI | SCI_AIRPLANE_MODE, KT_SCI | SCI_SUSPEND, K_PRINT_SCREEN, K_INSERT, K_DEL, K_HOME, K_END, K_PGUP, K_PGDN, + K_PLAY_PAUSE, K_1, K_2, K_3, K_4, K_5, K_6, K_7, K_8, K_9, K_0, K_MINUS, K_EQUALS, K_DEL, K_NUM_LOCK, KT_SCI_EXTRA | SCI_EXTRA_KBD_COLOR, KT_SCI_EXTRA | SCI_EXTRA_KBD_TOGGLE, KT_SCI_EXTRA | SCI_EXTRA_KBD_DOWN, + K_TAB, K_Q, K_W, K_E, K_R, K_T, K_Y, K_PGUP, K_HOME, K_PGDN, K_P, K_BRACE_OPEN, K_BRACE_CLOSE, K_BACKSLASH, K_NUM_7, K_NUM_8, K_NUM_9, KT_SCI_EXTRA | SCI_EXTRA_KBD_UP, + KT_FN, K_A, K_S, K_D, K_F, K_G, K_LEFT, K_DOWN, K_UP, K_RIGHT, K_BKSP, K_DEL, K_ENTER, K_NUM_4, K_NUM_5, K_NUM_6, + K_LEFT_SHIFT, K_Z, K_X, K_C, K_V, K_B, K_END, K_M, K_COMMA, K_PERIOD, K_SLASH, K_RIGHT_SHIFT, K_UP, K_NUM_1, K_NUM_2, K_NUM_3, K_NUM_ENTER, + K_LEFT_CTRL, KT_FN, K_LEFT_ALT, K_LEFT_SUPER, K_ESC, KT_FN, K_RIGHT_ALT, K_RIGHT_CTRL, K_LEFT, K_DOWN, K_RIGHT, K_NUM_0, K_NUM_PERIOD +) +}; diff --git a/src/board/system76/oryp6/scratch.c b/src/board/system76/oryp6/scratch.c new file mode 100644 index 0000000..225d2ff --- /dev/null +++ b/src/board/system76/oryp6/scratch.c @@ -0,0 +1,40 @@ +#include <8051.h> +#include + +#include +#include +#include + +// Include scratch ROM +uint8_t __code __at(SCRATCH_OFFSET) scratch_rom[] = { + #include +}; + +// SCAR0 is stored in processor cache, not in xram +volatile uint8_t __xdata __at(0x1040) SCAR0L; +volatile uint8_t __xdata __at(0x1041) SCAR0M; +volatile uint8_t __xdata __at(0x1042) SCAR0H; + +// Enter or exit scratch ROM +void scratch_trampoline(void) { + // Set fans to 100% + DCR2 = 0xFF; + DCR4 = 0xFF; + + //TODO: Clear keyboard presses + + // Start watchdog timer + smfi_watchdog(); + + // Disable interrupts + EA = 0; + + // Use DMA mapping to copy flash data + SCAR0H = 0x80; + SCAR0L = (uint8_t)(SCRATCH_OFFSET); + SCAR0M = (uint8_t)(SCRATCH_OFFSET >> 8); + SCAR0H = 0; + + // Jump to scratch reset function + __asm__("ljmp " xstr(SCRATCH_OFFSET)); +}