xref: /qemu/hw/input/virtio-input-hid.c (revision 06b40d250ecfa1633209c2e431a7a38acfd03a98)
155a1d80aSGerd Hoffmann /*
255a1d80aSGerd Hoffmann  * This work is licensed under the terms of the GNU GPL, version 2 or
355a1d80aSGerd Hoffmann  * (at your option) any later version.  See the COPYING file in the
455a1d80aSGerd Hoffmann  * top-level directory.
555a1d80aSGerd Hoffmann  */
655a1d80aSGerd Hoffmann 
79b8bfe21SPeter Maydell #include "qemu/osdep.h"
855a1d80aSGerd Hoffmann #include "qemu/iov.h"
90b8fa32fSMarkus Armbruster #include "qemu/module.h"
1055a1d80aSGerd Hoffmann 
1155a1d80aSGerd Hoffmann #include "hw/virtio/virtio.h"
12a27bd6c7SMarkus Armbruster #include "hw/qdev-properties.h"
1355a1d80aSGerd Hoffmann #include "hw/virtio/virtio-input.h"
1455a1d80aSGerd Hoffmann 
1555a1d80aSGerd Hoffmann #include "ui/console.h"
1655a1d80aSGerd Hoffmann 
1755a1d80aSGerd Hoffmann #include "standard-headers/linux/input.h"
1855a1d80aSGerd Hoffmann 
1955a1d80aSGerd Hoffmann #define VIRTIO_ID_NAME_KEYBOARD     "QEMU Virtio Keyboard"
2055a1d80aSGerd Hoffmann #define VIRTIO_ID_NAME_MOUSE        "QEMU Virtio Mouse"
2155a1d80aSGerd Hoffmann #define VIRTIO_ID_NAME_TABLET       "QEMU Virtio Tablet"
228e9ebd75SSergio Lopez #define VIRTIO_ID_NAME_MULTITOUCH   "QEMU Virtio MultiTouch"
2355a1d80aSGerd Hoffmann 
2455a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */
2555a1d80aSGerd Hoffmann 
26ae6b06abSDaniel P. Berrange static const unsigned short keymap_button[INPUT_BUTTON__MAX] = {
2755a1d80aSGerd Hoffmann     [INPUT_BUTTON_LEFT]              = BTN_LEFT,
2855a1d80aSGerd Hoffmann     [INPUT_BUTTON_RIGHT]             = BTN_RIGHT,
2955a1d80aSGerd Hoffmann     [INPUT_BUTTON_MIDDLE]            = BTN_MIDDLE,
30f22d0af0SGerd Hoffmann     [INPUT_BUTTON_WHEEL_UP]          = BTN_GEAR_UP,
31f22d0af0SGerd Hoffmann     [INPUT_BUTTON_WHEEL_DOWN]        = BTN_GEAR_DOWN,
322416760fSMiika S     [INPUT_BUTTON_SIDE]              = BTN_SIDE,
332416760fSMiika S     [INPUT_BUTTON_EXTRA]             = BTN_EXTRA,
348e9ebd75SSergio Lopez     [INPUT_BUTTON_TOUCH]             = BTN_TOUCH,
3555a1d80aSGerd Hoffmann };
3655a1d80aSGerd Hoffmann 
37ae6b06abSDaniel P. Berrange static const unsigned short axismap_rel[INPUT_AXIS__MAX] = {
3855a1d80aSGerd Hoffmann     [INPUT_AXIS_X]                   = REL_X,
3955a1d80aSGerd Hoffmann     [INPUT_AXIS_Y]                   = REL_Y,
4055a1d80aSGerd Hoffmann };
4155a1d80aSGerd Hoffmann 
42ae6b06abSDaniel P. Berrange static const unsigned short axismap_abs[INPUT_AXIS__MAX] = {
4355a1d80aSGerd Hoffmann     [INPUT_AXIS_X]                   = ABS_X,
4455a1d80aSGerd Hoffmann     [INPUT_AXIS_Y]                   = ABS_Y,
4555a1d80aSGerd Hoffmann };
4655a1d80aSGerd Hoffmann 
478e9ebd75SSergio Lopez static const unsigned short axismap_tch[INPUT_AXIS__MAX] = {
488e9ebd75SSergio Lopez     [INPUT_AXIS_X]                   = ABS_MT_POSITION_X,
498e9ebd75SSergio Lopez     [INPUT_AXIS_Y]                   = ABS_MT_POSITION_Y,
508e9ebd75SSergio Lopez };
518e9ebd75SSergio Lopez 
5255a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */
5355a1d80aSGerd Hoffmann 
virtio_input_extend_config(VirtIOInput * vinput,const unsigned short * map,size_t mapsize,uint8_t select,uint8_t subsel)54944ae6d9SSergio Lopez static void virtio_input_extend_config(VirtIOInput *vinput,
55944ae6d9SSergio Lopez                                        const unsigned short *map,
56944ae6d9SSergio Lopez                                        size_t mapsize,
57944ae6d9SSergio Lopez                                        uint8_t select, uint8_t subsel)
5855a1d80aSGerd Hoffmann {
59944ae6d9SSergio Lopez     virtio_input_config ext;
6055a1d80aSGerd Hoffmann     int i, bit, byte, bmax = 0;
6155a1d80aSGerd Hoffmann 
62944ae6d9SSergio Lopez     memset(&ext, 0, sizeof(ext));
6355a1d80aSGerd Hoffmann     for (i = 0; i < mapsize; i++) {
64944ae6d9SSergio Lopez         bit = map[i];
6555a1d80aSGerd Hoffmann         if (!bit) {
6655a1d80aSGerd Hoffmann             continue;
6755a1d80aSGerd Hoffmann         }
6855a1d80aSGerd Hoffmann         byte = bit / 8;
6955a1d80aSGerd Hoffmann         bit  = bit % 8;
70944ae6d9SSergio Lopez         ext.u.bitmap[byte] |= (1 << bit);
7155a1d80aSGerd Hoffmann         if (bmax < byte+1) {
7255a1d80aSGerd Hoffmann             bmax = byte+1;
7355a1d80aSGerd Hoffmann         }
7455a1d80aSGerd Hoffmann     }
75944ae6d9SSergio Lopez     ext.select = select;
76944ae6d9SSergio Lopez     ext.subsel = subsel;
77944ae6d9SSergio Lopez     ext.size   = bmax;
78944ae6d9SSergio Lopez     virtio_input_add_config(vinput, &ext);
7955a1d80aSGerd Hoffmann }
8055a1d80aSGerd Hoffmann 
virtio_input_handle_event(DeviceState * dev,QemuConsole * src,InputEvent * evt)8155a1d80aSGerd Hoffmann static void virtio_input_handle_event(DeviceState *dev, QemuConsole *src,
8255a1d80aSGerd Hoffmann                                       InputEvent *evt)
8355a1d80aSGerd Hoffmann {
84f4924974SGerd Hoffmann     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(dev);
8555a1d80aSGerd Hoffmann     VirtIOInput *vinput = VIRTIO_INPUT(dev);
8655a1d80aSGerd Hoffmann     virtio_input_event event;
8755a1d80aSGerd Hoffmann     int qcode;
88b5a1b443SEric Blake     InputKeyEvent *key;
89b5a1b443SEric Blake     InputMoveEvent *move;
90b5a1b443SEric Blake     InputBtnEvent *btn;
918e9ebd75SSergio Lopez     InputMultiTouchEvent *mtt;
9255a1d80aSGerd Hoffmann 
93568c73a4SEric Blake     switch (evt->type) {
9455a1d80aSGerd Hoffmann     case INPUT_EVENT_KIND_KEY:
9532bafa8fSEric Blake         key = evt->u.key.data;
96b5a1b443SEric Blake         qcode = qemu_input_key_value_to_qcode(key->key);
97ae6b06abSDaniel P. Berrange         if (qcode < qemu_input_map_qcode_to_linux_len &&
98ae6b06abSDaniel P. Berrange             qemu_input_map_qcode_to_linux[qcode]) {
9955a1d80aSGerd Hoffmann             event.type  = cpu_to_le16(EV_KEY);
100ae6b06abSDaniel P. Berrange             event.code  = cpu_to_le16(qemu_input_map_qcode_to_linux[qcode]);
101b5a1b443SEric Blake             event.value = cpu_to_le32(key->down ? 1 : 0);
10255a1d80aSGerd Hoffmann             virtio_input_send(vinput, &event);
10355a1d80aSGerd Hoffmann         } else {
104b5a1b443SEric Blake             if (key->down) {
10555a1d80aSGerd Hoffmann                 fprintf(stderr, "%s: unmapped key: %d [%s]\n", __func__,
106977c736fSMarkus Armbruster                         qcode, QKeyCode_str(qcode));
10755a1d80aSGerd Hoffmann             }
10855a1d80aSGerd Hoffmann         }
10955a1d80aSGerd Hoffmann         break;
11055a1d80aSGerd Hoffmann     case INPUT_EVENT_KIND_BTN:
11132bafa8fSEric Blake         btn = evt->u.btn.data;
112a5f99be4SMiika S         if (vhid->wheel_axis &&
113a5f99be4SMiika S             (btn->button == INPUT_BUTTON_WHEEL_UP ||
114a5f99be4SMiika S              btn->button == INPUT_BUTTON_WHEEL_DOWN) &&
115a5f99be4SMiika S             btn->down) {
116f4924974SGerd Hoffmann             event.type  = cpu_to_le16(EV_REL);
117f4924974SGerd Hoffmann             event.code  = cpu_to_le16(REL_WHEEL);
118f4924974SGerd Hoffmann             event.value = cpu_to_le32(btn->button == INPUT_BUTTON_WHEEL_UP
119f4924974SGerd Hoffmann                                       ? 1 : -1);
120f4924974SGerd Hoffmann             virtio_input_send(vinput, &event);
121f4924974SGerd Hoffmann         } else if (keymap_button[btn->button]) {
12255a1d80aSGerd Hoffmann             event.type  = cpu_to_le16(EV_KEY);
123b5a1b443SEric Blake             event.code  = cpu_to_le16(keymap_button[btn->button]);
124b5a1b443SEric Blake             event.value = cpu_to_le32(btn->down ? 1 : 0);
12555a1d80aSGerd Hoffmann             virtio_input_send(vinput, &event);
12655a1d80aSGerd Hoffmann         } else {
127b5a1b443SEric Blake             if (btn->down) {
12855a1d80aSGerd Hoffmann                 fprintf(stderr, "%s: unmapped button: %d [%s]\n", __func__,
129b5a1b443SEric Blake                         btn->button,
130977c736fSMarkus Armbruster                         InputButton_str(btn->button));
13155a1d80aSGerd Hoffmann             }
13255a1d80aSGerd Hoffmann         }
13355a1d80aSGerd Hoffmann         break;
13455a1d80aSGerd Hoffmann     case INPUT_EVENT_KIND_REL:
13532bafa8fSEric Blake         move = evt->u.rel.data;
13655a1d80aSGerd Hoffmann         event.type  = cpu_to_le16(EV_REL);
137b5a1b443SEric Blake         event.code  = cpu_to_le16(axismap_rel[move->axis]);
138b5a1b443SEric Blake         event.value = cpu_to_le32(move->value);
13955a1d80aSGerd Hoffmann         virtio_input_send(vinput, &event);
14055a1d80aSGerd Hoffmann         break;
14155a1d80aSGerd Hoffmann     case INPUT_EVENT_KIND_ABS:
14232bafa8fSEric Blake         move = evt->u.abs.data;
14355a1d80aSGerd Hoffmann         event.type  = cpu_to_le16(EV_ABS);
144b5a1b443SEric Blake         event.code  = cpu_to_le16(axismap_abs[move->axis]);
145b5a1b443SEric Blake         event.value = cpu_to_le32(move->value);
14655a1d80aSGerd Hoffmann         virtio_input_send(vinput, &event);
14755a1d80aSGerd Hoffmann         break;
1488e9ebd75SSergio Lopez     case INPUT_EVENT_KIND_MTT:
1498e9ebd75SSergio Lopez         mtt = evt->u.mtt.data;
1508e9ebd75SSergio Lopez         if (mtt->type == INPUT_MULTI_TOUCH_TYPE_DATA) {
1518e9ebd75SSergio Lopez             event.type  = cpu_to_le16(EV_ABS);
1528e9ebd75SSergio Lopez             event.code  = cpu_to_le16(axismap_tch[mtt->axis]);
1538e9ebd75SSergio Lopez             event.value = cpu_to_le32(mtt->value);
1548e9ebd75SSergio Lopez             virtio_input_send(vinput, &event);
1558e9ebd75SSergio Lopez         } else {
1568e9ebd75SSergio Lopez             event.type  = cpu_to_le16(EV_ABS);
1578e9ebd75SSergio Lopez             event.code  = cpu_to_le16(ABS_MT_SLOT);
1588e9ebd75SSergio Lopez             event.value = cpu_to_le32(mtt->slot);
1598e9ebd75SSergio Lopez             virtio_input_send(vinput, &event);
1608e9ebd75SSergio Lopez             event.type  = cpu_to_le16(EV_ABS);
1618e9ebd75SSergio Lopez             event.code  = cpu_to_le16(ABS_MT_TRACKING_ID);
1628e9ebd75SSergio Lopez             event.value = cpu_to_le32(mtt->tracking_id);
1638e9ebd75SSergio Lopez             virtio_input_send(vinput, &event);
1648e9ebd75SSergio Lopez         }
1658e9ebd75SSergio Lopez         break;
16655a1d80aSGerd Hoffmann     default:
16755a1d80aSGerd Hoffmann         /* keep gcc happy */
16855a1d80aSGerd Hoffmann         break;
16955a1d80aSGerd Hoffmann     }
17055a1d80aSGerd Hoffmann }
17155a1d80aSGerd Hoffmann 
virtio_input_handle_sync(DeviceState * dev)17255a1d80aSGerd Hoffmann static void virtio_input_handle_sync(DeviceState *dev)
17355a1d80aSGerd Hoffmann {
17455a1d80aSGerd Hoffmann     VirtIOInput *vinput = VIRTIO_INPUT(dev);
17555a1d80aSGerd Hoffmann     virtio_input_event event = {
17655a1d80aSGerd Hoffmann         .type  = cpu_to_le16(EV_SYN),
17755a1d80aSGerd Hoffmann         .code  = cpu_to_le16(SYN_REPORT),
17855a1d80aSGerd Hoffmann         .value = 0,
17955a1d80aSGerd Hoffmann     };
18055a1d80aSGerd Hoffmann 
18155a1d80aSGerd Hoffmann     virtio_input_send(vinput, &event);
18255a1d80aSGerd Hoffmann }
18355a1d80aSGerd Hoffmann 
virtio_input_hid_realize(DeviceState * dev,Error ** errp)18455a1d80aSGerd Hoffmann static void virtio_input_hid_realize(DeviceState *dev, Error **errp)
18555a1d80aSGerd Hoffmann {
18655a1d80aSGerd Hoffmann     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(dev);
1875cce1733SGerd Hoffmann 
18855a1d80aSGerd Hoffmann     vhid->hs = qemu_input_handler_register(dev, vhid->handler);
1895cce1733SGerd Hoffmann     if (vhid->display && vhid->hs) {
1905cce1733SGerd Hoffmann         qemu_input_handler_bind(vhid->hs, vhid->display, vhid->head, NULL);
1915cce1733SGerd Hoffmann     }
19255a1d80aSGerd Hoffmann }
19355a1d80aSGerd Hoffmann 
virtio_input_hid_unrealize(DeviceState * dev)194b69c3c21SMarkus Armbruster static void virtio_input_hid_unrealize(DeviceState *dev)
19555a1d80aSGerd Hoffmann {
19655a1d80aSGerd Hoffmann     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(dev);
19755a1d80aSGerd Hoffmann     qemu_input_handler_unregister(vhid->hs);
19855a1d80aSGerd Hoffmann }
19955a1d80aSGerd Hoffmann 
virtio_input_hid_change_active(VirtIOInput * vinput)20055a1d80aSGerd Hoffmann static void virtio_input_hid_change_active(VirtIOInput *vinput)
20155a1d80aSGerd Hoffmann {
20255a1d80aSGerd Hoffmann     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(vinput);
20355a1d80aSGerd Hoffmann 
20455a1d80aSGerd Hoffmann     if (vinput->active) {
20555a1d80aSGerd Hoffmann         qemu_input_handler_activate(vhid->hs);
20655a1d80aSGerd Hoffmann     } else {
20755a1d80aSGerd Hoffmann         qemu_input_handler_deactivate(vhid->hs);
20855a1d80aSGerd Hoffmann     }
20955a1d80aSGerd Hoffmann }
21055a1d80aSGerd Hoffmann 
virtio_input_hid_handle_status(VirtIOInput * vinput,virtio_input_event * event)21155a1d80aSGerd Hoffmann static void virtio_input_hid_handle_status(VirtIOInput *vinput,
21255a1d80aSGerd Hoffmann                                            virtio_input_event *event)
21355a1d80aSGerd Hoffmann {
21455a1d80aSGerd Hoffmann     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(vinput);
21555a1d80aSGerd Hoffmann     int ledbit = 0;
21655a1d80aSGerd Hoffmann 
21755a1d80aSGerd Hoffmann     switch (le16_to_cpu(event->type)) {
21855a1d80aSGerd Hoffmann     case EV_LED:
21955a1d80aSGerd Hoffmann         if (event->code == LED_NUML) {
22055a1d80aSGerd Hoffmann             ledbit = QEMU_NUM_LOCK_LED;
22155a1d80aSGerd Hoffmann         } else if (event->code == LED_CAPSL) {
22255a1d80aSGerd Hoffmann             ledbit = QEMU_CAPS_LOCK_LED;
22355a1d80aSGerd Hoffmann         } else if (event->code == LED_SCROLLL) {
22455a1d80aSGerd Hoffmann             ledbit = QEMU_SCROLL_LOCK_LED;
22555a1d80aSGerd Hoffmann         }
22655a1d80aSGerd Hoffmann         if (event->value) {
22755a1d80aSGerd Hoffmann             vhid->ledstate |= ledbit;
22855a1d80aSGerd Hoffmann         } else {
22955a1d80aSGerd Hoffmann             vhid->ledstate &= ~ledbit;
23055a1d80aSGerd Hoffmann         }
23155a1d80aSGerd Hoffmann         kbd_put_ledstate(vhid->ledstate);
23255a1d80aSGerd Hoffmann         break;
23355a1d80aSGerd Hoffmann     default:
23455a1d80aSGerd Hoffmann         fprintf(stderr, "%s: unknown type %d\n", __func__,
23555a1d80aSGerd Hoffmann                 le16_to_cpu(event->type));
23655a1d80aSGerd Hoffmann         break;
23755a1d80aSGerd Hoffmann     }
23855a1d80aSGerd Hoffmann }
23955a1d80aSGerd Hoffmann 
2409eb5c799SRichard Henderson static const Property virtio_input_hid_properties[] = {
2415cce1733SGerd Hoffmann     DEFINE_PROP_STRING("display", VirtIOInputHID, display),
2425cce1733SGerd Hoffmann     DEFINE_PROP_UINT32("head", VirtIOInputHID, head, 0),
2435cce1733SGerd Hoffmann };
2445cce1733SGerd Hoffmann 
virtio_input_hid_class_init(ObjectClass * klass,const void * data)245*12d1a768SPhilippe Mathieu-Daudé static void virtio_input_hid_class_init(ObjectClass *klass, const void *data)
24655a1d80aSGerd Hoffmann {
2475cce1733SGerd Hoffmann     DeviceClass *dc = DEVICE_CLASS(klass);
24855a1d80aSGerd Hoffmann     VirtIOInputClass *vic = VIRTIO_INPUT_CLASS(klass);
24955a1d80aSGerd Hoffmann 
2504f67d30bSMarc-André Lureau     device_class_set_props(dc, virtio_input_hid_properties);
25155a1d80aSGerd Hoffmann     vic->realize       = virtio_input_hid_realize;
25255a1d80aSGerd Hoffmann     vic->unrealize     = virtio_input_hid_unrealize;
25355a1d80aSGerd Hoffmann     vic->change_active = virtio_input_hid_change_active;
25455a1d80aSGerd Hoffmann     vic->handle_status = virtio_input_hid_handle_status;
25555a1d80aSGerd Hoffmann }
25655a1d80aSGerd Hoffmann 
25755a1d80aSGerd Hoffmann static const TypeInfo virtio_input_hid_info = {
25855a1d80aSGerd Hoffmann     .name          = TYPE_VIRTIO_INPUT_HID,
25955a1d80aSGerd Hoffmann     .parent        = TYPE_VIRTIO_INPUT,
26055a1d80aSGerd Hoffmann     .instance_size = sizeof(VirtIOInputHID),
26155a1d80aSGerd Hoffmann     .class_init    = virtio_input_hid_class_init,
26255a1d80aSGerd Hoffmann     .abstract      = true,
26355a1d80aSGerd Hoffmann };
26455a1d80aSGerd Hoffmann 
26555a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */
26655a1d80aSGerd Hoffmann 
267b1be65f6SPhilippe Mathieu-Daudé static const QemuInputHandler virtio_keyboard_handler = {
26855a1d80aSGerd Hoffmann     .name  = VIRTIO_ID_NAME_KEYBOARD,
26955a1d80aSGerd Hoffmann     .mask  = INPUT_EVENT_MASK_KEY,
27055a1d80aSGerd Hoffmann     .event = virtio_input_handle_event,
27155a1d80aSGerd Hoffmann     .sync  = virtio_input_handle_sync,
27255a1d80aSGerd Hoffmann };
27355a1d80aSGerd Hoffmann 
27455a1d80aSGerd Hoffmann static struct virtio_input_config virtio_keyboard_config[] = {
27555a1d80aSGerd Hoffmann     {
27655a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_NAME,
27755a1d80aSGerd Hoffmann         .size      = sizeof(VIRTIO_ID_NAME_KEYBOARD),
27855a1d80aSGerd Hoffmann         .u.string  = VIRTIO_ID_NAME_KEYBOARD,
27955a1d80aSGerd Hoffmann     },{
28055a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
28155a1d80aSGerd Hoffmann         .size      = sizeof(struct virtio_input_devids),
28255a1d80aSGerd Hoffmann         .u.ids     = {
28355a1d80aSGerd Hoffmann             .bustype = const_le16(BUS_VIRTUAL),
28455a1d80aSGerd Hoffmann             .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
28555a1d80aSGerd Hoffmann             .product = const_le16(0x0001),
28655a1d80aSGerd Hoffmann             .version = const_le16(0x0001),
28755a1d80aSGerd Hoffmann         },
28855a1d80aSGerd Hoffmann     },{
28955a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_EV_BITS,
29055a1d80aSGerd Hoffmann         .subsel    = EV_REP,
29155a1d80aSGerd Hoffmann         .size      = 1,
29255a1d80aSGerd Hoffmann     },{
29355a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_EV_BITS,
29455a1d80aSGerd Hoffmann         .subsel    = EV_LED,
29555a1d80aSGerd Hoffmann         .size      = 1,
29655a1d80aSGerd Hoffmann         .u.bitmap  = {
29755a1d80aSGerd Hoffmann             (1 << LED_NUML) | (1 << LED_CAPSL) | (1 << LED_SCROLLL),
29855a1d80aSGerd Hoffmann         },
29955a1d80aSGerd Hoffmann     },
30055a1d80aSGerd Hoffmann     { /* end of list */ },
30155a1d80aSGerd Hoffmann };
30255a1d80aSGerd Hoffmann 
virtio_keyboard_init(Object * obj)30355a1d80aSGerd Hoffmann static void virtio_keyboard_init(Object *obj)
30455a1d80aSGerd Hoffmann {
30555a1d80aSGerd Hoffmann     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
30655a1d80aSGerd Hoffmann     VirtIOInput *vinput = VIRTIO_INPUT(obj);
30755a1d80aSGerd Hoffmann 
30855a1d80aSGerd Hoffmann     vhid->handler = &virtio_keyboard_handler;
30955a1d80aSGerd Hoffmann     virtio_input_init_config(vinput, virtio_keyboard_config);
310944ae6d9SSergio Lopez     virtio_input_extend_config(vinput, qemu_input_map_qcode_to_linux,
311944ae6d9SSergio Lopez                                qemu_input_map_qcode_to_linux_len,
312944ae6d9SSergio Lopez                                VIRTIO_INPUT_CFG_EV_BITS, EV_KEY);
31355a1d80aSGerd Hoffmann }
31455a1d80aSGerd Hoffmann 
31555a1d80aSGerd Hoffmann static const TypeInfo virtio_keyboard_info = {
31655a1d80aSGerd Hoffmann     .name          = TYPE_VIRTIO_KEYBOARD,
31755a1d80aSGerd Hoffmann     .parent        = TYPE_VIRTIO_INPUT_HID,
31855a1d80aSGerd Hoffmann     .instance_size = sizeof(VirtIOInputHID),
31955a1d80aSGerd Hoffmann     .instance_init = virtio_keyboard_init,
32055a1d80aSGerd Hoffmann };
32155a1d80aSGerd Hoffmann 
32255a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */
32355a1d80aSGerd Hoffmann 
324b1be65f6SPhilippe Mathieu-Daudé static const QemuInputHandler virtio_mouse_handler = {
32555a1d80aSGerd Hoffmann     .name  = VIRTIO_ID_NAME_MOUSE,
32655a1d80aSGerd Hoffmann     .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
32755a1d80aSGerd Hoffmann     .event = virtio_input_handle_event,
32855a1d80aSGerd Hoffmann     .sync  = virtio_input_handle_sync,
32955a1d80aSGerd Hoffmann };
33055a1d80aSGerd Hoffmann 
331f4924974SGerd Hoffmann static struct virtio_input_config virtio_mouse_config_v1[] = {
33255a1d80aSGerd Hoffmann     {
33355a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_NAME,
33455a1d80aSGerd Hoffmann         .size      = sizeof(VIRTIO_ID_NAME_MOUSE),
33555a1d80aSGerd Hoffmann         .u.string  = VIRTIO_ID_NAME_MOUSE,
33655a1d80aSGerd Hoffmann     },{
33755a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
33855a1d80aSGerd Hoffmann         .size      = sizeof(struct virtio_input_devids),
33955a1d80aSGerd Hoffmann         .u.ids     = {
34055a1d80aSGerd Hoffmann             .bustype = const_le16(BUS_VIRTUAL),
34155a1d80aSGerd Hoffmann             .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
34255a1d80aSGerd Hoffmann             .product = const_le16(0x0002),
34355a1d80aSGerd Hoffmann             .version = const_le16(0x0001),
34455a1d80aSGerd Hoffmann         },
34555a1d80aSGerd Hoffmann     },{
34655a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_EV_BITS,
34755a1d80aSGerd Hoffmann         .subsel    = EV_REL,
34855a1d80aSGerd Hoffmann         .size      = 1,
34955a1d80aSGerd Hoffmann         .u.bitmap  = {
35055a1d80aSGerd Hoffmann             (1 << REL_X) | (1 << REL_Y),
35155a1d80aSGerd Hoffmann         },
35255a1d80aSGerd Hoffmann     },
35355a1d80aSGerd Hoffmann     { /* end of list */ },
35455a1d80aSGerd Hoffmann };
35555a1d80aSGerd Hoffmann 
356f4924974SGerd Hoffmann static struct virtio_input_config virtio_mouse_config_v2[] = {
357f4924974SGerd Hoffmann     {
358f4924974SGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_NAME,
359f4924974SGerd Hoffmann         .size      = sizeof(VIRTIO_ID_NAME_MOUSE),
360f4924974SGerd Hoffmann         .u.string  = VIRTIO_ID_NAME_MOUSE,
361f4924974SGerd Hoffmann     },{
362f4924974SGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
363f4924974SGerd Hoffmann         .size      = sizeof(struct virtio_input_devids),
364f4924974SGerd Hoffmann         .u.ids     = {
365f4924974SGerd Hoffmann             .bustype = const_le16(BUS_VIRTUAL),
366f4924974SGerd Hoffmann             .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
367f4924974SGerd Hoffmann             .product = const_le16(0x0002),
368f4924974SGerd Hoffmann             .version = const_le16(0x0002),
369f4924974SGerd Hoffmann         },
370f4924974SGerd Hoffmann     },{
371f4924974SGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_EV_BITS,
372f4924974SGerd Hoffmann         .subsel    = EV_REL,
373f4924974SGerd Hoffmann         .size      = 2,
374f4924974SGerd Hoffmann         .u.bitmap  = {
375f4924974SGerd Hoffmann             (1 << REL_X) | (1 << REL_Y),
376f4924974SGerd Hoffmann             (1 << (REL_WHEEL - 8))
377f4924974SGerd Hoffmann         },
378f4924974SGerd Hoffmann     },
379f4924974SGerd Hoffmann     { /* end of list */ },
380f4924974SGerd Hoffmann };
381f4924974SGerd Hoffmann 
3829eb5c799SRichard Henderson static const Property virtio_mouse_properties[] = {
383f4924974SGerd Hoffmann     DEFINE_PROP_BOOL("wheel-axis", VirtIOInputHID, wheel_axis, true),
384f4924974SGerd Hoffmann };
385f4924974SGerd Hoffmann 
virtio_mouse_class_init(ObjectClass * klass,const void * data)386*12d1a768SPhilippe Mathieu-Daudé static void virtio_mouse_class_init(ObjectClass *klass, const void *data)
387f4924974SGerd Hoffmann {
388f4924974SGerd Hoffmann     DeviceClass *dc = DEVICE_CLASS(klass);
389f4924974SGerd Hoffmann 
3904f67d30bSMarc-André Lureau     device_class_set_props(dc, virtio_mouse_properties);
391f4924974SGerd Hoffmann }
392f4924974SGerd Hoffmann 
virtio_mouse_init(Object * obj)39355a1d80aSGerd Hoffmann static void virtio_mouse_init(Object *obj)
39455a1d80aSGerd Hoffmann {
39555a1d80aSGerd Hoffmann     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
39655a1d80aSGerd Hoffmann     VirtIOInput *vinput = VIRTIO_INPUT(obj);
39755a1d80aSGerd Hoffmann 
39855a1d80aSGerd Hoffmann     vhid->handler = &virtio_mouse_handler;
399f4924974SGerd Hoffmann     virtio_input_init_config(vinput, vhid->wheel_axis
400f4924974SGerd Hoffmann                              ? virtio_mouse_config_v2
401f4924974SGerd Hoffmann                              : virtio_mouse_config_v1);
402944ae6d9SSergio Lopez     virtio_input_extend_config(vinput, keymap_button,
403944ae6d9SSergio Lopez                                ARRAY_SIZE(keymap_button),
404944ae6d9SSergio Lopez                                VIRTIO_INPUT_CFG_EV_BITS, EV_KEY);
40555a1d80aSGerd Hoffmann }
40655a1d80aSGerd Hoffmann 
40755a1d80aSGerd Hoffmann static const TypeInfo virtio_mouse_info = {
40855a1d80aSGerd Hoffmann     .name          = TYPE_VIRTIO_MOUSE,
40955a1d80aSGerd Hoffmann     .parent        = TYPE_VIRTIO_INPUT_HID,
41055a1d80aSGerd Hoffmann     .instance_size = sizeof(VirtIOInputHID),
41155a1d80aSGerd Hoffmann     .instance_init = virtio_mouse_init,
412f4924974SGerd Hoffmann     .class_init    = virtio_mouse_class_init,
41355a1d80aSGerd Hoffmann };
41455a1d80aSGerd Hoffmann 
41555a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */
41655a1d80aSGerd Hoffmann 
417b1be65f6SPhilippe Mathieu-Daudé static const QemuInputHandler virtio_tablet_handler = {
41855a1d80aSGerd Hoffmann     .name  = VIRTIO_ID_NAME_TABLET,
41955a1d80aSGerd Hoffmann     .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_ABS,
42055a1d80aSGerd Hoffmann     .event = virtio_input_handle_event,
42155a1d80aSGerd Hoffmann     .sync  = virtio_input_handle_sync,
42255a1d80aSGerd Hoffmann };
42355a1d80aSGerd Hoffmann 
424f4924974SGerd Hoffmann static struct virtio_input_config virtio_tablet_config_v1[] = {
42555a1d80aSGerd Hoffmann     {
42655a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_NAME,
42755a1d80aSGerd Hoffmann         .size      = sizeof(VIRTIO_ID_NAME_TABLET),
42855a1d80aSGerd Hoffmann         .u.string  = VIRTIO_ID_NAME_TABLET,
42955a1d80aSGerd Hoffmann     },{
43055a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
43155a1d80aSGerd Hoffmann         .size      = sizeof(struct virtio_input_devids),
43255a1d80aSGerd Hoffmann         .u.ids     = {
43355a1d80aSGerd Hoffmann             .bustype = const_le16(BUS_VIRTUAL),
43455a1d80aSGerd Hoffmann             .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
43555a1d80aSGerd Hoffmann             .product = const_le16(0x0003),
43655a1d80aSGerd Hoffmann             .version = const_le16(0x0001),
43755a1d80aSGerd Hoffmann         },
43855a1d80aSGerd Hoffmann     },{
43955a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_EV_BITS,
44055a1d80aSGerd Hoffmann         .subsel    = EV_ABS,
44155a1d80aSGerd Hoffmann         .size      = 1,
44255a1d80aSGerd Hoffmann         .u.bitmap  = {
44355a1d80aSGerd Hoffmann             (1 << ABS_X) | (1 << ABS_Y),
44455a1d80aSGerd Hoffmann         },
44555a1d80aSGerd Hoffmann     },{
44655a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ABS_INFO,
44755a1d80aSGerd Hoffmann         .subsel    = ABS_X,
44855a1d80aSGerd Hoffmann         .size      = sizeof(virtio_input_absinfo),
4499cfa7ab9SPhilippe Voinov         .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
4509cfa7ab9SPhilippe Voinov         .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
45155a1d80aSGerd Hoffmann     },{
45255a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ABS_INFO,
45355a1d80aSGerd Hoffmann         .subsel    = ABS_Y,
45455a1d80aSGerd Hoffmann         .size      = sizeof(virtio_input_absinfo),
4559cfa7ab9SPhilippe Voinov         .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
4569cfa7ab9SPhilippe Voinov         .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
45755a1d80aSGerd Hoffmann     },
45855a1d80aSGerd Hoffmann     { /* end of list */ },
45955a1d80aSGerd Hoffmann };
46055a1d80aSGerd Hoffmann 
461f4924974SGerd Hoffmann static struct virtio_input_config virtio_tablet_config_v2[] = {
462f4924974SGerd Hoffmann     {
463f4924974SGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_NAME,
464f4924974SGerd Hoffmann         .size      = sizeof(VIRTIO_ID_NAME_TABLET),
465f4924974SGerd Hoffmann         .u.string  = VIRTIO_ID_NAME_TABLET,
466f4924974SGerd Hoffmann     },{
467f4924974SGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
468f4924974SGerd Hoffmann         .size      = sizeof(struct virtio_input_devids),
469f4924974SGerd Hoffmann         .u.ids     = {
470f4924974SGerd Hoffmann             .bustype = const_le16(BUS_VIRTUAL),
471f4924974SGerd Hoffmann             .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
472f4924974SGerd Hoffmann             .product = const_le16(0x0003),
473f4924974SGerd Hoffmann             .version = const_le16(0x0002),
474f4924974SGerd Hoffmann         },
475f4924974SGerd Hoffmann     },{
476f4924974SGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_EV_BITS,
477f4924974SGerd Hoffmann         .subsel    = EV_ABS,
478f4924974SGerd Hoffmann         .size      = 1,
479f4924974SGerd Hoffmann         .u.bitmap  = {
480f4924974SGerd Hoffmann             (1 << ABS_X) | (1 << ABS_Y),
481f4924974SGerd Hoffmann         },
482f4924974SGerd Hoffmann     },{
483f4924974SGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_EV_BITS,
484f4924974SGerd Hoffmann         .subsel    = EV_REL,
485f4924974SGerd Hoffmann         .size      = 2,
486f4924974SGerd Hoffmann         .u.bitmap  = {
487f4924974SGerd Hoffmann             0,
488f4924974SGerd Hoffmann             (1 << (REL_WHEEL - 8))
489f4924974SGerd Hoffmann         },
490f4924974SGerd Hoffmann     },{
491f4924974SGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ABS_INFO,
492f4924974SGerd Hoffmann         .subsel    = ABS_X,
493f4924974SGerd Hoffmann         .size      = sizeof(virtio_input_absinfo),
494f4924974SGerd Hoffmann         .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
495f4924974SGerd Hoffmann         .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
496f4924974SGerd Hoffmann     },{
497f4924974SGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ABS_INFO,
498f4924974SGerd Hoffmann         .subsel    = ABS_Y,
499f4924974SGerd Hoffmann         .size      = sizeof(virtio_input_absinfo),
500f4924974SGerd Hoffmann         .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
501f4924974SGerd Hoffmann         .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
502f4924974SGerd Hoffmann     },
503f4924974SGerd Hoffmann     { /* end of list */ },
504f4924974SGerd Hoffmann };
505f4924974SGerd Hoffmann 
5069eb5c799SRichard Henderson static const Property virtio_tablet_properties[] = {
507f4924974SGerd Hoffmann     DEFINE_PROP_BOOL("wheel-axis", VirtIOInputHID, wheel_axis, true),
508f4924974SGerd Hoffmann };
509f4924974SGerd Hoffmann 
virtio_tablet_class_init(ObjectClass * klass,const void * data)510*12d1a768SPhilippe Mathieu-Daudé static void virtio_tablet_class_init(ObjectClass *klass, const void *data)
511f4924974SGerd Hoffmann {
512f4924974SGerd Hoffmann     DeviceClass *dc = DEVICE_CLASS(klass);
513f4924974SGerd Hoffmann 
5144f67d30bSMarc-André Lureau     device_class_set_props(dc, virtio_tablet_properties);
515f4924974SGerd Hoffmann }
516f4924974SGerd Hoffmann 
virtio_tablet_init(Object * obj)51755a1d80aSGerd Hoffmann static void virtio_tablet_init(Object *obj)
51855a1d80aSGerd Hoffmann {
51955a1d80aSGerd Hoffmann     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
52055a1d80aSGerd Hoffmann     VirtIOInput *vinput = VIRTIO_INPUT(obj);
52155a1d80aSGerd Hoffmann 
52255a1d80aSGerd Hoffmann     vhid->handler = &virtio_tablet_handler;
523f4924974SGerd Hoffmann     virtio_input_init_config(vinput, vhid->wheel_axis
524f4924974SGerd Hoffmann                              ? virtio_tablet_config_v2
525f4924974SGerd Hoffmann                              : virtio_tablet_config_v1);
526944ae6d9SSergio Lopez     virtio_input_extend_config(vinput, keymap_button,
527944ae6d9SSergio Lopez                                ARRAY_SIZE(keymap_button),
528944ae6d9SSergio Lopez                                VIRTIO_INPUT_CFG_EV_BITS, EV_KEY);
52955a1d80aSGerd Hoffmann }
53055a1d80aSGerd Hoffmann 
53155a1d80aSGerd Hoffmann static const TypeInfo virtio_tablet_info = {
53255a1d80aSGerd Hoffmann     .name          = TYPE_VIRTIO_TABLET,
53355a1d80aSGerd Hoffmann     .parent        = TYPE_VIRTIO_INPUT_HID,
53455a1d80aSGerd Hoffmann     .instance_size = sizeof(VirtIOInputHID),
53555a1d80aSGerd Hoffmann     .instance_init = virtio_tablet_init,
536f4924974SGerd Hoffmann     .class_init    = virtio_tablet_class_init,
53755a1d80aSGerd Hoffmann };
53855a1d80aSGerd Hoffmann 
53955a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */
54055a1d80aSGerd Hoffmann 
541b1be65f6SPhilippe Mathieu-Daudé static const QemuInputHandler virtio_multitouch_handler = {
5428e9ebd75SSergio Lopez     .name  = VIRTIO_ID_NAME_MULTITOUCH,
5438e9ebd75SSergio Lopez     .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_MTT,
5448e9ebd75SSergio Lopez     .event = virtio_input_handle_event,
5458e9ebd75SSergio Lopez     .sync  = virtio_input_handle_sync,
5468e9ebd75SSergio Lopez };
5478e9ebd75SSergio Lopez 
5488e9ebd75SSergio Lopez static struct virtio_input_config virtio_multitouch_config[] = {
5498e9ebd75SSergio Lopez     {
5508e9ebd75SSergio Lopez         .select    = VIRTIO_INPUT_CFG_ID_NAME,
5518e9ebd75SSergio Lopez         .size      = sizeof(VIRTIO_ID_NAME_MULTITOUCH),
5528e9ebd75SSergio Lopez         .u.string  = VIRTIO_ID_NAME_MULTITOUCH,
5538e9ebd75SSergio Lopez     },{
5548e9ebd75SSergio Lopez         .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
5558e9ebd75SSergio Lopez         .size      = sizeof(struct virtio_input_devids),
5568e9ebd75SSergio Lopez         .u.ids     = {
5578e9ebd75SSergio Lopez             .bustype = const_le16(BUS_VIRTUAL),
5588e9ebd75SSergio Lopez             .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
5598e9ebd75SSergio Lopez             .product = const_le16(0x0003),
5608e9ebd75SSergio Lopez             .version = const_le16(0x0001),
5618e9ebd75SSergio Lopez         },
5628e9ebd75SSergio Lopez     },{
5638e9ebd75SSergio Lopez         .select    = VIRTIO_INPUT_CFG_ABS_INFO,
5648e9ebd75SSergio Lopez         .subsel    = ABS_MT_SLOT,
5658e9ebd75SSergio Lopez         .size      = sizeof(virtio_input_absinfo),
5668e9ebd75SSergio Lopez         .u.abs.min = const_le32(INPUT_EVENT_SLOTS_MIN),
5678e9ebd75SSergio Lopez         .u.abs.max = const_le32(INPUT_EVENT_SLOTS_MAX),
5688e9ebd75SSergio Lopez     },{
5698e9ebd75SSergio Lopez         .select    = VIRTIO_INPUT_CFG_ABS_INFO,
5708e9ebd75SSergio Lopez         .subsel    = ABS_MT_TRACKING_ID,
5718e9ebd75SSergio Lopez         .size      = sizeof(virtio_input_absinfo),
5728e9ebd75SSergio Lopez         .u.abs.min = const_le32(INPUT_EVENT_SLOTS_MIN),
5738e9ebd75SSergio Lopez         .u.abs.max = const_le32(INPUT_EVENT_SLOTS_MAX),
5748e9ebd75SSergio Lopez     },{
5758e9ebd75SSergio Lopez         .select    = VIRTIO_INPUT_CFG_ABS_INFO,
5768e9ebd75SSergio Lopez         .subsel    = ABS_MT_POSITION_X,
5778e9ebd75SSergio Lopez         .size      = sizeof(virtio_input_absinfo),
5788e9ebd75SSergio Lopez         .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
5798e9ebd75SSergio Lopez         .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
5808e9ebd75SSergio Lopez     },{
5818e9ebd75SSergio Lopez         .select    = VIRTIO_INPUT_CFG_ABS_INFO,
5828e9ebd75SSergio Lopez         .subsel    = ABS_MT_POSITION_Y,
5838e9ebd75SSergio Lopez         .size      = sizeof(virtio_input_absinfo),
5848e9ebd75SSergio Lopez         .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
5858e9ebd75SSergio Lopez         .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
5868e9ebd75SSergio Lopez     },
5878e9ebd75SSergio Lopez     { /* end of list */ },
5888e9ebd75SSergio Lopez };
5898e9ebd75SSergio Lopez 
virtio_multitouch_init(Object * obj)5908e9ebd75SSergio Lopez static void virtio_multitouch_init(Object *obj)
5918e9ebd75SSergio Lopez {
5928e9ebd75SSergio Lopez     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
5938e9ebd75SSergio Lopez     VirtIOInput *vinput = VIRTIO_INPUT(obj);
5948e9ebd75SSergio Lopez     unsigned short abs_props[] = {
5958e9ebd75SSergio Lopez         INPUT_PROP_DIRECT,
5968e9ebd75SSergio Lopez     };
5978e9ebd75SSergio Lopez     unsigned short abs_bits[] = {
5988e9ebd75SSergio Lopez         ABS_MT_SLOT,
5998e9ebd75SSergio Lopez         ABS_MT_TRACKING_ID,
6008e9ebd75SSergio Lopez         ABS_MT_POSITION_X,
6018e9ebd75SSergio Lopez         ABS_MT_POSITION_Y,
6028e9ebd75SSergio Lopez     };
6038e9ebd75SSergio Lopez 
6048e9ebd75SSergio Lopez     vhid->handler = &virtio_multitouch_handler;
6058e9ebd75SSergio Lopez     virtio_input_init_config(vinput, virtio_multitouch_config);
6068e9ebd75SSergio Lopez     virtio_input_extend_config(vinput, keymap_button,
6078e9ebd75SSergio Lopez                                ARRAY_SIZE(keymap_button),
6088e9ebd75SSergio Lopez                                VIRTIO_INPUT_CFG_EV_BITS, EV_KEY);
6098e9ebd75SSergio Lopez     virtio_input_extend_config(vinput, abs_props,
6108e9ebd75SSergio Lopez                                ARRAY_SIZE(abs_props),
6118e9ebd75SSergio Lopez                                VIRTIO_INPUT_CFG_PROP_BITS, 0);
6128e9ebd75SSergio Lopez     virtio_input_extend_config(vinput, abs_bits,
6138e9ebd75SSergio Lopez                                ARRAY_SIZE(abs_bits),
6148e9ebd75SSergio Lopez                                VIRTIO_INPUT_CFG_EV_BITS, EV_ABS);
6158e9ebd75SSergio Lopez }
6168e9ebd75SSergio Lopez 
6178e9ebd75SSergio Lopez static const TypeInfo virtio_multitouch_info = {
6188e9ebd75SSergio Lopez     .name          = TYPE_VIRTIO_MULTITOUCH,
6198e9ebd75SSergio Lopez     .parent        = TYPE_VIRTIO_INPUT_HID,
6208e9ebd75SSergio Lopez     .instance_size = sizeof(VirtIOInputHID),
6218e9ebd75SSergio Lopez     .instance_init = virtio_multitouch_init,
6228e9ebd75SSergio Lopez };
6238e9ebd75SSergio Lopez 
6248e9ebd75SSergio Lopez /* ----------------------------------------------------------------- */
6258e9ebd75SSergio Lopez 
virtio_register_types(void)62655a1d80aSGerd Hoffmann static void virtio_register_types(void)
62755a1d80aSGerd Hoffmann {
62855a1d80aSGerd Hoffmann     type_register_static(&virtio_input_hid_info);
62955a1d80aSGerd Hoffmann     type_register_static(&virtio_keyboard_info);
63055a1d80aSGerd Hoffmann     type_register_static(&virtio_mouse_info);
63155a1d80aSGerd Hoffmann     type_register_static(&virtio_tablet_info);
6328e9ebd75SSergio Lopez     type_register_static(&virtio_multitouch_info);
63355a1d80aSGerd Hoffmann }
63455a1d80aSGerd Hoffmann 
63555a1d80aSGerd Hoffmann type_init(virtio_register_types)
636