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