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