2 * SEGA Dreamcast keyboard driver
3 * Based on drivers/usb/usbkbd.c
4 * Copyright YAEGASHI Takeshi, 2001
5 * Porting to 2.6 Copyright Adrian McMenamin, 2007
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, see the file COPYING, or write
19 * to the Free Software Foundation, Inc.,
20 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <linux/kernel.h>
24 #include <linux/slab.h>
25 #include <linux/input.h>
26 #include <linux/module.h>
27 #include <linux/init.h>
28 #include <linux/timer.h>
29 #include <linux/maple.h>
30 #include <asm/mach/maple.h>
32 /* Very simple mutex to ensure proper cleanup */
33 static DEFINE_MUTEX(maple_keyb_mutex
);
35 #define NR_SCANCODES 256
37 MODULE_AUTHOR("YAEGASHI Takeshi, Adrian McMenamin");
38 MODULE_DESCRIPTION("SEGA Dreamcast keyboard driver");
39 MODULE_LICENSE("GPL");
42 struct input_dev
*dev
;
43 unsigned short keycode
[NR_SCANCODES
];
48 static const unsigned short dc_kbd_keycode
[NR_SCANCODES
] = {
49 KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_A
, KEY_B
, KEY_C
, KEY_D
,
50 KEY_E
, KEY_F
, KEY_G
, KEY_H
, KEY_I
, KEY_J
, KEY_K
, KEY_L
,
51 KEY_M
, KEY_N
, KEY_O
, KEY_P
, KEY_Q
, KEY_R
, KEY_S
, KEY_T
,
52 KEY_U
, KEY_V
, KEY_W
, KEY_X
, KEY_Y
, KEY_Z
, KEY_1
, KEY_2
,
53 KEY_3
, KEY_4
, KEY_5
, KEY_6
, KEY_7
, KEY_8
, KEY_9
, KEY_0
,
54 KEY_ENTER
, KEY_ESC
, KEY_BACKSPACE
, KEY_TAB
, KEY_SPACE
, KEY_MINUS
, KEY_EQUAL
, KEY_LEFTBRACE
,
55 KEY_RIGHTBRACE
, KEY_BACKSLASH
, KEY_BACKSLASH
, KEY_SEMICOLON
, KEY_APOSTROPHE
, KEY_GRAVE
, KEY_COMMA
,
56 KEY_DOT
, KEY_SLASH
, KEY_CAPSLOCK
, KEY_F1
, KEY_F2
, KEY_F3
, KEY_F4
, KEY_F5
, KEY_F6
,
57 KEY_F7
, KEY_F8
, KEY_F9
, KEY_F10
, KEY_F11
, KEY_F12
, KEY_SYSRQ
,
58 KEY_SCROLLLOCK
, KEY_PAUSE
, KEY_INSERT
, KEY_HOME
, KEY_PAGEUP
, KEY_DELETE
,
59 KEY_END
, KEY_PAGEDOWN
, KEY_RIGHT
, KEY_LEFT
, KEY_DOWN
, KEY_UP
,
60 KEY_NUMLOCK
, KEY_KPSLASH
, KEY_KPASTERISK
, KEY_KPMINUS
, KEY_KPPLUS
, KEY_KPENTER
, KEY_KP1
, KEY_KP2
,
61 KEY_KP3
, KEY_KP4
, KEY_KP5
, KEY_KP6
, KEY_KP7
, KEY_KP8
, KEY_KP9
, KEY_KP0
, KEY_KPDOT
,
62 KEY_102ND
, KEY_COMPOSE
, KEY_POWER
, KEY_KPEQUAL
, KEY_F13
, KEY_F14
, KEY_F15
,
63 KEY_F16
, KEY_F17
, KEY_F18
, KEY_F19
, KEY_F20
,
64 KEY_F21
, KEY_F22
, KEY_F23
, KEY_F24
, KEY_OPEN
, KEY_HELP
, KEY_PROPS
, KEY_FRONT
,
65 KEY_STOP
, KEY_AGAIN
, KEY_UNDO
, KEY_CUT
, KEY_COPY
, KEY_PASTE
, KEY_FIND
, KEY_MUTE
,
66 KEY_VOLUMEUP
, KEY_VOLUMEDOWN
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_KPCOMMA
, KEY_RESERVED
, KEY_RO
, KEY_KATAKANAHIRAGANA
, KEY_YEN
,
67 KEY_HENKAN
, KEY_MUHENKAN
, KEY_KPJPCOMMA
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
,
68 KEY_HANGEUL
, KEY_HANJA
, KEY_KATAKANA
, KEY_HIRAGANA
, KEY_ZENKAKUHANKAKU
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
,
69 KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
,
70 KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
,
71 KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
,
72 KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
,
73 KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
,
74 KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
,
75 KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
,
76 KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
,
77 KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
,
78 KEY_LEFTCTRL
, KEY_LEFTSHIFT
, KEY_LEFTALT
, KEY_LEFTMETA
, KEY_RIGHTCTRL
, KEY_RIGHTSHIFT
, KEY_RIGHTALT
, KEY_RIGHTMETA
,
79 KEY_PLAYPAUSE
, KEY_STOPCD
, KEY_PREVIOUSSONG
, KEY_NEXTSONG
, KEY_EJECTCD
, KEY_VOLUMEUP
, KEY_VOLUMEDOWN
, KEY_MUTE
,
80 KEY_WWW
, KEY_BACK
, KEY_FORWARD
, KEY_STOP
, KEY_FIND
, KEY_SCROLLUP
, KEY_SCROLLDOWN
, KEY_EDIT
, KEY_SLEEP
,
81 KEY_SCREENLOCK
, KEY_REFRESH
, KEY_CALC
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
, KEY_RESERVED
84 static void dc_scan_kbd(struct dc_kbd
*kbd
)
86 struct input_dev
*dev
= kbd
->dev
;
91 for (i
= 0; i
< 8; i
++) {
93 keycode
= kbd
->keycode
[code
];
94 input_event(dev
, EV_MSC
, MSC_SCAN
, code
);
95 input_report_key(dev
, keycode
, (kbd
->new[0] >> i
) & 1);
98 for (i
= 2; i
< 8; i
++) {
99 ptr
= memchr(kbd
->new + 2, kbd
->old
[i
], 6);
101 if (code
> 3 && ptr
== NULL
) {
102 keycode
= kbd
->keycode
[code
];
104 input_event(dev
, EV_MSC
, MSC_SCAN
, code
);
105 input_report_key(dev
, keycode
, 0);
107 printk(KERN_DEBUG
"maple_keyb: "
108 "Unknown key (scancode %#x) released.",
111 ptr
= memchr(kbd
->old
+ 2, kbd
->new[i
], 6);
113 if (code
> 3 && ptr
) {
114 keycode
= kbd
->keycode
[code
];
116 input_event(dev
, EV_MSC
, MSC_SCAN
, code
);
117 input_report_key(dev
, keycode
, 1);
119 printk(KERN_DEBUG
"maple_keyb: "
120 "Unknown key (scancode %#x) pressed.",
125 memcpy(kbd
->old
, kbd
->new, 8);
128 static void dc_kbd_callback(struct mapleq
*mq
)
130 struct maple_device
*mapledev
= mq
->dev
;
131 struct dc_kbd
*kbd
= mapledev
->private_data
;
132 unsigned long *buf
= mq
->recvbuf
;
135 * We should always be getting the lock because the only
136 * time it may be locked if driver is in cleanup phase.
138 if (likely(mutex_trylock(&maple_keyb_mutex
))) {
140 if (buf
[1] == mapledev
->function
) {
141 memcpy(kbd
->new, buf
+ 2, 8);
145 mutex_unlock(&maple_keyb_mutex
);
149 static int dc_kbd_connect(struct maple_device
*mdev
)
153 struct input_dev
*dev
;
155 if (!(mdev
->function
& MAPLE_FUNC_KEYBOARD
))
158 kbd
= kzalloc(sizeof(struct dc_kbd
), GFP_KERNEL
);
159 dev
= input_allocate_device();
165 mdev
->private_data
= kbd
;
168 memcpy(kbd
->keycode
, dc_kbd_keycode
, sizeof(kbd
->keycode
));
170 dev
->name
= mdev
->product_name
;
171 dev
->evbit
[0] = BIT(EV_KEY
) | BIT(EV_REP
);
172 dev
->keycode
= kbd
->keycode
;
173 dev
->keycodesize
= sizeof (unsigned short);
174 dev
->keycodemax
= ARRAY_SIZE(kbd
->keycode
);
175 dev
->id
.bustype
= BUS_HOST
;
176 dev
->dev
.parent
= &mdev
->dev
;
178 for (i
= 0; i
< NR_SCANCODES
; i
++)
179 __set_bit(dc_kbd_keycode
[i
], dev
->keybit
);
180 __clear_bit(KEY_RESERVED
, dev
->keybit
);
182 input_set_capability(dev
, EV_MSC
, MSC_SCAN
);
183 input_set_drvdata(dev
, kbd
);
185 error
= input_register_device(dev
);
189 /* Maple polling is locked to VBLANK - which may be just 50/s */
190 maple_getcond_callback(mdev
, dc_kbd_callback
, HZ
/50, MAPLE_FUNC_KEYBOARD
);
194 input_free_device(dev
);
196 mdev
->private_data
= NULL
;
200 static void dc_kbd_disconnect(struct maple_device
*mdev
)
204 mutex_lock(&maple_keyb_mutex
);
206 kbd
= mdev
->private_data
;
207 mdev
->private_data
= NULL
;
208 input_unregister_device(kbd
->dev
);
211 mutex_unlock(&maple_keyb_mutex
);
214 /* allow the keyboard to be used */
215 static int probe_maple_kbd(struct device
*dev
)
217 struct maple_device
*mdev
= to_maple_dev(dev
);
218 struct maple_driver
*mdrv
= to_maple_driver(dev
->driver
);
221 error
= dc_kbd_connect(mdev
);
226 mdev
->registered
= 1;
231 static struct maple_driver dc_kbd_driver
= {
232 .function
= MAPLE_FUNC_KEYBOARD
,
233 .connect
= dc_kbd_connect
,
234 .disconnect
= dc_kbd_disconnect
,
236 .name
= "Dreamcast_keyboard",
237 .probe
= probe_maple_kbd
,
241 static int __init
dc_kbd_init(void)
243 return maple_driver_register(&dc_kbd_driver
.drv
);
246 static void __exit
dc_kbd_exit(void)
248 driver_unregister(&dc_kbd_driver
.drv
);
251 module_init(dc_kbd_init
);
252 module_exit(dc_kbd_exit
);