| @@ -1,906 +1,906 @@ | | | @@ -1,906 +1,906 @@ |
1 | /* $NetBSD: adb_kbd.c,v 1.29 2019/06/09 14:18:29 christos Exp $ */ | | 1 | /* $NetBSD: adb_kbd.c,v 1.30 2020/08/31 17:54:18 macallan Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (C) 1998 Colin Wood | | 4 | * Copyright (C) 1998 Colin Wood |
5 | * Copyright (C) 2006, 2007 Michael Lorenz | | 5 | * Copyright (C) 2006, 2007 Michael Lorenz |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
15 | * documentation and/or other materials provided with the distribution. | | 15 | * documentation and/or other materials provided with the distribution. |
16 | * 3. All advertising materials mentioning features or use of this software | | 16 | * 3. All advertising materials mentioning features or use of this software |
17 | * must display the following acknowledgement: | | 17 | * must display the following acknowledgement: |
18 | * This product includes software developed by Colin Wood. | | 18 | * This product includes software developed by Colin Wood. |
19 | * 4. The name of the author may not be used to endorse or promote products | | 19 | * 4. The name of the author may not be used to endorse or promote products |
20 | * derived from this software without specific prior written permission. | | 20 | * derived from this software without specific prior written permission. |
21 | * | | 21 | * |
22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | | 23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
24 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 24 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
25 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 25 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
27 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 27 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | | 28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | | 30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | | 31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
32 | */ | | 32 | */ |
33 | | | 33 | |
34 | #include <sys/cdefs.h> | | 34 | #include <sys/cdefs.h> |
35 | __KERNEL_RCSID(0, "$NetBSD: adb_kbd.c,v 1.29 2019/06/09 14:18:29 christos Exp $"); | | 35 | __KERNEL_RCSID(0, "$NetBSD: adb_kbd.c,v 1.30 2020/08/31 17:54:18 macallan Exp $"); |
36 | | | 36 | |
37 | #ifdef _KERNEL_OPT | | 37 | #ifdef _KERNEL_OPT |
38 | #include "opt_ddb.h" | | 38 | #include "opt_ddb.h" |
39 | #endif | | 39 | #endif |
40 | | | 40 | |
41 | #include <sys/param.h> | | 41 | #include <sys/param.h> |
42 | #include <sys/device.h> | | 42 | #include <sys/device.h> |
43 | #include <sys/fcntl.h> | | 43 | #include <sys/fcntl.h> |
44 | #include <sys/poll.h> | | 44 | #include <sys/poll.h> |
45 | #include <sys/select.h> | | 45 | #include <sys/select.h> |
46 | #include <sys/proc.h> | | 46 | #include <sys/proc.h> |
47 | #include <sys/systm.h> | | 47 | #include <sys/systm.h> |
48 | #include <sys/kernel.h> | | 48 | #include <sys/kernel.h> |
49 | #include <sys/sysctl.h> | | 49 | #include <sys/sysctl.h> |
50 | | | 50 | |
51 | #include <dev/wscons/wsconsio.h> | | 51 | #include <dev/wscons/wsconsio.h> |
52 | #include <dev/wscons/wskbdvar.h> | | 52 | #include <dev/wscons/wskbdvar.h> |
53 | #include <dev/wscons/wsksymdef.h> | | 53 | #include <dev/wscons/wsksymdef.h> |
54 | #include <dev/wscons/wsksymvar.h> | | 54 | #include <dev/wscons/wsksymvar.h> |
55 | #include <dev/wscons/wsmousevar.h> | | 55 | #include <dev/wscons/wsmousevar.h> |
56 | | | 56 | |
57 | #include <dev/sysmon/sysmonvar.h> | | 57 | #include <dev/sysmon/sysmonvar.h> |
58 | #include <dev/sysmon/sysmon_taskq.h> | | 58 | #include <dev/sysmon/sysmon_taskq.h> |
59 | | | 59 | |
60 | #include <machine/autoconf.h> | | 60 | #include <machine/autoconf.h> |
61 | #include <machine/keyboard.h> | | 61 | #include <machine/keyboard.h> |
62 | #include <machine/adbsys.h> | | 62 | #include <machine/adbsys.h> |
63 | | | 63 | |
64 | #include <dev/adb/adbvar.h> | | 64 | #include <dev/adb/adbvar.h> |
65 | #include <dev/adb/adb_keymap.h> | | 65 | #include <dev/adb/adb_keymap.h> |
66 | | | 66 | |
67 | #include "ioconf.h" | | 67 | #include "ioconf.h" |
68 | | | 68 | |
69 | #include "opt_wsdisplay_compat.h" | | 69 | #include "opt_wsdisplay_compat.h" |
70 | #include "opt_adbkbd.h" | | 70 | #include "opt_adbkbd.h" |
71 | #include "adbdebug.h" | | 71 | #include "adbdebug.h" |
72 | #include "wsmouse.h" | | 72 | #include "wsmouse.h" |
73 | | | 73 | |
74 | struct adbkbd_softc { | | 74 | struct adbkbd_softc { |
75 | device_t sc_dev; | | 75 | device_t sc_dev; |
76 | struct adb_device *sc_adbdev; | | 76 | struct adb_device *sc_adbdev; |
77 | struct adb_bus_accessops *sc_ops; | | 77 | struct adb_bus_accessops *sc_ops; |
78 | device_t sc_wskbddev; | | 78 | device_t sc_wskbddev; |
79 | #if NWSMOUSE > 0 | | 79 | #if NWSMOUSE > 0 |
80 | device_t sc_wsmousedev; | | 80 | device_t sc_wsmousedev; |
81 | #endif | | 81 | #endif |
82 | struct sysmon_pswitch sc_sm_pbutton; | | 82 | struct sysmon_pswitch sc_sm_pbutton; |
83 | int sc_leds; | | 83 | int sc_leds; |
84 | int sc_have_led_control; | | 84 | int sc_have_led_control; |
85 | int sc_power_button_delay; | | 85 | int sc_power_button_delay; |
86 | int sc_msg_len; | | 86 | int sc_msg_len; |
87 | int sc_event; | | 87 | int sc_event; |
88 | int sc_poll; | | 88 | int sc_poll; |
89 | int sc_polled_chars; | | 89 | int sc_polled_chars; |
90 | int sc_trans[3]; | | 90 | int sc_trans[3]; |
91 | int sc_capslock; | | 91 | int sc_capslock; |
92 | uint32_t sc_timestamp; | | 92 | uint32_t sc_timestamp; |
93 | #ifdef WSDISPLAY_COMPAT_RAWKBD | | 93 | #ifdef WSDISPLAY_COMPAT_RAWKBD |
94 | int sc_rawkbd; | | 94 | int sc_rawkbd; |
95 | #endif | | 95 | #endif |
96 | bool sc_emul_usb; | | 96 | bool sc_emul_usb; |
97 | bool sc_power_dbg; | | 97 | bool sc_power_dbg; |
98 | | | 98 | |
99 | uint32_t sc_power; | | 99 | uint32_t sc_power; |
100 | uint8_t sc_buffer[16]; | | 100 | uint8_t sc_buffer[16]; |
101 | uint8_t sc_pollbuf[16]; | | 101 | uint8_t sc_pollbuf[16]; |
102 | uint8_t sc_us, sc_pe; | | 102 | uint8_t sc_us, sc_pe; |
103 | }; | | 103 | }; |
104 | | | 104 | |
105 | /* | | 105 | /* |
106 | * Function declarations. | | 106 | * Function declarations. |
107 | */ | | 107 | */ |
108 | static int adbkbd_match(device_t, cfdata_t, void *); | | 108 | static int adbkbd_match(device_t, cfdata_t, void *); |
109 | static void adbkbd_attach(device_t, device_t, void *); | | 109 | static void adbkbd_attach(device_t, device_t, void *); |
110 | | | 110 | |
111 | static void adbkbd_initleds(struct adbkbd_softc *); | | 111 | static void adbkbd_initleds(struct adbkbd_softc *); |
112 | static void adbkbd_keys(struct adbkbd_softc *, uint8_t, uint8_t); | | 112 | static void adbkbd_keys(struct adbkbd_softc *, uint8_t, uint8_t); |
113 | static inline void adbkbd_key(struct adbkbd_softc *, uint8_t); | | 113 | static inline void adbkbd_key(struct adbkbd_softc *, uint8_t); |
114 | static int adbkbd_wait(struct adbkbd_softc *, int); | | 114 | static int adbkbd_wait(struct adbkbd_softc *, int); |
115 | | | 115 | |
116 | /* Driver definition. */ | | 116 | /* Driver definition. */ |
117 | CFATTACH_DECL_NEW(adbkbd, sizeof(struct adbkbd_softc), | | 117 | CFATTACH_DECL_NEW(adbkbd, sizeof(struct adbkbd_softc), |
118 | adbkbd_match, adbkbd_attach, NULL, NULL); | | 118 | adbkbd_match, adbkbd_attach, NULL, NULL); |
119 | | | 119 | |
120 | static int adbkbd_enable(void *, int); | | 120 | static int adbkbd_enable(void *, int); |
121 | static int adbkbd_ioctl(void *, u_long, void *, int, struct lwp *); | | 121 | static int adbkbd_ioctl(void *, u_long, void *, int, struct lwp *); |
122 | static void adbkbd_set_leds(void *, int); | | 122 | static void adbkbd_set_leds(void *, int); |
123 | static void adbkbd_handler(void *, int, uint8_t *); | | 123 | static void adbkbd_handler(void *, int, uint8_t *); |
124 | static void adbkbd_powerbutton(void *); | | 124 | static void adbkbd_powerbutton(void *); |
125 | | | 125 | |
126 | struct wskbd_accessops adbkbd_accessops = { | | 126 | struct wskbd_accessops adbkbd_accessops = { |
127 | adbkbd_enable, | | 127 | adbkbd_enable, |
128 | adbkbd_set_leds, | | 128 | adbkbd_set_leds, |
129 | adbkbd_ioctl, | | 129 | adbkbd_ioctl, |
130 | }; | | 130 | }; |
131 | | | 131 | |
132 | static void adbkbd_cngetc(void *, u_int *, int *); | | 132 | static void adbkbd_cngetc(void *, u_int *, int *); |
133 | static void adbkbd_cnpollc(void *, int); | | 133 | static void adbkbd_cnpollc(void *, int); |
134 | | | 134 | |
135 | struct wskbd_consops adbkbd_consops = { | | 135 | struct wskbd_consops adbkbd_consops = { |
136 | adbkbd_cngetc, | | 136 | adbkbd_cngetc, |
137 | adbkbd_cnpollc, | | 137 | adbkbd_cnpollc, |
138 | }; | | 138 | }; |
139 | | | 139 | |
140 | struct wskbd_mapdata adbkbd_keymapdata = { | | 140 | struct wskbd_mapdata adbkbd_keymapdata = { |
141 | akbd_keydesctab, | | 141 | akbd_keydesctab, |
142 | #ifdef AKBD_LAYOUT | | 142 | #ifdef ADBKBD_LAYOUT |
143 | AKBD_LAYOUT, | | 143 | ADBKBD_LAYOUT, |
144 | #else | | 144 | #else |
145 | KB_US, | | 145 | KB_US | KB_APPLE, |
146 | #endif | | 146 | #endif |
147 | }; | | 147 | }; |
148 | | | 148 | |
149 | #if NWSMOUSE > 0 | | 149 | #if NWSMOUSE > 0 |
150 | static int adbkms_enable(void *); | | 150 | static int adbkms_enable(void *); |
151 | static int adbkms_ioctl(void *, u_long, void *, int, struct lwp *); | | 151 | static int adbkms_ioctl(void *, u_long, void *, int, struct lwp *); |
152 | static void adbkms_disable(void *); | | 152 | static void adbkms_disable(void *); |
153 | | | 153 | |
154 | const struct wsmouse_accessops adbkms_accessops = { | | 154 | const struct wsmouse_accessops adbkms_accessops = { |
155 | adbkms_enable, | | 155 | adbkms_enable, |
156 | adbkms_ioctl, | | 156 | adbkms_ioctl, |
157 | adbkms_disable, | | 157 | adbkms_disable, |
158 | }; | | 158 | }; |
159 | | | 159 | |
160 | static int adbkbd_sysctl_mid(SYSCTLFN_ARGS); | | 160 | static int adbkbd_sysctl_mid(SYSCTLFN_ARGS); |
161 | static int adbkbd_sysctl_right(SYSCTLFN_ARGS); | | 161 | static int adbkbd_sysctl_right(SYSCTLFN_ARGS); |
162 | static int adbkbd_sysctl_usb(SYSCTLFN_ARGS); | | 162 | static int adbkbd_sysctl_usb(SYSCTLFN_ARGS); |
163 | | | 163 | |
164 | #endif /* NWSMOUSE > 0 */ | | 164 | #endif /* NWSMOUSE > 0 */ |
165 | | | 165 | |
166 | static void adbkbd_setup_sysctl(struct adbkbd_softc *); | | 166 | static void adbkbd_setup_sysctl(struct adbkbd_softc *); |
167 | | | 167 | |
168 | #ifdef ADBKBD_DEBUG | | 168 | #ifdef ADBKBD_DEBUG |
169 | #define DPRINTF printf | | 169 | #define DPRINTF printf |
170 | #else | | 170 | #else |
171 | #define DPRINTF while (0) printf | | 171 | #define DPRINTF while (0) printf |
172 | #endif | | 172 | #endif |
173 | | | 173 | |
174 | static int adbkbd_is_console = 0; | | 174 | static int adbkbd_is_console = 0; |
175 | static int adbkbd_console_attached = 0; | | 175 | static int adbkbd_console_attached = 0; |
176 | | | 176 | |
177 | static int | | 177 | static int |
178 | adbkbd_match(device_t parent, cfdata_t cf, void *aux) | | 178 | adbkbd_match(device_t parent, cfdata_t cf, void *aux) |
179 | { | | 179 | { |
180 | struct adb_attach_args *aaa = aux; | | 180 | struct adb_attach_args *aaa = aux; |
181 | | | 181 | |
182 | if (aaa->dev->original_addr == ADBADDR_KBD) | | 182 | if (aaa->dev->original_addr == ADBADDR_KBD) |
183 | return 1; | | 183 | return 1; |
184 | else | | 184 | else |
185 | return 0; | | 185 | return 0; |
186 | } | | 186 | } |
187 | | | 187 | |
188 | static void | | 188 | static void |
189 | adbkbd_attach(device_t parent, device_t self, void *aux) | | 189 | adbkbd_attach(device_t parent, device_t self, void *aux) |
190 | { | | 190 | { |
191 | struct adbkbd_softc *sc = device_private(self); | | 191 | struct adbkbd_softc *sc = device_private(self); |
192 | struct adb_attach_args *aaa = aux; | | 192 | struct adb_attach_args *aaa = aux; |
193 | short cmd; | | 193 | short cmd; |
194 | struct wskbddev_attach_args a; | | 194 | struct wskbddev_attach_args a; |
195 | #if NWSMOUSE > 0 | | 195 | #if NWSMOUSE > 0 |
196 | struct wsmousedev_attach_args am; | | 196 | struct wsmousedev_attach_args am; |
197 | #endif | | 197 | #endif |
198 | uint8_t buffer[2]; | | 198 | uint8_t buffer[2]; |
199 | | | 199 | |
200 | sc->sc_dev = self; | | 200 | sc->sc_dev = self; |
201 | sc->sc_ops = aaa->ops; | | 201 | sc->sc_ops = aaa->ops; |
202 | sc->sc_adbdev = aaa->dev; | | 202 | sc->sc_adbdev = aaa->dev; |
203 | sc->sc_adbdev->cookie = sc; | | 203 | sc->sc_adbdev->cookie = sc; |
204 | sc->sc_adbdev->handler = adbkbd_handler; | | 204 | sc->sc_adbdev->handler = adbkbd_handler; |
205 | sc->sc_us = ADBTALK(sc->sc_adbdev->current_addr, 0); | | 205 | sc->sc_us = ADBTALK(sc->sc_adbdev->current_addr, 0); |
206 | | | 206 | |
207 | sc->sc_leds = 0; /* initially off */ | | 207 | sc->sc_leds = 0; /* initially off */ |
208 | sc->sc_have_led_control = 0; | | 208 | sc->sc_have_led_control = 0; |
209 | | | 209 | |
210 | /* | | 210 | /* |
211 | * If this is != 0 then pushing the power button will not immadiately | | 211 | * If this is != 0 then pushing the power button will not immadiately |
212 | * send a shutdown event to sysmon but instead require another key | | 212 | * send a shutdown event to sysmon but instead require another key |
213 | * press within 5 seconds with a gap of at least two seconds. The | | 213 | * press within 5 seconds with a gap of at least two seconds. The |
214 | * reason to do this is the fact that some PowerBook keyboards, | | 214 | * reason to do this is the fact that some PowerBook keyboards, |
215 | * like the 2400, 3400 and original G3 have their power buttons | | 215 | * like the 2400, 3400 and original G3 have their power buttons |
216 | * right next to the backspace key and it's extremely easy to hit | | 216 | * right next to the backspace key and it's extremely easy to hit |
217 | * it by accident. | | 217 | * it by accident. |
218 | * On most other keyboards the power button is sufficiently far out | | 218 | * On most other keyboards the power button is sufficiently far out |
219 | * of the way so we don't need this. | | 219 | * of the way so we don't need this. |
220 | */ | | 220 | */ |
221 | sc->sc_power_button_delay = 0; | | 221 | sc->sc_power_button_delay = 0; |
222 | sc->sc_msg_len = 0; | | 222 | sc->sc_msg_len = 0; |
223 | sc->sc_poll = 0; | | 223 | sc->sc_poll = 0; |
224 | sc->sc_capslock = 0; | | 224 | sc->sc_capslock = 0; |
225 | sc->sc_trans[1] = 103; /* F11 */ | | 225 | sc->sc_trans[1] = 103; /* F11 */ |
226 | sc->sc_trans[2] = 111; /* F12 */ | | 226 | sc->sc_trans[2] = 111; /* F12 */ |
227 | | | 227 | |
228 | /* | | 228 | /* |
229 | * Most ADB keyboards send 0x7f 0x7f when the power button is pressed. | | 229 | * Most ADB keyboards send 0x7f 0x7f when the power button is pressed. |
230 | * Some older PowerBooks, like the 3400c, will send a single scancode | | 230 | * Some older PowerBooks, like the 3400c, will send a single scancode |
231 | * 0x7e instead. Unfortunately Fn-Command on some more recent *Books | | 231 | * 0x7e instead. Unfortunately Fn-Command on some more recent *Books |
232 | * sends the same scancode, so by default sc_power is set to a value | | 232 | * sends the same scancode, so by default sc_power is set to a value |
233 | * that can't occur as a scancode and only set to 0x7e on hardware that | | 233 | * that can't occur as a scancode and only set to 0x7e on hardware that |
234 | * needs it | | 234 | * needs it |
235 | */ | | 235 | */ |
236 | sc->sc_power = 0xffff; | | 236 | sc->sc_power = 0xffff; |
237 | sc->sc_timestamp = 0; | | 237 | sc->sc_timestamp = 0; |
238 | sc->sc_emul_usb = FALSE; | | 238 | sc->sc_emul_usb = FALSE; |
239 | #ifdef ADBKBD_POWER_DDB | | 239 | #ifdef ADBKBD_POWER_DDB |
240 | sc->sc_power_dbg = TRUE; | | 240 | sc->sc_power_dbg = TRUE; |
241 | #else | | 241 | #else |
242 | sc->sc_power_dbg = FALSE; | | 242 | sc->sc_power_dbg = FALSE; |
243 | #endif | | 243 | #endif |
244 | | | 244 | |
245 | aprint_normal(" addr %d: ", sc->sc_adbdev->current_addr); | | 245 | aprint_normal(" addr %d: ", sc->sc_adbdev->current_addr); |
246 | | | 246 | |
247 | switch (sc->sc_adbdev->handler_id) { | | 247 | switch (sc->sc_adbdev->handler_id) { |
248 | case ADB_STDKBD: | | 248 | case ADB_STDKBD: |
249 | aprint_normal("standard keyboard\n"); | | 249 | aprint_normal("standard keyboard\n"); |
250 | break; | | 250 | break; |
251 | case ADB_ISOKBD: | | 251 | case ADB_ISOKBD: |
252 | aprint_normal("standard keyboard (ISO layout)\n"); | | 252 | aprint_normal("standard keyboard (ISO layout)\n"); |
253 | break; | | 253 | break; |
254 | case ADB_EXTKBD: | | 254 | case ADB_EXTKBD: |
255 | cmd = ADBTALK(sc->sc_adbdev->current_addr, 1); | | 255 | cmd = ADBTALK(sc->sc_adbdev->current_addr, 1); |
256 | sc->sc_msg_len = 0; | | 256 | sc->sc_msg_len = 0; |
257 | sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 0, NULL); | | 257 | sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 0, NULL); |
258 | adbkbd_wait(sc, 10); | | 258 | adbkbd_wait(sc, 10); |
259 | | | 259 | |
260 | /* Ignore Logitech MouseMan/Trackman pseudo keyboard */ | | 260 | /* Ignore Logitech MouseMan/Trackman pseudo keyboard */ |
261 | /* XXX needs testing */ | | 261 | /* XXX needs testing */ |
262 | if (sc->sc_buffer[2] == 0x9a && sc->sc_buffer[3] == 0x20) { | | 262 | if (sc->sc_buffer[2] == 0x9a && sc->sc_buffer[3] == 0x20) { |
263 | aprint_normal("Mouseman (non-EMP) pseudo keyboard\n"); | | 263 | aprint_normal("Mouseman (non-EMP) pseudo keyboard\n"); |
264 | return; | | 264 | return; |
265 | } else if (sc->sc_buffer[2] == 0x9a && | | 265 | } else if (sc->sc_buffer[2] == 0x9a && |
266 | sc->sc_buffer[3] == 0x21) { | | 266 | sc->sc_buffer[3] == 0x21) { |
267 | aprint_normal("Trackman (non-EMP) pseudo keyboard\n"); | | 267 | aprint_normal("Trackman (non-EMP) pseudo keyboard\n"); |
268 | return; | | 268 | return; |
269 | } else { | | 269 | } else { |
270 | aprint_normal("extended keyboard\n"); | | 270 | aprint_normal("extended keyboard\n"); |
271 | adbkbd_initleds(sc); | | 271 | adbkbd_initleds(sc); |
272 | } | | 272 | } |
273 | break; | | 273 | break; |
274 | case ADB_EXTISOKBD: | | 274 | case ADB_EXTISOKBD: |
275 | aprint_normal("extended keyboard (ISO layout)\n"); | | 275 | aprint_normal("extended keyboard (ISO layout)\n"); |
276 | adbkbd_initleds(sc); | | 276 | adbkbd_initleds(sc); |
277 | break; | | 277 | break; |
278 | case ADB_KBDII: | | 278 | case ADB_KBDII: |
279 | aprint_normal("keyboard II\n"); | | 279 | aprint_normal("keyboard II\n"); |
280 | break; | | 280 | break; |
281 | case ADB_ISOKBDII: | | 281 | case ADB_ISOKBDII: |
282 | aprint_normal("keyboard II (ISO layout)\n"); | | 282 | aprint_normal("keyboard II (ISO layout)\n"); |
283 | break; | | 283 | break; |
284 | case ADB_PBKBD: | | 284 | case ADB_PBKBD: |
285 | aprint_normal("PowerBook keyboard\n"); | | 285 | aprint_normal("PowerBook keyboard\n"); |
286 | sc->sc_power = 0x7e; | | 286 | sc->sc_power = 0x7e; |
287 | sc->sc_power_button_delay = 1; | | 287 | sc->sc_power_button_delay = 1; |
288 | break; | | 288 | break; |
289 | case ADB_PBISOKBD: | | 289 | case ADB_PBISOKBD: |
290 | aprint_normal("PowerBook keyboard (ISO layout)\n"); | | 290 | aprint_normal("PowerBook keyboard (ISO layout)\n"); |
291 | sc->sc_power = 0x7e; | | 291 | sc->sc_power = 0x7e; |
292 | sc->sc_power_button_delay = 1; | | 292 | sc->sc_power_button_delay = 1; |
293 | break; | | 293 | break; |
294 | case ADB_ADJKPD: | | 294 | case ADB_ADJKPD: |
295 | aprint_normal("adjustable keypad\n"); | | 295 | aprint_normal("adjustable keypad\n"); |
296 | break; | | 296 | break; |
297 | case ADB_ADJKBD: | | 297 | case ADB_ADJKBD: |
298 | aprint_normal("adjustable keyboard\n"); | | 298 | aprint_normal("adjustable keyboard\n"); |
299 | break; | | 299 | break; |
300 | case ADB_ADJISOKBD: | | 300 | case ADB_ADJISOKBD: |
301 | aprint_normal("adjustable keyboard (ISO layout)\n"); | | 301 | aprint_normal("adjustable keyboard (ISO layout)\n"); |
302 | break; | | 302 | break; |
303 | case ADB_ADJJAPKBD: | | 303 | case ADB_ADJJAPKBD: |
304 | aprint_normal("adjustable keyboard (Japanese layout)\n"); | | 304 | aprint_normal("adjustable keyboard (Japanese layout)\n"); |
305 | break; | | 305 | break; |
306 | case ADB_PBEXTISOKBD: | | 306 | case ADB_PBEXTISOKBD: |
307 | aprint_normal("PowerBook extended keyboard (ISO layout)\n"); | | 307 | aprint_normal("PowerBook extended keyboard (ISO layout)\n"); |
308 | sc->sc_power_button_delay = 1; | | 308 | sc->sc_power_button_delay = 1; |
309 | sc->sc_power = 0x7e; | | 309 | sc->sc_power = 0x7e; |
310 | break; | | 310 | break; |
311 | case ADB_PBEXTJAPKBD: | | 311 | case ADB_PBEXTJAPKBD: |
312 | aprint_normal("PowerBook extended keyboard (Japanese layout)\n"); | | 312 | aprint_normal("PowerBook extended keyboard (Japanese layout)\n"); |
313 | sc->sc_power_button_delay = 1; | | 313 | sc->sc_power_button_delay = 1; |
314 | sc->sc_power = 0x7e; | | 314 | sc->sc_power = 0x7e; |
315 | break; | | 315 | break; |
316 | case ADB_JPKBDII: | | 316 | case ADB_JPKBDII: |
317 | aprint_normal("keyboard II (Japanese layout)\n"); | | 317 | aprint_normal("keyboard II (Japanese layout)\n"); |
318 | break; | | 318 | break; |
319 | case ADB_PBEXTKBD: | | 319 | case ADB_PBEXTKBD: |
320 | aprint_normal("PowerBook extended keyboard\n"); | | 320 | aprint_normal("PowerBook extended keyboard\n"); |
321 | sc->sc_power_button_delay = 1; | | 321 | sc->sc_power_button_delay = 1; |
322 | sc->sc_power = 0x7e; | | 322 | sc->sc_power = 0x7e; |
323 | break; | | 323 | break; |
324 | case ADB_DESIGNKBD: | | 324 | case ADB_DESIGNKBD: |
325 | aprint_normal("extended keyboard\n"); | | 325 | aprint_normal("extended keyboard\n"); |
326 | adbkbd_initleds(sc); | | 326 | adbkbd_initleds(sc); |
327 | break; | | 327 | break; |
328 | case ADB_PBJPKBD: | | 328 | case ADB_PBJPKBD: |
329 | aprint_normal("PowerBook keyboard (Japanese layout)\n"); | | 329 | aprint_normal("PowerBook keyboard (Japanese layout)\n"); |
330 | sc->sc_power_button_delay = 1; | | 330 | sc->sc_power_button_delay = 1; |
331 | sc->sc_power = 0x7e; | | 331 | sc->sc_power = 0x7e; |
332 | break; | | 332 | break; |
333 | case ADB_PBG3KBD: | | 333 | case ADB_PBG3KBD: |
334 | aprint_normal("PowerBook G3 keyboard\n"); | | 334 | aprint_normal("PowerBook G3 keyboard\n"); |
335 | break; | | 335 | break; |
336 | case ADB_PBG3JPKBD: | | 336 | case ADB_PBG3JPKBD: |
337 | aprint_normal("PowerBook G3 keyboard (Japanese layout)\n"); | | 337 | aprint_normal("PowerBook G3 keyboard (Japanese layout)\n"); |
338 | break; | | 338 | break; |
339 | case ADB_IBOOKKBD: | | 339 | case ADB_IBOOKKBD: |
340 | aprint_normal("iBook keyboard\n"); | | 340 | aprint_normal("iBook keyboard\n"); |
341 | break; | | 341 | break; |
342 | default: | | 342 | default: |
343 | aprint_normal("mapped device (%d)\n", sc->sc_adbdev->handler_id); | | 343 | aprint_normal("mapped device (%d)\n", sc->sc_adbdev->handler_id); |
344 | break; | | 344 | break; |
345 | } | | 345 | } |
346 | | | 346 | |
347 | /* | | 347 | /* |
348 | * try to switch to extended protocol | | 348 | * try to switch to extended protocol |
349 | * as in, tell the keyboard to distinguish between left and right | | 349 | * as in, tell the keyboard to distinguish between left and right |
350 | * Shift, Control and Alt keys | | 350 | * Shift, Control and Alt keys |
351 | */ | | 351 | */ |
352 | cmd = ADBLISTEN(sc->sc_adbdev->current_addr, 3); | | 352 | cmd = ADBLISTEN(sc->sc_adbdev->current_addr, 3); |
353 | buffer[0] = sc->sc_adbdev->current_addr; | | 353 | buffer[0] = sc->sc_adbdev->current_addr; |
354 | buffer[1] = 3; | | 354 | buffer[1] = 3; |
355 | sc->sc_msg_len = 0; | | 355 | sc->sc_msg_len = 0; |
356 | sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 2, buffer); | | 356 | sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 2, buffer); |
357 | adbkbd_wait(sc, 10); | | 357 | adbkbd_wait(sc, 10); |
358 | | | 358 | |
359 | cmd = ADBTALK(sc->sc_adbdev->current_addr, 3); | | 359 | cmd = ADBTALK(sc->sc_adbdev->current_addr, 3); |
360 | sc->sc_msg_len = 0; | | 360 | sc->sc_msg_len = 0; |
361 | sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 0, NULL); | | 361 | sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 0, NULL); |
362 | adbkbd_wait(sc, 10); | | 362 | adbkbd_wait(sc, 10); |
363 | if ((sc->sc_msg_len == 4) && (sc->sc_buffer[3] == 3)) { | | 363 | if ((sc->sc_msg_len == 4) && (sc->sc_buffer[3] == 3)) { |
364 | aprint_verbose_dev(sc->sc_dev, "extended protocol enabled\n"); | | 364 | aprint_verbose_dev(sc->sc_dev, "extended protocol enabled\n"); |
365 | } | | 365 | } |
366 | | | 366 | |
367 | #ifdef ADBKBD_DEBUG | | 367 | #ifdef ADBKBD_DEBUG |
368 | cmd = ADBTALK(sc->sc_adbdev->current_addr, 1); | | 368 | cmd = ADBTALK(sc->sc_adbdev->current_addr, 1); |
369 | sc->sc_msg_len = 0; | | 369 | sc->sc_msg_len = 0; |
370 | sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 0, NULL); | | 370 | sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 0, NULL); |
371 | adbkbd_wait(sc, 10); | | 371 | adbkbd_wait(sc, 10); |
372 | printf("buffer: %02x %02x\n", sc->sc_buffer[0], sc->sc_buffer[1]); | | 372 | printf("buffer: %02x %02x\n", sc->sc_buffer[0], sc->sc_buffer[1]); |
373 | #endif | | 373 | #endif |
374 | | | 374 | |
375 | if (adbkbd_is_console && (adbkbd_console_attached == 0)) { | | 375 | if (adbkbd_is_console && (adbkbd_console_attached == 0)) { |
376 | wskbd_cnattach(&adbkbd_consops, sc, &adbkbd_keymapdata); | | 376 | wskbd_cnattach(&adbkbd_consops, sc, &adbkbd_keymapdata); |
377 | adbkbd_console_attached = 1; | | 377 | adbkbd_console_attached = 1; |
378 | a.console = 1; | | 378 | a.console = 1; |
379 | } else { | | 379 | } else { |
380 | a.console = 0; | | 380 | a.console = 0; |
381 | } | | 381 | } |
382 | a.keymap = &adbkbd_keymapdata; | | 382 | a.keymap = &adbkbd_keymapdata; |
383 | a.accessops = &adbkbd_accessops; | | 383 | a.accessops = &adbkbd_accessops; |
384 | a.accesscookie = sc; | | 384 | a.accesscookie = sc; |
385 | | | 385 | |
386 | sc->sc_wskbddev = config_found_ia(self, "wskbddev", &a, wskbddevprint); | | 386 | sc->sc_wskbddev = config_found_ia(self, "wskbddev", &a, wskbddevprint); |
387 | #ifdef ADBKBD_EMUL_USB | | 387 | #ifdef ADBKBD_EMUL_USB |
388 | sc->sc_emul_usb = TRUE; | | 388 | sc->sc_emul_usb = TRUE; |
389 | wskbd_set_evtrans(sc->sc_wskbddev, adb_to_usb, 128); | | 389 | wskbd_set_evtrans(sc->sc_wskbddev, adb_to_usb, 128); |
390 | #endif /* ADBKBD_EMUL_USB */ | | 390 | #endif /* ADBKBD_EMUL_USB */ |
391 | | | 391 | |
392 | #if NWSMOUSE > 0 | | 392 | #if NWSMOUSE > 0 |
393 | /* attach the mouse device */ | | 393 | /* attach the mouse device */ |
394 | am.accessops = &adbkms_accessops; | | 394 | am.accessops = &adbkms_accessops; |
395 | am.accesscookie = sc; | | 395 | am.accesscookie = sc; |
396 | sc->sc_wsmousedev = config_found_ia(self, "wsmousedev", &am, | | 396 | sc->sc_wsmousedev = config_found_ia(self, "wsmousedev", &am, |
397 | wsmousedevprint); | | 397 | wsmousedevprint); |
398 | | | 398 | |
399 | #endif | | 399 | #endif |
400 | adbkbd_setup_sysctl(sc); | | 400 | adbkbd_setup_sysctl(sc); |
401 | | | 401 | |
402 | /* finally register the power button */ | | 402 | /* finally register the power button */ |
403 | sysmon_task_queue_init(); | | 403 | sysmon_task_queue_init(); |
404 | memset(&sc->sc_sm_pbutton, 0, sizeof(struct sysmon_pswitch)); | | 404 | memset(&sc->sc_sm_pbutton, 0, sizeof(struct sysmon_pswitch)); |
405 | sc->sc_sm_pbutton.smpsw_name = device_xname(sc->sc_dev); | | 405 | sc->sc_sm_pbutton.smpsw_name = device_xname(sc->sc_dev); |
406 | sc->sc_sm_pbutton.smpsw_type = PSWITCH_TYPE_POWER; | | 406 | sc->sc_sm_pbutton.smpsw_type = PSWITCH_TYPE_POWER; |
407 | if (sysmon_pswitch_register(&sc->sc_sm_pbutton) != 0) | | 407 | if (sysmon_pswitch_register(&sc->sc_sm_pbutton) != 0) |
408 | aprint_error_dev(sc->sc_dev, | | 408 | aprint_error_dev(sc->sc_dev, |
409 | "unable to register power button with sysmon\n"); | | 409 | "unable to register power button with sysmon\n"); |
410 | } | | 410 | } |
411 | | | 411 | |
412 | static void | | 412 | static void |
413 | adbkbd_handler(void *cookie, int len, uint8_t *data) | | 413 | adbkbd_handler(void *cookie, int len, uint8_t *data) |
414 | { | | 414 | { |
415 | struct adbkbd_softc *sc = cookie; | | 415 | struct adbkbd_softc *sc = cookie; |
416 | | | 416 | |
417 | #ifdef ADBKBD_DEBUG | | 417 | #ifdef ADBKBD_DEBUG |
418 | int i; | | 418 | int i; |
419 | printf("%s: %02x - ", device_xname(sc->sc_dev), sc->sc_us); | | 419 | printf("%s: %02x - ", device_xname(sc->sc_dev), sc->sc_us); |
420 | for (i = 0; i < len; i++) { | | 420 | for (i = 0; i < len; i++) { |
421 | printf(" %02x", data[i]); | | 421 | printf(" %02x", data[i]); |
422 | } | | 422 | } |
423 | printf("\n"); | | 423 | printf("\n"); |
424 | #endif | | 424 | #endif |
425 | if (len >= 2) { | | 425 | if (len >= 2) { |
426 | if (data[1] == sc->sc_us) { | | 426 | if (data[1] == sc->sc_us) { |
427 | adbkbd_keys(sc, data[2], data[3]); | | 427 | adbkbd_keys(sc, data[2], data[3]); |
428 | return; | | 428 | return; |
429 | } else { | | 429 | } else { |
430 | memcpy(sc->sc_buffer, data, len); | | 430 | memcpy(sc->sc_buffer, data, len); |
431 | } | | 431 | } |
432 | sc->sc_msg_len = len; | | 432 | sc->sc_msg_len = len; |
433 | wakeup(&sc->sc_event); | | 433 | wakeup(&sc->sc_event); |
434 | } else { | | 434 | } else { |
435 | DPRINTF("bogus message\n"); | | 435 | DPRINTF("bogus message\n"); |
436 | } | | 436 | } |
437 | } | | 437 | } |
438 | | | 438 | |
439 | static int | | 439 | static int |
440 | adbkbd_wait(struct adbkbd_softc *sc, int timeout) | | 440 | adbkbd_wait(struct adbkbd_softc *sc, int timeout) |
441 | { | | 441 | { |
442 | int cnt = 0; | | 442 | int cnt = 0; |
443 | | | 443 | |
444 | if (sc->sc_poll) { | | 444 | if (sc->sc_poll) { |
445 | while (sc->sc_msg_len == 0) { | | 445 | while (sc->sc_msg_len == 0) { |
446 | sc->sc_ops->poll(sc->sc_ops->cookie); | | 446 | sc->sc_ops->poll(sc->sc_ops->cookie); |
447 | } | | 447 | } |
448 | } else { | | 448 | } else { |
449 | while ((sc->sc_msg_len == 0) && (cnt < timeout)) { | | 449 | while ((sc->sc_msg_len == 0) && (cnt < timeout)) { |
450 | tsleep(&sc->sc_event, 0, "adbkbdio", hz); | | 450 | tsleep(&sc->sc_event, 0, "adbkbdio", hz); |
451 | cnt++; | | 451 | cnt++; |
452 | } | | 452 | } |
453 | } | | 453 | } |
454 | return (sc->sc_msg_len > 0); | | 454 | return (sc->sc_msg_len > 0); |
455 | } | | 455 | } |
456 | | | 456 | |
457 | static void | | 457 | static void |
458 | adbkbd_keys(struct adbkbd_softc *sc, uint8_t k1, uint8_t k2) | | 458 | adbkbd_keys(struct adbkbd_softc *sc, uint8_t k1, uint8_t k2) |
459 | { | | 459 | { |
460 | | | 460 | |
461 | /* keyboard event processing */ | | 461 | /* keyboard event processing */ |
462 | | | 462 | |
463 | DPRINTF("[%02x %02x]", k1, k2); | | 463 | DPRINTF("[%02x %02x]", k1, k2); |
464 | | | 464 | |
465 | if (((k1 == k2) && (k1 == 0x7f)) || (k1 == sc->sc_power)) { | | 465 | if (((k1 == k2) && (k1 == 0x7f)) || (k1 == sc->sc_power)) { |
466 | uint32_t now = time_second; | | 466 | uint32_t now = time_second; |
467 | uint32_t diff = now - sc->sc_timestamp; | | 467 | uint32_t diff = now - sc->sc_timestamp; |
468 | | | 468 | |
469 | sc->sc_timestamp = now; | | 469 | sc->sc_timestamp = now; |
470 | if (((diff > 1) && (diff < 5)) || | | 470 | if (((diff > 1) && (diff < 5)) || |
471 | (sc->sc_power_button_delay == 0)) { | | 471 | (sc->sc_power_button_delay == 0)) { |
472 | #ifdef DDB | | 472 | #ifdef DDB |
473 | if (sc->sc_power_dbg) { | | 473 | if (sc->sc_power_dbg) { |
474 | Debugger(); | | 474 | Debugger(); |
475 | return; | | 475 | return; |
476 | } | | 476 | } |
477 | #endif | | 477 | #endif |
478 | /* power button, report to sysmon */ | | 478 | /* power button, report to sysmon */ |
479 | sc->sc_pe = k1; | | 479 | sc->sc_pe = k1; |
480 | sysmon_task_queue_sched(0, adbkbd_powerbutton, sc); | | 480 | sysmon_task_queue_sched(0, adbkbd_powerbutton, sc); |
481 | } | | 481 | } |
482 | } else { | | 482 | } else { |
483 | | | 483 | |
484 | adbkbd_key(sc, k1); | | 484 | adbkbd_key(sc, k1); |
485 | if (k2 != 0xff) | | 485 | if (k2 != 0xff) |
486 | adbkbd_key(sc, k2); | | 486 | adbkbd_key(sc, k2); |
487 | } | | 487 | } |
488 | } | | 488 | } |
489 | | | 489 | |
490 | static void | | 490 | static void |
491 | adbkbd_powerbutton(void *cookie) | | 491 | adbkbd_powerbutton(void *cookie) |
492 | { | | 492 | { |
493 | struct adbkbd_softc *sc = cookie; | | 493 | struct adbkbd_softc *sc = cookie; |
494 | | | 494 | |
495 | sysmon_pswitch_event(&sc->sc_sm_pbutton, | | 495 | sysmon_pswitch_event(&sc->sc_sm_pbutton, |
496 | ADBK_PRESS(sc->sc_pe) ? PSWITCH_EVENT_PRESSED : | | 496 | ADBK_PRESS(sc->sc_pe) ? PSWITCH_EVENT_PRESSED : |
497 | PSWITCH_EVENT_RELEASED); | | 497 | PSWITCH_EVENT_RELEASED); |
498 | | | 498 | |
499 | } | | 499 | } |
500 | | | 500 | |
501 | static inline void | | 501 | static inline void |
502 | adbkbd_key(struct adbkbd_softc *sc, uint8_t k) | | 502 | adbkbd_key(struct adbkbd_softc *sc, uint8_t k) |
503 | { | | 503 | { |
504 | | | 504 | |
505 | if (sc->sc_poll) { | | 505 | if (sc->sc_poll) { |
506 | if (sc->sc_polled_chars >= 16) { | | 506 | if (sc->sc_polled_chars >= 16) { |
507 | aprint_error_dev(sc->sc_dev,"polling buffer is full\n"); | | 507 | aprint_error_dev(sc->sc_dev,"polling buffer is full\n"); |
508 | } | | 508 | } |
509 | sc->sc_pollbuf[sc->sc_polled_chars] = k; | | 509 | sc->sc_pollbuf[sc->sc_polled_chars] = k; |
510 | sc->sc_polled_chars++; | | 510 | sc->sc_polled_chars++; |
511 | return; | | 511 | return; |
512 | } | | 512 | } |
513 | | | 513 | |
514 | #if NWSMOUSE > 0 | | 514 | #if NWSMOUSE > 0 |
515 | /* translate some keys to mouse events */ | | 515 | /* translate some keys to mouse events */ |
516 | if (sc->sc_wsmousedev != NULL) { | | 516 | if (sc->sc_wsmousedev != NULL) { |
517 | if (ADBK_KEYVAL(k) == sc->sc_trans[1]) { | | 517 | if (ADBK_KEYVAL(k) == sc->sc_trans[1]) { |
518 | wsmouse_input(sc->sc_wsmousedev, ADBK_PRESS(k) ? 2 : 0, | | 518 | wsmouse_input(sc->sc_wsmousedev, ADBK_PRESS(k) ? 2 : 0, |
519 | 0, 0, 0, 0, | | 519 | 0, 0, 0, 0, |
520 | WSMOUSE_INPUT_DELTA); | | 520 | WSMOUSE_INPUT_DELTA); |
521 | return; | | 521 | return; |
522 | } | | 522 | } |
523 | if (ADBK_KEYVAL(k) == sc->sc_trans[2]) { | | 523 | if (ADBK_KEYVAL(k) == sc->sc_trans[2]) { |
524 | wsmouse_input(sc->sc_wsmousedev, ADBK_PRESS(k) ? 4 : 0, | | 524 | wsmouse_input(sc->sc_wsmousedev, ADBK_PRESS(k) ? 4 : 0, |
525 | 0, 0, 0, 0, | | 525 | 0, 0, 0, 0, |
526 | WSMOUSE_INPUT_DELTA); | | 526 | WSMOUSE_INPUT_DELTA); |
527 | return; | | 527 | return; |
528 | } | | 528 | } |
529 | } | | 529 | } |
530 | #endif | | 530 | #endif |
531 | | | 531 | |
532 | #ifdef WSDISPLAY_COMPAT_RAWKBD | | 532 | #ifdef WSDISPLAY_COMPAT_RAWKBD |
533 | if (sc->sc_rawkbd) { | | 533 | if (sc->sc_rawkbd) { |
534 | char cbuf[2]; | | 534 | char cbuf[2]; |
535 | int s; | | 535 | int s; |
536 | | | 536 | |
537 | cbuf[0] = k; | | 537 | cbuf[0] = k; |
538 | | | 538 | |
539 | s = spltty(); | | 539 | s = spltty(); |
540 | wskbd_rawinput(sc->sc_wskbddev, cbuf, 1); | | 540 | wskbd_rawinput(sc->sc_wskbddev, cbuf, 1); |
541 | splx(s); | | 541 | splx(s); |
542 | } else { | | 542 | } else { |
543 | #endif | | 543 | #endif |
544 | | | 544 | |
545 | if (ADBK_KEYVAL(k) == 0x39) { | | 545 | if (ADBK_KEYVAL(k) == 0x39) { |
546 | /* caps lock - send up and down */ | | 546 | /* caps lock - send up and down */ |
547 | if (ADBK_PRESS(k) != sc->sc_capslock) { | | 547 | if (ADBK_PRESS(k) != sc->sc_capslock) { |
548 | sc->sc_capslock = ADBK_PRESS(k); | | 548 | sc->sc_capslock = ADBK_PRESS(k); |
549 | wskbd_input(sc->sc_wskbddev, | | 549 | wskbd_input(sc->sc_wskbddev, |
550 | WSCONS_EVENT_KEY_DOWN, 0x39); | | 550 | WSCONS_EVENT_KEY_DOWN, 0x39); |
551 | wskbd_input(sc->sc_wskbddev, | | 551 | wskbd_input(sc->sc_wskbddev, |
552 | WSCONS_EVENT_KEY_UP, 0x39); | | 552 | WSCONS_EVENT_KEY_UP, 0x39); |
553 | } | | 553 | } |
554 | } else { | | 554 | } else { |
555 | /* normal event */ | | 555 | /* normal event */ |
556 | int type; | | 556 | int type; |
557 | | | 557 | |
558 | type = ADBK_PRESS(k) ? | | 558 | type = ADBK_PRESS(k) ? |
559 | WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; | | 559 | WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; |
560 | wskbd_input(sc->sc_wskbddev, type, ADBK_KEYVAL(k)); | | 560 | wskbd_input(sc->sc_wskbddev, type, ADBK_KEYVAL(k)); |
561 | } | | 561 | } |
562 | #ifdef WSDISPLAY_COMPAT_RAWKBD | | 562 | #ifdef WSDISPLAY_COMPAT_RAWKBD |
563 | } | | 563 | } |
564 | #endif | | 564 | #endif |
565 | } | | 565 | } |
566 | | | 566 | |
567 | /* | | 567 | /* |
568 | * Set the keyboard LED's. | | 568 | * Set the keyboard LED's. |
569 | * | | 569 | * |
570 | * Automatically translates from ioctl/softc format to the | | 570 | * Automatically translates from ioctl/softc format to the |
571 | * actual keyboard register format | | 571 | * actual keyboard register format |
572 | */ | | 572 | */ |
573 | static void | | 573 | static void |
574 | adbkbd_set_leds(void *cookie, int leds) | | 574 | adbkbd_set_leds(void *cookie, int leds) |
575 | { | | 575 | { |
576 | struct adbkbd_softc *sc = cookie; | | 576 | struct adbkbd_softc *sc = cookie; |
577 | int aleds; | | 577 | int aleds; |
578 | short cmd; | | 578 | short cmd; |
579 | uint8_t buffer[2]; | | 579 | uint8_t buffer[2]; |
580 | | | 580 | |
581 | DPRINTF("adbkbd_set_leds: %02x\n", leds); | | 581 | DPRINTF("adbkbd_set_leds: %02x\n", leds); |
582 | if ((leds & 0x07) == (sc->sc_leds & 0x07)) | | 582 | if ((leds & 0x07) == (sc->sc_leds & 0x07)) |
583 | return; | | 583 | return; |
584 | | | 584 | |
585 | if (sc->sc_have_led_control) { | | 585 | if (sc->sc_have_led_control) { |
586 | | | 586 | |
587 | aleds = (~leds & 0x04) | 3; | | 587 | aleds = (~leds & 0x04) | 3; |
588 | if (leds & 1) | | 588 | if (leds & 1) |
589 | aleds &= ~2; | | 589 | aleds &= ~2; |
590 | if (leds & 2) | | 590 | if (leds & 2) |
591 | aleds &= ~1; | | 591 | aleds &= ~1; |
592 | | | 592 | |
593 | buffer[0] = 0xff; | | 593 | buffer[0] = 0xff; |
594 | buffer[1] = aleds | 0xf8; | | 594 | buffer[1] = aleds | 0xf8; |
595 | | | 595 | |
596 | cmd = ADBLISTEN(sc->sc_adbdev->current_addr, 2); | | 596 | cmd = ADBLISTEN(sc->sc_adbdev->current_addr, 2); |
597 | sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 2, | | 597 | sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 2, |
598 | buffer); | | 598 | buffer); |
599 | } | | 599 | } |
600 | | | 600 | |
601 | sc->sc_leds = leds & 7; | | 601 | sc->sc_leds = leds & 7; |
602 | } | | 602 | } |
603 | | | 603 | |
604 | static void | | 604 | static void |
605 | adbkbd_initleds(struct adbkbd_softc *sc) | | 605 | adbkbd_initleds(struct adbkbd_softc *sc) |
606 | { | | 606 | { |
607 | short cmd; | | 607 | short cmd; |
608 | | | 608 | |
609 | /* talk R2 */ | | 609 | /* talk R2 */ |
610 | cmd = ADBTALK(sc->sc_adbdev->current_addr, 2); | | 610 | cmd = ADBTALK(sc->sc_adbdev->current_addr, 2); |
611 | sc->sc_msg_len = 0; | | 611 | sc->sc_msg_len = 0; |
612 | sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 0, NULL); | | 612 | sc->sc_ops->send(sc->sc_ops->cookie, sc->sc_poll, cmd, 0, NULL); |
613 | if (!adbkbd_wait(sc, 10)) { | | 613 | if (!adbkbd_wait(sc, 10)) { |
614 | aprint_error_dev(sc->sc_dev, "unable to read LED state\n"); | | 614 | aprint_error_dev(sc->sc_dev, "unable to read LED state\n"); |
615 | return; | | 615 | return; |
616 | } | | 616 | } |
617 | sc->sc_have_led_control = 1; | | 617 | sc->sc_have_led_control = 1; |
618 | DPRINTF("have LED control\n"); | | 618 | DPRINTF("have LED control\n"); |
619 | return; | | 619 | return; |
620 | } | | 620 | } |
621 | | | 621 | |
622 | static int | | 622 | static int |
623 | adbkbd_enable(void *v, int on) | | 623 | adbkbd_enable(void *v, int on) |
624 | { | | 624 | { |
625 | return 0; | | 625 | return 0; |
626 | } | | 626 | } |
627 | | | 627 | |
628 | static int | | 628 | static int |
629 | adbkbd_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l) | | 629 | adbkbd_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l) |
630 | { | | 630 | { |
631 | struct adbkbd_softc *sc = (struct adbkbd_softc *) v; | | 631 | struct adbkbd_softc *sc = (struct adbkbd_softc *) v; |
632 | | | 632 | |
633 | switch (cmd) { | | 633 | switch (cmd) { |
634 | | | 634 | |
635 | case WSKBDIO_GTYPE: | | 635 | case WSKBDIO_GTYPE: |
636 | if (sc->sc_emul_usb) { | | 636 | if (sc->sc_emul_usb) { |
637 | *(int *)data = WSKBD_TYPE_USB; | | 637 | *(int *)data = WSKBD_TYPE_USB; |
638 | } else { | | 638 | } else { |
639 | *(int *)data = WSKBD_TYPE_ADB; | | 639 | *(int *)data = WSKBD_TYPE_ADB; |
640 | } | | 640 | } |
641 | return 0; | | 641 | return 0; |
642 | case WSKBDIO_SETLEDS: | | 642 | case WSKBDIO_SETLEDS: |
643 | adbkbd_set_leds(sc, *(int *)data); | | 643 | adbkbd_set_leds(sc, *(int *)data); |
644 | return 0; | | 644 | return 0; |
645 | case WSKBDIO_GETLEDS: | | 645 | case WSKBDIO_GETLEDS: |
646 | *(int *)data = sc->sc_leds; | | 646 | *(int *)data = sc->sc_leds; |
647 | return 0; | | 647 | return 0; |
648 | #ifdef WSDISPLAY_COMPAT_RAWKBD | | 648 | #ifdef WSDISPLAY_COMPAT_RAWKBD |
649 | case WSKBDIO_SETMODE: | | 649 | case WSKBDIO_SETMODE: |
650 | sc->sc_rawkbd = *(int *)data == WSKBD_RAW; | | 650 | sc->sc_rawkbd = *(int *)data == WSKBD_RAW; |
651 | return 0; | | 651 | return 0; |
652 | #endif | | 652 | #endif |
653 | } | | 653 | } |
654 | | | 654 | |
655 | return EPASSTHROUGH; | | 655 | return EPASSTHROUGH; |
656 | } | | 656 | } |
657 | | | 657 | |
658 | int | | 658 | int |
659 | adbkbd_cnattach(void) | | 659 | adbkbd_cnattach(void) |
660 | { | | 660 | { |
661 | | | 661 | |
662 | adbkbd_is_console = 1; | | 662 | adbkbd_is_console = 1; |
663 | return 0; | | 663 | return 0; |
664 | } | | 664 | } |
665 | | | 665 | |
666 | static void | | 666 | static void |
667 | adbkbd_cngetc(void *v, u_int *type, int *data) | | 667 | adbkbd_cngetc(void *v, u_int *type, int *data) |
668 | { | | 668 | { |
669 | struct adbkbd_softc *sc = v; | | 669 | struct adbkbd_softc *sc = v; |
670 | int key, press, val; | | 670 | int key, press, val; |
671 | int s; | | 671 | int s; |
672 | | | 672 | |
673 | s = splhigh(); | | 673 | s = splhigh(); |
674 | | | 674 | |
675 | KASSERT(sc->sc_poll); | | 675 | KASSERT(sc->sc_poll); |
676 | | | 676 | |
677 | DPRINTF("polling..."); | | 677 | DPRINTF("polling..."); |
678 | while (sc->sc_polled_chars == 0) { | | 678 | while (sc->sc_polled_chars == 0) { |
679 | sc->sc_ops->poll(sc->sc_ops->cookie); | | 679 | sc->sc_ops->poll(sc->sc_ops->cookie); |
680 | } | | 680 | } |
681 | DPRINTF(" got one\n"); | | 681 | DPRINTF(" got one\n"); |
682 | splx(s); | | 682 | splx(s); |
683 | | | 683 | |
684 | key = sc->sc_pollbuf[0]; | | 684 | key = sc->sc_pollbuf[0]; |
685 | sc->sc_polled_chars--; | | 685 | sc->sc_polled_chars--; |
686 | memmove(sc->sc_pollbuf, sc->sc_pollbuf + 1, | | 686 | memmove(sc->sc_pollbuf, sc->sc_pollbuf + 1, |
687 | sc->sc_polled_chars); | | 687 | sc->sc_polled_chars); |
688 | | | 688 | |
689 | press = ADBK_PRESS(key); | | 689 | press = ADBK_PRESS(key); |
690 | val = ADBK_KEYVAL(key); | | 690 | val = ADBK_KEYVAL(key); |
691 | | | 691 | |
692 | *data = val; | | 692 | *data = val; |
693 | *type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; | | 693 | *type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; |
694 | } | | 694 | } |
695 | | | 695 | |
696 | static void | | 696 | static void |
697 | adbkbd_cnpollc(void *v, int on) | | 697 | adbkbd_cnpollc(void *v, int on) |
698 | { | | 698 | { |
699 | struct adbkbd_softc *sc = v; | | 699 | struct adbkbd_softc *sc = v; |
700 | | | 700 | |
701 | sc->sc_poll = on; | | 701 | sc->sc_poll = on; |
702 | if (!on) { | | 702 | if (!on) { |
703 | int i; | | 703 | int i; |
704 | | | 704 | |
705 | /* feed the poll buffer's content to wskbd */ | | 705 | /* feed the poll buffer's content to wskbd */ |
706 | for (i = 0; i < sc->sc_polled_chars; i++) { | | 706 | for (i = 0; i < sc->sc_polled_chars; i++) { |
707 | adbkbd_key(sc, sc->sc_pollbuf[i]); | | 707 | adbkbd_key(sc, sc->sc_pollbuf[i]); |
708 | } | | 708 | } |
709 | sc->sc_polled_chars = 0; | | 709 | sc->sc_polled_chars = 0; |
710 | } | | 710 | } |
711 | } | | 711 | } |
712 | | | 712 | |
713 | #if NWSMOUSE > 0 | | 713 | #if NWSMOUSE > 0 |
714 | /* stuff for the pseudo mouse */ | | 714 | /* stuff for the pseudo mouse */ |
715 | static int | | 715 | static int |
716 | adbkms_enable(void *v) | | 716 | adbkms_enable(void *v) |
717 | { | | 717 | { |
718 | return 0; | | 718 | return 0; |
719 | } | | 719 | } |
720 | | | 720 | |
721 | static int | | 721 | static int |
722 | adbkms_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l) | | 722 | adbkms_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l) |
723 | { | | 723 | { |
724 | | | 724 | |
725 | switch (cmd) { | | 725 | switch (cmd) { |
726 | case WSMOUSEIO_GTYPE: | | 726 | case WSMOUSEIO_GTYPE: |
727 | *(u_int *)data = WSMOUSE_TYPE_PSEUDO; | | 727 | *(u_int *)data = WSMOUSE_TYPE_PSEUDO; |
728 | break; | | 728 | break; |
729 | | | 729 | |
730 | default: | | 730 | default: |
731 | return (EPASSTHROUGH); | | 731 | return (EPASSTHROUGH); |
732 | } | | 732 | } |
733 | return (0); | | 733 | return (0); |
734 | } | | 734 | } |
735 | | | 735 | |
736 | static void | | 736 | static void |
737 | adbkms_disable(void *v) | | 737 | adbkms_disable(void *v) |
738 | { | | 738 | { |
739 | } | | 739 | } |
740 | | | 740 | |
741 | static int | | 741 | static int |
742 | adbkbd_sysctl_mid(SYSCTLFN_ARGS) | | 742 | adbkbd_sysctl_mid(SYSCTLFN_ARGS) |
743 | { | | 743 | { |
744 | struct sysctlnode node = *rnode; | | 744 | struct sysctlnode node = *rnode; |
745 | struct adbkbd_softc *sc=(struct adbkbd_softc *)node.sysctl_data; | | 745 | struct adbkbd_softc *sc=(struct adbkbd_softc *)node.sysctl_data; |
746 | const int *np = newp; | | 746 | const int *np = newp; |
747 | int reg; | | 747 | int reg; |
748 | | | 748 | |
749 | DPRINTF("adbkbd_sysctl_mid\n"); | | 749 | DPRINTF("adbkbd_sysctl_mid\n"); |
750 | reg = sc->sc_trans[1]; | | 750 | reg = sc->sc_trans[1]; |
751 | if (np) { | | 751 | if (np) { |
752 | /* we're asked to write */ | | 752 | /* we're asked to write */ |
753 | node.sysctl_data = ® | | 753 | node.sysctl_data = ® |
754 | if (sysctl_lookup(SYSCTLFN_CALL(&node)) == 0) { | | 754 | if (sysctl_lookup(SYSCTLFN_CALL(&node)) == 0) { |
755 | | | 755 | |
756 | sc->sc_trans[1] = *(int *)node.sysctl_data; | | 756 | sc->sc_trans[1] = *(int *)node.sysctl_data; |
757 | return 0; | | 757 | return 0; |
758 | } | | 758 | } |
759 | return EINVAL; | | 759 | return EINVAL; |
760 | } else { | | 760 | } else { |
761 | node.sysctl_data = ® | | 761 | node.sysctl_data = ® |
762 | node.sysctl_size = 4; | | 762 | node.sysctl_size = 4; |
763 | return (sysctl_lookup(SYSCTLFN_CALL(&node))); | | 763 | return (sysctl_lookup(SYSCTLFN_CALL(&node))); |
764 | } | | 764 | } |
765 | } | | 765 | } |
766 | | | 766 | |
767 | static int | | 767 | static int |
768 | adbkbd_sysctl_right(SYSCTLFN_ARGS) | | 768 | adbkbd_sysctl_right(SYSCTLFN_ARGS) |
769 | { | | 769 | { |
770 | struct sysctlnode node = *rnode; | | 770 | struct sysctlnode node = *rnode; |
771 | struct adbkbd_softc *sc=(struct adbkbd_softc *)node.sysctl_data; | | 771 | struct adbkbd_softc *sc=(struct adbkbd_softc *)node.sysctl_data; |
772 | const int *np = newp; | | 772 | const int *np = newp; |
773 | int reg; | | 773 | int reg; |
774 | | | 774 | |
775 | DPRINTF("adbkbd_sysctl_right\n"); | | 775 | DPRINTF("adbkbd_sysctl_right\n"); |
776 | reg = sc->sc_trans[2]; | | 776 | reg = sc->sc_trans[2]; |
777 | if (np) { | | 777 | if (np) { |
778 | /* we're asked to write */ | | 778 | /* we're asked to write */ |
779 | node.sysctl_data = ® | | 779 | node.sysctl_data = ® |
780 | if (sysctl_lookup(SYSCTLFN_CALL(&node)) == 0) { | | 780 | if (sysctl_lookup(SYSCTLFN_CALL(&node)) == 0) { |
781 | | | 781 | |
782 | sc->sc_trans[2] = *(int *)node.sysctl_data; | | 782 | sc->sc_trans[2] = *(int *)node.sysctl_data; |
783 | return 0; | | 783 | return 0; |
784 | } | | 784 | } |
785 | return EINVAL; | | 785 | return EINVAL; |
786 | } else { | | 786 | } else { |
787 | node.sysctl_data = ® | | 787 | node.sysctl_data = ® |
788 | node.sysctl_size = 4; | | 788 | node.sysctl_size = 4; |
789 | return (sysctl_lookup(SYSCTLFN_CALL(&node))); | | 789 | return (sysctl_lookup(SYSCTLFN_CALL(&node))); |
790 | } | | 790 | } |
791 | } | | 791 | } |
792 | | | 792 | |
793 | #endif /* NWSMOUSE > 0 */ | | 793 | #endif /* NWSMOUSE > 0 */ |
794 | | | 794 | |
795 | static int | | 795 | static int |
796 | adbkbd_sysctl_usb(SYSCTLFN_ARGS) | | 796 | adbkbd_sysctl_usb(SYSCTLFN_ARGS) |
797 | { | | 797 | { |
798 | struct sysctlnode node = *rnode; | | 798 | struct sysctlnode node = *rnode; |
799 | struct adbkbd_softc *sc=(struct adbkbd_softc *)node.sysctl_data; | | 799 | struct adbkbd_softc *sc=(struct adbkbd_softc *)node.sysctl_data; |
800 | const int *np = newp; | | 800 | const int *np = newp; |
801 | bool reg; | | 801 | bool reg; |
802 | | | 802 | |
803 | DPRINTF("%s\n", __func__); | | 803 | DPRINTF("%s\n", __func__); |
804 | reg = sc->sc_emul_usb; | | 804 | reg = sc->sc_emul_usb; |
805 | if (np) { | | 805 | if (np) { |
806 | /* we're asked to write */ | | 806 | /* we're asked to write */ |
807 | node.sysctl_data = ® | | 807 | node.sysctl_data = ® |
808 | if (sysctl_lookup(SYSCTLFN_CALL(&node)) == 0) { | | 808 | if (sysctl_lookup(SYSCTLFN_CALL(&node)) == 0) { |
809 | | | 809 | |
810 | sc->sc_emul_usb = *(bool *)node.sysctl_data; | | 810 | sc->sc_emul_usb = *(bool *)node.sysctl_data; |
811 | if (sc->sc_emul_usb) { | | 811 | if (sc->sc_emul_usb) { |
812 | wskbd_set_evtrans(sc->sc_wskbddev, | | 812 | wskbd_set_evtrans(sc->sc_wskbddev, |
813 | adb_to_usb, 128); | | 813 | adb_to_usb, 128); |
814 | } else { | | 814 | } else { |
815 | wskbd_set_evtrans(sc->sc_wskbddev, NULL, 0); | | 815 | wskbd_set_evtrans(sc->sc_wskbddev, NULL, 0); |
816 | } | | 816 | } |
817 | return 0; | | 817 | return 0; |
818 | } | | 818 | } |
819 | return EINVAL; | | 819 | return EINVAL; |
820 | } else { | | 820 | } else { |
821 | node.sysctl_data = ® | | 821 | node.sysctl_data = ® |
822 | node.sysctl_size = sizeof(reg); | | 822 | node.sysctl_size = sizeof(reg); |
823 | return (sysctl_lookup(SYSCTLFN_CALL(&node))); | | 823 | return (sysctl_lookup(SYSCTLFN_CALL(&node))); |
824 | } | | 824 | } |
825 | } | | 825 | } |
826 | | | 826 | |
827 | static int | | 827 | static int |
828 | adbkbd_sysctl_dbg(SYSCTLFN_ARGS) | | 828 | adbkbd_sysctl_dbg(SYSCTLFN_ARGS) |
829 | { | | 829 | { |
830 | struct sysctlnode node = *rnode; | | 830 | struct sysctlnode node = *rnode; |
831 | struct adbkbd_softc *sc=(struct adbkbd_softc *)node.sysctl_data; | | 831 | struct adbkbd_softc *sc=(struct adbkbd_softc *)node.sysctl_data; |
832 | const int *np = newp; | | 832 | const int *np = newp; |
833 | bool reg; | | 833 | bool reg; |
834 | | | 834 | |
835 | DPRINTF("%s\n", __func__); | | 835 | DPRINTF("%s\n", __func__); |
836 | reg = sc->sc_power_dbg; | | 836 | reg = sc->sc_power_dbg; |
837 | if (np) { | | 837 | if (np) { |
838 | /* we're asked to write */ | | 838 | /* we're asked to write */ |
839 | node.sysctl_data = ® | | 839 | node.sysctl_data = ® |
840 | if (sysctl_lookup(SYSCTLFN_CALL(&node)) == 0) { | | 840 | if (sysctl_lookup(SYSCTLFN_CALL(&node)) == 0) { |
841 | | | 841 | |
842 | sc->sc_power_dbg = *(bool *)node.sysctl_data; | | 842 | sc->sc_power_dbg = *(bool *)node.sysctl_data; |
843 | return 0; | | 843 | return 0; |
844 | } | | 844 | } |
845 | return EINVAL; | | 845 | return EINVAL; |
846 | } else { | | 846 | } else { |
847 | node.sysctl_data = ® | | 847 | node.sysctl_data = ® |
848 | node.sysctl_size = sizeof(reg); | | 848 | node.sysctl_size = sizeof(reg); |
849 | return (sysctl_lookup(SYSCTLFN_CALL(&node))); | | 849 | return (sysctl_lookup(SYSCTLFN_CALL(&node))); |
850 | } | | 850 | } |
851 | } | | 851 | } |
852 | | | 852 | |
853 | static void | | 853 | static void |
854 | adbkbd_setup_sysctl(struct adbkbd_softc *sc) | | 854 | adbkbd_setup_sysctl(struct adbkbd_softc *sc) |
855 | { | | 855 | { |
856 | const struct sysctlnode *me, *node; | | 856 | const struct sysctlnode *me, *node; |
857 | int ret; | | 857 | int ret; |
858 | | | 858 | |
859 | DPRINTF("%s: sysctl setup\n", device_xname(sc->sc_dev)); | | 859 | DPRINTF("%s: sysctl setup\n", device_xname(sc->sc_dev)); |
860 | ret = sysctl_createv(NULL, 0, NULL, &me, | | 860 | ret = sysctl_createv(NULL, 0, NULL, &me, |
861 | CTLFLAG_READWRITE, | | 861 | CTLFLAG_READWRITE, |
862 | CTLTYPE_NODE, device_xname(sc->sc_dev), NULL, | | 862 | CTLTYPE_NODE, device_xname(sc->sc_dev), NULL, |
863 | NULL, 0, NULL, 0, | | 863 | NULL, 0, NULL, 0, |
864 | CTL_MACHDEP, CTL_CREATE, CTL_EOL); | | 864 | CTL_MACHDEP, CTL_CREATE, CTL_EOL); |
865 | ret = sysctl_createv(NULL, 0, NULL, | | 865 | ret = sysctl_createv(NULL, 0, NULL, |
866 | (void *)&node, | | 866 | (void *)&node, |
867 | CTLFLAG_READWRITE | CTLFLAG_OWNDESC, | | 867 | CTLFLAG_READWRITE | CTLFLAG_OWNDESC, |
868 | CTLTYPE_BOOL, "emulate_usb", "USB keyboard emulation", | | 868 | CTLTYPE_BOOL, "emulate_usb", "USB keyboard emulation", |
869 | adbkbd_sysctl_usb, 1, (void *)sc, 0, CTL_MACHDEP, | | 869 | adbkbd_sysctl_usb, 1, (void *)sc, 0, CTL_MACHDEP, |
870 | me->sysctl_num, CTL_CREATE, CTL_EOL); | | 870 | me->sysctl_num, CTL_CREATE, CTL_EOL); |
871 | ret = sysctl_createv(NULL, 0, NULL, | | 871 | ret = sysctl_createv(NULL, 0, NULL, |
872 | (void *)&node, | | 872 | (void *)&node, |
873 | CTLFLAG_READWRITE | CTLFLAG_OWNDESC, | | 873 | CTLFLAG_READWRITE | CTLFLAG_OWNDESC, |
874 | CTLTYPE_BOOL, "power_ddb", "power button triggers ddb", | | 874 | CTLTYPE_BOOL, "power_ddb", "power button triggers ddb", |
875 | adbkbd_sysctl_dbg, 1, (void *)sc, 0, CTL_MACHDEP, | | 875 | adbkbd_sysctl_dbg, 1, (void *)sc, 0, CTL_MACHDEP, |
876 | me->sysctl_num, CTL_CREATE, CTL_EOL); | | 876 | me->sysctl_num, CTL_CREATE, CTL_EOL); |
877 | #if NWSMOUSE > 0 | | 877 | #if NWSMOUSE > 0 |
878 | if (sc->sc_wsmousedev != NULL) { | | 878 | if (sc->sc_wsmousedev != NULL) { |
879 | ret = sysctl_createv(NULL, 0, NULL, | | 879 | ret = sysctl_createv(NULL, 0, NULL, |
880 | (void *)&node, | | 880 | (void *)&node, |
881 | CTLFLAG_READWRITE | CTLFLAG_OWNDESC, | | 881 | CTLFLAG_READWRITE | CTLFLAG_OWNDESC, |
882 | CTLTYPE_INT, "middle", "middle mouse button", | | 882 | CTLTYPE_INT, "middle", "middle mouse button", |
883 | adbkbd_sysctl_mid, 1, (void *)sc, 0, CTL_MACHDEP, | | 883 | adbkbd_sysctl_mid, 1, (void *)sc, 0, CTL_MACHDEP, |
884 | me->sysctl_num, CTL_CREATE, CTL_EOL); | | 884 | me->sysctl_num, CTL_CREATE, CTL_EOL); |
885 | | | 885 | |
886 | ret = sysctl_createv(NULL, 0, NULL, | | 886 | ret = sysctl_createv(NULL, 0, NULL, |
887 | (void *)&node, | | 887 | (void *)&node, |
888 | CTLFLAG_READWRITE | CTLFLAG_OWNDESC, | | 888 | CTLFLAG_READWRITE | CTLFLAG_OWNDESC, |
889 | CTLTYPE_INT, "right", "right mouse button", | | 889 | CTLTYPE_INT, "right", "right mouse button", |
890 | adbkbd_sysctl_right, 2, (void *)sc, 0, CTL_MACHDEP, | | 890 | adbkbd_sysctl_right, 2, (void *)sc, 0, CTL_MACHDEP, |
891 | me->sysctl_num, CTL_CREATE, CTL_EOL); | | 891 | me->sysctl_num, CTL_CREATE, CTL_EOL); |
892 | } | | 892 | } |
893 | #endif /* NWSMOUSE > 0 */ | | 893 | #endif /* NWSMOUSE > 0 */ |
894 | | | 894 | |
895 | (void)ret; | | 895 | (void)ret; |
896 | } | | 896 | } |
897 | | | 897 | |
898 | SYSCTL_SETUP(sysctl_adbkbdtrans_setup, "adbkbd translator setup") | | 898 | SYSCTL_SETUP(sysctl_adbkbdtrans_setup, "adbkbd translator setup") |
899 | { | | 899 | { |
900 | | | 900 | |
901 | sysctl_createv(NULL, 0, NULL, NULL, | | 901 | sysctl_createv(NULL, 0, NULL, NULL, |
902 | CTLFLAG_PERMANENT, | | 902 | CTLFLAG_PERMANENT, |
903 | CTLTYPE_NODE, "machdep", NULL, | | 903 | CTLTYPE_NODE, "machdep", NULL, |
904 | NULL, 0, NULL, 0, | | 904 | NULL, 0, NULL, 0, |
905 | CTL_MACHDEP, CTL_EOL); | | 905 | CTL_MACHDEP, CTL_EOL); |
906 | } | | 906 | } |