blob: 50e13e95c0b953c521aee28d1c8828b64c5932ad [file] [log] [blame]
Sean Rhodes296994b2021-10-14 20:58:15 +01001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <console/console.h>
4#include <delay.h>
5#include <device/device.h>
6#include <device/pnp.h>
7#include <ec/acpi/ec.h>
8#include <option.h>
9#include <pc80/keyboard.h>
10
11#include "ec.h"
12#include "ecdefs.h"
13
14uint16_t it_get_version(void)
15{
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
30static uint16_t ite_get_chip_id(unsigned int port)
31{
32 return (pnp_read_index(port, ITE_CHIPID1) << 8) |
33 pnp_read_index(port, ITE_CHIPID2);
34}
35
36static void merlin_init(struct device *dev)
37{
38 if (!dev->enabled)
39 return;
40
41 /*
42 * The address/data IO port pair for the ite EC are configurable
43 * through the EC domain and are fixed by the EC's firmware blob. If
44 * the value(s) passed through the "dev" structure don't match the
45 * expected values then output severe warnings.
46 */
47 if (dev->path.pnp.port != ITE_FIXED_ADDR) {
48 printk(BIOS_ERR, "ITE: Incorrect ports defined in devicetree.cb.\n");
49 printk(BIOS_ERR, "ITE: Serious operational issues will arise.\n");
50 return;
51 }
52
53 const uint16_t chip_id = ite_get_chip_id(dev->path.pnp.port);
54
55 if (chip_id != ITE_CHIPID_VAL) {
56 printk(BIOS_ERR, "ITE: Expected chip ID 0x%04x, but got 0x%04x instead.\n",
57 ITE_CHIPID_VAL, chip_id);
58 return;
59 }
60
61 pc_keyboard_init(NO_AUX_DEVICE);
62
63 /*
64 * Restore settings from CMOS into EC RAM:
65 *
66 * kbl_timeout
67 * fn_ctrl_swap
68 * max_charge
69 * fan_mode
70 * fn_lock_state
71 * trackpad_state
72 * kbl_brightness
73 * kbl_state
74 */
75
76 /*
77 * Keyboard Backlight Timeout
78 *
79 * Setting: kbl_timeout
80 *
81 * Values: 30 Seconds, 1 Minute, 3 Minutes, 5 Minutes, Never
82 * Default: 30 Seconds
83 *
84 */
85 const uint8_t kbl_timeout[] = {
86 SEC_30,
87 MIN_1,
88 MIN_3,
89 MIN_5,
90 NEVER
91 };
92
93 ec_write(ECRAM_KBL_TIMEOUT,
94 get_ec_value_from_option("kbl_timeout",
95 0,
96 kbl_timeout,
97 ARRAY_SIZE(kbl_timeout)));
98
99 /*
100 * Fn Ctrl Reverse
101 *
102 * Setting: fn_ctrl_swap
103 *
104 * Values: Enabled, Disabled
105 * Default: Disabled
106 *
107 */
108 const uint8_t fn_ctrl_swap[] = {
109 FN_CTRL,
110 CTRL_FN
111 };
112
113 ec_write(ECRAM_FN_CTRL_REVERSE,
114 get_ec_value_from_option("fn_ctrl_swap",
115 1,
116 fn_ctrl_swap,
117 ARRAY_SIZE(fn_ctrl_swap)));
118
119 /*
120 * Maximum Charge Level
121 *
122 * Setting: max_charge
123 *
124 * Values: 60%, 80%, 100%
125 * Default: 100%
126 *
127 */
128 const uint8_t max_charge[] = {
129 CHARGE_100,
130 CHARGE_80,
131 CHARGE_60
132 };
133
134 ec_write(ECRAM_MAX_CHARGE,
135 get_ec_value_from_option("max_charge",
136 0,
137 max_charge,
138 ARRAY_SIZE(max_charge)));
139
140 /*
141 * Fan Mode
142 *
143 * Setting: fan_mode
144 *
145 * Values: Quiet, Normal, Aggressive
146 * Default: Normal
147 *
148 */
149 const uint8_t fan_mode[] = {
150 FAN_NORMAL,
151 FAN_AGGRESSIVE,
152 FAN_QUIET
153 };
154
155 if (CONFIG(EC_STARLABS_FAN))
156 ec_write(ECRAM_FAN_MODE,
157 get_ec_value_from_option("fan_mode",
158 0,
159 fan_mode,
160 ARRAY_SIZE(fan_mode)));
161
162 /*
163 * Function Lock
164 *
165 * Setting: fn_lock_state
166 *
167 * Values: Locked, Unlocked
168 * Default: Locked
169 *
170 */
171 const uint8_t fn_lock_state[] = {
172 UNLOCKED,
173 LOCKED
174 };
175
176 ec_write(ECRAM_FN_LOCK_STATE,
177 get_ec_value_from_option("fn_lock_state",
178 1,
179 fn_lock_state,
180 ARRAY_SIZE(fn_lock_state)));
181
182 /*
183 * Trackpad State
184 *
185 * Setting: trackpad_state
186 *
187 * Values: Enabled, Disabled
188 * Default: Enabled
189 *
190 */
191 const uint8_t trackpad_state[] = {
192 TRACKPAD_ENABLED,
193 TRACKPAD_DISABLED
194 };
195
196 ec_write(ECRAM_TRACKPAD_STATE,
197 get_ec_value_from_option("trackpad_state",
198 0,
199 trackpad_state,
200 ARRAY_SIZE(trackpad_state)));
201
202 /*
203 * Keyboard Backlight Brightness
204 *
205 * Setting: kbl_brightness
206 *
207 * Values: Off, Low, High / Off, On
208 * Default: Low
209 *
210 */
211 const uint8_t kbl_brightness[] = {
212 KBL_ON,
213 KBL_OFF,
214 KBL_LOW,
215 KBL_HIGH
216 };
217
218 if (CONFIG(EC_STARLABS_KBL_LEVELS))
219 ec_write(ECRAM_KBL_BRIGHTNESS,
220 get_ec_value_from_option("kbl_brightness",
221 2,
222 kbl_brightness,
223 ARRAY_SIZE(kbl_brightness)));
224 else
225 ec_write(ECRAM_KBL_BRIGHTNESS,
226 get_ec_value_from_option("kbl_brightness",
227 0,
228 kbl_brightness,
229 ARRAY_SIZE(kbl_brightness)));
230
231 /*
232 * Keyboard Backlight State
233 *
234 * Setting: kbl_state
235 *
236 * Values: Off, On
237 * Default: On
238 *
239 */
240 const uint8_t kbl_state[] = {
241 KBL_DISABLED,
242 KBL_ENABLED
243 };
244
245 ec_write(ECRAM_KBL_STATE,
246 get_ec_value_from_option("kbl_state",
247 1,
248 kbl_state,
249 ARRAY_SIZE(kbl_state)));
250}
251
252static struct device_operations ops = {
253 .init = merlin_init,
254 .read_resources = noop_read_resources,
255 .set_resources = noop_set_resources,
256};
257
258static struct pnp_info pnp_dev_info[] = {
259 /* Serial Port 1 (UART1) */
260 { NULL, ITE_SP1, PNP_IO0 | PNP_IRQ0, 0x0ff8, },
261 /* Serial Port 2 (UART2) */
262 { NULL, ITE_SP2, PNP_IO0 | PNP_IRQ0, 0x0ff8, },
263 /* System Wake-Up Control (SWUC) */
264 { NULL, ITE_SWUC, PNP_IO0 | PNP_IRQ0, 0xfff0, },
265 /* KBC / Mouse Interface */
266 { NULL, ITE_SWUC, PNP_IRQ0, },
267 /* KBC / Keyboard Interface */
268 { NULL, ITE_KBCK, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
269 /* Consumer IR (CIR) */
270 { NULL, ITE_IR, PNP_IO0 | PNP_IRQ0, 0xfff8, },
271 /* Shared Memory / Flash Interface (SMFI) */
272 { NULL, ITE_SMFI, PNP_IO0 | PNP_IRQ0, 0xfff0, },
273 /* RTC-like Timer (RCTC) */
274 { NULL, ITE_RTCT, PNP_IO0 | PNP_IO1 | PNP_IO2 | PNP_IO3 | PNP_IRQ0,
275 0xfffe, 0xfffe, 0xfffe, 0xfffe, },
276 /* Power Management I/F Channel 1 (PMC1) */
277 { NULL, ITE_PMC1, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
278 /* Power Management I/F Channel 2 (PMC2) */
279 { NULL, ITE_PMC2, PNP_IO0 | PNP_IO1 | PNP_IO2 | PNP_IRQ0, 0x07fc,
280 0x07fc, 0xfff0, },
281 /* Serial Peripheral Interface (SSPI) */
282 { NULL, ITE_SSPI, PNP_IO0 | PNP_IRQ0, 0xfff8, },
283 /* Platform Environment Control Interface (PECI) */
284 { NULL, ITE_PECI, PNP_IRQ0, 0xfff8, },
285 /* Power Management I/F Channel 3 (PMC3) */
286 { NULL, ITE_PMC3, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
287 /* Power Management I/F Channel 4 (PMC4) */
288 { NULL, ITE_PMC4, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
289 /* Power Management I/F Channel 5 (PMC5) */
290 { NULL, ITE_PMC5, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, },
291};
292
293static void enable_dev(struct device *dev)
294{
295 pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info);
296}
297
298struct chip_operations ec_starlabs_merlin_ops = {
299 CHIP_NAME("ITE EC")
300 .enable_dev = enable_dev
301};