The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/acpi_support/acpi_fujitsu.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: d492aa5d762c3dce7c4c66c7d2cd419d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.