How to use this patch: # mknod /dev/battery c 29 0 % cd src/sys/arch/macppc; patch -p < battery.diff % cd conf; config GENERIC etc. Index: conf/GENERIC =================================================================== RCS file: /cvsroot/src/sys/arch/macppc/conf/GENERIC,v retrieving revision 1.4 diff -c -r1.4 GENERIC *** conf/GENERIC 2001/08/27 09:46:50 1.4 --- conf/GENERIC 2001/08/29 03:22:24 *************** *** 194,199 **** --- 194,200 ---- wdc* at mediabay? flags 0 awacs* at obio? # Apple audio device wi* at obio? # AirMac + battery* at obio? # Battery status cardslot* at cbb? cardbus* at cardslot? Index: conf/files.macppc =================================================================== RCS file: /cvsroot/src/sys/arch/macppc/conf/files.macppc,v retrieving revision 1.2 diff -c -r1.2 files.macppc *** conf/files.macppc 2001/08/22 02:04:35 1.2 --- conf/files.macppc 2001/08/29 03:23:01 *************** *** 176,181 **** --- 176,185 ---- attach abtn at adb file arch/macppc/dev/abtn.c abtn + device battery + attach battery at obio + file arch/macppc/dev/battery.c battery needs-flag + device nvram attach nvram at obio file arch/macppc/dev/nvram.c nvram needs-flag Index: dev/pm_direct.c =================================================================== RCS file: /cvsroot/src/sys/arch/macppc/dev/pm_direct.c,v retrieving revision 1.2 diff -c -r1.2 pm_direct.c *** dev/pm_direct.c 2001/08/22 02:04:41 1.2 --- dev/pm_direct.c 2001/08/29 03:41:36 *************** *** 1282,1284 **** --- 1282,1318 ---- p.data[2] = val; pmgrop(&p); } + + int + pm_battery(val) + int val; + { + PMData p; + u_int16_t *bat = (void *)p.data; + + p.command = 0x6f; + p.num_data = 1; + p.s_buf = p.r_buf = p.data; + p.data[0] = val; + if (pmgrop(&p)) + return 0; + + if (bat[0] & 0x04) + return bat[1] * 100 / bat[2]; + else + return 0; + } + + int + pm_read_switch() + { + PMData p; + + p.command = 0xdc; + p.num_data = 0; + p.s_buf = p.r_buf = p.data; + if (pmgrop(&p)) + return 0; + + return p.data[0]; + } Index: dev/pm_direct.h =================================================================== RCS file: /cvsroot/src/sys/arch/macppc/dev/pm_direct.h,v retrieving revision 1.1.1.1 diff -c -r1.1.1.1 pm_direct.h *** dev/pm_direct.h 2001/07/10 12:01:26 1.1.1.1 --- dev/pm_direct.h 2001/08/29 03:14:24 *************** *** 55,60 **** --- 55,62 ---- void pm_set_brightness __P((int)); void pm_init_brightness __P((void)); void pm_eject_pcmcia __P((int)); + int pm_battery(int); + int pm_read_switch(void); /* PMU commands */ #define PMU_POWER_OFF 0x7e /* Turn Power off */ Index: macppc/conf.c =================================================================== RCS file: /cvsroot/src/sys/arch/macppc/macppc/conf.c,v retrieving revision 1.2 diff -c -r1.2 conf.c *** macppc/conf.c 2001/08/27 10:01:25 1.2 --- macppc/conf.c 2001/08/29 03:25:15 *************** *** 172,177 **** --- 172,180 ---- cdev_decl(i4brbch); cdev_decl(i4btel); + #include "battery.h" + cdev_decl(battery); + struct cdevsw cdevsw[] = { cdev_cn_init(1,cn), /* 0: virtual console */ cdev_ctty_init(1,ctty), /* 1: control tty */ *************** *** 202,208 **** cdev_disk_init(NCCD,ccd), /* 26: concatenated disk driver */ cdev_disk_init(NMD,md), /* 27: memory disk driver */ cdev_mouse_init(NAED,aed), /* 28: ADB event interface */ ! cdev_lkm_dummy(), /* 29: */ cdev_disk_init(NWD,wd), /* 30: IDE disk driver */ cdev_lkm_init(NLKM,lkm), /* 31: loadable module driver */ cdev_fd_init(1,filedesc), /* 32: file descriptor pseudo-device */ --- 205,211 ---- cdev_disk_init(NCCD,ccd), /* 26: concatenated disk driver */ cdev_disk_init(NMD,md), /* 27: memory disk driver */ cdev_mouse_init(NAED,aed), /* 28: ADB event interface */ ! cdev__ocri_init(NBATTERY,battery), /* 29: battery status */ cdev_disk_init(NWD,wd), /* 30: IDE disk driver */ cdev_lkm_init(NLKM,lkm), /* 31: loadable module driver */ cdev_fd_init(1,filedesc), /* 32: file descriptor pseudo-device */ Index: dev/battery.c =================================================================== diff -c /dev/null dev/battery.c:1.1 *** /dev/null Wed Aug 29 12:47:25 2001 --- dev/battery.c Wed Aug 29 12:21:19 2001 *************** *** 0 **** --- 1,141 ---- + /* $NetBSD$ */ + + /*- + * Copyright (c) 2001 Tsubai Masanari. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + #include + #include + #include + #include + #include + + #include + #include + + int battery_match(struct device *, struct cfdata *, void *); + void battery_attach(struct device *, struct device *, void *); + + cdev_decl(battery); + + struct cfattach battery_ca = { + sizeof(struct device), battery_match, battery_attach + }; + + int + battery_match(parent, cf, aux) + struct device *parent; + struct cfdata *cf; + void *aux; + { + struct confargs *ca = aux; + + if (strcmp(ca->ca_name, "battery") == 0) + return 1; + + return 0; + } + + void + battery_attach(parent, self, aux) + struct device *parent, *self; + void *aux; + { + + printf("\n"); + } + + int + batteryopen(dev, flag, mode, p) + dev_t dev; + int flag, mode; + struct proc *p; + { + int unit = minor(dev); + + if (unit != 0) + return ENXIO; + + return 0; + } + + int + batteryclose(dev, flag, mode, p) + dev_t dev; + int flag, mode; + struct proc *p; + { + + return 0; + } + + int + batteryread(dev, uio, flag) + dev_t dev; + struct uio *uio; + int flag; + { + int ac; + u_int len, off; + char buf[11]; /* "1 100 100\n" */ + + off = uio->uio_offset; + + if (off >= sizeof buf) + return uiomove(buf, 0, uio); + + len = uio->uio_resid; + if (off + len > sizeof buf) + len = sizeof buf - off; + + ac = (pm_read_switch() & 0x04) >> 2; + + bzero(buf, sizeof buf); + snprintf(buf, sizeof buf, "%d %d %d\n", + ac, pm_battery(1), pm_battery(2)); + return uiomove(buf + off, len, uio); + } + + int + batterywrite(dev, uio, flag) + dev_t dev; + struct uio *uio; + int flag; + { + + return ENXIO; + } + + int + batteryioctl(dev, cmd, data, flag, p) + dev_t dev; + u_long cmd; + caddr_t data; + int flag; + struct proc *p; + { + + return ENOTTY; + }