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