ec/starlabs/merlin: Add support for Nuvoton EC's
Support was created for the NPCE9m5x series, using version 1.1 of the datasheet. The specific model tested was the NPCE985P/G, on the StarLite Mk IV with version 1.00 of the EC firmware. Signed-off-by: Sean Rhodes <sean@starlabs.systems> Change-Id: Ib66baf1e88f5d548ce955dffa00c9b88255b2f95 Reviewed-on: https://review.coreboot.org/c/coreboot/+/62702 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Angel Pons <th3fanbus@gmail.com> Reviewed-by: Paul Menzel <paulepanter@mailbox.org>
This commit is contained in:
parent
6082ee5281
commit
78342989c4
@ -1,5 +1,11 @@
|
||||
## SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
config EC_STARLABS_NUVOTON
|
||||
bool
|
||||
select EC_ACPI
|
||||
help
|
||||
Interface to Nuvoton embedded controller principally in Star Labs notebooks.
|
||||
|
||||
config EC_STARLABS_ITE
|
||||
bool
|
||||
select EC_ACPI
|
||||
@ -33,21 +39,21 @@ config EC_STARLABS_ITE_BIN_PATH
|
||||
config EC_STARLABS_KBL_LEVELS
|
||||
bool
|
||||
default n
|
||||
depends on EC_STARLABS_ITE
|
||||
depends on EC_STARLABS_ITE || EC_STARLABS_NUVOTON
|
||||
help
|
||||
Select if the mainboard supports multiple levels of brightness for the keyboard.
|
||||
|
||||
config EC_STARLABS_FAN
|
||||
bool
|
||||
default n
|
||||
depends on EC_STARLABS_ITE
|
||||
depends on EC_STARLABS_ITE || EC_STARLABS_NUVOTON
|
||||
help
|
||||
Select if the mainboard has a fan.
|
||||
|
||||
config EC_STARLABS_MAX_CHARGE
|
||||
bool
|
||||
default n
|
||||
depends on EC_STARLABS_ITE
|
||||
depends on EC_STARLABS_ITE || EC_STARLABS_NUVOTON
|
||||
help
|
||||
Select if the mainboard supports limiting the maximum charge of the battery.
|
||||
|
||||
|
@ -26,3 +26,12 @@ warn_no_ite_fw:
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_EC_STARLABS_NUVOTON),y)
|
||||
|
||||
EC_VARIANT_DIR := $(call strip_quotes, $(CONFIG_EC_VARIANT_DIR))
|
||||
CPPFLAGS_common += -I$(src)/ec/starlabs/merlin/variants/$(EC_VARIANT_DIR)
|
||||
|
||||
all-y += nuvoton.c
|
||||
|
||||
endif
|
||||
|
@ -1,19 +1,20 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
/*
|
||||
* EC communication interface for ITE Embedded Controller.
|
||||
* EC communication interface for Embedded Controller.
|
||||
*/
|
||||
|
||||
#ifndef _EC_STARLABS_ITE_H
|
||||
#define _EC_STARLABS_ITE_H
|
||||
#ifndef _EC_STARLABS_EC_H
|
||||
#define _EC_STARLABS_EC_H
|
||||
|
||||
/*
|
||||
* Define the expected value of the PNP base address that is fixed through
|
||||
* the BADRSEL register controlled within the EC domain by the EC Firmware.
|
||||
*/
|
||||
#define ITE_FIXED_ADDR 0x4e
|
||||
#define NUVOTON_FIXED_ADDR 0x4e
|
||||
|
||||
/* Logical device number (LDN) assignments. */
|
||||
/* Logical device number (LDN) assignments for ITE. */
|
||||
#define ITE_SP1 0x01 /* Serial Port 1 (UART) */
|
||||
#define ITE_SP2 0x02 /* Serial Port 2 (UART) */
|
||||
#define ITE_SWUC 0x04 /* System Wake-Up Control (SWUC) */
|
||||
@ -30,9 +31,21 @@
|
||||
#define ITE_PMC4 0x18 /* Power Management I/F Channel 4 (PMC4) */
|
||||
#define ITE_PMC5 0x19 /* Power Management I/F Channel 5 (PMC5) */
|
||||
|
||||
/* Logical device number (LDN) assignments for Nuvoton. */
|
||||
#define NUVOTON_MSWC 0x04 /* Mobile System Wake-Up Control (MSWC) */
|
||||
#define NUVOTON_KBCM 0x05 /* KBC / Mouse Interface */
|
||||
#define NUVOTON_KBCK 0x06 /* KBC / Keyboard Interface */
|
||||
#define NUVOTON_SHM 0x0f /* Shared Memory (SHM) */
|
||||
#define NUVOTON_PM1 0x11 /* Power Management I/F Channel 1 (PM1) */
|
||||
#define NUVOTON_PM2 0x12 /* Power Management I/F Channel 2 (PM2) */
|
||||
#define NUVOTON_PM3 0x17 /* Power Management I/F Channel 3 (PM3) */
|
||||
#define NUVOTON_ESHM 0x1d /* Extended Shared Memory (ESHM) */
|
||||
#define NUVOTON_PM4 0x1e /* Power Management I/F Channel 3 (PM4) */
|
||||
|
||||
/* Host domain registers. */
|
||||
#define ITE_CHIPID1 0x20 /* Device ID register 1 */
|
||||
#define ITE_CHIPID2 0x21 /* Device ID register 2 */
|
||||
#define NUVOTON_CHIPID 0x27 /* Device ID register */
|
||||
|
||||
/* EC RAM common offsets */
|
||||
#define ECRAM_MAJOR_VERSION 0x00
|
||||
|
287
src/ec/starlabs/merlin/nuvoton.c
Normal file
287
src/ec/starlabs/merlin/nuvoton.c
Normal file
@ -0,0 +1,287 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <console/console.h>
|
||||
#include <device/device.h>
|
||||
#include <device/pnp.h>
|
||||
#include <ec/acpi/ec.h>
|
||||
#include <option.h>
|
||||
#include <pc80/keyboard.h>
|
||||
|
||||
#include "ec.h"
|
||||
#include "ecdefs.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)
|
||||
{
|
||||
unsigned int index = get_uint_option(name, fallback);
|
||||
if (index >= lut_size)
|
||||
index = fallback;
|
||||
return lut[index];
|
||||
}
|
||||
|
||||
static uint16_t ec_get_chip_id(unsigned int port)
|
||||
{
|
||||
return pnp_read_index(port, NUVOTON_CHIPID);
|
||||
}
|
||||
|
||||
static void merlin_init(struct device *dev)
|
||||
{
|
||||
if (!dev->enabled)
|
||||
return;
|
||||
|
||||
/*
|
||||
* The address/data IO port pair for the Nuvoton EC are configurable
|
||||
* through the EC domain and are fixed by the EC's firmware blob. If
|
||||
* the value(s) passed through the "dev" structure don't match the
|
||||
* expected values then output severe warnings.
|
||||
*/
|
||||
if (dev->path.pnp.port != NUVOTON_FIXED_ADDR) {
|
||||
printk(BIOS_ERR, "NUVOTON: Incorrect ports defined in devicetree.cb.\n");
|
||||
printk(BIOS_ERR, "NUVOTON: Serious operational issues will arise.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
const uint16_t chip_id = ec_get_chip_id(dev->path.pnp.port);
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
pc_keyboard_init(NO_AUX_DEVICE);
|
||||
|
||||
/*
|
||||
* Restore settings from CMOS into EC RAM:
|
||||
*
|
||||
* kbl_timeout
|
||||
* fn_ctrl_swap
|
||||
* max_charge
|
||||
* fan_mode
|
||||
* fn_lock_state
|
||||
* trackpad_state
|
||||
* kbl_brightness
|
||||
* kbl_state
|
||||
*/
|
||||
|
||||
/*
|
||||
* Keyboard Backlight Timeout
|
||||
*
|
||||
* Setting: kbl_timeout
|
||||
*
|
||||
* Values: 30 Seconds, 1 Minute, 3 Minutes, 5 Minutes, Never
|
||||
* Default: 30 Seconds
|
||||
*
|
||||
*/
|
||||
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)));
|
||||
|
||||
/*
|
||||
* Fn Ctrl Reverse
|
||||
*
|
||||
* Setting: fn_ctrl_swap
|
||||
*
|
||||
* Values: Enabled, Disabled
|
||||
* Default: Disabled
|
||||
*
|
||||
*/
|
||||
const uint8_t fn_ctrl_swap[] = {
|
||||
FN_CTRL,
|
||||
CTRL_FN
|
||||
};
|
||||
|
||||
ec_write(ECRAM_FN_CTRL_REVERSE,
|
||||
get_ec_value_from_option("fn_ctrl_swap",
|
||||
1,
|
||||
fn_ctrl_swap,
|
||||
ARRAY_SIZE(fn_ctrl_swap)));
|
||||
|
||||
/*
|
||||
* Maximum Charge Level
|
||||
*
|
||||
* Setting: max_charge
|
||||
*
|
||||
* Values: 60%, 80%, 100%
|
||||
* Default: 100%
|
||||
*
|
||||
*/
|
||||
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)));
|
||||
|
||||
/*
|
||||
* Fan Mode
|
||||
*
|
||||
* Setting: fan_mode
|
||||
*
|
||||
* Values: Quiet, Normal, Aggressive
|
||||
* Default: Normal
|
||||
*
|
||||
*/
|
||||
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)));
|
||||
|
||||
/*
|
||||
* Function Lock
|
||||
*
|
||||
* Setting: fn_lock_state
|
||||
*
|
||||
* Values: Locked, Unlocked
|
||||
* Default: 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)));
|
||||
|
||||
/*
|
||||
* Trackpad State
|
||||
*
|
||||
* Setting: trackpad_state
|
||||
*
|
||||
* Values: Enabled, Disabled
|
||||
* Default: Enabled
|
||||
*
|
||||
*/
|
||||
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)));
|
||||
|
||||
/*
|
||||
* Keyboard Backlight Brightness
|
||||
*
|
||||
* Setting: kbl_brightness
|
||||
*
|
||||
* Values: Off, Low, High / Off, On
|
||||
* Default: Low
|
||||
*
|
||||
*/
|
||||
const uint8_t kbl_brightness[] = {
|
||||
KBL_ON,
|
||||
KBL_OFF,
|
||||
KBL_LOW,
|
||||
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)));
|
||||
|
||||
/*
|
||||
* Keyboard Backlight State
|
||||
*
|
||||
* Setting: kbl_state
|
||||
*
|
||||
* Values: Off, On
|
||||
* Default: On
|
||||
*
|
||||
*/
|
||||
const uint8_t kbl_state[] = {
|
||||
KBL_DISABLED,
|
||||
KBL_ENABLED
|
||||
};
|
||||
|
||||
ec_write(ECRAM_KBL_STATE,
|
||||
get_ec_value_from_option("kbl_state",
|
||||
1,
|
||||
kbl_state,
|
||||
ARRAY_SIZE(kbl_state)));
|
||||
}
|
||||
|
||||
static struct device_operations ops = {
|
||||
.init = merlin_init,
|
||||
.read_resources = noop_read_resources,
|
||||
.set_resources = noop_set_resources,
|
||||
};
|
||||
|
||||
static struct pnp_info pnp_dev_info[] = {
|
||||
/* System Wake-Up Control (SWUC) */
|
||||
{ NULL, NUVOTON_MSWC, PNP_IO0 | PNP_IRQ0, 0xfff0, },
|
||||
/* KBC / Mouse Interface */
|
||||
{ NULL, NUVOTON_KBCM, PNP_IRQ0, },
|
||||
/* KBC / Keyboard Interface */
|
||||
{ NULL, NUVOTON_KBCK, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
|
||||
/* Shared Memory / Flash Interface (SMFI) */
|
||||
{ NULL, NUVOTON_SHM, PNP_IO0 | PNP_IRQ0, 0xfff0, },
|
||||
/* Power Management I/F Channel 1 (PMC1) */
|
||||
{ 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, },
|
||||
/* Power Management I/F Channel 3 (PMC3) */
|
||||
{ NULL, NUVOTON_PM3, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
|
||||
/* Extended Shared Memory (ESHM) */
|
||||
{ NULL, NUVOTON_ESHM },
|
||||
/* Power Management I/F Channel 4 (PMC4) */
|
||||
{ NULL, NUVOTON_PM4, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
|
||||
};
|
||||
|
||||
static void enable_dev(struct device *dev)
|
||||
{
|
||||
pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
|
||||
}
|
||||
|
||||
struct chip_operations ec_starlabs_merlin_ops = {
|
||||
CHIP_NAME("NUVOTON EC")
|
||||
.enable_dev = enable_dev
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user