xref: /qemu/hw/input/virtio-input-hid.c (revision 8e9ebd7523915900dad0cab6eb807c773c37b5fc)
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"
22*8e9ebd75SSergio 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,
34*8e9ebd75SSergio 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 
47*8e9ebd75SSergio Lopez static const unsigned short axismap_tch[INPUT_AXIS__MAX] = {
48*8e9ebd75SSergio Lopez     [INPUT_AXIS_X]                   = ABS_MT_POSITION_X,
49*8e9ebd75SSergio Lopez     [INPUT_AXIS_Y]                   = ABS_MT_POSITION_Y,
50*8e9ebd75SSergio Lopez };
51*8e9ebd75SSergio Lopez 
5255a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */
5355a1d80aSGerd Hoffmann 
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 
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;
91*8e9ebd75SSergio 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;
148*8e9ebd75SSergio Lopez     case INPUT_EVENT_KIND_MTT:
149*8e9ebd75SSergio Lopez         mtt = evt->u.mtt.data;
150*8e9ebd75SSergio Lopez         if (mtt->type == INPUT_MULTI_TOUCH_TYPE_DATA) {
151*8e9ebd75SSergio Lopez             event.type  = cpu_to_le16(EV_ABS);
152*8e9ebd75SSergio Lopez             event.code  = cpu_to_le16(axismap_tch[mtt->axis]);
153*8e9ebd75SSergio Lopez             event.value = cpu_to_le32(mtt->value);
154*8e9ebd75SSergio Lopez             virtio_input_send(vinput, &event);
155*8e9ebd75SSergio Lopez         } else {
156*8e9ebd75SSergio Lopez             event.type  = cpu_to_le16(EV_ABS);
157*8e9ebd75SSergio Lopez             event.code  = cpu_to_le16(ABS_MT_SLOT);
158*8e9ebd75SSergio Lopez             event.value = cpu_to_le32(mtt->slot);
159*8e9ebd75SSergio Lopez             virtio_input_send(vinput, &event);
160*8e9ebd75SSergio Lopez             event.type  = cpu_to_le16(EV_ABS);
161*8e9ebd75SSergio Lopez             event.code  = cpu_to_le16(ABS_MT_TRACKING_ID);
162*8e9ebd75SSergio Lopez             event.value = cpu_to_le32(mtt->tracking_id);
163*8e9ebd75SSergio Lopez             virtio_input_send(vinput, &event);
164*8e9ebd75SSergio Lopez         }
165*8e9ebd75SSergio Lopez         break;
16655a1d80aSGerd Hoffmann     default:
16755a1d80aSGerd Hoffmann         /* keep gcc happy */
16855a1d80aSGerd Hoffmann         break;
16955a1d80aSGerd Hoffmann     }
17055a1d80aSGerd Hoffmann }
17155a1d80aSGerd Hoffmann 
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 
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 
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 
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 
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 
2405cce1733SGerd Hoffmann static Property virtio_input_hid_properties[] = {
2415cce1733SGerd Hoffmann     DEFINE_PROP_STRING("display", VirtIOInputHID, display),
2425cce1733SGerd Hoffmann     DEFINE_PROP_UINT32("head", VirtIOInputHID, head, 0),
2432a19b229SLin Ma     DEFINE_PROP_END_OF_LIST(),
2445cce1733SGerd Hoffmann };
2455cce1733SGerd Hoffmann 
24655a1d80aSGerd Hoffmann static void virtio_input_hid_class_init(ObjectClass *klass, void *data)
24755a1d80aSGerd Hoffmann {
2485cce1733SGerd Hoffmann     DeviceClass *dc = DEVICE_CLASS(klass);
24955a1d80aSGerd Hoffmann     VirtIOInputClass *vic = VIRTIO_INPUT_CLASS(klass);
25055a1d80aSGerd Hoffmann 
2514f67d30bSMarc-André Lureau     device_class_set_props(dc, virtio_input_hid_properties);
25255a1d80aSGerd Hoffmann     vic->realize       = virtio_input_hid_realize;
25355a1d80aSGerd Hoffmann     vic->unrealize     = virtio_input_hid_unrealize;
25455a1d80aSGerd Hoffmann     vic->change_active = virtio_input_hid_change_active;
25555a1d80aSGerd Hoffmann     vic->handle_status = virtio_input_hid_handle_status;
25655a1d80aSGerd Hoffmann }
25755a1d80aSGerd Hoffmann 
25855a1d80aSGerd Hoffmann static const TypeInfo virtio_input_hid_info = {
25955a1d80aSGerd Hoffmann     .name          = TYPE_VIRTIO_INPUT_HID,
26055a1d80aSGerd Hoffmann     .parent        = TYPE_VIRTIO_INPUT,
26155a1d80aSGerd Hoffmann     .instance_size = sizeof(VirtIOInputHID),
26255a1d80aSGerd Hoffmann     .class_init    = virtio_input_hid_class_init,
26355a1d80aSGerd Hoffmann     .abstract      = true,
26455a1d80aSGerd Hoffmann };
26555a1d80aSGerd Hoffmann 
26655a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */
26755a1d80aSGerd Hoffmann 
26855a1d80aSGerd Hoffmann static QemuInputHandler virtio_keyboard_handler = {
26955a1d80aSGerd Hoffmann     .name  = VIRTIO_ID_NAME_KEYBOARD,
27055a1d80aSGerd Hoffmann     .mask  = INPUT_EVENT_MASK_KEY,
27155a1d80aSGerd Hoffmann     .event = virtio_input_handle_event,
27255a1d80aSGerd Hoffmann     .sync  = virtio_input_handle_sync,
27355a1d80aSGerd Hoffmann };
27455a1d80aSGerd Hoffmann 
27555a1d80aSGerd Hoffmann static struct virtio_input_config virtio_keyboard_config[] = {
27655a1d80aSGerd Hoffmann     {
27755a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_NAME,
27855a1d80aSGerd Hoffmann         .size      = sizeof(VIRTIO_ID_NAME_KEYBOARD),
27955a1d80aSGerd Hoffmann         .u.string  = VIRTIO_ID_NAME_KEYBOARD,
28055a1d80aSGerd Hoffmann     },{
28155a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
28255a1d80aSGerd Hoffmann         .size      = sizeof(struct virtio_input_devids),
28355a1d80aSGerd Hoffmann         .u.ids     = {
28455a1d80aSGerd Hoffmann             .bustype = const_le16(BUS_VIRTUAL),
28555a1d80aSGerd Hoffmann             .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
28655a1d80aSGerd Hoffmann             .product = const_le16(0x0001),
28755a1d80aSGerd Hoffmann             .version = const_le16(0x0001),
28855a1d80aSGerd Hoffmann         },
28955a1d80aSGerd Hoffmann     },{
29055a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_EV_BITS,
29155a1d80aSGerd Hoffmann         .subsel    = EV_REP,
29255a1d80aSGerd Hoffmann         .size      = 1,
29355a1d80aSGerd Hoffmann     },{
29455a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_EV_BITS,
29555a1d80aSGerd Hoffmann         .subsel    = EV_LED,
29655a1d80aSGerd Hoffmann         .size      = 1,
29755a1d80aSGerd Hoffmann         .u.bitmap  = {
29855a1d80aSGerd Hoffmann             (1 << LED_NUML) | (1 << LED_CAPSL) | (1 << LED_SCROLLL),
29955a1d80aSGerd Hoffmann         },
30055a1d80aSGerd Hoffmann     },
30155a1d80aSGerd Hoffmann     { /* end of list */ },
30255a1d80aSGerd Hoffmann };
30355a1d80aSGerd Hoffmann 
30455a1d80aSGerd Hoffmann static void virtio_keyboard_init(Object *obj)
30555a1d80aSGerd Hoffmann {
30655a1d80aSGerd Hoffmann     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
30755a1d80aSGerd Hoffmann     VirtIOInput *vinput = VIRTIO_INPUT(obj);
30855a1d80aSGerd Hoffmann 
30955a1d80aSGerd Hoffmann     vhid->handler = &virtio_keyboard_handler;
31055a1d80aSGerd Hoffmann     virtio_input_init_config(vinput, virtio_keyboard_config);
311944ae6d9SSergio Lopez     virtio_input_extend_config(vinput, qemu_input_map_qcode_to_linux,
312944ae6d9SSergio Lopez                                qemu_input_map_qcode_to_linux_len,
313944ae6d9SSergio Lopez                                VIRTIO_INPUT_CFG_EV_BITS, EV_KEY);
31455a1d80aSGerd Hoffmann }
31555a1d80aSGerd Hoffmann 
31655a1d80aSGerd Hoffmann static const TypeInfo virtio_keyboard_info = {
31755a1d80aSGerd Hoffmann     .name          = TYPE_VIRTIO_KEYBOARD,
31855a1d80aSGerd Hoffmann     .parent        = TYPE_VIRTIO_INPUT_HID,
31955a1d80aSGerd Hoffmann     .instance_size = sizeof(VirtIOInputHID),
32055a1d80aSGerd Hoffmann     .instance_init = virtio_keyboard_init,
32155a1d80aSGerd Hoffmann };
32255a1d80aSGerd Hoffmann 
32355a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */
32455a1d80aSGerd Hoffmann 
32555a1d80aSGerd Hoffmann static QemuInputHandler virtio_mouse_handler = {
32655a1d80aSGerd Hoffmann     .name  = VIRTIO_ID_NAME_MOUSE,
32755a1d80aSGerd Hoffmann     .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_REL,
32855a1d80aSGerd Hoffmann     .event = virtio_input_handle_event,
32955a1d80aSGerd Hoffmann     .sync  = virtio_input_handle_sync,
33055a1d80aSGerd Hoffmann };
33155a1d80aSGerd Hoffmann 
332f4924974SGerd Hoffmann static struct virtio_input_config virtio_mouse_config_v1[] = {
33355a1d80aSGerd Hoffmann     {
33455a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_NAME,
33555a1d80aSGerd Hoffmann         .size      = sizeof(VIRTIO_ID_NAME_MOUSE),
33655a1d80aSGerd Hoffmann         .u.string  = VIRTIO_ID_NAME_MOUSE,
33755a1d80aSGerd Hoffmann     },{
33855a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
33955a1d80aSGerd Hoffmann         .size      = sizeof(struct virtio_input_devids),
34055a1d80aSGerd Hoffmann         .u.ids     = {
34155a1d80aSGerd Hoffmann             .bustype = const_le16(BUS_VIRTUAL),
34255a1d80aSGerd Hoffmann             .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
34355a1d80aSGerd Hoffmann             .product = const_le16(0x0002),
34455a1d80aSGerd Hoffmann             .version = const_le16(0x0001),
34555a1d80aSGerd Hoffmann         },
34655a1d80aSGerd Hoffmann     },{
34755a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_EV_BITS,
34855a1d80aSGerd Hoffmann         .subsel    = EV_REL,
34955a1d80aSGerd Hoffmann         .size      = 1,
35055a1d80aSGerd Hoffmann         .u.bitmap  = {
35155a1d80aSGerd Hoffmann             (1 << REL_X) | (1 << REL_Y),
35255a1d80aSGerd Hoffmann         },
35355a1d80aSGerd Hoffmann     },
35455a1d80aSGerd Hoffmann     { /* end of list */ },
35555a1d80aSGerd Hoffmann };
35655a1d80aSGerd Hoffmann 
357f4924974SGerd Hoffmann static struct virtio_input_config virtio_mouse_config_v2[] = {
358f4924974SGerd Hoffmann     {
359f4924974SGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_NAME,
360f4924974SGerd Hoffmann         .size      = sizeof(VIRTIO_ID_NAME_MOUSE),
361f4924974SGerd Hoffmann         .u.string  = VIRTIO_ID_NAME_MOUSE,
362f4924974SGerd Hoffmann     },{
363f4924974SGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
364f4924974SGerd Hoffmann         .size      = sizeof(struct virtio_input_devids),
365f4924974SGerd Hoffmann         .u.ids     = {
366f4924974SGerd Hoffmann             .bustype = const_le16(BUS_VIRTUAL),
367f4924974SGerd Hoffmann             .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
368f4924974SGerd Hoffmann             .product = const_le16(0x0002),
369f4924974SGerd Hoffmann             .version = const_le16(0x0002),
370f4924974SGerd Hoffmann         },
371f4924974SGerd Hoffmann     },{
372f4924974SGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_EV_BITS,
373f4924974SGerd Hoffmann         .subsel    = EV_REL,
374f4924974SGerd Hoffmann         .size      = 2,
375f4924974SGerd Hoffmann         .u.bitmap  = {
376f4924974SGerd Hoffmann             (1 << REL_X) | (1 << REL_Y),
377f4924974SGerd Hoffmann             (1 << (REL_WHEEL - 8))
378f4924974SGerd Hoffmann         },
379f4924974SGerd Hoffmann     },
380f4924974SGerd Hoffmann     { /* end of list */ },
381f4924974SGerd Hoffmann };
382f4924974SGerd Hoffmann 
383f4924974SGerd Hoffmann static Property virtio_mouse_properties[] = {
384f4924974SGerd Hoffmann     DEFINE_PROP_BOOL("wheel-axis", VirtIOInputHID, wheel_axis, true),
385f4924974SGerd Hoffmann     DEFINE_PROP_END_OF_LIST(),
386f4924974SGerd Hoffmann };
387f4924974SGerd Hoffmann 
388f4924974SGerd Hoffmann static void virtio_mouse_class_init(ObjectClass *klass, void *data)
389f4924974SGerd Hoffmann {
390f4924974SGerd Hoffmann     DeviceClass *dc = DEVICE_CLASS(klass);
391f4924974SGerd Hoffmann 
3924f67d30bSMarc-André Lureau     device_class_set_props(dc, virtio_mouse_properties);
393f4924974SGerd Hoffmann }
394f4924974SGerd Hoffmann 
39555a1d80aSGerd Hoffmann static void virtio_mouse_init(Object *obj)
39655a1d80aSGerd Hoffmann {
39755a1d80aSGerd Hoffmann     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
39855a1d80aSGerd Hoffmann     VirtIOInput *vinput = VIRTIO_INPUT(obj);
39955a1d80aSGerd Hoffmann 
40055a1d80aSGerd Hoffmann     vhid->handler = &virtio_mouse_handler;
401f4924974SGerd Hoffmann     virtio_input_init_config(vinput, vhid->wheel_axis
402f4924974SGerd Hoffmann                              ? virtio_mouse_config_v2
403f4924974SGerd Hoffmann                              : virtio_mouse_config_v1);
404944ae6d9SSergio Lopez     virtio_input_extend_config(vinput, keymap_button,
405944ae6d9SSergio Lopez                                ARRAY_SIZE(keymap_button),
406944ae6d9SSergio Lopez                                VIRTIO_INPUT_CFG_EV_BITS, EV_KEY);
40755a1d80aSGerd Hoffmann }
40855a1d80aSGerd Hoffmann 
40955a1d80aSGerd Hoffmann static const TypeInfo virtio_mouse_info = {
41055a1d80aSGerd Hoffmann     .name          = TYPE_VIRTIO_MOUSE,
41155a1d80aSGerd Hoffmann     .parent        = TYPE_VIRTIO_INPUT_HID,
41255a1d80aSGerd Hoffmann     .instance_size = sizeof(VirtIOInputHID),
41355a1d80aSGerd Hoffmann     .instance_init = virtio_mouse_init,
414f4924974SGerd Hoffmann     .class_init    = virtio_mouse_class_init,
41555a1d80aSGerd Hoffmann };
41655a1d80aSGerd Hoffmann 
41755a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */
41855a1d80aSGerd Hoffmann 
41955a1d80aSGerd Hoffmann static QemuInputHandler virtio_tablet_handler = {
42055a1d80aSGerd Hoffmann     .name  = VIRTIO_ID_NAME_TABLET,
42155a1d80aSGerd Hoffmann     .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_ABS,
42255a1d80aSGerd Hoffmann     .event = virtio_input_handle_event,
42355a1d80aSGerd Hoffmann     .sync  = virtio_input_handle_sync,
42455a1d80aSGerd Hoffmann };
42555a1d80aSGerd Hoffmann 
426f4924974SGerd Hoffmann static struct virtio_input_config virtio_tablet_config_v1[] = {
42755a1d80aSGerd Hoffmann     {
42855a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_NAME,
42955a1d80aSGerd Hoffmann         .size      = sizeof(VIRTIO_ID_NAME_TABLET),
43055a1d80aSGerd Hoffmann         .u.string  = VIRTIO_ID_NAME_TABLET,
43155a1d80aSGerd Hoffmann     },{
43255a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
43355a1d80aSGerd Hoffmann         .size      = sizeof(struct virtio_input_devids),
43455a1d80aSGerd Hoffmann         .u.ids     = {
43555a1d80aSGerd Hoffmann             .bustype = const_le16(BUS_VIRTUAL),
43655a1d80aSGerd Hoffmann             .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
43755a1d80aSGerd Hoffmann             .product = const_le16(0x0003),
43855a1d80aSGerd Hoffmann             .version = const_le16(0x0001),
43955a1d80aSGerd Hoffmann         },
44055a1d80aSGerd Hoffmann     },{
44155a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_EV_BITS,
44255a1d80aSGerd Hoffmann         .subsel    = EV_ABS,
44355a1d80aSGerd Hoffmann         .size      = 1,
44455a1d80aSGerd Hoffmann         .u.bitmap  = {
44555a1d80aSGerd Hoffmann             (1 << ABS_X) | (1 << ABS_Y),
44655a1d80aSGerd Hoffmann         },
44755a1d80aSGerd Hoffmann     },{
44855a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ABS_INFO,
44955a1d80aSGerd Hoffmann         .subsel    = ABS_X,
45055a1d80aSGerd Hoffmann         .size      = sizeof(virtio_input_absinfo),
4519cfa7ab9SPhilippe Voinov         .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
4529cfa7ab9SPhilippe Voinov         .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
45355a1d80aSGerd Hoffmann     },{
45455a1d80aSGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ABS_INFO,
45555a1d80aSGerd Hoffmann         .subsel    = ABS_Y,
45655a1d80aSGerd Hoffmann         .size      = sizeof(virtio_input_absinfo),
4579cfa7ab9SPhilippe Voinov         .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
4589cfa7ab9SPhilippe Voinov         .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
45955a1d80aSGerd Hoffmann     },
46055a1d80aSGerd Hoffmann     { /* end of list */ },
46155a1d80aSGerd Hoffmann };
46255a1d80aSGerd Hoffmann 
463f4924974SGerd Hoffmann static struct virtio_input_config virtio_tablet_config_v2[] = {
464f4924974SGerd Hoffmann     {
465f4924974SGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_NAME,
466f4924974SGerd Hoffmann         .size      = sizeof(VIRTIO_ID_NAME_TABLET),
467f4924974SGerd Hoffmann         .u.string  = VIRTIO_ID_NAME_TABLET,
468f4924974SGerd Hoffmann     },{
469f4924974SGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
470f4924974SGerd Hoffmann         .size      = sizeof(struct virtio_input_devids),
471f4924974SGerd Hoffmann         .u.ids     = {
472f4924974SGerd Hoffmann             .bustype = const_le16(BUS_VIRTUAL),
473f4924974SGerd Hoffmann             .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
474f4924974SGerd Hoffmann             .product = const_le16(0x0003),
475f4924974SGerd Hoffmann             .version = const_le16(0x0002),
476f4924974SGerd Hoffmann         },
477f4924974SGerd Hoffmann     },{
478f4924974SGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_EV_BITS,
479f4924974SGerd Hoffmann         .subsel    = EV_ABS,
480f4924974SGerd Hoffmann         .size      = 1,
481f4924974SGerd Hoffmann         .u.bitmap  = {
482f4924974SGerd Hoffmann             (1 << ABS_X) | (1 << ABS_Y),
483f4924974SGerd Hoffmann         },
484f4924974SGerd Hoffmann     },{
485f4924974SGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_EV_BITS,
486f4924974SGerd Hoffmann         .subsel    = EV_REL,
487f4924974SGerd Hoffmann         .size      = 2,
488f4924974SGerd Hoffmann         .u.bitmap  = {
489f4924974SGerd Hoffmann             0,
490f4924974SGerd Hoffmann             (1 << (REL_WHEEL - 8))
491f4924974SGerd Hoffmann         },
492f4924974SGerd Hoffmann     },{
493f4924974SGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ABS_INFO,
494f4924974SGerd Hoffmann         .subsel    = ABS_X,
495f4924974SGerd Hoffmann         .size      = sizeof(virtio_input_absinfo),
496f4924974SGerd Hoffmann         .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
497f4924974SGerd Hoffmann         .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
498f4924974SGerd Hoffmann     },{
499f4924974SGerd Hoffmann         .select    = VIRTIO_INPUT_CFG_ABS_INFO,
500f4924974SGerd Hoffmann         .subsel    = ABS_Y,
501f4924974SGerd Hoffmann         .size      = sizeof(virtio_input_absinfo),
502f4924974SGerd Hoffmann         .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
503f4924974SGerd Hoffmann         .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
504f4924974SGerd Hoffmann     },
505f4924974SGerd Hoffmann     { /* end of list */ },
506f4924974SGerd Hoffmann };
507f4924974SGerd Hoffmann 
508f4924974SGerd Hoffmann static Property virtio_tablet_properties[] = {
509f4924974SGerd Hoffmann     DEFINE_PROP_BOOL("wheel-axis", VirtIOInputHID, wheel_axis, true),
510f4924974SGerd Hoffmann     DEFINE_PROP_END_OF_LIST(),
511f4924974SGerd Hoffmann };
512f4924974SGerd Hoffmann 
513f4924974SGerd Hoffmann static void virtio_tablet_class_init(ObjectClass *klass, void *data)
514f4924974SGerd Hoffmann {
515f4924974SGerd Hoffmann     DeviceClass *dc = DEVICE_CLASS(klass);
516f4924974SGerd Hoffmann 
5174f67d30bSMarc-André Lureau     device_class_set_props(dc, virtio_tablet_properties);
518f4924974SGerd Hoffmann }
519f4924974SGerd Hoffmann 
52055a1d80aSGerd Hoffmann static void virtio_tablet_init(Object *obj)
52155a1d80aSGerd Hoffmann {
52255a1d80aSGerd Hoffmann     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
52355a1d80aSGerd Hoffmann     VirtIOInput *vinput = VIRTIO_INPUT(obj);
52455a1d80aSGerd Hoffmann 
52555a1d80aSGerd Hoffmann     vhid->handler = &virtio_tablet_handler;
526f4924974SGerd Hoffmann     virtio_input_init_config(vinput, vhid->wheel_axis
527f4924974SGerd Hoffmann                              ? virtio_tablet_config_v2
528f4924974SGerd Hoffmann                              : virtio_tablet_config_v1);
529944ae6d9SSergio Lopez     virtio_input_extend_config(vinput, keymap_button,
530944ae6d9SSergio Lopez                                ARRAY_SIZE(keymap_button),
531944ae6d9SSergio Lopez                                VIRTIO_INPUT_CFG_EV_BITS, EV_KEY);
53255a1d80aSGerd Hoffmann }
53355a1d80aSGerd Hoffmann 
53455a1d80aSGerd Hoffmann static const TypeInfo virtio_tablet_info = {
53555a1d80aSGerd Hoffmann     .name          = TYPE_VIRTIO_TABLET,
53655a1d80aSGerd Hoffmann     .parent        = TYPE_VIRTIO_INPUT_HID,
53755a1d80aSGerd Hoffmann     .instance_size = sizeof(VirtIOInputHID),
53855a1d80aSGerd Hoffmann     .instance_init = virtio_tablet_init,
539f4924974SGerd Hoffmann     .class_init    = virtio_tablet_class_init,
54055a1d80aSGerd Hoffmann };
54155a1d80aSGerd Hoffmann 
54255a1d80aSGerd Hoffmann /* ----------------------------------------------------------------- */
54355a1d80aSGerd Hoffmann 
544*8e9ebd75SSergio Lopez static QemuInputHandler virtio_multitouch_handler = {
545*8e9ebd75SSergio Lopez     .name  = VIRTIO_ID_NAME_MULTITOUCH,
546*8e9ebd75SSergio Lopez     .mask  = INPUT_EVENT_MASK_BTN | INPUT_EVENT_MASK_MTT,
547*8e9ebd75SSergio Lopez     .event = virtio_input_handle_event,
548*8e9ebd75SSergio Lopez     .sync  = virtio_input_handle_sync,
549*8e9ebd75SSergio Lopez };
550*8e9ebd75SSergio Lopez 
551*8e9ebd75SSergio Lopez static struct virtio_input_config virtio_multitouch_config[] = {
552*8e9ebd75SSergio Lopez     {
553*8e9ebd75SSergio Lopez         .select    = VIRTIO_INPUT_CFG_ID_NAME,
554*8e9ebd75SSergio Lopez         .size      = sizeof(VIRTIO_ID_NAME_MULTITOUCH),
555*8e9ebd75SSergio Lopez         .u.string  = VIRTIO_ID_NAME_MULTITOUCH,
556*8e9ebd75SSergio Lopez     },{
557*8e9ebd75SSergio Lopez         .select    = VIRTIO_INPUT_CFG_ID_DEVIDS,
558*8e9ebd75SSergio Lopez         .size      = sizeof(struct virtio_input_devids),
559*8e9ebd75SSergio Lopez         .u.ids     = {
560*8e9ebd75SSergio Lopez             .bustype = const_le16(BUS_VIRTUAL),
561*8e9ebd75SSergio Lopez             .vendor  = const_le16(0x0627), /* same we use for usb hid devices */
562*8e9ebd75SSergio Lopez             .product = const_le16(0x0003),
563*8e9ebd75SSergio Lopez             .version = const_le16(0x0001),
564*8e9ebd75SSergio Lopez         },
565*8e9ebd75SSergio Lopez     },{
566*8e9ebd75SSergio Lopez         .select    = VIRTIO_INPUT_CFG_ABS_INFO,
567*8e9ebd75SSergio Lopez         .subsel    = ABS_MT_SLOT,
568*8e9ebd75SSergio Lopez         .size      = sizeof(virtio_input_absinfo),
569*8e9ebd75SSergio Lopez         .u.abs.min = const_le32(INPUT_EVENT_SLOTS_MIN),
570*8e9ebd75SSergio Lopez         .u.abs.max = const_le32(INPUT_EVENT_SLOTS_MAX),
571*8e9ebd75SSergio Lopez     },{
572*8e9ebd75SSergio Lopez         .select    = VIRTIO_INPUT_CFG_ABS_INFO,
573*8e9ebd75SSergio Lopez         .subsel    = ABS_MT_TRACKING_ID,
574*8e9ebd75SSergio Lopez         .size      = sizeof(virtio_input_absinfo),
575*8e9ebd75SSergio Lopez         .u.abs.min = const_le32(INPUT_EVENT_SLOTS_MIN),
576*8e9ebd75SSergio Lopez         .u.abs.max = const_le32(INPUT_EVENT_SLOTS_MAX),
577*8e9ebd75SSergio Lopez     },{
578*8e9ebd75SSergio Lopez         .select    = VIRTIO_INPUT_CFG_ABS_INFO,
579*8e9ebd75SSergio Lopez         .subsel    = ABS_MT_POSITION_X,
580*8e9ebd75SSergio Lopez         .size      = sizeof(virtio_input_absinfo),
581*8e9ebd75SSergio Lopez         .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
582*8e9ebd75SSergio Lopez         .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
583*8e9ebd75SSergio Lopez     },{
584*8e9ebd75SSergio Lopez         .select    = VIRTIO_INPUT_CFG_ABS_INFO,
585*8e9ebd75SSergio Lopez         .subsel    = ABS_MT_POSITION_Y,
586*8e9ebd75SSergio Lopez         .size      = sizeof(virtio_input_absinfo),
587*8e9ebd75SSergio Lopez         .u.abs.min = const_le32(INPUT_EVENT_ABS_MIN),
588*8e9ebd75SSergio Lopez         .u.abs.max = const_le32(INPUT_EVENT_ABS_MAX),
589*8e9ebd75SSergio Lopez     },
590*8e9ebd75SSergio Lopez     { /* end of list */ },
591*8e9ebd75SSergio Lopez };
592*8e9ebd75SSergio Lopez 
593*8e9ebd75SSergio Lopez static void virtio_multitouch_init(Object *obj)
594*8e9ebd75SSergio Lopez {
595*8e9ebd75SSergio Lopez     VirtIOInputHID *vhid = VIRTIO_INPUT_HID(obj);
596*8e9ebd75SSergio Lopez     VirtIOInput *vinput = VIRTIO_INPUT(obj);
597*8e9ebd75SSergio Lopez     unsigned short abs_props[] = {
598*8e9ebd75SSergio Lopez         INPUT_PROP_DIRECT,
599*8e9ebd75SSergio Lopez     };
600*8e9ebd75SSergio Lopez     unsigned short abs_bits[] = {
601*8e9ebd75SSergio Lopez         ABS_MT_SLOT,
602*8e9ebd75SSergio Lopez         ABS_MT_TRACKING_ID,
603*8e9ebd75SSergio Lopez         ABS_MT_POSITION_X,
604*8e9ebd75SSergio Lopez         ABS_MT_POSITION_Y,
605*8e9ebd75SSergio Lopez     };
606*8e9ebd75SSergio Lopez 
607*8e9ebd75SSergio Lopez     vhid->handler = &virtio_multitouch_handler;
608*8e9ebd75SSergio Lopez     virtio_input_init_config(vinput, virtio_multitouch_config);
609*8e9ebd75SSergio Lopez     virtio_input_extend_config(vinput, keymap_button,
610*8e9ebd75SSergio Lopez                                ARRAY_SIZE(keymap_button),
611*8e9ebd75SSergio Lopez                                VIRTIO_INPUT_CFG_EV_BITS, EV_KEY);
612*8e9ebd75SSergio Lopez     virtio_input_extend_config(vinput, abs_props,
613*8e9ebd75SSergio Lopez                                ARRAY_SIZE(abs_props),
614*8e9ebd75SSergio Lopez                                VIRTIO_INPUT_CFG_PROP_BITS, 0);
615*8e9ebd75SSergio Lopez     virtio_input_extend_config(vinput, abs_bits,
616*8e9ebd75SSergio Lopez                                ARRAY_SIZE(abs_bits),
617*8e9ebd75SSergio Lopez                                VIRTIO_INPUT_CFG_EV_BITS, EV_ABS);
618*8e9ebd75SSergio Lopez }
619*8e9ebd75SSergio Lopez 
620*8e9ebd75SSergio Lopez static const TypeInfo virtio_multitouch_info = {
621*8e9ebd75SSergio Lopez     .name          = TYPE_VIRTIO_MULTITOUCH,
622*8e9ebd75SSergio Lopez     .parent        = TYPE_VIRTIO_INPUT_HID,
623*8e9ebd75SSergio Lopez     .instance_size = sizeof(VirtIOInputHID),
624*8e9ebd75SSergio Lopez     .instance_init = virtio_multitouch_init,
625*8e9ebd75SSergio Lopez };
626*8e9ebd75SSergio Lopez 
627*8e9ebd75SSergio Lopez /* ----------------------------------------------------------------- */
628*8e9ebd75SSergio Lopez 
62955a1d80aSGerd Hoffmann static void virtio_register_types(void)
63055a1d80aSGerd Hoffmann {
63155a1d80aSGerd Hoffmann     type_register_static(&virtio_input_hid_info);
63255a1d80aSGerd Hoffmann     type_register_static(&virtio_keyboard_info);
63355a1d80aSGerd Hoffmann     type_register_static(&virtio_mouse_info);
63455a1d80aSGerd Hoffmann     type_register_static(&virtio_tablet_info);
635*8e9ebd75SSergio Lopez     type_register_static(&virtio_multitouch_info);
63655a1d80aSGerd Hoffmann }
63755a1d80aSGerd Hoffmann 
63855a1d80aSGerd Hoffmann type_init(virtio_register_types)
639