diff options
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/keyboard/maple_keyb.c | 101 |
1 files changed, 32 insertions, 69 deletions
diff --git a/drivers/input/keyboard/maple_keyb.c b/drivers/input/keyboard/maple_keyb.c index 7d13f55b504e..42f5d4ec39ab 100644 --- a/drivers/input/keyboard/maple_keyb.c +++ b/drivers/input/keyboard/maple_keyb.c | |||
@@ -143,8 +143,8 @@ static void dc_kbd_callback(struct mapleq *mq) | |||
143 | unsigned long *buf = mq->recvbuf; | 143 | unsigned long *buf = mq->recvbuf; |
144 | 144 | ||
145 | /* | 145 | /* |
146 | * We should always be getting the lock because the only | 146 | * We should always get the lock because the only |
147 | * time it may be locked if driver is in cleanup phase. | 147 | * time it may be locked is if the driver is in the cleanup phase. |
148 | */ | 148 | */ |
149 | if (likely(mutex_trylock(&maple_keyb_mutex))) { | 149 | if (likely(mutex_trylock(&maple_keyb_mutex))) { |
150 | 150 | ||
@@ -157,103 +157,80 @@ static void dc_kbd_callback(struct mapleq *mq) | |||
157 | } | 157 | } |
158 | } | 158 | } |
159 | 159 | ||
160 | static int dc_kbd_connect(struct maple_device *mdev) | 160 | static int probe_maple_kbd(struct device *dev) |
161 | { | 161 | { |
162 | struct maple_device *mdev = to_maple_dev(dev); | ||
163 | struct maple_driver *mdrv = to_maple_driver(dev->driver); | ||
162 | int i, error; | 164 | int i, error; |
163 | struct dc_kbd *kbd; | 165 | struct dc_kbd *kbd; |
164 | struct input_dev *dev; | 166 | struct input_dev *idev; |
167 | |||
168 | if (!(mdev->function & MAPLE_FUNC_KEYBOARD)) | ||
169 | return -EINVAL; | ||
165 | 170 | ||
166 | kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL); | 171 | kbd = kzalloc(sizeof(struct dc_kbd), GFP_KERNEL); |
167 | if (!kbd) { | 172 | idev = input_allocate_device(); |
173 | if (!kbd || !idev) { | ||
168 | error = -ENOMEM; | 174 | error = -ENOMEM; |
169 | goto fail_kbd; | 175 | goto fail; |
170 | } | ||
171 | dev = input_allocate_device(); | ||
172 | if (!dev) { | ||
173 | error = -ENOMEM; | ||
174 | goto fail_dev; | ||
175 | } | 176 | } |
176 | 177 | ||
177 | mdev->private_data = kbd; | 178 | mdev->private_data = kbd; |
178 | 179 | ||
179 | kbd->dev = dev; | 180 | kbd->dev = idev; |
180 | memcpy(kbd->keycode, dc_kbd_keycode, sizeof(kbd->keycode)); | 181 | memcpy(kbd->keycode, dc_kbd_keycode, sizeof(kbd->keycode)); |
181 | 182 | ||
182 | dev->name = mdev->product_name; | 183 | idev->name = mdev->product_name; |
183 | dev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); | 184 | idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REP); |
184 | dev->keycode = kbd->keycode; | 185 | idev->keycode = kbd->keycode; |
185 | dev->keycodesize = sizeof(unsigned short); | 186 | idev->keycodesize = sizeof(unsigned short); |
186 | dev->keycodemax = ARRAY_SIZE(kbd->keycode); | 187 | idev->keycodemax = ARRAY_SIZE(kbd->keycode); |
187 | dev->id.bustype = BUS_HOST; | 188 | idev->id.bustype = BUS_HOST; |
188 | dev->dev.parent = &mdev->dev; | 189 | idev->dev.parent = &mdev->dev; |
189 | 190 | ||
190 | for (i = 0; i < NR_SCANCODES; i++) | 191 | for (i = 0; i < NR_SCANCODES; i++) |
191 | __set_bit(dc_kbd_keycode[i], dev->keybit); | 192 | __set_bit(dc_kbd_keycode[i], idev->keybit); |
192 | __clear_bit(KEY_RESERVED, dev->keybit); | 193 | __clear_bit(KEY_RESERVED, idev->keybit); |
193 | 194 | ||
194 | input_set_capability(dev, EV_MSC, MSC_SCAN); | 195 | input_set_capability(idev, EV_MSC, MSC_SCAN); |
195 | input_set_drvdata(dev, kbd); | 196 | input_set_drvdata(idev, kbd); |
196 | 197 | ||
197 | error = input_register_device(dev); | 198 | error = input_register_device(idev); |
198 | if (error) | 199 | if (error) |
199 | goto fail; | 200 | goto fail; |
200 | 201 | ||
201 | /* Maple polling is locked to VBLANK - which may be just 50/s */ | 202 | /* Maple polling is locked to VBLANK - which may be just 50/s */ |
202 | maple_getcond_callback(mdev, dc_kbd_callback, HZ/50, | 203 | maple_getcond_callback(mdev, dc_kbd_callback, HZ/50, |
203 | MAPLE_FUNC_KEYBOARD); | 204 | MAPLE_FUNC_KEYBOARD); |
204 | return 0; | 205 | |
206 | mdev->driver = mdrv; | ||
207 | return error; | ||
205 | 208 | ||
206 | fail: | 209 | fail: |
207 | input_free_device(dev); | 210 | input_free_device(idev); |
208 | fail_dev: | ||
209 | kfree(kbd); | 211 | kfree(kbd); |
210 | fail_kbd: | ||
211 | mdev->private_data = NULL; | 212 | mdev->private_data = NULL; |
212 | return error; | 213 | return error; |
213 | } | 214 | } |
214 | 215 | ||
215 | static void dc_kbd_disconnect(struct maple_device *mdev) | 216 | static int remove_maple_kbd(struct device *dev) |
216 | { | 217 | { |
218 | struct maple_device *mdev = to_maple_dev(dev); | ||
217 | struct dc_kbd *kbd; | 219 | struct dc_kbd *kbd; |
218 | 220 | ||
219 | mutex_lock(&maple_keyb_mutex); | 221 | mutex_lock(&maple_keyb_mutex); |
220 | mdev->callback = NULL; | 222 | |
221 | kbd = mdev->private_data; | 223 | kbd = mdev->private_data; |
222 | mdev->private_data = NULL; | 224 | mdev->private_data = NULL; |
223 | input_unregister_device(kbd->dev); | 225 | input_unregister_device(kbd->dev); |
224 | kfree(kbd); | 226 | kfree(kbd); |
225 | 227 | ||
226 | mutex_unlock(&maple_keyb_mutex); | 228 | mutex_unlock(&maple_keyb_mutex); |
227 | } | ||
228 | |||
229 | /* allow the keyboard to be used */ | ||
230 | static int probe_maple_kbd(struct device *dev) | ||
231 | { | ||
232 | struct maple_device *mdev = to_maple_dev(dev); | ||
233 | struct maple_driver *mdrv = to_maple_driver(dev->driver); | ||
234 | int error; | ||
235 | |||
236 | error = dc_kbd_connect(mdev); | ||
237 | if (error) | ||
238 | return error; | ||
239 | |||
240 | mdev->driver = mdrv; | ||
241 | |||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | static int remove_maple_kbd(struct device *dev) | ||
246 | { | ||
247 | struct maple_device *mdev = to_maple_dev(dev); | ||
248 | |||
249 | dc_kbd_disconnect(mdev); | ||
250 | return 0; | 229 | return 0; |
251 | } | 230 | } |
252 | 231 | ||
253 | static struct maple_driver dc_kbd_driver = { | 232 | static struct maple_driver dc_kbd_driver = { |
254 | .function = MAPLE_FUNC_KEYBOARD, | 233 | .function = MAPLE_FUNC_KEYBOARD, |
255 | .connect = dc_kbd_connect, | ||
256 | .disconnect = dc_kbd_disconnect, | ||
257 | .drv = { | 234 | .drv = { |
258 | .name = "Dreamcast_keyboard", | 235 | .name = "Dreamcast_keyboard", |
259 | .probe = probe_maple_kbd, | 236 | .probe = probe_maple_kbd, |
@@ -261,19 +238,6 @@ static struct maple_driver dc_kbd_driver = { | |||
261 | }, | 238 | }, |
262 | }; | 239 | }; |
263 | 240 | ||
264 | static int unplug_maple_keyb(struct device *dev, void *ignored) | ||
265 | { | ||
266 | /* Please DO NOT really unplug your keyboard */ | ||
267 | struct maple_device *mdev; | ||
268 | |||
269 | mdev = to_maple_dev(dev); | ||
270 | if ((mdev->function & MAPLE_FUNC_KEYBOARD) | ||
271 | && (mdev->driver == &dc_kbd_driver)) | ||
272 | remove_maple_kbd(dev); | ||
273 | |||
274 | return 0; | ||
275 | } | ||
276 | |||
277 | static int __init dc_kbd_init(void) | 241 | static int __init dc_kbd_init(void) |
278 | { | 242 | { |
279 | return maple_driver_register(&dc_kbd_driver.drv); | 243 | return maple_driver_register(&dc_kbd_driver.drv); |
@@ -281,7 +245,6 @@ static int __init dc_kbd_init(void) | |||
281 | 245 | ||
282 | static void __exit dc_kbd_exit(void) | 246 | static void __exit dc_kbd_exit(void) |
283 | { | 247 | { |
284 | bus_for_each_dev(&maple_bus_type, NULL, NULL, unplug_maple_keyb); | ||
285 | driver_unregister(&dc_kbd_driver.drv); | 248 | driver_unregister(&dc_kbd_driver.drv); |
286 | } | 249 | } |
287 | 250 | ||