blob: a096fe838948994d57b58481f5ab2ba006210763 [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>
9
10#include "ec.h"
11#include "ecdefs.h"
12
Sean Rhodes6082ee52022-03-09 08:07:30 +000013uint16_t ec_get_version(void)
Sean Rhodes296994b2021-10-14 20:58:15 +010014{
15 return (ec_read(ECRAM_MAJOR_VERSION) << 8) | ec_read(ECRAM_MINOR_VERSION);
16}
17
18static uint8_t get_ec_value_from_option(const char *name,
19 unsigned int fallback,
20 const uint8_t *lut,
21 size_t lut_size)
22{
23 unsigned int index = get_uint_option(name, fallback);
24 if (index >= lut_size)
25 index = fallback;
26 return lut[index];
27}
28
Sean Rhodes0579c602023-02-16 15:00:14 +000029void ec_mirror_flag(void)
30{
31 /*
32 * For the mirror flag to work, the status of the EC pin must be known
33 * at all times, which means external power. This can be either a DC
34 * charger, or PD with CCG6. PD with an ANX7447 requires configuration
35 * from the EC, so the update will interrupt this.
36 *
37 * This means we can unconditionally apply the mirror flag to devices
38 * that have CCG6, present on devices with TBT, but have a manual
39 * flag for devices without it.
40 */
Sean Rhodes7d00b7c2023-07-07 14:27:28 +010041 uint16_t ec_version = ec_get_version();
42
Sean Rhodesded5a602023-09-20 14:51:57 +010043 /* Full mirror support was added in EC 1.18 (0x0112) */
44 if (ec_version < 0x0112)
45 return;
46
Sean Rhodes0579c602023-02-16 15:00:14 +000047 if (CONFIG(EC_STARLABS_MIRROR_SUPPORT) &&
Sean Rhodese4fd5612023-07-18 11:49:19 +010048 (CONFIG(DRIVERS_INTEL_USB4_RETIMER) || get_uint_option("mirror_flag", 0)) &&
Sean Rhodes7d00b7c2023-07-07 14:27:28 +010049 (ec_version != CONFIG_EC_STARLABS_MIRROR_VERSION)) {
50 printk(BIOS_ERR, "ITE: EC version 0x%x doesn't match coreboot version 0x%x.\n",
51 ec_version, CONFIG_EC_STARLABS_MIRROR_VERSION);
Sean Rhodesded5a602023-09-20 14:51:57 +010052
53 ec_write(ECRAM_MIRROR_FLAG, MIRROR_ENABLED);
Sean Rhodes0579c602023-02-16 15:00:14 +000054 }
55}
56
Sean Rhodes6082ee52022-03-09 08:07:30 +000057static uint16_t ec_get_chip_id(unsigned int port)
Sean Rhodes296994b2021-10-14 20:58:15 +010058{
59 return (pnp_read_index(port, ITE_CHIPID1) << 8) |
60 pnp_read_index(port, ITE_CHIPID2);
61}
62
63static void merlin_init(struct device *dev)
64{
65 if (!dev->enabled)
66 return;
67
68 /*
69 * The address/data IO port pair for the ite EC are configurable
70 * through the EC domain and are fixed by the EC's firmware blob. If
71 * the value(s) passed through the "dev" structure don't match the
72 * expected values then output severe warnings.
73 */
74 if (dev->path.pnp.port != ITE_FIXED_ADDR) {
75 printk(BIOS_ERR, "ITE: Incorrect ports defined in devicetree.cb.\n");
76 printk(BIOS_ERR, "ITE: Serious operational issues will arise.\n");
77 return;
78 }
79
Sean Rhodes6082ee52022-03-09 08:07:30 +000080 const uint16_t chip_id = ec_get_chip_id(dev->path.pnp.port);
Sean Rhodes296994b2021-10-14 20:58:15 +010081
82 if (chip_id != ITE_CHIPID_VAL) {
83 printk(BIOS_ERR, "ITE: Expected chip ID 0x%04x, but got 0x%04x instead.\n",
84 ITE_CHIPID_VAL, chip_id);
85 return;
86 }
87
Sean Rhodes0579c602023-02-16 15:00:14 +000088 ec_mirror_flag();
89
Sean Rhodes296994b2021-10-14 20:58:15 +010090 /*
91 * Restore settings from CMOS into EC RAM:
92 *
93 * kbl_timeout
94 * fn_ctrl_swap
95 * max_charge
96 * fan_mode
97 * fn_lock_state
98 * trackpad_state
99 * kbl_brightness
100 * kbl_state
101 */
102
103 /*
104 * Keyboard Backlight Timeout
105 *
106 * Setting: kbl_timeout
107 *
108 * Values: 30 Seconds, 1 Minute, 3 Minutes, 5 Minutes, Never
109 * Default: 30 Seconds
110 *
111 */
112 const uint8_t kbl_timeout[] = {
113 SEC_30,
114 MIN_1,
115 MIN_3,
116 MIN_5,
117 NEVER
118 };
119
120 ec_write(ECRAM_KBL_TIMEOUT,
121 get_ec_value_from_option("kbl_timeout",
122 0,
123 kbl_timeout,
124 ARRAY_SIZE(kbl_timeout)));
125
126 /*
127 * Fn Ctrl Reverse
128 *
129 * Setting: fn_ctrl_swap
130 *
131 * Values: Enabled, Disabled
132 * Default: Disabled
133 *
134 */
135 const uint8_t fn_ctrl_swap[] = {
136 FN_CTRL,
137 CTRL_FN
138 };
139
140 ec_write(ECRAM_FN_CTRL_REVERSE,
141 get_ec_value_from_option("fn_ctrl_swap",
Sean Rhodesc45cfad2023-04-25 22:51:57 +0100142 0,
Sean Rhodes296994b2021-10-14 20:58:15 +0100143 fn_ctrl_swap,
144 ARRAY_SIZE(fn_ctrl_swap)));
145
146 /*
147 * Maximum Charge Level
148 *
149 * Setting: max_charge
150 *
151 * Values: 60%, 80%, 100%
152 * Default: 100%
153 *
154 */
155 const uint8_t max_charge[] = {
156 CHARGE_100,
157 CHARGE_80,
158 CHARGE_60
159 };
160
Sean Rhodes4d1bf7b2022-02-17 13:55:34 +0000161 if (CONFIG(EC_STARLABS_MAX_CHARGE))
162 ec_write(ECRAM_MAX_CHARGE,
163 get_ec_value_from_option("max_charge",
164 0,
165 max_charge,
166 ARRAY_SIZE(max_charge)));
Sean Rhodes296994b2021-10-14 20:58:15 +0100167
168 /*
169 * Fan Mode
170 *
171 * Setting: fan_mode
172 *
173 * Values: Quiet, Normal, Aggressive
174 * Default: Normal
175 *
176 */
177 const uint8_t fan_mode[] = {
178 FAN_NORMAL,
179 FAN_AGGRESSIVE,
180 FAN_QUIET
181 };
182
183 if (CONFIG(EC_STARLABS_FAN))
184 ec_write(ECRAM_FAN_MODE,
185 get_ec_value_from_option("fan_mode",
186 0,
187 fan_mode,
188 ARRAY_SIZE(fan_mode)));
189
190 /*
191 * Function Lock
192 *
193 * Setting: fn_lock_state
194 *
195 * Values: Locked, Unlocked
196 * Default: Locked
197 *
198 */
199 const uint8_t fn_lock_state[] = {
200 UNLOCKED,
201 LOCKED
202 };
203
204 ec_write(ECRAM_FN_LOCK_STATE,
205 get_ec_value_from_option("fn_lock_state",
206 1,
207 fn_lock_state,
208 ARRAY_SIZE(fn_lock_state)));
209
210 /*
211 * Trackpad State
212 *
213 * Setting: trackpad_state
214 *
215 * Values: Enabled, Disabled
216 * Default: Enabled
217 *
218 */
219 const uint8_t trackpad_state[] = {
220 TRACKPAD_ENABLED,
221 TRACKPAD_DISABLED
222 };
223
224 ec_write(ECRAM_TRACKPAD_STATE,
225 get_ec_value_from_option("trackpad_state",
226 0,
227 trackpad_state,
228 ARRAY_SIZE(trackpad_state)));
229
230 /*
231 * Keyboard Backlight Brightness
232 *
233 * Setting: kbl_brightness
234 *
235 * Values: Off, Low, High / Off, On
236 * Default: Low
237 *
238 */
239 const uint8_t kbl_brightness[] = {
240 KBL_ON,
241 KBL_OFF,
242 KBL_LOW,
243 KBL_HIGH
244 };
245
246 if (CONFIG(EC_STARLABS_KBL_LEVELS))
247 ec_write(ECRAM_KBL_BRIGHTNESS,
248 get_ec_value_from_option("kbl_brightness",
249 2,
250 kbl_brightness,
251 ARRAY_SIZE(kbl_brightness)));
252 else
253 ec_write(ECRAM_KBL_BRIGHTNESS,
254 get_ec_value_from_option("kbl_brightness",
255 0,
256 kbl_brightness,
257 ARRAY_SIZE(kbl_brightness)));
258
259 /*
260 * Keyboard Backlight State
261 *
262 * Setting: kbl_state
263 *
264 * Values: Off, On
265 * Default: On
266 *
Sean Rhodescbedae12023-08-16 09:25:42 +0100267 * Note: Always enable, as the brightness level of `off` disables it.
268 *
Sean Rhodes296994b2021-10-14 20:58:15 +0100269 */
Sean Rhodes296994b2021-10-14 20:58:15 +0100270
Sean Rhodescbedae12023-08-16 09:25:42 +0100271 ec_write(ECRAM_KBL_STATE, KBL_ENABLED);
Sean Rhodes296994b2021-10-14 20:58:15 +0100272}
273
274static struct device_operations ops = {
275 .init = merlin_init,
276 .read_resources = noop_read_resources,
277 .set_resources = noop_set_resources,
278};
279
280static struct pnp_info pnp_dev_info[] = {
281 /* Serial Port 1 (UART1) */
282 { NULL, ITE_SP1, PNP_IO0 | PNP_IRQ0, 0x0ff8, },
283 /* Serial Port 2 (UART2) */
284 { NULL, ITE_SP2, PNP_IO0 | PNP_IRQ0, 0x0ff8, },
285 /* System Wake-Up Control (SWUC) */
286 { NULL, ITE_SWUC, PNP_IO0 | PNP_IRQ0, 0xfff0, },
287 /* KBC / Mouse Interface */
288 { NULL, ITE_SWUC, PNP_IRQ0, },
289 /* KBC / Keyboard Interface */
290 { NULL, ITE_KBCK, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
291 /* Consumer IR (CIR) */
292 { NULL, ITE_IR, PNP_IO0 | PNP_IRQ0, 0xfff8, },
293 /* Shared Memory / Flash Interface (SMFI) */
294 { NULL, ITE_SMFI, PNP_IO0 | PNP_IRQ0, 0xfff0, },
295 /* RTC-like Timer (RCTC) */
296 { NULL, ITE_RTCT, PNP_IO0 | PNP_IO1 | PNP_IO2 | PNP_IO3 | PNP_IRQ0,
297 0xfffe, 0xfffe, 0xfffe, 0xfffe, },
298 /* Power Management I/F Channel 1 (PMC1) */
299 { NULL, ITE_PMC1, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
300 /* Power Management I/F Channel 2 (PMC2) */
301 { NULL, ITE_PMC2, PNP_IO0 | PNP_IO1 | PNP_IO2 | PNP_IRQ0, 0x07fc,
302 0x07fc, 0xfff0, },
303 /* Serial Peripheral Interface (SSPI) */
304 { NULL, ITE_SSPI, PNP_IO0 | PNP_IRQ0, 0xfff8, },
305 /* Platform Environment Control Interface (PECI) */
306 { NULL, ITE_PECI, PNP_IRQ0, 0xfff8, },
307 /* Power Management I/F Channel 3 (PMC3) */
308 { NULL, ITE_PMC3, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
309 /* Power Management I/F Channel 4 (PMC4) */
310 { NULL, ITE_PMC4, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
311 /* Power Management I/F Channel 5 (PMC5) */
312 { NULL, ITE_PMC5, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
313};
314
315static void enable_dev(struct device *dev)
316{
317 pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
318}
319
320struct chip_operations ec_starlabs_merlin_ops = {
Nicholas Sudsgaardbfb11be2024-01-30 09:53:46 +0900321 .name = "ITE EC",
Sean Rhodes296994b2021-10-14 20:58:15 +0100322 .enable_dev = enable_dev
323};