1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <device/device.h>
5 #include <device/pnp.h>
6 #include <ec/acpi/ec.h>
8 #include <pc80/keyboard.h>
13 uint16_t ec_get_version(void)
15 return (ec_read(ECRAM_MAJOR_VERSION
) << 8) | ec_read(ECRAM_MINOR_VERSION
);
18 static uint8_t get_ec_value_from_option(const char *name
,
19 unsigned int fallback
,
23 unsigned int index
= get_uint_option(name
, fallback
);
24 if (index
>= lut_size
)
29 static uint16_t ec_get_chip_id(unsigned int port
)
31 return pnp_read_index(port
, NUVOTON_CHIPID
);
34 static void merlin_init(struct device
*dev
)
40 * The address/data IO port pair for the Nuvoton EC are configurable
41 * through the EC domain and are fixed by the EC's firmware blob. If
42 * the value(s) passed through the "dev" structure don't match the
43 * expected values then output severe warnings.
45 if (dev
->path
.pnp
.port
!= NUVOTON_FIXED_ADDR
) {
46 printk(BIOS_ERR
, "NUVOTON: Incorrect ports defined in devicetree.cb.\n");
47 printk(BIOS_ERR
, "NUVOTON: Serious operational issues will arise.\n");
51 const uint16_t chip_id
= ec_get_chip_id(dev
->path
.pnp
.port
);
53 if (chip_id
!= NUVOTON_CHIPID_VAL
) {
54 printk(BIOS_ERR
, "NUVOTON: Expected chip ID 0x%04x, but got 0x%04x instead.\n",
55 NUVOTON_CHIPID_VAL
, chip_id
);
59 pc_keyboard_init(NO_AUX_DEVICE
);
62 * Restore settings from CMOS into EC RAM:
75 * Keyboard Backlight Timeout
77 * Setting: kbl_timeout
79 * Values: 30 Seconds, 1 Minute, 3 Minutes, 5 Minutes, Never
83 const uint8_t kbl_timeout
[] = {
91 ec_write(ECRAM_KBL_TIMEOUT
,
92 get_ec_value_from_option("kbl_timeout",
95 ARRAY_SIZE(kbl_timeout
)));
100 * Setting: fn_ctrl_swap
102 * Values: Enabled, Disabled
106 const uint8_t fn_ctrl_swap
[] = {
111 ec_write(ECRAM_FN_CTRL_REVERSE
,
112 get_ec_value_from_option("fn_ctrl_swap",
115 ARRAY_SIZE(fn_ctrl_swap
)));
118 * Maximum Charge Level
120 * Setting: max_charge
122 * Values: 60%, 80%, 100%
126 const uint8_t max_charge
[] = {
132 if (CONFIG(EC_STARLABS_MAX_CHARGE
))
133 ec_write(ECRAM_MAX_CHARGE
,
134 get_ec_value_from_option("max_charge",
137 ARRAY_SIZE(max_charge
)));
142 * Setting: fast_charge
144 * Values: Normal, Fast
148 const uint8_t fast_charge
[] = {
153 if (CONFIG(EC_STARLABS_FAST_CHARGE
))
154 ec_write(ECRAM_FAST_CHARGE
,
155 get_ec_value_from_option("fast_charge",
158 ARRAY_SIZE(fast_charge
)));
165 * Values: Quiet, Normal, Aggressive
169 const uint8_t fan_mode
[] = {
175 if (CONFIG(EC_STARLABS_FAN
))
176 ec_write(ECRAM_FAN_MODE
,
177 get_ec_value_from_option("fan_mode",
180 ARRAY_SIZE(fan_mode
)));
185 * Setting: fn_lock_state
187 * Values: Locked, Unlocked
191 const uint8_t fn_lock_state
[] = {
196 ec_write(ECRAM_FN_LOCK_STATE
,
197 get_ec_value_from_option("fn_lock_state",
200 ARRAY_SIZE(fn_lock_state
)));
205 * Setting: trackpad_state
207 * Values: Enabled, Disabled
211 const uint8_t trackpad_state
[] = {
216 ec_write(ECRAM_TRACKPAD_STATE
,
217 get_ec_value_from_option("trackpad_state",
220 ARRAY_SIZE(trackpad_state
)));
223 * Keyboard Backlight Brightness
225 * Setting: kbl_brightness
227 * Values: Off, Low, High / Off, On
231 const uint8_t kbl_brightness
[] = {
238 if (CONFIG(EC_STARLABS_KBL_LEVELS
))
239 ec_write(ECRAM_KBL_BRIGHTNESS
,
240 get_ec_value_from_option("kbl_brightness",
243 ARRAY_SIZE(kbl_brightness
)));
245 ec_write(ECRAM_KBL_BRIGHTNESS
,
246 get_ec_value_from_option("kbl_brightness",
249 ARRAY_SIZE(kbl_brightness
)));
252 * Keyboard Backlight State
259 * Note: Always enable, as the brightness level of `off` disables it.
263 ec_write(ECRAM_KBL_STATE
, KBL_ENABLED
);
266 static struct device_operations ops
= {
268 .read_resources
= noop_read_resources
,
269 .set_resources
= noop_set_resources
,
272 static struct pnp_info pnp_dev_info
[] = {
273 /* System Wake-Up Control (SWUC) */
274 { NULL
, NUVOTON_MSWC
, PNP_IO0
| PNP_IRQ0
, 0xfff0, },
275 /* KBC / Mouse Interface */
276 { NULL
, NUVOTON_KBCM
, PNP_IRQ0
, },
277 /* KBC / Keyboard Interface */
278 { NULL
, NUVOTON_KBCK
, PNP_IO0
| PNP_IO1
| PNP_IRQ0
, 0x07ff, 0x07ff, },
279 /* Shared Memory / Flash Interface (SMFI) */
280 { NULL
, NUVOTON_SHM
, PNP_IO0
| PNP_IRQ0
, 0xfff0, },
281 /* Power Management I/F Channel 1 (PMC1) */
282 { NULL
, NUVOTON_PM1
, PNP_IO0
| PNP_IO1
| PNP_IRQ0
, 0x07ff, 0x07ff, },
283 /* Power Management I/F Channel 2 (PMC2) */
284 { NULL
, NUVOTON_PM2
, PNP_IO0
| PNP_IO1
| PNP_IO2
| PNP_IRQ0
, 0x07fc,
286 /* Power Management I/F Channel 3 (PMC3) */
287 { NULL
, NUVOTON_PM3
, PNP_IO0
| PNP_IO1
| PNP_IRQ0
, 0x07ff, 0x07ff, },
288 /* Extended Shared Memory (ESHM) */
289 { NULL
, NUVOTON_ESHM
},
290 /* Power Management I/F Channel 4 (PMC4) */
291 { NULL
, NUVOTON_PM4
, PNP_IO0
| PNP_IO1
| PNP_IRQ0
, 0x07ff, 0x07ff, },
294 static void enable_dev(struct device
*dev
)
296 pnp_enable_devices(dev
, &ops
, ARRAY_SIZE(pnp_dev_info
), pnp_dev_info
);
299 struct chip_operations ec_starlabs_merlin_ops
= {
300 CHIP_NAME("NUVOTON EC")
301 .enable_dev
= enable_dev