]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/dev/acpi_support/acpi_fujitsu.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / dev / acpi_support / acpi_fujitsu.c
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 }