1 /*- 2 * Copyright (c) 2002 Sean Bullington <seanATstalker.org> 3 * 2003-2008 Anish Mistry <amistry@am-productions.biz> 4 * 2004 Mark Santcroos <marks@ripe.net> 5 * All Rights Reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 */ 29 30 #include <sys/cdefs.h> 31 #include "opt_acpi.h" 32 #include <sys/param.h> 33 #include <sys/kernel.h> 34 #include <sys/bus.h> 35 #include <sys/module.h> 36 #include <sys/sysctl.h> 37 38 #include <contrib/dev/acpica/include/acpi.h> 39 #include <contrib/dev/acpica/include/accommon.h> 40 41 #include <dev/acpica/acpivar.h> 42 43 /* Hooks for the ACPI CA debugging infrastructure */ 44 #define _COMPONENT ACPI_OEM 45 ACPI_MODULE_NAME("Fujitsu") 46 47 /* Change and update bits for the hotkeys */ 48 #define VOLUME_MUTE_BIT 0x40000000 49 50 /* Values of settings */ 51 #define GENERAL_SETTING_BITS 0x0fffffff 52 #define MOUSE_SETTING_BITS GENERAL_SETTING_BITS 53 #define VOLUME_SETTING_BITS GENERAL_SETTING_BITS 54 #define BRIGHTNESS_SETTING_BITS GENERAL_SETTING_BITS 55 56 /* Possible state changes */ 57 /* 58 * These are NOT arbitrary values. They are the 59 * GHKS return value from the device that says which 60 * hotkey is active. They should match up with a bit 61 * from the GSIF bitmask. 62 */ 63 #define BRIGHT_CHANGED 0x01 64 #define VOLUME_CHANGED 0x04 65 #define MOUSE_CHANGED 0x08 66 /* 67 * It is unknown which hotkey this bit is supposed to indicate, but 68 * according to values from GSIF this is a valid flag. 69 */ 70 #define UNKNOWN_CHANGED 0x10 71 72 /* sysctl values */ 73 #define FN_MUTE 0 74 #define FN_POINTER_ENABLE 1 75 #define FN_LCD_BRIGHTNESS 2 76 #define FN_VOLUME 3 77 78 /* Methods */ 79 #define METHOD_GBLL 1 80 #define METHOD_GMOU 2 81 #define METHOD_GVOL 3 82 #define METHOD_MUTE 4 83 #define METHOD_RBLL 5 84 #define METHOD_RVOL 6 85 #define METHOD_GSIF 7 86 #define METHOD_GHKS 8 87 #define METHOD_GBLS 9 88 89 /* Notify event */ 90 #define ACPI_NOTIFY_STATUS_CHANGED 0x80 91 92 /* 93 * Holds a control method name and its associated integer value. 94 * Only used for no-argument control methods which return a value. 95 */ 96 struct int_nameval { 97 char *name; 98 int value; 99 int exists; 100 }; 101 102 /* 103 * Driver extension for the FUJITSU ACPI driver. 104 */ 105 struct acpi_fujitsu_softc { 106 device_t dev; 107 ACPI_HANDLE handle; 108 109 /* Control methods */ 110 struct int_nameval _sta, /* unused */ 111 gbll, /* brightness */ 112 gbls, /* get brightness state */ 113 ghks, /* hotkey selector */ 114 gbuf, /* unused (buffer?) */ 115 gmou, /* mouse */ 116 gsif, /* function key bitmask */ 117 gvol, /* volume */ 118 rbll, /* number of brightness levels (radix) */ 119 rvol; /* number of volume levels (radix) */ 120 121 /* State variables */ 122 uint8_t bIsMuted; /* Is volume muted */ 123 uint8_t bIntPtrEnabled; /* Is internal ptr enabled */ 124 uint32_t lastValChanged; /* The last value updated */ 125 126 /* sysctl tree */ 127 struct sysctl_ctx_list sysctl_ctx; 128 struct sysctl_oid *sysctl_tree; 129 }; 130 131 /* Driver entry point forward declarations. */ 132 static int acpi_fujitsu_probe(device_t dev); 133 static int acpi_fujitsu_attach(device_t dev); 134 static int acpi_fujitsu_detach(device_t dev); 135 static int acpi_fujitsu_suspend(device_t dev); 136 static int acpi_fujitsu_resume(device_t dev); 137 138 static void acpi_fujitsu_notify_status_changed(void *arg); 139 static void acpi_fujitsu_notify_handler(ACPI_HANDLE h, uint32_t notify, void *context); 140 static int acpi_fujitsu_sysctl(SYSCTL_HANDLER_ARGS); 141 142 /* Utility function declarations */ 143 static uint8_t acpi_fujitsu_update(struct acpi_fujitsu_softc *sc); 144 static uint8_t acpi_fujitsu_init(struct acpi_fujitsu_softc *sc); 145 static uint8_t acpi_fujitsu_check_hardware(struct acpi_fujitsu_softc *sc); 146 147 /* Driver/Module specific structure definitions. */ 148 static device_method_t acpi_fujitsu_methods[] = { 149 /* Device interface */ 150 DEVMETHOD(device_probe, acpi_fujitsu_probe), 151 DEVMETHOD(device_attach, acpi_fujitsu_attach), 152 DEVMETHOD(device_detach, acpi_fujitsu_detach), 153 DEVMETHOD(device_suspend, acpi_fujitsu_suspend), 154 DEVMETHOD(device_resume, acpi_fujitsu_resume), 155 156 DEVMETHOD_END 157 }; 158 159 static driver_t acpi_fujitsu_driver = { 160 "acpi_fujitsu", 161 acpi_fujitsu_methods, 162 sizeof(struct acpi_fujitsu_softc), 163 }; 164 165 /* Prototype for function hotkeys for getting/setting a value. */ 166 static int acpi_fujitsu_method_get(struct acpi_fujitsu_softc *sc, int method); 167 static int acpi_fujitsu_method_set(struct acpi_fujitsu_softc *sc, int method, int value); 168 169 static char *fujitsu_ids[] = { "FUJ02B1", NULL }; 170 171 ACPI_SERIAL_DECL(fujitsu, "Fujitsu Function Hotkeys"); 172 173 /* sysctl names and function calls */ 174 static struct { 175 char *name; 176 int method; 177 char *description; 178 } sysctl_table[] = { 179 { 180 .name = "mute", 181 .method = METHOD_MUTE, 182 .description = "Speakers/headphones mute status" 183 }, 184 { 185 .name = "pointer_enable", 186 .method = METHOD_GMOU, 187 .description = "Enable and disable the internal pointer" 188 }, 189 { 190 .name = "lcd_brightness", 191 .method = METHOD_GBLL, 192 .description = "Brightness level of the LCD panel" 193 }, 194 { 195 .name = "lcd_brightness", 196 .method = METHOD_GBLS, 197 .description = "Brightness level of the LCD panel" 198 }, 199 { 200 .name = "volume", 201 .method = METHOD_GVOL, 202 .description = "Speakers/headphones volume level" 203 }, 204 { 205 .name = "volume_radix", 206 .method = METHOD_RVOL, 207 .description = "Number of volume level steps" 208 }, 209 { 210 .name = "lcd_brightness_radix", 211 .method = METHOD_RBLL, 212 .description = "Number of brightness level steps" 213 }, 214 { NULL, 0, NULL } 215 }; 216 217 DRIVER_MODULE(acpi_fujitsu, acpi, acpi_fujitsu_driver, 0, 0); 218 MODULE_DEPEND(acpi_fujitsu, acpi, 1, 1, 1); 219 MODULE_VERSION(acpi_fujitsu, 1); 220 221 static int 222 acpi_fujitsu_probe(device_t dev) 223 { 224 char *name; 225 char buffer[64]; 226 int rv; 227 228 rv = ACPI_ID_PROBE(device_get_parent(dev), dev, fujitsu_ids, &name); 229 if (acpi_disabled("fujitsu") || rv > 0 || device_get_unit(dev) > 1) 230 return (ENXIO); 231 sprintf(buffer, "Fujitsu Function Hotkeys %s", name); 232 device_set_desc_copy(dev, buffer); 233 234 return (rv); 235 } 236 237 static int 238 acpi_fujitsu_attach(device_t dev) 239 { 240 struct acpi_fujitsu_softc *sc; 241 242 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 243 244 sc = device_get_softc(dev); 245 sc->dev = dev; 246 sc->handle = acpi_get_handle(dev); 247 248 /* Install notification handler */ 249 AcpiInstallNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY, 250 acpi_fujitsu_notify_handler, sc); 251 252 /* Snag our default values for the hotkeys / hotkey states. */ 253 ACPI_SERIAL_BEGIN(fujitsu); 254 if (!acpi_fujitsu_init(sc)) 255 device_printf(dev, "Couldn't initialize hotkey states!\n"); 256 ACPI_SERIAL_END(fujitsu); 257 258 return (0); 259 } 260 261 /* 262 * Called when the system is being suspended, simply 263 * set an event to be signalled when we wake up. 264 */ 265 static int 266 acpi_fujitsu_suspend(device_t dev) 267 { 268 269 return (0); 270 } 271 272 static int 273 acpi_fujitsu_resume(device_t dev) 274 { 275 struct acpi_fujitsu_softc *sc; 276 ACPI_STATUS status; 277 278 sc = device_get_softc(dev); 279 280 /* 281 * The pointer needs to be re-enabled for 282 * some revisions of the P series (2120). 283 */ 284 ACPI_SERIAL_BEGIN(fujitsu); 285 286 if(sc->gmou.exists) { 287 status = acpi_SetInteger(sc->handle, "SMOU", 1); 288 if (ACPI_FAILURE(status)) 289 device_printf(sc->dev, "Couldn't enable pointer\n"); 290 } 291 ACPI_SERIAL_END(fujitsu); 292 293 return (0); 294 } 295 296 static void 297 acpi_fujitsu_notify_status_changed(void *arg) 298 { 299 struct acpi_fujitsu_softc *sc; 300 301 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 302 303 sc = (struct acpi_fujitsu_softc *)arg; 304 305 /* 306 * Since our notify function is called, we know something has 307 * happened. So the only reason for acpi_fujitsu_update to fail 308 * is if we can't find what has changed or an error occurs. 309 */ 310 ACPI_SERIAL_BEGIN(fujitsu); 311 acpi_fujitsu_update(sc); 312 ACPI_SERIAL_END(fujitsu); 313 } 314 315 static void 316 acpi_fujitsu_notify_handler(ACPI_HANDLE h, uint32_t notify, void *context) 317 { 318 struct acpi_fujitsu_softc *sc; 319 320 ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, notify); 321 322 sc = (struct acpi_fujitsu_softc *)context; 323 324 switch (notify) { 325 case ACPI_NOTIFY_STATUS_CHANGED: 326 AcpiOsExecute(OSL_NOTIFY_HANDLER, 327 acpi_fujitsu_notify_status_changed, sc); 328 break; 329 default: 330 /* unknown notification value */ 331 break; 332 } 333 } 334 335 static int 336 acpi_fujitsu_detach(device_t dev) 337 { 338 struct acpi_fujitsu_softc *sc; 339 340 sc = device_get_softc(dev); 341 AcpiRemoveNotifyHandler(sc->handle, ACPI_DEVICE_NOTIFY, 342 acpi_fujitsu_notify_handler); 343 344 sysctl_ctx_free(&sc->sysctl_ctx); 345 346 return (0); 347 } 348 349 /* 350 * Initializes the names of the ACPI control methods and grabs 351 * the current state of all of the ACPI hotkeys into the softc. 352 */ 353 static uint8_t 354 acpi_fujitsu_init(struct acpi_fujitsu_softc *sc) 355 { 356 struct acpi_softc *acpi_sc; 357 int i, exists; 358 359 ACPI_SERIAL_ASSERT(fujitsu); 360 361 /* Setup all of the names for each control method */ 362 sc->_sta.name = "_STA"; 363 sc->gbll.name = "GBLL"; 364 sc->gbls.name = "GBLS"; 365 sc->ghks.name = "GHKS"; 366 sc->gmou.name = "GMOU"; 367 sc->gsif.name = "GSIF"; 368 sc->gvol.name = "GVOL"; 369 sc->ghks.name = "GHKS"; 370 sc->gsif.name = "GSIF"; 371 sc->rbll.name = "RBLL"; 372 sc->rvol.name = "RVOL"; 373 374 /* Determine what hardware functionality is available */ 375 acpi_fujitsu_check_hardware(sc); 376 377 /* Build the sysctl tree */ 378 acpi_sc = acpi_device_get_parent_softc(sc->dev); 379 sysctl_ctx_init(&sc->sysctl_ctx); 380 sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx, 381 SYSCTL_CHILDREN(acpi_sc->acpi_sysctl_tree), 382 OID_AUTO, "fujitsu", CTLFLAG_RD | CTLFLAG_MPSAFE, 0, ""); 383 384 for (i = 0; sysctl_table[i].name != NULL; i++) { 385 switch(sysctl_table[i].method) { 386 case METHOD_GMOU: 387 exists = sc->gmou.exists; 388 break; 389 case METHOD_GBLL: 390 exists = sc->gbll.exists; 391 break; 392 case METHOD_GBLS: 393 exists = sc->gbls.exists; 394 break; 395 case METHOD_GVOL: 396 case METHOD_MUTE: 397 exists = sc->gvol.exists; 398 break; 399 case METHOD_RVOL: 400 exists = sc->rvol.exists; 401 break; 402 case METHOD_RBLL: 403 exists = sc->rbll.exists; 404 break; 405 default: 406 /* Allow by default */ 407 exists = 1; 408 break; 409 } 410 if(!exists) 411 continue; 412 SYSCTL_ADD_PROC(&sc->sysctl_ctx, 413 SYSCTL_CHILDREN(sc->sysctl_tree), OID_AUTO, 414 sysctl_table[i].name, 415 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_ANYBODY | 416 CTLFLAG_MPSAFE, sc, i, acpi_fujitsu_sysctl, "I", 417 sysctl_table[i].description); 418 } 419 420 /* Set the hotkeys to their initial states */ 421 if (!acpi_fujitsu_update(sc)) { 422 device_printf(sc->dev, "Couldn't init hotkey states\n"); 423 return (FALSE); 424 } 425 426 return (TRUE); 427 } 428 429 static int 430 acpi_fujitsu_sysctl(SYSCTL_HANDLER_ARGS) 431 { 432 struct acpi_fujitsu_softc *sc; 433 int method; 434 int arg; 435 int function_num, error = 0; 436 437 sc = (struct acpi_fujitsu_softc *)oidp->oid_arg1; 438 function_num = oidp->oid_arg2; 439 method = sysctl_table[function_num].method; 440 441 ACPI_SERIAL_BEGIN(fujitsu); 442 443 /* Get the current value */ 444 arg = acpi_fujitsu_method_get(sc, method); 445 error = sysctl_handle_int(oidp, &arg, 0, req); 446 447 if (error != 0 || req->newptr == NULL) 448 goto out; 449 450 /* Update the value */ 451 error = acpi_fujitsu_method_set(sc, method, arg); 452 453 out: 454 ACPI_SERIAL_END(fujitsu); 455 return (error); 456 } 457 458 static int 459 acpi_fujitsu_method_get(struct acpi_fujitsu_softc *sc, int method) 460 { 461 struct int_nameval nv; 462 ACPI_STATUS status; 463 464 ACPI_SERIAL_ASSERT(fujitsu); 465 466 switch (method) { 467 case METHOD_GBLL: 468 nv = sc->gbll; 469 break; 470 case METHOD_GBLS: 471 nv = sc->gbls; 472 break; 473 case METHOD_GMOU: 474 nv = sc->gmou; 475 break; 476 case METHOD_GVOL: 477 case METHOD_MUTE: 478 nv = sc->gvol; 479 break; 480 case METHOD_GHKS: 481 nv = sc->ghks; 482 break; 483 case METHOD_GSIF: 484 nv = sc->gsif; 485 break; 486 case METHOD_RBLL: 487 nv = sc->rbll; 488 break; 489 case METHOD_RVOL: 490 nv = sc->rvol; 491 break; 492 default: 493 return (FALSE); 494 } 495 496 if(!nv.exists) 497 return (EINVAL); 498 499 status = acpi_GetInteger(sc->handle, nv.name, &nv.value); 500 if (ACPI_FAILURE(status)) { 501 device_printf(sc->dev, "Couldn't query method (%s)\n", nv.name); 502 return (FALSE); 503 } 504 505 if (method == METHOD_MUTE) { 506 sc->bIsMuted = (uint8_t)((nv.value & VOLUME_MUTE_BIT) != 0); 507 return (sc->bIsMuted); 508 } 509 510 nv.value &= GENERAL_SETTING_BITS; 511 return (nv.value); 512 } 513 514 static int 515 acpi_fujitsu_method_set(struct acpi_fujitsu_softc *sc, int method, int value) 516 { 517 struct int_nameval nv; 518 ACPI_STATUS status; 519 char *control; 520 int changed; 521 522 ACPI_SERIAL_ASSERT(fujitsu); 523 524 switch (method) { 525 case METHOD_GBLL: 526 changed = BRIGHT_CHANGED; 527 control = "SBLL"; 528 nv = sc->gbll; 529 break; 530 case METHOD_GBLS: 531 changed = BRIGHT_CHANGED; 532 control = "SBL2"; 533 nv = sc->gbls; 534 break; 535 case METHOD_GMOU: 536 changed = MOUSE_CHANGED; 537 control = "SMOU"; 538 nv = sc->gmou; 539 break; 540 case METHOD_GVOL: 541 case METHOD_MUTE: 542 changed = VOLUME_CHANGED; 543 control = "SVOL"; 544 nv = sc->gvol; 545 break; 546 default: 547 return (EINVAL); 548 } 549 550 if(!nv.exists) 551 return (EINVAL); 552 553 if (method == METHOD_MUTE) { 554 if (value == 1) 555 value = nv.value | VOLUME_MUTE_BIT; 556 else if (value == 0) 557 value = nv.value & ~VOLUME_MUTE_BIT; 558 else 559 return (EINVAL); 560 } 561 562 status = acpi_SetInteger(sc->handle, control, value); 563 if (ACPI_FAILURE(status)) { 564 device_printf(sc->dev, "Couldn't update %s\n", control); 565 return (FALSE); 566 } 567 568 sc->lastValChanged = changed; 569 return (0); 570 } 571 572 /* 573 * Query the get methods to determine what functionality is available 574 * from the hardware function hotkeys. 575 */ 576 static uint8_t 577 acpi_fujitsu_check_hardware(struct acpi_fujitsu_softc *sc) 578 { 579 int val; 580 581 ACPI_SERIAL_ASSERT(fujitsu); 582 /* save the hotkey bitmask */ 583 if (ACPI_FAILURE(acpi_GetInteger(sc->handle, 584 sc->gsif.name, &(sc->gsif.value)))) { 585 sc->gsif.exists = 0; 586 device_printf(sc->dev, "Couldn't query bitmask value\n"); 587 } else { 588 sc->gsif.exists = 1; 589 } 590 591 /* System Volume Level */ 592 if (ACPI_FAILURE(acpi_GetInteger(sc->handle, 593 sc->gvol.name, &val))) { 594 sc->gvol.exists = 0; 595 } else { 596 sc->gvol.exists = 1; 597 } 598 599 if (ACPI_FAILURE(acpi_GetInteger(sc->handle, 600 sc->gbls.name, &val))) { 601 sc->gbls.exists = 0; 602 } else { 603 sc->gbls.exists = 1; 604 } 605 606 // don't add if we can use the new method 607 if (sc->gbls.exists || ACPI_FAILURE(acpi_GetInteger(sc->handle, 608 sc->gbll.name, &val))) { 609 sc->gbll.exists = 0; 610 } else { 611 sc->gbll.exists = 1; 612 } 613 614 if (ACPI_FAILURE(acpi_GetInteger(sc->handle, 615 sc->ghks.name, &val))) { 616 sc->ghks.exists = 0; 617 } else { 618 sc->ghks.exists = 1; 619 } 620 621 if (ACPI_FAILURE(acpi_GetInteger(sc->handle, 622 sc->gmou.name, &val))) { 623 sc->gmou.exists = 0; 624 } else { 625 sc->gmou.exists = 1; 626 } 627 628 if (ACPI_FAILURE(acpi_GetInteger(sc->handle, 629 sc->rbll.name, &val))) { 630 sc->rbll.exists = 0; 631 } else { 632 sc->rbll.exists = 1; 633 } 634 635 if (ACPI_FAILURE(acpi_GetInteger(sc->handle, 636 sc->rvol.name, &val))) { 637 sc->rvol.exists = 0; 638 } else { 639 sc->rvol.exists = 1; 640 } 641 642 return (TRUE); 643 } 644 645 /* 646 * Query each of the ACPI control methods that contain information we're 647 * interested in. We check the return values from the control methods and 648 * adjust any state variables if they should be adjusted. 649 */ 650 static uint8_t 651 acpi_fujitsu_update(struct acpi_fujitsu_softc *sc) 652 { 653 int changed; 654 struct acpi_softc *acpi_sc; 655 656 acpi_sc = acpi_device_get_parent_softc(sc->dev); 657 658 ACPI_SERIAL_ASSERT(fujitsu); 659 if(sc->gsif.exists) 660 changed = sc->gsif.value & acpi_fujitsu_method_get(sc,METHOD_GHKS); 661 else 662 changed = 0; 663 664 /* System Volume Level */ 665 if(sc->gvol.exists) { 666 if (ACPI_FAILURE(acpi_GetInteger(sc->handle, 667 sc->gvol.name, &(sc->gvol.value)))) { 668 device_printf(sc->dev, "Couldn't query volume level\n"); 669 return (FALSE); 670 } 671 672 if (changed & VOLUME_CHANGED) { 673 sc->bIsMuted = 674 (uint8_t)((sc->gvol.value & VOLUME_MUTE_BIT) != 0); 675 676 /* Clear the modification bit */ 677 sc->gvol.value &= VOLUME_SETTING_BITS; 678 679 if (sc->bIsMuted) { 680 acpi_UserNotify("FUJITSU", sc->handle, FN_MUTE); 681 ACPI_VPRINT(sc->dev, acpi_sc, "Volume is now mute\n"); 682 } else 683 ACPI_VPRINT(sc->dev, acpi_sc, "Volume is now %d\n", 684 sc->gvol.value); 685 686 acpi_UserNotify("FUJITSU", sc->handle, FN_VOLUME); 687 } 688 } 689 690 /* Internal mouse pointer (eraserhead) */ 691 if(sc->gmou.exists) { 692 if (ACPI_FAILURE(acpi_GetInteger(sc->handle, 693 sc->gmou.name, &(sc->gmou.value)))) { 694 device_printf(sc->dev, "Couldn't query pointer state\n"); 695 return (FALSE); 696 } 697 698 if (changed & MOUSE_CHANGED) { 699 sc->bIntPtrEnabled = (uint8_t)(sc->gmou.value & 0x1); 700 701 /* Clear the modification bit */ 702 sc->gmou.value &= MOUSE_SETTING_BITS; 703 704 /* Set the value in case it is not hardware controlled */ 705 acpi_fujitsu_method_set(sc, METHOD_GMOU, sc->gmou.value); 706 707 acpi_UserNotify("FUJITSU", sc->handle, FN_POINTER_ENABLE); 708 709 ACPI_VPRINT(sc->dev, acpi_sc, "Internal pointer is now %s\n", 710 (sc->bIntPtrEnabled) ? "enabled" : "disabled"); 711 } 712 } 713 714 /* Screen Brightness Level P8XXX */ 715 if(sc->gbls.exists) { 716 if (ACPI_FAILURE(acpi_GetInteger(sc->handle, 717 sc->gbls.name, &(sc->gbls.value)))) { 718 device_printf(sc->dev, "Couldn't query P8XXX brightness level\n"); 719 return (FALSE); 720 } 721 if (changed & BRIGHT_CHANGED) { 722 /* No state to record here. */ 723 724 /* Clear the modification bit */ 725 sc->gbls.value &= BRIGHTNESS_SETTING_BITS; 726 727 /* Set the value in case it is not hardware controlled */ 728 acpi_fujitsu_method_set(sc, METHOD_GBLS, sc->gbls.value); 729 730 acpi_UserNotify("FUJITSU", sc->handle, FN_LCD_BRIGHTNESS); 731 732 ACPI_VPRINT(sc->dev, acpi_sc, "P8XXX Brightness level is now %d\n", 733 sc->gbls.value); 734 } 735 } 736 737 /* Screen Brightness Level */ 738 if(sc->gbll.exists) { 739 if (ACPI_FAILURE(acpi_GetInteger(sc->handle, 740 sc->gbll.name, &(sc->gbll.value)))) { 741 device_printf(sc->dev, "Couldn't query brightness level\n"); 742 return (FALSE); 743 } 744 745 if (changed & BRIGHT_CHANGED) { 746 /* No state to record here. */ 747 748 /* Clear the modification bit */ 749 sc->gbll.value &= BRIGHTNESS_SETTING_BITS; 750 751 acpi_UserNotify("FUJITSU", sc->handle, FN_LCD_BRIGHTNESS); 752 753 ACPI_VPRINT(sc->dev, acpi_sc, "Brightness level is now %d\n", 754 sc->gbll.value); 755 } 756 } 757 758 sc->lastValChanged = changed; 759 return (TRUE); 760 } 761