Please test, details below.

We attach acpivout(4) to every device enumerated in _DOD.  However,
if you read ACPI spec. closely, it says that _DOD (unlike _DOS) is
not required if the system supports LCD brightness control.

In my case the situation is even worse--_DOD enumerates only 0x400
(which is non-existent), however there's this DD03 device which is
LCD and perfecly can handle brightness control.

I suggest to trust _DOD less, and search for devices having _BCL,
_BCM, and _BQC instead;  because only such device would be able to
handle brightness control.

We use the same trick in other drivers (look for functions instead
of trusting enumeration crap in acpi).

The following diff fixes my problem (Toshiba L300):

 acpivideo0 at acpi0: OVGA
+acpivout0 at acpivideo0: DD03

 acpivar.h   |    8 -----
 acpivideo.c |   81
++++++++----------------------------------------------------
 acpivout.c  |   30 +++++-----------------
 3 files changed, 20 insertions(+), 99 deletions(-)

Index: acpivar.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpivar.h,v
retrieving revision 1.69
diff -u -r1.69 acpivar.h
--- acpivar.h   2 Jan 2011 04:56:57 -0000       1.69
+++ acpivar.h   31 Mar 2011 07:57:59 -0000
@@ -49,9 +49,6 @@

        struct acpi_softc *sc_acpi;
        struct aml_node *sc_devnode;
-
-       int     *sc_dod;
-       size_t  sc_dod_len;
 };

 struct acpi_attach_args {
@@ -61,11 +58,6 @@
        void            *aaa_table;
        struct aml_node *aaa_node;
        const char      *aaa_dev;
-};
-
-struct acpivideo_attach_args {
-       struct acpi_attach_args aaa;
-       int dod;
 };

 struct acpi_mem_map {
Index: acpivideo.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpivideo.c,v
retrieving revision 1.7
diff -u -r1.7 acpivideo.c
--- acpivideo.c 27 Jul 2010 06:12:50 -0000      1.7
+++ acpivideo.c 31 Mar 2011 07:57:59 -0000
@@ -54,7 +54,6 @@
 int    acpivideo_notify(struct aml_node *, int, void *);

 void   acpivideo_set_policy(struct acpivideo_softc *, int);
-void   acpivideo_get_dod(struct acpivideo_softc *);
 int    acpi_foundvout(struct aml_node *, void *);
 int    acpivideo_print(void *, const char *);

@@ -101,8 +100,6 @@
        acpivideo_set_policy(sc,
            DOS_SWITCH_BY_OSPM | DOS_BRIGHTNESS_BY_OSPM);

-       acpivideo_get_dod(sc);
-       aml_find_node(aaa->aaa_node, "_DCS", acpi_foundvout, sc);
        aml_find_node(aaa->aaa_node, "_BCL", acpi_foundvout, sc);
 }

@@ -137,7 +134,7 @@
        args.type = AML_OBJTYPE_INTEGER;

        aml_evalname(sc->sc_acpi, sc->sc_devnode, "_DOS", 1, &args, &res);
-       DPRINTF(("%s: set policy to %d", DEVNAME(sc), aml_val2int(&res)));
+       DPRINTF(("%s: set policy to %X\n", DEVNAME(sc), aml_val2int(&res)));

        aml_freevalue(&res);
 }
@@ -145,45 +142,23 @@
 int
 acpi_foundvout(struct aml_node *node, void *arg)
 {
-       struct aml_value        res;
-       int     i, addr;
-       char    fattach = 0;
-
        struct acpivideo_softc *sc = (struct acpivideo_softc *)arg;
        struct device *self = (struct device *)arg;
-       struct acpivideo_attach_args av;
+       struct acpi_attach_args aaa;
+       node = node->parent;

-       if (sc->sc_dod == NULL)
-               return (0);
-       DPRINTF(("Inside acpi_foundvout()"));
-       if (aml_evalname(sc->sc_acpi, node->parent, "_ADR", 0, NULL, &res)) {
-               DPRINTF(("%s: no _ADR\n", DEVNAME(sc)));
+       DPRINTF(("Inside acpi_foundvout()\n"));
+       if (node->parent != sc->sc_devnode)
                return (0);
-       }
-       addr = aml_val2int(&res);
-       DPRINTF(("_ADR: %X\n", addr));
-       aml_freevalue(&res);

-       for (i = 0; i < sc->sc_dod_len; i++)
-               if (addr == (sc->sc_dod[i]&0xffff)) {
-                       DPRINTF(("Matched: %X\n", sc->sc_dod[i]));
-                       fattach = 1;
-                       break;
-               }
-       if (fattach) {
-               memset(&av, 0, sizeof(av));
-               av.aaa.aaa_iot = sc->sc_acpi->sc_iot;
-               av.aaa.aaa_memt = sc->sc_acpi->sc_memt;
-               av.aaa.aaa_node = node->parent;
-               av.aaa.aaa_name = "acpivout";
-               av.dod = sc->sc_dod[i];
-               /*
-                *  Make sure we don't attach twice if both _BCL and
-                * _DCS methods are found by zeroing the DOD address.
-                */
-               sc->sc_dod[i] = 0;
+       if (aml_searchname(node, "_BCM") && aml_searchname(node, "_BQC")) {
+               memset(&aaa, 0, sizeof(aaa));
+               aaa.aaa_iot = sc->sc_acpi->sc_iot;
+               aaa.aaa_memt = sc->sc_acpi->sc_memt;
+               aaa.aaa_node = node;
+               aaa.aaa_name = "acpivout";

-               config_found(self, &av, acpivideo_print);
+               config_found(self, &aaa, acpivideo_print);
        }

        return (0);
@@ -202,38 +177,6 @@
        }

        return (UNCONF);
-}
-
-void
-acpivideo_get_dod(struct acpivideo_softc * sc)
-{
-       struct aml_value        res;
-       int     i;
-
-       if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "_DOD", 0, NULL, &res)) {
-               DPRINTF(("%s: no _DOD\n", DEVNAME(sc)));
-               return;
-       }
-       sc->sc_dod_len = res.length;
-       if (sc->sc_dod_len == 0) {
-               sc->sc_dod = NULL;
-               aml_freevalue(&res);
-               return;
-       }
-       sc->sc_dod = malloc(sc->sc_dod_len * sizeof(int), M_DEVBUF,
-           M_WAITOK|M_ZERO);
-       if (sc->sc_dod == NULL) {
-               aml_freevalue(&res);
-               return;
-       }
-
-       for (i = 0; i < sc->sc_dod_len; i++) {
-               sc->sc_dod[i] = aml_val2int(res.v_package[i]);
-               DPRINTF(("DOD: %X ", sc->sc_dod[i]));
-       }
-       DPRINTF(("\n"));
-
-       aml_freevalue(&res);
 }

 int
Index: acpivout.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpivout.c,v
retrieving revision 1.7
diff -u -r1.7 acpivout.c
--- acpivout.c  8 Aug 2010 20:45:18 -0000       1.7
+++ acpivout.c  31 Mar 2011 07:57:59 -0000
@@ -58,16 +58,6 @@

        int     *sc_bcl;
        size_t  sc_bcl_len;
-
-       int     sc_dod;
-       int     sc_vout_type;
-#define ACPIVOUT_OTHER         0
-#define ACPIVOUT_VGA           1
-#define ACPIVOUT_TV            2
-#define ACPIVOUT_DVI           3
-#define ACPIVOUT_LCD           4
-
-#define        ACPIVOUT_TYPE_MASK      0x0f00
 };

 void   acpivout_brightness_cycle(struct acpivout_softc *);
@@ -97,12 +87,12 @@
 int
 acpivout_match(struct device *parent, void *match, void *aux)
 {
-       struct acpivideo_attach_args *av = aux;
+       struct acpi_attach_args *aaa = aux;
        struct cfdata           *cf = match;

-       if (av->aaa.aaa_name == NULL ||
-           strcmp(av->aaa.aaa_name, cf->cf_driver->cd_name) != 0 ||
-           av->aaa.aaa_table != NULL)
+       if (aaa->aaa_name == NULL ||
+           strcmp(aaa->aaa_name, cf->cf_driver->cd_name) != 0 ||
+           aaa->aaa_table != NULL)
                return (0);

        return (1);
@@ -112,24 +102,20 @@
 acpivout_attach(struct device *parent, struct device *self, void *aux)
 {
        struct acpivout_softc   *sc = (struct acpivout_softc *)self;
-       struct acpivideo_attach_args *av = aux;
+       struct acpi_attach_args *aaa = aux;

        sc->sc_acpi = ((struct acpivideo_softc *)parent)->sc_acpi;
-       sc->sc_devnode = av->aaa.aaa_node;
-
-       sc->sc_vout_type = (av->dod & ACPIVOUT_TYPE_MASK) >> 8;
+       sc->sc_devnode = aaa->aaa_node;

        printf(": %s\n", sc->sc_devnode->name);

-       aml_register_notify(sc->sc_devnode, av->aaa.aaa_dev,
+       aml_register_notify(sc->sc_devnode, aaa->aaa_dev,
            acpivout_notify, sc, ACPIDEV_NOPOLL);

        ws_get_param = acpivout_get_param;
        ws_set_param = acpivout_set_param;

-       if (sc->sc_vout_type == ACPIVOUT_LCD ||
-           sc->sc_vout_type == ACPIVOUT_VGA)
-               acpivout_get_bcl(sc);
+       acpivout_get_bcl(sc);
 }

 int

Reply via email to