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-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 }

Cache object: 049d0635fa7ff15a3a8faf9a8637573d


[ 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.