Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/input/joydev.c
15109 views
1
/*
2
* Joystick device driver for the input driver suite.
3
*
4
* Copyright (c) 1999-2002 Vojtech Pavlik
5
* Copyright (c) 1999 Colin Van Dyke
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
13
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
15
#include <asm/io.h>
16
#include <asm/system.h>
17
#include <linux/delay.h>
18
#include <linux/errno.h>
19
#include <linux/joystick.h>
20
#include <linux/input.h>
21
#include <linux/kernel.h>
22
#include <linux/major.h>
23
#include <linux/sched.h>
24
#include <linux/slab.h>
25
#include <linux/mm.h>
26
#include <linux/miscdevice.h>
27
#include <linux/module.h>
28
#include <linux/poll.h>
29
#include <linux/init.h>
30
#include <linux/device.h>
31
32
MODULE_AUTHOR("Vojtech Pavlik <[email protected]>");
33
MODULE_DESCRIPTION("Joystick device interfaces");
34
MODULE_SUPPORTED_DEVICE("input/js");
35
MODULE_LICENSE("GPL");
36
37
#define JOYDEV_MINOR_BASE 0
38
#define JOYDEV_MINORS 16
39
#define JOYDEV_BUFFER_SIZE 64
40
41
struct joydev {
42
int open;
43
int minor;
44
struct input_handle handle;
45
wait_queue_head_t wait;
46
struct list_head client_list;
47
spinlock_t client_lock; /* protects client_list */
48
struct mutex mutex;
49
struct device dev;
50
bool exist;
51
52
struct js_corr corr[ABS_CNT];
53
struct JS_DATA_SAVE_TYPE glue;
54
int nabs;
55
int nkey;
56
__u16 keymap[KEY_MAX - BTN_MISC + 1];
57
__u16 keypam[KEY_MAX - BTN_MISC + 1];
58
__u8 absmap[ABS_CNT];
59
__u8 abspam[ABS_CNT];
60
__s16 abs[ABS_CNT];
61
};
62
63
struct joydev_client {
64
struct js_event buffer[JOYDEV_BUFFER_SIZE];
65
int head;
66
int tail;
67
int startup;
68
spinlock_t buffer_lock; /* protects access to buffer, head and tail */
69
struct fasync_struct *fasync;
70
struct joydev *joydev;
71
struct list_head node;
72
};
73
74
static struct joydev *joydev_table[JOYDEV_MINORS];
75
static DEFINE_MUTEX(joydev_table_mutex);
76
77
static int joydev_correct(int value, struct js_corr *corr)
78
{
79
switch (corr->type) {
80
81
case JS_CORR_NONE:
82
break;
83
84
case JS_CORR_BROKEN:
85
value = value > corr->coef[0] ? (value < corr->coef[1] ? 0 :
86
((corr->coef[3] * (value - corr->coef[1])) >> 14)) :
87
((corr->coef[2] * (value - corr->coef[0])) >> 14);
88
break;
89
90
default:
91
return 0;
92
}
93
94
return value < -32767 ? -32767 : (value > 32767 ? 32767 : value);
95
}
96
97
static void joydev_pass_event(struct joydev_client *client,
98
struct js_event *event)
99
{
100
struct joydev *joydev = client->joydev;
101
102
/*
103
* IRQs already disabled, just acquire the lock
104
*/
105
spin_lock(&client->buffer_lock);
106
107
client->buffer[client->head] = *event;
108
109
if (client->startup == joydev->nabs + joydev->nkey) {
110
client->head++;
111
client->head &= JOYDEV_BUFFER_SIZE - 1;
112
if (client->tail == client->head)
113
client->startup = 0;
114
}
115
116
spin_unlock(&client->buffer_lock);
117
118
kill_fasync(&client->fasync, SIGIO, POLL_IN);
119
}
120
121
static void joydev_event(struct input_handle *handle,
122
unsigned int type, unsigned int code, int value)
123
{
124
struct joydev *joydev = handle->private;
125
struct joydev_client *client;
126
struct js_event event;
127
128
switch (type) {
129
130
case EV_KEY:
131
if (code < BTN_MISC || value == 2)
132
return;
133
event.type = JS_EVENT_BUTTON;
134
event.number = joydev->keymap[code - BTN_MISC];
135
event.value = value;
136
break;
137
138
case EV_ABS:
139
event.type = JS_EVENT_AXIS;
140
event.number = joydev->absmap[code];
141
event.value = joydev_correct(value,
142
&joydev->corr[event.number]);
143
if (event.value == joydev->abs[event.number])
144
return;
145
joydev->abs[event.number] = event.value;
146
break;
147
148
default:
149
return;
150
}
151
152
event.time = jiffies_to_msecs(jiffies);
153
154
rcu_read_lock();
155
list_for_each_entry_rcu(client, &joydev->client_list, node)
156
joydev_pass_event(client, &event);
157
rcu_read_unlock();
158
159
wake_up_interruptible(&joydev->wait);
160
}
161
162
static int joydev_fasync(int fd, struct file *file, int on)
163
{
164
struct joydev_client *client = file->private_data;
165
166
return fasync_helper(fd, file, on, &client->fasync);
167
}
168
169
static void joydev_free(struct device *dev)
170
{
171
struct joydev *joydev = container_of(dev, struct joydev, dev);
172
173
input_put_device(joydev->handle.dev);
174
kfree(joydev);
175
}
176
177
static void joydev_attach_client(struct joydev *joydev,
178
struct joydev_client *client)
179
{
180
spin_lock(&joydev->client_lock);
181
list_add_tail_rcu(&client->node, &joydev->client_list);
182
spin_unlock(&joydev->client_lock);
183
}
184
185
static void joydev_detach_client(struct joydev *joydev,
186
struct joydev_client *client)
187
{
188
spin_lock(&joydev->client_lock);
189
list_del_rcu(&client->node);
190
spin_unlock(&joydev->client_lock);
191
synchronize_rcu();
192
}
193
194
static int joydev_open_device(struct joydev *joydev)
195
{
196
int retval;
197
198
retval = mutex_lock_interruptible(&joydev->mutex);
199
if (retval)
200
return retval;
201
202
if (!joydev->exist)
203
retval = -ENODEV;
204
else if (!joydev->open++) {
205
retval = input_open_device(&joydev->handle);
206
if (retval)
207
joydev->open--;
208
}
209
210
mutex_unlock(&joydev->mutex);
211
return retval;
212
}
213
214
static void joydev_close_device(struct joydev *joydev)
215
{
216
mutex_lock(&joydev->mutex);
217
218
if (joydev->exist && !--joydev->open)
219
input_close_device(&joydev->handle);
220
221
mutex_unlock(&joydev->mutex);
222
}
223
224
/*
225
* Wake up users waiting for IO so they can disconnect from
226
* dead device.
227
*/
228
static void joydev_hangup(struct joydev *joydev)
229
{
230
struct joydev_client *client;
231
232
spin_lock(&joydev->client_lock);
233
list_for_each_entry(client, &joydev->client_list, node)
234
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
235
spin_unlock(&joydev->client_lock);
236
237
wake_up_interruptible(&joydev->wait);
238
}
239
240
static int joydev_release(struct inode *inode, struct file *file)
241
{
242
struct joydev_client *client = file->private_data;
243
struct joydev *joydev = client->joydev;
244
245
joydev_detach_client(joydev, client);
246
kfree(client);
247
248
joydev_close_device(joydev);
249
put_device(&joydev->dev);
250
251
return 0;
252
}
253
254
static int joydev_open(struct inode *inode, struct file *file)
255
{
256
struct joydev_client *client;
257
struct joydev *joydev;
258
int i = iminor(inode) - JOYDEV_MINOR_BASE;
259
int error;
260
261
if (i >= JOYDEV_MINORS)
262
return -ENODEV;
263
264
error = mutex_lock_interruptible(&joydev_table_mutex);
265
if (error)
266
return error;
267
joydev = joydev_table[i];
268
if (joydev)
269
get_device(&joydev->dev);
270
mutex_unlock(&joydev_table_mutex);
271
272
if (!joydev)
273
return -ENODEV;
274
275
client = kzalloc(sizeof(struct joydev_client), GFP_KERNEL);
276
if (!client) {
277
error = -ENOMEM;
278
goto err_put_joydev;
279
}
280
281
spin_lock_init(&client->buffer_lock);
282
client->joydev = joydev;
283
joydev_attach_client(joydev, client);
284
285
error = joydev_open_device(joydev);
286
if (error)
287
goto err_free_client;
288
289
file->private_data = client;
290
nonseekable_open(inode, file);
291
292
return 0;
293
294
err_free_client:
295
joydev_detach_client(joydev, client);
296
kfree(client);
297
err_put_joydev:
298
put_device(&joydev->dev);
299
return error;
300
}
301
302
static int joydev_generate_startup_event(struct joydev_client *client,
303
struct input_dev *input,
304
struct js_event *event)
305
{
306
struct joydev *joydev = client->joydev;
307
int have_event;
308
309
spin_lock_irq(&client->buffer_lock);
310
311
have_event = client->startup < joydev->nabs + joydev->nkey;
312
313
if (have_event) {
314
315
event->time = jiffies_to_msecs(jiffies);
316
if (client->startup < joydev->nkey) {
317
event->type = JS_EVENT_BUTTON | JS_EVENT_INIT;
318
event->number = client->startup;
319
event->value = !!test_bit(joydev->keypam[event->number],
320
input->key);
321
} else {
322
event->type = JS_EVENT_AXIS | JS_EVENT_INIT;
323
event->number = client->startup - joydev->nkey;
324
event->value = joydev->abs[event->number];
325
}
326
client->startup++;
327
}
328
329
spin_unlock_irq(&client->buffer_lock);
330
331
return have_event;
332
}
333
334
static int joydev_fetch_next_event(struct joydev_client *client,
335
struct js_event *event)
336
{
337
int have_event;
338
339
spin_lock_irq(&client->buffer_lock);
340
341
have_event = client->head != client->tail;
342
if (have_event) {
343
*event = client->buffer[client->tail++];
344
client->tail &= JOYDEV_BUFFER_SIZE - 1;
345
}
346
347
spin_unlock_irq(&client->buffer_lock);
348
349
return have_event;
350
}
351
352
/*
353
* Old joystick interface
354
*/
355
static ssize_t joydev_0x_read(struct joydev_client *client,
356
struct input_dev *input,
357
char __user *buf)
358
{
359
struct joydev *joydev = client->joydev;
360
struct JS_DATA_TYPE data;
361
int i;
362
363
spin_lock_irq(&input->event_lock);
364
365
/*
366
* Get device state
367
*/
368
for (data.buttons = i = 0; i < 32 && i < joydev->nkey; i++)
369
data.buttons |=
370
test_bit(joydev->keypam[i], input->key) ? (1 << i) : 0;
371
data.x = (joydev->abs[0] / 256 + 128) >> joydev->glue.JS_CORR.x;
372
data.y = (joydev->abs[1] / 256 + 128) >> joydev->glue.JS_CORR.y;
373
374
/*
375
* Reset reader's event queue
376
*/
377
spin_lock(&client->buffer_lock);
378
client->startup = 0;
379
client->tail = client->head;
380
spin_unlock(&client->buffer_lock);
381
382
spin_unlock_irq(&input->event_lock);
383
384
if (copy_to_user(buf, &data, sizeof(struct JS_DATA_TYPE)))
385
return -EFAULT;
386
387
return sizeof(struct JS_DATA_TYPE);
388
}
389
390
static inline int joydev_data_pending(struct joydev_client *client)
391
{
392
struct joydev *joydev = client->joydev;
393
394
return client->startup < joydev->nabs + joydev->nkey ||
395
client->head != client->tail;
396
}
397
398
static ssize_t joydev_read(struct file *file, char __user *buf,
399
size_t count, loff_t *ppos)
400
{
401
struct joydev_client *client = file->private_data;
402
struct joydev *joydev = client->joydev;
403
struct input_dev *input = joydev->handle.dev;
404
struct js_event event;
405
int retval;
406
407
if (!joydev->exist)
408
return -ENODEV;
409
410
if (count < sizeof(struct js_event))
411
return -EINVAL;
412
413
if (count == sizeof(struct JS_DATA_TYPE))
414
return joydev_0x_read(client, input, buf);
415
416
if (!joydev_data_pending(client) && (file->f_flags & O_NONBLOCK))
417
return -EAGAIN;
418
419
retval = wait_event_interruptible(joydev->wait,
420
!joydev->exist || joydev_data_pending(client));
421
if (retval)
422
return retval;
423
424
if (!joydev->exist)
425
return -ENODEV;
426
427
while (retval + sizeof(struct js_event) <= count &&
428
joydev_generate_startup_event(client, input, &event)) {
429
430
if (copy_to_user(buf + retval, &event, sizeof(struct js_event)))
431
return -EFAULT;
432
433
retval += sizeof(struct js_event);
434
}
435
436
while (retval + sizeof(struct js_event) <= count &&
437
joydev_fetch_next_event(client, &event)) {
438
439
if (copy_to_user(buf + retval, &event, sizeof(struct js_event)))
440
return -EFAULT;
441
442
retval += sizeof(struct js_event);
443
}
444
445
return retval;
446
}
447
448
/* No kernel lock - fine */
449
static unsigned int joydev_poll(struct file *file, poll_table *wait)
450
{
451
struct joydev_client *client = file->private_data;
452
struct joydev *joydev = client->joydev;
453
454
poll_wait(file, &joydev->wait, wait);
455
return (joydev_data_pending(client) ? (POLLIN | POLLRDNORM) : 0) |
456
(joydev->exist ? 0 : (POLLHUP | POLLERR));
457
}
458
459
static int joydev_handle_JSIOCSAXMAP(struct joydev *joydev,
460
void __user *argp, size_t len)
461
{
462
__u8 *abspam;
463
int i;
464
int retval = 0;
465
466
len = min(len, sizeof(joydev->abspam));
467
468
/* Validate the map. */
469
abspam = kmalloc(len, GFP_KERNEL);
470
if (!abspam)
471
return -ENOMEM;
472
473
if (copy_from_user(abspam, argp, len)) {
474
retval = -EFAULT;
475
goto out;
476
}
477
478
for (i = 0; i < joydev->nabs; i++) {
479
if (abspam[i] > ABS_MAX) {
480
retval = -EINVAL;
481
goto out;
482
}
483
}
484
485
memcpy(joydev->abspam, abspam, len);
486
487
for (i = 0; i < joydev->nabs; i++)
488
joydev->absmap[joydev->abspam[i]] = i;
489
490
out:
491
kfree(abspam);
492
return retval;
493
}
494
495
static int joydev_handle_JSIOCSBTNMAP(struct joydev *joydev,
496
void __user *argp, size_t len)
497
{
498
__u16 *keypam;
499
int i;
500
int retval = 0;
501
502
len = min(len, sizeof(joydev->keypam));
503
504
/* Validate the map. */
505
keypam = kmalloc(len, GFP_KERNEL);
506
if (!keypam)
507
return -ENOMEM;
508
509
if (copy_from_user(keypam, argp, len)) {
510
retval = -EFAULT;
511
goto out;
512
}
513
514
for (i = 0; i < joydev->nkey; i++) {
515
if (keypam[i] > KEY_MAX || keypam[i] < BTN_MISC) {
516
retval = -EINVAL;
517
goto out;
518
}
519
}
520
521
memcpy(joydev->keypam, keypam, len);
522
523
for (i = 0; i < joydev->nkey; i++)
524
joydev->keymap[keypam[i] - BTN_MISC] = i;
525
526
out:
527
kfree(keypam);
528
return retval;
529
}
530
531
532
static int joydev_ioctl_common(struct joydev *joydev,
533
unsigned int cmd, void __user *argp)
534
{
535
struct input_dev *dev = joydev->handle.dev;
536
size_t len;
537
int i;
538
const char *name;
539
540
/* Process fixed-sized commands. */
541
switch (cmd) {
542
543
case JS_SET_CAL:
544
return copy_from_user(&joydev->glue.JS_CORR, argp,
545
sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0;
546
547
case JS_GET_CAL:
548
return copy_to_user(argp, &joydev->glue.JS_CORR,
549
sizeof(joydev->glue.JS_CORR)) ? -EFAULT : 0;
550
551
case JS_SET_TIMEOUT:
552
return get_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
553
554
case JS_GET_TIMEOUT:
555
return put_user(joydev->glue.JS_TIMEOUT, (s32 __user *) argp);
556
557
case JSIOCGVERSION:
558
return put_user(JS_VERSION, (__u32 __user *) argp);
559
560
case JSIOCGAXES:
561
return put_user(joydev->nabs, (__u8 __user *) argp);
562
563
case JSIOCGBUTTONS:
564
return put_user(joydev->nkey, (__u8 __user *) argp);
565
566
case JSIOCSCORR:
567
if (copy_from_user(joydev->corr, argp,
568
sizeof(joydev->corr[0]) * joydev->nabs))
569
return -EFAULT;
570
571
for (i = 0; i < joydev->nabs; i++) {
572
int val = input_abs_get_val(dev, joydev->abspam[i]);
573
joydev->abs[i] = joydev_correct(val, &joydev->corr[i]);
574
}
575
return 0;
576
577
case JSIOCGCORR:
578
return copy_to_user(argp, joydev->corr,
579
sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0;
580
581
}
582
583
/*
584
* Process variable-sized commands (the axis and button map commands
585
* are considered variable-sized to decouple them from the values of
586
* ABS_MAX and KEY_MAX).
587
*/
588
switch (cmd & ~IOCSIZE_MASK) {
589
590
case (JSIOCSAXMAP & ~IOCSIZE_MASK):
591
return joydev_handle_JSIOCSAXMAP(joydev, argp, _IOC_SIZE(cmd));
592
593
case (JSIOCGAXMAP & ~IOCSIZE_MASK):
594
len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->abspam));
595
return copy_to_user(argp, joydev->abspam, len) ? -EFAULT : len;
596
597
case (JSIOCSBTNMAP & ~IOCSIZE_MASK):
598
return joydev_handle_JSIOCSBTNMAP(joydev, argp, _IOC_SIZE(cmd));
599
600
case (JSIOCGBTNMAP & ~IOCSIZE_MASK):
601
len = min_t(size_t, _IOC_SIZE(cmd), sizeof(joydev->keypam));
602
return copy_to_user(argp, joydev->keypam, len) ? -EFAULT : len;
603
604
case JSIOCGNAME(0):
605
name = dev->name;
606
if (!name)
607
return 0;
608
609
len = min_t(size_t, _IOC_SIZE(cmd), strlen(name) + 1);
610
return copy_to_user(argp, name, len) ? -EFAULT : len;
611
}
612
613
return -EINVAL;
614
}
615
616
#ifdef CONFIG_COMPAT
617
static long joydev_compat_ioctl(struct file *file,
618
unsigned int cmd, unsigned long arg)
619
{
620
struct joydev_client *client = file->private_data;
621
struct joydev *joydev = client->joydev;
622
void __user *argp = (void __user *)arg;
623
s32 tmp32;
624
struct JS_DATA_SAVE_TYPE_32 ds32;
625
int retval;
626
627
retval = mutex_lock_interruptible(&joydev->mutex);
628
if (retval)
629
return retval;
630
631
if (!joydev->exist) {
632
retval = -ENODEV;
633
goto out;
634
}
635
636
switch (cmd) {
637
638
case JS_SET_TIMELIMIT:
639
retval = get_user(tmp32, (s32 __user *) arg);
640
if (retval == 0)
641
joydev->glue.JS_TIMELIMIT = tmp32;
642
break;
643
644
case JS_GET_TIMELIMIT:
645
tmp32 = joydev->glue.JS_TIMELIMIT;
646
retval = put_user(tmp32, (s32 __user *) arg);
647
break;
648
649
case JS_SET_ALL:
650
retval = copy_from_user(&ds32, argp,
651
sizeof(ds32)) ? -EFAULT : 0;
652
if (retval == 0) {
653
joydev->glue.JS_TIMEOUT = ds32.JS_TIMEOUT;
654
joydev->glue.BUSY = ds32.BUSY;
655
joydev->glue.JS_EXPIRETIME = ds32.JS_EXPIRETIME;
656
joydev->glue.JS_TIMELIMIT = ds32.JS_TIMELIMIT;
657
joydev->glue.JS_SAVE = ds32.JS_SAVE;
658
joydev->glue.JS_CORR = ds32.JS_CORR;
659
}
660
break;
661
662
case JS_GET_ALL:
663
ds32.JS_TIMEOUT = joydev->glue.JS_TIMEOUT;
664
ds32.BUSY = joydev->glue.BUSY;
665
ds32.JS_EXPIRETIME = joydev->glue.JS_EXPIRETIME;
666
ds32.JS_TIMELIMIT = joydev->glue.JS_TIMELIMIT;
667
ds32.JS_SAVE = joydev->glue.JS_SAVE;
668
ds32.JS_CORR = joydev->glue.JS_CORR;
669
670
retval = copy_to_user(argp, &ds32, sizeof(ds32)) ? -EFAULT : 0;
671
break;
672
673
default:
674
retval = joydev_ioctl_common(joydev, cmd, argp);
675
break;
676
}
677
678
out:
679
mutex_unlock(&joydev->mutex);
680
return retval;
681
}
682
#endif /* CONFIG_COMPAT */
683
684
static long joydev_ioctl(struct file *file,
685
unsigned int cmd, unsigned long arg)
686
{
687
struct joydev_client *client = file->private_data;
688
struct joydev *joydev = client->joydev;
689
void __user *argp = (void __user *)arg;
690
int retval;
691
692
retval = mutex_lock_interruptible(&joydev->mutex);
693
if (retval)
694
return retval;
695
696
if (!joydev->exist) {
697
retval = -ENODEV;
698
goto out;
699
}
700
701
switch (cmd) {
702
703
case JS_SET_TIMELIMIT:
704
retval = get_user(joydev->glue.JS_TIMELIMIT,
705
(long __user *) arg);
706
break;
707
708
case JS_GET_TIMELIMIT:
709
retval = put_user(joydev->glue.JS_TIMELIMIT,
710
(long __user *) arg);
711
break;
712
713
case JS_SET_ALL:
714
retval = copy_from_user(&joydev->glue, argp,
715
sizeof(joydev->glue)) ? -EFAULT: 0;
716
break;
717
718
case JS_GET_ALL:
719
retval = copy_to_user(argp, &joydev->glue,
720
sizeof(joydev->glue)) ? -EFAULT : 0;
721
break;
722
723
default:
724
retval = joydev_ioctl_common(joydev, cmd, argp);
725
break;
726
}
727
out:
728
mutex_unlock(&joydev->mutex);
729
return retval;
730
}
731
732
static const struct file_operations joydev_fops = {
733
.owner = THIS_MODULE,
734
.read = joydev_read,
735
.poll = joydev_poll,
736
.open = joydev_open,
737
.release = joydev_release,
738
.unlocked_ioctl = joydev_ioctl,
739
#ifdef CONFIG_COMPAT
740
.compat_ioctl = joydev_compat_ioctl,
741
#endif
742
.fasync = joydev_fasync,
743
.llseek = no_llseek,
744
};
745
746
static int joydev_install_chrdev(struct joydev *joydev)
747
{
748
joydev_table[joydev->minor] = joydev;
749
return 0;
750
}
751
752
static void joydev_remove_chrdev(struct joydev *joydev)
753
{
754
mutex_lock(&joydev_table_mutex);
755
joydev_table[joydev->minor] = NULL;
756
mutex_unlock(&joydev_table_mutex);
757
}
758
759
/*
760
* Mark device non-existent. This disables writes, ioctls and
761
* prevents new users from opening the device. Already posted
762
* blocking reads will stay, however new ones will fail.
763
*/
764
static void joydev_mark_dead(struct joydev *joydev)
765
{
766
mutex_lock(&joydev->mutex);
767
joydev->exist = false;
768
mutex_unlock(&joydev->mutex);
769
}
770
771
static void joydev_cleanup(struct joydev *joydev)
772
{
773
struct input_handle *handle = &joydev->handle;
774
775
joydev_mark_dead(joydev);
776
joydev_hangup(joydev);
777
joydev_remove_chrdev(joydev);
778
779
/* joydev is marked dead so no one else accesses joydev->open */
780
if (joydev->open)
781
input_close_device(handle);
782
}
783
784
785
static bool joydev_match(struct input_handler *handler, struct input_dev *dev)
786
{
787
/* Avoid touchpads and touchscreens */
788
if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_TOUCH, dev->keybit))
789
return false;
790
791
/* Avoid tablets, digitisers and similar devices */
792
if (test_bit(EV_KEY, dev->evbit) && test_bit(BTN_DIGI, dev->keybit))
793
return false;
794
795
return true;
796
}
797
798
static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
799
const struct input_device_id *id)
800
{
801
struct joydev *joydev;
802
int i, j, t, minor;
803
int error;
804
805
for (minor = 0; minor < JOYDEV_MINORS; minor++)
806
if (!joydev_table[minor])
807
break;
808
809
if (minor == JOYDEV_MINORS) {
810
pr_err("no more free joydev devices\n");
811
return -ENFILE;
812
}
813
814
joydev = kzalloc(sizeof(struct joydev), GFP_KERNEL);
815
if (!joydev)
816
return -ENOMEM;
817
818
INIT_LIST_HEAD(&joydev->client_list);
819
spin_lock_init(&joydev->client_lock);
820
mutex_init(&joydev->mutex);
821
init_waitqueue_head(&joydev->wait);
822
823
dev_set_name(&joydev->dev, "js%d", minor);
824
joydev->exist = true;
825
joydev->minor = minor;
826
827
joydev->handle.dev = input_get_device(dev);
828
joydev->handle.name = dev_name(&joydev->dev);
829
joydev->handle.handler = handler;
830
joydev->handle.private = joydev;
831
832
for (i = 0; i < ABS_CNT; i++)
833
if (test_bit(i, dev->absbit)) {
834
joydev->absmap[i] = joydev->nabs;
835
joydev->abspam[joydev->nabs] = i;
836
joydev->nabs++;
837
}
838
839
for (i = BTN_JOYSTICK - BTN_MISC; i < KEY_MAX - BTN_MISC + 1; i++)
840
if (test_bit(i + BTN_MISC, dev->keybit)) {
841
joydev->keymap[i] = joydev->nkey;
842
joydev->keypam[joydev->nkey] = i + BTN_MISC;
843
joydev->nkey++;
844
}
845
846
for (i = 0; i < BTN_JOYSTICK - BTN_MISC; i++)
847
if (test_bit(i + BTN_MISC, dev->keybit)) {
848
joydev->keymap[i] = joydev->nkey;
849
joydev->keypam[joydev->nkey] = i + BTN_MISC;
850
joydev->nkey++;
851
}
852
853
for (i = 0; i < joydev->nabs; i++) {
854
j = joydev->abspam[i];
855
if (input_abs_get_max(dev, j) == input_abs_get_min(dev, j)) {
856
joydev->corr[i].type = JS_CORR_NONE;
857
joydev->abs[i] = input_abs_get_val(dev, j);
858
continue;
859
}
860
joydev->corr[i].type = JS_CORR_BROKEN;
861
joydev->corr[i].prec = input_abs_get_fuzz(dev, j);
862
863
t = (input_abs_get_max(dev, j) + input_abs_get_min(dev, j)) / 2;
864
joydev->corr[i].coef[0] = t - input_abs_get_flat(dev, j);
865
joydev->corr[i].coef[1] = t + input_abs_get_flat(dev, j);
866
867
t = (input_abs_get_max(dev, j) - input_abs_get_min(dev, j)) / 2
868
- 2 * input_abs_get_flat(dev, j);
869
if (t) {
870
joydev->corr[i].coef[2] = (1 << 29) / t;
871
joydev->corr[i].coef[3] = (1 << 29) / t;
872
873
joydev->abs[i] =
874
joydev_correct(input_abs_get_val(dev, j),
875
joydev->corr + i);
876
}
877
}
878
879
joydev->dev.devt = MKDEV(INPUT_MAJOR, JOYDEV_MINOR_BASE + minor);
880
joydev->dev.class = &input_class;
881
joydev->dev.parent = &dev->dev;
882
joydev->dev.release = joydev_free;
883
device_initialize(&joydev->dev);
884
885
error = input_register_handle(&joydev->handle);
886
if (error)
887
goto err_free_joydev;
888
889
error = joydev_install_chrdev(joydev);
890
if (error)
891
goto err_unregister_handle;
892
893
error = device_add(&joydev->dev);
894
if (error)
895
goto err_cleanup_joydev;
896
897
return 0;
898
899
err_cleanup_joydev:
900
joydev_cleanup(joydev);
901
err_unregister_handle:
902
input_unregister_handle(&joydev->handle);
903
err_free_joydev:
904
put_device(&joydev->dev);
905
return error;
906
}
907
908
static void joydev_disconnect(struct input_handle *handle)
909
{
910
struct joydev *joydev = handle->private;
911
912
device_del(&joydev->dev);
913
joydev_cleanup(joydev);
914
input_unregister_handle(handle);
915
put_device(&joydev->dev);
916
}
917
918
static const struct input_device_id joydev_ids[] = {
919
{
920
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
921
INPUT_DEVICE_ID_MATCH_ABSBIT,
922
.evbit = { BIT_MASK(EV_ABS) },
923
.absbit = { BIT_MASK(ABS_X) },
924
},
925
{
926
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
927
INPUT_DEVICE_ID_MATCH_ABSBIT,
928
.evbit = { BIT_MASK(EV_ABS) },
929
.absbit = { BIT_MASK(ABS_WHEEL) },
930
},
931
{
932
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
933
INPUT_DEVICE_ID_MATCH_ABSBIT,
934
.evbit = { BIT_MASK(EV_ABS) },
935
.absbit = { BIT_MASK(ABS_THROTTLE) },
936
},
937
{
938
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
939
INPUT_DEVICE_ID_MATCH_KEYBIT,
940
.evbit = { BIT_MASK(EV_KEY) },
941
.keybit = {[BIT_WORD(BTN_JOYSTICK)] = BIT_MASK(BTN_JOYSTICK) },
942
},
943
{
944
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
945
INPUT_DEVICE_ID_MATCH_KEYBIT,
946
.evbit = { BIT_MASK(EV_KEY) },
947
.keybit = { [BIT_WORD(BTN_GAMEPAD)] = BIT_MASK(BTN_GAMEPAD) },
948
},
949
{
950
.flags = INPUT_DEVICE_ID_MATCH_EVBIT |
951
INPUT_DEVICE_ID_MATCH_KEYBIT,
952
.evbit = { BIT_MASK(EV_KEY) },
953
.keybit = { [BIT_WORD(BTN_TRIGGER_HAPPY)] = BIT_MASK(BTN_TRIGGER_HAPPY) },
954
},
955
{ } /* Terminating entry */
956
};
957
958
MODULE_DEVICE_TABLE(input, joydev_ids);
959
960
static struct input_handler joydev_handler = {
961
.event = joydev_event,
962
.match = joydev_match,
963
.connect = joydev_connect,
964
.disconnect = joydev_disconnect,
965
.fops = &joydev_fops,
966
.minor = JOYDEV_MINOR_BASE,
967
.name = "joydev",
968
.id_table = joydev_ids,
969
};
970
971
static int __init joydev_init(void)
972
{
973
return input_register_handler(&joydev_handler);
974
}
975
976
static void __exit joydev_exit(void)
977
{
978
input_unregister_handler(&joydev_handler);
979
}
980
981
module_init(joydev_init);
982
module_exit(joydev_exit);
983
984