xref: /linux/drivers/platform/x86/lg-laptop.c (revision bb97142197df73fbbb0e6f8629dc1f89ef6960f7)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * lg-laptop.c - LG Gram ACPI features and hotkeys Driver
4  *
5  * Copyright (C) 2018 Matan Ziv-Av <matan@svgalib.org>
6  */
7 
8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9 
10 #include <linux/acpi.h>
11 #include <linux/bitfield.h>
12 #include <linux/bits.h>
13 #include <linux/device.h>
14 #include <linux/dev_printk.h>
15 #include <linux/dmi.h>
16 #include <linux/input.h>
17 #include <linux/input/sparse-keymap.h>
18 #include <linux/kernel.h>
19 #include <linux/leds.h>
20 #include <linux/module.h>
21 #include <linux/platform_device.h>
22 #include <linux/types.h>
23 
24 #include <acpi/battery.h>
25 
26 #define LED_DEVICE(_name, max, flag) struct led_classdev _name = { \
27 	.name           = __stringify(_name),   \
28 	.max_brightness = max,                  \
29 	.brightness_set = _name##_set,          \
30 	.brightness_get = _name##_get,          \
31 	.flags = flag,                          \
32 }
33 
34 MODULE_AUTHOR("Matan Ziv-Av");
35 MODULE_DESCRIPTION("LG WMI Hotkey Driver");
36 MODULE_LICENSE("GPL");
37 
38 static bool fw_debug;
39 module_param(fw_debug, bool, 0);
40 MODULE_PARM_DESC(fw_debug, "Enable printing of firmware debug messages");
41 
42 #define LG_ADDRESS_SPACE_ID			0x8F
43 
44 #define LG_ADDRESS_SPACE_DEBUG_FLAG_ADR		0x00
45 #define LG_ADDRESS_SPACE_FAN_MODE_ADR		0x03
46 
47 #define LG_ADDRESS_SPACE_DTTM_FLAG_ADR		0x20
48 #define LG_ADDRESS_SPACE_CPU_TEMP_ADR		0x21
49 #define LG_ADDRESS_SPACE_CPU_TRIP_LOW_ADR	0x22
50 #define LG_ADDRESS_SPACE_CPU_TRIP_HIGH_ADR	0x23
51 #define LG_ADDRESS_SPACE_MB_TEMP_ADR		0x24
52 #define LG_ADDRESS_SPACE_MB_TRIP_LOW_ADR	0x25
53 #define LG_ADDRESS_SPACE_MB_TRIP_HIGH_ADR	0x26
54 
55 #define LG_ADDRESS_SPACE_DEBUG_MSG_START_ADR	0x3E8
56 #define LG_ADDRESS_SPACE_DEBUG_MSG_END_ADR	0x5E8
57 
58 #define WMI_EVENT_GUID0	"E4FB94F9-7F2B-4173-AD1A-CD1D95086248"
59 #define WMI_EVENT_GUID1	"023B133E-49D1-4E10-B313-698220140DC2"
60 #define WMI_EVENT_GUID2	"37BE1AC0-C3F2-4B1F-BFBE-8FDEAF2814D6"
61 #define WMI_EVENT_GUID3	"911BAD44-7DF8-4FBB-9319-BABA1C4B293B"
62 #define WMI_METHOD_WMAB "C3A72B38-D3EF-42D3-8CBB-D5A57049F66D"
63 #define WMI_METHOD_WMBB "2B4F501A-BD3C-4394-8DCF-00A7D2BC8210"
64 #define WMI_EVENT_GUID  WMI_EVENT_GUID0
65 
66 #define SB_GGOV_METHOD  "\\_SB.GGOV"
67 #define GOV_TLED        0x2020008
68 #define WM_GET          1
69 #define WM_SET          2
70 #define WM_KEY_LIGHT    0x400
71 #define WM_TLED         0x404
72 #define WM_FN_LOCK      0x407
73 #define WM_BATT_LIMIT   0x61
74 #define WM_READER_MODE  0xBF
75 #define WM_FAN_MODE	0x33
76 #define WMBB_USB_CHARGE 0x10B
77 #define WMBB_BATT_LIMIT 0x10C
78 
79 #define FAN_MODE_LOWER GENMASK(1, 0)
80 #define FAN_MODE_UPPER GENMASK(5, 4)
81 
82 #define PLATFORM_NAME   "lg-laptop"
83 
84 MODULE_ALIAS("wmi:" WMI_EVENT_GUID0);
85 MODULE_ALIAS("wmi:" WMI_EVENT_GUID1);
86 MODULE_ALIAS("wmi:" WMI_EVENT_GUID2);
87 MODULE_ALIAS("wmi:" WMI_EVENT_GUID3);
88 MODULE_ALIAS("wmi:" WMI_METHOD_WMAB);
89 MODULE_ALIAS("wmi:" WMI_METHOD_WMBB);
90 
91 static struct platform_device *pf_device;
92 static struct input_dev *wmi_input_dev;
93 
94 static u32 inited;
95 #define INIT_INPUT_WMI_0        0x01
96 #define INIT_INPUT_WMI_2        0x02
97 #define INIT_INPUT_ACPI         0x04
98 #define INIT_SPARSE_KEYMAP      0x80
99 
100 static int battery_limit_use_wmbb;
101 static struct led_classdev kbd_backlight;
102 static enum led_brightness get_kbd_backlight_level(struct device *dev);
103 
104 static const struct key_entry wmi_keymap[] = {
105 	{KE_KEY, 0x70, {KEY_F15} },	 /* LG control panel (F1) */
106 	{KE_KEY, 0x74, {KEY_F21} },	 /* Touchpad toggle (F5) */
107 	{KE_KEY, 0xf020000, {KEY_F14} }, /* Read mode (F9) */
108 	{KE_KEY, 0x10000000, {KEY_F16} },/* Keyboard backlight (F8) - pressing
109 					  * this key both sends an event and
110 					  * changes backlight level.
111 					  */
112 	{KE_END, 0}
113 };
114 
ggov(u32 arg0)115 static int ggov(u32 arg0)
116 {
117 	union acpi_object args[1];
118 	union acpi_object *r;
119 	acpi_status status;
120 	acpi_handle handle;
121 	struct acpi_object_list arg;
122 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
123 	int res;
124 
125 	args[0].type = ACPI_TYPE_INTEGER;
126 	args[0].integer.value = arg0;
127 
128 	status = acpi_get_handle(NULL, (acpi_string) SB_GGOV_METHOD, &handle);
129 	if (ACPI_FAILURE(status)) {
130 		pr_err("Cannot get handle");
131 		return -ENODEV;
132 	}
133 
134 	arg.count = 1;
135 	arg.pointer = args;
136 
137 	status = acpi_evaluate_object(handle, NULL, &arg, &buffer);
138 	if (ACPI_FAILURE(status)) {
139 		acpi_handle_err(handle, "GGOV: call failed.\n");
140 		return -EINVAL;
141 	}
142 
143 	r = buffer.pointer;
144 	if (r->type != ACPI_TYPE_INTEGER) {
145 		kfree(r);
146 		return -EINVAL;
147 	}
148 
149 	res = r->integer.value;
150 	kfree(r);
151 
152 	return res;
153 }
154 
lg_wmab(struct device * dev,u32 method,u32 arg1,u32 arg2)155 static union acpi_object *lg_wmab(struct device *dev, u32 method, u32 arg1, u32 arg2)
156 {
157 	union acpi_object args[3];
158 	acpi_status status;
159 	struct acpi_object_list arg;
160 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
161 
162 	args[0].type = ACPI_TYPE_INTEGER;
163 	args[0].integer.value = method;
164 	args[1].type = ACPI_TYPE_INTEGER;
165 	args[1].integer.value = arg1;
166 	args[2].type = ACPI_TYPE_INTEGER;
167 	args[2].integer.value = arg2;
168 
169 	arg.count = 3;
170 	arg.pointer = args;
171 
172 	status = acpi_evaluate_object(ACPI_HANDLE(dev), "WMAB", &arg, &buffer);
173 	if (ACPI_FAILURE(status)) {
174 		dev_err(dev, "WMAB: call failed.\n");
175 		return NULL;
176 	}
177 
178 	return buffer.pointer;
179 }
180 
lg_wmbb(struct device * dev,u32 method_id,u32 arg1,u32 arg2)181 static union acpi_object *lg_wmbb(struct device *dev, u32 method_id, u32 arg1, u32 arg2)
182 {
183 	union acpi_object args[3];
184 	acpi_status status;
185 	struct acpi_object_list arg;
186 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
187 	u8 buf[32];
188 
189 	*(u32 *)buf = method_id;
190 	*(u32 *)(buf + 4) = arg1;
191 	*(u32 *)(buf + 16) = arg2;
192 	args[0].type = ACPI_TYPE_INTEGER;
193 	args[0].integer.value = 0; /* ignored */
194 	args[1].type = ACPI_TYPE_INTEGER;
195 	args[1].integer.value = 1; /* Must be 1 or 2. Does not matter which */
196 	args[2].type = ACPI_TYPE_BUFFER;
197 	args[2].buffer.length = 32;
198 	args[2].buffer.pointer = buf;
199 
200 	arg.count = 3;
201 	arg.pointer = args;
202 
203 	status = acpi_evaluate_object(ACPI_HANDLE(dev), "WMBB", &arg, &buffer);
204 	if (ACPI_FAILURE(status)) {
205 		dev_err(dev, "WMBB: call failed.\n");
206 		return NULL;
207 	}
208 
209 	return (union acpi_object *)buffer.pointer;
210 }
211 
wmi_notify(union acpi_object * obj,void * context)212 static void wmi_notify(union acpi_object *obj, void *context)
213 {
214 	long data = (long)context;
215 
216 	pr_debug("event guid %li\n", data);
217 	if (!obj)
218 		return;
219 
220 	if (obj->type == ACPI_TYPE_INTEGER) {
221 		int eventcode = obj->integer.value;
222 		struct key_entry *key;
223 
224 		if (eventcode == 0x10000000) {
225 			led_classdev_notify_brightness_hw_changed(
226 				&kbd_backlight, get_kbd_backlight_level(kbd_backlight.dev->parent));
227 		} else {
228 			key = sparse_keymap_entry_from_scancode(
229 				wmi_input_dev, eventcode);
230 			if (key && key->type == KE_KEY)
231 				sparse_keymap_report_entry(wmi_input_dev,
232 							   key, 1, true);
233 		}
234 	}
235 
236 	pr_debug("Type: %i    Eventcode: 0x%llx\n", obj->type,
237 		 obj->integer.value);
238 }
239 
wmi_input_setup(void)240 static void wmi_input_setup(void)
241 {
242 	acpi_status status;
243 
244 	wmi_input_dev = input_allocate_device();
245 	if (wmi_input_dev) {
246 		wmi_input_dev->name = "LG WMI hotkeys";
247 		wmi_input_dev->phys = "wmi/input0";
248 		wmi_input_dev->id.bustype = BUS_HOST;
249 
250 		if (sparse_keymap_setup(wmi_input_dev, wmi_keymap, NULL) ||
251 		    input_register_device(wmi_input_dev)) {
252 			pr_info("Cannot initialize input device");
253 			input_free_device(wmi_input_dev);
254 			return;
255 		}
256 
257 		inited |= INIT_SPARSE_KEYMAP;
258 		status = wmi_install_notify_handler(WMI_EVENT_GUID0, wmi_notify,
259 						    (void *)0);
260 		if (ACPI_SUCCESS(status))
261 			inited |= INIT_INPUT_WMI_0;
262 
263 		status = wmi_install_notify_handler(WMI_EVENT_GUID2, wmi_notify,
264 						    (void *)2);
265 		if (ACPI_SUCCESS(status))
266 			inited |= INIT_INPUT_WMI_2;
267 	} else {
268 		pr_info("Cannot allocate input device");
269 	}
270 }
271 
acpi_notify(struct acpi_device * device,u32 event)272 static void acpi_notify(struct acpi_device *device, u32 event)
273 {
274 	acpi_handle_debug(device->handle, "notify: %d\n", event);
275 }
276 
fan_mode_store(struct device * dev,struct device_attribute * attr,const char * buffer,size_t count)277 static ssize_t fan_mode_store(struct device *dev,
278 			      struct device_attribute *attr,
279 			      const char *buffer, size_t count)
280 {
281 	unsigned long value;
282 	union acpi_object *r;
283 	int ret;
284 
285 	ret = kstrtoul(buffer, 10, &value);
286 	if (ret)
287 		return ret;
288 	if (value >= 3)
289 		return -EINVAL;
290 
291 	r = lg_wmab(dev, WM_FAN_MODE, WM_SET,
292 		FIELD_PREP(FAN_MODE_LOWER, value) |
293 		FIELD_PREP(FAN_MODE_UPPER, value));
294 	kfree(r);
295 
296 	return count;
297 }
298 
fan_mode_show(struct device * dev,struct device_attribute * attr,char * buffer)299 static ssize_t fan_mode_show(struct device *dev,
300 			     struct device_attribute *attr, char *buffer)
301 {
302 	unsigned int mode;
303 	union acpi_object *r;
304 
305 	r = lg_wmab(dev, WM_FAN_MODE, WM_GET, 0);
306 	if (!r)
307 		return -EIO;
308 
309 	if (r->type != ACPI_TYPE_INTEGER) {
310 		kfree(r);
311 		return -EIO;
312 	}
313 
314 	mode = FIELD_GET(FAN_MODE_LOWER, r->integer.value);
315 	kfree(r);
316 
317 	return sysfs_emit(buffer, "%d\n", mode);
318 }
319 
usb_charge_store(struct device * dev,struct device_attribute * attr,const char * buffer,size_t count)320 static ssize_t usb_charge_store(struct device *dev,
321 				struct device_attribute *attr,
322 				const char *buffer, size_t count)
323 {
324 	bool value;
325 	union acpi_object *r;
326 	int ret;
327 
328 	ret = kstrtobool(buffer, &value);
329 	if (ret)
330 		return ret;
331 
332 	r = lg_wmbb(dev, WMBB_USB_CHARGE, WM_SET, value);
333 	if (!r)
334 		return -EIO;
335 
336 	kfree(r);
337 	return count;
338 }
339 
usb_charge_show(struct device * dev,struct device_attribute * attr,char * buffer)340 static ssize_t usb_charge_show(struct device *dev,
341 			       struct device_attribute *attr, char *buffer)
342 {
343 	unsigned int status;
344 	union acpi_object *r;
345 
346 	r = lg_wmbb(dev, WMBB_USB_CHARGE, WM_GET, 0);
347 	if (!r)
348 		return -EIO;
349 
350 	if (r->type != ACPI_TYPE_BUFFER) {
351 		kfree(r);
352 		return -EIO;
353 	}
354 
355 	status = !!r->buffer.pointer[0x10];
356 
357 	kfree(r);
358 
359 	return sysfs_emit(buffer, "%d\n", status);
360 }
361 
reader_mode_store(struct device * dev,struct device_attribute * attr,const char * buffer,size_t count)362 static ssize_t reader_mode_store(struct device *dev,
363 				 struct device_attribute *attr,
364 				 const char *buffer, size_t count)
365 {
366 	bool value;
367 	union acpi_object *r;
368 	int ret;
369 
370 	ret = kstrtobool(buffer, &value);
371 	if (ret)
372 		return ret;
373 
374 	r = lg_wmab(dev, WM_READER_MODE, WM_SET, value);
375 	if (!r)
376 		return -EIO;
377 
378 	kfree(r);
379 	return count;
380 }
381 
reader_mode_show(struct device * dev,struct device_attribute * attr,char * buffer)382 static ssize_t reader_mode_show(struct device *dev,
383 				struct device_attribute *attr, char *buffer)
384 {
385 	unsigned int status;
386 	union acpi_object *r;
387 
388 	r = lg_wmab(dev, WM_READER_MODE, WM_GET, 0);
389 	if (!r)
390 		return -EIO;
391 
392 	if (r->type != ACPI_TYPE_INTEGER) {
393 		kfree(r);
394 		return -EIO;
395 	}
396 
397 	status = !!r->integer.value;
398 
399 	kfree(r);
400 
401 	return sysfs_emit(buffer, "%d\n", status);
402 }
403 
fn_lock_store(struct device * dev,struct device_attribute * attr,const char * buffer,size_t count)404 static ssize_t fn_lock_store(struct device *dev,
405 			     struct device_attribute *attr,
406 			     const char *buffer, size_t count)
407 {
408 	bool value;
409 	union acpi_object *r;
410 	int ret;
411 
412 	ret = kstrtobool(buffer, &value);
413 	if (ret)
414 		return ret;
415 
416 	r = lg_wmab(dev, WM_FN_LOCK, WM_SET, value);
417 	if (!r)
418 		return -EIO;
419 
420 	kfree(r);
421 	return count;
422 }
423 
fn_lock_show(struct device * dev,struct device_attribute * attr,char * buffer)424 static ssize_t fn_lock_show(struct device *dev,
425 			    struct device_attribute *attr, char *buffer)
426 {
427 	unsigned int status;
428 	union acpi_object *r;
429 
430 	r = lg_wmab(dev, WM_FN_LOCK, WM_GET, 0);
431 	if (!r)
432 		return -EIO;
433 
434 	if (r->type != ACPI_TYPE_BUFFER) {
435 		kfree(r);
436 		return -EIO;
437 	}
438 
439 	status = !!r->buffer.pointer[0];
440 	kfree(r);
441 
442 	return sysfs_emit(buffer, "%d\n", status);
443 }
444 
charge_control_end_threshold_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)445 static ssize_t charge_control_end_threshold_store(struct device *dev,
446 						  struct device_attribute *attr,
447 						  const char *buf, size_t count)
448 {
449 	unsigned long value;
450 	int ret;
451 
452 	ret = kstrtoul(buf, 10, &value);
453 	if (ret)
454 		return ret;
455 
456 	if (value == 100 || value == 80) {
457 		union acpi_object *r;
458 
459 		if (battery_limit_use_wmbb)
460 			r = lg_wmbb(&pf_device->dev, WMBB_BATT_LIMIT, WM_SET, value);
461 		else
462 			r = lg_wmab(&pf_device->dev, WM_BATT_LIMIT, WM_SET, value);
463 		if (!r)
464 			return -EIO;
465 
466 		kfree(r);
467 		return count;
468 	}
469 
470 	return -EINVAL;
471 }
472 
charge_control_end_threshold_show(struct device * device,struct device_attribute * attr,char * buf)473 static ssize_t charge_control_end_threshold_show(struct device *device,
474 						 struct device_attribute *attr,
475 						 char *buf)
476 {
477 	unsigned int status;
478 	union acpi_object *r;
479 
480 	if (battery_limit_use_wmbb) {
481 		r = lg_wmbb(&pf_device->dev, WMBB_BATT_LIMIT, WM_GET, 0);
482 		if (!r)
483 			return -EIO;
484 
485 		if (r->type != ACPI_TYPE_BUFFER) {
486 			kfree(r);
487 			return -EIO;
488 		}
489 
490 		status = r->buffer.pointer[0x10];
491 	} else {
492 		r = lg_wmab(&pf_device->dev, WM_BATT_LIMIT, WM_GET, 0);
493 		if (!r)
494 			return -EIO;
495 
496 		if (r->type != ACPI_TYPE_INTEGER) {
497 			kfree(r);
498 			return -EIO;
499 		}
500 
501 		status = r->integer.value;
502 	}
503 	kfree(r);
504 	if (status != 80 && status != 100)
505 		status = 0;
506 
507 	return sysfs_emit(buf, "%d\n", status);
508 }
509 
battery_care_limit_show(struct device * dev,struct device_attribute * attr,char * buffer)510 static ssize_t battery_care_limit_show(struct device *dev,
511 				       struct device_attribute *attr,
512 				       char *buffer)
513 {
514 	return charge_control_end_threshold_show(dev, attr, buffer);
515 }
516 
battery_care_limit_store(struct device * dev,struct device_attribute * attr,const char * buffer,size_t count)517 static ssize_t battery_care_limit_store(struct device *dev,
518 					struct device_attribute *attr,
519 					const char *buffer, size_t count)
520 {
521 	return charge_control_end_threshold_store(dev, attr, buffer, count);
522 }
523 
524 static DEVICE_ATTR_RW(fan_mode);
525 static DEVICE_ATTR_RW(usb_charge);
526 static DEVICE_ATTR_RW(reader_mode);
527 static DEVICE_ATTR_RW(fn_lock);
528 static DEVICE_ATTR_RW(charge_control_end_threshold);
529 static DEVICE_ATTR_RW(battery_care_limit);
530 
lg_battery_add(struct power_supply * battery,struct acpi_battery_hook * hook)531 static int lg_battery_add(struct power_supply *battery, struct acpi_battery_hook *hook)
532 {
533 	if (device_create_file(&battery->dev,
534 			       &dev_attr_charge_control_end_threshold))
535 		return -ENODEV;
536 
537 	return 0;
538 }
539 
lg_battery_remove(struct power_supply * battery,struct acpi_battery_hook * hook)540 static int lg_battery_remove(struct power_supply *battery, struct acpi_battery_hook *hook)
541 {
542 	device_remove_file(&battery->dev,
543 			   &dev_attr_charge_control_end_threshold);
544 	return 0;
545 }
546 
547 static struct acpi_battery_hook battery_hook = {
548 	.add_battery = lg_battery_add,
549 	.remove_battery = lg_battery_remove,
550 	.name = "LG Battery Extension",
551 };
552 
553 static struct attribute *dev_attributes[] = {
554 	&dev_attr_fan_mode.attr,
555 	&dev_attr_usb_charge.attr,
556 	&dev_attr_reader_mode.attr,
557 	&dev_attr_fn_lock.attr,
558 	&dev_attr_battery_care_limit.attr,
559 	NULL
560 };
561 
562 static const struct attribute_group dev_attribute_group = {
563 	.attrs = dev_attributes,
564 };
565 
tpad_led_set(struct led_classdev * cdev,enum led_brightness brightness)566 static void tpad_led_set(struct led_classdev *cdev,
567 			 enum led_brightness brightness)
568 {
569 	union acpi_object *r;
570 
571 	r = lg_wmab(cdev->dev->parent, WM_TLED, WM_SET, brightness > LED_OFF);
572 	kfree(r);
573 }
574 
tpad_led_get(struct led_classdev * cdev)575 static enum led_brightness tpad_led_get(struct led_classdev *cdev)
576 {
577 	return ggov(GOV_TLED) > 0 ? LED_ON : LED_OFF;
578 }
579 
580 static LED_DEVICE(tpad_led, 1, 0);
581 
kbd_backlight_set(struct led_classdev * cdev,enum led_brightness brightness)582 static void kbd_backlight_set(struct led_classdev *cdev,
583 			      enum led_brightness brightness)
584 {
585 	u32 val;
586 	union acpi_object *r;
587 
588 	val = 0x22;
589 	if (brightness <= LED_OFF)
590 		val = 0;
591 	if (brightness >= LED_FULL)
592 		val = 0x24;
593 	r = lg_wmab(cdev->dev->parent, WM_KEY_LIGHT, WM_SET, val);
594 	kfree(r);
595 }
596 
get_kbd_backlight_level(struct device * dev)597 static enum led_brightness get_kbd_backlight_level(struct device *dev)
598 {
599 	union acpi_object *r;
600 	int val;
601 
602 	r = lg_wmab(dev, WM_KEY_LIGHT, WM_GET, 0);
603 
604 	if (!r)
605 		return LED_OFF;
606 
607 	if (r->type != ACPI_TYPE_BUFFER || r->buffer.pointer[1] != 0x05) {
608 		kfree(r);
609 		return LED_OFF;
610 	}
611 
612 	switch (r->buffer.pointer[0] & 0x27) {
613 	case 0x24:
614 		val = LED_FULL;
615 		break;
616 	case 0x22:
617 		val = LED_HALF;
618 		break;
619 	default:
620 		val = LED_OFF;
621 	}
622 
623 	kfree(r);
624 
625 	return val;
626 }
627 
kbd_backlight_get(struct led_classdev * cdev)628 static enum led_brightness kbd_backlight_get(struct led_classdev *cdev)
629 {
630 	return get_kbd_backlight_level(cdev->dev->parent);
631 }
632 
633 static LED_DEVICE(kbd_backlight, 255, LED_BRIGHT_HW_CHANGED);
634 
wmi_input_destroy(void)635 static void wmi_input_destroy(void)
636 {
637 	if (inited & INIT_INPUT_WMI_2)
638 		wmi_remove_notify_handler(WMI_EVENT_GUID2);
639 
640 	if (inited & INIT_INPUT_WMI_0)
641 		wmi_remove_notify_handler(WMI_EVENT_GUID0);
642 
643 	if (inited & INIT_SPARSE_KEYMAP)
644 		input_unregister_device(wmi_input_dev);
645 
646 	inited &= ~(INIT_INPUT_WMI_0 | INIT_INPUT_WMI_2 | INIT_SPARSE_KEYMAP);
647 }
648 
649 static struct platform_driver pf_driver = {
650 	.driver = {
651 		   .name = PLATFORM_NAME,
652 	}
653 };
654 
lg_laptop_address_space_write(struct device * dev,acpi_physical_address address,size_t size,u64 value)655 static acpi_status lg_laptop_address_space_write(struct device *dev, acpi_physical_address address,
656 						 size_t size, u64 value)
657 {
658 	u8 byte;
659 
660 	/* Ignore any debug messages */
661 	if (address >= LG_ADDRESS_SPACE_DEBUG_MSG_START_ADR &&
662 	    address <= LG_ADDRESS_SPACE_DEBUG_MSG_END_ADR)
663 		return AE_OK;
664 
665 	if (size != sizeof(byte))
666 		return AE_BAD_PARAMETER;
667 
668 	byte = value & 0xFF;
669 
670 	switch (address) {
671 	case LG_ADDRESS_SPACE_FAN_MODE_ADR:
672 		/*
673 		 * The fan mode field is not affected by the DTTM flag, so we
674 		 * have to manually check fw_debug.
675 		 */
676 		if (fw_debug)
677 			dev_dbg(dev, "Fan mode set to mode %u\n", byte);
678 
679 		return AE_OK;
680 	case LG_ADDRESS_SPACE_CPU_TEMP_ADR:
681 		dev_dbg(dev, "CPU temperature is %u °C\n", byte);
682 		return AE_OK;
683 	case LG_ADDRESS_SPACE_CPU_TRIP_LOW_ADR:
684 		dev_dbg(dev, "CPU lower trip point set to %u °C\n", byte);
685 		return AE_OK;
686 	case LG_ADDRESS_SPACE_CPU_TRIP_HIGH_ADR:
687 		dev_dbg(dev, "CPU higher trip point set to %u °C\n", byte);
688 		return AE_OK;
689 	case LG_ADDRESS_SPACE_MB_TEMP_ADR:
690 		dev_dbg(dev, "Motherboard temperature is %u °C\n", byte);
691 		return AE_OK;
692 	case LG_ADDRESS_SPACE_MB_TRIP_LOW_ADR:
693 		dev_dbg(dev, "Motherboard lower trip point set to %u °C\n", byte);
694 		return AE_OK;
695 	case LG_ADDRESS_SPACE_MB_TRIP_HIGH_ADR:
696 		dev_dbg(dev, "Motherboard higher trip point set to %u °C\n", byte);
697 		return AE_OK;
698 	default:
699 		dev_notice_ratelimited(dev, "Ignoring write to unknown opregion address %llu\n",
700 				       address);
701 		return AE_OK;
702 	}
703 }
704 
lg_laptop_address_space_read(struct device * dev,acpi_physical_address address,size_t size,u64 * value)705 static acpi_status lg_laptop_address_space_read(struct device *dev, acpi_physical_address address,
706 						size_t size, u64 *value)
707 {
708 	if (size != 1)
709 		return AE_BAD_PARAMETER;
710 
711 	switch (address) {
712 	case LG_ADDRESS_SPACE_DEBUG_FLAG_ADR:
713 		/* Debug messages are already printed using the standard ACPI Debug object */
714 		*value = 0x00;
715 		return AE_OK;
716 	case LG_ADDRESS_SPACE_DTTM_FLAG_ADR:
717 		*value = fw_debug;
718 		return AE_OK;
719 	default:
720 		dev_notice_ratelimited(dev, "Attempt to read unknown opregion address %llu\n",
721 				       address);
722 		return AE_BAD_PARAMETER;
723 	}
724 }
725 
lg_laptop_address_space_handler(u32 function,acpi_physical_address address,u32 bits,u64 * value,void * handler_context,void * region_context)726 static acpi_status lg_laptop_address_space_handler(u32 function, acpi_physical_address address,
727 						   u32 bits, u64 *value, void *handler_context,
728 						   void *region_context)
729 {
730 	struct device *dev = handler_context;
731 	size_t size;
732 
733 	if (bits % BITS_PER_BYTE)
734 		return AE_BAD_PARAMETER;
735 
736 	size = bits / BITS_PER_BYTE;
737 
738 	switch (function) {
739 	case ACPI_READ:
740 		return lg_laptop_address_space_read(dev, address, size, value);
741 	case ACPI_WRITE:
742 		return lg_laptop_address_space_write(dev, address, size, *value);
743 	default:
744 		return AE_BAD_PARAMETER;
745 	}
746 }
747 
lg_laptop_remove_address_space_handler(void * data)748 static void lg_laptop_remove_address_space_handler(void *data)
749 {
750 	struct acpi_device *device = data;
751 
752 	acpi_remove_address_space_handler(device->handle, LG_ADDRESS_SPACE_ID,
753 					  &lg_laptop_address_space_handler);
754 }
755 
acpi_add(struct acpi_device * device)756 static int acpi_add(struct acpi_device *device)
757 {
758 	struct platform_device_info pdev_info = {
759 		.fwnode = acpi_fwnode_handle(device),
760 		.name = PLATFORM_NAME,
761 		.id = PLATFORM_DEVID_NONE,
762 	};
763 	acpi_status status;
764 	int ret;
765 	const char *product;
766 	int year = 2017;
767 
768 	if (pf_device)
769 		return 0;
770 
771 	status = acpi_install_address_space_handler(device->handle, LG_ADDRESS_SPACE_ID,
772 						    &lg_laptop_address_space_handler,
773 						    NULL, &device->dev);
774 	if (ACPI_FAILURE(status))
775 		return -ENODEV;
776 
777 	ret = devm_add_action_or_reset(&device->dev, lg_laptop_remove_address_space_handler,
778 				       device);
779 	if (ret < 0)
780 		return ret;
781 
782 	ret = platform_driver_register(&pf_driver);
783 	if (ret)
784 		return ret;
785 
786 	pf_device = platform_device_register_full(&pdev_info);
787 	if (IS_ERR(pf_device)) {
788 		ret = PTR_ERR(pf_device);
789 		pf_device = NULL;
790 		pr_err("unable to register platform device\n");
791 		goto out_platform_registered;
792 	}
793 	product = dmi_get_system_info(DMI_PRODUCT_NAME);
794 	if (product && strlen(product) > 4)
795 		switch (product[4]) {
796 		case '5':
797 			if (strlen(product) > 5)
798 				switch (product[5]) {
799 				case 'N':
800 					year = 2021;
801 					break;
802 				case '0':
803 					year = 2016;
804 					break;
805 				default:
806 					year = 2022;
807 				}
808 			break;
809 		case '6':
810 			year = 2016;
811 			break;
812 		case '7':
813 			year = 2017;
814 			break;
815 		case '8':
816 			year = 2018;
817 			break;
818 		case '9':
819 			year = 2019;
820 			break;
821 		case '0':
822 			if (strlen(product) > 5)
823 				switch (product[5]) {
824 				case 'N':
825 					year = 2020;
826 					break;
827 				case 'P':
828 					year = 2021;
829 					break;
830 				default:
831 					year = 2022;
832 				}
833 			break;
834 		default:
835 			year = 2019;
836 		}
837 	pr_info("product: %s  year: %d\n", product ?: "unknown", year);
838 
839 	if (year >= 2019)
840 		battery_limit_use_wmbb = 1;
841 
842 	ret = sysfs_create_group(&pf_device->dev.kobj, &dev_attribute_group);
843 	if (ret)
844 		goto out_platform_device;
845 
846 	/* LEDs are optional */
847 	led_classdev_register(&pf_device->dev, &kbd_backlight);
848 	led_classdev_register(&pf_device->dev, &tpad_led);
849 
850 	wmi_input_setup();
851 	battery_hook_register(&battery_hook);
852 
853 	return 0;
854 
855 out_platform_device:
856 	platform_device_unregister(pf_device);
857 out_platform_registered:
858 	platform_driver_unregister(&pf_driver);
859 	return ret;
860 }
861 
acpi_remove(struct acpi_device * device)862 static void acpi_remove(struct acpi_device *device)
863 {
864 	sysfs_remove_group(&pf_device->dev.kobj, &dev_attribute_group);
865 
866 	led_classdev_unregister(&tpad_led);
867 	led_classdev_unregister(&kbd_backlight);
868 
869 	battery_hook_unregister(&battery_hook);
870 	wmi_input_destroy();
871 	platform_device_unregister(pf_device);
872 	pf_device = NULL;
873 	platform_driver_unregister(&pf_driver);
874 }
875 
876 static const struct acpi_device_id device_ids[] = {
877 	{"LGEX0820", 0},
878 	{"", 0}
879 };
880 MODULE_DEVICE_TABLE(acpi, device_ids);
881 
882 static struct acpi_driver acpi_driver = {
883 	.name = "LG Gram Laptop Support",
884 	.class = "lg-laptop",
885 	.ids = device_ids,
886 	.ops = {
887 		.add = acpi_add,
888 		.remove = acpi_remove,
889 		.notify = acpi_notify,
890 		},
891 };
892 
acpi_init(void)893 static int __init acpi_init(void)
894 {
895 	int result;
896 
897 	result = acpi_bus_register_driver(&acpi_driver);
898 	if (result < 0) {
899 		pr_debug("Error registering driver\n");
900 		return -ENODEV;
901 	}
902 
903 	return 0;
904 }
905 
acpi_exit(void)906 static void __exit acpi_exit(void)
907 {
908 	acpi_bus_unregister_driver(&acpi_driver);
909 }
910 
911 module_init(acpi_init);
912 module_exit(acpi_exit);
913