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