Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
maple_keyb.c
Go to the documentation of this file.
1 /*
2  * SEGA Dreamcast keyboard driver
3  * Based on drivers/usb/usbkbd.c
4  * Copyright (c) YAEGASHI Takeshi, 2001
5  * Porting to 2.6 Copyright (c) Adrian McMenamin, 2007 - 2009
6  *
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.
11  *
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.
16  *
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
21  */
22 
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 
31 /* Very simple mutex to ensure proper cleanup */
32 static DEFINE_MUTEX(maple_keyb_mutex);
33 
34 #define NR_SCANCODES 256
35 
36 MODULE_AUTHOR("Adrian McMenamin <[email protected]");
37 MODULE_DESCRIPTION("SEGA Dreamcast keyboard driver");
38 MODULE_LICENSE("GPL");
39 
40 struct dc_kbd {
41  struct input_dev *dev;
42  unsigned short keycode[NR_SCANCODES];
43  unsigned char new[8];
44  unsigned char old[8];
45 };
46 
47 static const unsigned short dc_kbd_keycode[NR_SCANCODES] = {
93 };
94 
95 static void dc_scan_kbd(struct dc_kbd *kbd)
96 {
97  struct input_dev *dev = kbd->dev;
98  void *ptr;
99  int code, keycode;
100  int i;
101 
102  for (i = 0; i < 8; i++) {
103  code = i + 224;
104  keycode = kbd->keycode[code];
105  input_event(dev, EV_MSC, MSC_SCAN, code);
106  input_report_key(dev, keycode, (kbd->new[0] >> i) & 1);
107  }
108 
109  for (i = 2; i < 8; i++) {
110  ptr = memchr(kbd->new + 2, kbd->old[i], 6);
111  code = kbd->old[i];
112  if (code > 3 && ptr == NULL) {
113  keycode = kbd->keycode[code];
114  if (keycode) {
115  input_event(dev, EV_MSC, MSC_SCAN, code);
116  input_report_key(dev, keycode, 0);
117  } else
118  dev_dbg(&dev->dev,
119  "Unknown key (scancode %#x) released.",
120  code);
121  }
122  ptr = memchr(kbd->old + 2, kbd->new[i], 6);
123  code = kbd->new[i];
124  if (code > 3 && ptr) {
125  keycode = kbd->keycode[code];
126  if (keycode) {
127  input_event(dev, EV_MSC, MSC_SCAN, code);
128  input_report_key(dev, keycode, 1);
129  } else
130  dev_dbg(&dev->dev,
131  "Unknown key (scancode %#x) pressed.",
132  code);
133  }
134  }
135  input_sync(dev);
136  memcpy(kbd->old, kbd->new, 8);
137 }
138 
139 static void dc_kbd_callback(struct mapleq *mq)
140 {
141  struct maple_device *mapledev = mq->dev;
142  struct dc_kbd *kbd = maple_get_drvdata(mapledev);
143  unsigned long *buf = (unsigned long *)(mq->recvbuf->buf);
144 
145  /*
146  * We should always get the lock because the only
147  * time it may be locked is if the driver is in the cleanup phase.
148  */
149  if (likely(mutex_trylock(&maple_keyb_mutex))) {
150 
151  if (buf[1] == mapledev->function) {
152  memcpy(kbd->new, buf + 2, 8);
153  dc_scan_kbd(kbd);
154  }
155 
156  mutex_unlock(&maple_keyb_mutex);
157  }
158 }
159 
160 static int probe_maple_kbd(struct device *dev)
161 {
162  struct maple_device *mdev;
163  struct maple_driver *mdrv;
164  int i, error;
165  struct dc_kbd *kbd;
166  struct input_dev *idev;
167 
168  mdev = to_maple_dev(dev);
169  mdrv = to_maple_driver(dev->driver);
170 
171  kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL);
172  if (!kbd) {
173  error = -ENOMEM;
174  goto fail;
175  }
176 
177  idev = input_allocate_device();
178  if (!idev) {
179  error = -ENOMEM;
180  goto fail_idev_alloc;
181  }
182 
183  kbd->dev = idev;
184  memcpy(kbd->keycode, dc_kbd_keycode, sizeof(kbd->keycode));
185 
186  idev->name = mdev->product_name;
187  idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP);
188  idev->keycode = kbd->keycode;
189  idev->keycodesize = sizeof(unsigned short);
190  idev->keycodemax = ARRAY_SIZE(kbd->keycode);
191  idev->id.bustype = BUS_HOST;
192  idev->dev.parent = &mdev->dev;
193 
194  for (i = 0; i < NR_SCANCODES; i++)
195  __set_bit(dc_kbd_keycode[i], idev->keybit);
196  __clear_bit(KEY_RESERVED, idev->keybit);
197 
198  input_set_capability(idev, EV_MSC, MSC_SCAN);
199  input_set_drvdata(idev, kbd);
200 
201  error = input_register_device(idev);
202  if (error)
203  goto fail_register;
204 
205  /* Maple polling is locked to VBLANK - which may be just 50/s */
206  maple_getcond_callback(mdev, dc_kbd_callback, HZ/50,
208 
209  mdev->driver = mdrv;
210 
211  maple_set_drvdata(mdev, kbd);
212 
213  return error;
214 
215 fail_register:
216  maple_set_drvdata(mdev, NULL);
217  input_free_device(idev);
218 fail_idev_alloc:
219  kfree(kbd);
220 fail:
221  return error;
222 }
223 
224 static int remove_maple_kbd(struct device *dev)
225 {
226  struct maple_device *mdev = to_maple_dev(dev);
227  struct dc_kbd *kbd = maple_get_drvdata(mdev);
228 
229  mutex_lock(&maple_keyb_mutex);
230 
231  input_unregister_device(kbd->dev);
232  kfree(kbd);
233 
234  maple_set_drvdata(mdev, NULL);
235 
236  mutex_unlock(&maple_keyb_mutex);
237  return 0;
238 }
239 
240 static struct maple_driver dc_kbd_driver = {
241  .function = MAPLE_FUNC_KEYBOARD,
242  .drv = {
243  .name = "Dreamcast_keyboard",
244  .probe = probe_maple_kbd,
245  .remove = remove_maple_kbd,
246  },
247 };
248 
249 static int __init dc_kbd_init(void)
250 {
251  return maple_driver_register(&dc_kbd_driver);
252 }
253 
254 static void __exit dc_kbd_exit(void)
255 {
256  maple_driver_unregister(&dc_kbd_driver);
257 }
258 
259 module_init(dc_kbd_init);
260 module_exit(dc_kbd_exit);