ec/starlabs/merlin: Adjust the EC code to read values from CMOS

This is in preparation to store options in EFI variable store, rather
than CMOS. However, some still need to stay in CMOS, so that they can
be accessed via ACPI.

Change-Id: Idb094456543c75b59a8ddd80b58eb4fa1e10144f
Signed-off-by: Sean Rhodes <sean@starlabs.systems>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/76582
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Sean Rhodes 2023-05-31 10:33:41 +01:00
commit c46494153d
2 changed files with 137 additions and 48 deletions

View file

@ -5,9 +5,12 @@
#include <device/pnp.h>
#include <ec/acpi/ec.h>
#include <option.h>
#include <pc80/mc146818rtc.h>
#include <halt.h>
#include "ec.h"
#include "ecdefs.h"
#include "option_table.h"
#include "ec.h"
#define ITE_IT5570 0x5570
#define ITE_IT8987 0x8987
@ -17,12 +20,34 @@ uint16_t ec_get_version(void)
return (ec_read(ECRAM_MAJOR_VERSION) << 8) | ec_read(ECRAM_MINOR_VERSION);
}
static uint8_t get_ec_value_from_option(const char *name,
unsigned int fallback,
const uint8_t *lut,
size_t lut_size)
static uint8_t get_cmos_value(uint32_t bit, uint32_t length)
{
unsigned int index = get_uint_option(name, fallback);
uint32_t byte, byte_bit;
uint8_t uchar;
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
// 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,
uint32_t cmos_length)
{
unsigned int index;
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;
return lut[index];
@ -95,7 +120,9 @@ static void merlin_init(struct device *dev)
get_ec_value_from_option("kbl_timeout",
0,
kbl_timeout,
ARRAY_SIZE(kbl_timeout)));
ARRAY_SIZE(kbl_timeout),
UINT_MAX,
UINT_MAX));
/*
* Fn Ctrl Reverse
@ -115,7 +142,9 @@ static void merlin_init(struct device *dev)
get_ec_value_from_option("fn_ctrl_swap",
0,
fn_ctrl_swap,
ARRAY_SIZE(fn_ctrl_swap)));
ARRAY_SIZE(fn_ctrl_swap),
UINT_MAX,
UINT_MAX));
/*
* Maximum Charge Level
@ -137,7 +166,9 @@ static void merlin_init(struct device *dev)
get_ec_value_from_option("max_charge",
0,
max_charge,
ARRAY_SIZE(max_charge)));
ARRAY_SIZE(max_charge),
UINT_MAX,
UINT_MAX));
/*
* Fan Mode
@ -159,7 +190,9 @@ static void merlin_init(struct device *dev)
get_ec_value_from_option("fan_mode",
0,
fan_mode,
ARRAY_SIZE(fan_mode)));
ARRAY_SIZE(fan_mode),
UINT_MAX,
UINT_MAX));
/*
* Function Lock
@ -170,6 +203,7 @@ static void merlin_init(struct device *dev)
* Default: Locked
*
*/
#ifdef CMOS_VLEN_fn_lock_state
const uint8_t fn_lock_state[] = {
UNLOCKED,
LOCKED
@ -179,7 +213,10 @@ static void merlin_init(struct device *dev)
get_ec_value_from_option("fn_lock_state",
1,
fn_lock_state,
ARRAY_SIZE(fn_lock_state)));
ARRAY_SIZE(fn_lock_state),
CMOS_VSTART_fn_lock_state,
CMOS_VLEN_fn_lock_state));
#endif
/*
* Trackpad State
@ -190,6 +227,7 @@ static void merlin_init(struct device *dev)
* Default: Enabled
*
*/
#ifdef CMOS_VSTART_trackpad_state
const uint8_t trackpad_state[] = {
TRACKPAD_ENABLED,
TRACKPAD_DISABLED
@ -199,7 +237,10 @@ static void merlin_init(struct device *dev)
get_ec_value_from_option("trackpad_state",
0,
trackpad_state,
ARRAY_SIZE(trackpad_state)));
ARRAY_SIZE(trackpad_state),
CMOS_VSTART_trackpad_state,
CMOS_VLEN_trackpad_state));
#endif
/*
* Keyboard Backlight Brightness
@ -210,6 +251,7 @@ static void merlin_init(struct device *dev)
* Default: Low
*
*/
#ifdef CMOS_VSTART_kbl_brightness
const uint8_t kbl_brightness[] = {
KBL_ON,
KBL_OFF,
@ -217,18 +259,16 @@ static void merlin_init(struct device *dev)
KBL_HIGH
};
if (CONFIG(EC_STARLABS_KBL_LEVELS))
ec_write(ECRAM_KBL_BRIGHTNESS,
get_ec_value_from_option("kbl_brightness",
2,
kbl_brightness,
ARRAY_SIZE(kbl_brightness)));
else
ec_write(ECRAM_KBL_BRIGHTNESS,
get_ec_value_from_option("kbl_brightness",
0,
kbl_brightness,
ARRAY_SIZE(kbl_brightness)));
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));
#endif
/*
* Keyboard Backlight State
@ -264,7 +304,9 @@ static void merlin_init(struct device *dev)
get_ec_value_from_option("charging_speed",
SPEED_0_5C,
charging_speed,
ARRAY_SIZE(charging_speed)));
ARRAY_SIZE(charging_speed),
UINT_MAX,
UINT_MAX));
/*
* Lid Switch
@ -285,7 +327,9 @@ static void merlin_init(struct device *dev)
get_ec_value_from_option("lid_switch",
0,
lid_switch,
ARRAY_SIZE(lid_switch)));
ARRAY_SIZE(lid_switch),
UINT_MAX,
UINT_MAX));
/*
* Power LED Brightness
@ -306,7 +350,9 @@ static void merlin_init(struct device *dev)
get_ec_value_from_option("power_led",
0,
power_led,
ARRAY_SIZE(power_led)));
ARRAY_SIZE(power_led),
UINT_MAX,
UINT_MAX));
}
static struct device_operations ops = {

View file

@ -5,21 +5,47 @@
#include <device/pnp.h>
#include <ec/acpi/ec.h>
#include <option.h>
#include <pc80/mc146818rtc.h>
#include <halt.h>
#include "ec.h"
#include "ecdefs.h"
#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);
}
static uint8_t get_ec_value_from_option(const char *name,
unsigned int fallback,
const uint8_t *lut,
size_t lut_size)
static uint8_t get_cmos_value(uint32_t bit, uint32_t length)
{
unsigned int index = get_uint_option(name, fallback);
uint32_t byte, byte_bit;
uint8_t uchar;
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
// 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,
uint32_t cmos_length)
{
unsigned int index;
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;
return lut[index];
@ -89,7 +115,9 @@ static void merlin_init(struct device *dev)
get_ec_value_from_option("kbl_timeout",
0,
kbl_timeout,
ARRAY_SIZE(kbl_timeout)));
ARRAY_SIZE(kbl_timeout),
UINT_MAX,
UINT_MAX));
/*
* Fn Ctrl Reverse
@ -109,7 +137,9 @@ static void merlin_init(struct device *dev)
get_ec_value_from_option("fn_ctrl_swap",
0,
fn_ctrl_swap,
ARRAY_SIZE(fn_ctrl_swap)));
ARRAY_SIZE(fn_ctrl_swap),
UINT_MAX,
UINT_MAX));
/*
* Maximum Charge Level
@ -131,7 +161,9 @@ static void merlin_init(struct device *dev)
get_ec_value_from_option("max_charge",
0,
max_charge,
ARRAY_SIZE(max_charge)));
ARRAY_SIZE(max_charge),
UINT_MAX,
UINT_MAX));
/*
* Fast Charge
@ -152,7 +184,9 @@ static void merlin_init(struct device *dev)
get_ec_value_from_option("fast_charge",
0,
fast_charge,
ARRAY_SIZE(fast_charge)));
ARRAY_SIZE(fast_charge),
UINT_MAX,
UINT_MAX));
/*
* Fan Mode
@ -174,7 +208,9 @@ static void merlin_init(struct device *dev)
get_ec_value_from_option("fan_mode",
0,
fan_mode,
ARRAY_SIZE(fan_mode)));
ARRAY_SIZE(fan_mode),
UINT_MAX,
UINT_MAX));
/*
* Function Lock
@ -185,6 +221,7 @@ static void merlin_init(struct device *dev)
* Default: Locked
*
*/
#ifdef CMOS_VLEN_fn_lock_state
const uint8_t fn_lock_state[] = {
UNLOCKED,
LOCKED
@ -194,7 +231,10 @@ static void merlin_init(struct device *dev)
get_ec_value_from_option("fn_lock_state",
1,
fn_lock_state,
ARRAY_SIZE(fn_lock_state)));
ARRAY_SIZE(fn_lock_state),
CMOS_VSTART_fn_lock_state,
CMOS_VLEN_fn_lock_state));
#endif
/*
* Trackpad State
@ -205,6 +245,7 @@ static void merlin_init(struct device *dev)
* Default: Enabled
*
*/
#ifdef CMOS_VSTART_trackpad_state
const uint8_t trackpad_state[] = {
TRACKPAD_ENABLED,
TRACKPAD_DISABLED
@ -214,7 +255,10 @@ static void merlin_init(struct device *dev)
get_ec_value_from_option("trackpad_state",
0,
trackpad_state,
ARRAY_SIZE(trackpad_state)));
ARRAY_SIZE(trackpad_state),
CMOS_VSTART_trackpad_state,
CMOS_VLEN_trackpad_state));
#endif
/*
* Keyboard Backlight Brightness
@ -225,6 +269,7 @@ static void merlin_init(struct device *dev)
* Default: Low
*
*/
#ifdef CMOS_VSTART_kbl_brightness
const uint8_t kbl_brightness[] = {
KBL_ON,
KBL_OFF,
@ -232,18 +277,16 @@ static void merlin_init(struct device *dev)
KBL_HIGH
};
if (CONFIG(EC_STARLABS_KBL_LEVELS))
ec_write(ECRAM_KBL_BRIGHTNESS,
get_ec_value_from_option("kbl_brightness",
2,
kbl_brightness,
ARRAY_SIZE(kbl_brightness)));
else
ec_write(ECRAM_KBL_BRIGHTNESS,
get_ec_value_from_option("kbl_brightness",
0,
kbl_brightness,
ARRAY_SIZE(kbl_brightness)));
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));
#endif
/*
* Keyboard Backlight State