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