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 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 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 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 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 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 272 static void acpi_notify(struct acpi_device *device, u32 event) 273 { 274 acpi_handle_debug(device->handle, "notify: %d\n", event); 275 } 276 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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