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

          Line data    Source code
       1             : /* $OpenBSD: acpials.c,v 1.3 2017/03/13 14:44:37 jcs Exp $ */
       2             : /*
       3             :  * Ambient Light Sensor device driver
       4             :  * ACPI 5.0 spec section 9.2
       5             :  *
       6             :  * Copyright (c) 2016 joshua stein <jcs@openbsd.org>
       7             :  *
       8             :  * Permission to use, copy, modify, and distribute this software for any
       9             :  * purpose with or without fee is hereby granted, provided that the above
      10             :  * copyright notice and this permission notice appear in all copies.
      11             :  *
      12             :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      13             :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      14             :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      15             :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      16             :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      17             :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      18             :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      19             :  */
      20             : 
      21             : #include <sys/param.h>
      22             : #include <sys/systm.h>
      23             : #include <sys/device.h>
      24             : 
      25             : #include <dev/acpi/acpireg.h>
      26             : #include <dev/acpi/acpivar.h>
      27             : #include <dev/acpi/acpidev.h>
      28             : #include <dev/acpi/amltypes.h>
      29             : #include <dev/acpi/dsdt.h>
      30             : 
      31             : #include <sys/sensors.h>
      32             : 
      33             : /* #define ACPIALS_DEBUG */
      34             : 
      35             : #ifdef ACPIALS_DEBUG
      36             : #define DPRINTF(x) printf x
      37             : #else
      38             : #define DPRINTF(x)
      39             : #endif
      40             : 
      41             : struct acpials_softc {
      42             :         struct device           sc_dev;
      43             : 
      44             :         bus_space_tag_t         sc_iot;
      45             :         bus_space_handle_t      sc_ioh;
      46             : 
      47             :         struct acpi_softc       *sc_acpi;
      48             :         struct aml_node         *sc_devnode;
      49             : 
      50             :         struct ksensor          sc_sensor;
      51             :         struct ksensordev       sc_sensordev;
      52             :         struct sensor_task      *sc_sensor_task;
      53             : };
      54             : 
      55             : int     acpials_match(struct device *, void *, void *);
      56             : void    acpials_attach(struct device *, struct device *, void *);
      57             : int     acpials_read(struct acpials_softc *);
      58             : int     acpials_notify(struct aml_node *, int, void *);
      59             : void    acpials_addtask(void *);
      60             : void    acpials_update(void *, int);
      61             : 
      62             : const struct cfattach acpials_ca = {
      63             :         sizeof(struct acpials_softc),
      64             :         acpials_match,
      65             :         acpials_attach,
      66             : };
      67             : 
      68             : struct cfdriver acpials_cd = {
      69             :         NULL, "acpials", DV_DULL
      70             : };
      71             : 
      72             : const char *acpials_hids[] = {
      73             :         "ACPI0008",
      74             :         NULL
      75             : };
      76             : 
      77             : extern char *hw_vendor;
      78             : 
      79             : int
      80           0 : acpials_match(struct device *parent, void *match, void *aux)
      81             : {
      82           0 :         struct acpi_attach_args *aa = aux;
      83           0 :         struct cfdata *cf = match;
      84             : 
      85             :         /*
      86             :          * Apple hardware will most likely have asmc(4) which also provides an
      87             :          * illuminance sensor.
      88             :          */
      89           0 :         if (hw_vendor != NULL && strncmp(hw_vendor, "Apple", 5) == 0)
      90           0 :                 return 0;
      91             : 
      92           0 :         return (acpi_matchhids(aa, acpials_hids, cf->cf_driver->cd_name));
      93           0 : }
      94             : 
      95             : void
      96           0 : acpials_attach(struct device *parent, struct device *self, void *aux)
      97             : {
      98           0 :         struct acpials_softc *sc = (struct acpials_softc *)self;
      99           0 :         struct acpi_attach_args *aa = aux;
     100           0 :         int64_t st;
     101             : 
     102           0 :         sc->sc_acpi = (struct acpi_softc *)parent;
     103           0 :         sc->sc_devnode = aa->aaa_node;
     104             : 
     105           0 :         printf(": %s\n", sc->sc_devnode->name);
     106             : 
     107           0 :         if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "_STA", 0, NULL, &st))
     108           0 :                 st = STA_PRESENT | STA_ENABLED | STA_DEV_OK;
     109           0 :         if ((st & (STA_PRESENT | STA_ENABLED | STA_DEV_OK)) !=
     110             :             (STA_PRESENT | STA_ENABLED | STA_DEV_OK))
     111           0 :                 return;
     112             : 
     113           0 :         if (acpials_read(sc))
     114           0 :                 return;
     115             : 
     116           0 :         strlcpy(sc->sc_sensordev.xname, DEVNAME(sc),
     117             :             sizeof(sc->sc_sensordev.xname));
     118           0 :         strlcpy(sc->sc_sensor.desc, "ambient light sensor",
     119             :             sizeof(sc->sc_sensor.desc));
     120           0 :         sc->sc_sensor.type = SENSOR_LUX;
     121           0 :         sensor_attach(&sc->sc_sensordev, &sc->sc_sensor);
     122             : 
     123             :         /*
     124             :          * aml_register_notify with ACPIDEV_POLL is too slow (10 second
     125             :          * intervals), so register the task with sensors so we can specify the
     126             :          * interval, which will then just inject an acpi task and tell it to
     127             :          * wakeup to handle the task.
     128             :          */
     129           0 :         if (!(sc->sc_sensor_task = sensor_task_register(sc, acpials_addtask,
     130             :             1))) {
     131           0 :                 printf("%s: unable to register task\n", sc->sc_dev.dv_xname);
     132           0 :                 return;
     133             :         }
     134             : 
     135             :         /*
     136             :          * But also install an event handler in case AML Notify()s us of any
     137             :          * large changes - 9.2.7
     138             :          */
     139           0 :         aml_register_notify(sc->sc_devnode, aa->aaa_dev, acpials_notify,
     140             :             sc, ACPIDEV_NOPOLL);
     141             : 
     142           0 :         sensordev_install(&sc->sc_sensordev);
     143           0 : }
     144             : 
     145             : int
     146           0 : acpials_read(struct acpials_softc *sc)
     147             : {
     148           0 :         int64_t ali = 0;
     149             : 
     150             :         /* 9.2.2 - "Current ambient light illuminance reading in lux" */
     151           0 :         if (aml_evalinteger(sc->sc_acpi, sc->sc_devnode, "_ALI", 0, NULL,
     152             :             &ali))
     153           0 :                 return 1;
     154             : 
     155           0 :         sc->sc_sensor.value = (ali * 1000000);
     156             : 
     157           0 :         return 0;
     158           0 : }
     159             : 
     160             : int
     161           0 : acpials_notify(struct aml_node *node, int notify_type, void *arg)
     162             : {
     163           0 :         struct acpials_softc *sc = arg;
     164             : 
     165             :         DPRINTF(("%s: %s: %d\n", sc->sc_dev.dv_xname, __func__, notify_type));
     166             : 
     167           0 :         if (notify_type == 0x80)
     168           0 :                 acpials_read(sc);
     169             : 
     170           0 :         return 0;
     171             : }
     172             : 
     173             : void
     174           0 : acpials_addtask(void *arg)
     175             : {
     176           0 :         struct acpials_softc *sc = arg;
     177             : 
     178           0 :         acpi_addtask(sc->sc_acpi, acpials_update, sc, 0);
     179           0 :         acpi_wakeup(sc->sc_acpi);
     180           0 : }
     181             : 
     182             : void
     183           0 : acpials_update(void *arg0, int arg1)
     184             : {
     185           0 :         struct acpials_softc *sc = arg0;
     186             : 
     187           0 :         if (acpials_read(sc) == 0) {
     188             :                 DPRINTF(("%s: %s: %lld\n", sc->sc_dev.dv_xname, __func__,
     189             :                     sc->sc_sensor.value));
     190           0 :                 sc->sc_sensor.flags &= ~SENSOR_FINVALID;
     191           0 :         } else
     192           0 :                 sc->sc_sensor.flags |= SENSOR_FINVALID;
     193           0 : }

Generated by: LCOV version 1.13