hwkey: added virtio hwkey device
authorgiwoong.kim <giwoong.kim@samsung.com>
Tue, 19 Feb 2013 06:24:43 +0000 (15:24 +0900)
committergiwoong.kim <giwoong.kim@samsung.com>
Tue, 19 Feb 2013 06:54:19 +0000 (15:54 +0900)
added virtio hwkey device

Signed-off-by: GiWoong Kim <giwoong.kim@samsung.com>
hw/virtio-pci.c
tizen/src/Makefile.tizen
tizen/src/hw/maru_device_ids.h
tizen/src/hw/maru_vga.c [changed mode: 0755->0644]
tizen/src/hw/maru_virtio_hwkey.c [new file with mode: 0644]
tizen/src/hw/maru_virtio_hwkey.h [new file with mode: 0644]
tizen/src/hw/maru_virtio_touchscreen.h

index 8ff80d931907d448294c68ffd7ff9c6e175331d5..eb6e23603a316e848b9a69b9a73ca728565aa439 100644 (file)
@@ -970,6 +970,29 @@ static void virtio_esm_exit_pci(PCIDevice *pci_dev)
     virtio_esm_exit(proxy->vdev);
     virtio_exit_pci(pci_dev);
 }
+
+static int virtio_hwkey_init_pci(PCIDevice *pci_dev)
+{
+    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+    VirtIODevice *vdev;
+
+    vdev = maru_virtio_hwkey_init(&pci_dev->qdev);
+    if (!vdev) {
+        return -1;
+    }
+    virtio_init_pci(proxy, vdev);
+    return 0;
+}
+
+static void virtio_hwkey_exit_pci(PCIDevice *pci_dev)
+{
+    VirtIOPCIProxy *proxy = DO_UPCAST(VirtIOPCIProxy, pci_dev, pci_dev);
+
+    virtio_pci_stop_ioeventfd(proxy);
+    maru_virtio_hwkey_exit(proxy->vdev);
+    virtio_exit_pci(pci_dev);
+}
+
 #endif
 
 static Property virtio_blk_properties[] = {
@@ -1245,6 +1268,28 @@ static TypeInfo virtio_esm_info = {
     .instance_size = sizeof(VirtIOPCIProxy),
     .class_init    = virtio_esm_class_init,
 };
+
+static void virtio_hwkey_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_hwkey_init_pci;
+    k->exit = virtio_hwkey_exit_pci;
+    k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    k->device_id = PCI_DEVICE_ID_VIRTIO_HWKEY;
+    k->revision = VIRTIO_PCI_ABI_VERSION;
+    k->class_id = PCI_CLASS_OTHERS;
+    dc->reset = virtio_pci_reset;
+}
+
+static TypeInfo virtio_hwkey_info = {
+    .name          = "virtio-hwkey-pci",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(VirtIOPCIProxy),
+    .class_init    = virtio_hwkey_class_init,
+};
+
 #endif /* CONFIG_MARU */
 
 static void virtio_pci_register_types(void)
@@ -1261,6 +1306,7 @@ static void virtio_pci_register_types(void)
     type_register_static(&maru_virtio_touchscreen_info);
     type_register_static(&virtio_keyboard_info);
     type_register_static(&virtio_esm_info);
+    type_register_static(&virtio_hwkey_info);
 #endif
 }
 
index dc1864a0454bd6ac4e4db07072182f97d56eb7ba..292f4621a1ed2e4c52b4f7d22cb0d2a19d07c1f4 100755 (executable)
@@ -112,6 +112,7 @@ obj-y += maru_usb_touchscreen.o maru_virtio_touchscreen.o
 obj-y += maru_virtio_keyboard.o
 obj-y += maru_codec.o
 obj-y += maru_virtio_esm.o
+obj-y += maru_virtio_hwkey.o
 
 obj-$(CONFIG_PCI) += maru_camera_common_pci.o
 obj-$(CONFIG_LINUX) += maru_camera_linux_pci.o
index 0fc77de5f975e906edf5c4191a75b8c34543de15..8a2a0bd8e98426d64bf026ce785ca893ce7e7a74 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Maru Device IDs
  *
- * Copyright (C) 2011 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
  *
  * Contact:
  * SeokYeon Hwang <syeon.hwang@samsung.com>
@@ -49,8 +49,9 @@
 #define PCI_DEVICE_ID_VIRTUAL_CODEC      0x101C
 /* Device ID 0x1000 through 0x103F inclusive is a virtio device */
 #define PCI_DEVICE_ID_VIRTIO_TOUCHSCREEN 0x101D
-#define PCI_DEVICE_ID_VIRTIO_KEYBOARD   0x1020
+#define PCI_DEVICE_ID_VIRTIO_KEYBOARD    0x1020
 #define PCI_DEVICE_ID_VIRTIO_ESM         0x1024
+#define PCI_DEVICE_ID_VIRTIO_HWKEY       0x1028
 
 /* Virtio */
 /*
@@ -82,5 +83,6 @@
 #define VIRTIO_ID_TOUCHSCREEN   11
 #define VIRTIO_ID_KEYBOARD      12
 #define VIRTIO_ID_ESM           13
+#define VIRTIO_ID_HWKEY         14
 
 #endif /* MARU_DEVICE_IDS_H_ */
old mode 100755 (executable)
new mode 100644 (file)
diff --git a/tizen/src/hw/maru_virtio_hwkey.c b/tizen/src/hw/maru_virtio_hwkey.c
new file mode 100644 (file)
index 0000000..a882820
--- /dev/null
@@ -0,0 +1,191 @@
+/*
+ * 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 "console.h"
+#include "emul_state.h"
+#include "maru_virtio_hwkey.h"
+#include "maru_device_ids.h"
+#include "debug_ch.h"
+
+MULTI_DEBUG_CHANNEL(qemu, hwkey);
+
+
+#define DEVICE_NAME "virtio-hwkey"
+
+/*
+ * 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 */
+
+VirtIOHwKey *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 (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]);
+    event_ringbuf_cnt++;
+
+    /* hwkey event is copied into the queue */
+    entry->hwkey.keycode = keycode;
+    entry->hwkey.event_type = event_type;
+
+    pthread_mutex_lock(&event_mutex);
+
+    entry->index = ++event_queue_cnt; // 1 ~
+
+    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);
+}
+
+void maru_virtio_hwkey_notify(void)
+{
+    HwKeyEventEntry *event_entry = NULL;
+
+    TRACE("maru_virtio_hwkey_notify\n");
+
+    while (true) {
+        if (event_queue_cnt == 0) {
+            TRACE("no event\n");
+            break;
+        }
+
+        /* get touch event from host queue */
+        event_entry = QTAILQ_FIRST(&events_queue);
+
+        TRACE("hwkey(%d) : keycode=%d, event_type=%d | \
+            event_queue_cnt=%d\n",
+            event_entry->index,
+            event_entry->hwkey.keycode, event_entry->hwkey.event_type,
+            event_queue_cnt);
+
+        /* copy event into virtio buffer */
+        //memcpy(vbuf, &(event_entry->touch), sizeof(event_entry->touch));
+    /* TODO: */
+    if (KEY_PRESSED == event_entry->hwkey.event_type) {
+        ps2kbd_put_keycode(event_entry->hwkey.keycode & 0x7f);
+    } else if (KEY_RELEASED == event_entry->hwkey.event_type) {
+        ps2kbd_put_keycode(event_entry->hwkey.keycode | 0x80);
+    } else {
+        ERR("Unknown hwkey event type : keycode=%d, event_type=%d\n",
+            event_entry->hwkey.keycode, event_entry->hwkey.event_type);
+    }        
+
+        pthread_mutex_lock(&event_mutex);
+
+        /* remove host event */
+        QTAILQ_REMOVE(&events_queue, event_entry, node);
+        event_queue_cnt--;
+
+        pthread_mutex_unlock(&event_mutex);
+    }
+}
+
+static uint32_t virtio_hwkey_get_features(
+    VirtIODevice *vdev, uint32_t request_features)
+{
+    // TODO:
+    return request_features;
+}
+
+static void maru_hwkey_bh(void *opaque)
+{
+    maru_virtio_hwkey_notify();
+}
+
+VirtIODevice *maru_virtio_hwkey_init(DeviceState *dev)
+{
+    INFO("initialize the hwkey device\n");
+
+    vhk = (VirtIOHwKey *)virtio_common_init(DEVICE_NAME,
+        VIRTIO_ID_HWKEY, 0 /*config_size*/, sizeof(VirtIOHwKey));
+
+    if (vhk == NULL) {
+        ERR("failed to initialize the hwkey device\n");
+        return NULL;
+    }
+
+    vhk->vdev.get_features = virtio_hwkey_get_features;
+    vhk->qdev = dev;
+
+    /* bottom-half */
+    vhk->bh = qemu_bh_new(maru_hwkey_bh, vhk);
+
+    return &(vhk->vdev);
+}
+
+void maru_virtio_hwkey_exit(VirtIODevice *vdev)
+{
+    VirtIOHwKey *vhk = (VirtIOHwKey *)vdev;
+
+    INFO("exit the hwkey device\n");
+
+    if (vhk->bh) {
+        qemu_bh_delete(vhk->bh);
+    }
+
+    virtio_cleanup(vdev);
+
+    pthread_mutex_destroy(&event_mutex);
+}
+
diff --git a/tizen/src/hw/maru_virtio_hwkey.h b/tizen/src/hw/maru_virtio_hwkey.h
new file mode 100644 (file)
index 0000000..d80866a
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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 "console.h"
+#include "hw/virtio.h"
+
+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_ */
index 84c938ad2503397b270a7e9e91c321e46dce9042..b78abadc6d4e0a097083153b2f6a411d6e13005d 100644 (file)
@@ -1,7 +1,7 @@
 /*
- * Maru Virtual Virtio Touchscreen emulation
+ * Maru Virtio Touchscreen Device
  *
- * Copyright (c) 2011 -2013 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
  *
  * Contact:
  *  GiWoong Kim <giwoong.kim@samsung.com>