LCOV - code coverage report
Current view: top level - dev/acpi - acpisony.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 117 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 10 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* $OpenBSD: acpisony.c,v 1.7 2017/02/28 10:39:07 natano Exp $ */
       2             : /*
       3             :  * Copyright (c) 2010 Paul Irofti <pirofti@openbsd.org>
       4             :  *
       5             :  * Permission to use, copy, modify, and/or distribute this software for any
       6             :  * purpose with or without fee is hereby granted, provided that the above
       7             :  * copyright notice and this permission notice appear in all copies.
       8             :  *
       9             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      10             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      11             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      12             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      13             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      14             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      15             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      16             :  */
      17             : 
      18             : #include <sys/param.h>
      19             : #include <sys/systm.h>
      20             : 
      21             : #include <dev/acpi/acpireg.h>
      22             : #include <dev/acpi/acpivar.h>
      23             : #include <dev/acpi/acpidev.h>
      24             : #include <dev/acpi/amltypes.h>
      25             : #include <dev/acpi/dsdt.h>
      26             : 
      27             : #include <machine/apmvar.h>
      28             : 
      29             : int     acpisony_match(struct device *, void *, void *);
      30             : void    acpisony_attach(struct device *, struct device *, void *);
      31             : int     acpisony_activate(struct device *, int);
      32             : int     acpisony_notify(struct aml_node *, int, void *);
      33             : 
      34             : #ifdef ACPISONY_DEBUG
      35             : #define DPRINTF(x)      printf x
      36             : #else
      37             : #define DPRINTF(x)
      38             : #endif
      39             : 
      40             : /* Notifications */
      41             : #define SONY_NOTIFY_FN_KEY                      0x90
      42             : 
      43             : #define SONY_NOTIFY_BRIGHTNESS_DOWN_PRESSED     0x85
      44             : #define SONY_NOTIFY_BRIGHTNESS_DOWN_RELEASED    0x05
      45             : #define SONY_NOTIFY_BRIGHTNESS_UP_PRESSED       0x86
      46             : #define SONY_NOTIFY_BRIGHTNESS_UP_RELEASED      0x06
      47             : 
      48             : #define SONY_NOTIFY_DISPLAY_SWITCH_PRESSED      0x87
      49             : #define SONY_NOTIFY_DISPLAY_SWITCH_RELEASED     0x07
      50             : 
      51             : #define SONY_NOTIFY_ZOOM_OUT_PRESSED            0x89
      52             : #define SONY_NOTIFY_ZOOM_OUT_RELEASED           0x09
      53             : 
      54             : #define SONY_NOTIFY_ZOOM_IN_PRESSED             0x8a
      55             : #define SONY_NOTIFY_ZOOM_IN_RELEASED            0x0a
      56             : 
      57             : #define SONY_NOTIFY_SUSPEND_PRESSED             0x8c
      58             : #define SONY_NOTIFY_SUSPEND_RELEASED            0x0c
      59             : 
      60             : struct acpisony_softc {
      61             :         struct device           sc_dev;
      62             : 
      63             :         bus_space_tag_t         sc_iot;
      64             :         bus_space_handle_t      sc_ioh;
      65             : 
      66             :         struct acpi_softc       *sc_acpi;
      67             :         struct aml_node         *sc_devnode;
      68             : };
      69             : 
      70             : struct cfattach acpisony_ca = {
      71             :         sizeof(struct acpisony_softc), acpisony_match, acpisony_attach,
      72             :         NULL, acpisony_activate
      73             : };
      74             : 
      75             : struct cfdriver acpisony_cd = {
      76             :         NULL, "acpisony", DV_DULL
      77             : };
      78             : 
      79             : void acpisony_notify_setup(struct acpisony_softc *);
      80             : int acpisony_set_hotkey(struct acpisony_softc *, int, int);
      81             : int acpisony_find_offset(struct acpisony_softc *, int);
      82             : 
      83             : void acpisony_brightness_down(struct acpisony_softc *);
      84             : int acpisony_get_brightness(struct acpisony_softc *);
      85             : void acpisony_set_brightness(struct acpisony_softc *, int);
      86             : 
      87             : int
      88           0 : acpisony_match(struct device *parent, void *match, void *aux)
      89             : {
      90           0 :         struct acpi_attach_args *aa = aux;
      91           0 :         struct cfdata           *cf = match;
      92             : 
      93           0 :         if (aa->aaa_name == NULL ||
      94           0 :             strcmp(aa->aaa_name, cf->cf_driver->cd_name) != 0 ||
      95           0 :             aa->aaa_table != NULL)
      96           0 :                 return (0);
      97             : 
      98           0 :         return (1);
      99           0 : }
     100             : 
     101             : void
     102           0 : acpisony_attach(struct device *parent, struct device *self, void *aux)
     103             : {
     104           0 :         struct acpisony_softc   *sc = (struct acpisony_softc *)self;
     105           0 :         struct acpi_attach_args *aa = aux;
     106             : 
     107           0 :         sc->sc_acpi = (struct acpi_softc *)parent;
     108           0 :         sc->sc_devnode = aa->aaa_node;
     109             : 
     110           0 :         printf(": %s\n", sc->sc_devnode->name);
     111             : 
     112             :         /* Setup the notification masks */
     113           0 :         acpisony_notify_setup(sc);
     114             : 
     115           0 :         aml_register_notify(sc->sc_devnode, aa->aaa_dev,
     116           0 :             acpisony_notify, sc, ACPIDEV_NOPOLL);
     117           0 : }
     118             : 
     119             : int
     120           0 : acpisony_activate(struct device *self, int act)
     121             : {
     122           0 :         struct acpisony_softc *sc = (struct acpisony_softc *)self;
     123             : 
     124           0 :         switch (act) {
     125             :         case DVACT_WAKEUP:
     126           0 :                 acpisony_notify_setup(sc);
     127           0 :                 break;
     128             :         }
     129           0 :         return 0;
     130             : }
     131             : 
     132             : int
     133           0 : acpisony_notify(struct aml_node *node, int notify, void *arg)
     134             : {
     135           0 :         struct acpisony_softc *sc = arg;
     136             :         int val, key = 0;
     137             : 
     138           0 :         if (notify == SONY_NOTIFY_FN_KEY) {
     139           0 :                 notify -= 0x90;
     140             :                 DPRINTF(("notify = %X", notify));
     141             : 
     142           0 :                 if (notify == acpisony_find_offset(sc, 0x100)) {
     143             :                         DPRINTF(("key = 0x100\n"));
     144             :                         key = 0x100;
     145           0 :                 }
     146           0 :                 if (notify == acpisony_find_offset(sc, 0x127)) {
     147             :                         DPRINTF(("key = 0x127\n"));
     148             :                         key = 0x127;
     149           0 :                 }
     150             : 
     151           0 :                 if (key) {
     152           0 :                         val = acpisony_set_hotkey(sc, key, 0x200);
     153           0 :                         if (val < 0) {
     154           0 :                                 printf("returned val = %X", val);
     155           0 :                                 return 1;
     156             :                         }
     157           0 :                         notify = val & 0xff;
     158             : 
     159             :                         DPRINTF(("Treat %X events, notify %X\n", key, notify));
     160           0 :                 } else
     161             :                         DPRINTF(("rfkill update, notify %X\n", notify));
     162             :         }
     163             : 
     164           0 :         switch (notify) {
     165             :         case SONY_NOTIFY_BRIGHTNESS_DOWN_PRESSED:
     166             :                 DPRINTF(("br-down-pressed\n"));
     167           0 :                 acpisony_brightness_down(sc);
     168           0 :                 break;
     169             :         case SONY_NOTIFY_BRIGHTNESS_DOWN_RELEASED:
     170             :                 DPRINTF(("br-down-released\n"));
     171             :                 break;
     172             :         case SONY_NOTIFY_BRIGHTNESS_UP_PRESSED:
     173             :                 DPRINTF(("br-up-pressed\n"));
     174             :                 break;
     175             :         case SONY_NOTIFY_BRIGHTNESS_UP_RELEASED:
     176             :                 DPRINTF(("br-up-released\n"));
     177             :                 break;
     178             :         case SONY_NOTIFY_DISPLAY_SWITCH_PRESSED:
     179             :                 DPRINTF(("display-pressed\n"));
     180             :                 break;
     181             :         case SONY_NOTIFY_DISPLAY_SWITCH_RELEASED:
     182             :                 DPRINTF(("display-released\n"));
     183             :                 break;
     184             :         case SONY_NOTIFY_ZOOM_IN_PRESSED:
     185             :                 DPRINTF(("zoom-in-pressed\n"));
     186             :                 break;
     187             :         case SONY_NOTIFY_ZOOM_IN_RELEASED:
     188             :                 DPRINTF(("zoom-in-released\n"));
     189             :                 break;
     190             :         case SONY_NOTIFY_ZOOM_OUT_PRESSED:
     191             :                 DPRINTF(("zoom-out-pressed\n"));
     192             :                 break;
     193             :         case SONY_NOTIFY_ZOOM_OUT_RELEASED:
     194             :                 DPRINTF(("zoom-out-released\n"));
     195             :                 break;
     196             :         case SONY_NOTIFY_SUSPEND_PRESSED:
     197             :                 DPRINTF(("suspend-pressed\n"));
     198             : #ifndef SMALL_KERNEL
     199           0 :                 if (acpi_record_event(sc->sc_acpi, APM_USER_SUSPEND_REQ))
     200           0 :                         acpi_addtask(sc->sc_acpi, acpi_sleep_task,
     201           0 :                             sc->sc_acpi, ACPI_SLEEP_SUSPEND);
     202             : #endif
     203             :                 break;
     204             :         case SONY_NOTIFY_SUSPEND_RELEASED:
     205             :                 DPRINTF(("suspend-released\n"));
     206             :                 break;
     207             :         default:
     208           0 :                 printf("%s: unknown event 0x%02x\n", DEVNAME(sc), notify);
     209           0 :                 break;
     210             :         }
     211             : 
     212           0 :         return 0;
     213           0 : }
     214             : 
     215             : void
     216           0 : acpisony_notify_setup(struct acpisony_softc *sc)
     217             : {
     218           0 :         struct aml_value arg;
     219             : 
     220           0 :         bzero(&arg, sizeof(arg));
     221           0 :         arg.type = AML_OBJTYPE_INTEGER;
     222             : 
     223           0 :         arg.v_integer = 1;
     224           0 :         aml_evalname(sc->sc_acpi, sc->sc_devnode, "ECON", 1, &arg, NULL);
     225             : 
     226             :         /* Enable all events */
     227           0 :         arg.v_integer = 0xffff;
     228           0 :         aml_evalname(sc->sc_acpi, sc->sc_devnode, "SN02", 1, &arg, NULL);
     229             : 
     230             :         /* Enable hotkeys */
     231           0 :         arg.v_integer = 0x04;
     232           0 :         aml_evalname(sc->sc_acpi, sc->sc_devnode, "SN02", 1, &arg, NULL);
     233           0 :         arg.v_integer = 0x02;
     234           0 :         aml_evalname(sc->sc_acpi, sc->sc_devnode, "SN07", 1, &arg, NULL);
     235           0 :         arg.v_integer = 0x10;
     236           0 :         aml_evalname(sc->sc_acpi, sc->sc_devnode, "SN02", 1, &arg, NULL);
     237           0 :         arg.v_integer = 0x00;
     238           0 :         aml_evalname(sc->sc_acpi, sc->sc_devnode, "SN07", 1, &arg, NULL);
     239           0 :         arg.v_integer = 0x02;
     240           0 :         aml_evalname(sc->sc_acpi, sc->sc_devnode, "SN03", 1, &arg, NULL);
     241           0 :         arg.v_integer = 0x101;
     242           0 :         aml_evalname(sc->sc_acpi, sc->sc_devnode, "SN07", 1, &arg, NULL);
     243           0 : }
     244             : 
     245             : int
     246           0 : acpisony_find_offset(struct acpisony_softc *sc, int key)
     247             : {
     248           0 :         struct aml_value arg, res;
     249             :         int val;
     250             : 
     251           0 :         bzero(&arg, sizeof(arg));
     252           0 :         arg.type = AML_OBJTYPE_INTEGER;
     253             : 
     254           0 :         for (arg.v_integer = 0x20; arg.v_integer < 0x30; arg.v_integer++) {
     255           0 :                 aml_evalname(sc->sc_acpi, sc->sc_devnode, "SN00", 1, &arg, &res);
     256           0 :                 val = aml_val2int(&res);
     257           0 :                 aml_freevalue(&res);
     258           0 :                 if (val == key) {
     259             :                         DPRINTF(("Matched key %X\n", val));
     260           0 :                         return arg.v_integer - 0x20;
     261             :                 }
     262             :         }
     263             : 
     264           0 :         return -1;
     265           0 : }
     266             : 
     267             : int
     268           0 : acpisony_set_hotkey(struct acpisony_softc *sc, int key, int val)
     269             : {
     270             :         int off, rc = -1;
     271           0 :         struct aml_value res, arg;
     272             : 
     273           0 :         bzero(&arg, sizeof(arg));
     274           0 :         arg.type = AML_OBJTYPE_INTEGER;
     275             : 
     276           0 :         off = acpisony_find_offset(sc, key);
     277             :         DPRINTF(("off = %X\n", off));
     278           0 :         if (off < 0)
     279           0 :                 return rc;
     280             : 
     281           0 :         arg.v_integer = off | val;
     282           0 :         aml_evalname(sc->sc_acpi, sc->sc_devnode, "SN07", 1, &arg, &res);
     283           0 :         rc = aml_val2int(&res);
     284           0 :         aml_freevalue(&res);
     285             : 
     286           0 :         return rc;
     287           0 : }
     288             : 
     289             : void
     290           0 : acpisony_brightness_down(struct acpisony_softc *sc)
     291             : {
     292             :         int val;
     293             : 
     294           0 :         val = acpisony_get_brightness(sc);
     295             :         DPRINTF(("current value = %X", val));
     296           0 :         if (val > 0)
     297           0 :                 val--;
     298             :         else
     299             :                 val = 0;
     300             :         DPRINTF(("next value = %X", val));
     301           0 :         acpisony_set_brightness(sc, val);
     302           0 : }
     303             : 
     304             : int
     305           0 : acpisony_get_brightness(struct acpisony_softc *sc)
     306             : {
     307           0 :         struct aml_value res;
     308             :         int val;
     309             : 
     310           0 :         aml_evalname(sc->sc_acpi, sc->sc_devnode, "GBRT", 0, NULL, &res);
     311           0 :         val = aml_val2int(&res);
     312           0 :         aml_freevalue(&res);
     313             : 
     314           0 :         return val;
     315           0 : }
     316             : 
     317             : void
     318           0 : acpisony_set_brightness(struct acpisony_softc *sc, int level)
     319             : {
     320           0 :         struct aml_value arg;
     321             : 
     322           0 :         bzero(&arg, sizeof(arg));
     323           0 :         arg.type = AML_OBJTYPE_INTEGER;
     324           0 :         arg.v_integer = level;
     325           0 :         aml_evalname(sc->sc_acpi, sc->sc_devnode, "SBRT", 1, &arg, NULL);
     326           0 :         aml_freevalue(&arg);
     327           0 : }

Generated by: LCOV version 1.13