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