xref: /netbsd-src/sys/arch/zaurus/dev/zrc.c (revision 88c7a0e2ff6d0b9b46bd07d9abb5ae7c5b566e21)
1*88c7a0e2Sandvar /*	$NetBSD: zrc.c,v 1.13 2023/03/28 20:01:58 andvar Exp $	*/
2953d3b5bSober /*	$OpenBSD: zaurus_remote.c,v 1.1 2005/11/17 05:26:31 uwe Exp $	*/
3953d3b5bSober 
4953d3b5bSober /*
5953d3b5bSober  * Copyright (c) 2005 Uwe Stuehler <uwe@openbsd.org>
6953d3b5bSober  *
7953d3b5bSober  * Permission to use, copy, modify, and distribute this software for any
8953d3b5bSober  * purpose with or without fee is hereby granted, provided that the above
9953d3b5bSober  * copyright notice and this permission notice appear in all copies.
10953d3b5bSober  *
11953d3b5bSober  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12953d3b5bSober  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13953d3b5bSober  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14953d3b5bSober  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15953d3b5bSober  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16953d3b5bSober  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17953d3b5bSober  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18953d3b5bSober  */
19953d3b5bSober 
20aa1e0567Stsutsui #include "opt_wsdisplay_compat.h"
21aa1e0567Stsutsui 
22953d3b5bSober #include <sys/cdefs.h>
23*88c7a0e2Sandvar __KERNEL_RCSID(0, "$NetBSD: zrc.c,v 1.13 2023/03/28 20:01:58 andvar Exp $");
24953d3b5bSober 
25953d3b5bSober #include <sys/param.h>
26953d3b5bSober #include <sys/device.h>
27953d3b5bSober #include <sys/kernel.h>
28953d3b5bSober #include <sys/callout.h>
29953d3b5bSober #include <sys/systm.h>
30953d3b5bSober 
31953d3b5bSober #include <dev/wscons/wsconsio.h>
32953d3b5bSober #include <dev/wscons/wskbdvar.h>
33953d3b5bSober #include <dev/wscons/wsksymdef.h>
34953d3b5bSober #include <dev/wscons/wsksymvar.h>
35953d3b5bSober 
36953d3b5bSober #include <arm/xscale/pxa2x0reg.h>
37953d3b5bSober #include <arm/xscale/pxa2x0_gpio.h>
38953d3b5bSober 
39953d3b5bSober #include <machine/intr.h>
40953d3b5bSober 
41953d3b5bSober #include <zaurus/zaurus/zaurus_reg.h>
42953d3b5bSober #include <zaurus/zaurus/zaurus_var.h>
43003bdf4cSnonaka #include <zaurus/dev/zsspvar.h>
44003bdf4cSnonaka #include <zaurus/dev/scoopvar.h>
45003bdf4cSnonaka #include <zaurus/dev/ioexpvar.h>
46953d3b5bSober 
47953d3b5bSober #define RESCAN_INTERVAL		(hz/100)
48953d3b5bSober 
49953d3b5bSober #define KEY_RELEASE		0	/* button release */
50953d3b5bSober #define KEY_VOL_DOWN		1
51953d3b5bSober #define KEY_MUTE		2
52953d3b5bSober #define KEY_REWIND		3
53953d3b5bSober #define KEY_VOL_UP		4
54953d3b5bSober #define KEY_FORWARD		5
55953d3b5bSober #define KEY_PLAY		6
56953d3b5bSober #define KEY_STOP		7
57953d3b5bSober #define KEY_EARPHONE		8
58953d3b5bSober 
59953d3b5bSober #ifdef DEBUG
60953d3b5bSober static const char *zrc_keyname[] = {
61953d3b5bSober 	"(release)", "volume down", "mute", "rewind", "volume up",
62953d3b5bSober 	"forward", "play", "stop", "(earphone)"
63953d3b5bSober };
64953d3b5bSober #endif
65953d3b5bSober 
66953d3b5bSober struct zrc_akey {
67953d3b5bSober 	int	min;		/* minimum ADC value or INT_MIN */
68953d3b5bSober 	int	key;		/* remote control key number */
69953d3b5bSober };
70953d3b5bSober 
71953d3b5bSober /* Values match the resistors in the CE-RH2 remote control. */
72953d3b5bSober static const struct zrc_akey zrc_akeytab_c3000[] = {
73953d3b5bSober 	{ 238,		KEY_RELEASE  },
74953d3b5bSober 	{ 202,		KEY_VOL_DOWN },
75953d3b5bSober 	{ 168,		KEY_MUTE     },
76953d3b5bSober 	{ 135,		KEY_REWIND   },
77953d3b5bSober 	{ 105,		KEY_VOL_UP   },
78953d3b5bSober 	{ 74,		KEY_FORWARD  },
79953d3b5bSober 	{ 42,		KEY_PLAY     },
80953d3b5bSober 	{ 12,		KEY_STOP     },
81953d3b5bSober 	{ INT_MIN,	KEY_EARPHONE }
82953d3b5bSober };
83953d3b5bSober 
84953d3b5bSober static const struct zrc_akey *zrc_akeytab = zrc_akeytab_c3000;
85953d3b5bSober 
86953d3b5bSober struct zrc_softc {
871a686006Snonaka 	device_t	 sc_dev;
88953d3b5bSober 	struct callout	 sc_to;
89953d3b5bSober 	void		*sc_ih;
90953d3b5bSober 	int		 sc_key;	/* being scanned */
91953d3b5bSober 	int		 sc_scans;	/* rescan counter */
92953d3b5bSober 	int		 sc_noise;	/* discard if too noisy? */
93953d3b5bSober 	int		 sc_keydown;	/* currently pressed key */
94cbab9cadSchs 	device_t	 sc_wskbddev;
95953d3b5bSober #ifdef WSDISPLAY_COMPAT_RAWKBD
96953d3b5bSober 	int		 sc_rawkbd;
97953d3b5bSober #endif
98953d3b5bSober };
99953d3b5bSober 
100cbab9cadSchs static int	zrc_match(device_t, cfdata_t, void *);
101cbab9cadSchs static void	zrc_attach(device_t, device_t, void *);
102953d3b5bSober 
1031a686006Snonaka CFATTACH_DECL_NEW(zrc, sizeof(struct zrc_softc),
104953d3b5bSober     zrc_match, zrc_attach, NULL, NULL);
105953d3b5bSober 
106fd148500Stsutsui static int	zrc_finalize(device_t);
107953d3b5bSober static int	zrc_intr(void *);
108953d3b5bSober static void	zrc_timeout(void *);
109953d3b5bSober static int	zrc_scan(void);
110953d3b5bSober static void	zrc_input(struct zrc_softc *, int, int);
111953d3b5bSober 
112953d3b5bSober static int	zrc_enable(void *, int);
113953d3b5bSober static void	zrc_set_leds(void *, int);
11453524e44Schristos static int	zrc_ioctl(void *, u_long, void *, int, struct lwp *);
115953d3b5bSober 
116953d3b5bSober struct wskbd_accessops zrc_accessops = {
117953d3b5bSober 	zrc_enable,
118953d3b5bSober 	zrc_set_leds,
119953d3b5bSober 	zrc_ioctl,
120953d3b5bSober };
121953d3b5bSober 
122953d3b5bSober #define	KC(n) KS_KEYCODE(n)
123953d3b5bSober 
124953d3b5bSober /* XXX what keys should be generated in translated mode? */
125953d3b5bSober static const keysym_t zrc_keydesc[] = {
126003bdf4cSnonaka 	KC(KEY_VOL_DOWN),	KS_Cmd_VolumeUp,
127003bdf4cSnonaka 	KC(KEY_MUTE),		KS_Cmd_VolumeToggle,
128953d3b5bSober 	KC(KEY_REWIND),		KS_b,
129003bdf4cSnonaka 	KC(KEY_VOL_UP),		KS_Cmd_VolumeDown,
130953d3b5bSober 	KC(KEY_FORWARD),	KS_f,
131953d3b5bSober 	KC(KEY_PLAY),		KS_p,
132953d3b5bSober 	KC(KEY_STOP),		KS_s,
133953d3b5bSober };
134953d3b5bSober 
135953d3b5bSober #ifdef WSDISPLAY_COMPAT_RAWKBD
136aa1e0567Stsutsui /* XXX see OpenBSD's <sys/dev/wscons/wskbdraw.h> */
137aa1e0567Stsutsui #define	RAWKEY_Null		0x00
138aa1e0567Stsutsui #define	RAWKEY_AudioMute	0x85
139aa1e0567Stsutsui #define	RAWKEY_AudioLower	0x86
140aa1e0567Stsutsui #define	RAWKEY_AudioRaise 	0x87
141953d3b5bSober #define	RAWKEY_AudioRewind	0xa0
142953d3b5bSober #define	RAWKEY_AudioForward	0xa1
143953d3b5bSober #define	RAWKEY_AudioPlay	0xa2
144953d3b5bSober #define	RAWKEY_AudioStop	0xa3
145953d3b5bSober static const keysym_t zrc_xt_keymap[] = {
146953d3b5bSober 	/* KC(KEY_RELEASE), */	RAWKEY_Null,
147953d3b5bSober 	/* KC(KEY_VOL_DOWN), */	RAWKEY_AudioLower,
148953d3b5bSober 	/* KC(KEY_MUTE), */	RAWKEY_AudioMute,
149953d3b5bSober 	/* KC(KEY_REWIND), */	RAWKEY_AudioRewind,
150953d3b5bSober 	/* KC(KEY_VOL_UP), */	RAWKEY_AudioRaise,
151953d3b5bSober 	/* KC(KEY_FORWARD), */	RAWKEY_AudioForward,
152953d3b5bSober 	/* KC(KEY_PLAY), */	RAWKEY_AudioPlay,
153953d3b5bSober 	/* KC(KEY_STOP), */	RAWKEY_AudioStop,
154953d3b5bSober };
155953d3b5bSober #endif
156953d3b5bSober 
157953d3b5bSober static const struct wscons_keydesc zrc_keydesctab[] = {
158953d3b5bSober         {KB_US, 0, sizeof(zrc_keydesc)/sizeof(keysym_t), zrc_keydesc},
159953d3b5bSober         {0, 0, 0, 0}
160953d3b5bSober };
161953d3b5bSober 
162953d3b5bSober struct wskbd_mapdata zrc_keymapdata = {
163953d3b5bSober 	zrc_keydesctab, KB_US
164953d3b5bSober };
165953d3b5bSober 
166f19ed1a8Speter #undef	KC
167f19ed1a8Speter 
168f19ed1a8Speter static int
zrc_match(device_t parent,cfdata_t cf,void * aux)1691a686006Snonaka zrc_match(device_t parent, cfdata_t cf, void *aux)
170953d3b5bSober {
171953d3b5bSober 
172003bdf4cSnonaka 	if (ZAURUS_ISC1000 || ZAURUS_ISC3000)
173953d3b5bSober 		return 1;
174953d3b5bSober 	return 0;
175953d3b5bSober }
176953d3b5bSober 
177f19ed1a8Speter static void
zrc_attach(device_t parent,device_t self,void * aux)1781a686006Snonaka zrc_attach(device_t parent, device_t self, void *aux)
179953d3b5bSober {
1801a686006Snonaka 	struct zrc_softc *sc = device_private(self);
181953d3b5bSober 	struct wskbddev_attach_args a;
182953d3b5bSober 
1831a686006Snonaka 	sc->sc_dev = self;
1841a686006Snonaka 
1851a686006Snonaka 	aprint_normal(": CE-RH2 remote control\n");
1861a686006Snonaka 	aprint_naive("\n");
1871a686006Snonaka 
188953d3b5bSober 	/* Configure remote control interrupt handling. */
18988ab7da9Sad 	callout_init(&sc->sc_to, 0);
190953d3b5bSober 	callout_setfunc(&sc->sc_to, zrc_timeout, sc);
1911a686006Snonaka 
192*88c7a0e2Sandvar 	/* Establish interrupt */
193953d3b5bSober 	pxa2x0_gpio_set_function(C3000_RC_IRQ_PIN, GPIO_IN);
194953d3b5bSober 	sc->sc_ih = pxa2x0_gpio_intr_establish(C3000_RC_IRQ_PIN,
195953d3b5bSober 	    IST_EDGE_BOTH, IPL_BIO, zrc_intr, sc);
1961a686006Snonaka 	if (sc->sc_ih == NULL) {
1971a686006Snonaka 		aprint_error_dev(sc->sc_dev, "couldn't establish interrupt.\n");
1981a686006Snonaka 		return;
1991a686006Snonaka 	}
200953d3b5bSober 
201fd148500Stsutsui 	/* defer enabling pullup until ioexp or scoop is attached */
202fd148500Stsutsui 	config_finalize_register(self, zrc_finalize);
203953d3b5bSober 
204953d3b5bSober 	sc->sc_keydown = KEY_RELEASE;
205953d3b5bSober 
206953d3b5bSober 	a.console = 0;
207953d3b5bSober 	a.keymap = &zrc_keymapdata;
208953d3b5bSober 	a.accessops = &zrc_accessops;
209953d3b5bSober 	a.accesscookie = sc;
210953d3b5bSober 
211c7fb772bSthorpej 	sc->sc_wskbddev = config_found(self, &a, wskbddevprint, CFARGS_NONE);
212953d3b5bSober }
213953d3b5bSober 
214f19ed1a8Speter static int
zrc_finalize(device_t dv)215fd148500Stsutsui zrc_finalize(device_t dv)
216fd148500Stsutsui {
217fd148500Stsutsui 
218fd148500Stsutsui 	/* Enable the pullup while waiting for an interrupt. */
219fd148500Stsutsui 	if (ZAURUS_ISC1000)
220fd148500Stsutsui 		ioexp_akin_pullup(1);
221fd148500Stsutsui 	else
222fd148500Stsutsui 		scoop_akin_pullup(1);
223fd148500Stsutsui 
224fd148500Stsutsui 	return 0;
225fd148500Stsutsui }
226fd148500Stsutsui 
227fd148500Stsutsui static int
zrc_intr(void * v)228953d3b5bSober zrc_intr(void *v)
229953d3b5bSober {
230953d3b5bSober 	struct zrc_softc *sc = v;
231953d3b5bSober 
232953d3b5bSober 	/* just return if remote control isn't present */
233953d3b5bSober 
234953d3b5bSober 	pxa2x0_gpio_intr_mask(sc->sc_ih);
235003bdf4cSnonaka 	if (ZAURUS_ISC1000)
236003bdf4cSnonaka 		ioexp_akin_pullup(0);
237003bdf4cSnonaka 	else
238953d3b5bSober 		scoop_akin_pullup(0);
239953d3b5bSober 	sc->sc_key = zrc_scan();
240953d3b5bSober 	sc->sc_scans = 0;
241953d3b5bSober 	sc->sc_noise = 0;
242953d3b5bSober 	callout_schedule(&sc->sc_to, RESCAN_INTERVAL);
243f19ed1a8Speter 
244953d3b5bSober 	return 1;
245953d3b5bSober }
246953d3b5bSober 
247f19ed1a8Speter static void
zrc_timeout(void * v)248953d3b5bSober zrc_timeout(void *v)
249953d3b5bSober {
250953d3b5bSober 	struct zrc_softc *sc = v;
251953d3b5bSober 	int key;
252953d3b5bSober 
253953d3b5bSober 	key = zrc_scan();
254953d3b5bSober 	switch (sc->sc_scans) {
255953d3b5bSober 	case 0:
256953d3b5bSober 	case 1:
257953d3b5bSober 	case 2:
258953d3b5bSober 		/* wait for a stable read */
259953d3b5bSober 		if (sc->sc_key == key)
260953d3b5bSober 			sc->sc_scans++;
261953d3b5bSober 		else {
262953d3b5bSober 			sc->sc_key = key;
263953d3b5bSober 			sc->sc_scans = 0;
264953d3b5bSober 			sc->sc_noise++;
265953d3b5bSober 		}
266953d3b5bSober 		callout_schedule(&sc->sc_to, RESCAN_INTERVAL);
267953d3b5bSober 		break;
268953d3b5bSober 	case 3:
269953d3b5bSober 		/* generate key press event */
270953d3b5bSober 		if (sc->sc_key != key) {
271953d3b5bSober 			key = sc->sc_key;
272953d3b5bSober 			sc->sc_noise++;
273953d3b5bSober 		}
274953d3b5bSober 		sc->sc_scans++;
275953d3b5bSober 		switch (key) {
276953d3b5bSober 		case KEY_EARPHONE:
277953d3b5bSober 		case KEY_RELEASE:
278953d3b5bSober 			sc->sc_scans = 6;
279953d3b5bSober 			break;
280953d3b5bSober 		default:
281953d3b5bSober #ifdef DEBUG
2821a686006Snonaka 			printf("%s: %s pressed (%d noise)\n",
2831a686006Snonaka 			    device_xname(sc->sc_dev),
2841a686006Snonaka 			    zrc_keyname[key], sc->sc_noise);
285953d3b5bSober #endif
286953d3b5bSober 			sc->sc_keydown = key;
287953d3b5bSober 			sc->sc_noise = 0;
288953d3b5bSober 			zrc_input(sc, key, 1);
289953d3b5bSober 			break;
290953d3b5bSober 		}
291953d3b5bSober 		callout_schedule(&sc->sc_to, RESCAN_INTERVAL);
292953d3b5bSober 		break;
293953d3b5bSober 	case 4:
294953d3b5bSober 	case 5:
295953d3b5bSober 		/* wait for key release, permit noise */
296953d3b5bSober 		if (sc->sc_key == key) {
297953d3b5bSober 			if (sc->sc_scans == 5)
298953d3b5bSober 				sc->sc_noise++;
299953d3b5bSober 			sc->sc_scans = 4;
300953d3b5bSober 		} else
301953d3b5bSober 			sc->sc_scans++;
302953d3b5bSober 		callout_schedule(&sc->sc_to, RESCAN_INTERVAL);
303953d3b5bSober 		break;
304953d3b5bSober 	case 6:
305953d3b5bSober 		/* generate key release event */
306953d3b5bSober 		if (sc->sc_keydown != KEY_RELEASE) {
307953d3b5bSober 			zrc_input(sc, sc->sc_keydown, 0);
308953d3b5bSober #ifdef DEBUG
3091a686006Snonaka 			printf("%s: %s released (%d noise)\n",
3101a686006Snonaka 			    device_xname(sc->sc_dev),
311953d3b5bSober 			    zrc_keyname[sc->sc_keydown], sc->sc_noise);
312953d3b5bSober #endif
313953d3b5bSober 			sc->sc_keydown = KEY_RELEASE;
314953d3b5bSober 		}
315953d3b5bSober 		/* FALLTHROUGH */
316953d3b5bSober 	default:
317953d3b5bSober 		/* unmask interrupt again */
318953d3b5bSober 		callout_stop(&sc->sc_to);
319953d3b5bSober 		sc->sc_scans = 7;
320003bdf4cSnonaka 		if (ZAURUS_ISC1000)
321003bdf4cSnonaka 			ioexp_akin_pullup(1);
322003bdf4cSnonaka 		else
323953d3b5bSober 			scoop_akin_pullup(1);
324953d3b5bSober 		pxa2x0_gpio_intr_unmask(sc->sc_ih);
325953d3b5bSober 	}
326953d3b5bSober }
327953d3b5bSober 
328f19ed1a8Speter static int
zrc_scan(void)329953d3b5bSober zrc_scan(void)
330953d3b5bSober {
331953d3b5bSober 	int val;
332953d3b5bSober 	int i;
333953d3b5bSober 
334953d3b5bSober /* XXX MAX1111 command word - also appears in zaurus_apm.c */
335953d3b5bSober #define MAXCTRL_PD0		(1<<0)
336953d3b5bSober #define MAXCTRL_PD1		(1<<1)
337953d3b5bSober #define MAXCTRL_SGL		(1<<2)
338953d3b5bSober #define MAXCTRL_UNI		(1<<3)
339953d3b5bSober #define MAXCTRL_SEL_SHIFT	4
340953d3b5bSober #define MAXCTRL_STR		(1<<7)
341953d3b5bSober 
342953d3b5bSober #define C3000_ADCCH_ZRC 0
343953d3b5bSober 	val = zssp_read_max1111(MAXCTRL_PD0 | MAXCTRL_PD1 | MAXCTRL_SGL |
344953d3b5bSober 	    MAXCTRL_UNI | (C3000_ADCCH_ZRC << MAXCTRL_SEL_SHIFT) |
345953d3b5bSober 	    MAXCTRL_STR);
346953d3b5bSober 	for (i = 0; zrc_akeytab[i].min != INT_MIN; i++)
347953d3b5bSober 		if (val >= zrc_akeytab[i].min)
348953d3b5bSober 			break;
349953d3b5bSober 	return zrc_akeytab[i].key;
350953d3b5bSober }
351953d3b5bSober 
352f19ed1a8Speter static void
zrc_input(struct zrc_softc * sc,int key,int down)353953d3b5bSober zrc_input(struct zrc_softc *sc, int key, int down)
354953d3b5bSober {
355953d3b5bSober 	u_int type = down ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
356953d3b5bSober 	int s;
357953d3b5bSober 
358953d3b5bSober 	s = spltty();
359953d3b5bSober 
360953d3b5bSober #ifdef WSDISPLAY_COMPAT_RAWKBD
361953d3b5bSober 	if (sc->sc_rawkbd) {
362953d3b5bSober 		int	c;
363953d3b5bSober 		u_char	cbuf[2];
364953d3b5bSober 		int	ncbuf = 0;
365953d3b5bSober 
366953d3b5bSober 		c = zrc_xt_keymap[key];
367953d3b5bSober 		if (c & 0x80)
368953d3b5bSober 			cbuf[ncbuf++] = 0xe0;
369953d3b5bSober 		cbuf[ncbuf] = c & 0x7f;
370953d3b5bSober 
371953d3b5bSober 		if (!down)
372953d3b5bSober 			cbuf[ncbuf] |= 0x80;
373953d3b5bSober 		ncbuf++;
374953d3b5bSober 
375953d3b5bSober 		wskbd_rawinput(sc->sc_wskbddev, cbuf, ncbuf);
376953d3b5bSober 	} else
377953d3b5bSober #endif
378953d3b5bSober 		wskbd_input(sc->sc_wskbddev, type, key);
379953d3b5bSober 
380953d3b5bSober 	splx(s);
381953d3b5bSober }
382953d3b5bSober 
383f19ed1a8Speter static int
zrc_enable(void * v,int on)384953d3b5bSober zrc_enable(void *v, int on)
385953d3b5bSober {
386953d3b5bSober 
387953d3b5bSober 	return 0;
388953d3b5bSober }
389953d3b5bSober 
390f19ed1a8Speter static void
zrc_set_leds(void * v,int on)391953d3b5bSober zrc_set_leds(void *v, int on)
392953d3b5bSober {
393953d3b5bSober 
394953d3b5bSober 	/* Nothing to do */
395953d3b5bSober }
396953d3b5bSober 
397f19ed1a8Speter static int
zrc_ioctl(void * v,u_long cmd,void * data,int flag,struct lwp * l)39853524e44Schristos zrc_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l)
399953d3b5bSober {
400953d3b5bSober #ifdef WSDISPLAY_COMPAT_RAWKBD
401953d3b5bSober 	struct zrc_softc *sc = v;
402953d3b5bSober #endif
403953d3b5bSober 
404953d3b5bSober 	switch (cmd) {
405953d3b5bSober 	case WSKBDIO_GTYPE:
406953d3b5bSober 		*(int *)data = WSKBD_TYPE_ZAURUS;
407953d3b5bSober 		return 0;
408953d3b5bSober 	case WSKBDIO_SETLEDS:
409953d3b5bSober 		return 0;
410953d3b5bSober 	case WSKBDIO_GETLEDS:
411953d3b5bSober 		*(int *)data = 0;
412953d3b5bSober 		return 0;
413953d3b5bSober #ifdef WSDISPLAY_COMPAT_RAWKBD
414953d3b5bSober 	case WSKBDIO_SETMODE:
415953d3b5bSober 		sc->sc_rawkbd = (*(int *)data == WSKBD_RAW);
416953d3b5bSober 		return 0;
417953d3b5bSober #endif
418953d3b5bSober 	}
419f19ed1a8Speter 	return EPASSTHROUGH;
420953d3b5bSober }
421