2 * Xen para-virtual input device
4 * Copyright (C) 2005 Anthony Liguori <aliguori@us.ibm.com>
5 * Copyright (C) 2006-2008 Red Hat, Inc., Markus Armbruster <armbru@redhat.com>
7 * Based on linux/drivers/input/mouse/sermouse.c
9 * This file is subject to the terms and conditions of the GNU General Public
10 * License. See the file COPYING in the main directory of this archive for
14 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16 #include <linux/kernel.h>
17 #include <linux/errno.h>
18 #include <linux/module.h>
19 #include <linux/input.h>
20 #include <linux/input/mt.h>
21 #include <linux/slab.h>
23 #include <asm/xen/hypervisor.h>
26 #include <xen/events.h>
28 #include <xen/grant_table.h>
29 #include <xen/interface/grant_table.h>
30 #include <xen/interface/io/fbif.h>
31 #include <xen/interface/io/kbdif.h>
32 #include <xen/xenbus.h>
33 #include <xen/platform_pci.h>
36 struct input_dev
*kbd
;
37 struct input_dev
*ptr
;
38 struct input_dev
*mtouch
;
39 struct xenkbd_page
*page
;
42 struct xenbus_device
*xbdev
;
44 /* current MT slot/contact ID we are injecting events in */
45 int mtouch_cur_contact_id
;
48 enum { KPARAM_X
, KPARAM_Y
, KPARAM_CNT
};
49 static int ptr_size
[KPARAM_CNT
] = { XENFB_WIDTH
, XENFB_HEIGHT
};
50 module_param_array(ptr_size
, int, NULL
, 0444);
51 MODULE_PARM_DESC(ptr_size
,
52 "Pointing device width, height in pixels (default 800,600)");
54 static int xenkbd_remove(struct xenbus_device
*);
55 static int xenkbd_connect_backend(struct xenbus_device
*, struct xenkbd_info
*);
56 static void xenkbd_disconnect_backend(struct xenkbd_info
*);
59 * Note: if you need to send out events, see xenfb_do_update() for how
63 static void xenkbd_handle_motion_event(struct xenkbd_info
*info
,
64 struct xenkbd_motion
*motion
)
66 if (unlikely(!info
->ptr
))
69 input_report_rel(info
->ptr
, REL_X
, motion
->rel_x
);
70 input_report_rel(info
->ptr
, REL_Y
, motion
->rel_y
);
72 input_report_rel(info
->ptr
, REL_WHEEL
, -motion
->rel_z
);
73 input_sync(info
->ptr
);
76 static void xenkbd_handle_position_event(struct xenkbd_info
*info
,
77 struct xenkbd_position
*pos
)
79 if (unlikely(!info
->ptr
))
82 input_report_abs(info
->ptr
, ABS_X
, pos
->abs_x
);
83 input_report_abs(info
->ptr
, ABS_Y
, pos
->abs_y
);
85 input_report_rel(info
->ptr
, REL_WHEEL
, -pos
->rel_z
);
86 input_sync(info
->ptr
);
89 static void xenkbd_handle_key_event(struct xenkbd_info
*info
,
90 struct xenkbd_key
*key
)
92 struct input_dev
*dev
;
93 int value
= key
->pressed
;
95 if (test_bit(key
->keycode
, info
->ptr
->keybit
)) {
97 } else if (test_bit(key
->keycode
, info
->kbd
->keybit
)) {
99 if (key
->pressed
&& test_bit(key
->keycode
, info
->kbd
->key
))
100 value
= 2; /* Mark as autorepeat */
102 pr_warn("unhandled keycode 0x%x\n", key
->keycode
);
109 input_event(dev
, EV_KEY
, key
->keycode
, value
);
113 static void xenkbd_handle_mt_event(struct xenkbd_info
*info
,
114 struct xenkbd_mtouch
*mtouch
)
116 if (unlikely(!info
->mtouch
))
119 if (mtouch
->contact_id
!= info
->mtouch_cur_contact_id
) {
120 info
->mtouch_cur_contact_id
= mtouch
->contact_id
;
121 input_mt_slot(info
->mtouch
, mtouch
->contact_id
);
124 switch (mtouch
->event_type
) {
125 case XENKBD_MT_EV_DOWN
:
126 input_mt_report_slot_state(info
->mtouch
, MT_TOOL_FINGER
, true);
129 case XENKBD_MT_EV_MOTION
:
130 input_report_abs(info
->mtouch
, ABS_MT_POSITION_X
,
131 mtouch
->u
.pos
.abs_x
);
132 input_report_abs(info
->mtouch
, ABS_MT_POSITION_Y
,
133 mtouch
->u
.pos
.abs_y
);
136 case XENKBD_MT_EV_SHAPE
:
137 input_report_abs(info
->mtouch
, ABS_MT_TOUCH_MAJOR
,
138 mtouch
->u
.shape
.major
);
139 input_report_abs(info
->mtouch
, ABS_MT_TOUCH_MINOR
,
140 mtouch
->u
.shape
.minor
);
143 case XENKBD_MT_EV_ORIENT
:
144 input_report_abs(info
->mtouch
, ABS_MT_ORIENTATION
,
145 mtouch
->u
.orientation
);
148 case XENKBD_MT_EV_UP
:
149 input_mt_report_slot_state(info
->mtouch
, MT_TOOL_FINGER
, false);
152 case XENKBD_MT_EV_SYN
:
153 input_mt_sync_frame(info
->mtouch
);
154 input_sync(info
->mtouch
);
159 static void xenkbd_handle_event(struct xenkbd_info
*info
,
160 union xenkbd_in_event
*event
)
162 switch (event
->type
) {
163 case XENKBD_TYPE_MOTION
:
164 xenkbd_handle_motion_event(info
, &event
->motion
);
167 case XENKBD_TYPE_KEY
:
168 xenkbd_handle_key_event(info
, &event
->key
);
171 case XENKBD_TYPE_POS
:
172 xenkbd_handle_position_event(info
, &event
->pos
);
175 case XENKBD_TYPE_MTOUCH
:
176 xenkbd_handle_mt_event(info
, &event
->mtouch
);
181 static irqreturn_t
input_handler(int rq
, void *dev_id
)
183 struct xenkbd_info
*info
= dev_id
;
184 struct xenkbd_page
*page
= info
->page
;
187 prod
= page
->in_prod
;
188 if (prod
== page
->in_cons
)
190 rmb(); /* ensure we see ring contents up to prod */
191 for (cons
= page
->in_cons
; cons
!= prod
; cons
++)
192 xenkbd_handle_event(info
, &XENKBD_IN_RING_REF(page
, cons
));
193 mb(); /* ensure we got ring contents */
194 page
->in_cons
= cons
;
195 notify_remote_via_irq(info
->irq
);
200 static int xenkbd_probe(struct xenbus_device
*dev
,
201 const struct xenbus_device_id
*id
)
204 bool with_mtouch
, with_kbd
, with_ptr
;
205 struct xenkbd_info
*info
;
206 struct input_dev
*kbd
, *ptr
, *mtouch
;
208 info
= kzalloc(sizeof(*info
), GFP_KERNEL
);
210 xenbus_dev_fatal(dev
, -ENOMEM
, "allocating info structure");
213 dev_set_drvdata(&dev
->dev
, info
);
217 snprintf(info
->phys
, sizeof(info
->phys
), "xenbus/%s", dev
->nodename
);
219 info
->page
= (void *)__get_free_page(GFP_KERNEL
| __GFP_ZERO
);
224 * The below are reverse logic, e.g. if the feature is set, then
225 * do not expose the corresponding virtual device.
227 with_kbd
= !xenbus_read_unsigned(dev
->otherend
,
228 XENKBD_FIELD_FEAT_DSBL_KEYBRD
, 0);
230 with_ptr
= !xenbus_read_unsigned(dev
->otherend
,
231 XENKBD_FIELD_FEAT_DSBL_POINTER
, 0);
233 /* Direct logic: if set, then create multi-touch device. */
234 with_mtouch
= xenbus_read_unsigned(dev
->otherend
,
235 XENKBD_FIELD_FEAT_MTOUCH
, 0);
237 ret
= xenbus_write(XBT_NIL
, dev
->nodename
,
238 XENKBD_FIELD_REQ_MTOUCH
, "1");
240 pr_warn("xenkbd: can't request multi-touch");
247 kbd
= input_allocate_device();
250 kbd
->name
= "Xen Virtual Keyboard";
251 kbd
->phys
= info
->phys
;
252 kbd
->id
.bustype
= BUS_PCI
;
253 kbd
->id
.vendor
= 0x5853;
254 kbd
->id
.product
= 0xffff;
256 __set_bit(EV_KEY
, kbd
->evbit
);
257 for (i
= KEY_ESC
; i
< KEY_UNKNOWN
; i
++)
258 __set_bit(i
, kbd
->keybit
);
259 for (i
= KEY_OK
; i
< KEY_MAX
; i
++)
260 __set_bit(i
, kbd
->keybit
);
262 ret
= input_register_device(kbd
);
264 input_free_device(kbd
);
265 xenbus_dev_fatal(dev
, ret
,
266 "input_register_device(kbd)");
272 /* pointing device */
276 /* Set input abs params to match backend screen res */
277 abs
= xenbus_read_unsigned(dev
->otherend
,
278 XENKBD_FIELD_FEAT_ABS_POINTER
, 0);
279 ptr_size
[KPARAM_X
] = xenbus_read_unsigned(dev
->otherend
,
282 ptr_size
[KPARAM_Y
] = xenbus_read_unsigned(dev
->otherend
,
286 ret
= xenbus_write(XBT_NIL
, dev
->nodename
,
287 XENKBD_FIELD_REQ_ABS_POINTER
, "1");
289 pr_warn("xenkbd: can't request abs-pointer\n");
294 ptr
= input_allocate_device();
297 ptr
->name
= "Xen Virtual Pointer";
298 ptr
->phys
= info
->phys
;
299 ptr
->id
.bustype
= BUS_PCI
;
300 ptr
->id
.vendor
= 0x5853;
301 ptr
->id
.product
= 0xfffe;
304 __set_bit(EV_ABS
, ptr
->evbit
);
305 input_set_abs_params(ptr
, ABS_X
, 0,
306 ptr_size
[KPARAM_X
], 0, 0);
307 input_set_abs_params(ptr
, ABS_Y
, 0,
308 ptr_size
[KPARAM_Y
], 0, 0);
310 input_set_capability(ptr
, EV_REL
, REL_X
);
311 input_set_capability(ptr
, EV_REL
, REL_Y
);
313 input_set_capability(ptr
, EV_REL
, REL_WHEEL
);
315 __set_bit(EV_KEY
, ptr
->evbit
);
316 for (i
= BTN_LEFT
; i
<= BTN_TASK
; i
++)
317 __set_bit(i
, ptr
->keybit
);
319 ret
= input_register_device(ptr
);
321 input_free_device(ptr
);
322 xenbus_dev_fatal(dev
, ret
,
323 "input_register_device(ptr)");
329 /* multi-touch device */
331 int num_cont
, width
, height
;
333 mtouch
= input_allocate_device();
337 num_cont
= xenbus_read_unsigned(info
->xbdev
->otherend
,
338 XENKBD_FIELD_MT_NUM_CONTACTS
,
340 width
= xenbus_read_unsigned(info
->xbdev
->otherend
,
341 XENKBD_FIELD_MT_WIDTH
,
343 height
= xenbus_read_unsigned(info
->xbdev
->otherend
,
344 XENKBD_FIELD_MT_HEIGHT
,
347 mtouch
->name
= "Xen Virtual Multi-touch";
348 mtouch
->phys
= info
->phys
;
349 mtouch
->id
.bustype
= BUS_PCI
;
350 mtouch
->id
.vendor
= 0x5853;
351 mtouch
->id
.product
= 0xfffd;
353 input_set_abs_params(mtouch
, ABS_MT_TOUCH_MAJOR
,
355 input_set_abs_params(mtouch
, ABS_MT_POSITION_X
,
357 input_set_abs_params(mtouch
, ABS_MT_POSITION_Y
,
360 ret
= input_mt_init_slots(mtouch
, num_cont
, INPUT_MT_DIRECT
);
362 input_free_device(mtouch
);
363 xenbus_dev_fatal(info
->xbdev
, ret
,
364 "input_mt_init_slots");
368 ret
= input_register_device(mtouch
);
370 input_free_device(mtouch
);
371 xenbus_dev_fatal(info
->xbdev
, ret
,
372 "input_register_device(mtouch)");
375 info
->mtouch_cur_contact_id
= -1;
376 info
->mtouch
= mtouch
;
379 if (!(with_kbd
|| with_ptr
|| with_mtouch
)) {
384 ret
= xenkbd_connect_backend(dev
, info
);
392 xenbus_dev_fatal(dev
, ret
, "allocating device memory");
398 static int xenkbd_resume(struct xenbus_device
*dev
)
400 struct xenkbd_info
*info
= dev_get_drvdata(&dev
->dev
);
402 xenkbd_disconnect_backend(info
);
403 memset(info
->page
, 0, PAGE_SIZE
);
404 return xenkbd_connect_backend(dev
, info
);
407 static int xenkbd_remove(struct xenbus_device
*dev
)
409 struct xenkbd_info
*info
= dev_get_drvdata(&dev
->dev
);
411 xenkbd_disconnect_backend(info
);
413 input_unregister_device(info
->kbd
);
415 input_unregister_device(info
->ptr
);
417 input_unregister_device(info
->mtouch
);
418 free_page((unsigned long)info
->page
);
423 static int xenkbd_connect_backend(struct xenbus_device
*dev
,
424 struct xenkbd_info
*info
)
427 struct xenbus_transaction xbt
;
429 ret
= gnttab_grant_foreign_access(dev
->otherend_id
,
430 virt_to_gfn(info
->page
), 0);
435 ret
= xenbus_alloc_evtchn(dev
, &evtchn
);
438 ret
= bind_evtchn_to_irqhandler(evtchn
, input_handler
,
439 0, dev
->devicetype
, info
);
441 xenbus_dev_fatal(dev
, ret
, "bind_evtchn_to_irqhandler");
447 ret
= xenbus_transaction_start(&xbt
);
449 xenbus_dev_fatal(dev
, ret
, "starting transaction");
452 ret
= xenbus_printf(xbt
, dev
->nodename
, XENKBD_FIELD_RING_REF
, "%lu",
453 virt_to_gfn(info
->page
));
456 ret
= xenbus_printf(xbt
, dev
->nodename
, XENKBD_FIELD_RING_GREF
,
460 ret
= xenbus_printf(xbt
, dev
->nodename
, XENKBD_FIELD_EVT_CHANNEL
, "%u",
464 ret
= xenbus_transaction_end(xbt
, 0);
468 xenbus_dev_fatal(dev
, ret
, "completing transaction");
472 xenbus_switch_state(dev
, XenbusStateInitialised
);
476 xenbus_transaction_end(xbt
, 1);
477 xenbus_dev_fatal(dev
, ret
, "writing xenstore");
479 unbind_from_irqhandler(info
->irq
, info
);
482 xenbus_free_evtchn(dev
, evtchn
);
484 gnttab_end_foreign_access(info
->gref
, 0, 0UL);
489 static void xenkbd_disconnect_backend(struct xenkbd_info
*info
)
492 unbind_from_irqhandler(info
->irq
, info
);
495 gnttab_end_foreign_access(info
->gref
, 0, 0UL);
499 static void xenkbd_backend_changed(struct xenbus_device
*dev
,
500 enum xenbus_state backend_state
)
502 switch (backend_state
) {
503 case XenbusStateInitialising
:
504 case XenbusStateInitialised
:
505 case XenbusStateReconfiguring
:
506 case XenbusStateReconfigured
:
507 case XenbusStateUnknown
:
510 case XenbusStateInitWait
:
511 xenbus_switch_state(dev
, XenbusStateConnected
);
514 case XenbusStateConnected
:
516 * Work around xenbus race condition: If backend goes
517 * through InitWait to Connected fast enough, we can
518 * get Connected twice here.
520 if (dev
->state
!= XenbusStateConnected
)
521 xenbus_switch_state(dev
, XenbusStateConnected
);
524 case XenbusStateClosed
:
525 if (dev
->state
== XenbusStateClosed
)
527 /* fall through - Missed the backend's CLOSING state */
528 case XenbusStateClosing
:
529 xenbus_frontend_closed(dev
);
534 static const struct xenbus_device_id xenkbd_ids
[] = {
535 { XENKBD_DRIVER_NAME
},
539 static struct xenbus_driver xenkbd_driver
= {
541 .probe
= xenkbd_probe
,
542 .remove
= xenkbd_remove
,
543 .resume
= xenkbd_resume
,
544 .otherend_changed
= xenkbd_backend_changed
,
547 static int __init
xenkbd_init(void)
552 /* Nothing to do if running in dom0. */
553 if (xen_initial_domain())
556 if (!xen_has_pv_devices())
559 return xenbus_register_frontend(&xenkbd_driver
);
562 static void __exit
xenkbd_cleanup(void)
564 xenbus_unregister_driver(&xenkbd_driver
);
567 module_init(xenkbd_init
);
568 module_exit(xenkbd_cleanup
);
570 MODULE_DESCRIPTION("Xen virtual keyboard/pointer device frontend");
571 MODULE_LICENSE("GPL");
572 MODULE_ALIAS("xen:" XENKBD_DRIVER_NAME
);