diff --git a/src/board/system76/galp5/board.c b/src/board/system76/galp5/board.c new file mode 100644 index 0000000..fe9ef31 --- /dev/null +++ b/src/board/system76/galp5/board.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-3.0-only + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern uint8_t main_cycle; + +void board_init(void) { + espi_init(); + + // Make sure charger is in off state, also enables PSYS + battery_charger_disable(); + + // 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); + // Enable right USB port + gpio_set(&USB_PWR_EN_N, false); + // Assert SMI# and SWI# + gpio_set(&SMI_N, true); + gpio_set(&SWI_N, true); + + // Enable POST codes + SPCTRL1 |= 0xC8; +} + +#if HAVE_DGPU +// Set PL4 using PECI +static int set_power_limit(uint8_t watts) { + return peci_wr_pkg_config( + 60, // index + 0, // param + ((uint32_t)watts) * 8 + ); +} + +void board_on_ac(bool ac) { + uint8_t power_limit = ac ? POWER_LIMIT_AC : POWER_LIMIT_DC; + // Retry, timeout errors happen occasionally + for (int i = 0; i < 16; i++) { + int res = set_power_limit(power_limit); + DEBUG("set_power_limit %d = %d\n", power_limit, res); + if (res == 0x40) { + break; + } else if (res < 0) { + ERROR("set_power_limit failed: 0x%02X\n", -res); + } else { + ERROR("set_power_limit unknown response: 0x%02X\n", res); + } + } +} +#else // HAVE_DGPU +void board_on_ac(bool ac) { /* Fix unused variable */ ac = ac; } +#endif // HAVE_DGPU + +void board_event(void) { +#if HAVE_DGPU + static bool last_power_limit_ac = true; + // We don't use power_state because the latency needs to be low + if (gpio_get(&CPU_C10_GATE_N)) { + bool ac = !gpio_get(&ACIN_N); + if (last_power_limit_ac != ac) { + board_on_ac(ac); + last_power_limit_ac = ac; + } + } else { + last_power_limit_ac = true; + } +#endif // HAVE_DGPU + + espi_event(); + + // Read POST codes + while (P80H81HS & 1) { + uint8_t p80h = P80HD; + uint8_t p81h = P81HD; + P80H81HS |= 1; + + DEBUG("POST %02X%02X\n", p81h, p80h); + } +} diff --git a/src/board/system76/galp5/board.mk b/src/board/system76/galp5/board.mk new file mode 100644 index 0000000..0b23d63 --- /dev/null +++ b/src/board/system76/galp5/board.mk @@ -0,0 +1,63 @@ +# SPDX-License-Identifier: GPL-3.0-only + +EC=it5570e + +# Enable eSPI +CFLAGS+=-DEC_ESPI=1 + +# Add keymap to src +KEYMAP?=default +SRC+=$(BOARD_DIR)/keymap/$(KEYMAP).c + +# 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 +#TODO: Find out why input current must by divided by two +CHARGER=oz26786 +CFLAGS+=\ + -DCHARGER_CHARGE_CURRENT=1536 \ + -DCHARGER_CHARGE_VOLTAGE=17400 \ + -DCHARGER_INPUT_CURRENT=1600 + +# Set battery charging thresholds +CFLAGS+=\ + -DBATTERY_START_THRESHOLD=0 \ + -DBATTERY_END_THRESHOLD=100 + +# Set CPU power limits in watts +CFLAGS+=\ + -DPOWER_LIMIT_AC=65 \ + -DPOWER_LIMIT_DC=28 + +# Custom fan curve +CFLAGS+=-DBOARD_HEATUP=5 +CFLAGS+=-DBOARD_COOLDOWN=20 +CFLAGS+=-DBOARD_FAN_POINTS="\ + FAN_POINT(70, 40), \ + FAN_POINT(75, 60), \ + FAN_POINT(80, 75), \ + FAN_POINT(85, 90), \ + FAN_POINT(90, 100) \ +" + +# DGPU support +CFLAGS+=-DHAVE_DGPU=1 +CFLAGS+=-DBOARD_DGPU_HEATUP=5 +CFLAGS+=-DBOARD_DGPU_COOLDOWN=20 +CFLAGS+=-DBOARD_DGPU_FAN_POINTS="\ + FAN_POINT(70, 40), \ + FAN_POINT(75, 60), \ + FAN_POINT(80, 75), \ + FAN_POINT(85, 90), \ + FAN_POINT(90, 100) \ +" + +# Add system76 common code +include src/board/system76/common/common.mk diff --git a/src/board/system76/galp5/espi.c b/src/board/system76/galp5/espi.c new file mode 100644 index 0000000..c6b0204 --- /dev/null +++ b/src/board/system76/galp5/espi.c @@ -0,0 +1,194 @@ +#include <8051.h> +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG_SET(REG, MASK, BITS) { \ + DEBUG("%s: %X", #REG, REG); \ + REG = ((REG) & ~(MASK)) | (BITS); \ + DEBUG(" set to %X\n", REG); \ +} + +#define DEBUG_ON(REG, BITS) \ + DEBUG_SET(REG, BITS, BITS) + +#define DEBUG_OFF(REG, BITS) \ + DEBUG_SET(REG, BITS, 0) + +#define DEBUG_CHANGED(REG) { \ + static uint8_t last_ ## REG = 0; \ + uint8_t new_ ## REG = REG; \ + if (new_ ## REG != last_ ## REG) { \ + DEBUG( \ + "%S: %X changed to %X\n", \ + #REG, \ + last_ ## REG, \ + new_ ## REG \ + ); \ + last_ ## REG = new_ ## REG; \ + } \ +} + +#define VW_SET_DEBUG(W, V) { \ + DEBUG("%s = %X\n", #W, V); \ + vw_set(&W, V); \ +} + +void espi_init(void) { + if (PLLFREQ != 0b0111) { + // Workarounds to allow changing PLL + { + // ESPI_CS# set to input + GPCRM5 = GPIO_IN; + // Disable eSPI pads + DEBUG_ON(ESGCTRL2, BIT(6)); + } + + DEBUG("PLLFREQ is 0x%02X\n", PLLFREQ); + + // Set PLL frequency to 64.5 MHz for eSPI + PLLFREQ = 0b0111; + + // Prepare to sleep + PLLCTRL = 0x01; + + // No idea why + __asm__("nop"); + + // Set power down bit + PCON |= BIT(1); + + // Wait for "internal bus turn-around" + __asm__("nop"); + __asm__("nop"); + __asm__("nop"); + __asm__("nop"); + __asm__("nop"); + __asm__("nop"); + __asm__("nop"); + __asm__("nop"); + + DEBUG("PLLFREQ is now 0x%02X\n", PLLFREQ); + + // Wait for PLL to stabilize + delay_ms(5); + + // Workarounds to allow changing PLL + { + // Enable eSPI pads + DEBUG_OFF(ESGCTRL2, BIT(6)); + // ESPI_CS# set to alternate mode + GPCRM5 = GPIO_ALT; + } + } + + // Set maximum eSPI frequency to 50MHz + DEBUG_SET(ESGCAC2, 0b111, 0b011); + + espi_event(); +} + +void espi_reset(void) { + espi_event(); +} + +void espi_event(void) { + uint8_t value; + enum VirtualWireState wire; + + // Detect channel enabled + value = ESGCTRL0; + if (value) { + ESGCTRL0 = value; + DEBUG("ESGCTRL0 %X\n", value); + + if (value & BIT(1)) { + DEBUG("VW EN\n"); + // Set SUS_ACK# low + VW_SET_DEBUG(VW_SUS_ACK_N, VWS_LOW); + } + if (value & BIT(2)) { + DEBUG("OOB EN\n"); + VW_SET_DEBUG(VW_OOB_RST_ACK, VWS_LOW); + } + if (value & BIT(3)) { + DEBUG("FLASH EN\n"); + // Set boot load status and boot load done high + VW_SET_DEBUG(VW_BOOT_LOAD_STATUS, VWS_HIGH); + VW_SET_DEBUG(VW_BOOT_LOAD_DONE, VWS_HIGH); + } + } + + // Detect PUT_PC + value = ESPCTRL0; + if (value & BIT(7)) { + ESPCTRL0 = BIT(7); + DEBUG("ESPCTRL0 %X\n", value); + } + + // Detect updated virtual wires + value = VWCTRL1; + if (value) { + VWCTRL1 = value; + DEBUG("VWCTRL1 %X\n", value); + + if (value & BIT(0)) { + DEBUG("VWIDX2 %X\n", VWIDX2); + } + if (value & BIT(1)) { + DEBUG("VWIDX3 %X\n", VWIDX3); + + // Set OOB_RST_ACK to OOB_RST_WARN + wire = vw_get(&VW_OOB_RST_WARN); + if (wire != vw_get(&VW_OOB_RST_ACK)) { + VW_SET_DEBUG(VW_OOB_RST_ACK, wire); + } + + static enum VirtualWireState last_pltrst_n = VWS_INVALID; + wire = vw_get(&VW_PLTRST_N); + if (wire != last_pltrst_n) { + DEBUG("ESPI PLTRST# %X\n", wire); + if (wire == VWS_HIGH) { + // Set SCI, SMI, and RCIN to high + VW_SET_DEBUG(VW_SCI_N, VWS_HIGH); + VW_SET_DEBUG(VW_SMI_N, VWS_HIGH); + VW_SET_DEBUG(VW_RCIN_N, VWS_HIGH); + + power_cpu_reset(); + } + last_pltrst_n = wire; + } + } + if (value & BIT(2)) { + DEBUG("VWIDX7 %X\n", VWIDX7); + + // Set HOST_RST_ACK to HOST_RST_WARN + wire = vw_get(&VW_HOST_RST_WARN); + if (wire != vw_get(&VW_HOST_RST_ACK)) { + VW_SET_DEBUG(VW_HOST_RST_ACK, wire); + } + } + if (value & BIT(3)) { + DEBUG("VWIDX41 %X\n", VWIDX41); + + // Set SUS_ACK# to SUS_WARN# + wire = vw_get(&VW_SUS_WARN_N); + if (wire != vw_get(&VW_SUS_ACK_N)) { + VW_SET_DEBUG(VW_SUS_ACK_N, wire); + } + } + } + + // Detect when frequency changes + DEBUG_CHANGED(ESGCTRL2); + + // Detect when I/O mode changes + DEBUG_CHANGED(ESGCTRL3); +} diff --git a/src/board/system76/galp5/gpio.c b/src/board/system76/galp5/gpio.c new file mode 100644 index 0000000..8669eac --- /dev/null +++ b/src/board/system76/galp5/gpio.c @@ -0,0 +1,291 @@ +// SPDX-License-Identifier: GPL-3.0-only + +#include +#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); // renamed to EC_ERST# +struct Gpio __code CCD_EN = GPIO(D, 1); +struct Gpio __code CPU_C10_GATE_N = GPIO(D, 3); +struct Gpio __code DD_ON = GPIO(E, 4); +struct Gpio __code DGPU_PWR_EN = GPIO(H, 4); +struct Gpio __code EC_EN = GPIO(B, 6); // renamed to SUSBC_EN +struct Gpio __code EC_RSMRST_N = GPIO(E, 5); +struct Gpio __code GC6_FB_EN = GPIO(J, 3); +struct Gpio __code LAN_WAKEUP_N = GPIO(B, 2); +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 PCH_DPWROK_EC = GPIO(C, 5); +struct Gpio __code PCH_PWROK_EC = GPIO(A, 6); +struct Gpio __code PM_CLKRUN_N = GPIO(H, 0); +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 SLP_S0_N = GPIO(A, 5); +struct Gpio __code SLP_SUS_N = GPIO(J, 7); +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 USB_PWR_EN_N = GPIO(E, 3); +struct Gpio __code VA_EC_EN = GPIO(J, 4); +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 = BIT(4); + // Set GPD2 to 1.8V + GCR19 = BIT(0); + // Set GPF2 and GPF3 to 3.3V + GCR20 = 0; + // Set GPH0 to 1.8V + GCR21 = BIT(2); + + // Set GPIO data + GPDRA = 0; + // XLP_OUT, PWR_SW# + GPDRB = BIT(4) | BIT(3); + // PCH_DPWROK_EC + GPDRC = BIT(5); + // PWR_BTN#, SMI# + GPDRD = BIT(5) | BIT(4); + GPDRE = 0; + // H_PECI + GPDRF = BIT(6); + // H_PROCHOT_EC + GPDRG = BIT(6); + GPDRH = 0; + GPDRI = 0; + // KBC_MUTE# + GPDRJ = BIT(1); + GPDRM = 0; + + // Set GPIO control + // ME_WE + GPCRA0 = GPIO_OUT; + // KBC_BEEP + GPCRA1 = GPIO_ALT; + // CPU_FAN + GPCRA2 = GPIO_ALT; + // WLAN_PWR_EN + GPCRA3 = GPIO_OUT | GPIO_UP; + // VGA_FAN + GPCRA4 = GPIO_ALT; + // SLP_S0# + GPCRA5 = GPIO_IN | GPIO_DOWN; + // PCH_PWROK_EC + GPCRA6 = GPIO_OUT | GPIO_UP; + // PCH_SLP_WLAN#_R + GPCRA7 = GPIO_IN; + // AC_IN# + GPCRB0 = GPIO_IN | GPIO_UP; + // LID_SW# + GPCRB1 = GPIO_IN | GPIO_UP; + // EC_LAN_WAKEUP# + GPCRB2 = GPIO_IN | GPIO_UP; + // PWR_SW# + GPCRB3 = GPIO_IN; + // XLP_OUT + GPCRB4 = GPIO_OUT; + // SWI# + GPCRB5 = GPIO_OUT | GPIO_UP; + // SUSBC_EC + GPCRB6 = GPIO_OUT | GPIO_UP; + // N/A + GPCRB7 = GPIO_IN; + // ALL_SYS_PWRGD + GPCRC0 = GPIO_IN; + // SMC_VGA_THERM + GPCRC1 = GPIO_ALT | GPIO_UP; + // SMD_VGA_THERM + GPCRC2 = GPIO_ALT | GPIO_UP; + // SINK_CTRL_EC + GPCRC3 = GPIO_IN; + // CNVI_DET# + GPCRC4 = GPIO_IN | GPIO_UP; + // PCH_DPWROK_EC + GPCRC5 = GPIO_OUT | GPIO_UP; + // 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; + // EC_ERST# + GPCRD2 = GPIO_ALT; + // CPU_C10_GATE# + GPCRD3 = GPIO_IN | GPIO_DOWN; + // 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 | GPIO_UP; + // AC_PRESENT + GPCRE1 = GPIO_OUT | GPIO_UP; + // KB-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_IN; + // SMD_BAT + GPCRE7 = GPIO_ALT | GPIO_UP; + // 80CLK + GPCRF0 = GPIO_IN | GPIO_UP; + // 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 | GPIO_UP; + // TP_DATA + GPCRF5 = GPIO_ALT | GPIO_UP; + // H_PECI + GPCRF6 = GPIO_ALT; + // CC_EN: TODO! + GPCRF7 = GPIO_IN | GPIO_UP; + // dGPU_GPIO8_OVERT + GPCRG0 = GPIO_IN; + // WLAN_EN + GPCRG1 = GPIO_OUT | GPIO_UP; + // 10K pull-up + 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_IN; + // SUSC#_PCH + GPCRH1 = GPIO_IN; + // BKL_EN + GPCRH2 = GPIO_OUT | GPIO_UP; + // PCIE_WAKE# + GPCRH3 = GPIO_IN; + // DGPU_PWR_EN + GPCRH4 = GPIO_IN; + // LED_BAT_CHG + GPCRH5 = GPIO_OUT | GPIO_UP; + // SUSB#_PCH + GPCRH6 = GPIO_IN; + // d_GPIO9_ALERT_FAN + GPCRH7 = GPIO_IN; + // BAT_DET + GPCRI0 = GPIO_ALT; + // BAT_VOLT + GPCRI1 = GPIO_ALT; + // THERM_VOLT2 + GPCRI2 = GPIO_ALT; + // THERM_VOLT + GPCRI3 = GPIO_ALT; + // TOTAL_CUR + GPCRI4 = GPIO_ALT; + // ASM1543_CC1 + GPCRI5 = GPIO_ALT; + // ASM1543_CC2 + GPCRI6 = GPIO_ALT; + // MODEL_ID + GPCRI7 = GPIO_IN; + // LED_BAT_FULL + GPCRJ0 = GPIO_OUT | GPIO_UP; + // KBC_MUTE# + GPCRJ1 = GPIO_OUT; + // KBLIGHT_ADJ + GPCRJ2 = GPIO_ALT; + // GC6_FB_EN + GPCRJ3 = GPIO_IN; + // VA_EC_EN + GPCRJ4 = GPIO_OUT; + // VBATT_BOOST# + GPCRJ5 = GPIO_IN; + // EC_GPIO + GPCRJ6 = GPIO_OUT | GPIO_UP; + // SLP_SUS# + GPCRJ7 = GPIO_IN; + // ESPI_IO0_EC + GPCRM0 = GPIO_ALT; + // ESPI_IO1_EC + GPCRM1 = GPIO_ALT; + // ESPI_IO2_EC + GPCRM2 = GPIO_ALT; + // ESPI_IO3_EC + GPCRM3 = GPIO_ALT; + // ESPI_CLK_EC + GPCRM4 = GPIO_ALT; + // ESPI_CS_EC# + GPCRM5 = GPIO_ALT; + // ALERT# + GPCRM6 = GPIO_IN | GPIO_UP; +} + +#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: data %d mirror %d pot %d control %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); + #define GPOTM 0 + bank(M); + #undef GPOTM + #undef bank +} +#endif diff --git a/src/board/system76/galp5/include/board/espi.h b/src/board/system76/galp5/include/board/espi.h new file mode 100644 index 0000000..abc101a --- /dev/null +++ b/src/board/system76/galp5/include/board/espi.h @@ -0,0 +1,10 @@ +#ifndef _BOARD_ESPI_H +#define _BOARD_ESPI_H + +#include + +void espi_init(void); +void espi_reset(void); +void espi_event(void); + +#endif // _BOARD_ESPI_H diff --git a/src/board/system76/galp5/include/board/gpio.h b/src/board/system76/galp5/include/board/gpio.h new file mode 100644 index 0000000..0a8d0c2 --- /dev/null +++ b/src/board/system76/galp5/include/board/gpio.h @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-3.0-only + +#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 CPU_C10_GATE_N; +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 GC6_FB_EN; +extern struct Gpio __code LAN_WAKEUP_N; +extern struct Gpio __code LED_ACIN; +#define HAVE_LED_AIRPLANE_N 0 +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; +extern struct Gpio __code PCH_DPWROK_EC; +extern struct Gpio __code PCH_PWROK_EC; +extern struct Gpio __code PM_CLKRUN_N; +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; +#define HAVE_SCI_N 0 +extern struct Gpio __code SLP_S0_N; +extern struct Gpio __code SLP_SUS_N; +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 USB_PWR_EN_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/galp5/include/board/keymap.h b/src/board/system76/galp5/include/board/keymap.h new file mode 100644 index 0000000..843d1f0 --- /dev/null +++ b/src/board/system76/galp5/include/board/keymap.h @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-3.0-only + +#ifndef _BOARD_KEYMAP_H +#define _BOARD_KEYMAP_H + +// Keymap layers (normal, Fn) +#define KM_LAY 2 +// Keymap output pins +#define KM_OUT 16 +// Keymap input pins +#define KM_IN 8 + +// common/keymap.h requires KM_LAY, KM_OUT, and KM_IN definitions +#include + +// 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, \ + K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \ + K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, \ + K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, \ + K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4B, \ + K50, K51, K52, K53, K54, K55, K56, K57, K58, K59, \ + K60, K61, K62 \ +) { \ + { ___, ___, ___, ___, ___, ___, K52, ___ }, \ + { ___, ___, ___, ___, ___, ___, K50, K56 }, \ + { ___, ___, ___, ___, ___, ___, K53, K55 }, \ + { ___, ___, ___, ___, ___, ___, K40, K4B }, \ + { K42, K41, K30, K31, K20, ___, K54, K21 }, \ + { K44, K43, ___, K33, ___, ___, ___, K23 }, \ + { K51, K45, K34, K35, K24, K25, ___, ___ }, \ + { ___, K46, K36, K26, K12, K11, K10, K00 }, \ + { K28, K47, K27, K15, K14, K13, K02, K01 }, \ + { K22, K37, K38, ___, K17, K16, K04, K03 }, \ + { K32, K48, K39, K29, K19, K18, K06, K05 }, \ + { ___, K58, K49, K3A, K2A, K1A, K08, K07 }, \ + { ___, ___, K4A, K3B, K2B, K1B, K0A, K09 }, \ + { ___, ___, K0D, K2C, K1C, K62, K0E, K0B }, \ + { ___, K2D, K60, K1D, K57, K0F, ___, K0G }, \ + { ___, ___, K3C, ___, K61, K0C, ___, K59 } \ +} + +// Position of physical Esc key in the matrix +#define MATRIX_ESC_INPUT 7 +#define MATRIX_ESC_OUTPUT 7 + +// Position of physical Fn key in the matrix +#define MATRIX_FN_INPUT 0 +#define MATRIX_FN_OUTPUT 6 + +#endif // _BOARD_KEYMAP_H diff --git a/src/board/system76/galp5/kbled.c b/src/board/system76/galp5/kbled.c new file mode 100644 index 0000000..1ef92d1 --- /dev/null +++ b/src/board/system76/galp5/kbled.c @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-3.0-only + +#include +#include +#include + +#define KBLED_DAC 2 +#define KBLED_DACDAT DACDAT2 + +static uint8_t __code levels[] = { + 0x00, + 0x80, + 0x90, + 0xA8, + 0xC0, + 0xFF +}; + +void kbled_init(void) { + // Enable DAC used for KBLIGHT_ADJ + DACPDREG &= ~(1 << KBLED_DAC); + kbled_reset(); +} + +void kbled_reset(void) { + kbled_set(0); +} + +uint8_t kbled_get(void) { + uint8_t level; + uint8_t raw = KBLED_DACDAT; + for (level = 0; level < ARRAY_SIZE(levels); level++) { + if (raw <= levels[level]) { + return level; + } + } + return 0; +} + +void kbled_set(uint8_t level) { + uint8_t raw = 0; + if (level < ARRAY_SIZE(levels)) { + raw = levels[level]; + } + KBLED_DACDAT = raw; +} + +void kbled_set_color(uint32_t color) { /*Fix unused variable*/ color = color; } diff --git a/src/board/system76/galp5/keymap/default.c b/src/board/system76/galp5/keymap/default.c new file mode 100644 index 0000000..9381d95 --- /dev/null +++ b/src/board/system76/galp5/keymap/default.c @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-3.0-only + +// 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_HOME, K_END, K_PRINT_SCREEN, K_DEL, + 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_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_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_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_LEFT_CTRL, KT_FN, K_LEFT_SUPER, K_LEFT_ALT, K_SPACE, K_RIGHT_ALT, K_RIGHT_CTRL, K_PGUP, K_UP, K_PGDN, + K_LEFT, K_DOWN, K_RIGHT +), +LAYOUT( + K_ESC, K_TOUCHPAD, K_DISPLAY_TOGGLE, K_MUTE, K_KBD_BKL, K_VOLUME_DOWN, K_VOLUME_UP, K_DISPLAY_MODE, K_BRIGHTNESS_DOWN, K_BRIGHTNESS_UP, K_CAMERA_TOGGLE, K_AIRPLANE_MODE, K_SUSPEND, K_HOME, K_END, K_PRINT_SCREEN, K_DEL, + K_PLAY_PAUSE, K_FAN_TOGGLE, 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_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_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_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_LEFT_CTRL, KT_FN, K_LEFT_SUPER, K_LEFT_ALT, K_SPACE, K_RIGHT_ALT, K_APP, K_PGUP, K_UP, K_PGDN, + K_LEFT, K_DOWN, K_RIGHT +) +}; diff --git a/src/board/system76/galp5/keymap/jeremy.c b/src/board/system76/galp5/keymap/jeremy.c new file mode 100644 index 0000000..f1a390f --- /dev/null +++ b/src/board/system76/galp5/keymap/jeremy.c @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-3.0-only + +// Jeremy's 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_HOME, K_END, K_PRINT_SCREEN, K_DEL, + 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_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, + 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_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_LEFT_CTRL, KT_FN, K_LEFT_ALT, K_LEFT_SUPER, K_SPACE, K_RIGHT_ALT, K_RIGHT_CTRL, K_PGUP, K_UP, K_PGDN, + K_LEFT, K_DOWN, K_RIGHT +), +LAYOUT( + K_ESC, K_TOUCHPAD, K_DISPLAY_TOGGLE, K_MUTE, K_KBD_BKL, K_VOLUME_DOWN, K_VOLUME_UP, K_DISPLAY_MODE, K_BRIGHTNESS_DOWN, K_BRIGHTNESS_UP, K_CAMERA_TOGGLE, K_AIRPLANE_MODE, K_SUSPEND, K_HOME, K_END, K_PRINT_SCREEN, K_DEL, + K_PLAY_PAUSE, K_FAN_TOGGLE, 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_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, + 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_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_LEFT_CTRL, KT_FN, K_LEFT_ALT, K_LEFT_SUPER, K_ESC, K_RIGHT_ALT, K_APP, K_PGUP, K_UP, K_PGDN, + K_LEFT, K_DOWN, K_RIGHT +) +};