Cool. What I am not sure about is if we want to have a bunch of little vendor drivers or a big driver that does all the vendor stuff. I need to think this through. Any comments?

giovanni wrote:
hello,

because I could not change the excessive lcd brightness of my laptop under openbsd I started searching for... this article
http://www.linux.it/~malattia/wiki/index.php/Sony-laptop
was the inspiration and I wrote this humble basic driver.
here it works well and I think it should also work for others
vaio laptops (or at least for vaios that have SBRT/GBRT acpi methods.

...
acpidock at acpi0 not configured
acpisnc0 at acpi0: SNC_
...

usage:
sysctl -w hw.brightness=0..8

giovanni

diff -ruN sys.orig/arch/i386/conf/GENERIC sys/arch/i386/conf/GENERIC
--- sys.orig/arch/i386/conf/GENERIC    Fri Apr 27 11:03:35 2007
+++ sys/arch/i386/conf/GENERIC    Sat Apr 28 09:22:37 2007
@@ -59,7 +59,7 @@
 pci*    at mainbus0

 #option        ACPIVERBOSE
-#option        ACPI_ENABLE
+option        ACPI_ENABLE

 acpi0        at mainbus?    disable
 #acpitimer*    at acpi?
@@ -72,6 +72,7 @@
 acpiec*        at acpi?    disable
 acpiprt*    at acpi?
 #acpitz*    at acpi?
+acpisnc* at acpi?    # sony notebook controller

 option        PCIVERBOSE
 option        EISAVERBOSE
diff -ruN sys.orig/dev/acpi/acpi.c sys/dev/acpi/acpi.c
--- sys.orig/dev/acpi/acpi.c    Fri Apr 27 10:46:22 2007
+++ sys/dev/acpi/acpi.c    Sat Apr 28 08:57:53 2007
@@ -65,6 +65,7 @@
 void    acpi_foundec(struct aml_node *, void *);
 void    acpi_foundtmp(struct aml_node *, void *);
 void    acpi_inidev(struct aml_node *, void *);
+void  acpi_foundsnc(struct aml_node *, void *);

 int    acpi_loadtables(struct acpi_softc *, struct acpi_rsdp *);
 void    acpi_load_table(paddr_t, size_t, acpi_qhead_t *);
@@ -573,6 +574,9 @@
     /* attach docks */
     aml_find_node(aml_root.child, "_DCK", acpi_founddock, sc);

+  /* attach sony notebook control */
+  aml_find_node(aml_root.child, "GBRT", acpi_foundsnc, sc);
+
     /* create list of devices we want to query when APM come in */
     SLIST_INIT(&sc->sc_ac);
     SLIST_INIT(&sc->sc_bat);
@@ -1718,4 +1722,24 @@

     config_found(self, &aaa, acpi_print);
 }
+
+void
+acpi_foundsnc(struct aml_node *node, void *arg)
+{
+    struct acpi_softc *sc = (struct acpi_softc *)arg;
+    struct device   *self = (struct device *)arg;
+    const char    *dev;
+    struct acpi_attach_args aaa;
+
+    dnprintf(10, "found snc entry: %s\n", node->parent->name);
+    memset(&aaa, 0, sizeof(aaa));
+    aaa.aaa_iot = sc->sc_iot;
+    aaa.aaa_memt = sc->sc_memt;
+    aaa.aaa_node = node->parent;
+    aaa.aaa_dev = dev;
+    aaa.aaa_name = "acpisnc";
+ + config_found(self, &aaa, acpi_print);
+}
+
 #endif /* SMALL_KERNEL */
diff -ruN sys.orig/dev/acpi/acpidev.h sys/dev/acpi/acpidev.h
--- sys.orig/dev/acpi/acpidev.h    Fri Apr 27 10:46:22 2007
+++ sys/dev/acpi/acpidev.h    Sat Apr 28 07:33:48 2007
@@ -311,5 +311,14 @@
 #define ACPIDOCK_EVENT_INSERT    0
 #define    ACPIDOCK_EVENT_EJECT    3

+struct acpisnc_softc {
+    struct device             sc_dev;
+
+    bus_space_tag_t     sc_iot;
+    bus_space_handle_t    sc_ioh;
+
+    struct acpi_softc     *sc_acpi;
+    struct aml_node         *sc_devnode;
+};

 #endif /* __DEV_ACPI_ACPIDEV_H__ */
diff -ruN sys.orig/dev/acpi/acpisnc.c sys/dev/acpi/acpisnc.c
--- sys.orig/dev/acpi/acpisnc.c    Thu Jan  1 01:00:00 1970
+++ sys/dev/acpi/acpisnc.c    Sat Apr 28 15:14:59 2007
@@ -0,0 +1,89 @@
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/malloc.h>
+#include <sys/sysctl.h>
+
+#include <machine/bus.h>
+
+#include <dev/acpi/acpireg.h>
+#include <dev/acpi/acpivar.h>
+#include <dev/acpi/acpidev.h>
+#include <dev/acpi/amltypes.h>
+#include <dev/acpi/dsdt.h>
+
+extern int brtlevel;
+
+int    acpisnc_match(struct device *, void *, void *);
+void     acpisnc_attach(struct device *, struct device *, void *);
+void brightness(int*);
+
+static struct acpisnc_softc    *sc;
+
+struct cfattach acpisnc_ca = {
+    sizeof(struct acpisnc_softc), acpisnc_match, acpisnc_attach
+};
+
+struct cfdriver acpisnc_cd = {
+    NULL, "acpisnc", DV_DULL
+};
+
+int
+acpisnc_match(struct device *parent, void *match, void *aux)
+{
+    struct acpi_attach_args     *aaa = aux;
+    struct cfdata         *cf = match;
+
+    /* sanity */
+    if (aaa->aaa_name == NULL ||
+        strcmp(aaa->aaa_name, cf->cf_driver->cd_name) != 0 ||
+        aaa->aaa_table != NULL)
+        return (0);
+
+    return (1);
+}
+
+void
+acpisnc_attach(struct device *parent, struct device *self, void *aux)
+{
+    sc = (struct acpisnc_softc *)self;
+    struct acpi_attach_args *aa = aux;
+    struct aml_value    res;
+
+    sc->sc_acpi = (struct acpi_softc *)parent;
+    sc->sc_devnode = aa->aaa_node->child;
+
+    printf(": %s\n", sc->sc_devnode->parent->name);
+ + /* read GBRT i.e default stored brighteness level */ + if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "GBRT", 0, NULL, &res)) {
+        dnprintf(10, "%s: error reading current brightness", DEVNAME(sc));
+        goto err;
+    }
+ + brtlevel = aml_val2int(&res); + brt_set = brightness;
+
+err: + aml_freevalue(&res); +}
+
+void
+brightness(int *val) {
+ + struct aml_value res;
+
+    if (*val > 8)
+        *val = 8;
+    if (*val < 0)
+        *val = 0;
+
+    memset(&res, 0, sizeof(res));
+    res.type = AML_OBJTYPE_INTEGER;
+    res.v_integer = *val;
+ + if (aml_evalname(sc->sc_acpi, sc->sc_devnode, "SBRT", 1, &res, NULL))
+        printf("error settings current brightness to %d\n", *val);
+ + aml_freevalue(&res); +}
diff -ruN sys.orig/dev/acpi/files.acpi sys/dev/acpi/files.acpi
--- sys.orig/dev/acpi/files.acpi    Fri Apr 27 10:46:22 2007
+++ sys/dev/acpi/files.acpi    Sat Apr 28 07:35:45 2007
@@ -66,3 +66,8 @@
 attach    acpidock at acpi
 file    dev/acpi/acpidock.c        acpidock

+# sony notebook controller
+device  acpisnc
+attach  acpisnc at acpi
+file    dev/acpi/acpisnc.c    acpisnc
+
diff -ruN sys.orig/kern/kern_sysctl.c sys/kern/kern_sysctl.c
--- sys.orig/kern/kern_sysctl.c    Fri Apr 27 10:46:55 2007
+++ sys/kern/kern_sysctl.c    Sat Apr 28 07:48:53 2007
@@ -107,6 +107,9 @@
 void (*cpu_setperf)(int);
 int perflevel = 100;

+int brtlevel = 1;
+void (*brt_set)(int*);
+
 /*
  * Lock to avoid too many processes vslocking a large amount of memory
  * at the same time.
@@ -605,6 +608,15 @@
         if (err)
             return err;
         return (sysctl_rdint(oldp, oldlenp, newp, cpuspeed));
+    case HW_SETBRT:
+        if (!brt_set)
+          return (EOPNOTSUPP);
+        err = sysctl_int(oldp, oldlenp, newp, newlen, &brtlevel);
+        if (err)
+            return err;
+        if (newp)
+            brt_set(&brtlevel);
+        return (0);
     case HW_SETPERF:
         if (!cpu_setperf)
             return (EOPNOTSUPP);
diff -ruN sys.orig/sys/sysctl.h sys/sys/sysctl.h
--- sys.orig/sys/sysctl.h    Fri Apr 27 10:47:11 2007
+++ sys/sys/sysctl.h    Sat Apr 28 07:50:36 2007
@@ -552,7 +552,8 @@
 #define    HW_VERSION    16        /* string: hardware version */
 #define    HW_SERIALNO    17        /* string: hardware serial number */
 #define    HW_UUID        18        /* string: universal unique id */
-#define    HW_MAXID    19        /* number of valid hw ids */
+#define HW_SETBRT 19    /* set LCD brightness */
+#define    HW_MAXID    20        /* number of valid hw ids */

 #define    CTL_HW_NAMES { \
     { 0, 0 }, \
@@ -574,6 +575,7 @@
     { "version", CTLTYPE_STRING }, \
     { "serialno", CTLTYPE_STRING }, \
     { "uuid", CTLTYPE_STRING }, \
+    { "brightness", CTLTYPE_INT }, \
 }

 /*
@@ -724,6 +726,7 @@

 extern int (*cpu_cpuspeed)(int *);
 extern void (*cpu_setperf)(int);
+extern void (*brt_set)(int*);

 int bpf_sysctl(int *, u_int, void *, size_t *, void *, size_t);

Reply via email to