blob: c7a027974b4aee506a1cf9c80e76b0476655f5d9 [file] [log] [blame]
Sean Rhodes296994b2021-10-14 20:58:15 +01001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <console/console.h>
Sean Rhodes296994b2021-10-14 20:58:15 +01004#include <device/device.h>
5#include <device/pnp.h>
6#include <ec/acpi/ec.h>
7#include <option.h>
8#include <pc80/keyboard.h>
Sean Rhodes0579c602023-02-16 15:00:14 +00009#include <halt.h>
Sean Rhodes296994b2021-10-14 20:58:15 +010010
11#include "ec.h"
12#include "ecdefs.h"
13
Sean Rhodes6082ee52022-03-09 08:07:30 +000014uint16_t ec_get_version(void)
Sean Rhodes296994b2021-10-14 20:58:15 +010015{
16 return (ec_read(ECRAM_MAJOR_VERSION) << 8) | ec_read(ECRAM_MINOR_VERSION);
17}
18
19static uint8_t get_ec_value_from_option(const char *name,
20 unsigned int fallback,
21 const uint8_t *lut,
22 size_t lut_size)
23{
24 unsigned int index = get_uint_option(name, fallback);
25 if (index >= lut_size)
26 index = fallback;
27 return lut[index];
28}
29
Sean Rhodes0579c602023-02-16 15:00:14 +000030static void ec_mirror_with_count(void)
31{
32 unsigned int cmos_mirror_flag_counter = get_uint_option("mirror_flag_counter", UINT_MAX);
33
34 if (cmos_mirror_flag_counter != UINT_MAX) {
35 printk(BIOS_DEBUG, "ITE: mirror_flag_counter = %u\n", cmos_mirror_flag_counter);
36
37 /* Avoid boot loops by only trying a state change once */
38 if (cmos_mirror_flag_counter < MIRROR_ATTEMPTS) {
39 cmos_mirror_flag_counter++;
40 set_uint_option("mirror_flag_counter", cmos_mirror_flag_counter);
41 printk(BIOS_DEBUG, "ITE: Mirror attempt %u/%u.\n", cmos_mirror_flag_counter,
42 MIRROR_ATTEMPTS);
43
44 /* Write the EC mirror flag */
45 ec_write(ECRAM_MIRROR_FLAG, MIRROR_ENABLED);
46
47 /* Check what has been written */
48 if (ec_read(ECRAM_MIRROR_FLAG) == MIRROR_ENABLED)
49 poweroff();
50 } else {
51 /*
52 * If the mirror flags fails after 1 attempt, it will
53 * likely need a cold boot, or recovering.
54 */
55 printk(BIOS_ERR, "ITE: Failed to mirror the EC in %u attempts!\n",
56 MIRROR_ATTEMPTS);
57 }
58 } else {
59 printk(BIOS_DEBUG, "ITE: Powering Off");
60 /* Write the EC mirror flag */
61 ec_write(ECRAM_MIRROR_FLAG, MIRROR_ENABLED);
62
63 /* Check what has been written */
64 if (ec_read(ECRAM_MIRROR_FLAG) == MIRROR_ENABLED)
65 poweroff();
66 }
67}
68
69
70void ec_mirror_flag(void)
71{
72 /*
73 * For the mirror flag to work, the status of the EC pin must be known
74 * at all times, which means external power. This can be either a DC
75 * charger, or PD with CCG6. PD with an ANX7447 requires configuration
76 * from the EC, so the update will interrupt this.
77 *
78 * This means we can unconditionally apply the mirror flag to devices
79 * that have CCG6, present on devices with TBT, but have a manual
80 * flag for devices without it.
81 */
Sean Rhodes7d00b7c2023-07-07 14:27:28 +010082 uint16_t ec_version = ec_get_version();
83
Sean Rhodes0579c602023-02-16 15:00:14 +000084 if (CONFIG(EC_STARLABS_MIRROR_SUPPORT) &&
Sean Rhodese4fd5612023-07-18 11:49:19 +010085 (CONFIG(DRIVERS_INTEL_USB4_RETIMER) || get_uint_option("mirror_flag", 0)) &&
Sean Rhodes7d00b7c2023-07-07 14:27:28 +010086 (ec_version != CONFIG_EC_STARLABS_MIRROR_VERSION)) {
87 printk(BIOS_ERR, "ITE: EC version 0x%x doesn't match coreboot version 0x%x.\n",
88 ec_version, CONFIG_EC_STARLABS_MIRROR_VERSION);
Sean Rhodes0579c602023-02-16 15:00:14 +000089 ec_mirror_with_count();
90 }
91}
92
Sean Rhodes6082ee52022-03-09 08:07:30 +000093static uint16_t ec_get_chip_id(unsigned int port)
Sean Rhodes296994b2021-10-14 20:58:15 +010094{
95 return (pnp_read_index(port, ITE_CHIPID1) << 8) |
96 pnp_read_index(port, ITE_CHIPID2);
97}
98
99static void merlin_init(struct device *dev)
100{
101 if (!dev->enabled)
102 return;
103
104 /*
105 * The address/data IO port pair for the ite EC are configurable
106 * through the EC domain and are fixed by the EC's firmware blob. If
107 * the value(s) passed through the "dev" structure don't match the
108 * expected values then output severe warnings.
109 */
110 if (dev->path.pnp.port != ITE_FIXED_ADDR) {
111 printk(BIOS_ERR, "ITE: Incorrect ports defined in devicetree.cb.\n");
112 printk(BIOS_ERR, "ITE: Serious operational issues will arise.\n");
113 return;
114 }
115
Sean Rhodes6082ee52022-03-09 08:07:30 +0000116 const uint16_t chip_id = ec_get_chip_id(dev->path.pnp.port);
Sean Rhodes296994b2021-10-14 20:58:15 +0100117
118 if (chip_id != ITE_CHIPID_VAL) {
119 printk(BIOS_ERR, "ITE: Expected chip ID 0x%04x, but got 0x%04x instead.\n",
120 ITE_CHIPID_VAL, chip_id);
121 return;
122 }
123
Sean Rhodes0579c602023-02-16 15:00:14 +0000124 ec_mirror_flag();
125
Sean Rhodes296994b2021-10-14 20:58:15 +0100126 pc_keyboard_init(NO_AUX_DEVICE);
127
128 /*
129 * Restore settings from CMOS into EC RAM:
130 *
131 * kbl_timeout
132 * fn_ctrl_swap
133 * max_charge
134 * fan_mode
135 * fn_lock_state
136 * trackpad_state
137 * kbl_brightness
138 * kbl_state
139 */
140
141 /*
142 * Keyboard Backlight Timeout
143 *
144 * Setting: kbl_timeout
145 *
146 * Values: 30 Seconds, 1 Minute, 3 Minutes, 5 Minutes, Never
147 * Default: 30 Seconds
148 *
149 */
150 const uint8_t kbl_timeout[] = {
151 SEC_30,
152 MIN_1,
153 MIN_3,
154 MIN_5,
155 NEVER
156 };
157
158 ec_write(ECRAM_KBL_TIMEOUT,
159 get_ec_value_from_option("kbl_timeout",
160 0,
161 kbl_timeout,
162 ARRAY_SIZE(kbl_timeout)));
163
164 /*
165 * Fn Ctrl Reverse
166 *
167 * Setting: fn_ctrl_swap
168 *
169 * Values: Enabled, Disabled
170 * Default: Disabled
171 *
172 */
173 const uint8_t fn_ctrl_swap[] = {
174 FN_CTRL,
175 CTRL_FN
176 };
177
178 ec_write(ECRAM_FN_CTRL_REVERSE,
179 get_ec_value_from_option("fn_ctrl_swap",
Sean Rhodesc45cfad2023-04-25 22:51:57 +0100180 0,
Sean Rhodes296994b2021-10-14 20:58:15 +0100181 fn_ctrl_swap,
182 ARRAY_SIZE(fn_ctrl_swap)));
183
184 /*
185 * Maximum Charge Level
186 *
187 * Setting: max_charge
188 *
189 * Values: 60%, 80%, 100%
190 * Default: 100%
191 *
192 */
193 const uint8_t max_charge[] = {
194 CHARGE_100,
195 CHARGE_80,
196 CHARGE_60
197 };
198
Sean Rhodes4d1bf7b2022-02-17 13:55:34 +0000199 if (CONFIG(EC_STARLABS_MAX_CHARGE))
200 ec_write(ECRAM_MAX_CHARGE,
201 get_ec_value_from_option("max_charge",
202 0,
203 max_charge,
204 ARRAY_SIZE(max_charge)));
Sean Rhodes296994b2021-10-14 20:58:15 +0100205
206 /*
207 * Fan Mode
208 *
209 * Setting: fan_mode
210 *
211 * Values: Quiet, Normal, Aggressive
212 * Default: Normal
213 *
214 */
215 const uint8_t fan_mode[] = {
216 FAN_NORMAL,
217 FAN_AGGRESSIVE,
218 FAN_QUIET
219 };
220
221 if (CONFIG(EC_STARLABS_FAN))
222 ec_write(ECRAM_FAN_MODE,
223 get_ec_value_from_option("fan_mode",
224 0,
225 fan_mode,
226 ARRAY_SIZE(fan_mode)));
227
228 /*
229 * Function Lock
230 *
231 * Setting: fn_lock_state
232 *
233 * Values: Locked, Unlocked
234 * Default: Locked
235 *
236 */
237 const uint8_t fn_lock_state[] = {
238 UNLOCKED,
239 LOCKED
240 };
241
242 ec_write(ECRAM_FN_LOCK_STATE,
243 get_ec_value_from_option("fn_lock_state",
244 1,
245 fn_lock_state,
246 ARRAY_SIZE(fn_lock_state)));
247
248 /*
249 * Trackpad State
250 *
251 * Setting: trackpad_state
252 *
253 * Values: Enabled, Disabled
254 * Default: Enabled
255 *
256 */
257 const uint8_t trackpad_state[] = {
258 TRACKPAD_ENABLED,
259 TRACKPAD_DISABLED
260 };
261
262 ec_write(ECRAM_TRACKPAD_STATE,
263 get_ec_value_from_option("trackpad_state",
264 0,
265 trackpad_state,
266 ARRAY_SIZE(trackpad_state)));
267
268 /*
269 * Keyboard Backlight Brightness
270 *
271 * Setting: kbl_brightness
272 *
273 * Values: Off, Low, High / Off, On
274 * Default: Low
275 *
276 */
277 const uint8_t kbl_brightness[] = {
278 KBL_ON,
279 KBL_OFF,
280 KBL_LOW,
281 KBL_HIGH
282 };
283
284 if (CONFIG(EC_STARLABS_KBL_LEVELS))
285 ec_write(ECRAM_KBL_BRIGHTNESS,
286 get_ec_value_from_option("kbl_brightness",
287 2,
288 kbl_brightness,
289 ARRAY_SIZE(kbl_brightness)));
290 else
291 ec_write(ECRAM_KBL_BRIGHTNESS,
292 get_ec_value_from_option("kbl_brightness",
293 0,
294 kbl_brightness,
295 ARRAY_SIZE(kbl_brightness)));
296
297 /*
298 * Keyboard Backlight State
299 *
300 * Setting: kbl_state
301 *
302 * Values: Off, On
303 * Default: On
304 *
305 */
306 const uint8_t kbl_state[] = {
307 KBL_DISABLED,
308 KBL_ENABLED
309 };
310
311 ec_write(ECRAM_KBL_STATE,
312 get_ec_value_from_option("kbl_state",
313 1,
314 kbl_state,
315 ARRAY_SIZE(kbl_state)));
Sean Rhodes296994b2021-10-14 20:58:15 +0100316}
317
318static struct device_operations ops = {
319 .init = merlin_init,
320 .read_resources = noop_read_resources,
321 .set_resources = noop_set_resources,
322};
323
324static struct pnp_info pnp_dev_info[] = {
325 /* Serial Port 1 (UART1) */
326 { NULL, ITE_SP1, PNP_IO0 | PNP_IRQ0, 0x0ff8, },
327 /* Serial Port 2 (UART2) */
328 { NULL, ITE_SP2, PNP_IO0 | PNP_IRQ0, 0x0ff8, },
329 /* System Wake-Up Control (SWUC) */
330 { NULL, ITE_SWUC, PNP_IO0 | PNP_IRQ0, 0xfff0, },
331 /* KBC / Mouse Interface */
332 { NULL, ITE_SWUC, PNP_IRQ0, },
333 /* KBC / Keyboard Interface */
334 { NULL, ITE_KBCK, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
335 /* Consumer IR (CIR) */
336 { NULL, ITE_IR, PNP_IO0 | PNP_IRQ0, 0xfff8, },
337 /* Shared Memory / Flash Interface (SMFI) */
338 { NULL, ITE_SMFI, PNP_IO0 | PNP_IRQ0, 0xfff0, },
339 /* RTC-like Timer (RCTC) */
340 { NULL, ITE_RTCT, PNP_IO0 | PNP_IO1 | PNP_IO2 | PNP_IO3 | PNP_IRQ0,
341 0xfffe, 0xfffe, 0xfffe, 0xfffe, },
342 /* Power Management I/F Channel 1 (PMC1) */
343 { NULL, ITE_PMC1, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
344 /* Power Management I/F Channel 2 (PMC2) */
345 { NULL, ITE_PMC2, PNP_IO0 | PNP_IO1 | PNP_IO2 | PNP_IRQ0, 0x07fc,
346 0x07fc, 0xfff0, },
347 /* Serial Peripheral Interface (SSPI) */
348 { NULL, ITE_SSPI, PNP_IO0 | PNP_IRQ0, 0xfff8, },
349 /* Platform Environment Control Interface (PECI) */
350 { NULL, ITE_PECI, PNP_IRQ0, 0xfff8, },
351 /* Power Management I/F Channel 3 (PMC3) */
352 { NULL, ITE_PMC3, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
353 /* Power Management I/F Channel 4 (PMC4) */
354 { NULL, ITE_PMC4, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
355 /* Power Management I/F Channel 5 (PMC5) */
356 { NULL, ITE_PMC5, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
357};
358
359static void enable_dev(struct device *dev)
360{
361 pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
362}
363
364struct chip_operations ec_starlabs_merlin_ops = {
365 CHIP_NAME("ITE EC")
366 .enable_dev = enable_dev
367};