Home | History | Annotate | Line # | Download | only in hpc
btnmgr.c revision 1.1
      1 /*	$NetBSD: btnmgr.c,v 1.1 2001/02/22 18:37:54 uch Exp $	*/
      2 
      3 /*-
      4  * Copyright (c) 1999
      5  *         Shin Takemura and PocketBSD Project. All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *	This product includes software developed by the PocketBSD project
     18  *	and its contributors.
     19  * 4. Neither the name of the project nor the names of its contributors
     20  *    may be used to endorse or promote products derived from this software
     21  *    without specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  * SUCH DAMAGE.
     34  *
     35  */
     36 #define BTNMGRDEBUG
     37 
     38 #include <sys/param.h>
     39 #include <sys/systm.h>
     40 #include <sys/ioctl.h>
     41 #include <sys/conf.h>
     42 #include <sys/device.h>
     43 #include <sys/malloc.h>
     44 #include <sys/kernel.h>
     45 
     46 #include "opt_wsdisplay_compat.h"
     47 #include <dev/wscons/wsconsio.h>
     48 #include <dev/wscons/wskbdvar.h>
     49 #include <dev/wscons/wsksymdef.h>
     50 #ifdef WSDISPLAY_COMPAT_RAWKBD
     51 #include <dev/hpc/pckbd_encode.h>
     52 #endif
     53 
     54 #include <machine/bus.h>
     55 #include <machine/autoconf.h>
     56 #include <machine/config_hook.h>
     57 
     58 #ifdef BTNMGRDEBUG
     59 #ifndef BTNMGRDEBUG_CONF
     60 #define BTNMGRDEBUG_CONF 0
     61 #endif
     62 int	btnmgr_debug = BTNMGRDEBUG_CONF;
     63 #define	DPRINTF(arg) if (btnmgr_debug) printf arg;
     64 #define	DPRINTFN(n, arg) if (btnmgr_debug > (n)) printf arg;
     65 #else
     66 #define	DPRINTF(arg)
     67 #define DPRINTFN(n, arg)
     68 #endif
     69 
     70 cdev_decl(btnmgr);
     71 
     72 struct btnmgr_softc {
     73 	struct device sc_dev;
     74 	config_hook_tag	sc_hook_tag;
     75 	int sc_enabled;
     76 	struct device *sc_wskbddev;
     77 #ifdef WSDISPLAY_COMPAT_RAWKBD
     78 	int sc_rawkbd;
     79 #endif
     80 };
     81 
     82 /*
     83 static struct btnmgr_softc *the_btnmgr_sc;
     84 */
     85 
     86 /*
     87 void		btnmgrattach  __P((int));
     88  */
     89 int btnmgrmatch __P((struct device *, struct cfdata *, void *));
     90 void btnmgrattach __P((struct device *, struct device *, void *));
     91 char*		btnmgr_name __P((long));
     92 static int	btnmgr_hook __P((void *, int, long, void *));
     93 
     94 
     95 /*
     96  * global/static data
     97  */
     98 struct cfattach btnmgr_ca = {
     99 	sizeof(struct btnmgr_softc), btnmgrmatch, btnmgrattach
    100 };
    101 
    102 /* wskbd accessopts */
    103 int	btnmgr_wskbd_enable __P((void *, int));
    104 void	btnmgr_wskbd_set_leds __P((void *, int));
    105 int	btnmgr_wskbd_ioctl __P((void *, u_long, caddr_t, int, struct proc *));
    106 
    107 const struct wskbd_accessops btnmgr_wskbd_accessops = {
    108 	btnmgr_wskbd_enable,
    109 	btnmgr_wskbd_set_leds,
    110 	btnmgr_wskbd_ioctl,
    111 };
    112 
    113 /* button config: index by buttun event id */
    114 static const struct {
    115 	int  kevent;
    116 	int  keycode;
    117 	char *name;
    118 } button_config[] = {
    119 	/* id					kevent keycode name	*/
    120 	[CONFIG_HOOK_BUTTONEVENT_POWER] =	{ 0,   0, "Power"	},
    121 	[CONFIG_HOOK_BUTTONEVENT_OK] =		{ 1,  28, "OK"		},
    122 	[CONFIG_HOOK_BUTTONEVENT_CANCEL] =	{ 1,   1, "Cancel"	},
    123 	[CONFIG_HOOK_BUTTONEVENT_UP] =		{ 1,  72, "Up"		},
    124 	[CONFIG_HOOK_BUTTONEVENT_DOWN] =	{ 1,  80, "Down"	},
    125 	[CONFIG_HOOK_BUTTONEVENT_REC] =		{ 0,   0, "Rec"		},
    126 	[CONFIG_HOOK_BUTTONEVENT_COVER] =	{ 0,   0, "Cover"	},
    127 	[CONFIG_HOOK_BUTTONEVENT_LIGHT] =	{ 1,  57, "Light"	},
    128 	[CONFIG_HOOK_BUTTONEVENT_CONTRAST] =	{ 0,   0, "Contrast"	},
    129 	[CONFIG_HOOK_BUTTONEVENT_APP0] =	{ 1,  67, "Application 0" },
    130 	[CONFIG_HOOK_BUTTONEVENT_APP1] =	{ 1,  68, "Application 1" },
    131 	[CONFIG_HOOK_BUTTONEVENT_APP2] =	{ 1,  87, "Application 2" },
    132 	[CONFIG_HOOK_BUTTONEVENT_APP3] =	{ 1,  88, "Application 3" },
    133 };
    134 static const int n_button_config =
    135 	sizeof(button_config) / sizeof(*button_config);
    136 
    137 #define KC(n) KS_KEYCODE(n)
    138 static const keysym_t btnmgr_keydesc_default[] = {
    139 /*  pos				normal			shifted		*/
    140     KC(1), 			KS_Escape,
    141     KC(28), 			KS_Return,
    142     KC(57),	KS_Cmd,		KS_Cmd_BacklightToggle,
    143     KC(67), 			KS_f9,
    144     KC(68), 			KS_f10,
    145     KC(72), 			KS_KP_Up,
    146     KC(80), 			KS_KP_Down,
    147     KC(87), 			KS_f11,
    148     KC(88), 			KS_f12,
    149 };
    150 #undef KC
    151 #define KBD_MAP(name, base, map) \
    152 			{ name, base, sizeof(map)/sizeof(keysym_t), map }
    153 const struct wscons_keydesc btnmgr_keydesctab[] = {
    154 	KBD_MAP(KB_US,		0,	btnmgr_keydesc_default),
    155 	{0, 0, 0, 0}
    156 };
    157 #undef KBD_MAP
    158 
    159 struct wskbd_mapdata btnmgr_keymapdata = {
    160 	btnmgr_keydesctab,
    161 	KB_US, /* XXX, This is bad idea... */
    162 };
    163 
    164 /*
    165  *  function bodies
    166  */
    167 int
    168 btnmgrmatch(parent, match, aux)
    169 	struct device *parent;
    170 	struct cfdata *match;
    171 	void *aux;
    172 {
    173 	struct mainbus_attach_args *ma = aux;
    174 
    175 	if (strcmp(ma->ma_name, match->cf_driver->cd_name))
    176 		return 0;
    177 
    178 	return (1);
    179 }
    180 
    181 void
    182 btnmgrattach(parent, self, aux)
    183 	struct device *parent, *self;
    184 	void *aux;
    185 {
    186 	int id;
    187 	struct btnmgr_softc *sc = (struct btnmgr_softc *)self;
    188 	struct wskbddev_attach_args wa;
    189 
    190 	printf("\n");
    191 
    192 	/*
    193 	 * install button event listener
    194 	 */
    195 	for (id = 0; id <= CONFIG_HOOK_MAX_ID; id++)
    196 		if (button_config[id].name != NULL)
    197 			sc->sc_hook_tag = config_hook(CONFIG_HOOK_BUTTONEVENT,
    198 						      id, CONFIG_HOOK_SHARE,
    199 						      btnmgr_hook, sc);
    200 
    201 	/*
    202 	 * attach wskbd
    203 	 */
    204 	wa.console = 0;
    205 	wa.keymap = &btnmgr_keymapdata;
    206 	wa.accessops = &btnmgr_wskbd_accessops;
    207 	wa.accesscookie = sc;
    208 
    209 	sc->sc_wskbddev = config_found(self, &wa, wskbddevprint);
    210 }
    211 
    212 static int
    213 btnmgr_hook(ctx, type, id, msg)
    214 	void *ctx;
    215 	int type;
    216 	long id;
    217 	void *msg;
    218 {
    219 	struct btnmgr_softc *sc = ctx;
    220 
    221 	DPRINTF(("%s button: %s\n", btnmgr_name(id), msg ? "ON" : "OFF"));
    222 
    223 	if (button_config[id].kevent) {
    224 		u_int evtype;
    225 		evtype = msg ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
    226 #ifdef WSDISPLAY_COMPAT_RAWKBD
    227 		if (sc->sc_rawkbd) {
    228 			int n;
    229 			u_char data[16];
    230 			n = pckbd_encode(evtype, button_config[id].keycode,
    231 					 data);
    232 			wskbd_rawinput(sc->sc_wskbddev, data, n);
    233 		} else
    234 #endif
    235 		wskbd_input(sc->sc_wskbddev, evtype,
    236 			    button_config[id].keycode);
    237 	}
    238 
    239 	if (id == CONFIG_HOOK_BUTTONEVENT_POWER && msg)
    240 		config_hook_call(CONFIG_HOOK_PMEVENT,
    241 				 CONFIG_HOOK_PMEVENT_SUSPENDREQ, NULL);
    242 
    243 
    244 	return (0);
    245 }
    246 
    247 char*
    248 btnmgr_name(id)
    249 	long id;
    250 {
    251 	if (id < n_button_config)
    252 		return button_config[id].name;
    253 	return ("unknown");
    254 }
    255 
    256 int
    257 btnmgr_wskbd_enable(scx, on)
    258 	void *scx;
    259 	int on;
    260 {
    261 	struct btnmgr_softc *sc = scx;
    262 
    263 	if (on) {
    264 		if (sc->sc_enabled)
    265 			return (EBUSY);
    266 		sc->sc_enabled = 1;
    267 	} else {
    268 		sc->sc_enabled = 0;
    269 	}
    270 
    271 	return (0);
    272 }
    273 
    274 void
    275 btnmgr_wskbd_set_leds(scx, leds)
    276 	void *scx;
    277 	int leds;
    278 {
    279 	/*
    280 	 * We have nothing to do.
    281 	 */
    282 }
    283 
    284 int
    285 btnmgr_wskbd_ioctl(scx, cmd, data, flag, p)
    286 	void *scx;
    287 	u_long cmd;
    288 	caddr_t data;
    289 	int flag;
    290 	struct proc *p;
    291 {
    292 #ifdef WSDISPLAY_COMPAT_RAWKBD
    293 	struct btnmgr_softc *sc = scx;
    294 #endif
    295 	switch (cmd) {
    296 	case WSKBDIO_GTYPE:
    297 		*(int *)data = WSKBD_TYPE_HPC_BTN;
    298 		return 0;
    299 	case WSKBDIO_SETLEDS:
    300 		DPRINTF(("%s(%d): no LED\n", __FILE__, __LINE__));
    301 		return 0;
    302 	case WSKBDIO_GETLEDS:
    303 		DPRINTF(("%s(%d): no LED\n", __FILE__, __LINE__));
    304 		*(int *)data = 0;
    305 		return (0);
    306 #ifdef WSDISPLAY_COMPAT_RAWKBD
    307 	case WSKBDIO_SETMODE:
    308 		sc->sc_rawkbd = (*(int *)data == WSKBD_RAW);
    309 		DPRINTF(("%s(%d): rawkbd is %s\n", __FILE__, __LINE__,
    310 			sc->sc_rawkbd ? "on" : "off"));
    311 		return (0);
    312 #endif
    313 	}
    314 	return (-1);
    315 }
    316 
    317 #ifdef notyet
    318 int
    319 btnmgropen(dev, flag, mode, p)
    320 	dev_t dev;
    321 	int flag, mode;
    322 	struct proc *p;
    323 {
    324 	return (EINVAL);
    325 }
    326 
    327 int
    328 btnmgrclose(dev, flag, mode, p)
    329 	dev_t dev;
    330 	int flag, mode;
    331 	struct proc *p;
    332 {
    333 	return (EINVAL);
    334 }
    335 
    336 int
    337 btnmgrread(dev, uio, flag)
    338 	dev_t dev;
    339 	struct uio *uio;
    340 	int flag;
    341 {
    342 	return (EINVAL);
    343 }
    344 
    345 int
    346 btnmgrwrite(dev, uio, flag)
    347 	dev_t dev;
    348 	struct uio *uio;
    349 	int flag;
    350 {
    351 	return (EINVAL);
    352 }
    353 
    354 int
    355 btnmgrioctl(dev, cmd, data, flag, p)
    356 	dev_t dev;
    357 	u_long cmd;
    358 	caddr_t data;
    359 	int flag;
    360 	struct proc *p;
    361 {
    362 	return (EINVAL);
    363 }
    364 #endif /* notyet */
    365