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: releng/8.4/sys/dev/acpi_support/acpi_fujitsu.c 219513 2011-03-11 18:07:49Z avg $");
   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 }

Cache object: 3c32caa59541ba3c87f1bc0334475e9d


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