1/* $NetBSD: abtn.c,v 1.19 2012/10/27 17:18:00 chs Exp $ */ 2 3/*- 4 * Copyright (C) 1999 Tsubai Masanari. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> 30__KERNEL_RCSID(0, "$NetBSD: abtn.c,v 1.19 2012/10/27 17:18:00 chs Exp $"); 31 32#include <sys/param.h> 33#include <sys/device.h> 34#include <sys/systm.h> 35 36#include <macppc/dev/akbdvar.h> 37#include <macppc/dev/adbvar.h> 38#include <macppc/dev/pm_direct.h> 39 40#define NVRAM_BRIGHTNESS 0x140e 41#define ABTN_HANDLER_ID 31 42 43#define BUTTON_LOUDER 0x06 44#define BUTTON_SOFTER 0x07 45#define BUTTON_MUTE 0x08 46#define BUTTON_BRIGHTER 0x09 47#define BUTTON_DIMMER 0x0a 48#define BUTTON_EJECT 0x0b 49#define BUTTON_DISPLAY 0x0c 50#define BUTTON_KEYPAD 0x7f 51#define BUTTON_DEPRESS 0x80 52 53struct abtn_softc { 54 device_t sc_dev; 55 56 int origaddr; /* ADB device type */ 57 int adbaddr; /* current ADB address */ 58 int handler_id; 59 60 int brightness; /* backlight brightness */ 61 int volume; /* speaker volume (not yet) */ 62}; 63 64static int abtn_match(device_t, cfdata_t, void *); 65static void abtn_attach(device_t, device_t, void *); 66static void abtn_adbcomplete(uint8_t *, uint8_t *, int); 67 68CFATTACH_DECL_NEW(abtn, sizeof(struct abtn_softc), 69 abtn_match, abtn_attach, NULL, NULL); 70 71int 72abtn_match(device_t parent, cfdata_t cf, void *aux) 73{ 74 struct adb_attach_args *aa = aux; 75 76 if (aa->origaddr == ADBADDR_MISC && 77 aa->handler_id == ABTN_HANDLER_ID) 78 return 1; 79 80 return 0; 81} 82 83void 84abtn_attach(device_t parent, device_t self, void *aux) 85{ 86 struct abtn_softc *sc = device_private(self); 87 struct adb_attach_args *aa = aux; 88 ADBSetInfoBlock adbinfo; 89 int bright; 90 91 sc->sc_dev = self; 92 93 printf("buttons\n"); 94 95 bright = pm_read_nvram(NVRAM_BRIGHTNESS); 96 if (bright != 0) 97 pm_set_brightness(bright); 98 sc->brightness = bright; 99 100 sc->origaddr = aa->origaddr; 101 sc->adbaddr = aa->adbaddr; 102 sc->handler_id = aa->handler_id; 103 104 adbinfo.siServiceRtPtr = (Ptr)abtn_adbcomplete; 105 adbinfo.siDataAreaAddr = (void *)sc; 106 107 SetADBInfo(&adbinfo, sc->adbaddr); 108} 109 110extern struct cfdriver akbd_cd; 111 112void 113abtn_adbcomplete(uint8_t *buffer, uint8_t *data, int adb_command) 114{ 115 struct abtn_softc *sc = (struct abtn_softc *)data; 116 u_int cmd; 117#ifdef FORCE_FUNCTION_KEYS 118 int key = 0; 119#endif 120 121 cmd = buffer[1]; 122 123#ifdef FORCE_FUNCTION_KEYS 124 switch (cmd & 0x7f) { 125 case 0x0a: /* f1 */ 126 key = 122; 127 break; 128 case 0x09: /* f2 */ 129 key = 120; 130 break; 131 case 0x08: /* f3 */ 132 key = 99; 133 break; 134 case 0x07: /* f4 */ 135 key = 118; 136 break; 137 case 0x06: /* f5 */ 138 key = 96; 139 break; 140 case 0x7f: /* f6 */ 141 key = 97; 142 break; 143 case 0x0b: /* f12 */ 144 key = 111; 145 break; 146 } 147 if (key != 0) { 148 key |= cmd & 0x80; 149 kbd_passup(device_lookup_private(&akbd_cd, 0),key); 150 return; 151 } 152#endif 153 154 if (cmd >= BUTTON_DEPRESS) 155 return; 156 157 switch (cmd) { 158 case BUTTON_DIMMER: 159 sc->brightness -= 8; 160 if (sc->brightness < 8) 161 sc->brightness = 8; 162 pm_set_brightness(sc->brightness); 163 pm_write_nvram(NVRAM_BRIGHTNESS, sc->brightness); 164 break; 165 166 case BUTTON_BRIGHTER: 167 sc->brightness += 8; 168 if (sc->brightness > 0x78) 169 sc->brightness = 0x78; 170 pm_set_brightness(sc->brightness); 171 pm_write_nvram(NVRAM_BRIGHTNESS, sc->brightness); 172 break; 173 174 case BUTTON_MUTE: 175 case BUTTON_SOFTER: 176 case BUTTON_LOUDER: 177 printf("%s: volume setting not implemented\n", 178 device_xname(sc->sc_dev)); 179 break; 180 case BUTTON_DISPLAY: 181 printf("%s: display selection not implemented\n", 182 device_xname(sc->sc_dev)); 183 break; 184 case BUTTON_EJECT: 185 printf("%s: eject not implemented\n", 186 device_xname(sc->sc_dev)); 187 break; 188 189 /* The keyboard gets wacky when in keypad mode. */ 190 case BUTTON_KEYPAD: 191 break; 192 193 default: 194 printf("%s: unknown button 0x%x\n", 195 device_xname(sc->sc_dev), cmd); 196 } 197} 198