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