ec/starlabs/merlin: persist settings via EFI options

When STARLABS_ACPI_EFI_OPTION_SMI is enabled, store and restore
trackpad and keyboard backlight state across S4/S5 using the EFI
variable store SMI bridge instead of CMOS.

Also make the EC init paths treat CMOS as an index mapping and
prefer the option backend when CMOS options are not in use.

Signed-off-by: Sean Rhodes <sean@starlabs.systems>
Change-Id: Ia31ac0440eba1334be48030ce7fe03dc84193ac3
Reviewed-on: https://review.coreboot.org/c/coreboot/+/91304
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Sean Rhodes 2026-02-16 21:32:24 +00:00
commit 9dac2b9e53
3 changed files with 246 additions and 243 deletions

View file

@ -1,8 +1,75 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#if CONFIG(STARLABS_ACPI_EFI_OPTION_SMI)
Field (\DNVS, ByteAcc, NoLock, Preserve)
{
EOCM, 32, // EFI option command
EOID, 32, // EFI option ID
EOVL, 32, // EFI option value
EORS, 32, // EFI option status
}
Name (EOAP, 0xE2) // STARLABS_APMC_CMD_EFI_OPTION
Name (EOFL, 0x1) // STARLABS_EFIOPT_ID_FN_LOCK_STATE
Name (EOTP, 0x2) // STARLABS_EFIOPT_ID_TRACKPAD_STATE
Name (EOKB, 0x3) // STARLABS_EFIOPT_ID_KBL_BRIGHTNESS
Name (EOKS, 0x4) // STARLABS_EFIOPT_ID_KBL_STATE
Mutex (EOMX, 0x00)
Method (EOGT, 1, Serialized)
{
If (Acquire (EOMX, 1000))
{
Return (0xFFFFFFFF)
}
Store (0x01, EOCM)
Store (Arg0, EOID)
Store (0x00, EORS)
Store (EOAP, \_SB.PCI0.LPCB.EC.SMB2)
Store (EOVL, Local0)
Release (EOMX)
Return (Local0)
}
Method (EOSV, 2, Serialized)
{
If (Acquire (EOMX, 1000))
{
Return (0x01)
}
Store (0x02, EOCM)
Store (Arg0, EOID)
Store (Arg1, EOVL)
Store (0x00, EORS)
Store (EOAP, \_SB.PCI0.LPCB.EC.SMB2)
Store (EORS, Local0)
Release (EOMX)
Return (Local0)
}
#endif
Method (RPTS, 1, Serialized)
{
#if CONFIG(STARLABS_ACPI_EFI_OPTION_SMI)
/* Store current EC settings in UEFI variable store */
Store (\_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.TPLE)), Local0)
If (Local0 == 0x11)
{
Store (0x00, Local0)
}
EOSV (EOTP, Local0)
EOSV (EOFL, \_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.FLKE)))
EOSV (EOKS, \_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.KLSE)))
EOSV (EOKB, \_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.KLBE)))
#else
/* Store current EC settings in CMOS */
Switch (ToInteger (\_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.TPLE))))
{
@ -11,20 +78,19 @@ Method (RPTS, 1, Serialized)
// 0x22 == Disabled == 0x01
Case (0x00)
{
\_SB.PCI0.LPCB.TPLC = 0x00
Store (0x00, \_SB.PCI0.LPCB.TPLC)
}
Case (0x11)
{
\_SB.PCI0.LPCB.TPLC = 0x00
Store (0x00, \_SB.PCI0.LPCB.TPLC)
}
Case (0x22)
{
\_SB.PCI0.LPCB.TPLC = 0x01
Store (0x01, \_SB.PCI0.LPCB.TPLC)
}
}
\_SB.PCI0.LPCB.FLKC =
\_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.FLKE))
Store (\_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.FLKE)), \_SB.PCI0.LPCB.FLKC)
Switch (ToInteger (\_SB.PCI0.LPCB.EC.ECRD (RefOf (\_SB.PCI0.LPCB.EC.KLSE))))
{
@ -32,11 +98,11 @@ Method (RPTS, 1, Serialized)
// 0xdd == Enabled == 0x01
Case (0x00)
{
\_SB.PCI0.LPCB.KLSC = 0x00
Store (0x00, \_SB.PCI0.LPCB.KLSC)
}
Case (0xdd)
{
\_SB.PCI0.LPCB.KLSC = 0x01
Store (0x01, \_SB.PCI0.LPCB.KLSC)
}
}
@ -48,27 +114,30 @@ Method (RPTS, 1, Serialized)
// 0xaa == High == 0x03
Case (0xdd)
{
\_SB.PCI0.LPCB.KLBC = 0x00
Store (0x00, \_SB.PCI0.LPCB.KLBC)
}
Case (0xcc)
{
\_SB.PCI0.LPCB.KLBC = 0x01
Store (0x01, \_SB.PCI0.LPCB.KLBC)
}
Case (0xbb)
{
\_SB.PCI0.LPCB.KLBC = 0x02
Store (0x02, \_SB.PCI0.LPCB.KLBC)
}
Case (0xaa)
{
\_SB.PCI0.LPCB.KLBC = 0x03
Store (0x03, \_SB.PCI0.LPCB.KLBC)
}
}
#endif
/*
* Disable ACPI support.
* This should always be the last action before entering a sleep state.
*/
\_SB.PCI0.LPCB.EC.ECWR(0x00, RefOf(\_SB.PCI0.LPCB.EC.OSFG))
Return (Arg0)
}
Method (RWAK, 1, Serialized)
@ -79,6 +148,51 @@ Method (RWAK, 1, Serialized)
*/
\_SB.PCI0.LPCB.EC.ECWR(0x01, RefOf(\_SB.PCI0.LPCB.EC.OSFG))
#if CONFIG(STARLABS_ACPI_EFI_OPTION_SMI)
/* Restore EC settings from UEFI variable store */
Store (EOGT (EOTP), Local0)
If (Local0 == 0x22)
{
\_SB.PCI0.LPCB.EC.ECWR (0x22, RefOf(\_SB.PCI0.LPCB.EC.TPLE))
}
Else
{
\_SB.PCI0.LPCB.EC.ECWR (0x00, RefOf(\_SB.PCI0.LPCB.EC.TPLE))
}
\_SB.PCI0.LPCB.EC.ECWR (EOGT (EOFL), RefOf(\_SB.PCI0.LPCB.EC.FLKE))
Store (EOGT (EOKS), Local0)
If (Local0 == 0xdd)
{
\_SB.PCI0.LPCB.EC.ECWR (0xdd, RefOf(\_SB.PCI0.LPCB.EC.KLSE))
}
Else
{
\_SB.PCI0.LPCB.EC.ECWR (0x00, RefOf(\_SB.PCI0.LPCB.EC.KLSE))
}
Store (EOGT (EOKB), Local0)
Switch (ToInteger (Local0))
{
Case (0xdd)
{
\_SB.PCI0.LPCB.EC.ECWR (0xdd, RefOf(\_SB.PCI0.LPCB.EC.KLBE))
}
Case (0xcc)
{
\_SB.PCI0.LPCB.EC.ECWR (0xcc, RefOf(\_SB.PCI0.LPCB.EC.KLBE))
}
Case (0xbb)
{
\_SB.PCI0.LPCB.EC.ECWR (0xbb, RefOf(\_SB.PCI0.LPCB.EC.KLBE))
}
Case (0xaa)
{
\_SB.PCI0.LPCB.EC.ECWR (0xaa, RefOf(\_SB.PCI0.LPCB.EC.KLBE))
}
}
#else
/* Restore EC settings from CMOS */
Switch (ToInteger (\_SB.PCI0.LPCB.TPLC))
{
@ -134,4 +248,7 @@ Method (RWAK, 1, Serialized)
\_SB.PCI0.LPCB.EC.ECWR (0xaa, RefOf(\_SB.PCI0.LPCB.EC.KLBE))
}
}
#endif
Return (Arg0)
}

View file

@ -12,8 +12,8 @@
#include "option_table.h"
#include "ec.h"
#define ITE_IT5570 0x5570
#define ITE_IT8987 0x8987
#define ITE_IT5570 0x5570
#define ITE_IT8987 0x8987
uint16_t ec_get_version(void)
{
@ -25,20 +25,17 @@ static uint8_t get_cmos_value(uint32_t bit, uint32_t length)
uint32_t byte, byte_bit;
uint8_t uchar;
byte = bit / 8; // find the byte where the data starts
byte = bit / 8; // find the byte where the data starts
byte_bit = bit % 8; // find the bit in the byte where the data starts
uchar = cmos_read(byte); // load the byte
uchar >>= byte_bit; // shift the bits to byte align
uchar >>= byte_bit; // shift the bits to byte align
// clear unspecified bits
return uchar & ((1U << length) - 1);
}
static uint8_t get_ec_value_from_option(const char *name,
uint32_t fallback,
const uint8_t *lut,
size_t lut_size,
uint32_t cmos_start_bit,
static uint8_t get_ec_value_from_option(const char *name, uint32_t fallback, const uint8_t *lut,
size_t lut_size, uint32_t cmos_start_bit,
uint32_t cmos_length)
{
/*
@ -69,8 +66,7 @@ static uint8_t get_ec_value_from_option(const char *name,
static uint16_t ec_get_chip_id(unsigned int port)
{
return (pnp_read_index(port, ITE_CHIPID1) << 8) |
pnp_read_index(port, ITE_CHIPID2);
return (pnp_read_index(port, ITE_CHIPID1) << 8) | pnp_read_index(port, ITE_CHIPID2);
}
static void merlin_init(struct device *dev)
@ -122,21 +118,11 @@ static void merlin_init(struct device *dev)
* Default: 30 Seconds
*
*/
const uint8_t kbl_timeout[] = {
SEC_30,
MIN_1,
MIN_3,
MIN_5,
NEVER
};
const uint8_t kbl_timeout[] = {SEC_30, MIN_1, MIN_3, MIN_5, NEVER};
ec_write(ECRAM_KBL_TIMEOUT,
get_ec_value_from_option("kbl_timeout",
SEC_30,
kbl_timeout,
ARRAY_SIZE(kbl_timeout),
UINT_MAX,
UINT_MAX));
get_ec_value_from_option("kbl_timeout", SEC_30, kbl_timeout,
ARRAY_SIZE(kbl_timeout), UINT_MAX, UINT_MAX));
/*
* Fn Ctrl Reverse
@ -147,18 +133,11 @@ static void merlin_init(struct device *dev)
* Default: Disabled
*
*/
const uint8_t fn_ctrl_swap[] = {
FN_CTRL,
CTRL_FN
};
const uint8_t fn_ctrl_swap[] = {FN_CTRL, CTRL_FN};
ec_write(ECRAM_FN_CTRL_REVERSE,
get_ec_value_from_option("fn_ctrl_swap",
FN_CTRL,
fn_ctrl_swap,
ARRAY_SIZE(fn_ctrl_swap),
UINT_MAX,
UINT_MAX));
get_ec_value_from_option("fn_ctrl_swap", FN_CTRL, fn_ctrl_swap,
ARRAY_SIZE(fn_ctrl_swap), UINT_MAX, UINT_MAX));
/*
* Maximum Charge Level
@ -169,20 +148,12 @@ static void merlin_init(struct device *dev)
* Default: 100%
*
*/
const uint8_t max_charge[] = {
CHARGE_100,
CHARGE_80,
CHARGE_60
};
const uint8_t max_charge[] = {CHARGE_100, CHARGE_80, CHARGE_60};
if (CONFIG(EC_STARLABS_MAX_CHARGE))
ec_write(ECRAM_MAX_CHARGE,
get_ec_value_from_option("max_charge",
CHARGE_100,
max_charge,
ARRAY_SIZE(max_charge),
UINT_MAX,
UINT_MAX));
get_ec_value_from_option("max_charge", CHARGE_100, max_charge,
ARRAY_SIZE(max_charge), UINT_MAX, UINT_MAX));
/*
* Fan Mode
@ -193,21 +164,12 @@ static void merlin_init(struct device *dev)
* Default: Normal
*
*/
const uint8_t fan_mode[] = {
FAN_NORMAL,
FAN_AGGRESSIVE,
FAN_QUIET,
FAN_DISABLED
};
const uint8_t fan_mode[] = {FAN_NORMAL, FAN_AGGRESSIVE, FAN_QUIET, FAN_DISABLED};
if (CONFIG(EC_STARLABS_FAN))
ec_write(ECRAM_FAN_MODE,
get_ec_value_from_option("fan_mode",
FAN_NORMAL,
fan_mode,
ARRAY_SIZE(fan_mode),
UINT_MAX,
UINT_MAX));
get_ec_value_from_option("fan_mode", FAN_NORMAL, fan_mode,
ARRAY_SIZE(fan_mode), UINT_MAX, UINT_MAX));
/*
* Function Lock
@ -219,18 +181,13 @@ static void merlin_init(struct device *dev)
*
*/
#ifdef CMOS_VLEN_fn_lock_state
const uint8_t fn_lock_state[] = {
UNLOCKED,
LOCKED
};
const uint8_t fn_lock_state[] = {UNLOCKED, LOCKED};
ec_write(ECRAM_FN_LOCK_STATE,
get_ec_value_from_option("fn_lock_state",
UNLOCKED,
fn_lock_state,
ARRAY_SIZE(fn_lock_state),
CMOS_VSTART_fn_lock_state,
CMOS_VLEN_fn_lock_state));
get_ec_value_from_option(
"fn_lock_state", UNLOCKED, fn_lock_state, ARRAY_SIZE(fn_lock_state),
CONFIG(USE_OPTION_TABLE) ? CMOS_VSTART_fn_lock_state : UINT_MAX,
CONFIG(USE_OPTION_TABLE) ? CMOS_VLEN_fn_lock_state : UINT_MAX));
#endif
/*
@ -243,18 +200,14 @@ static void merlin_init(struct device *dev)
*
*/
#ifdef CMOS_VSTART_trackpad_state
const uint8_t trackpad_state[] = {
TRACKPAD_ENABLED,
TRACKPAD_DISABLED
};
const uint8_t trackpad_state[] = {TRACKPAD_ENABLED, TRACKPAD_DISABLED};
ec_write(ECRAM_TRACKPAD_STATE,
get_ec_value_from_option("trackpad_state",
TRACKPAD_ENABLED,
trackpad_state,
ARRAY_SIZE(trackpad_state),
CMOS_VSTART_trackpad_state,
CMOS_VLEN_trackpad_state));
get_ec_value_from_option(
"trackpad_state", TRACKPAD_ENABLED, trackpad_state,
ARRAY_SIZE(trackpad_state),
CONFIG(USE_OPTION_TABLE) ? CMOS_VSTART_trackpad_state : UINT_MAX,
CONFIG(USE_OPTION_TABLE) ? CMOS_VLEN_trackpad_state : UINT_MAX));
#endif
/*
@ -267,24 +220,19 @@ static void merlin_init(struct device *dev)
*
*/
#ifdef CMOS_VSTART_kbl_brightness
const uint8_t kbl_brightness[] = {
KBL_ON,
KBL_OFF,
KBL_LOW,
KBL_HIGH
};
const uint8_t kbl_brightness[] = {KBL_ON, KBL_OFF, KBL_LOW, KBL_HIGH};
ec_write(ECRAM_KBL_BRIGHTNESS,
get_ec_value_from_option("kbl_brightness",
CONFIG(EC_STARLABS_KBL_LEVELS) ? 2 : 0,
kbl_brightness,
ARRAY_SIZE(kbl_brightness),
CMOS_VSTART_kbl_brightness,
CMOS_VLEN_kbl_brightness));
get_ec_value_from_option(
"kbl_brightness",
CONFIG(USE_OPTION_TABLE) ?
(CONFIG(EC_STARLABS_KBL_LEVELS) ? 2 : 0) :
(CONFIG(EC_STARLABS_KBL_LEVELS) ? KBL_LOW : KBL_ON),
kbl_brightness, ARRAY_SIZE(kbl_brightness),
CONFIG(USE_OPTION_TABLE) ? CMOS_VSTART_kbl_brightness : UINT_MAX,
CONFIG(USE_OPTION_TABLE) ? CMOS_VLEN_kbl_brightness : UINT_MAX));
#endif
/*
* Keyboard Backlight State
*
@ -308,20 +256,13 @@ static void merlin_init(struct device *dev)
* Default: 0.5C
*
*/
const uint8_t charging_speed[] = {
SPEED_1_0C,
SPEED_0_5C,
SPEED_0_2C
};
const uint8_t charging_speed[] = {SPEED_1_0C, SPEED_0_5C, SPEED_0_2C};
if (CONFIG(EC_STARLABS_CHARGING_SPEED))
ec_write(ECRAM_CHARGING_SPEED,
get_ec_value_from_option("charging_speed",
SPEED_0_5C,
charging_speed,
ARRAY_SIZE(charging_speed),
UINT_MAX,
UINT_MAX));
get_ec_value_from_option("charging_speed", SPEED_0_5C, charging_speed,
ARRAY_SIZE(charging_speed), UINT_MAX,
UINT_MAX));
/*
* Lid Switch
@ -332,20 +273,12 @@ static void merlin_init(struct device *dev)
* Default: 0
*
*/
const uint8_t lid_switch[] = {
SWITCH_NORMAL,
SWITCH_SLEEP_ONLY,
SWITCH_DISABLED
};
const uint8_t lid_switch[] = {SWITCH_NORMAL, SWITCH_SLEEP_ONLY, SWITCH_DISABLED};
if (CONFIG(EC_STARLABS_LID_SWITCH))
ec_write(ECRAM_LID_SWITCH,
get_ec_value_from_option("lid_switch",
SWITCH_NORMAL,
lid_switch,
ARRAY_SIZE(lid_switch),
UINT_MAX,
UINT_MAX));
get_ec_value_from_option("lid_switch", SWITCH_NORMAL, lid_switch,
ARRAY_SIZE(lid_switch), UINT_MAX, UINT_MAX));
/*
* Power LED Brightness
@ -356,20 +289,13 @@ static void merlin_init(struct device *dev)
* Default: 0
*
*/
const uint8_t led_brightness[] = {
LED_NORMAL,
LED_REDUCED,
LED_OFF
};
const uint8_t led_brightness[] = {LED_NORMAL, LED_REDUCED, LED_OFF};
if (CONFIG(EC_STARLABS_POWER_LED))
ec_write(ECRAM_POWER_LED,
get_ec_value_from_option("power_led",
LED_NORMAL,
led_brightness,
ARRAY_SIZE(led_brightness),
UINT_MAX,
UINT_MAX));
get_ec_value_from_option("power_led", LED_NORMAL, led_brightness,
ARRAY_SIZE(led_brightness), UINT_MAX,
UINT_MAX));
/*
* Charge LED Brightness
@ -383,18 +309,15 @@ static void merlin_init(struct device *dev)
if (CONFIG(EC_STARLABS_CHARGE_LED))
ec_write(ECRAM_CHARGE_LED,
get_ec_value_from_option("charge_led",
LED_NORMAL,
led_brightness,
ARRAY_SIZE(led_brightness),
UINT_MAX,
UINT_MAX));
get_ec_value_from_option("charge_led", LED_NORMAL, led_brightness,
ARRAY_SIZE(led_brightness), UINT_MAX,
UINT_MAX));
}
static struct device_operations ops = {
.init = merlin_init,
.read_resources = noop_read_resources,
.set_resources = noop_set_resources,
.init = merlin_init,
.read_resources = noop_read_resources,
.set_resources = noop_set_resources,
};
static struct pnp_info pnp_dev_info[] = {

View file

@ -12,7 +12,6 @@
#include "option_table.h"
#include "ec.h"
uint16_t ec_get_version(void)
{
return (ec_read(ECRAM_MAJOR_VERSION) << 8) | ec_read(ECRAM_MINOR_VERSION);
@ -23,32 +22,43 @@ static uint8_t get_cmos_value(uint32_t bit, uint32_t length)
uint32_t byte, byte_bit;
uint8_t uchar;
byte = bit / 8; // find the byte where the data starts
byte = bit / 8; // find the byte where the data starts
byte_bit = bit % 8; // find the bit in the byte where the data starts
uchar = cmos_read(byte); // load the byte
uchar >>= byte_bit; // shift the bits to byte align
uchar >>= byte_bit; // shift the bits to byte align
// clear unspecified bits
return uchar & ((1U << length) - 1);
}
static uint8_t get_ec_value_from_option(const char *name,
uint32_t fallback,
const uint8_t *lut,
size_t lut_size,
uint32_t cmos_start_bit,
static uint8_t get_ec_value_from_option(const char *name, uint32_t fallback, const uint8_t *lut,
size_t lut_size, uint32_t cmos_start_bit,
uint32_t cmos_length)
{
unsigned int index;
/*
* CMOS-backed EC options store an index (see cmos.layout and ACPI
* RPTS/RWAK mappings), while the option backend stores the EC's raw
* values (e.g. 0xaa/0xbb/0xdd).
*/
if (cmos_start_bit != UINT_MAX) {
unsigned int index = get_cmos_value(cmos_start_bit, cmos_length);
if (cmos_start_bit != UINT_MAX)
index = get_cmos_value(cmos_start_bit, cmos_length);
else
index = get_uint_option(name, fallback);
if (index >= lut_size)
index = fallback;
if (index >= lut_size)
index = 0;
if (index >= lut_size)
index = fallback;
return lut[index];
return lut[index];
}
const uint8_t value = get_uint_option(name, fallback);
/* Check if the value exists in the LUT array */
for (size_t i = 0; i < lut_size; i++)
if (lut[i] == value)
return value;
return fallback;
}
static uint16_t ec_get_chip_id(unsigned int port)
@ -77,7 +87,7 @@ static void merlin_init(struct device *dev)
if (chip_id != NUVOTON_CHIPID_VAL) {
printk(BIOS_ERR, "NUVOTON: Expected chip ID 0x%04x, but got 0x%04x instead.\n",
NUVOTON_CHIPID_VAL, chip_id);
NUVOTON_CHIPID_VAL, chip_id);
return;
}
@ -103,21 +113,11 @@ static void merlin_init(struct device *dev)
* Default: 30 Seconds
*
*/
const uint8_t kbl_timeout[] = {
SEC_30,
MIN_1,
MIN_3,
MIN_5,
NEVER
};
const uint8_t kbl_timeout[] = {SEC_30, MIN_1, MIN_3, MIN_5, NEVER};
ec_write(ECRAM_KBL_TIMEOUT,
get_ec_value_from_option("kbl_timeout",
0,
kbl_timeout,
ARRAY_SIZE(kbl_timeout),
UINT_MAX,
UINT_MAX));
get_ec_value_from_option("kbl_timeout", 0, kbl_timeout,
ARRAY_SIZE(kbl_timeout), UINT_MAX, UINT_MAX));
/*
* Fn Ctrl Reverse
@ -128,18 +128,11 @@ static void merlin_init(struct device *dev)
* Default: Disabled
*
*/
const uint8_t fn_ctrl_swap[] = {
FN_CTRL,
CTRL_FN
};
const uint8_t fn_ctrl_swap[] = {FN_CTRL, CTRL_FN};
ec_write(ECRAM_FN_CTRL_REVERSE,
get_ec_value_from_option("fn_ctrl_swap",
0,
fn_ctrl_swap,
ARRAY_SIZE(fn_ctrl_swap),
UINT_MAX,
UINT_MAX));
get_ec_value_from_option("fn_ctrl_swap", 0, fn_ctrl_swap,
ARRAY_SIZE(fn_ctrl_swap), UINT_MAX, UINT_MAX));
/*
* Maximum Charge Level
@ -150,20 +143,12 @@ static void merlin_init(struct device *dev)
* Default: 100%
*
*/
const uint8_t max_charge[] = {
CHARGE_100,
CHARGE_80,
CHARGE_60
};
const uint8_t max_charge[] = {CHARGE_100, CHARGE_80, CHARGE_60};
if (CONFIG(EC_STARLABS_MAX_CHARGE))
ec_write(ECRAM_MAX_CHARGE,
get_ec_value_from_option("max_charge",
0,
max_charge,
ARRAY_SIZE(max_charge),
UINT_MAX,
UINT_MAX));
get_ec_value_from_option("max_charge", 0, max_charge,
ARRAY_SIZE(max_charge), UINT_MAX, UINT_MAX));
/*
* Fan Mode
@ -174,20 +159,12 @@ static void merlin_init(struct device *dev)
* Default: Normal
*
*/
const uint8_t fan_mode[] = {
FAN_NORMAL,
FAN_AGGRESSIVE,
FAN_QUIET
};
const uint8_t fan_mode[] = {FAN_NORMAL, FAN_AGGRESSIVE, FAN_QUIET};
if (CONFIG(EC_STARLABS_FAN))
ec_write(ECRAM_FAN_MODE,
get_ec_value_from_option("fan_mode",
0,
fan_mode,
ARRAY_SIZE(fan_mode),
UINT_MAX,
UINT_MAX));
get_ec_value_from_option("fan_mode", 0, fan_mode, ARRAY_SIZE(fan_mode),
UINT_MAX, UINT_MAX));
/*
* Function Lock
@ -199,18 +176,13 @@ static void merlin_init(struct device *dev)
*
*/
#ifdef CMOS_VLEN_fn_lock_state
const uint8_t fn_lock_state[] = {
UNLOCKED,
LOCKED
};
const uint8_t fn_lock_state[] = {UNLOCKED, LOCKED};
ec_write(ECRAM_FN_LOCK_STATE,
get_ec_value_from_option("fn_lock_state",
1,
fn_lock_state,
ARRAY_SIZE(fn_lock_state),
CMOS_VSTART_fn_lock_state,
CMOS_VLEN_fn_lock_state));
get_ec_value_from_option(
"fn_lock_state", 1, fn_lock_state, ARRAY_SIZE(fn_lock_state),
CONFIG(USE_OPTION_TABLE) ? CMOS_VSTART_fn_lock_state : UINT_MAX,
CONFIG(USE_OPTION_TABLE) ? CMOS_VLEN_fn_lock_state : UINT_MAX));
#endif
/*
@ -223,18 +195,13 @@ static void merlin_init(struct device *dev)
*
*/
#ifdef CMOS_VSTART_trackpad_state
const uint8_t trackpad_state[] = {
TRACKPAD_ENABLED,
TRACKPAD_DISABLED
};
const uint8_t trackpad_state[] = {TRACKPAD_ENABLED, TRACKPAD_DISABLED};
ec_write(ECRAM_TRACKPAD_STATE,
get_ec_value_from_option("trackpad_state",
0,
trackpad_state,
ARRAY_SIZE(trackpad_state),
CMOS_VSTART_trackpad_state,
CMOS_VLEN_trackpad_state));
get_ec_value_from_option(
"trackpad_state", 0, trackpad_state, ARRAY_SIZE(trackpad_state),
CONFIG(USE_OPTION_TABLE) ? CMOS_VSTART_trackpad_state : UINT_MAX,
CONFIG(USE_OPTION_TABLE) ? CMOS_VLEN_trackpad_state : UINT_MAX));
#endif
/*
@ -247,24 +214,20 @@ static void merlin_init(struct device *dev)
*
*/
#ifdef CMOS_VSTART_kbl_brightness
const uint8_t kbl_brightness[] = {
KBL_ON,
KBL_OFF,
KBL_LOW,
KBL_HIGH
};
const uint8_t kbl_brightness[] = {KBL_ON, KBL_OFF, KBL_LOW, KBL_HIGH};
ec_write(ECRAM_KBL_BRIGHTNESS,
get_ec_value_from_option("kbl_brightness",
CONFIG(EC_STARLABS_KBL_LEVELS) ? 2 : 0,
kbl_brightness,
ARRAY_SIZE(kbl_brightness),
CMOS_VSTART_kbl_brightness,
CMOS_VLEN_kbl_brightness));
get_ec_value_from_option(
"kbl_brightness",
CONFIG(USE_OPTION_TABLE) ?
(CONFIG(EC_STARLABS_KBL_LEVELS) ? 2 : 0) :
(CONFIG(EC_STARLABS_KBL_LEVELS) ? KBL_LOW : KBL_ON),
kbl_brightness, ARRAY_SIZE(kbl_brightness),
CONFIG(USE_OPTION_TABLE) ? CMOS_VSTART_kbl_brightness : UINT_MAX,
CONFIG(USE_OPTION_TABLE) ? CMOS_VLEN_kbl_brightness : UINT_MAX));
#endif
/*
* Keyboard Backlight State
*
@ -281,9 +244,9 @@ static void merlin_init(struct device *dev)
}
static struct device_operations ops = {
.init = merlin_init,
.read_resources = noop_read_resources,
.set_resources = noop_set_resources,
.init = merlin_init,
.read_resources = noop_read_resources,
.set_resources = noop_set_resources,
};
static struct pnp_info pnp_dev_info[] = {
@ -299,7 +262,7 @@ static struct pnp_info pnp_dev_info[] = {
{ NULL, NUVOTON_PM1, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
/* Power Management I/F Channel 2 (PMC2) */
{ NULL, NUVOTON_PM2, PNP_IO0 | PNP_IO1 | PNP_IO2 | PNP_IRQ0, 0x07fc,
0x07fc, 0xfff0, },
0x07fc, 0xfff0, },
/* Power Management I/F Channel 3 (PMC3) */
{ NULL, NUVOTON_PM3, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
/* Extended Shared Memory (ESHM) */