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