1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/fb.h>
15#include <linux/input.h>
16#include <linux/kernel.h>
17#include <linux/module.h>
18#include <linux/uuid.h>
19#include <linux/visorbus.h>
20
21
22
23
24
25#define INPUTACTION_XY_MOTION 1
26
27
28#define INPUTACTION_MOUSE_BUTTON_DOWN 2
29#define INPUTACTION_MOUSE_BUTTON_UP 3
30#define INPUTACTION_MOUSE_BUTTON_CLICK 4
31#define INPUTACTION_MOUSE_BUTTON_DCLICK 5
32
33
34#define INPUTACTION_WHEEL_ROTATE_AWAY 6
35#define INPUTACTION_WHEEL_ROTATE_TOWARD 7
36
37
38
39
40
41
42#define INPUTACTION_KEY_DOWN 64
43#define INPUTACTION_KEY_UP 65
44#define INPUTACTION_KEY_DOWN_UP 67
45
46
47
48
49
50#define INPUTACTION_SET_LOCKING_KEY_STATE 66
51
52
53#define VISOR_KEYBOARD_CHANNEL_GUID \
54 GUID_INIT(0xc73416d0, 0xb0b8, 0x44af, \
55 0xb3, 0x4, 0x9d, 0x2a, 0xe9, 0x9f, 0x1b, 0x3d)
56#define VISOR_KEYBOARD_CHANNEL_GUID_STR "c73416d0-b0b8-44af-b304-9d2ae99f1b3d"
57
58
59#define VISOR_MOUSE_CHANNEL_GUID \
60 GUID_INIT(0xaddf07d4, 0x94a9, 0x46e2, \
61 0x81, 0xc3, 0x61, 0xab, 0xcd, 0xbd, 0xbd, 0x87)
62#define VISOR_MOUSE_CHANNEL_GUID_STR "addf07d4-94a9-46e2-81c3-61abcdbdbd87"
63
64#define PIXELS_ACROSS_DEFAULT 1024
65#define PIXELS_DOWN_DEFAULT 768
66#define KEYCODE_TABLE_BYTES 256
67
68struct visor_inputactivity {
69 u16 action;
70 u16 arg1;
71 u16 arg2;
72 u16 arg3;
73} __packed;
74
75struct visor_inputreport {
76 u64 seq_no;
77 struct visor_inputactivity activity;
78} __packed;
79
80
81struct visor_input_channel_data {
82 u32 n_input_reports;
83 union {
84 struct {
85 u16 x_res;
86 u16 y_res;
87 } mouse;
88 struct {
89 u32 flags;
90 } keyboard;
91 };
92} __packed;
93
94enum visorinput_dev_type {
95 visorinput_keyboard,
96 visorinput_mouse,
97};
98
99
100
101
102
103
104struct visorinput_devdata {
105 struct visor_device *dev;
106
107 struct mutex lock_visor_dev;
108 struct input_dev *visorinput_dev;
109 bool paused;
110 bool interrupts_enabled;
111
112 unsigned int keycode_table_bytes;
113
114 unsigned char keycode_table[];
115};
116
117static const guid_t visor_keyboard_channel_guid = VISOR_KEYBOARD_CHANNEL_GUID;
118static const guid_t visor_mouse_channel_guid = VISOR_MOUSE_CHANNEL_GUID;
119
120
121
122
123
124static const unsigned char visorkbd_keycode[KEYCODE_TABLE_BYTES] = {
125
126 [0] = KEY_GRAVE,
127 [1] = KEY_ESC,
128 [2] = KEY_1,
129 [3] = KEY_2,
130 [4] = KEY_3,
131 [5] = KEY_4,
132 [6] = KEY_5,
133 [7] = KEY_6,
134 [8] = KEY_7,
135 [9] = KEY_8,
136 [10] = KEY_9,
137 [11] = KEY_0,
138 [12] = KEY_MINUS,
139 [13] = KEY_EQUAL,
140 [14] = KEY_BACKSPACE,
141 [15] = KEY_TAB,
142 [16] = KEY_Q,
143 [17] = KEY_W,
144 [18] = KEY_E,
145 [19] = KEY_R,
146 [20] = KEY_T,
147 [21] = KEY_Y,
148 [22] = KEY_U,
149 [23] = KEY_I,
150 [24] = KEY_O,
151 [25] = KEY_P,
152 [26] = KEY_LEFTBRACE,
153 [27] = KEY_RIGHTBRACE,
154 [28] = KEY_ENTER,
155 [29] = KEY_LEFTCTRL,
156 [30] = KEY_A,
157 [31] = KEY_S,
158 [32] = KEY_D,
159 [33] = KEY_F,
160 [34] = KEY_G,
161 [35] = KEY_H,
162 [36] = KEY_J,
163 [37] = KEY_K,
164 [38] = KEY_L,
165 [39] = KEY_SEMICOLON,
166 [40] = KEY_APOSTROPHE,
167 [41] = KEY_GRAVE,
168 [42] = KEY_LEFTSHIFT,
169 [43] = KEY_BACKSLASH,
170 [44] = KEY_Z,
171 [45] = KEY_X,
172 [46] = KEY_C,
173 [47] = KEY_V,
174 [48] = KEY_B,
175 [49] = KEY_N,
176 [50] = KEY_M,
177 [51] = KEY_COMMA,
178 [52] = KEY_DOT,
179 [53] = KEY_SLASH,
180 [54] = KEY_RIGHTSHIFT,
181 [55] = KEY_KPASTERISK,
182 [56] = KEY_LEFTALT,
183 [57] = KEY_SPACE,
184 [58] = KEY_CAPSLOCK,
185 [59] = KEY_F1,
186 [60] = KEY_F2,
187 [61] = KEY_F3,
188 [62] = KEY_F4,
189 [63] = KEY_F5,
190 [64] = KEY_F6,
191 [65] = KEY_F7,
192 [66] = KEY_F8,
193 [67] = KEY_F9,
194 [68] = KEY_F10,
195 [69] = KEY_NUMLOCK,
196 [70] = KEY_SCROLLLOCK,
197 [71] = KEY_KP7,
198 [72] = KEY_KP8,
199 [73] = KEY_KP9,
200 [74] = KEY_KPMINUS,
201 [75] = KEY_KP4,
202 [76] = KEY_KP5,
203 [77] = KEY_KP6,
204 [78] = KEY_KPPLUS,
205 [79] = KEY_KP1,
206 [80] = KEY_KP2,
207 [81] = KEY_KP3,
208 [82] = KEY_KP0,
209 [83] = KEY_KPDOT,
210
211 [86] = KEY_102ND,
212 [87] = KEY_F11,
213 [88] = KEY_F12,
214 [90] = KEY_KPLEFTPAREN,
215 [91] = KEY_KPRIGHTPAREN,
216 [92] = KEY_KPASTERISK,
217 [93] = KEY_KPASTERISK,
218 [94] = KEY_KPPLUS,
219 [95] = KEY_HELP,
220 [96] = KEY_KPENTER,
221 [97] = KEY_RIGHTCTRL,
222 [98] = KEY_KPSLASH,
223 [99] = KEY_KPLEFTPAREN,
224 [100] = KEY_KPRIGHTPAREN,
225 [101] = KEY_KPSLASH,
226 [102] = KEY_HOME,
227 [103] = KEY_UP,
228 [104] = KEY_PAGEUP,
229 [105] = KEY_LEFT,
230 [106] = KEY_RIGHT,
231 [107] = KEY_END,
232 [108] = KEY_DOWN,
233 [109] = KEY_PAGEDOWN,
234 [110] = KEY_INSERT,
235 [111] = KEY_DELETE,
236 [112] = KEY_MACRO,
237 [113] = KEY_MUTE
238};
239
240
241
242
243
244static const unsigned char visorkbd_ext_keycode[KEYCODE_TABLE_BYTES] = {
245 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
246 0, 0, 0, 0, 0, 0, 0, 0,
247 0, 0, 0, 0, KEY_KPENTER, KEY_RIGHTCTRL, 0, 0,
248 0, 0, 0, 0, 0, 0, 0, 0,
249 KEY_RIGHTALT, 0, 0, 0, 0, 0, 0, 0,
250 0, 0, 0, 0, 0, 0, 0, 0,
251 KEY_RIGHTALT , 0, 0, 0, 0, 0, 0, 0,
252 0, 0, 0, 0, 0, 0, 0, KEY_HOME,
253 KEY_UP, KEY_PAGEUP, 0, KEY_LEFT, 0, KEY_RIGHT, 0, KEY_END,
254 KEY_DOWN, KEY_PAGEDOWN, KEY_INSERT, KEY_DELETE, 0, 0, 0, 0,
255 0, 0, 0, 0, 0, 0, 0, 0,
256 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
257 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
258};
259
260static int visorinput_open(struct input_dev *visorinput_dev)
261{
262 struct visorinput_devdata *devdata = input_get_drvdata(visorinput_dev);
263
264 if (!devdata) {
265 dev_err(&visorinput_dev->dev,
266 "%s input_get_drvdata(%p) returned NULL\n",
267 __func__, visorinput_dev);
268 return -EINVAL;
269 }
270 dev_dbg(&visorinput_dev->dev, "%s opened\n", __func__);
271
272
273
274
275
276
277 mutex_lock(&devdata->lock_visor_dev);
278 devdata->interrupts_enabled = true;
279 if (devdata->paused)
280 goto out_unlock;
281 visorbus_enable_channel_interrupts(devdata->dev);
282
283out_unlock:
284 mutex_unlock(&devdata->lock_visor_dev);
285 return 0;
286}
287
288static void visorinput_close(struct input_dev *visorinput_dev)
289{
290 struct visorinput_devdata *devdata = input_get_drvdata(visorinput_dev);
291
292 if (!devdata) {
293 dev_err(&visorinput_dev->dev,
294 "%s input_get_drvdata(%p) returned NULL\n",
295 __func__, visorinput_dev);
296 return;
297 }
298 dev_dbg(&visorinput_dev->dev, "%s closed\n", __func__);
299
300
301
302
303
304
305 mutex_lock(&devdata->lock_visor_dev);
306 devdata->interrupts_enabled = false;
307 if (devdata->paused)
308 goto out_unlock;
309 visorbus_disable_channel_interrupts(devdata->dev);
310
311out_unlock:
312 mutex_unlock(&devdata->lock_visor_dev);
313}
314
315
316
317
318
319
320static struct input_dev *setup_client_keyboard(void *devdata,
321 unsigned char *keycode_table)
322
323{
324 int i;
325 struct input_dev *visorinput_dev = input_allocate_device();
326
327 if (!visorinput_dev)
328 return NULL;
329
330 visorinput_dev->name = "visor Keyboard";
331 visorinput_dev->phys = "visorkbd:input0";
332 visorinput_dev->id.bustype = BUS_VIRTUAL;
333 visorinput_dev->id.vendor = 0x0001;
334 visorinput_dev->id.product = 0x0001;
335 visorinput_dev->id.version = 0x0100;
336
337 visorinput_dev->evbit[0] = BIT_MASK(EV_KEY) |
338 BIT_MASK(EV_REP) |
339 BIT_MASK(EV_LED);
340 visorinput_dev->ledbit[0] = BIT_MASK(LED_CAPSL) |
341 BIT_MASK(LED_SCROLLL) |
342 BIT_MASK(LED_NUML);
343 visorinput_dev->keycode = keycode_table;
344
345 visorinput_dev->keycodesize = 1;
346 visorinput_dev->keycodemax = KEYCODE_TABLE_BYTES;
347
348 for (i = 1; i < visorinput_dev->keycodemax; i++)
349 set_bit(keycode_table[i], visorinput_dev->keybit);
350 for (i = 1; i < visorinput_dev->keycodemax; i++)
351 set_bit(keycode_table[i + KEYCODE_TABLE_BYTES],
352 visorinput_dev->keybit);
353
354 visorinput_dev->open = visorinput_open;
355 visorinput_dev->close = visorinput_close;
356
357 input_set_drvdata(visorinput_dev, devdata);
358
359 return visorinput_dev;
360}
361
362static struct input_dev *setup_client_mouse(void *devdata, unsigned int xres,
363 unsigned int yres)
364{
365 struct input_dev *visorinput_dev = input_allocate_device();
366
367 if (!visorinput_dev)
368 return NULL;
369
370 visorinput_dev->name = "visor Mouse";
371 visorinput_dev->phys = "visormou:input0";
372 visorinput_dev->id.bustype = BUS_VIRTUAL;
373 visorinput_dev->id.vendor = 0x0001;
374 visorinput_dev->id.product = 0x0002;
375 visorinput_dev->id.version = 0x0100;
376
377 visorinput_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
378 set_bit(BTN_LEFT, visorinput_dev->keybit);
379 set_bit(BTN_RIGHT, visorinput_dev->keybit);
380 set_bit(BTN_MIDDLE, visorinput_dev->keybit);
381
382 if (xres == 0)
383 xres = PIXELS_ACROSS_DEFAULT;
384 if (yres == 0)
385 yres = PIXELS_DOWN_DEFAULT;
386 input_set_abs_params(visorinput_dev, ABS_X, 0, xres, 0, 0);
387 input_set_abs_params(visorinput_dev, ABS_Y, 0, yres, 0, 0);
388
389 visorinput_dev->open = visorinput_open;
390 visorinput_dev->close = visorinput_close;
391
392 input_set_drvdata(visorinput_dev, devdata);
393 input_set_capability(visorinput_dev, EV_REL, REL_WHEEL);
394
395 return visorinput_dev;
396}
397
398static struct visorinput_devdata *devdata_create(struct visor_device *dev,
399 enum visorinput_dev_type dtype)
400{
401 struct visorinput_devdata *devdata = NULL;
402 unsigned int extra_bytes = 0;
403 unsigned int size, xres, yres, err;
404 struct visor_input_channel_data data;
405
406 if (dtype == visorinput_keyboard)
407
408 extra_bytes = KEYCODE_TABLE_BYTES * 2;
409 devdata = kzalloc(sizeof(*devdata) + extra_bytes, GFP_KERNEL);
410 if (!devdata)
411 return NULL;
412 mutex_init(&devdata->lock_visor_dev);
413 mutex_lock(&devdata->lock_visor_dev);
414 devdata->dev = dev;
415
416
417
418
419
420
421
422 devdata->paused = true;
423
424
425
426
427
428
429 switch (dtype) {
430 case visorinput_keyboard:
431 devdata->keycode_table_bytes = extra_bytes;
432 memcpy(devdata->keycode_table, visorkbd_keycode,
433 KEYCODE_TABLE_BYTES);
434 memcpy(devdata->keycode_table + KEYCODE_TABLE_BYTES,
435 visorkbd_ext_keycode, KEYCODE_TABLE_BYTES);
436 devdata->visorinput_dev = setup_client_keyboard
437 (devdata, devdata->keycode_table);
438 if (!devdata->visorinput_dev)
439 goto cleanups_register;
440 break;
441 case visorinput_mouse:
442 size = sizeof(struct visor_input_channel_data);
443 err = visorbus_read_channel(dev, sizeof(struct channel_header),
444 &data, size);
445 if (err)
446 goto cleanups_register;
447 xres = data.mouse.x_res;
448 yres = data.mouse.y_res;
449 devdata->visorinput_dev = setup_client_mouse(devdata, xres,
450 yres);
451 if (!devdata->visorinput_dev)
452 goto cleanups_register;
453 break;
454 default:
455
456 break;
457 }
458
459 dev_set_drvdata(&dev->device, devdata);
460 mutex_unlock(&devdata->lock_visor_dev);
461
462
463
464
465
466
467
468 if (input_register_device(devdata->visorinput_dev)) {
469 input_free_device(devdata->visorinput_dev);
470 goto err_kfree_devdata;
471 }
472
473 mutex_lock(&devdata->lock_visor_dev);
474
475
476
477
478
479 devdata->paused = false;
480 if (devdata->interrupts_enabled)
481 visorbus_enable_channel_interrupts(dev);
482 mutex_unlock(&devdata->lock_visor_dev);
483
484 return devdata;
485
486cleanups_register:
487 mutex_unlock(&devdata->lock_visor_dev);
488err_kfree_devdata:
489 kfree(devdata);
490 return NULL;
491}
492
493static int visorinput_probe(struct visor_device *dev)
494{
495 const guid_t *guid;
496 enum visorinput_dev_type dtype;
497
498 guid = visorchannel_get_guid(dev->visorchannel);
499 if (guid_equal(guid, &visor_mouse_channel_guid))
500 dtype = visorinput_mouse;
501 else if (guid_equal(guid, &visor_keyboard_channel_guid))
502 dtype = visorinput_keyboard;
503 else
504 return -ENODEV;
505 visorbus_disable_channel_interrupts(dev);
506 if (!devdata_create(dev, dtype))
507 return -ENOMEM;
508 return 0;
509}
510
511static void unregister_client_input(struct input_dev *visorinput_dev)
512{
513 if (visorinput_dev)
514 input_unregister_device(visorinput_dev);
515}
516
517static void visorinput_remove(struct visor_device *dev)
518{
519 struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device);
520
521 if (!devdata)
522 return;
523
524 mutex_lock(&devdata->lock_visor_dev);
525 visorbus_disable_channel_interrupts(dev);
526
527
528
529
530
531
532 dev_set_drvdata(&dev->device, NULL);
533 mutex_unlock(&devdata->lock_visor_dev);
534
535 unregister_client_input(devdata->visorinput_dev);
536 kfree(devdata);
537}
538
539
540
541
542
543static void handle_locking_key(struct input_dev *visorinput_dev, int keycode,
544 int desired_state)
545{
546 int led;
547
548 switch (keycode) {
549 case KEY_CAPSLOCK:
550 led = LED_CAPSL;
551 break;
552 case KEY_SCROLLLOCK:
553 led = LED_SCROLLL;
554 break;
555 case KEY_NUMLOCK:
556 led = LED_NUML;
557 break;
558 default:
559 return;
560 }
561 if (test_bit(led, visorinput_dev->led) != desired_state) {
562 input_report_key(visorinput_dev, keycode, 1);
563 input_sync(visorinput_dev);
564 input_report_key(visorinput_dev, keycode, 0);
565 input_sync(visorinput_dev);
566 __change_bit(led, visorinput_dev->led);
567 }
568}
569
570
571
572
573
574static int scancode_to_keycode(int scancode)
575{
576 if (scancode > 0xff)
577 return visorkbd_ext_keycode[(scancode >> 8) & 0xff];
578
579 return visorkbd_keycode[scancode];
580}
581
582static int calc_button(int x)
583{
584 switch (x) {
585 case 1:
586 return BTN_LEFT;
587 case 2:
588 return BTN_MIDDLE;
589 case 3:
590 return BTN_RIGHT;
591 default:
592 return -EINVAL;
593 }
594}
595
596
597
598
599
600
601static void visorinput_channel_interrupt(struct visor_device *dev)
602{
603 struct visor_inputreport r;
604 int scancode, keycode;
605 struct input_dev *visorinput_dev;
606 int xmotion, ymotion, button;
607 int i;
608 struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device);
609
610 if (!devdata)
611 return;
612
613 visorinput_dev = devdata->visorinput_dev;
614
615 while (!visorchannel_signalremove(dev->visorchannel, 0, &r)) {
616 scancode = r.activity.arg1;
617 keycode = scancode_to_keycode(scancode);
618 switch (r.activity.action) {
619 case INPUTACTION_KEY_DOWN:
620 input_report_key(visorinput_dev, keycode, 1);
621 input_sync(visorinput_dev);
622 break;
623 case INPUTACTION_KEY_UP:
624 input_report_key(visorinput_dev, keycode, 0);
625 input_sync(visorinput_dev);
626 break;
627 case INPUTACTION_KEY_DOWN_UP:
628 input_report_key(visorinput_dev, keycode, 1);
629 input_sync(visorinput_dev);
630 input_report_key(visorinput_dev, keycode, 0);
631 input_sync(visorinput_dev);
632 break;
633 case INPUTACTION_SET_LOCKING_KEY_STATE:
634 handle_locking_key(visorinput_dev, keycode,
635 r.activity.arg2);
636 break;
637 case INPUTACTION_XY_MOTION:
638 xmotion = r.activity.arg1;
639 ymotion = r.activity.arg2;
640 input_report_abs(visorinput_dev, ABS_X, xmotion);
641 input_report_abs(visorinput_dev, ABS_Y, ymotion);
642 input_sync(visorinput_dev);
643 break;
644 case INPUTACTION_MOUSE_BUTTON_DOWN:
645 button = calc_button(r.activity.arg1);
646 if (button < 0)
647 break;
648 input_report_key(visorinput_dev, button, 1);
649 input_sync(visorinput_dev);
650 break;
651 case INPUTACTION_MOUSE_BUTTON_UP:
652 button = calc_button(r.activity.arg1);
653 if (button < 0)
654 break;
655 input_report_key(visorinput_dev, button, 0);
656 input_sync(visorinput_dev);
657 break;
658 case INPUTACTION_MOUSE_BUTTON_CLICK:
659 button = calc_button(r.activity.arg1);
660 if (button < 0)
661 break;
662 input_report_key(visorinput_dev, button, 1);
663 input_sync(visorinput_dev);
664 input_report_key(visorinput_dev, button, 0);
665 input_sync(visorinput_dev);
666 break;
667 case INPUTACTION_MOUSE_BUTTON_DCLICK:
668 button = calc_button(r.activity.arg1);
669 if (button < 0)
670 break;
671 for (i = 0; i < 2; i++) {
672 input_report_key(visorinput_dev, button, 1);
673 input_sync(visorinput_dev);
674 input_report_key(visorinput_dev, button, 0);
675 input_sync(visorinput_dev);
676 }
677 break;
678 case INPUTACTION_WHEEL_ROTATE_AWAY:
679 input_report_rel(visorinput_dev, REL_WHEEL, 1);
680 input_sync(visorinput_dev);
681 break;
682 case INPUTACTION_WHEEL_ROTATE_TOWARD:
683 input_report_rel(visorinput_dev, REL_WHEEL, -1);
684 input_sync(visorinput_dev);
685 break;
686 default:
687
688 break;
689 }
690 }
691}
692
693static int visorinput_pause(struct visor_device *dev,
694 visorbus_state_complete_func complete_func)
695{
696 int rc;
697 struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device);
698
699 if (!devdata) {
700 rc = -ENODEV;
701 goto out;
702 }
703
704 mutex_lock(&devdata->lock_visor_dev);
705 if (devdata->paused) {
706 rc = -EBUSY;
707 goto out_locked;
708 }
709 if (devdata->interrupts_enabled)
710 visorbus_disable_channel_interrupts(dev);
711
712
713
714
715
716 devdata->paused = true;
717 complete_func(dev, 0);
718 rc = 0;
719out_locked:
720 mutex_unlock(&devdata->lock_visor_dev);
721out:
722 return rc;
723}
724
725static int visorinput_resume(struct visor_device *dev,
726 visorbus_state_complete_func complete_func)
727{
728 int rc;
729 struct visorinput_devdata *devdata = dev_get_drvdata(&dev->device);
730
731 if (!devdata) {
732 rc = -ENODEV;
733 goto out;
734 }
735 mutex_lock(&devdata->lock_visor_dev);
736 if (!devdata->paused) {
737 rc = -EBUSY;
738 goto out_locked;
739 }
740 devdata->paused = false;
741 complete_func(dev, 0);
742
743
744
745
746
747
748 if (devdata->interrupts_enabled)
749 visorbus_enable_channel_interrupts(dev);
750
751 rc = 0;
752out_locked:
753 mutex_unlock(&devdata->lock_visor_dev);
754out:
755 return rc;
756}
757
758
759static struct visor_channeltype_descriptor visorinput_channel_types[] = {
760 { VISOR_KEYBOARD_CHANNEL_GUID, "keyboard",
761 sizeof(struct channel_header), 0 },
762 { VISOR_MOUSE_CHANNEL_GUID, "mouse", sizeof(struct channel_header), 0 },
763 {}
764};
765
766static struct visor_driver visorinput_driver = {
767 .name = "visorinput",
768 .owner = THIS_MODULE,
769 .channel_types = visorinput_channel_types,
770 .probe = visorinput_probe,
771 .remove = visorinput_remove,
772 .channel_interrupt = visorinput_channel_interrupt,
773 .pause = visorinput_pause,
774 .resume = visorinput_resume,
775};
776
777module_driver(visorinput_driver, visorbus_register_visor_driver,
778 visorbus_unregister_visor_driver);
779
780MODULE_DEVICE_TABLE(visorbus, visorinput_channel_types);
781
782MODULE_AUTHOR("Unisys");
783MODULE_LICENSE("GPL");
784MODULE_DESCRIPTION("s-Par human input driver for virtual keyboard/mouse");
785
786MODULE_ALIAS("visorbus:" VISOR_MOUSE_CHANNEL_GUID_STR);
787MODULE_ALIAS("visorbus:" VISOR_KEYBOARD_CHANNEL_GUID_STR);
788