Skip to content
Open
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
2 changes: 1 addition & 1 deletion configs/config.protectli_vp46xx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v1.2.1-rc4"
CONFIG_LOCALVERSION="v1.2.1-rc5"
CONFIG_OPTION_BACKEND_NONE=y
CONFIG_VENDOR_PROTECTLI=y
CONFIG_ONBOARD_VGA_IS_PRIMARY=y
Expand Down
2 changes: 1 addition & 1 deletion configs/config.protectli_vp46xx_no_emmc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
CONFIG_LOCALVERSION="v1.2.1-rc4"
CONFIG_LOCALVERSION="v1.2.1-rc5"
CONFIG_OPTION_BACKEND_NONE=y
CONFIG_VENDOR_PROTECTLI=y
CONFIG_ONBOARD_VGA_IS_PRIMARY=y
Expand Down
12 changes: 12 additions & 0 deletions src/mainboard/protectli/vault_cml/bootblock.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <bootblock_common.h>
#include <device/pnp_ops.h>
#include <soc/gpio.h>
#include <superio/ite/common/ite.h>
#include <superio/ite/common/ite_gpio.h>
#include <superio/ite/it8784e/it8784e.h>
#include "gpio.h"

#define UART_DEV PNP_DEV(0x2e, IT8784E_SP1)
#define GPIO_DEV PNP_DEV(0x2e, IT8784E_GPIO)

static void ite_set_gpio_iobase(u16 iobase)
{
pnp_enter_conf_state(GPIO_DEV);
pnp_set_logical_device(GPIO_DEV);
pnp_set_iobase(GPIO_DEV, PNP_IDX_IO1, iobase);
pnp_exit_conf_state(GPIO_DEV);
}

void bootblock_mainboard_early_init(void)
{
/* CLKIN freq 24MHz, Ext CLKIN for Watchdog, Internal VCC_OK */
Expand All @@ -25,6 +35,8 @@ void bootblock_mainboard_early_init(void)
ite_delay_pwrgd3(GPIO_DEV);
ite_kill_watchdog(GPIO_DEV);
ite_enable_serial(UART_DEV, CONFIG_TTYS0_BASE);
ite_gpio_setup(GPIO_DEV, 80, ITE_GPIO_INPUT, ITE_GPIO_SIMPLE_IO_MODE, ITE_GPIO_PULLUP_ENABLE);
ite_set_gpio_iobase(0xa00);
}

void bootblock_mainboard_init(void)
Expand Down
4 changes: 3 additions & 1 deletion src/mainboard/protectli/vault_cml/devicetree.cb
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,9 @@ chip soc/intel/cannonlake
end
device pnp 2e.5 off end # Keyboard
device pnp 2e.6 off end # Mouse
device pnp 2e.7 off end # GPIO
device pnp 2e.7 on
io 0x62 = 0xa00
end # GPIO
device pnp 2e.a off end # CIR
end
chip drivers/pc80/tpm
Expand Down
7 changes: 7 additions & 0 deletions src/superio/ite/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@
bootblock-$(CONFIG_SUPERIO_ITE_COMMON_PRE_RAM) += common/early_serial.c
romstage-$(CONFIG_SUPERIO_ITE_COMMON_PRE_RAM) += common/early_serial.c

bootblock-$(CONFIG_SUPERIO_ITE_COMMON_GPIO_PRE_RAM) += common/gpio.c
romstage-$(CONFIG_SUPERIO_ITE_COMMON_GPIO_PRE_RAM) += common/gpio.c

## include generic ite environment controller driver
ramstage-$(CONFIG_SUPERIO_ITE_ENV_CTRL) += common/env_ctrl.c

## include generic ite driver to smm to control S3-relevant functions
smm-$(CONFIG_SUPERIO_ITE_COMMON_PRE_RAM) += common/early_serial.c
smm-$(CONFIG_SUPERIO_ITE_COMMON_GPIO_PRE_RAM) += common/gpio.c

subdirs-y += it8528e
subdirs-y += it8613e
subdirs-y += it8623e
Expand Down
27 changes: 27 additions & 0 deletions src/superio/ite/common/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,33 @@
config SUPERIO_ITE_COMMON_PRE_RAM
bool

config SUPERIO_ITE_COMMON_GPIO_PRE_RAM
bool
help
Enable generic pre-ram driver for configuring ITE SIO GPIOs.
It applies only to ITE SIOs not ITE ECs using LDN 7 (typically)
to configure GPIO Simple I/O mode.

if SUPERIO_ITE_COMMON_GPIO_PRE_RAM

config SUPERIO_ITE_COMMON_NUM_GPIO_SETS
int
help
The maximum number of GPIO sets supported by ITE SIO chip.
Each SIO chip must set this config option to a proper values
if it intends to enable SUPERIO_ITE_COMMON_GPIO_PRE_RAM.

config SUPERIO_ITE_COMMON_GPIO_LED_FREQ_5BIT
bool
default n
help
Selected ITE SIOs control the GPIO LED frequency using 5 bits
instead of two. The LED register layout is also different for
these chips. Select this if the SIO GP LED Frequency control
field has 5 bits and support duty cycle as well.

endif

# Generic ITE environment controller driver
config SUPERIO_ITE_ENV_CTRL
bool
Expand Down
191 changes: 191 additions & 0 deletions src/superio/ite/common/gpio.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <device/pnp_ops.h>
#include <device/pnp.h>
#include <stdint.h>

#include "ite.h"
#include "ite_gpio.h"

/* Catch ITE SIOs that enable the driver but do not configure the number of sets */
#if CONFIG_SUPERIO_ITE_COMMON_NUM_GPIO_SETS == 0
#error "Maximum number of ITE SIO GPIO sets not provided"
#endif

#if CONFIG_SUPERIO_ITE_COMMON_NUM_GPIO_SETS > 10
#error "ITE SIO GPIO drivers only support up to 10 GPIO sets"
#endif

/* GPIO Polarity Select: 1: Inverting, 0: Non-inverting */
#define ITE_GPIO_REG_POLARITY(x) \
(((x) > 8) ? (0xd1 + ((x) - 9) * 5) \
: (0xb0 + ((x) - 1)) \
)

/* GPIO Internal Pull-up: 1: Enable, 0: Disable */
#define ITE_GPIO_REG_PULLUP(x) \
(((x) > 8) ? (0xd4 + ((x) - 9) * 5) \
: (0xb8 + ((x) - 1)) \
)

/* GPIO Function Select: 1: Simple I/O, 0: Alternate function */
#define ITE_GPIO_REG_FN_SELECT(x) \
(((x) > 8) ? (0xd3 + ((x) - 9) * 5) \
: (0xc0 + ((x) - 1)) \
)

/* GPIO Mode: 0: input mode, 1: output mode */
#define ITE_GPIO_REG_OUTPUT(x) \
(((x) > 8) ? (0xd2 + ((x) - 9) * 5) \
: (0xc8 + ((x) - 1)) \
)

/* GPIO LED pin mapping register */
#define ITE_GPIO_REG_LED_PINMAP(x) (0xf8 + ((x) & 1) * 2)
#define ITE_GPIO_LED_PIN_LOC(set, pin) ((((set) & 7) << 3) | ((pin) & 7))
#define ITE_GPIO_LED_PIN_LOC_MASK 0x3f
/* GPIO LED control register */
#define ITE_GPIO_REG_LED_CONTROL(x) (0xf9 + ((x) & 1) * 2)
#define ITE_GPIO_LED_OUTPUT_LOW (1 << 0)
#define ITE_GPIO_LED_PINMAP_CLEAR (1 << 4)
#define ITE_GPIO_LED_SHORT_LOW_PULSE \
(CONFIG(SUPERIO_ITE_COMMON_GPIO_LED_FREQ_5BIT) ? (1 << 5) \
: (1 << 3) \
)
#define ITE_GPIO_LED_FREQ_SEL(x) \
(CONFIG(SUPERIO_ITE_COMMON_GPIO_LED_FREQ_5BIT) \
? ((((x) & 0x18) << 3) | (((x) & 0x7) << 1)) \
: (((x) & 0x3) << 1) \
)
#define ITE_GPIO_LED_FREQ_SEL_MASK \
(CONFIG(SUPERIO_ITE_COMMON_GPIO_LED_FREQ_5BIT) ? 0xce : 0x06)

static bool ite_has_gpio_fn_select_reg(u8 set)
{
/* IT8718F has all registers for all sets. */
if (CONFIG(SUPERIO_ITE_IT8718F))
return true;

/* Typically ITE GPIO sets 6 to 8 don't have enable and polarity registers. */
if (set < 6 || set > 8)
return true;

return false;
}

static bool ite_has_gpio_polarity_reg(u8 set)
{
/* IT8718F has all registers for all sets. */
if (CONFIG(SUPERIO_ITE_IT8718F))
return true;

/* IT8720F/IT8721F has polarity register for all GPIO sets */
if (CONFIG(SUPERIO_ITE_IT8720F) || CONFIG(SUPERIO_ITE_IT8721F))
return true;

/* Typically ITE GPIO sets 6 to 8 don't have enable and polarity registers. */
if (set < 6 || set > 8)
return true;

return false;
}

static bool ite_has_gpio_pullup_reg(u8 set)
{
/* IT8718F/IT8720F does not have pull-up register for set 2 */
if ((CONFIG(SUPERIO_ITE_IT8718F) || CONFIG(SUPERIO_ITE_IT8720F)) && (set == 2))
return false;

/* IT8783E/F does not have pull-up register for set 6 */
if (CONFIG(SUPERIO_ITE_IT8783EF) && (set == 6))
return false;

/*
* ITE GPIO Sets 7 and 8 don't have a pullup register.
* See IT8786/IT8625 datasheet section 8.10.10.
* Also applies to IT8728F.
*/
if (set != 7 && set != 8)
return true;

return false;
}

/*
* Configures a single GPIO given its number as gpio_num, direction ("in_out"
* parameter) and properties, such as polarity and pull ("gpio_ctrl"
* parameter). The "enable" parameter can configure the GPIO in Simple I/O
* mode when set or Alternate function mode when clear. Some chips may also
* not support configuring all properties for a particular GPIO. It is left to
* the implementer to check if GPIO settings are valid for given gpio_num.
*/
void ite_gpio_setup(pnp_devfn_t gpiodev, u8 gpio_num, enum ite_gpio_direction in_out,
enum ite_gpio_mode enable, u8 gpio_ctrl)
{
u8 set = (gpio_num / 10);
u8 pin = (gpio_num % 10);

/* Number of configurable sets is chip dependent, 8 pins each */
if (gpio_num < 10 || set > CONFIG_SUPERIO_ITE_COMMON_NUM_GPIO_SETS || pin > 7)
return;

pnp_enter_conf_state(gpiodev);
pnp_set_logical_device(gpiodev);

if (ite_has_gpio_fn_select_reg(set))
pnp_unset_and_set_config(gpiodev, ITE_GPIO_REG_FN_SELECT(set),
1 << pin, (enable & 1) << pin);

if (ite_has_gpio_polarity_reg(set))
pnp_unset_and_set_config(gpiodev, ITE_GPIO_REG_POLARITY(set),
1 << pin,
(gpio_ctrl & ITE_GPIO_POL_INVERT) ? 1 << pin : 0);


pnp_unset_and_set_config(gpiodev, ITE_GPIO_REG_OUTPUT(set), 1 << pin, (in_out & 1) << pin);

if (ite_has_gpio_pullup_reg(set))
pnp_unset_and_set_config(gpiodev, ITE_GPIO_REG_PULLUP(set), 1 << pin,
(gpio_ctrl & ITE_GPIO_PULLUP_ENABLE) ? 1 << pin : 0);

pnp_exit_conf_state(gpiodev);
}

void ite_gpio_setup_led(pnp_devfn_t gpiodev, u8 gpio_num,
enum ite_gpio_led led_no,
enum ite_led_frequency freq,
u8 led_ctrl)
{
u8 set = (gpio_num / 10);
u8 pin = (gpio_num % 10);
u8 reg = 0;

/* Number of configurable sets is chip dependent, 8 pins each */
if (gpio_num < 10 || set > CONFIG_SUPERIO_ITE_COMMON_NUM_GPIO_SETS || pin > 7)
return;

/* LED is available only for GPIO sets 1-5 */
if (set > 5)
return;

pnp_enter_conf_state(gpiodev);
pnp_set_logical_device(gpiodev);

/* Pinmap clear bit is only available when frequency is controlled with 5 bits */
if (CONFIG(SUPERIO_ITE_COMMON_GPIO_LED_FREQ_5BIT) && (led_ctrl & ITE_LED_PINMAP_CLEAR))
reg |= ITE_GPIO_LED_PINMAP_CLEAR;

if (led_ctrl & ITE_LED_OUTPUT_LOW)
reg |= ITE_GPIO_LED_OUTPUT_LOW;

if (led_ctrl & ITE_LED_SHORT_LOW_PULSE)
reg |= ITE_GPIO_LED_SHORT_LOW_PULSE;

reg |= ITE_GPIO_LED_FREQ_SEL(freq);
pnp_write_config(gpiodev, ITE_GPIO_REG_LED_CONTROL(led_no), reg);

reg = ITE_GPIO_LED_PIN_LOC(set, pin);
pnp_write_config(gpiodev, ITE_GPIO_REG_LED_PINMAP(led_no), reg);

pnp_exit_conf_state(gpiodev);
}
75 changes: 75 additions & 0 deletions src/superio/ite/common/ite_gpio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */

#ifndef SUPERIO_ITE_COMMON_GPIO_PRE_RAM_H
#define SUPERIO_ITE_COMMON_GPIO_PRE_RAM_H

#include <device/pnp_type.h>
#include <stdint.h>

#define ITE_GPIO_REG_SELECT(x) (0x25 + (x))

enum ite_gpio_control {
ITE_GPIO_CONTROL_DEFAULT = 0,
ITE_GPIO_POL_INVERT = (1 << 0),
ITE_GPIO_PULLUP_ENABLE = (1 << 1),
};

enum ite_gpio_direction {
ITE_GPIO_INPUT,
ITE_GPIO_OUTPUT
};

enum ite_gpio_mode {
ITE_GPIO_ALT_FN_MODE,
ITE_GPIO_SIMPLE_IO_MODE
};

/* There are two GP LED blink register sets */
enum ite_gpio_led {
ITE_GPIO_LED_1,
ITE_GPIO_LED_2
};

enum ite_led_control {
ITE_LED_CONTROL_DEFAULT = 0,
ITE_LED_SHORT_LOW_PULSE = (1 << 0),
ITE_LED_OUTPUT_LOW = (1 << 1),
/*
* Only for ITE SIOs with 5-bit frequency selection.
* When enabled, the LED pin mapping register is cleared when PANSWH# is low for over 4s.
*/
ITE_LED_PINMAP_CLEAR = (1 << 2),
};

enum ite_led_frequency {
/* Most ITE SIOs have 2-bit frequency selection */
ITE_LED_FREQ_4HZ = 0,
ITE_LED_FREQ_1HZ = 1,
ITE_LED_FREQ_0P25HZ = 2,
ITE_LED_FREQ_0P125HZ = 3,
/* ITE SIOs with 5-bit frequency selection: IT8625, IT8613 */
ITE_LED_FREQ_4HZ_DUTY_50 = 0,
ITE_LED_FREQ_1HZ_DUTY_50 = 1,
ITE_LED_FREQ_0P25HZ_DUTY_50 = 2,
ITE_LED_FREQ_2HZ_DUTY_50 = 3,
ITE_LED_FREQ_0P25HZ_DUTY_25 = 4,
ITE_LED_FREQ_0P25HZ_DUTY_75 = 5,
ITE_LED_FREQ_0P125HZ_DUTY_25 = 6,
ITE_LED_FREQ_0P125HZ_DUTY_75 = 7,
ITE_LED_FREQ_0P4HZ_DUTY_20 = 8,
ITE_LED_FREQ_0P5HZ_DUTY_50 = 16,
ITE_LED_FREQ_0P125HZ_DUTY_50 = 24,
};

void ite_gpio_setup(pnp_devfn_t gpiodev, u8 gpio_num,
enum ite_gpio_direction output,
enum ite_gpio_mode enable,
u8 gpio_ctrl);

void ite_gpio_setup_led(pnp_devfn_t gpiodev, u8 gpio_num,
enum ite_gpio_led led_no,
enum ite_led_frequency freq,
u8 led_ctrl);


#endif /* SUPERIO_ITE_COMMON_PRE_RAM_H */
Copy link
Copy Markdown
Member

@filipleple filipleple May 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#endif /* SUPERIO_ITE_COMMON_PRE_RAM_H */
#endif /* SUPERIO_ITE_COMMON_GPIO_PRE_RAM_H */

not a dealbreaker but might confuse someone, sometime

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a cherry pick, I'm not sure I should touch that or it will become a merge conflict

8 changes: 8 additions & 0 deletions src/superio/ite/it8784e/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@
config SUPERIO_ITE_IT8784E
bool
select SUPERIO_ITE_COMMON_PRE_RAM
select SUPERIO_ITE_COMMON_GPIO_PRE_RAM
select SUPERIO_ITE_ENV_CTRL
select SUPERIO_ITE_ENV_CTRL_PWM_FREQ2
select SUPERIO_ITE_ENV_CTRL_8BIT_PWM
select SUPERIO_ITE_ENV_CTRL_7BIT_SLOPE_REG
select SUPERIO_ITE_ENV_CTRL_EXT_ANY_TMPIN

if SUPERIO_ITE_IT8784E

config SUPERIO_ITE_COMMON_NUM_GPIO_SETS
default 10

endif