"maru_virtio_input" contains touchscreen, keyboard, hwkey now.
"rotary" will be added soon.
Change-Id: I6a8983e8d7e6e78489ec06d77497042f85d823d7
Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
#include "eventcast/common.h"
#include "eventcast/sensor.h"
#include "eventcast/touch.h"
-#include "hw/virtio/maru_virtio_touchscreen.h"
-#include "hw/virtio/maru_virtio_hwkey.h"
+#include "hw/virtio/maru_virtio_input.h"
#include "util/new_debug_ch.h"
#include "emulator.h"
#include "emulator_options.h"
-#include "hw/virtio/maru_virtio_touchscreen.h"
+#include "hw/virtio/maru_virtio_input.h"
#include "hw/virtio/maru_virtio_evdi.h"
#include "util/net_helper.h"
#include "util/new_debug_ch.h"
obj-y += maru_virtio_pci.o
-obj-y += maru_virtio_touchscreen.o
+obj-y += maru_virtio_input.o
obj-y += maru_virtio_evdi.o
-obj-y += maru_virtio_hwkey.o
obj-y += maru_virtio_jack.o
-obj-y += maru_virtio_keyboard.o
obj-y += maru_virtio_nfc.o
obj-y += maru_virtio_power.o
obj-y += maru_virtio_sensor.o
+++ /dev/null
-/*
- * Maru Virtio HW Key Device
- *
- * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- * GiWoong Kim <giwoong.kim@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-
-#include <pthread.h>
-#include "emul_state.h"
-#include "maru_virtio_hwkey.h"
-#include "hw/maru_device_ids.h"
-#include "debug_ch.h"
-
-MULTI_DEBUG_CHANNEL(qemu, hwkey);
-
-#define DEVICE_NAME "virtio-hwkey"
-#define MAX_BUF_COUNT 64
-static int vqidx;
-/*
- * HW key event queue
- */
-typedef struct HwKeyEventEntry {
- unsigned int index;
- EmulHWKeyEvent hwkey;
-
- QTAILQ_ENTRY(HwKeyEventEntry) node;
-} HwKeyEventEntry;
-
-/* the maximum number of HW key event that can be put into a queue */
-#define MAX_HWKEY_EVENT_CNT 64
-
-static HwKeyEventEntry _events_buf[MAX_HWKEY_EVENT_CNT];
-static QTAILQ_HEAD(, HwKeyEventEntry) events_queue =
- QTAILQ_HEAD_INITIALIZER(events_queue);
-
-static unsigned int event_ringbuf_cnt; /* _events_buf */
-static unsigned int event_queue_cnt; /* events_queue */
-
-/*
- * VirtQueueElement queue
- */
-typedef struct ElementEntry {
- unsigned int el_index;
- unsigned int sg_index;
- VirtQueueElement elem;
-
- QTAILQ_ENTRY(ElementEntry) node;
-} ElementEntry;
-
-static QTAILQ_HEAD(, ElementEntry) elem_queue =
- QTAILQ_HEAD_INITIALIZER(elem_queue);
-
-static unsigned int elem_ringbuf_cnt; /* _elem_buf */
-static unsigned int elem_queue_cnt; /* elem_queue */
-
-VirtIOHWKey *vhk;
-VirtQueueElement elem_vhk;
-
-/* lock for between communication thread and IO thread */
-static pthread_mutex_t event_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-void maru_hwkey_event(int event_type, int keycode)
-{
- HwKeyEventEntry *entry = NULL;
-
- if (!vhk) {
- INFO("Hwkey device can not be used.\n");
- return;
- }
-
- if (unlikely(event_queue_cnt >= MAX_HWKEY_EVENT_CNT)) {
- INFO("full hwkey event queue, lose event\n", event_queue_cnt);
-
- qemu_bh_schedule(vhk->bh);
- return;
- }
-
- entry = &(_events_buf[event_ringbuf_cnt % MAX_HWKEY_EVENT_CNT]);
-
- /* hwkey event is copied into the queue */
- entry->hwkey.keycode = keycode;
- entry->hwkey.event_type = event_type;
-
- pthread_mutex_lock(&event_mutex);
-
- event_ringbuf_cnt++;
-
- /* 1 ~ */
- entry->index = ++event_queue_cnt;
-
- QTAILQ_INSERT_TAIL(&events_queue, entry, node);
-
- pthread_mutex_unlock(&event_mutex);
-
- /* call maru_virtio_hwkey_notify */
- qemu_bh_schedule(vhk->bh);
-
- TRACE("hwkey event (%d) : keycode=%d, event_type=%d\n",
- entry->index, entry->hwkey.keycode, entry->hwkey.event_type);
-}
-
-static void maru_virtio_hwkey_handle(VirtIODevice *vdev, VirtQueue *vq)
-{
- int virt_sg_index = 0;
-
- TRACE("maru_virtio_hwkey_handle\n");
-
- if (unlikely(virtio_queue_empty(vhk->vq))) {
- TRACE("virtqueue is empty\n");
- return;
- }
- /* Get a queue buffer which is written by guest side. */
- do {
- virt_sg_index = virtqueue_pop(vq, &elem_vhk);
- TRACE("virtqueue pop.\n");
- } while (virt_sg_index < MAX_BUF_COUNT);
-}
-
-void maru_virtio_hwkey_notify(void)
-{
- HwKeyEventEntry *event_entry = NULL;
-
- TRACE("maru_virtio_hwkey_notify\n");
-
- if (unlikely(!virtio_queue_ready(vhk->vq))) {
- ERR("virtio queue is not ready\n");
- return;
- }
-
- while (true) {
- if (event_queue_cnt == 0) {
- TRACE("no event\n");
- break;
- }
-
- /* get hwkey event from host queue */
- event_entry = QTAILQ_FIRST(&events_queue);
-
- TRACE("keycode=%d, event_type=%d, event_queue_cnt=%d, vqidx=%d\n",
- event_entry->hwkey.keycode, event_entry->hwkey.event_type,
- event_queue_cnt, vqidx);
-
- /* copy event into virtio buffer */
- memcpy(elem_vhk.in_sg[vqidx++].iov_base, &(event_entry->hwkey),
- sizeof(EmulHWKeyEvent));
- if (vqidx == MAX_BUF_COUNT) {
- vqidx = 0;
- }
-
- virtqueue_push(vhk->vq, &elem_vhk, sizeof(EmulHWKeyEvent));
- virtio_notify(&vhk->vdev, vhk->vq);
-
- pthread_mutex_lock(&event_mutex);
-
- /* remove host event */
- QTAILQ_REMOVE(&events_queue, event_entry, node);
- event_queue_cnt--;
-
- pthread_mutex_unlock(&event_mutex);
- }
-}
-
-static uint64_t virtio_hwkey_get_features(
- VirtIODevice *vdev, uint64_t request_features, Error **errp)
-{
- return request_features;
-}
-
-static void maru_hwkey_bh(void *opaque)
-{
- maru_virtio_hwkey_notify();
-}
-
-static void virtio_hwkey_device_realize(DeviceState *dev, Error **errp)
-{
- INFO("initialize the hwkey device\n");
- VirtIODevice *vdev = VIRTIO_DEVICE(dev);
- vhk = VIRTIO_MARU_HWKEY(dev);
-
- if (vdev == NULL) {
- ERR("failed to initialize the hwkey device\n");
- return;
- }
-
- virtio_init(vdev, TYPE_VIRTIO_MARU_HWKEY, VIRTIO_ID_MARU_HWKEY, 0);
-
- vhk->vq = virtio_add_queue(vdev, MAX_BUF_COUNT, maru_virtio_hwkey_handle);
-
- vhk->qdev = dev;
-
- /* reset the counters */
- pthread_mutex_lock(&event_mutex);
- event_queue_cnt = event_ringbuf_cnt = 0;
- pthread_mutex_unlock(&event_mutex);
-
- elem_queue_cnt = elem_ringbuf_cnt = 0;
-
- /* bottom-half */
- vhk->bh = qemu_bh_new(maru_hwkey_bh, vhk);
-}
-
-static void virtio_hwkey_device_unrealize(DeviceState *dev, Error **errp)
-{
- VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-
- INFO("exit the hwkey device\n");
-
- if (vhk->bh) {
- qemu_bh_delete(vhk->bh);
- }
-
- virtio_cleanup(vdev);
-
- pthread_mutex_destroy(&event_mutex);
-}
-
-static void virtio_hwkey_device_reset(VirtIODevice *vdev)
-{
- INFO("reset hwkey device\n");
- vqidx = 0;
-}
-
-static void virtio_hwkey_class_init(ObjectClass *klass, void *data)
-{
- VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
- vdc->unrealize = virtio_hwkey_device_unrealize;
- vdc->realize = virtio_hwkey_device_realize;
- vdc->reset = virtio_hwkey_device_reset;
- vdc->get_features = virtio_hwkey_get_features;
-}
-
-static const TypeInfo virtio_hwkey_info = {
- .name = TYPE_VIRTIO_MARU_HWKEY,
- .parent = TYPE_VIRTIO_DEVICE,
- .instance_size = sizeof(VirtIOHWKey),
- .class_init = virtio_hwkey_class_init,
-};
-
-static void virtio_register_types(void)
-{
- type_register_static(&virtio_hwkey_info);
-}
-
-type_init(virtio_register_types)
-
+++ /dev/null
-/*
- * Maru Virtio HW Key Device
- *
- * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- * GiWoong Kim <giwoong.kim@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-
-#ifndef MARU_HWKEY_H_
-#define MARU_HWKEY_H_
-
-#include "ui/console.h"
-#include "hw/virtio/virtio.h"
-
-#define TYPE_VIRTIO_MARU_HWKEY "virtio-maru-hwkey-device"
-#define VIRTIO_MARU_HWKEY(obj) \
- OBJECT_CHECK(VirtIOHWKey, (obj), TYPE_VIRTIO_MARU_HWKEY)
-
-
-typedef struct VirtIOHWKey
-{
- VirtIODevice vdev;
- /* simply a queue into which buffers are posted
- by the guest for consumption by the host */
- VirtQueue *vq;
-
- QEMUBH *bh;
- DeviceState *qdev;
-} VirtIOHWKey;
-
-/* This structure must match the kernel definitions */
-typedef struct EmulHWKeyEvent {
- uint8_t event_type;
- uint32_t keycode;
-} EmulHWKeyEvent;
-
-
-VirtIODevice *maru_virtio_hwkey_init(DeviceState *dev);
-void maru_virtio_hwkey_exit(VirtIODevice *vdev);
-
-void maru_hwkey_event(int event_type, int keycode);
-void maru_virtio_hwkey_notify(void);
-
-#endif /* MARU_HWKEY_H_ */
--- /dev/null
+/*
+ * Maru Virtio Input Device
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/iov.h"
+#include "hw/maru_device_ids.h"
+#include "maru_virtio_input.h"
+
+#include "util/new_debug_ch.h"
+DECLARE_DEBUG_CHANNEL(input);
+
+
+//
+// INPUT COMMON
+//
+
+#define MAX_EVENT_CNT 256
+
+#define TYPE_VIRTIO_MARU_INPUT "virtio-maru-input-device"
+
+#if 0
+// TODO
+#define VIRTIO_MARU_INPUT(obj) \
+ OBJECT_CHECK(VirtIOMaruInput, (obj), TYPE_VIRTIO_MARU_INPUT)
+#else
+#define VIRTIO_MARU_INPUT(obj) ((VirtIOMaruInput *)(obj))
+#endif
+
+static void default_get_config(
+ VirtIODevice *vdev, uint8_t *config_data)
+{
+ // do nothing
+}
+
+static void default_set_config(
+ VirtIODevice *vdev, const uint8_t *config_data)
+{
+ // do nothing
+}
+
+static uint64_t default_get_features(
+ VirtIODevice *vdev, uint64_t request_features, Error **errp)
+{
+ // do nothing
+ return request_features;
+}
+
+
+static void default_handle_output(VirtIODevice *vdev, VirtQueue *vq)
+{
+ // do nothing
+}
+
+static void send_event(void *opaque)
+{
+ VirtIOMaruInput *input = VIRTIO_MARU_INPUT(opaque);
+ int i = 0;
+ int len = 0;
+
+ LOG_TRACE("%s\n", __func__);
+
+ qemu_mutex_lock(&input->event_mutex);
+
+ for (i = 0; i < input->buf_index; ++i) {
+ VirtQueueElement elem;
+ VirtQueueElement *element = &elem;
+// preparing to merge qemu 2.6
+// element = virtqueue_pop(input->vq, sizeof(VirtQueueElement));
+// if (element) {
+ if (virtqueue_pop(input->vq, element)) {
+ len = iov_from_buf(element->in_sg, element->in_num,
+ 0, input->events + (input->event_size * i),
+ input->event_size);
+ virtqueue_push(input->vq, element, len);
+ } else {
+ LOG_SEVERE("virtqueue is not available, dropping event.\n");
+ break;
+ }
+ }
+ input->buf_index = 0;
+
+ qemu_mutex_unlock(&input->event_mutex);
+
+ virtio_notify(VIRTIO_DEVICE(input), input->vq);
+}
+
+static void input_common_realize(DeviceState *dev, const char* name,
+ uint16_t device_id, void *handle_output, void *bh,
+ void *events, size_t event_size)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+ VirtIOMaruInput *input = VIRTIO_MARU_INPUT(dev);
+
+ if (!handle_output) {
+ handle_output = default_handle_output;
+ }
+
+ if (!bh) {
+ bh = send_event;
+ }
+
+ virtio_init(vdev, name, device_id, 4);
+
+ input->vq = virtio_add_queue(&input->vdev, MAX_EVENT_CNT, handle_output);
+ input->qdev = dev;
+
+ /* bottom halves */
+ input->bh = qemu_bh_new(bh, vdev);
+
+ input->events = (uint8_t *)events;
+ input->event_size = event_size;
+
+ qemu_mutex_init(&input->event_mutex);
+}
+
+static void input_common_unrealize(DeviceState *dev)
+{
+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+ VirtIOMaruInput *input = VIRTIO_MARU_INPUT(dev);
+
+ if (input->bh) {
+ qemu_bh_delete(input->bh);
+ }
+
+ qemu_mutex_destroy(&input->event_mutex);
+
+ virtio_cleanup(vdev);
+}
+
+static void input_common_reset(VirtIODevice *vdev)
+{
+ VirtIOMaruInput *input = VIRTIO_MARU_INPUT(vdev);
+
+ qemu_mutex_lock(&input->event_mutex);
+ /* reset the counters */
+ input->event_cnt = 0;
+ input->buf_index = 0;
+ qemu_mutex_unlock(&input->event_mutex);
+}
+
+static bool check_ready(VirtIOMaruInput *input)
+{
+ if (unlikely(!virtio_queue_ready(input->vq))) {
+ LOG_INFO("virtqueue is not ready, dropping event.\n");
+ return false;
+ }
+
+ ++(input->event_cnt);
+
+ if (input->buf_index >= MAX_EVENT_CNT ) {
+ LOG_SEVERE("event queue is not available, dropping event.\n");
+ return false;
+ }
+
+ return true;
+}
+
+static void push_event(VirtIOMaruInput *input)
+{
+ /* send */
+ qemu_bh_schedule(input->bh);
+}
+
+
+//
+// TOUCHSCREEN
+//
+
+#define VIRTIO_MARU_TOUCHSCREEN(obj) \
+ OBJECT_CHECK(VirtIOTouchscreen, (obj), TYPE_VIRTIO_MARU_TOUCHSCREEN)
+
+#define TOUCHSCREEN_OPTION_NAME "max_point"
+
+static VirtIOTouchscreen *ts;
+static touch_event touch_events[MAX_EVENT_CNT];
+
+bool virtio_touchscreen_ready(void)
+{
+ if (ts == NULL) {
+ return false;
+ }
+
+ return virtio_queue_ready(ts->input.vq) != 0;
+}
+
+int virtio_touchscreen_get_max_touch_point(void)
+{
+ if (ts) {
+ return ts->max_finger;
+ } else {
+ return 1;
+ }
+}
+
+void virtio_touchscreen_event(int x, int y, int z, int buttons_state)
+{
+ VirtIOMaruInput *input = &ts->input;
+ touch_event *event;
+
+ qemu_mutex_lock(&input->event_mutex);
+
+ if (!check_ready(input)) {
+ return;
+ }
+
+ event = &touch_events[input->buf_index++];
+
+ /* mouse event is copied into the queue */
+ event->x = x;
+ event->y = y;
+ event->z = z;
+ event->state = buttons_state;
+
+ qemu_mutex_unlock(&input->event_mutex);
+
+ push_event(input);
+
+
+ LOG_TRACE("touch event: x=%d, y=%d, z=%d, state=%d\n",
+ event->x, event->y,
+ event->z, event->state);
+}
+
+static void virtio_touchscreen_get_config(
+ VirtIODevice *vdev, uint8_t *config_data)
+{
+ VirtIOTouchscreen *ts = VIRTIO_MARU_TOUCHSCREEN(vdev);
+ int max_trkid = 10;
+
+ LOG_TRACE("%s\n", __func__);
+
+ max_trkid = ts->max_finger;
+ memcpy(config_data, &max_trkid, 4);
+}
+
+static void virtio_touchscreen_device_realize(DeviceState *dev, Error **errp)
+{
+ ts = VIRTIO_MARU_TOUCHSCREEN(dev);
+
+ LOG_INFO("%s: %d\n", __func__, ts->max_finger);
+
+ input_common_realize(dev, TYPE_VIRTIO_MARU_TOUCHSCREEN,
+ VIRTIO_ID_MARU_TOUCHSCREEN, NULL, NULL,
+ touch_events, sizeof(touch_event));
+}
+
+static void virtio_touchscreen_device_unrealize(DeviceState *dev, Error **errp)
+{
+ LOG_INFO("%s\n", __func__);
+
+ input_common_unrealize(dev);
+}
+
+static void virtio_touchscreen_device_reset(VirtIODevice *vdev)
+{
+ LOG_INFO("%s\n", __func__);
+
+ input_common_reset(vdev);
+}
+
+static Property virtio_touchscreen_properties[] = {
+ DEFINE_PROP_UINT32(TOUCHSCREEN_OPTION_NAME,
+ VirtIOTouchscreen, max_finger, DEFAULT_MAX_FINGER),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_touchscreen_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+
+ dc->props = virtio_touchscreen_properties;
+ vdc->realize = virtio_touchscreen_device_realize;
+ vdc->unrealize = virtio_touchscreen_device_unrealize;
+ vdc->reset = virtio_touchscreen_device_reset;
+ vdc->get_config = virtio_touchscreen_get_config;
+ vdc->set_config = default_set_config;
+ vdc->get_features = default_get_features;
+}
+
+static const TypeInfo virtio_touchscreen_info = {
+ .name = TYPE_VIRTIO_MARU_TOUCHSCREEN,
+ .parent = TYPE_VIRTIO_DEVICE,
+ .instance_size = sizeof(VirtIOTouchscreen),
+ .class_init = virtio_touchscreen_class_init,
+};
+
+
+//
+// KEYBOARD
+//
+
+#define VIRTIO_MARU_KEYBOARD(obj) \
+ OBJECT_CHECK(VirtIOKeyboard, (obj), TYPE_VIRTIO_MARU_KEYBOARD)
+
+static VirtIOKeyboard *kbd;
+static keyboard_event keyboard_events[MAX_EVENT_CNT];
+
+void virtio_keyboard_event(int keycode)
+{
+ VirtIOMaruInput *input = &kbd->input;
+ keyboard_event *event;
+
+ qemu_mutex_lock(&input->event_mutex);
+
+ if (!check_ready(input)) {
+ return;
+ }
+
+ event = &keyboard_events[input->buf_index++];
+
+ if (keycode < 0xe0) {
+ if (kbd->extension_key) {
+ switch (keycode & 0x7f) {
+ case 28: /* KP_Enter */
+ event->code = 96;
+ break;
+ case 29: /* Right Ctrl */
+ event->code = 97;
+ break;
+ case 56: /* Right Alt */
+ event->code = 100;
+ break;
+ case 71: /* Home */
+ event->code = 102;
+ break;
+ case 72: /* Up */
+ event->code = 103;
+ break;
+ case 73: /* Page Up */
+ event->code = 104;
+ break;
+ case 75: /* Left */
+ event->code = 105;
+ break;
+ case 77: /* Right */
+ event->code = 106;
+ break;
+ case 79: /* End */
+ event->code = 107;
+ break;
+ case 80: /* Down */
+ event->code = 108;
+ break;
+ case 81: /* Page Down */
+ event->code = 109;
+ break;
+ case 82: /* Insert */
+ event->code = 110;
+ break;
+ case 83: /* Delete */
+ event->code = 111;
+ break;
+ default:
+ LOG_WARNING("There is no keymap for this keycode %d.\n", keycode);
+ }
+ kbd->extension_key = 0;
+ } else {
+ event->code = keycode & 0x7f;
+ }
+
+ if (!(keycode & 0x80)) {
+ event->type = 1; /* KEY_PRESSED */
+ } else {
+ event->type = 0; /* KEY_RELEASED */
+ }
+ } else {
+ LOG_TRACE("Extension key.\n");
+ event->code = keycode;
+ kbd->extension_key = 1;
+ }
+
+ qemu_mutex_unlock(&input->event_mutex);
+
+ push_event(input);
+
+ LOG_TRACE("keyboard event: code=%d, type=%d\n",
+ event->code, event->type);
+}
+
+static void virtio_keyboard_device_realize(DeviceState *dev, Error **errp)
+{
+ kbd = VIRTIO_MARU_KEYBOARD(dev);
+
+ LOG_INFO("%s\n", __func__);
+
+ input_common_realize(dev, TYPE_VIRTIO_MARU_KEYBOARD,
+ VIRTIO_ID_MARU_KEYBOARD, NULL, NULL,
+ keyboard_events, sizeof(keyboard_event));
+}
+
+static void virtio_keyboard_device_unrealize(DeviceState *dev, Error **errp)
+{
+ LOG_INFO("%s\n", __func__);
+
+ input_common_unrealize(dev);
+}
+
+static void virtio_keyboard_device_reset(VirtIODevice *vdev)
+{
+ VirtIOKeyboard *vkbd = (VirtIOKeyboard *)vdev;
+
+ LOG_INFO("%s\n", __func__);
+
+ vkbd->extension_key = 0;
+ input_common_reset(vdev);
+}
+
+static void virtio_keyboard_class_init(ObjectClass *klass, void *data)
+{
+ VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+ vdc->unrealize = virtio_keyboard_device_unrealize;
+ vdc->realize = virtio_keyboard_device_realize;
+ vdc->reset = virtio_keyboard_device_reset;
+ vdc->get_config = default_get_config;
+ vdc->set_config = default_set_config;
+ vdc->get_features = default_get_features;
+}
+
+static const TypeInfo virtio_keyboard_info = {
+ .name = TYPE_VIRTIO_MARU_KEYBOARD,
+ .parent = TYPE_VIRTIO_DEVICE,
+ .instance_size = sizeof(VirtIOKeyboard),
+ .class_init = virtio_keyboard_class_init,
+};
+
+
+//
+// HW KEY
+//
+
+#define VIRTIO_MARU_HWKEY(obj) \
+ OBJECT_CHECK(VirtIOHWKey, (obj), TYPE_VIRTIO_MARU_HWKEY)
+
+static VirtIOHWKey *hwkey;
+static hwkey_event hwkey_events[MAX_EVENT_CNT];
+
+void maru_hwkey_event(int event_type, int keycode)
+{
+ VirtIOMaruInput *input = &hwkey->input;
+ hwkey_event *event;
+
+ if (!check_ready(input)) {
+ return;
+ }
+
+ qemu_mutex_lock(&input->event_mutex);
+
+ event = &hwkey_events[input->buf_index++];
+
+ /* hwkey event is copied into the queue */
+ event->keycode = keycode;
+ event->event_type = event_type;
+
+ qemu_mutex_unlock(&input->event_mutex);
+
+ push_event(input);
+
+ LOG_TRACE("hwkey event: keycode=%d, event_type=%d\n",
+ event->keycode, event->event_type);
+}
+
+static void virtio_hwkey_device_realize(DeviceState *dev, Error **errp)
+{
+ hwkey = VIRTIO_MARU_HWKEY(dev);
+
+ LOG_INFO("%s\n", __func__);
+
+ input_common_realize(dev, TYPE_VIRTIO_MARU_HWKEY,
+ VIRTIO_ID_MARU_HWKEY, NULL, NULL,
+ hwkey_events, sizeof(hwkey_event));
+}
+
+static void virtio_hwkey_device_unrealize(DeviceState *dev, Error **errp)
+{
+ LOG_INFO("%s\n", __func__);
+
+ input_common_unrealize(dev);
+}
+
+static void virtio_hwkey_device_reset(VirtIODevice *vdev)
+{
+ LOG_INFO("%s\n", __func__);
+
+ input_common_reset(vdev);
+}
+
+static void virtio_hwkey_class_init(ObjectClass *klass, void *data)
+{
+ VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+ vdc->unrealize = virtio_hwkey_device_unrealize;
+ vdc->realize = virtio_hwkey_device_realize;
+ vdc->reset = virtio_hwkey_device_reset;
+ vdc->get_config = default_get_config;
+ vdc->set_config = default_set_config;
+ vdc->get_features = default_get_features;
+}
+
+static const TypeInfo virtio_hwkey_info = {
+ .name = TYPE_VIRTIO_MARU_HWKEY,
+ .parent = TYPE_VIRTIO_DEVICE,
+ .instance_size = sizeof(VirtIOHWKey),
+ .class_init = virtio_hwkey_class_init,
+};
+
+
+//
+// Register devices
+//
+
+static void virtio_register_types(void)
+{
+ type_register_static(&virtio_touchscreen_info);
+ type_register_static(&virtio_keyboard_info);
+ type_register_static(&virtio_hwkey_info);
+}
+
+type_init(virtio_register_types)
--- /dev/null
+/*
+ * Maru Virtio Input Device
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#ifndef __MARU_VIRTIO_INPUT_H__
+#define __MARU_VIRTIO_INPUT_H__
+
+#include <stdbool.h>
+#include "hw/virtio/virtio.h"
+
+typedef struct VirtIOMaruInput VirtIOMaruInput;
+typedef struct VirtIOTouchscreen VirtIOTouchscreen;
+typedef struct VirtIOKeyboard VirtIOKeyboard;
+typedef struct VirtIOHWKey VirtIOHWKey;
+
+typedef struct touch_event touch_event;
+typedef struct keyboard_event keyboard_event;
+typedef struct hwkey_event hwkey_event;
+
+//
+// COMMON
+//
+struct VirtIOMaruInput {
+ VirtIODevice vdev;
+ VirtQueue *vq;
+ DeviceState *qdev;
+
+ QemuMutex event_mutex;
+ QEMUBH *bh;
+
+ uint8_t *events;
+ size_t event_size;
+ unsigned int event_cnt;
+ unsigned int buf_index;
+};
+
+//
+// TOUCHSCREEN
+//
+#define TYPE_VIRTIO_MARU_TOUCHSCREEN "virtio-maru-touchscreen-device"
+#define DEFAULT_MAX_FINGER (1)
+
+/* This structure must match the kernel definitions */
+struct touch_event {
+ uint16_t x, y, z;
+ uint8_t state;
+};
+
+struct VirtIOTouchscreen {
+ struct VirtIOMaruInput input;
+
+ unsigned int max_finger;
+};
+
+bool virtio_touchscreen_ready(void);
+void virtio_touchscreen_event(int x, int y, int z, int buttons_state);
+int virtio_touchscreen_get_max_touch_point(void);
+
+//
+// KEYBOARD
+//
+#define TYPE_VIRTIO_MARU_KEYBOARD "virtio-maru-keyboard-device"
+
+/* This structure must match the kernel definitions */
+struct keyboard_event {
+ uint16_t code;
+ uint16_t type;
+};
+
+struct VirtIOKeyboard {
+ struct VirtIOMaruInput input;
+
+ uint16_t extension_key;
+};
+
+void virtio_keyboard_event(int keycode);
+
+//
+// HWKEY
+//
+#define TYPE_VIRTIO_MARU_HWKEY "virtio-maru-hwkey-device"
+
+/* This structure must match the kernel definitions */
+struct hwkey_event {
+ uint8_t event_type;
+ uint32_t keycode;
+};
+
+struct VirtIOHWKey
+{
+ struct VirtIOMaruInput input;
+};
+
+void maru_hwkey_event(int event_type, int keycode);
+
+#endif // __MARU_VIRTIO_INPUT_H__
+++ /dev/null
-/*
- * Virtio Keyboard Device
- *
- * Copyright (c) 2011 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- * SeokYeon Hwang <syeon.hwang@samsung.com>
- * SungMin Ha <sungmin82.ha@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-#include "qemu/iov.h"
-#include "hw/maru_device_ids.h"
-#include "maru_virtio_keyboard.h"
-
-#include "debug_ch.h"
-
-MULTI_DEBUG_CHANNEL(qemu, keyboard);
-
-#define VIRTIO_MARU_KEYBOARD(obj) \
- OBJECT_CHECK(VirtIOKeyboard, (obj), TYPE_VIRTIO_MARU_KEYBOARD)
-
-#define MAX_EVENT_CNT 256
-
-typedef struct EmulKbdEvent {
- uint16_t code;
- uint16_t type;
-} EmulKbdEvent;
-
-typedef struct VirtIOKbdList {
- VirtIOKeyboard *vkbd;
- struct VirtIOKbdList *next;
-} VirtIOKbdList;
-
-static VirtIOKbdList *head = NULL;
-static VirtIOKbdList *curr = NULL;
-
-
-typedef struct KeyboardEventEntry {
- EmulKbdEvent event;
-
- QTAILQ_ENTRY(KeyboardEventEntry) node;
-} KeyboardEventEntry;
-
-static KeyboardEventEntry events_buf[MAX_EVENT_CNT];
-static QTAILQ_HEAD(, KeyboardEventEntry) events_queue =
- QTAILQ_HEAD_INITIALIZER(events_queue);
-
-
-void virtio_keyboard_event(int keycode)
-{
- KeyboardEventEntry *entry = NULL;
- VirtIOKeyboard *vkbd;
- EmulKbdEvent *kbdevt;
-
- if (unlikely(!curr || !(vkbd = curr->vkbd))) {
- LOG_TRACE("The keyboard device is not realized.\n");
- return;
- }
-
- if (unlikely(!virtio_queue_ready(vkbd->vq))) {
- LOG_INFO("virtqueue is not ready, dropping event.\n");
- return;
- }
-
- ++(vkbd->event_cnt);
-
- if ((vkbd->avail_buf_cnt)-- == 0) {
- LOG_SEVERE("event queue is not available, dropping event.\n");
- ++(vkbd->avail_buf_cnt);
- return;
- }
-
- entry = &(events_buf[vkbd->event_cnt % MAX_EVENT_CNT]);
- kbdevt = &entry->event;
-
- if (keycode < 0xe0) {
- if (vkbd->extension_key) {
- switch (keycode & 0x7f) {
- case 28: /* KP_Enter */
- kbdevt->code = 96;
- break;
- case 29: /* Right Ctrl */
- kbdevt->code = 97;
- break;
- case 56: /* Right Alt */
- kbdevt->code = 100;
- break;
- case 71: /* Home */
- kbdevt->code = 102;
- break;
- case 72: /* Up */
- kbdevt->code = 103;
- break;
- case 73: /* Page Up */
- kbdevt->code = 104;
- break;
- case 75: /* Left */
- kbdevt->code = 105;
- break;
- case 77: /* Right */
- kbdevt->code = 106;
- break;
- case 79: /* End */
- kbdevt->code = 107;
- break;
- case 80: /* Down */
- kbdevt->code = 108;
- break;
- case 81: /* Page Down */
- kbdevt->code = 109;
- break;
- case 82: /* Insert */
- kbdevt->code = 110;
- break;
- case 83: /* Delete */
- kbdevt->code = 111;
- break;
- default:
- WARN("There is no keymap for this keycode %d.\n", keycode);
- }
- vkbd->extension_key = 0;
- } else {
- kbdevt->code = keycode & 0x7f;
- }
-
- if (!(keycode & 0x80)) {
- kbdevt->type = 1; /* KEY_PRESSED */
- } else {
- kbdevt->type = 0; /* KEY_RELEASED */
- }
- } else {
- TRACE("Extension key.\n");
- kbdevt->code = keycode;
- vkbd->extension_key = 1;
- }
-
- qemu_mutex_lock(&vkbd->event_mutex);
-
- QTAILQ_INSERT_TAIL(&events_queue, entry, node);
-
- qemu_mutex_unlock(&vkbd->event_mutex);
-
- qemu_bh_schedule(vkbd->bh);
-}
-
-static VirtIOKbdList* create_list(VirtIOKeyboard *vkbd)
-{
- VirtIOKbdList *ptr = (VirtIOKbdList*)malloc(sizeof(VirtIOKbdList));
- if (ptr == NULL) {
- ERR("Node creation failed\n");
- return NULL;
- }
-
- ptr->vkbd = vkbd;
- ptr->next = NULL;
-
- head = curr = ptr;
- return ptr;
-}
-
-static VirtIOKbdList* add_to_list(VirtIOKeyboard *vkbd, bool add_to_end)
-{
- if (head == NULL) {
- return (create_list(vkbd));
- }
-
- VirtIOKbdList *ptr = (VirtIOKbdList*)malloc(sizeof(VirtIOKbdList));
- if (ptr == NULL) {
- ERR("Node creation failed\n");
- return NULL;
- }
-
- ptr->vkbd = vkbd;
- ptr->next = NULL;
-
- if (add_to_end) {
- curr->next = ptr;
- curr = ptr;
- } else {
- ptr->next = head;
- head = ptr;
- }
-
- return ptr;
-}
-
-static VirtIOKbdList* search_in_list(VirtIOKeyboard *vkbd, VirtIOKbdList **prev)
-{
- VirtIOKbdList *ptr = head;
- VirtIOKbdList *tmp = NULL;
- bool found = false;
-
- while (ptr != NULL) {
- if (ptr->vkbd == vkbd) {
- found = true;
- break;
- } else {
- tmp = ptr;
- ptr = ptr->next;
- }
- }
-
- if (true == found) {
- if (prev) {
- *prev = tmp;
- }
- return ptr;
- } else {
- return NULL;
- }
-}
-
-static int delete_from_list(VirtIOKeyboard *vkbd)
-{
- VirtIOKbdList *prev = NULL;
- VirtIOKbdList *del = NULL;
-
- del = search_in_list(vkbd, &prev);
- if (del == NULL) {
- return -1;
- } else {
- if (prev != NULL) {
- prev->next = del->next;
- }
-
- if (del == curr) {
- curr = prev;
- } else if (del == head) {
- head = del->next;
- }
- }
-
- free(del);
- del = NULL;
-
- return 0;
-}
-
-static void virtio_keyboard_handle(VirtIODevice *vdev, VirtQueue *vq)
-{
- // nothing to do
-}
-
-static void virtio_keyboard_send(void *opaque)
-{
- VirtIOKeyboard *vkbd = (VirtIOKeyboard *)opaque;
- KeyboardEventEntry *entry = NULL;
- int len = 0;
-
- LOG_TRACE("%s\n", __func__);
-
- qemu_mutex_lock(&vkbd->event_mutex);
- QTAILQ_FOREACH(entry, &events_queue, node) {
- VirtQueueElement element;
- EmulKbdEvent *event = &entry->event;
-
- if (virtqueue_pop(vkbd->vq, &element)) {
- len = iov_from_buf(element.in_sg, element.in_num,
- 0, event, sizeof(EmulKbdEvent));
- virtqueue_push(vkbd->vq, &element, len);
- } else {
- ERR("virtqueue is not available, dropping event.\n");
- break;
- }
-
- ++(vkbd->avail_buf_cnt);
- }
- QTAILQ_INIT(&events_queue);
- qemu_mutex_unlock(&vkbd->event_mutex);
-
- virtio_notify(VIRTIO_DEVICE(vkbd), vkbd->vq);
-}
-
-static uint64_t virtio_keyboard_get_features(VirtIODevice *vdev,
- uint64_t request_feature, Error **errp)
-{
- TRACE("virtio_keyboard_get_features.\n");
- return 0;
-}
-
-static void virtio_keyboard_bh(void *opaque)
-{
- virtio_keyboard_send(opaque);
-}
-
-static void virtio_keyboard_device_realize(DeviceState *dev, Error **errp)
-{
- VirtIODevice *vdev = VIRTIO_DEVICE(dev);
- VirtIOKeyboard *vkbd = VIRTIO_MARU_KEYBOARD(vdev);
-
- INFO("initialize virtio-keyboard device\n");
-
- if (vdev == NULL) {
- ERR("failed to initialize virtio-keyboard device\n");
- return;
- }
-
- virtio_init(vdev, TYPE_VIRTIO_MARU_KEYBOARD, VIRTIO_ID_MARU_KEYBOARD, 0);
-
- vkbd->extension_key = 0;
-
- vkbd->vq = virtio_add_queue(vdev, 128, virtio_keyboard_handle);
- vkbd->qdev = dev;
-
- /* bottom half */
- vkbd->bh = qemu_bh_new(virtio_keyboard_bh, vkbd);
-
- if (curr == NULL) {
- create_list(vkbd);
- } else {
- add_to_list(vkbd, true);
- }
-
- qemu_mutex_init(&vkbd->event_mutex);
-}
-
-static void virtio_keyboard_device_unrealize(DeviceState *dev, Error **errp)
-{
- VirtIODevice *vdev = VIRTIO_DEVICE(dev);
- VirtIOKeyboard *vkbd = (VirtIOKeyboard *)vdev;
-
- if (delete_from_list(vkbd) != 0) {
- ERR("not exist vkbd ptr!\n");
- }
-
- INFO("destroy device\n");
-
- if (vkbd->bh) {
- qemu_bh_delete(vkbd->bh);
- }
-
- qemu_mutex_destroy(&vkbd->event_mutex);
-
- virtio_cleanup(vdev);
-}
-
-static void virtio_keyboard_device_reset(VirtIODevice *vdev)
-{
- VirtIOKeyboard *vkbd = (VirtIOKeyboard *)vdev;
-
- INFO("reset keyboard device\n");
-
- qemu_mutex_lock(&vkbd->event_mutex);
- vkbd->event_cnt = 0;
- vkbd->avail_buf_cnt = MAX_EVENT_CNT;
-
- QTAILQ_INIT(&events_queue);
- qemu_mutex_unlock(&vkbd->event_mutex);
-}
-
-static void virtio_keyboard_class_init(ObjectClass *klass, void *data)
-{
- VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
- vdc->unrealize = virtio_keyboard_device_unrealize;
- vdc->realize = virtio_keyboard_device_realize;
- vdc->reset = virtio_keyboard_device_reset;
- vdc->get_features = virtio_keyboard_get_features;
-}
-
-static const TypeInfo virtio_keyboard_info = {
- .name = TYPE_VIRTIO_MARU_KEYBOARD,
- .parent = TYPE_VIRTIO_DEVICE,
- .instance_size = sizeof(VirtIOKeyboard),
- .class_init = virtio_keyboard_class_init,
-};
-
-static void virtio_register_types(void)
-{
- type_register_static(&virtio_keyboard_info);
-}
-
-type_init(virtio_register_types)
-
+++ /dev/null
-/*
- * Virtio Keyboard Device
- *
- * Copyright (c) 2011 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- * SeokYeon Hwang <syeon.hwang@samsung.com>
- * SungMin Ha <sungmin82.ha@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-#ifndef VIRTIO_KEYBOARD_H_
-#define VIRTIO_KEYBOARD_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "qemu/thread.h"
-#include "hw/virtio/virtio.h"
-
-#define TYPE_VIRTIO_MARU_KEYBOARD "virtio-maru-keyboard-device"
-
-typedef struct VirtIOKeyboard {
- VirtIODevice vdev;
- VirtQueue *vq;
- DeviceState *qdev;
-
- QemuMutex event_mutex;
- QEMUBH *bh;
-
- uint16_t extension_key;
-
- unsigned int event_cnt;
- unsigned int avail_buf_cnt;
-} VirtIOKeyboard;
-
-void virtio_keyboard_event(int keycode);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* VIRTIO_KEYBOARD_H_ */
#include "hw/maru_device_ids.h"
#include "maru_virtio_evdi.h"
#include "maru_virtio_esm.h"
-#include "maru_virtio_hwkey.h"
-#include "maru_virtio_keyboard.h"
-#include "maru_virtio_touchscreen.h"
+#include "maru_virtio_input.h"
#include "maru_virtio_sensor.h"
#include "maru_virtio_jack.h"
#include "maru_virtio_power.h"
+++ /dev/null
-/*
- * Maru Virtio Touchscreen Device
- *
- * Copyright (c) 2011 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- * SeokYeon Hwang <syeon.hwang@samsung.com>
- * GiWoong Kim <giwoong.kim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-
-#include "qemu/iov.h"
-#include "maru_virtio_touchscreen.h"
-#include "hw/maru_device_ids.h"
-
-#include "debug_ch.h"
-
-DECLARE_DEBUG_CHANNEL(tsp);
-
-
-#define DEVICE_NAME "virtio-touchscreen"
-#define VIRTIO_MARU_TOUCHSCREEN(obj) \
- OBJECT_CHECK(VirtIOTouchscreen, (obj), TYPE_VIRTIO_MARU_TOUCHSCREEN)
-
-#define TOUCHSCREEN_OPTION_NAME "max_point"
-#define MAX_EVENT_CNT 256
-
-/* This structure must match the kernel definitions */
-typedef struct EmulTouchEvent {
- uint16_t x, y, z;
- uint8_t state;
-} EmulTouchEvent;
-
-
-/*
- * touch event queue
- */
-typedef struct TouchEventEntry {
- EmulTouchEvent event;
-
- QTAILQ_ENTRY(TouchEventEntry) node;
-} TouchEventEntry;
-
-static TouchEventEntry events_buf[MAX_EVENT_CNT];
-static QTAILQ_HEAD(, TouchEventEntry) events_queue =
- QTAILQ_HEAD_INITIALIZER(events_queue);
-
-static VirtIOTouchscreen *ts;
-
-bool virtio_touchscreen_ready(void)
-{
- if (ts == NULL) {
- return false;
- }
-
- return virtio_queue_ready(ts->vq) != 0;
-}
-
-int virtio_touchscreen_get_max_touch_point(void)
-{
- if (ts) {
- return ts->max_finger;
- } else {
- return 1;
- }
-}
-
-void virtio_touchscreen_event(int x, int y, int z, int buttons_state)
-{
- TouchEventEntry *entry = NULL;
-
- if (unlikely(!virtio_queue_ready(ts->vq))) {
- LOG_INFO("virtqueue is not ready, dropping event.\n");
- return;
- }
-
- ++(ts->event_cnt);
-
- if ((ts->avail_buf_cnt)-- == 0) {
- LOG_SEVERE("event queue is not available, dropping event.\n");
- ++(ts->avail_buf_cnt);
- return;
- }
-
- entry = &(events_buf[ts->event_cnt % MAX_EVENT_CNT]);
-
- /* mouse event is copied into the queue */
- entry->event.x = x;
- entry->event.y = y;
- entry->event.z = z;
- entry->event.state = buttons_state;
-
- qemu_mutex_lock(&ts->event_mutex);
-
- QTAILQ_INSERT_TAIL(&events_queue, entry, node);
-
- qemu_mutex_unlock(&ts->event_mutex);
-
- /* call maru_virtio_touchscreen_send */
- qemu_bh_schedule(ts->bh);
-
- LOG_TRACE("touch event: x=%d, y=%d, z=%d, state=%d\n",
- entry->event.x, entry->event.y,
- entry->event.z, entry->event.state);
-}
-
-static void maru_virtio_touchscreen_handle(VirtIODevice *vdev, VirtQueue *vq)
-{
- // do nothing
-}
-
-static void maru_virtio_touchscreen_send(void *opaque)
-{
- VirtIOTouchscreen *ts = (VirtIOTouchscreen *)opaque;
- TouchEventEntry *entry = NULL;
- int len = 0;
-
- LOG_TRACE("%s\n", __func__);
-
- qemu_mutex_lock(&ts->event_mutex);
- QTAILQ_FOREACH(entry, &events_queue, node) {
- VirtQueueElement element;
- EmulTouchEvent *event = &entry->event;
-
- if (virtqueue_pop(ts->vq, &element)) {
- len = iov_from_buf(element.in_sg, element.in_num,
- 0, event, sizeof(EmulTouchEvent));
- virtqueue_push(ts->vq, &element, len);
- } else {
- ERR("virtqueue is not available, dropping event.\n");
- break;
- }
-
- ++(ts->avail_buf_cnt);
- }
- QTAILQ_INIT(&events_queue);
- qemu_mutex_unlock(&ts->event_mutex);
-
- virtio_notify(VIRTIO_DEVICE(ts), ts->vq);
-}
-
-static void virtio_touchscreen_get_config(
- VirtIODevice *vdev, uint8_t *config_data)
-{
- int max_trkid = 10;
-
- LOG_TRACE("%s\n", __func__);
-
- max_trkid = ts->max_finger;
- memcpy(config_data, &max_trkid, 4);
-}
-
-static void virtio_touchscreen_set_config(
- VirtIODevice *vdev, const uint8_t *config_data)
-{
- /* do nothing */
-}
-
-static uint64_t virtio_touchscreen_get_features(
- VirtIODevice *vdev, uint64_t request_features, Error **errp)
-{
- /* do nothing */
-
- return request_features;
-}
-
-static void maru_touchscreen_bh(void *opaque)
-{
- maru_virtio_touchscreen_send(opaque);
-}
-
-static void virtio_touchscreen_device_realize(DeviceState *dev, Error **errp)
-{
- VirtIODevice *vdev = VIRTIO_DEVICE(dev);
- ts = VIRTIO_MARU_TOUCHSCREEN(dev);
-
- LOG_INFO("%s: %d\n", __func__, ts->max_finger);
-
- virtio_init(vdev, DEVICE_NAME, VIRTIO_ID_MARU_TOUCHSCREEN, 4);
-
- // TODO: reduce size
- ts->vq = virtio_add_queue(&ts->vdev, 64, maru_virtio_touchscreen_handle);
- ts->qdev = dev;
-
- /* bottom halves */
- ts->bh = qemu_bh_new(maru_touchscreen_bh, ts);
-
- qemu_mutex_init(&ts->event_mutex);
-}
-
-static void virtio_touchscreen_device_unrealize(DeviceState *dev, Error **errp)
-{
- VirtIODevice *vdev = VIRTIO_DEVICE(dev);
- VirtIOTouchscreen *ts = VIRTIO_MARU_TOUCHSCREEN(vdev);
-
- LOG_INFO("%s\n", __func__);
-
- if (ts->bh) {
- qemu_bh_delete(ts->bh);
- }
-
- qemu_mutex_destroy(&ts->event_mutex);
-
- virtio_cleanup(vdev);
-}
-
-static Property virtio_touchscreen_properties[] = {
- DEFINE_PROP_UINT32(TOUCHSCREEN_OPTION_NAME,
- VirtIOTouchscreen, max_finger, DEFAULT_MAX_FINGER),
- DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_touchscreen_device_reset(VirtIODevice *vdev)
-{
- VirtIOTouchscreen *ts = VIRTIO_MARU_TOUCHSCREEN(vdev);
-
- LOG_INFO("%s\n", __func__);
-
- qemu_mutex_lock(&ts->event_mutex);
- /* reset the counters */
- ts->event_cnt = 0;
- ts->avail_buf_cnt = MAX_EVENT_CNT;
-
- /* reset queue */
- QTAILQ_INIT(&events_queue);
- qemu_mutex_unlock(&ts->event_mutex);
-}
-
-static void virtio_touchscreen_class_init(ObjectClass *klass, void *data)
-{
- DeviceClass *dc = DEVICE_CLASS(klass);
- VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
-
- dc->props = virtio_touchscreen_properties;
- vdc->realize = virtio_touchscreen_device_realize;
- vdc->unrealize = virtio_touchscreen_device_unrealize;
- vdc->reset = virtio_touchscreen_device_reset;
- vdc->get_config = virtio_touchscreen_get_config;
- vdc->set_config = virtio_touchscreen_set_config;
- vdc->get_features = virtio_touchscreen_get_features;
-}
-
-static const TypeInfo virtio_touchscreen_info = {
- .name = TYPE_VIRTIO_MARU_TOUCHSCREEN,
- .parent = TYPE_VIRTIO_DEVICE,
- .instance_size = sizeof(VirtIOTouchscreen),
- .class_init = virtio_touchscreen_class_init,
-};
-
-static void virtio_register_types(void)
-{
- type_register_static(&virtio_touchscreen_info);
-}
-
-type_init(virtio_register_types)
+++ /dev/null
-/*
- * Maru Virtio Touchscreen Device
- *
- * Copyright (c) 2011 - 2016 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- * SeokYeon Hwang <syeon.hwang@samsung.com>
- * GiWoong Kim <giwoong.kim@samsung.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * Contributors:
- * - S-Core Co., Ltd
- *
- */
-
-
-#ifndef MARU_TOUCHSCREEN_H_
-#define MARU_TOUCHSCREEN_H_
-
-#include <stdbool.h>
-#include "hw/virtio/virtio.h"
-
-#define TYPE_VIRTIO_MARU_TOUCHSCREEN "virtio-maru-touchscreen-device"
-#define DEFAULT_MAX_FINGER (1)
-
-typedef struct VirtIOTouchscreen {
- VirtIODevice vdev;
- VirtQueue *vq;
- DeviceState *qdev;
-
- QemuMutex event_mutex;
- QEMUBH *bh;
-
- unsigned int max_finger;
-
- unsigned int event_cnt;
- unsigned int avail_buf_cnt;
-} VirtIOTouchscreen;
-
-
-bool virtio_touchscreen_ready(void);
-void virtio_touchscreen_event(int x, int y, int z, int buttons_state);
-int virtio_touchscreen_get_max_touch_point(void);
-
-#endif /* MARU_TOUCHSCREEN_H_ */
#include "emulator_common.h"
#include "emul_state.h"
-#include "hw/virtio/maru_virtio_hwkey.h"
+#include "hw/virtio/maru_virtio_input.h"
#include "hw/maru_pm.h"
#include "ecs/ecs.h"
#include "new_debug_ch.h"
#include "emul_state.h"
#include "hw/maru_pm.h"
#include "util/new_debug_ch.h"
-#include "hw/virtio/maru_virtio_hwkey.h"
-#include "hw/virtio/maru_virtio_touchscreen.h"
+#include "hw/virtio/maru_virtio_input.h"
#include "hw/virtio/maru_virtio_rotary.h"
-#include "hw/virtio/maru_virtio_keyboard.h"
#include "hw/pci/maru_brightness.h"
#include "util/device_hotplug.h"