emulator: clean-up source directories 60/23660/4
authorSeokYeon Hwang <syeon.hwang@samsung.com>
Tue, 1 Jul 2014 06:54:49 +0000 (15:54 +0900)
committerSeokYeon Hwang <syeon.hwang@samsung.com>
Tue, 1 Jul 2014 09:48:11 +0000 (18:48 +0900)
Source files under "tizen/src/hw/" moved into each parent bus directory.

Change-Id: I32d4cd527583a5cacf43cb4e2bc490212b849ee4
Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
108 files changed:
tizen/src/Makefile.objs
tizen/src/display/maru_finger.c
tizen/src/display/maru_sdl.c
tizen/src/display/maru_sdl_processing.c
tizen/src/ecs/ecs_mon.c
tizen/src/ecs/ecs_msg.c
tizen/src/ecs/ecs_sensor.c
tizen/src/ecs/ecs_tethering.c
tizen/src/emulator.c
tizen/src/emulator_legacy.c
tizen/src/hw/Makefile.objs
tizen/src/hw/Makefile.objs.arm [deleted file]
tizen/src/hw/arm/Makefile.objs [new file with mode: 0644]
tizen/src/hw/arm/maru_arm.h [new file with mode: 0644]
tizen/src/hw/arm/maru_arm_board.c [new file with mode: 0644]
tizen/src/hw/arm/maru_arm_pmu.c [new file with mode: 0644]
tizen/src/hw/arm/maru_arm_soc.c [new file with mode: 0644]
tizen/src/hw/arm/maru_arm_vpci.c [new file with mode: 0644]
tizen/src/hw/maru_arm.h [deleted file]
tizen/src/hw/maru_arm_board.c [deleted file]
tizen/src/hw/maru_arm_pmu.c [deleted file]
tizen/src/hw/maru_arm_soc.c [deleted file]
tizen/src/hw/maru_arm_vpci.c [deleted file]
tizen/src/hw/maru_brightness.c [deleted file]
tizen/src/hw/maru_brightness.h [deleted file]
tizen/src/hw/maru_brill_codec.c [deleted file]
tizen/src/hw/maru_brill_codec.h [deleted file]
tizen/src/hw/maru_camera_common.h [deleted file]
tizen/src/hw/maru_camera_common_pci.c [deleted file]
tizen/src/hw/maru_camera_darwin.h [deleted file]
tizen/src/hw/maru_camera_darwin_converter.c [deleted file]
tizen/src/hw/maru_camera_darwin_pci.m [deleted file]
tizen/src/hw/maru_camera_linux_pci.c [deleted file]
tizen/src/hw/maru_camera_win32_interface.h [deleted file]
tizen/src/hw/maru_camera_win32_pci.c [deleted file]
tizen/src/hw/maru_codec.c [deleted file]
tizen/src/hw/maru_codec.h [deleted file]
tizen/src/hw/maru_pm.c
tizen/src/hw/maru_usb_touchscreen.c [deleted file]
tizen/src/hw/maru_usb_touchscreen.h [deleted file]
tizen/src/hw/maru_virtio_esm.c [deleted file]
tizen/src/hw/maru_virtio_esm.h [deleted file]
tizen/src/hw/maru_virtio_evdi.c [deleted file]
tizen/src/hw/maru_virtio_evdi.h [deleted file]
tizen/src/hw/maru_virtio_hwkey.c [deleted file]
tizen/src/hw/maru_virtio_hwkey.h [deleted file]
tizen/src/hw/maru_virtio_jack.c [deleted file]
tizen/src/hw/maru_virtio_jack.h [deleted file]
tizen/src/hw/maru_virtio_keyboard.c [deleted file]
tizen/src/hw/maru_virtio_keyboard.h [deleted file]
tizen/src/hw/maru_virtio_nfc.c [deleted file]
tizen/src/hw/maru_virtio_nfc.h [deleted file]
tizen/src/hw/maru_virtio_pci.c [deleted file]
tizen/src/hw/maru_virtio_power.c [deleted file]
tizen/src/hw/maru_virtio_power.h [deleted file]
tizen/src/hw/maru_virtio_sensor.c [deleted file]
tizen/src/hw/maru_virtio_sensor.h [deleted file]
tizen/src/hw/maru_virtio_touchscreen.c [deleted file]
tizen/src/hw/maru_virtio_touchscreen.h [deleted file]
tizen/src/hw/maru_virtio_vmodem.c [deleted file]
tizen/src/hw/maru_virtio_vmodem.h [deleted file]
tizen/src/hw/pci/Makefile.objs [new file with mode: 0644]
tizen/src/hw/pci/maru_brightness.c [new file with mode: 0644]
tizen/src/hw/pci/maru_brightness.h [new file with mode: 0644]
tizen/src/hw/pci/maru_brill_codec.c [new file with mode: 0644]
tizen/src/hw/pci/maru_brill_codec.h [new file with mode: 0644]
tizen/src/hw/pci/maru_camera_common.h [new file with mode: 0644]
tizen/src/hw/pci/maru_camera_common_pci.c [new file with mode: 0644]
tizen/src/hw/pci/maru_camera_darwin.h [new file with mode: 0644]
tizen/src/hw/pci/maru_camera_darwin_converter.c [new file with mode: 0644]
tizen/src/hw/pci/maru_camera_darwin_pci.m [new file with mode: 0644]
tizen/src/hw/pci/maru_camera_linux_pci.c [new file with mode: 0644]
tizen/src/hw/pci/maru_camera_win32_interface.h [new file with mode: 0644]
tizen/src/hw/pci/maru_camera_win32_pci.c [new file with mode: 0644]
tizen/src/hw/pci/maru_codec.c [new file with mode: 0644]
tizen/src/hw/pci/maru_codec.h [new file with mode: 0644]
tizen/src/hw/usb/Makefile.objs [new file with mode: 0644]
tizen/src/hw/usb/maru_usb_touchscreen.c [new file with mode: 0644]
tizen/src/hw/usb/maru_usb_touchscreen.h [new file with mode: 0644]
tizen/src/hw/virtio/Makefile.objs [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_esm.c [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_esm.h [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_evdi.c [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_evdi.h [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_hwkey.c [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_hwkey.h [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_jack.c [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_jack.h [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_keyboard.c [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_keyboard.h [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_nfc.c [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_nfc.h [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_pci.c [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_power.c [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_power.h [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_sensor.c [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_sensor.h [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_touchscreen.c [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_touchscreen.h [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_vmodem.c [new file with mode: 0644]
tizen/src/hw/virtio/maru_virtio_vmodem.h [new file with mode: 0644]
tizen/src/sdb_noti_server.c [deleted file]
tizen/src/sdb_noti_server.h [deleted file]
tizen/src/skin/maruskin_keymap.h
tizen/src/skin/maruskin_operation.c
tizen/src/util/Makefile.objs
tizen/src/util/sdb_noti_server.c [new file with mode: 0644]
tizen/src/util/sdb_noti_server.h [new file with mode: 0644]

index 2a6d433b42fad9f591e8447c7590d3fb13111822..44bddfa55b504e6e888b77b9f94503062b31298f 100644 (file)
@@ -23,9 +23,6 @@ obj-y += tethering/
 # maru skin
 obj-y += skin/
 
-# sdb noti server
-obj-y += sdb_noti_server.o
-
 # debug channel
 obj-y += debug_ch.o
 
index b97a71e0f166970f410e2c2317bd311a8adfe7f8..de365e84606057a85f6343810c318f37d41d1d60 100644 (file)
@@ -33,7 +33,7 @@
 #include <SDL.h>
 #include "maru_finger.h"
 #include "emul_state.h"
-#include "hw/maru_virtio_touchscreen.h"
+#include "hw/virtio/maru_virtio_touchscreen.h"
 #include "debug_ch.h"
 
 MULTI_DEBUG_CHANNEL(qemu, maru_finger);
index 35be462273a6d3746b1b4a96b3cc8ae2bd26aae5..426daa90a94fd30d06cb89a7b695832414ada4b2 100644 (file)
@@ -36,7 +36,7 @@
 #include "maru_display.h"
 #include "maru_sdl.h"
 #include "maru_sdl_processing.h"
-#include "hw/maru_brightness.h"
+#include "hw/pci/maru_brightness.h"
 #include "debug_ch.h"
 
 MULTI_DEBUG_CHANNEL(tizen, maru_sdl);
index 4e28eb8e6e02adb3098f4223a213604cad6a7d4d..174198e46a0ef07f4d393567bb0c441ff339a755 100644 (file)
@@ -30,7 +30,7 @@
 
 
 #include "maru_sdl_processing.h"
-#include "hw/maru_brightness.h"
+#include "hw/pci/maru_brightness.h"
 #include "debug_ch.h"
 
 MULTI_DEBUG_CHANNEL(tizen, sdl_processing);
index 1161e0750b1cac91d4e9a1740c65b28dc384465f..995714419c458aa102bec09c65db407e9d97e834 100644 (file)
@@ -39,9 +39,9 @@
 #include "qapi/qmp/json-parser.h"
 
 #include "ecs.h"
-#include "hw/maru_virtio_evdi.h"
-#include "hw/maru_virtio_sensor.h"
-#include "hw/maru_virtio_nfc.h"
+#include "hw/virtio/maru_virtio_evdi.h"
+#include "hw/virtio/maru_virtio_sensor.h"
+#include "hw/virtio/maru_virtio_nfc.h"
 
 #include "debug_ch.h"
 MULTI_DEBUG_CHANNEL(qemu, ecs);
index d6b023b4bcd7bc7679ad32bc5bf3547ef3464e13..866b9eff9cb6625ae8c9dc86993b8f57cbfb0887 100644 (file)
 #include "display/maru_finger.h"
 #endif
 
-#include "hw/maru_virtio_evdi.h"
-#include "hw/maru_virtio_sensor.h"
-#include "hw/maru_virtio_jack.h"
-#include "hw/maru_virtio_power.h"
-#include "hw/maru_virtio_nfc.h"
-#include "hw/maru_virtio_vmodem.h"
+#include "hw/virtio/maru_virtio_evdi.h"
+#include "hw/virtio/maru_virtio_sensor.h"
+#include "hw/virtio/maru_virtio_jack.h"
+#include "hw/virtio/maru_virtio_power.h"
+#include "hw/virtio/maru_virtio_nfc.h"
+#include "hw/virtio/maru_virtio_vmodem.h"
 #include "skin/maruskin_operation.h"
 #include "skin/maruskin_server.h"
 #include "util/maru_device_hotplug.h"
index 4d82e7c1d9770e8a01f35e50cb2ccc5e9569f319..46d7ee4fc78bb1220bf4ee93cff5eb44ad23f650 100644 (file)
@@ -36,9 +36,9 @@
 //#include "qemu-timer.h"
 
 #include "ecs.h"
-#include "hw/maru_virtio_sensor.h"
-#include "hw/maru_virtio_power.h"
-#include "hw/maru_virtio_jack.h"
+#include "hw/virtio/maru_virtio_sensor.h"
+#include "hw/virtio/maru_virtio_power.h"
+#include "hw/virtio/maru_virtio_jack.h"
 
 #define TEMP_BUF_SIZE   255
 #define MAX_VAL_LENGTH  40
index 0b588b28e73cc214a9c3c9d7895ada670d00c540..eec010be2724daf44bd879a0dc0938ce05fe57c0 100644 (file)
@@ -32,7 +32,7 @@
 #include "ecs.h"
 #include "ecs_tethering.h"
 #include "tethering/app_tethering.h"
-#include "hw/maru_virtio_touchscreen.h"
+#include "hw/virtio/maru_virtio_touchscreen.h"
 #include "debug_ch.h"
 
 MULTI_DEBUG_CHANNEL(tizen, ecs_tethering);
index 7bc6d19c400a921e8a7c1cfd772efa9c66b19225..a659db802d5b2ae8ef39a745f46ed515e90823bb 100644 (file)
@@ -37,8 +37,8 @@
 #include "build_info.h"
 #include "emulator.h"
 #include "emul_state.h"
-#include "sdb_noti_server.h"
 #include "emulator_options.h"
+#include "util/sdb_noti_server.h"
 #include "util/check_gl.h"
 #include "maru_err_table.h"
 #include "util/osutil.h"
index 721c8c8ad46e09fb60f59f5ae303fb41051ee4fd..85fa9d55e428f2332dab4cb9f1b16eef3b21f5cd 100644 (file)
@@ -39,7 +39,7 @@
 #include "emulator.h"
 #include "emul_state.h"
 #include "guest_debug.h"
-#include "hw/maru_virtio_touchscreen.h"
+#include "hw/virtio/maru_virtio_touchscreen.h"
 #include "util/check_gl.h"
 #include "maru_err_table.h"
 #include "display/maru_display.h"
index 42c9dc66bd8910d06dc28d6f343e91a127cd5fda..a72d5d6c071081f86f1579a362183c6c2f724727 100644 (file)
@@ -1,36 +1,7 @@
 obj-y += maru_board.o maru_pm.o
 
-obj-y += maru_brill_codec.o
-obj-y += maru_brightness.o
+obj-y += pci/
+obj-y += virtio/
 
-obj-y += maru_virtio_pci.o
-obj-y += maru_virtio_touchscreen.o
-obj-y += maru_virtio_esm.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
-obj-y += maru_virtio_vmodem.o
-
-obj-y += maru_camera_common_pci.o
-ifdef CONFIG_LINUX
-obj-y += maru_camera_linux_pci.o
-LIBS += -lv4l2 -lv4lconvert
-endif
-ifdef CONFIG_WIN32
-obj-y += maru_camera_win32_pci.o
-LIBS += -lole32 -loleaut32 -luuid -lstrmiids
-endif
-ifdef CONFIG_DARWIN
-obj-y += maru_camera_darwin_converter.o
-obj-y += maru_camera_darwin_pci.o
-LIBS += -framework Foundation -framework SystemConfiguration
-LIBS += -framework Cocoa -framework QTKit -framework CoreVideo
-LIBS += -framework AppKit
-endif
-
-#obj-y += maru_codec.o
-#obj-y += maru_usb_touchscreen.o
+#obj-y += usb/
+#obj-y += arm/
diff --git a/tizen/src/hw/Makefile.objs.arm b/tizen/src/hw/Makefile.objs.arm
deleted file mode 100644 (file)
index f216625..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-obj-y += maru_arm_soc.o
-
-ifndef  CONFIG_DARWIN
-obj-y += maru_arm_board.o
-endif
-
-obj-y += maru_arm_vpci.o
-obj-y += maru_arm_pmu.o
diff --git a/tizen/src/hw/arm/Makefile.objs b/tizen/src/hw/arm/Makefile.objs
new file mode 100644 (file)
index 0000000..f216625
--- /dev/null
@@ -0,0 +1,8 @@
+obj-y += maru_arm_soc.o
+
+ifndef  CONFIG_DARWIN
+obj-y += maru_arm_board.o
+endif
+
+obj-y += maru_arm_vpci.o
+obj-y += maru_arm_pmu.o
diff --git a/tizen/src/hw/arm/maru_arm.h b/tizen/src/hw/arm/maru_arm.h
new file mode 100644 (file)
index 0000000..6fa1a9d
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ *  Samsung Maru ARM SoC emulation
+ *
+ *  Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *    Evgeny Voevodin <e.voevodin@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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef MARU_ARM_H_
+#define MARU_ARM_H_
+
+#include "qemu-common.h"
+#include "memory.h"
+#include "exynos4210.h"
+
+void maru_arm_write_secondary(ARMCPU *cpu,
+        const struct arm_boot_info *info);
+
+Exynos4210State *maru_arm_soc_init(MemoryRegion *system_mem,
+        unsigned long ram_size);
+
+int codec_init(PCIBus *bus);
+int maru_camera_pci_init(PCIBus *bus);
+
+#endif /* MARU_ARM_H_ */
diff --git a/tizen/src/hw/arm/maru_arm_board.c b/tizen/src/hw/arm/maru_arm_board.c
new file mode 100644 (file)
index 0000000..dae7534
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * TIZEN ARM base board
+ *
+ * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd.
+ *
+ * Based on maru_board.c, exynos4210.c and exynos4210_boards.c
+ *
+ * Author:
+ *  Evgeny Voevodin <e.voevodin@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License; 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+
+#include "boards.h"
+#include "arm-misc.h"
+#include "sysbus.h"
+#include "pci.h"
+#include "maru_arm.h"
+#include "i2c.h"
+#include "exec-memory.h"
+#include "hw/maru_brightness.h"
+#include "arch_init.h"
+
+#include "xen.h"
+#ifdef CONFIG_XEN
+#  include <xen/hvm/hvm_info_table.h>
+#endif
+#include "maru_common.h"
+#if defined(__linux__)
+#include <X11/Xlib.h>
+#endif
+#include "vigs_device.h"
+extern int enable_yagl;
+extern const char *yagl_backend;
+extern int enable_vigs;
+extern const char *vigs_backend;
+
+#undef DEBUG
+//#define DEBUG
+#ifdef DEBUG
+    #undef PRINT_DEBUG
+    #define  PRINT_DEBUG(fmt, args...) \
+        do { \
+            fprintf(stderr, "  [%s:%d]   "fmt, __func__, __LINE__, ##args); \
+        } while (0)
+#else
+    #define  PRINT_DEBUG(fmt, args...)  do {} while (0)
+#endif
+
+#ifndef DEBUG_LOG_PATH
+#define DEBUG_LOG_PATH                     "./debug.log"
+#endif
+
+#define EXYNOS4210_WM8994_ADDR             0x1A
+#define MARU_ARM_BOARD_ID                  0xF3B
+#define MARU_ARM_BOARD_SMP_BOOTREG_ADDR    EXYNOS4210_SECOND_CPU_BOOTREG
+#define MARU_ARM_BOARD_RAMSIZE_MIN         0x20000000
+#define MARU_ARM_BOARD_RAMSIZE_DEFAULT     0x40000000
+
+static struct arm_boot_info maru_arm_board_binfo = {
+    .loader_start     = EXYNOS4210_BASE_BOOT_ADDR,
+    .smp_loader_start = EXYNOS4210_SMP_BOOT_ADDR,
+    .nb_cpus          = EXYNOS4210_NCPUS,
+    .write_secondary_boot = maru_arm_write_secondary,
+};
+
+static void maru_arm_machine_init(ram_addr_t ram_size,
+                        const char *boot_device,
+                        const char *kernel_filename,
+                        const char *kernel_cmdline,
+                        const char *initrd_filename,
+                        const char *cpu_model)
+{
+    Exynos4210State *s;
+    DeviceState *dev;
+    PCIBus *pci_bus;
+#if defined(__linux__)
+    Display *display = XOpenDisplay(0);
+    if (!display) {
+        fprintf(stderr, "Cannot open X display\n");
+        exit(1);
+    }
+#else
+    void *display = NULL;
+#endif
+    struct winsys_interface *vigs_wsi = NULL;
+
+    /*
+     * W/A for allocate larger continuous heap. From maru_board.c
+     */
+    if (!xen_enabled()) {
+        if(preallocated_ptr != NULL) {
+            qemu_vfree(preallocated_ptr);
+        }
+    }
+
+    if (ram_size < MARU_ARM_BOARD_RAMSIZE_MIN) {
+       ram_size = MARU_ARM_BOARD_RAMSIZE_DEFAULT;
+       fprintf(stderr, "RAM size is too small, setting to default value 0x%lx",
+                       (long unsigned int)ram_size);
+    }
+
+    maru_arm_board_binfo.ram_size = ram_size;
+    maru_arm_board_binfo.board_id = MARU_ARM_BOARD_ID;
+    maru_arm_board_binfo.smp_bootreg_addr = MARU_ARM_BOARD_SMP_BOOTREG_ADDR;
+    maru_arm_board_binfo.kernel_filename = kernel_filename;
+    maru_arm_board_binfo.initrd_filename = initrd_filename;
+    maru_arm_board_binfo.kernel_cmdline = kernel_cmdline;
+    maru_arm_board_binfo.gic_cpu_if_addr =
+                        EXYNOS4210_SMP_PRIVATE_BASE_ADDR + 0x100;
+
+    PRINT_DEBUG("\n ram_size: %luMiB [0x%08lx]\n"
+            " kernel_filename: %s\n"
+            " kernel_cmdline: %s\n"
+            " initrd_filename: %s\n",
+            (long unsigned int)ram_size / 1048576,
+            (long unsigned int)ram_size,
+            kernel_filename,
+            kernel_cmdline,
+            initrd_filename);
+    s = maru_arm_soc_init(get_system_memory(), ram_size);
+
+    /* PCI config */
+    dev = qdev_create(NULL, "tizen_vpci");
+    s->vpci_bus = sysbus_from_qdev(dev);
+    qdev_init_nofail(dev);
+    sysbus_mmio_map(s->vpci_bus, 0, EXYNOS4210_VPCI_CFG_BASE_ADDR);
+    sysbus_connect_irq(s->vpci_bus, 0, s->irq_table[exynos4210_get_irq(38, 0)]);
+    sysbus_connect_irq(s->vpci_bus, 1, s->irq_table[exynos4210_get_irq(38, 1)]);
+    sysbus_connect_irq(s->vpci_bus, 2, s->irq_table[exynos4210_get_irq(38, 2)]);
+    sysbus_connect_irq(s->vpci_bus, 3, s->irq_table[exynos4210_get_irq(38, 3)]);
+    pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
+
+    pci_create_simple(pci_bus, -1, "pci-ohci");
+    maru_camera_pci_init(pci_bus);
+    maru_brill_codec_pci_device_init(pci_bus);
+    pci_maru_brightness_init(pci_bus);
+
+    if (enable_vigs) {
+        PCIDevice *pci_dev = pci_create(pci_bus, -1, "vigs");
+        qdev_prop_set_ptr(&pci_dev->qdev, "display", display);
+        qdev_init_nofail(&pci_dev->qdev);
+        vigs_wsi = DO_UPCAST(VIGSDevice, pci_dev, pci_dev)->wsi;
+    }
+
+    if (enable_yagl) {
+        PCIDevice *pci_dev = pci_create(pci_bus, -1, "yagl");
+        qdev_prop_set_ptr(&pci_dev->qdev, "display", display);
+        if (vigs_wsi &&
+            (strcmp(yagl_backend, "vigs") == 0) &&
+            (strcmp(vigs_backend, "gl") == 0)) {
+            qdev_prop_set_ptr(&pci_dev->qdev, "winsys_gl_interface", vigs_wsi);
+        }
+        qdev_init_nofail(&pci_dev->qdev);
+    }
+
+    audio_init(NULL, pci_bus);
+
+    arm_load_kernel(arm_env_get_cpu(first_cpu), &maru_arm_board_binfo);
+}
+
+static QEMUMachine maru_arm_machine = {
+    .name = "maru-arm-machine",
+    .desc = "maru board(ARM)",
+    .init = maru_arm_machine_init,
+    .max_cpus = 255,
+};
+
+static void maru_machine_init(void)
+{
+    qemu_register_machine(&maru_arm_machine);
+}
+
+machine_init(maru_machine_init);
diff --git a/tizen/src/hw/arm/maru_arm_pmu.c b/tizen/src/hw/arm/maru_arm_pmu.c
new file mode 100644 (file)
index 0000000..202ad81
--- /dev/null
@@ -0,0 +1,520 @@
+/*
+ *  Tizen Power Management Unit (PMU) Emulation
+ *
+ *  Based on exynos4210_pmu.c
+ *  Copyright (C) 2011 Samsung Electronics Co Ltd.
+ *    Evgeny Voevodin <e.voevodin@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, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * This model implements PMU registers just as a bulk of memory.
+ * Able to shutdown and restart only.
+ */
+
+#include "sysbus.h"
+#include "sysemu.h"
+#include "ptimer.h"
+
+#ifndef DEBUG_PMU
+#define DEBUG_PMU           0
+#endif
+
+#ifndef DEBUG_PMU_EXTEND
+#define DEBUG_PMU_EXTEND    0
+#endif
+
+#if DEBUG_PMU
+#define  PRINT_DEBUG(fmt, args...)  \
+        do { \
+            fprintf(stderr, "  [%s:%d]   "fmt, __func__, __LINE__, ##args); \
+        } while (0)
+
+#if DEBUG_PMU_EXTEND
+#define  PRINT_DEBUG_EXTEND(fmt, args...) \
+        do { \
+            fprintf(stderr, "  [%s:%d]   "fmt, __func__, __LINE__, ##args); \
+        } while (0)
+#else
+#define  PRINT_DEBUG_EXTEND(fmt, args...)  do {} while (0)
+#endif /* EXTEND */
+
+#else
+#define  PRINT_DEBUG(fmt, args...)   do {} while (0)
+#define  PRINT_DEBUG_EXTEND(fmt, args...)  do {} while (0)
+#endif
+
+#define  POWER_OFF_TIMER_FREQ   24000000
+
+/*
+ *  Offsets for PMU registers
+ */
+#define OM_STAT                  0x0000 /* OM status register */
+#define RTC_CLKO_SEL             0x000C /* Controls RTCCLKOUT */
+#define GNSS_RTC_OUT_CTRL        0x0010 /* Controls GNSS_RTC_OUT */
+/* Decides whether system-level low-power mode is used. */
+#define SYSTEM_POWER_DOWN_CTRL   0x0200
+/* Sets control options for CENTRAL_SEQ */
+#define SYSTEM_POWER_DOWN_OPTION 0x0208
+#define SWRESET                  0x0400 /* Generate software reset */
+#define RST_STAT                 0x0404 /* Reset status register */
+#define WAKEUP_STAT              0x0600 /* Wakeup status register  */
+#define EINT_WAKEUP_MASK         0x0604 /* Configure External INTerrupt mask */
+#define WAKEUP_MASK              0x0608 /* Configure wakeup source mask */
+#define HDMI_PHY_CONTROL         0x0700 /* HDMI PHY control register */
+#define USBDEVICE_PHY_CONTROL    0x0704 /* USB Device PHY control register */
+#define USBHOST_PHY_CONTROL      0x0708 /* USB HOST PHY control register */
+#define DAC_PHY_CONTROL          0x070C /* DAC control register  */
+#define MIPI_PHY0_CONTROL        0x0710 /* MIPI PHY control register */
+#define MIPI_PHY1_CONTROL        0x0714 /* MIPI PHY control register */
+#define ADC_PHY_CONTROL          0x0718 /* TS-ADC control register */
+#define PCIe_PHY_CONTROL         0x071C /* TS-PCIe control register */
+#define SATA_PHY_CONTROL         0x0720 /* TS-SATA control register */
+#define INFORM0                  0x0800 /* Information register 0  */
+#define INFORM1                  0x0804 /* Information register 1  */
+#define INFORM2                  0x0808 /* Information register 2  */
+#define INFORM3                  0x080C /* Information register 3  */
+#define INFORM4                  0x0810 /* Information register 4  */
+#define INFORM5                  0x0814 /* Information register 5  */
+#define INFORM6                  0x0818 /* Information register 6  */
+#define INFORM7                  0x081C /* Information register 7  */
+#define PMU_DEBUG                0x0A00 /* PMU debug register */
+/* Registers to set system-level low-power option */
+#define ARM_CORE0_SYS_PWR_REG              0x1000
+#define ARM_CORE1_SYS_PWR_REG              0x1010
+#define ARM_COMMON_SYS_PWR_REG             0x1080
+#define ARM_CPU_L2_0_SYS_PWR_REG           0x10C0
+#define ARM_CPU_L2_1_SYS_PWR_REG           0x10C4
+#define CMU_ACLKSTOP_SYS_PWR_REG           0x1100
+#define CMU_SCLKSTOP_SYS_PWR_REG           0x1104
+#define CMU_RESET_SYS_PWR_REG              0x110C
+#define APLL_SYSCLK_SYS_PWR_REG            0x1120
+#define MPLL_SYSCLK_SYS_PWR_REG            0x1124
+#define VPLL_SYSCLK_SYS_PWR_REG            0x1128
+#define EPLL_SYSCLK_SYS_PWR_REG            0x112C
+#define CMU_CLKSTOP_GPS_ALIVE_SYS_PWR_REG  0x1138
+#define CMU_RESET_GPS_ALIVE_SYS_PWR_REG    0x113C
+#define CMU_CLKSTOP_CAM_SYS_PWR_REG        0x1140
+#define CMU_CLKSTOP_TV_SYS_PWR_REG         0x1144
+#define CMU_CLKSTOP_MFC_SYS_PWR_REG        0x1148
+#define CMU_CLKSTOP_G3D_SYS_PWR_REG        0x114C
+#define CMU_CLKSTOP_LCD0_SYS_PWR_REG       0x1150
+#define CMU_CLKSTOP_LCD1_SYS_PWR_REG       0x1154
+#define CMU_CLKSTOP_MAUDIO_SYS_PWR_REG     0x1158
+#define CMU_CLKSTOP_GPS_SYS_PWR_REG        0x115C
+#define CMU_RESET_CAM_SYS_PWR_REG          0x1160
+#define CMU_RESET_TV_SYS_PWR_REG           0x1164
+#define CMU_RESET_MFC_SYS_PWR_REG          0x1168
+#define CMU_RESET_G3D_SYS_PWR_REG          0x116C
+#define CMU_RESET_LCD0_SYS_PWR_REG         0x1170
+#define CMU_RESET_LCD1_SYS_PWR_REG         0x1174
+#define CMU_RESET_MAUDIO_SYS_PWR_REG       0x1178
+#define CMU_RESET_GPS_SYS_PWR_REG          0x117C
+#define TOP_BUS_SYS_PWR_REG                0x1180
+#define TOP_RETENTION_SYS_PWR_REG          0x1184
+#define TOP_PWR_SYS_PWR_REG                0x1188
+#define LOGIC_RESET_SYS_PWR_REG            0x11A0
+#define OneNANDXL_MEM_SYS_PWR_REG          0x11C0
+#define MODEMIF_MEM_SYS_PWR_REG            0x11C4
+#define USBDEVICE_MEM_SYS_PWR_REG          0x11CC
+#define SDMMC_MEM_SYS_PWR_REG              0x11D0
+#define CSSYS_MEM_SYS_PWR_REG              0x11D4
+#define SECSS_MEM_SYS_PWR_REG              0x11D8
+#define PCIe_MEM_SYS_PWR_REG               0x11E0
+#define SATA_MEM_SYS_PWR_REG               0x11E4
+#define PAD_RETENTION_DRAM_SYS_PWR_REG     0x1200
+#define PAD_RETENTION_MAUDIO_SYS_PWR_REG   0x1204
+#define PAD_RETENTION_GPIO_SYS_PWR_REG     0x1220
+#define PAD_RETENTION_UART_SYS_PWR_REG     0x1224
+#define PAD_RETENTION_MMCA_SYS_PWR_REG     0x1228
+#define PAD_RETENTION_MMCB_SYS_PWR_REG     0x122C
+#define PAD_RETENTION_EBIA_SYS_PWR_REG     0x1230
+#define PAD_RETENTION_EBIB_SYS_PWR_REG     0x1234
+#define PAD_ISOLATION_SYS_PWR_REG          0x1240
+#define PAD_ALV_SEL_SYS_PWR_REG            0x1260
+#define XUSBXTI_SYS_PWR_REG                0x1280
+#define XXTI_SYS_PWR_REG                   0x1284
+#define EXT_REGULATOR_SYS_PWR_REG          0x12C0
+#define GPIO_MODE_SYS_PWR_REG              0x1300
+#define GPIO_MODE_MAUDIO_SYS_PWR_REG       0x1340
+#define CAM_SYS_PWR_REG                    0x1380
+#define TV_SYS_PWR_REG                     0x1384
+#define MFC_SYS_PWR_REG                    0x1388
+#define G3D_SYS_PWR_REG                    0x138C
+#define LCD0_SYS_PWR_REG                   0x1390
+#define LCD1_SYS_PWR_REG                   0x1394
+#define MAUDIO_SYS_PWR_REG                 0x1398
+#define GPS_SYS_PWR_REG                    0x139C
+#define GPS_ALIVE_SYS_PWR_REG              0x13A0
+#define ARM_CORE0_CONFIGURATION 0x2000 /* Configure power mode of ARM_CORE0 */
+#define ARM_CORE0_STATUS        0x2004 /* Check power mode of ARM_CORE0 */
+#define ARM_CORE0_OPTION        0x2008 /* Sets control options for ARM_CORE0 */
+#define ARM_CORE1_CONFIGURATION 0x2080 /* Configure power mode of ARM_CORE1 */
+#define ARM_CORE1_STATUS        0x2084 /* Check power mode of ARM_CORE1 */
+#define ARM_CORE1_OPTION        0x2088 /* Sets control options for ARM_CORE0 */
+#define ARM_COMMON_OPTION       0x2408 /* Sets control options for ARM_COMMON */
+/* Configure power mode of ARM_CPU_L2_0 */
+#define ARM_CPU_L2_0_CONFIGURATION 0x2600
+#define ARM_CPU_L2_0_STATUS        0x2604 /* Check power mode of ARM_CPU_L2_0 */
+/* Configure power mode of ARM_CPU_L2_1 */
+#define ARM_CPU_L2_1_CONFIGURATION 0x2620
+#define ARM_CPU_L2_1_STATUS        0x2624 /* Check power mode of ARM_CPU_L2_1 */
+/* Sets control options for PAD_RETENTION_MAUDIO */
+#define PAD_RETENTION_MAUDIO_OPTION 0x3028
+/* Sets control options for PAD_RETENTION_GPIO */
+#define PAD_RETENTION_GPIO_OPTION   0x3108
+/* Sets control options for PAD_RETENTION_UART */
+#define PAD_RETENTION_UART_OPTION   0x3128
+/* Sets control options for PAD_RETENTION_MMCA */
+#define PAD_RETENTION_MMCA_OPTION   0x3148
+/* Sets control options for PAD_RETENTION_MMCB */
+#define PAD_RETENTION_MMCB_OPTION   0x3168
+/* Sets control options for PAD_RETENTION_EBIA */
+#define PAD_RETENTION_EBIA_OPTION   0x3188
+/* Sets control options for PAD_RETENTION_EBIB */
+#define PAD_RETENTION_EBIB_OPTION   0x31A8
+#define PS_HOLD_CONTROL         0x330C /* PS_HOLD control register */
+#define XUSBXTI_CONFIGURATION   0x3400 /* Configure the pad of XUSBXTI */
+#define XUSBXTI_STATUS          0x3404 /* Check the pad of XUSBXTI */
+/* Sets time required for XUSBXTI to be stabilized */
+#define XUSBXTI_DURATION        0x341C
+#define XXTI_CONFIGURATION      0x3420 /* Configure the pad of XXTI */
+#define XXTI_STATUS             0x3424 /* Check the pad of XXTI */
+/* Sets time required for XXTI to be stabilized */
+#define XXTI_DURATION           0x343C
+/* Sets time required for EXT_REGULATOR to be stabilized */
+#define EXT_REGULATOR_DURATION  0x361C
+#define CAM_CONFIGURATION       0x3C00 /* Configure power mode of CAM */
+#define CAM_STATUS              0x3C04 /* Check power mode of CAM */
+#define CAM_OPTION              0x3C08 /* Sets control options for CAM */
+#define TV_CONFIGURATION        0x3C20 /* Configure power mode of TV */
+#define TV_STATUS               0x3C24 /* Check power mode of TV */
+#define TV_OPTION               0x3C28 /* Sets control options for TV */
+#define MFC_CONFIGURATION       0x3C40 /* Configure power mode of MFC */
+#define MFC_STATUS              0x3C44 /* Check power mode of MFC */
+#define MFC_OPTION              0x3C48 /* Sets control options for MFC */
+#define G3D_CONFIGURATION       0x3C60 /* Configure power mode of G3D */
+#define G3D_STATUS              0x3C64 /* Check power mode of G3D */
+#define G3D_OPTION              0x3C68 /* Sets control options for G3D */
+#define LCD0_CONFIGURATION      0x3C80 /* Configure power mode of LCD0 */
+#define LCD0_STATUS             0x3C84 /* Check power mode of LCD0 */
+#define LCD0_OPTION             0x3C88 /* Sets control options for LCD0 */
+#define LCD1_CONFIGURATION      0x3CA0 /* Configure power mode of LCD1 */
+#define LCD1_STATUS             0x3CA4 /* Check power mode of LCD1 */
+#define LCD1_OPTION             0x3CA8 /* Sets control options for LCD1 */
+#define GPS_CONFIGURATION       0x3CE0 /* Configure power mode of GPS */
+#define GPS_STATUS              0x3CE4 /* Check power mode of GPS */
+#define GPS_OPTION              0x3CE8 /* Sets control options for GPS */
+#define GPS_ALIVE_CONFIGURATION 0x3D00 /* Configure power mode of GPS */
+#define GPS_ALIVE_STATUS        0x3D04 /* Check power mode of GPS */
+#define GPS_ALIVE_OPTION        0x3D08 /* Sets control options for GPS */
+
+#define EXYNOS4210_PMU_REGS_MEM_SIZE 0x3d0c
+
+typedef struct Exynos4210PmuReg {
+    const char  *name; /* for debug only */
+    uint32_t     offset;
+    uint32_t     reset_value;
+} Exynos4210PmuReg;
+
+static const Exynos4210PmuReg exynos4210_pmu_regs[] = {
+    {"OM_STAT", OM_STAT, 0x00000000},
+    {"RTC_CLKO_SEL", RTC_CLKO_SEL, 0x00000000},
+    {"GNSS_RTC_OUT_CTRL", GNSS_RTC_OUT_CTRL, 0x00000001},
+    {"SYSTEM_POWER_DOWN_CTRL", SYSTEM_POWER_DOWN_CTRL, 0x00010000},
+    {"SYSTEM_POWER_DOWN_OPTION", SYSTEM_POWER_DOWN_OPTION, 0x03030000},
+    {"SWRESET", SWRESET, 0x00000000},
+    {"RST_STAT", RST_STAT, 0x00000000},
+    {"WAKEUP_STAT", WAKEUP_STAT, 0x00000000},
+    {"EINT_WAKEUP_MASK", EINT_WAKEUP_MASK, 0x00000000},
+    {"WAKEUP_MASK", WAKEUP_MASK, 0x00000000},
+    {"HDMI_PHY_CONTROL", HDMI_PHY_CONTROL, 0x00960000},
+    {"USBDEVICE_PHY_CONTROL", USBDEVICE_PHY_CONTROL, 0x00000000},
+    {"USBHOST_PHY_CONTROL", USBHOST_PHY_CONTROL, 0x00000000},
+    {"DAC_PHY_CONTROL", DAC_PHY_CONTROL, 0x00000000},
+    {"MIPI_PHY0_CONTROL", MIPI_PHY0_CONTROL, 0x00000000},
+    {"MIPI_PHY1_CONTROL", MIPI_PHY1_CONTROL, 0x00000000},
+    {"ADC_PHY_CONTROL", ADC_PHY_CONTROL, 0x00000001},
+    {"PCIe_PHY_CONTROL", PCIe_PHY_CONTROL, 0x00000000},
+    {"SATA_PHY_CONTROL", SATA_PHY_CONTROL, 0x00000000},
+    {"INFORM0", INFORM0, 0x00000000},
+    {"INFORM1", INFORM1, 0x00000000},
+    {"INFORM2", INFORM2, 0x00000000},
+    {"INFORM3", INFORM3, 0x00000000},
+    {"INFORM4", INFORM4, 0x00000000},
+    {"INFORM5", INFORM5, 0x00000000},
+    {"INFORM6", INFORM6, 0x00000000},
+    {"INFORM7", INFORM7, 0x00000000},
+    {"PMU_DEBUG", PMU_DEBUG, 0x00000000},
+    {"ARM_CORE0_SYS_PWR_REG", ARM_CORE0_SYS_PWR_REG, 0xFFFFFFFF},
+    {"ARM_CORE1_SYS_PWR_REG", ARM_CORE1_SYS_PWR_REG, 0xFFFFFFFF},
+    {"ARM_COMMON_SYS_PWR_REG", ARM_COMMON_SYS_PWR_REG, 0xFFFFFFFF},
+    {"ARM_CPU_L2_0_SYS_PWR_REG", ARM_CPU_L2_0_SYS_PWR_REG, 0xFFFFFFFF},
+    {"ARM_CPU_L2_1_SYS_PWR_REG", ARM_CPU_L2_1_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CMU_ACLKSTOP_SYS_PWR_REG", CMU_ACLKSTOP_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CMU_SCLKSTOP_SYS_PWR_REG", CMU_SCLKSTOP_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CMU_RESET_SYS_PWR_REG", CMU_RESET_SYS_PWR_REG, 0xFFFFFFFF},
+    {"APLL_SYSCLK_SYS_PWR_REG", APLL_SYSCLK_SYS_PWR_REG, 0xFFFFFFFF},
+    {"MPLL_SYSCLK_SYS_PWR_REG", MPLL_SYSCLK_SYS_PWR_REG, 0xFFFFFFFF},
+    {"VPLL_SYSCLK_SYS_PWR_REG", VPLL_SYSCLK_SYS_PWR_REG, 0xFFFFFFFF},
+    {"EPLL_SYSCLK_SYS_PWR_REG", EPLL_SYSCLK_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CMU_CLKSTOP_GPS_ALIVE_SYS_PWR_REG", CMU_CLKSTOP_GPS_ALIVE_SYS_PWR_REG,
+            0xFFFFFFFF},
+    {"CMU_RESET_GPS_ALIVE_SYS_PWR_REG", CMU_RESET_GPS_ALIVE_SYS_PWR_REG,
+            0xFFFFFFFF},
+    {"CMU_CLKSTOP_CAM_SYS_PWR_REG", CMU_CLKSTOP_CAM_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CMU_CLKSTOP_TV_SYS_PWR_REG", CMU_CLKSTOP_TV_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CMU_CLKSTOP_MFC_SYS_PWR_REG", CMU_CLKSTOP_MFC_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CMU_CLKSTOP_G3D_SYS_PWR_REG", CMU_CLKSTOP_G3D_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CMU_CLKSTOP_LCD0_SYS_PWR_REG", CMU_CLKSTOP_LCD0_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CMU_CLKSTOP_LCD1_SYS_PWR_REG", CMU_CLKSTOP_LCD1_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CMU_CLKSTOP_MAUDIO_SYS_PWR_REG", CMU_CLKSTOP_MAUDIO_SYS_PWR_REG,
+            0xFFFFFFFF},
+    {"CMU_CLKSTOP_GPS_SYS_PWR_REG", CMU_CLKSTOP_GPS_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CMU_RESET_CAM_SYS_PWR_REG", CMU_RESET_CAM_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CMU_RESET_TV_SYS_PWR_REG", CMU_RESET_TV_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CMU_RESET_MFC_SYS_PWR_REG", CMU_RESET_MFC_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CMU_RESET_G3D_SYS_PWR_REG", CMU_RESET_G3D_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CMU_RESET_LCD0_SYS_PWR_REG", CMU_RESET_LCD0_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CMU_RESET_LCD1_SYS_PWR_REG", CMU_RESET_LCD1_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CMU_RESET_MAUDIO_SYS_PWR_REG", CMU_RESET_MAUDIO_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CMU_RESET_GPS_SYS_PWR_REG", CMU_RESET_GPS_SYS_PWR_REG, 0xFFFFFFFF},
+    {"TOP_BUS_SYS_PWR_REG", TOP_BUS_SYS_PWR_REG, 0xFFFFFFFF},
+    {"TOP_RETENTION_SYS_PWR_REG", TOP_RETENTION_SYS_PWR_REG, 0xFFFFFFFF},
+    {"TOP_PWR_SYS_PWR_REG", TOP_PWR_SYS_PWR_REG, 0xFFFFFFFF},
+    {"LOGIC_RESET_SYS_PWR_REG", LOGIC_RESET_SYS_PWR_REG, 0xFFFFFFFF},
+    {"OneNANDXL_MEM_SYS_PWR_REG", OneNANDXL_MEM_SYS_PWR_REG, 0xFFFFFFFF},
+    {"MODEMIF_MEM_SYS_PWR_REG", MODEMIF_MEM_SYS_PWR_REG, 0xFFFFFFFF},
+    {"USBDEVICE_MEM_SYS_PWR_REG", USBDEVICE_MEM_SYS_PWR_REG, 0xFFFFFFFF},
+    {"SDMMC_MEM_SYS_PWR_REG", SDMMC_MEM_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CSSYS_MEM_SYS_PWR_REG", CSSYS_MEM_SYS_PWR_REG, 0xFFFFFFFF},
+    {"SECSS_MEM_SYS_PWR_REG", SECSS_MEM_SYS_PWR_REG, 0xFFFFFFFF},
+    {"PCIe_MEM_SYS_PWR_REG", PCIe_MEM_SYS_PWR_REG, 0xFFFFFFFF},
+    {"SATA_MEM_SYS_PWR_REG", SATA_MEM_SYS_PWR_REG, 0xFFFFFFFF},
+    {"PAD_RETENTION_DRAM_SYS_PWR_REG", PAD_RETENTION_DRAM_SYS_PWR_REG,
+            0xFFFFFFFF},
+    {"PAD_RETENTION_MAUDIO_SYS_PWR_REG", PAD_RETENTION_MAUDIO_SYS_PWR_REG,
+            0xFFFFFFFF},
+    {"PAD_RETENTION_GPIO_SYS_PWR_REG", PAD_RETENTION_GPIO_SYS_PWR_REG,
+            0xFFFFFFFF},
+    {"PAD_RETENTION_UART_SYS_PWR_REG", PAD_RETENTION_UART_SYS_PWR_REG,
+            0xFFFFFFFF},
+    {"PAD_RETENTION_MMCA_SYS_PWR_REG", PAD_RETENTION_MMCA_SYS_PWR_REG,
+            0xFFFFFFFF},
+    {"PAD_RETENTION_MMCB_SYS_PWR_REG", PAD_RETENTION_MMCB_SYS_PWR_REG,
+            0xFFFFFFFF},
+    {"PAD_RETENTION_EBIA_SYS_PWR_REG", PAD_RETENTION_EBIA_SYS_PWR_REG,
+            0xFFFFFFFF},
+    {"PAD_RETENTION_EBIB_SYS_PWR_REG", PAD_RETENTION_EBIB_SYS_PWR_REG,
+            0xFFFFFFFF},
+    {"PAD_ISOLATION_SYS_PWR_REG", PAD_ISOLATION_SYS_PWR_REG, 0xFFFFFFFF},
+    {"PAD_ALV_SEL_SYS_PWR_REG", PAD_ALV_SEL_SYS_PWR_REG, 0xFFFFFFFF},
+    {"XUSBXTI_SYS_PWR_REG", XUSBXTI_SYS_PWR_REG, 0xFFFFFFFF},
+    {"XXTI_SYS_PWR_REG", XXTI_SYS_PWR_REG, 0xFFFFFFFF},
+    {"EXT_REGULATOR_SYS_PWR_REG", EXT_REGULATOR_SYS_PWR_REG, 0xFFFFFFFF},
+    {"GPIO_MODE_SYS_PWR_REG", GPIO_MODE_SYS_PWR_REG, 0xFFFFFFFF},
+    {"GPIO_MODE_MAUDIO_SYS_PWR_REG", GPIO_MODE_MAUDIO_SYS_PWR_REG, 0xFFFFFFFF},
+    {"CAM_SYS_PWR_REG", CAM_SYS_PWR_REG, 0xFFFFFFFF},
+    {"TV_SYS_PWR_REG", TV_SYS_PWR_REG, 0xFFFFFFFF},
+    {"MFC_SYS_PWR_REG", MFC_SYS_PWR_REG, 0xFFFFFFFF},
+    {"G3D_SYS_PWR_REG", G3D_SYS_PWR_REG, 0xFFFFFFFF},
+    {"LCD0_SYS_PWR_REG", LCD0_SYS_PWR_REG, 0xFFFFFFFF},
+    {"LCD1_SYS_PWR_REG", LCD1_SYS_PWR_REG, 0xFFFFFFFF},
+    {"MAUDIO_SYS_PWR_REG", MAUDIO_SYS_PWR_REG, 0xFFFFFFFF},
+    {"GPS_SYS_PWR_REG", GPS_SYS_PWR_REG, 0xFFFFFFFF},
+    {"GPS_ALIVE_SYS_PWR_REG", GPS_ALIVE_SYS_PWR_REG, 0xFFFFFFFF},
+    {"ARM_CORE0_CONFIGURATION", ARM_CORE0_CONFIGURATION, 0x00000003},
+    {"ARM_CORE0_STATUS", ARM_CORE0_STATUS, 0x00030003},
+    {"ARM_CORE0_OPTION", ARM_CORE0_OPTION, 0x01010001},
+    {"ARM_CORE1_CONFIGURATION", ARM_CORE1_CONFIGURATION, 0x00000003},
+    {"ARM_CORE1_STATUS", ARM_CORE1_STATUS, 0x00030003},
+    {"ARM_CORE1_OPTION", ARM_CORE1_OPTION, 0x01010001},
+    {"ARM_COMMON_OPTION", ARM_COMMON_OPTION, 0x00000001},
+    {"ARM_CPU_L2_0_CONFIGURATION", ARM_CPU_L2_0_CONFIGURATION, 0x00000003},
+    {"ARM_CPU_L2_0_STATUS", ARM_CPU_L2_0_STATUS, 0x00000003},
+    {"ARM_CPU_L2_1_CONFIGURATION", ARM_CPU_L2_1_CONFIGURATION, 0x00000003},
+    {"ARM_CPU_L2_1_STATUS", ARM_CPU_L2_1_STATUS, 0x00000003},
+    {"PAD_RETENTION_MAUDIO_OPTION", PAD_RETENTION_MAUDIO_OPTION, 0x00000000},
+    {"PAD_RETENTION_GPIO_OPTION", PAD_RETENTION_GPIO_OPTION, 0x00000000},
+    {"PAD_RETENTION_UART_OPTION", PAD_RETENTION_UART_OPTION, 0x00000000},
+    {"PAD_RETENTION_MMCA_OPTION", PAD_RETENTION_MMCA_OPTION, 0x00000000},
+    {"PAD_RETENTION_MMCB_OPTION", PAD_RETENTION_MMCB_OPTION, 0x00000000},
+    {"PAD_RETENTION_EBIA_OPTION", PAD_RETENTION_EBIA_OPTION, 0x00000000},
+    {"PAD_RETENTION_EBIB_OPTION", PAD_RETENTION_EBIB_OPTION, 0x00000000},
+    {"PS_HOLD_CONTROL", PS_HOLD_CONTROL, 0x00005200},
+    {"XUSBXTI_CONFIGURATION", XUSBXTI_CONFIGURATION, 0x00000001},
+    {"XUSBXTI_STATUS", XUSBXTI_STATUS, 0x00000001},
+    {"XUSBXTI_DURATION", XUSBXTI_DURATION, 0xFFF00000},
+    {"XXTI_CONFIGURATION", XXTI_CONFIGURATION, 0x00000001},
+    {"XXTI_STATUS", XXTI_STATUS, 0x00000001},
+    {"XXTI_DURATION", XXTI_DURATION, 0xFFF00000},
+    {"EXT_REGULATOR_DURATION", EXT_REGULATOR_DURATION, 0xFFF03FFF},
+    {"CAM_CONFIGURATION", CAM_CONFIGURATION, 0x00000007},
+    {"CAM_STATUS", CAM_STATUS, 0x00060007},
+    {"CAM_OPTION", CAM_OPTION, 0x00000001},
+    {"TV_CONFIGURATION", TV_CONFIGURATION, 0x00000007},
+    {"TV_STATUS", TV_STATUS, 0x00060007},
+    {"TV_OPTION", TV_OPTION, 0x00000001},
+    {"MFC_CONFIGURATION", MFC_CONFIGURATION, 0x00000007},
+    {"MFC_STATUS", MFC_STATUS, 0x00060007},
+    {"MFC_OPTION", MFC_OPTION, 0x00000001},
+    {"G3D_CONFIGURATION", G3D_CONFIGURATION, 0x00000007},
+    {"G3D_STATUS", G3D_STATUS, 0x00060007},
+    {"G3D_OPTION", G3D_OPTION, 0x00000001},
+    {"LCD0_CONFIGURATION", LCD0_CONFIGURATION, 0x00000007},
+    {"LCD0_STATUS", LCD0_STATUS, 0x00060007},
+    {"LCD0_OPTION", LCD0_OPTION, 0x00000001},
+    {"LCD1_CONFIGURATION", LCD1_CONFIGURATION, 0x00000007},
+    {"LCD1_STATUS", LCD1_STATUS, 0x00060007},
+    {"LCD1_OPTION", LCD1_OPTION, 0x00000001},
+    {"GPS_CONFIGURATION", GPS_CONFIGURATION, 0x00000007},
+    {"GPS_STATUS", GPS_STATUS, 0x00060007},
+    {"GPS_OPTION", GPS_OPTION, 0x00000001},
+    {"GPS_ALIVE_CONFIGURATION", GPS_ALIVE_CONFIGURATION, 0x00000007},
+    {"GPS_ALIVE_STATUS", GPS_ALIVE_STATUS, 0x00060007},
+    {"GPS_ALIVE_OPTION", GPS_ALIVE_OPTION, 0x00000001},
+};
+
+#define PMU_NUM_OF_REGISTERS     \
+    (sizeof(exynos4210_pmu_regs) / sizeof(Exynos4210PmuReg))
+
+typedef struct Exynos4210PmuState {
+    SysBusDevice busdev;
+    MemoryRegion iomem;
+    uint32_t reg[PMU_NUM_OF_REGISTERS];
+
+    ptimer_state *ptimer;
+} Exynos4210PmuState;
+
+static uint64_t exynos4210_pmu_read(void *opaque, target_phys_addr_t offset,
+                                    unsigned size)
+{
+    Exynos4210PmuState *s = (Exynos4210PmuState *)opaque;
+    unsigned i;
+    const Exynos4210PmuReg *reg_p = exynos4210_pmu_regs;
+
+    for (i = 0; i < PMU_NUM_OF_REGISTERS; i++) {
+        if (reg_p->offset == offset) {
+            PRINT_DEBUG_EXTEND("%s [0x%04x] -> 0x%04x\n", reg_p->name,
+                                   (uint32_t)offset, s->reg[i]);
+            return s->reg[i];
+        }
+        reg_p++;
+    }
+    PRINT_DEBUG("QEMU PMU ERROR: bad read offset 0x%04x\n", (uint32_t)offset);
+    return 0;
+}
+
+static void exynos4210_pmu_write(void *opaque, target_phys_addr_t offset,
+                                 uint64_t val, unsigned size)
+{
+    Exynos4210PmuState *s = (Exynos4210PmuState *)opaque;
+    unsigned i;
+    const Exynos4210PmuReg *reg_p = exynos4210_pmu_regs;
+
+    for (i = 0; i < PMU_NUM_OF_REGISTERS; i++) {
+        if (reg_p->offset == offset) {
+            PRINT_DEBUG_EXTEND("%s <0x%04x> <- 0x%04x\n", reg_p->name,
+                    (uint32_t)offset, (uint32_t)val);
+            s->reg[i] = val;
+            break;
+        }
+        reg_p++;
+    }
+
+    switch (offset) {
+    case SYSTEM_POWER_DOWN_CTRL:
+        if (!(val & (1 << 16))) {
+            qemu_system_shutdown_request();
+            return;
+        }
+    case SWRESET:
+        if (val & 1) {
+            qemu_system_reset_request();
+            return;
+        }
+    default:
+        break;
+    }
+}
+
+static const MemoryRegionOps exynos4210_pmu_ops = {
+    .read = exynos4210_pmu_read,
+    .write = exynos4210_pmu_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+        .unaligned = false
+    }
+};
+
+static void exynos4210_pmu_reset(DeviceState *dev)
+{
+    Exynos4210PmuState *s =
+            container_of(dev, Exynos4210PmuState, busdev.qdev);
+    unsigned i;
+
+    /* Set default values for registers */
+    for (i = 0; i < PMU_NUM_OF_REGISTERS; i++) {
+        s->reg[i] = exynos4210_pmu_regs[i].reset_value;
+    }
+}
+
+static int exynos4210_pmu_init(SysBusDevice *dev)
+{
+    Exynos4210PmuState *s = FROM_SYSBUS(Exynos4210PmuState, dev);
+
+    /* memory mapping */
+    memory_region_init_io(&s->iomem, &exynos4210_pmu_ops, s, "maru_arm.pmu",
+                          EXYNOS4210_PMU_REGS_MEM_SIZE);
+    sysbus_init_mmio(dev, &s->iomem);
+
+    return 0;
+}
+
+static const VMStateDescription exynos4210_pmu_vmstate = {
+    .name = "maru_arm.pmu",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32_ARRAY(reg, Exynos4210PmuState, PMU_NUM_OF_REGISTERS),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void exynos4210_pmu_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
+
+    k->init = exynos4210_pmu_init;
+    dc->reset = exynos4210_pmu_reset;
+    dc->vmsd = &exynos4210_pmu_vmstate;
+}
+
+static TypeInfo exynos4210_pmu_info = {
+    .name          = "maru_arm.pmu",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(Exynos4210PmuState),
+    .class_init    = exynos4210_pmu_class_init,
+};
+
+static void exynos4210_pmu_register(void)
+{
+    type_register_static(&exynos4210_pmu_info);
+}
+
+type_init(exynos4210_pmu_register)
diff --git a/tizen/src/hw/arm/maru_arm_soc.c b/tizen/src/hw/arm/maru_arm_soc.c
new file mode 100644 (file)
index 0000000..ba72bd8
--- /dev/null
@@ -0,0 +1,422 @@
+/*
+ *  Samsung Maru ARM SoC emulation
+ *
+ *  Based on exynos4210.c
+ *
+ *  Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *    Maksim Kozlov <m.kozlov@samsung.com>
+ *    Evgeny Voevodin <e.voevodin@samsung.com>
+ *    Igor Mitsyanko  <i.mitsyanko@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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "boards.h"
+#include "arm-misc.h"
+#include "sysbus.h"
+#include "pci.h"
+#include "maru_arm.h"
+#include "i2c.h"
+#include "exec-memory.h"
+
+#include "loader.h"
+#include "exynos4210_i2s.h"
+extern int enable_vigs;
+
+#define EXYNOS4210_CHIPID_ADDR         0x10000000
+
+/* CMUs */
+#define EXYNOS4210_CMU_LEFTBUS_BASE_ADDR     0x10034000
+#define EXYNOS4210_CMU_RIGHTBUS_BASE_ADDR    0x10038000
+#define EXYNOS4210_CMU_TOP_BASE_ADDR         0x1003C000
+#define EXYNOS4210_CMU_DMC_BASE_ADDR         0x10040000
+#define EXYNOS4210_CMU_CPU_BASE_ADDR         0x10044000
+
+/* PWM */
+#define EXYNOS4210_PWM_BASE_ADDR       0x139D0000
+
+/* RTC */
+#define EXYNOS4210_RTC_BASE_ADDR       0x10070000
+
+/* MCT */
+#define EXYNOS4210_MCT_BASE_ADDR       0x10050000
+
+/* DMA */
+#define EXYNOS4210_DMAMEM_BASE_ADDR    0x12840000
+#define EXYNOS4210_DMAPERI0_BASE_ADDR  0x12680000
+#define EXYNOS4210_DMAPERI1_BASE_ADDR  0x12690000
+
+/* I2C */
+#define EXYNOS4210_I2C_SHIFT           0x00010000
+#define EXYNOS4210_I2C_BASE_ADDR       0x13860000
+/* Interrupt Group of External Interrupt Combiner for I2C */
+#define EXYNOS4210_I2C_INTG            27
+#define EXYNOS4210_HDMI_INTG           16
+
+/* There are two set of touch screen interfaces, which share one ADC */
+#define EXYNOS4210_TS0_BASE_ADDR       0x13910000
+#define EXYNOS4210_TS1_BASE_ADDR       0x13911000
+#define EXYNOS4210_TS_INTG             19
+
+/* UART's definitions */
+#define EXYNOS4210_UART0_BASE_ADDR     0x13800000
+#define EXYNOS4210_UART1_BASE_ADDR     0x13810000
+#define EXYNOS4210_UART2_BASE_ADDR     0x13820000
+#define EXYNOS4210_UART3_BASE_ADDR     0x13830000
+#define EXYNOS4210_UART0_FIFO_SIZE     256
+#define EXYNOS4210_UART1_FIFO_SIZE     64
+#define EXYNOS4210_UART2_FIFO_SIZE     16
+#define EXYNOS4210_UART3_FIFO_SIZE     16
+/* Interrupt Group of External Interrupt Combiner for UART */
+#define EXYNOS4210_UART_INT_GRP        26
+
+/* External GIC */
+#define EXYNOS4210_EXT_GIC_CPU_BASE_ADDR    0x10480000
+#define EXYNOS4210_EXT_GIC_DIST_BASE_ADDR   0x10490000
+
+/* Combiner */
+#define EXYNOS4210_EXT_COMBINER_BASE_ADDR   0x10440000
+#define EXYNOS4210_INT_COMBINER_BASE_ADDR   0x10448000
+
+/* SD/MMC host controllers SFR base addresses */
+#define EXYNOS4210_SDHC0_BASE_ADDR          0x12510000
+#define EXYNOS4210_SDHC1_BASE_ADDR          0x12520000
+#define EXYNOS4210_SDHC2_BASE_ADDR          0x12530000
+#define EXYNOS4210_SDHC3_BASE_ADDR          0x12540000
+
+/* PMU SFR base address */
+#define EXYNOS4210_PMU_BASE_ADDR            0x10020000
+
+/* Display controllers (FIMD) */
+#define EXYNOS4210_FIMD0_BASE_ADDR          0x11C00000
+#define EXYNOS4210_FIMD1_BASE_ADDR          0x12000000
+
+/* MALI400 (G3D) */
+#define EXYNOS4210_G3D_BASE_ADDR            0x13000000
+#define EXYNOS4210_G3D_PIXEL_PROC_0_IRQ     0
+#define EXYNOS4210_G3D_PIXEL_PROC_1_IRQ     1
+#define EXYNOS4210_G3D_PIXEL_PROC_2_IRQ     2
+#define EXYNOS4210_G3D_PIXEL_PROC_3_IRQ     3
+#define EXYNOS4210_G3D_GEOM_PROC_IRQ        4
+#define EXYNOS4210_G3D_PMU_IRQ              5
+#define EXYNOS4210_G3D_PPMMU0_IRQ           0
+#define EXYNOS4210_G3D_PPMMU1_IRQ           1
+#define EXYNOS4210_G3D_PPMMU2_IRQ           2
+#define EXYNOS4210_G3D_PPMMU3_IRQ           3
+#define EXYNOS4210_G3D_GPMMU_IRQ            4
+
+/* PPMU */
+#define EXYNOS4210_PPMU_CPU_BASE_ADDR       0x106C0000
+/* DMC */
+#define EXYNOS4210_DMC0_BASE_ADDR           0x10400000
+#define EXYNOS4210_DMC1_BASE_ADDR           0x10410000
+
+/* I2S */
+#define EXYNOS4210_I2S0_BASE_ADDR           0x03830000
+
+/* pl050 ps/2 interface */
+#define EXYNOS4210_PL050_BASE_ADDR          0x12E30000
+
+static uint8_t chipid_and_omr[TARGET_PAGE_SIZE] = { 0x11, 0x02, 0x21, 0x43,
+                                    0x09, 0x00, 0x00, 0x00 };
+
+void maru_arm_write_secondary(ARMCPU *cpu,
+        const struct arm_boot_info *info)
+{
+    int n;
+    uint32_t smpboot[] = {
+        0xe59f3024, /* ldr r3, External gic_cpu_if */
+        0xe59f2024, /* ldr r2, Internal gic_cpu_if */
+        0xe59f0024, /* ldr r0, startaddr */
+        0xe3a01001, /* mov r1, #1 */
+        0xe5821000, /* str r1, [r2] */
+        0xe5831000, /* str r1, [r3] */
+        0xe320f003, /* wfi */
+        0xe5901000, /* ldr     r1, [r0] */
+        0xe1110001, /* tst     r1, r1 */
+        0x0afffffb, /* beq     <wfi> */
+        0xe12fff11, /* bx      r1 */
+        EXYNOS4210_EXT_GIC_CPU_BASE_ADDR,
+        0,          /* gic_cpu_if: base address of Internal GIC CPU interface */
+        0           /* bootreg: Boot register address is held here */
+    };
+    smpboot[ARRAY_SIZE(smpboot) - 1] = info->smp_bootreg_addr;
+    smpboot[ARRAY_SIZE(smpboot) - 2] = info->gic_cpu_if_addr;
+    for (n = 0; n < ARRAY_SIZE(smpboot); n++) {
+        smpboot[n] = tswap32(smpboot[n]);
+    }
+    rom_add_blob_fixed("smpboot", smpboot, sizeof(smpboot),
+                       info->smp_loader_start);
+}
+
+Exynos4210State *maru_arm_soc_init(MemoryRegion *system_mem,
+        unsigned long ram_size)
+{
+    qemu_irq cpu_irq[EXYNOS4210_NCPUS];
+    int i, n;
+    Exynos4210State *s = g_new(Exynos4210State, 1);
+    qemu_irq *irqp;
+    qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
+    unsigned long mem_size;
+    DeviceState *dev;
+    SysBusDevice *busdev;
+
+    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
+        s->cpu[n] = cpu_arm_init("cortex-a9");
+        if (!s->cpu[n]) {
+            fprintf(stderr, "Unable to find CPU %d definition\n", n);
+            exit(1);
+        }
+
+        /* Create PIC controller for each processor instance */
+        irqp = arm_pic_init_cpu(s->cpu[n]);
+
+        /*
+         * Get GICs gpio_in cpu_irq to connect a combiner to them later.
+         * Use only IRQ for a while.
+         */
+        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
+    }
+
+    /*** IRQs ***/
+
+    s->irq_table = exynos4210_init_irq(&s->irqs);
+
+    /* IRQ Gate */
+    for (i = 0; i < EXYNOS4210_NCPUS; i++) {
+        dev = qdev_create(NULL, "exynos4210.irq_gate");
+        qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
+        qdev_init_nofail(dev);
+        /* Get IRQ Gate input in gate_irq */
+        for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
+            gate_irq[i][n] = qdev_get_gpio_in(dev, n);
+        }
+        busdev = sysbus_from_qdev(dev);
+
+        /* Connect IRQ Gate output to cpu_irq */
+        sysbus_connect_irq(busdev, 0, cpu_irq[i]);
+    }
+
+    /* Private memory region and Internal GIC */
+    dev = qdev_create(NULL, "a9mpcore_priv");
+    qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
+    qdev_init_nofail(dev);
+    busdev = sysbus_from_qdev(dev);
+    sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
+    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
+        sysbus_connect_irq(busdev, n, gate_irq[n][0]);
+    }
+    for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
+        s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
+    }
+
+    /* Cache controller */
+    sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
+
+    /* External GIC */
+    dev = qdev_create(NULL, "exynos4210.gic");
+    qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
+    qdev_init_nofail(dev);
+    busdev = sysbus_from_qdev(dev);
+    /* Map CPU interface */
+    sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR);
+    /* Map Distributer interface */
+    sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
+    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
+        sysbus_connect_irq(busdev, n, gate_irq[n][1]);
+    }
+    for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
+        s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
+    }
+
+    /* Internal Interrupt Combiner */
+    dev = qdev_create(NULL, "exynos4210.combiner");
+    qdev_init_nofail(dev);
+    busdev = sysbus_from_qdev(dev);
+    for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
+        sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]);
+    }
+    exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
+    sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
+
+    /* External Interrupt Combiner */
+    dev = qdev_create(NULL, "exynos4210.combiner");
+    qdev_prop_set_uint32(dev, "external", 1);
+    qdev_init_nofail(dev);
+    busdev = sysbus_from_qdev(dev);
+    for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
+        sysbus_connect_irq(busdev, n, s->irqs.ext_gic_irq[n]);
+    }
+    exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
+    sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
+
+    /* Initialize board IRQs. */
+    exynos4210_init_board_irqs(&s->irqs);
+
+    /*** Memory ***/
+
+    /* Chip-ID and OMR */
+    memory_region_init_ram_ptr(&s->chipid_mem, "exynos4210.chipid",
+            sizeof(chipid_and_omr), chipid_and_omr);
+    memory_region_set_readonly(&s->chipid_mem, true);
+    memory_region_add_subregion(system_mem, EXYNOS4210_CHIPID_ADDR,
+                                &s->chipid_mem);
+
+    /* Internal ROM */
+    memory_region_init_ram(&s->irom_mem, "exynos4210.irom",
+                           EXYNOS4210_IROM_SIZE);
+    memory_region_set_readonly(&s->irom_mem, true);
+    memory_region_add_subregion(system_mem, EXYNOS4210_IROM_BASE_ADDR,
+                                &s->irom_mem);
+    /* mirror of iROM */
+    memory_region_init_alias(&s->irom_alias_mem, "exynos4210.irom_alias",
+                             &s->irom_mem,
+                             0,
+                             EXYNOS4210_IROM_SIZE);
+    memory_region_set_readonly(&s->irom_alias_mem, true);
+    memory_region_add_subregion(system_mem, EXYNOS4210_IROM_MIRROR_BASE_ADDR,
+                                &s->irom_alias_mem);
+
+    /* Internal RAM */
+    memory_region_init_ram(&s->iram_mem, "exynos4210.iram",
+                           EXYNOS4210_IRAM_SIZE);
+    vmstate_register_ram_global(&s->iram_mem);
+    memory_region_add_subregion(system_mem, EXYNOS4210_IRAM_BASE_ADDR,
+                                &s->iram_mem);
+
+    /* DRAM */
+    mem_size = ram_size;
+    if (mem_size > EXYNOS4210_DRAM_MAX_SIZE) {
+        memory_region_init_ram(&s->dram1_mem, "exynos4210.dram1",
+                mem_size - EXYNOS4210_DRAM_MAX_SIZE);
+        vmstate_register_ram_global(&s->dram1_mem);
+        memory_region_add_subregion(system_mem, EXYNOS4210_DRAM1_BASE_ADDR,
+                &s->dram1_mem);
+        mem_size = EXYNOS4210_DRAM_MAX_SIZE;
+    }
+    memory_region_init_ram(&s->dram0_mem, "exynos4210.dram0", mem_size);
+    vmstate_register_ram_global(&s->dram0_mem);
+    memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
+            &s->dram0_mem);
+
+    /* Audio Subsystem Internal Memory */
+    memory_region_init_ram(&s->audss_intmem, "exynos4210.audss",
+                           EXYNOS4210_AUDSS_INTMEM_SIZE);
+    vmstate_register_ram_global(&s->audss_intmem);
+    memory_region_add_subregion(system_mem, EXYNOS4210_AUDSS_INTMEM_BASE_ADDR,
+                                &s->audss_intmem);
+
+   /* PMU.
+    * The only reason of existence at the moment is that secondary CPU boot
+    * loader uses PMU INFORM5 register as a holding pen.
+    */
+    sysbus_create_simple("maru_arm.pmu", EXYNOS4210_PMU_BASE_ADDR, NULL);
+
+    /* CMUs */
+    exynos4210_cmu_create(EXYNOS4210_CMU_LEFTBUS_BASE_ADDR,
+                                                       EXYNOS4210_CMU_LEFTBUS);
+    exynos4210_cmu_create(EXYNOS4210_CMU_RIGHTBUS_BASE_ADDR,
+                                                      EXYNOS4210_CMU_RIGHTBUS);
+    exynos4210_cmu_create(EXYNOS4210_CMU_TOP_BASE_ADDR, EXYNOS4210_CMU_TOP);
+    exynos4210_cmu_create(EXYNOS4210_CMU_DMC_BASE_ADDR, EXYNOS4210_CMU_DMC);
+    exynos4210_cmu_create(EXYNOS4210_CMU_CPU_BASE_ADDR, EXYNOS4210_CMU_CPU);
+
+    /* PWM */
+    sysbus_create_varargs("exynos4210.pwm", EXYNOS4210_PWM_BASE_ADDR,
+                          s->irq_table[exynos4210_get_irq(22, 0)],
+                          s->irq_table[exynos4210_get_irq(22, 1)],
+                          s->irq_table[exynos4210_get_irq(22, 2)],
+                          s->irq_table[exynos4210_get_irq(22, 3)],
+                          s->irq_table[exynos4210_get_irq(22, 4)],
+                          NULL);
+    /* RTC */
+    sysbus_create_varargs("exynos4210.rtc", EXYNOS4210_RTC_BASE_ADDR,
+                          s->irq_table[exynos4210_get_irq(23, 0)],
+                          s->irq_table[exynos4210_get_irq(23, 1)],
+                          NULL);
+
+    /* Multi Core Timer */
+    dev = qdev_create(NULL, "exynos4210.mct");
+    qdev_init_nofail(dev);
+    busdev = sysbus_from_qdev(dev);
+    for (n = 0; n < 4; n++) {
+        /* Connect global timer interrupts to Combiner gpio_in */
+        sysbus_connect_irq(busdev, n,
+                s->irq_table[exynos4210_get_irq(1, 4 + n)]);
+    }
+    /* Connect local timer interrupts to Combiner gpio_in */
+    sysbus_connect_irq(busdev, 4,
+            s->irq_table[exynos4210_get_irq(51, 0)]);
+    sysbus_connect_irq(busdev, 5,
+            s->irq_table[exynos4210_get_irq(35, 3)]);
+    sysbus_mmio_map(busdev, 0, EXYNOS4210_MCT_BASE_ADDR);
+
+    /*** I2C ***/
+    for (n = 0; n < EXYNOS4210_I2C_NUMBER; n++) {
+        uint32_t addr = EXYNOS4210_I2C_BASE_ADDR + EXYNOS4210_I2C_SHIFT * n;
+        qemu_irq i2c_irq;
+
+        if (n < 8) {
+            i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_I2C_INTG, n)];
+        } else {
+            i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_HDMI_INTG, 1)];
+        }
+
+        dev = qdev_create(NULL, "exynos4210.i2c");
+        qdev_init_nofail(dev);
+        busdev = sysbus_from_qdev(dev);
+        sysbus_connect_irq(busdev, 0, i2c_irq);
+        sysbus_mmio_map(busdev, 0, addr);
+        s->i2c_if[n] = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
+    }
+
+
+    /*** UARTs ***/
+    exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
+                           EXYNOS4210_UART0_FIFO_SIZE, 0, NULL,
+                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 0)]);
+
+    exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
+                           EXYNOS4210_UART1_FIFO_SIZE, 1, NULL,
+                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 1)]);
+
+    exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
+                           EXYNOS4210_UART2_FIFO_SIZE, 2, NULL,
+                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 2)]);
+
+    exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
+                           EXYNOS4210_UART3_FIFO_SIZE, 3, NULL,
+                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 3)]);
+
+    if (!enable_vigs) {
+        /*** Display controller (FIMD) ***/
+        sysbus_create_varargs("exynos4210.fimd", EXYNOS4210_FIMD0_BASE_ADDR,
+                s->irq_table[exynos4210_get_irq(11, 0)],
+                s->irq_table[exynos4210_get_irq(11, 1)],
+                s->irq_table[exynos4210_get_irq(11, 2)],
+                NULL);
+    }
+
+    /* I2S0 */
+    s->i2s_bus[0] = exynos4210_i2s_bus_new("exynos4210.i2s",
+                                 EXYNOS4210_I2S0_BASE_ADDR,
+                                 s->irqs.ext_gic_irq[97]);
+
+    /* PL050 PS/2 if keyboard */
+    sysbus_create_simple("pl050_keyboard", EXYNOS4210_PL050_BASE_ADDR,
+            s->irq_table[exynos4210_get_irq(28, 2)]);
+
+    return s;
+}
diff --git a/tizen/src/hw/arm/maru_arm_vpci.c b/tizen/src/hw/arm/maru_arm_vpci.c
new file mode 100644 (file)
index 0000000..66e714b
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * Samsung Tizen Virtual PCI driver
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *  Vorobiov Stanislav <s.vorobiov@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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "sysbus.h"
+#include "pci.h"
+#include "pci_host.h"
+#include "exec-memory.h"
+
+#define TIZEN_VPCI_VENDOR_ID 0x10ee
+#define TIZEN_VPCI_DEVICE_ID 0x0300
+#define TIZEN_VPCI_CLASS_ID  PCI_CLASS_PROCESSOR_CO
+
+#define TIZEN_VPCI_IO_ADDR 0xC3000000
+#define TIZEN_VPCI_IO_SIZE 0xFFFF
+
+typedef struct {
+    SysBusDevice busdev;
+    qemu_irq irq[4];
+    MemoryRegion mem_config;
+    MemoryRegion iospace_alias_mem;
+} TizenVPCIState;
+
+static uint64_t tizen_vpci_io_read(void *opaque, target_phys_addr_t addr,
+                                   unsigned size)
+{
+    switch (size) {
+    case 1:
+        return cpu_inb(addr);
+    case 2:
+        return cpu_inw(addr);
+    case 4:
+        return cpu_inl(addr);
+    default:
+        break;
+    }
+    assert(0);
+}
+
+static void tizen_vpci_io_write(void *opaque, target_phys_addr_t addr,
+                                uint64_t data, unsigned size)
+{
+    switch (size) {
+    case 1:
+        cpu_outb(addr, data);
+        return;
+    case 2:
+        cpu_outw(addr, data);
+        return;
+    case 4:
+        cpu_outl(addr, data);
+        return;
+    }
+    assert(0);
+}
+
+static const MemoryRegionOps tizen_vpci_io_ops = {
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .read = tizen_vpci_io_read,
+    .write = tizen_vpci_io_write
+};
+
+static inline uint32_t tizen_vpci_config_addr(target_phys_addr_t addr)
+{
+    return addr & 0xffffff;
+}
+
+static void tizen_vpci_config_write(void *opaque, target_phys_addr_t addr,
+                                 uint64_t val, unsigned size)
+{
+    pci_data_write(opaque, tizen_vpci_config_addr(addr), val, size);
+}
+
+static uint64_t tizen_vpci_config_read(void *opaque, target_phys_addr_t addr,
+                                    unsigned size)
+{
+    uint32_t val;
+    val = pci_data_read(opaque, tizen_vpci_config_addr(addr), size);
+    return val;
+}
+
+static const MemoryRegionOps tizen_vpci_config_ops = {
+    .read = tizen_vpci_config_read,
+    .write = tizen_vpci_config_write,
+    .endianness = DEVICE_NATIVE_ENDIAN,
+};
+
+static int tizen_vpci_map_irq(PCIDevice *d, int irq_num)
+{
+    return irq_num;
+}
+
+static void tizen_vpci_set_irq(void *opaque, int irq_num, int level)
+{
+    qemu_irq *pic = opaque;
+
+    qemu_set_irq(pic[irq_num], level);
+}
+
+static int tizen_vpci_init(SysBusDevice *dev)
+{
+    TizenVPCIState *s = FROM_SYSBUS(TizenVPCIState, dev);
+    PCIBus *bus;
+    int i;
+
+    for (i = 0; i < 4; i++) {
+        sysbus_init_irq(dev, &s->irq[i]);
+    }
+
+    /* On ARM, we only have MMIO no specific IO space from the CPU
+     * perspective.  In theory we ought to be able to embed the PCI IO
+     * memory region direction in the system memory space.  However,
+     * if any of the IO BAR subregions use the old_portio mechanism,
+     * that won't be processed properly unless accessed from the
+     * system io address space.  This hack to bounce things via
+     * system_io works around the problem until all the users of
+     * old_portion are updated */
+
+    memory_region_init_io(&s->iospace_alias_mem, &tizen_vpci_io_ops, s,
+                          "tizen_vpci.io-alias", TIZEN_VPCI_IO_SIZE);
+    memory_region_add_subregion(get_system_memory(), TIZEN_VPCI_IO_ADDR,
+                                &s->iospace_alias_mem);
+
+    bus = pci_register_bus(&dev->qdev, "pci",
+                           tizen_vpci_set_irq, tizen_vpci_map_irq, s->irq,
+                           get_system_memory(), get_system_io(),
+                           0, 4);
+
+    memory_region_init_io(&s->mem_config, &tizen_vpci_config_ops, bus,
+                          "tizen-vpci-config", 0x1000000);
+    sysbus_init_mmio(dev, &s->mem_config);
+
+    pci_create_simple(bus, -1, "tizen_vpci_host");
+
+    return 0;
+}
+
+static int tizen_vpci_host_init(PCIDevice *d)
+{
+    pci_set_word(d->config + PCI_STATUS,
+         PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_FAST);
+    return 0;
+}
+
+static void tizen_vpci_host_class_init(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = tizen_vpci_host_init;
+    k->vendor_id = TIZEN_VPCI_VENDOR_ID;
+    k->device_id = TIZEN_VPCI_DEVICE_ID;
+    k->class_id = TIZEN_VPCI_CLASS_ID;
+}
+
+static TypeInfo tizen_vpci_host_info = {
+    .name          = "tizen_vpci_host",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIDevice),
+    .class_init    = tizen_vpci_host_class_init,
+};
+
+static void tizen_vpci_class_init(ObjectClass *klass, void *data)
+{
+    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
+
+    sdc->init = tizen_vpci_init;
+}
+
+static TypeInfo tizen_vpci_info = {
+    .name          = "tizen_vpci",
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(TizenVPCIState),
+    .class_init    = tizen_vpci_class_init,
+};
+
+static void tizen_vpci_register_types(void)
+{
+    type_register_static(&tizen_vpci_info);
+    type_register_static(&tizen_vpci_host_info);
+}
+
+type_init(tizen_vpci_register_types)
diff --git a/tizen/src/hw/maru_arm.h b/tizen/src/hw/maru_arm.h
deleted file mode 100644 (file)
index 6fa1a9d..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *  Samsung Maru ARM SoC emulation
- *
- *  Copyright (c) 2012 Samsung Electronics Co., Ltd.
- *    Evgeny Voevodin <e.voevodin@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, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#ifndef MARU_ARM_H_
-#define MARU_ARM_H_
-
-#include "qemu-common.h"
-#include "memory.h"
-#include "exynos4210.h"
-
-void maru_arm_write_secondary(ARMCPU *cpu,
-        const struct arm_boot_info *info);
-
-Exynos4210State *maru_arm_soc_init(MemoryRegion *system_mem,
-        unsigned long ram_size);
-
-int codec_init(PCIBus *bus);
-int maru_camera_pci_init(PCIBus *bus);
-
-#endif /* MARU_ARM_H_ */
diff --git a/tizen/src/hw/maru_arm_board.c b/tizen/src/hw/maru_arm_board.c
deleted file mode 100644 (file)
index dae7534..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * TIZEN ARM base board
- *
- * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd.
- *
- * Based on maru_board.c, exynos4210.c and exynos4210_boards.c
- *
- * Author:
- *  Evgeny Voevodin <e.voevodin@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License; 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <glib.h>
-
-#include "boards.h"
-#include "arm-misc.h"
-#include "sysbus.h"
-#include "pci.h"
-#include "maru_arm.h"
-#include "i2c.h"
-#include "exec-memory.h"
-#include "hw/maru_brightness.h"
-#include "arch_init.h"
-
-#include "xen.h"
-#ifdef CONFIG_XEN
-#  include <xen/hvm/hvm_info_table.h>
-#endif
-#include "maru_common.h"
-#if defined(__linux__)
-#include <X11/Xlib.h>
-#endif
-#include "vigs_device.h"
-extern int enable_yagl;
-extern const char *yagl_backend;
-extern int enable_vigs;
-extern const char *vigs_backend;
-
-#undef DEBUG
-//#define DEBUG
-#ifdef DEBUG
-    #undef PRINT_DEBUG
-    #define  PRINT_DEBUG(fmt, args...) \
-        do { \
-            fprintf(stderr, "  [%s:%d]   "fmt, __func__, __LINE__, ##args); \
-        } while (0)
-#else
-    #define  PRINT_DEBUG(fmt, args...)  do {} while (0)
-#endif
-
-#ifndef DEBUG_LOG_PATH
-#define DEBUG_LOG_PATH                     "./debug.log"
-#endif
-
-#define EXYNOS4210_WM8994_ADDR             0x1A
-#define MARU_ARM_BOARD_ID                  0xF3B
-#define MARU_ARM_BOARD_SMP_BOOTREG_ADDR    EXYNOS4210_SECOND_CPU_BOOTREG
-#define MARU_ARM_BOARD_RAMSIZE_MIN         0x20000000
-#define MARU_ARM_BOARD_RAMSIZE_DEFAULT     0x40000000
-
-static struct arm_boot_info maru_arm_board_binfo = {
-    .loader_start     = EXYNOS4210_BASE_BOOT_ADDR,
-    .smp_loader_start = EXYNOS4210_SMP_BOOT_ADDR,
-    .nb_cpus          = EXYNOS4210_NCPUS,
-    .write_secondary_boot = maru_arm_write_secondary,
-};
-
-static void maru_arm_machine_init(ram_addr_t ram_size,
-                        const char *boot_device,
-                        const char *kernel_filename,
-                        const char *kernel_cmdline,
-                        const char *initrd_filename,
-                        const char *cpu_model)
-{
-    Exynos4210State *s;
-    DeviceState *dev;
-    PCIBus *pci_bus;
-#if defined(__linux__)
-    Display *display = XOpenDisplay(0);
-    if (!display) {
-        fprintf(stderr, "Cannot open X display\n");
-        exit(1);
-    }
-#else
-    void *display = NULL;
-#endif
-    struct winsys_interface *vigs_wsi = NULL;
-
-    /*
-     * W/A for allocate larger continuous heap. From maru_board.c
-     */
-    if (!xen_enabled()) {
-        if(preallocated_ptr != NULL) {
-            qemu_vfree(preallocated_ptr);
-        }
-    }
-
-    if (ram_size < MARU_ARM_BOARD_RAMSIZE_MIN) {
-       ram_size = MARU_ARM_BOARD_RAMSIZE_DEFAULT;
-       fprintf(stderr, "RAM size is too small, setting to default value 0x%lx",
-                       (long unsigned int)ram_size);
-    }
-
-    maru_arm_board_binfo.ram_size = ram_size;
-    maru_arm_board_binfo.board_id = MARU_ARM_BOARD_ID;
-    maru_arm_board_binfo.smp_bootreg_addr = MARU_ARM_BOARD_SMP_BOOTREG_ADDR;
-    maru_arm_board_binfo.kernel_filename = kernel_filename;
-    maru_arm_board_binfo.initrd_filename = initrd_filename;
-    maru_arm_board_binfo.kernel_cmdline = kernel_cmdline;
-    maru_arm_board_binfo.gic_cpu_if_addr =
-                        EXYNOS4210_SMP_PRIVATE_BASE_ADDR + 0x100;
-
-    PRINT_DEBUG("\n ram_size: %luMiB [0x%08lx]\n"
-            " kernel_filename: %s\n"
-            " kernel_cmdline: %s\n"
-            " initrd_filename: %s\n",
-            (long unsigned int)ram_size / 1048576,
-            (long unsigned int)ram_size,
-            kernel_filename,
-            kernel_cmdline,
-            initrd_filename);
-    s = maru_arm_soc_init(get_system_memory(), ram_size);
-
-    /* PCI config */
-    dev = qdev_create(NULL, "tizen_vpci");
-    s->vpci_bus = sysbus_from_qdev(dev);
-    qdev_init_nofail(dev);
-    sysbus_mmio_map(s->vpci_bus, 0, EXYNOS4210_VPCI_CFG_BASE_ADDR);
-    sysbus_connect_irq(s->vpci_bus, 0, s->irq_table[exynos4210_get_irq(38, 0)]);
-    sysbus_connect_irq(s->vpci_bus, 1, s->irq_table[exynos4210_get_irq(38, 1)]);
-    sysbus_connect_irq(s->vpci_bus, 2, s->irq_table[exynos4210_get_irq(38, 2)]);
-    sysbus_connect_irq(s->vpci_bus, 3, s->irq_table[exynos4210_get_irq(38, 3)]);
-    pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");
-
-    pci_create_simple(pci_bus, -1, "pci-ohci");
-    maru_camera_pci_init(pci_bus);
-    maru_brill_codec_pci_device_init(pci_bus);
-    pci_maru_brightness_init(pci_bus);
-
-    if (enable_vigs) {
-        PCIDevice *pci_dev = pci_create(pci_bus, -1, "vigs");
-        qdev_prop_set_ptr(&pci_dev->qdev, "display", display);
-        qdev_init_nofail(&pci_dev->qdev);
-        vigs_wsi = DO_UPCAST(VIGSDevice, pci_dev, pci_dev)->wsi;
-    }
-
-    if (enable_yagl) {
-        PCIDevice *pci_dev = pci_create(pci_bus, -1, "yagl");
-        qdev_prop_set_ptr(&pci_dev->qdev, "display", display);
-        if (vigs_wsi &&
-            (strcmp(yagl_backend, "vigs") == 0) &&
-            (strcmp(vigs_backend, "gl") == 0)) {
-            qdev_prop_set_ptr(&pci_dev->qdev, "winsys_gl_interface", vigs_wsi);
-        }
-        qdev_init_nofail(&pci_dev->qdev);
-    }
-
-    audio_init(NULL, pci_bus);
-
-    arm_load_kernel(arm_env_get_cpu(first_cpu), &maru_arm_board_binfo);
-}
-
-static QEMUMachine maru_arm_machine = {
-    .name = "maru-arm-machine",
-    .desc = "maru board(ARM)",
-    .init = maru_arm_machine_init,
-    .max_cpus = 255,
-};
-
-static void maru_machine_init(void)
-{
-    qemu_register_machine(&maru_arm_machine);
-}
-
-machine_init(maru_machine_init);
diff --git a/tizen/src/hw/maru_arm_pmu.c b/tizen/src/hw/maru_arm_pmu.c
deleted file mode 100644 (file)
index 202ad81..0000000
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- *  Tizen Power Management Unit (PMU) Emulation
- *
- *  Based on exynos4210_pmu.c
- *  Copyright (C) 2011 Samsung Electronics Co Ltd.
- *    Evgeny Voevodin <e.voevodin@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, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * This model implements PMU registers just as a bulk of memory.
- * Able to shutdown and restart only.
- */
-
-#include "sysbus.h"
-#include "sysemu.h"
-#include "ptimer.h"
-
-#ifndef DEBUG_PMU
-#define DEBUG_PMU           0
-#endif
-
-#ifndef DEBUG_PMU_EXTEND
-#define DEBUG_PMU_EXTEND    0
-#endif
-
-#if DEBUG_PMU
-#define  PRINT_DEBUG(fmt, args...)  \
-        do { \
-            fprintf(stderr, "  [%s:%d]   "fmt, __func__, __LINE__, ##args); \
-        } while (0)
-
-#if DEBUG_PMU_EXTEND
-#define  PRINT_DEBUG_EXTEND(fmt, args...) \
-        do { \
-            fprintf(stderr, "  [%s:%d]   "fmt, __func__, __LINE__, ##args); \
-        } while (0)
-#else
-#define  PRINT_DEBUG_EXTEND(fmt, args...)  do {} while (0)
-#endif /* EXTEND */
-
-#else
-#define  PRINT_DEBUG(fmt, args...)   do {} while (0)
-#define  PRINT_DEBUG_EXTEND(fmt, args...)  do {} while (0)
-#endif
-
-#define  POWER_OFF_TIMER_FREQ   24000000
-
-/*
- *  Offsets for PMU registers
- */
-#define OM_STAT                  0x0000 /* OM status register */
-#define RTC_CLKO_SEL             0x000C /* Controls RTCCLKOUT */
-#define GNSS_RTC_OUT_CTRL        0x0010 /* Controls GNSS_RTC_OUT */
-/* Decides whether system-level low-power mode is used. */
-#define SYSTEM_POWER_DOWN_CTRL   0x0200
-/* Sets control options for CENTRAL_SEQ */
-#define SYSTEM_POWER_DOWN_OPTION 0x0208
-#define SWRESET                  0x0400 /* Generate software reset */
-#define RST_STAT                 0x0404 /* Reset status register */
-#define WAKEUP_STAT              0x0600 /* Wakeup status register  */
-#define EINT_WAKEUP_MASK         0x0604 /* Configure External INTerrupt mask */
-#define WAKEUP_MASK              0x0608 /* Configure wakeup source mask */
-#define HDMI_PHY_CONTROL         0x0700 /* HDMI PHY control register */
-#define USBDEVICE_PHY_CONTROL    0x0704 /* USB Device PHY control register */
-#define USBHOST_PHY_CONTROL      0x0708 /* USB HOST PHY control register */
-#define DAC_PHY_CONTROL          0x070C /* DAC control register  */
-#define MIPI_PHY0_CONTROL        0x0710 /* MIPI PHY control register */
-#define MIPI_PHY1_CONTROL        0x0714 /* MIPI PHY control register */
-#define ADC_PHY_CONTROL          0x0718 /* TS-ADC control register */
-#define PCIe_PHY_CONTROL         0x071C /* TS-PCIe control register */
-#define SATA_PHY_CONTROL         0x0720 /* TS-SATA control register */
-#define INFORM0                  0x0800 /* Information register 0  */
-#define INFORM1                  0x0804 /* Information register 1  */
-#define INFORM2                  0x0808 /* Information register 2  */
-#define INFORM3                  0x080C /* Information register 3  */
-#define INFORM4                  0x0810 /* Information register 4  */
-#define INFORM5                  0x0814 /* Information register 5  */
-#define INFORM6                  0x0818 /* Information register 6  */
-#define INFORM7                  0x081C /* Information register 7  */
-#define PMU_DEBUG                0x0A00 /* PMU debug register */
-/* Registers to set system-level low-power option */
-#define ARM_CORE0_SYS_PWR_REG              0x1000
-#define ARM_CORE1_SYS_PWR_REG              0x1010
-#define ARM_COMMON_SYS_PWR_REG             0x1080
-#define ARM_CPU_L2_0_SYS_PWR_REG           0x10C0
-#define ARM_CPU_L2_1_SYS_PWR_REG           0x10C4
-#define CMU_ACLKSTOP_SYS_PWR_REG           0x1100
-#define CMU_SCLKSTOP_SYS_PWR_REG           0x1104
-#define CMU_RESET_SYS_PWR_REG              0x110C
-#define APLL_SYSCLK_SYS_PWR_REG            0x1120
-#define MPLL_SYSCLK_SYS_PWR_REG            0x1124
-#define VPLL_SYSCLK_SYS_PWR_REG            0x1128
-#define EPLL_SYSCLK_SYS_PWR_REG            0x112C
-#define CMU_CLKSTOP_GPS_ALIVE_SYS_PWR_REG  0x1138
-#define CMU_RESET_GPS_ALIVE_SYS_PWR_REG    0x113C
-#define CMU_CLKSTOP_CAM_SYS_PWR_REG        0x1140
-#define CMU_CLKSTOP_TV_SYS_PWR_REG         0x1144
-#define CMU_CLKSTOP_MFC_SYS_PWR_REG        0x1148
-#define CMU_CLKSTOP_G3D_SYS_PWR_REG        0x114C
-#define CMU_CLKSTOP_LCD0_SYS_PWR_REG       0x1150
-#define CMU_CLKSTOP_LCD1_SYS_PWR_REG       0x1154
-#define CMU_CLKSTOP_MAUDIO_SYS_PWR_REG     0x1158
-#define CMU_CLKSTOP_GPS_SYS_PWR_REG        0x115C
-#define CMU_RESET_CAM_SYS_PWR_REG          0x1160
-#define CMU_RESET_TV_SYS_PWR_REG           0x1164
-#define CMU_RESET_MFC_SYS_PWR_REG          0x1168
-#define CMU_RESET_G3D_SYS_PWR_REG          0x116C
-#define CMU_RESET_LCD0_SYS_PWR_REG         0x1170
-#define CMU_RESET_LCD1_SYS_PWR_REG         0x1174
-#define CMU_RESET_MAUDIO_SYS_PWR_REG       0x1178
-#define CMU_RESET_GPS_SYS_PWR_REG          0x117C
-#define TOP_BUS_SYS_PWR_REG                0x1180
-#define TOP_RETENTION_SYS_PWR_REG          0x1184
-#define TOP_PWR_SYS_PWR_REG                0x1188
-#define LOGIC_RESET_SYS_PWR_REG            0x11A0
-#define OneNANDXL_MEM_SYS_PWR_REG          0x11C0
-#define MODEMIF_MEM_SYS_PWR_REG            0x11C4
-#define USBDEVICE_MEM_SYS_PWR_REG          0x11CC
-#define SDMMC_MEM_SYS_PWR_REG              0x11D0
-#define CSSYS_MEM_SYS_PWR_REG              0x11D4
-#define SECSS_MEM_SYS_PWR_REG              0x11D8
-#define PCIe_MEM_SYS_PWR_REG               0x11E0
-#define SATA_MEM_SYS_PWR_REG               0x11E4
-#define PAD_RETENTION_DRAM_SYS_PWR_REG     0x1200
-#define PAD_RETENTION_MAUDIO_SYS_PWR_REG   0x1204
-#define PAD_RETENTION_GPIO_SYS_PWR_REG     0x1220
-#define PAD_RETENTION_UART_SYS_PWR_REG     0x1224
-#define PAD_RETENTION_MMCA_SYS_PWR_REG     0x1228
-#define PAD_RETENTION_MMCB_SYS_PWR_REG     0x122C
-#define PAD_RETENTION_EBIA_SYS_PWR_REG     0x1230
-#define PAD_RETENTION_EBIB_SYS_PWR_REG     0x1234
-#define PAD_ISOLATION_SYS_PWR_REG          0x1240
-#define PAD_ALV_SEL_SYS_PWR_REG            0x1260
-#define XUSBXTI_SYS_PWR_REG                0x1280
-#define XXTI_SYS_PWR_REG                   0x1284
-#define EXT_REGULATOR_SYS_PWR_REG          0x12C0
-#define GPIO_MODE_SYS_PWR_REG              0x1300
-#define GPIO_MODE_MAUDIO_SYS_PWR_REG       0x1340
-#define CAM_SYS_PWR_REG                    0x1380
-#define TV_SYS_PWR_REG                     0x1384
-#define MFC_SYS_PWR_REG                    0x1388
-#define G3D_SYS_PWR_REG                    0x138C
-#define LCD0_SYS_PWR_REG                   0x1390
-#define LCD1_SYS_PWR_REG                   0x1394
-#define MAUDIO_SYS_PWR_REG                 0x1398
-#define GPS_SYS_PWR_REG                    0x139C
-#define GPS_ALIVE_SYS_PWR_REG              0x13A0
-#define ARM_CORE0_CONFIGURATION 0x2000 /* Configure power mode of ARM_CORE0 */
-#define ARM_CORE0_STATUS        0x2004 /* Check power mode of ARM_CORE0 */
-#define ARM_CORE0_OPTION        0x2008 /* Sets control options for ARM_CORE0 */
-#define ARM_CORE1_CONFIGURATION 0x2080 /* Configure power mode of ARM_CORE1 */
-#define ARM_CORE1_STATUS        0x2084 /* Check power mode of ARM_CORE1 */
-#define ARM_CORE1_OPTION        0x2088 /* Sets control options for ARM_CORE0 */
-#define ARM_COMMON_OPTION       0x2408 /* Sets control options for ARM_COMMON */
-/* Configure power mode of ARM_CPU_L2_0 */
-#define ARM_CPU_L2_0_CONFIGURATION 0x2600
-#define ARM_CPU_L2_0_STATUS        0x2604 /* Check power mode of ARM_CPU_L2_0 */
-/* Configure power mode of ARM_CPU_L2_1 */
-#define ARM_CPU_L2_1_CONFIGURATION 0x2620
-#define ARM_CPU_L2_1_STATUS        0x2624 /* Check power mode of ARM_CPU_L2_1 */
-/* Sets control options for PAD_RETENTION_MAUDIO */
-#define PAD_RETENTION_MAUDIO_OPTION 0x3028
-/* Sets control options for PAD_RETENTION_GPIO */
-#define PAD_RETENTION_GPIO_OPTION   0x3108
-/* Sets control options for PAD_RETENTION_UART */
-#define PAD_RETENTION_UART_OPTION   0x3128
-/* Sets control options for PAD_RETENTION_MMCA */
-#define PAD_RETENTION_MMCA_OPTION   0x3148
-/* Sets control options for PAD_RETENTION_MMCB */
-#define PAD_RETENTION_MMCB_OPTION   0x3168
-/* Sets control options for PAD_RETENTION_EBIA */
-#define PAD_RETENTION_EBIA_OPTION   0x3188
-/* Sets control options for PAD_RETENTION_EBIB */
-#define PAD_RETENTION_EBIB_OPTION   0x31A8
-#define PS_HOLD_CONTROL         0x330C /* PS_HOLD control register */
-#define XUSBXTI_CONFIGURATION   0x3400 /* Configure the pad of XUSBXTI */
-#define XUSBXTI_STATUS          0x3404 /* Check the pad of XUSBXTI */
-/* Sets time required for XUSBXTI to be stabilized */
-#define XUSBXTI_DURATION        0x341C
-#define XXTI_CONFIGURATION      0x3420 /* Configure the pad of XXTI */
-#define XXTI_STATUS             0x3424 /* Check the pad of XXTI */
-/* Sets time required for XXTI to be stabilized */
-#define XXTI_DURATION           0x343C
-/* Sets time required for EXT_REGULATOR to be stabilized */
-#define EXT_REGULATOR_DURATION  0x361C
-#define CAM_CONFIGURATION       0x3C00 /* Configure power mode of CAM */
-#define CAM_STATUS              0x3C04 /* Check power mode of CAM */
-#define CAM_OPTION              0x3C08 /* Sets control options for CAM */
-#define TV_CONFIGURATION        0x3C20 /* Configure power mode of TV */
-#define TV_STATUS               0x3C24 /* Check power mode of TV */
-#define TV_OPTION               0x3C28 /* Sets control options for TV */
-#define MFC_CONFIGURATION       0x3C40 /* Configure power mode of MFC */
-#define MFC_STATUS              0x3C44 /* Check power mode of MFC */
-#define MFC_OPTION              0x3C48 /* Sets control options for MFC */
-#define G3D_CONFIGURATION       0x3C60 /* Configure power mode of G3D */
-#define G3D_STATUS              0x3C64 /* Check power mode of G3D */
-#define G3D_OPTION              0x3C68 /* Sets control options for G3D */
-#define LCD0_CONFIGURATION      0x3C80 /* Configure power mode of LCD0 */
-#define LCD0_STATUS             0x3C84 /* Check power mode of LCD0 */
-#define LCD0_OPTION             0x3C88 /* Sets control options for LCD0 */
-#define LCD1_CONFIGURATION      0x3CA0 /* Configure power mode of LCD1 */
-#define LCD1_STATUS             0x3CA4 /* Check power mode of LCD1 */
-#define LCD1_OPTION             0x3CA8 /* Sets control options for LCD1 */
-#define GPS_CONFIGURATION       0x3CE0 /* Configure power mode of GPS */
-#define GPS_STATUS              0x3CE4 /* Check power mode of GPS */
-#define GPS_OPTION              0x3CE8 /* Sets control options for GPS */
-#define GPS_ALIVE_CONFIGURATION 0x3D00 /* Configure power mode of GPS */
-#define GPS_ALIVE_STATUS        0x3D04 /* Check power mode of GPS */
-#define GPS_ALIVE_OPTION        0x3D08 /* Sets control options for GPS */
-
-#define EXYNOS4210_PMU_REGS_MEM_SIZE 0x3d0c
-
-typedef struct Exynos4210PmuReg {
-    const char  *name; /* for debug only */
-    uint32_t     offset;
-    uint32_t     reset_value;
-} Exynos4210PmuReg;
-
-static const Exynos4210PmuReg exynos4210_pmu_regs[] = {
-    {"OM_STAT", OM_STAT, 0x00000000},
-    {"RTC_CLKO_SEL", RTC_CLKO_SEL, 0x00000000},
-    {"GNSS_RTC_OUT_CTRL", GNSS_RTC_OUT_CTRL, 0x00000001},
-    {"SYSTEM_POWER_DOWN_CTRL", SYSTEM_POWER_DOWN_CTRL, 0x00010000},
-    {"SYSTEM_POWER_DOWN_OPTION", SYSTEM_POWER_DOWN_OPTION, 0x03030000},
-    {"SWRESET", SWRESET, 0x00000000},
-    {"RST_STAT", RST_STAT, 0x00000000},
-    {"WAKEUP_STAT", WAKEUP_STAT, 0x00000000},
-    {"EINT_WAKEUP_MASK", EINT_WAKEUP_MASK, 0x00000000},
-    {"WAKEUP_MASK", WAKEUP_MASK, 0x00000000},
-    {"HDMI_PHY_CONTROL", HDMI_PHY_CONTROL, 0x00960000},
-    {"USBDEVICE_PHY_CONTROL", USBDEVICE_PHY_CONTROL, 0x00000000},
-    {"USBHOST_PHY_CONTROL", USBHOST_PHY_CONTROL, 0x00000000},
-    {"DAC_PHY_CONTROL", DAC_PHY_CONTROL, 0x00000000},
-    {"MIPI_PHY0_CONTROL", MIPI_PHY0_CONTROL, 0x00000000},
-    {"MIPI_PHY1_CONTROL", MIPI_PHY1_CONTROL, 0x00000000},
-    {"ADC_PHY_CONTROL", ADC_PHY_CONTROL, 0x00000001},
-    {"PCIe_PHY_CONTROL", PCIe_PHY_CONTROL, 0x00000000},
-    {"SATA_PHY_CONTROL", SATA_PHY_CONTROL, 0x00000000},
-    {"INFORM0", INFORM0, 0x00000000},
-    {"INFORM1", INFORM1, 0x00000000},
-    {"INFORM2", INFORM2, 0x00000000},
-    {"INFORM3", INFORM3, 0x00000000},
-    {"INFORM4", INFORM4, 0x00000000},
-    {"INFORM5", INFORM5, 0x00000000},
-    {"INFORM6", INFORM6, 0x00000000},
-    {"INFORM7", INFORM7, 0x00000000},
-    {"PMU_DEBUG", PMU_DEBUG, 0x00000000},
-    {"ARM_CORE0_SYS_PWR_REG", ARM_CORE0_SYS_PWR_REG, 0xFFFFFFFF},
-    {"ARM_CORE1_SYS_PWR_REG", ARM_CORE1_SYS_PWR_REG, 0xFFFFFFFF},
-    {"ARM_COMMON_SYS_PWR_REG", ARM_COMMON_SYS_PWR_REG, 0xFFFFFFFF},
-    {"ARM_CPU_L2_0_SYS_PWR_REG", ARM_CPU_L2_0_SYS_PWR_REG, 0xFFFFFFFF},
-    {"ARM_CPU_L2_1_SYS_PWR_REG", ARM_CPU_L2_1_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CMU_ACLKSTOP_SYS_PWR_REG", CMU_ACLKSTOP_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CMU_SCLKSTOP_SYS_PWR_REG", CMU_SCLKSTOP_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CMU_RESET_SYS_PWR_REG", CMU_RESET_SYS_PWR_REG, 0xFFFFFFFF},
-    {"APLL_SYSCLK_SYS_PWR_REG", APLL_SYSCLK_SYS_PWR_REG, 0xFFFFFFFF},
-    {"MPLL_SYSCLK_SYS_PWR_REG", MPLL_SYSCLK_SYS_PWR_REG, 0xFFFFFFFF},
-    {"VPLL_SYSCLK_SYS_PWR_REG", VPLL_SYSCLK_SYS_PWR_REG, 0xFFFFFFFF},
-    {"EPLL_SYSCLK_SYS_PWR_REG", EPLL_SYSCLK_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CMU_CLKSTOP_GPS_ALIVE_SYS_PWR_REG", CMU_CLKSTOP_GPS_ALIVE_SYS_PWR_REG,
-            0xFFFFFFFF},
-    {"CMU_RESET_GPS_ALIVE_SYS_PWR_REG", CMU_RESET_GPS_ALIVE_SYS_PWR_REG,
-            0xFFFFFFFF},
-    {"CMU_CLKSTOP_CAM_SYS_PWR_REG", CMU_CLKSTOP_CAM_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CMU_CLKSTOP_TV_SYS_PWR_REG", CMU_CLKSTOP_TV_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CMU_CLKSTOP_MFC_SYS_PWR_REG", CMU_CLKSTOP_MFC_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CMU_CLKSTOP_G3D_SYS_PWR_REG", CMU_CLKSTOP_G3D_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CMU_CLKSTOP_LCD0_SYS_PWR_REG", CMU_CLKSTOP_LCD0_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CMU_CLKSTOP_LCD1_SYS_PWR_REG", CMU_CLKSTOP_LCD1_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CMU_CLKSTOP_MAUDIO_SYS_PWR_REG", CMU_CLKSTOP_MAUDIO_SYS_PWR_REG,
-            0xFFFFFFFF},
-    {"CMU_CLKSTOP_GPS_SYS_PWR_REG", CMU_CLKSTOP_GPS_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CMU_RESET_CAM_SYS_PWR_REG", CMU_RESET_CAM_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CMU_RESET_TV_SYS_PWR_REG", CMU_RESET_TV_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CMU_RESET_MFC_SYS_PWR_REG", CMU_RESET_MFC_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CMU_RESET_G3D_SYS_PWR_REG", CMU_RESET_G3D_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CMU_RESET_LCD0_SYS_PWR_REG", CMU_RESET_LCD0_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CMU_RESET_LCD1_SYS_PWR_REG", CMU_RESET_LCD1_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CMU_RESET_MAUDIO_SYS_PWR_REG", CMU_RESET_MAUDIO_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CMU_RESET_GPS_SYS_PWR_REG", CMU_RESET_GPS_SYS_PWR_REG, 0xFFFFFFFF},
-    {"TOP_BUS_SYS_PWR_REG", TOP_BUS_SYS_PWR_REG, 0xFFFFFFFF},
-    {"TOP_RETENTION_SYS_PWR_REG", TOP_RETENTION_SYS_PWR_REG, 0xFFFFFFFF},
-    {"TOP_PWR_SYS_PWR_REG", TOP_PWR_SYS_PWR_REG, 0xFFFFFFFF},
-    {"LOGIC_RESET_SYS_PWR_REG", LOGIC_RESET_SYS_PWR_REG, 0xFFFFFFFF},
-    {"OneNANDXL_MEM_SYS_PWR_REG", OneNANDXL_MEM_SYS_PWR_REG, 0xFFFFFFFF},
-    {"MODEMIF_MEM_SYS_PWR_REG", MODEMIF_MEM_SYS_PWR_REG, 0xFFFFFFFF},
-    {"USBDEVICE_MEM_SYS_PWR_REG", USBDEVICE_MEM_SYS_PWR_REG, 0xFFFFFFFF},
-    {"SDMMC_MEM_SYS_PWR_REG", SDMMC_MEM_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CSSYS_MEM_SYS_PWR_REG", CSSYS_MEM_SYS_PWR_REG, 0xFFFFFFFF},
-    {"SECSS_MEM_SYS_PWR_REG", SECSS_MEM_SYS_PWR_REG, 0xFFFFFFFF},
-    {"PCIe_MEM_SYS_PWR_REG", PCIe_MEM_SYS_PWR_REG, 0xFFFFFFFF},
-    {"SATA_MEM_SYS_PWR_REG", SATA_MEM_SYS_PWR_REG, 0xFFFFFFFF},
-    {"PAD_RETENTION_DRAM_SYS_PWR_REG", PAD_RETENTION_DRAM_SYS_PWR_REG,
-            0xFFFFFFFF},
-    {"PAD_RETENTION_MAUDIO_SYS_PWR_REG", PAD_RETENTION_MAUDIO_SYS_PWR_REG,
-            0xFFFFFFFF},
-    {"PAD_RETENTION_GPIO_SYS_PWR_REG", PAD_RETENTION_GPIO_SYS_PWR_REG,
-            0xFFFFFFFF},
-    {"PAD_RETENTION_UART_SYS_PWR_REG", PAD_RETENTION_UART_SYS_PWR_REG,
-            0xFFFFFFFF},
-    {"PAD_RETENTION_MMCA_SYS_PWR_REG", PAD_RETENTION_MMCA_SYS_PWR_REG,
-            0xFFFFFFFF},
-    {"PAD_RETENTION_MMCB_SYS_PWR_REG", PAD_RETENTION_MMCB_SYS_PWR_REG,
-            0xFFFFFFFF},
-    {"PAD_RETENTION_EBIA_SYS_PWR_REG", PAD_RETENTION_EBIA_SYS_PWR_REG,
-            0xFFFFFFFF},
-    {"PAD_RETENTION_EBIB_SYS_PWR_REG", PAD_RETENTION_EBIB_SYS_PWR_REG,
-            0xFFFFFFFF},
-    {"PAD_ISOLATION_SYS_PWR_REG", PAD_ISOLATION_SYS_PWR_REG, 0xFFFFFFFF},
-    {"PAD_ALV_SEL_SYS_PWR_REG", PAD_ALV_SEL_SYS_PWR_REG, 0xFFFFFFFF},
-    {"XUSBXTI_SYS_PWR_REG", XUSBXTI_SYS_PWR_REG, 0xFFFFFFFF},
-    {"XXTI_SYS_PWR_REG", XXTI_SYS_PWR_REG, 0xFFFFFFFF},
-    {"EXT_REGULATOR_SYS_PWR_REG", EXT_REGULATOR_SYS_PWR_REG, 0xFFFFFFFF},
-    {"GPIO_MODE_SYS_PWR_REG", GPIO_MODE_SYS_PWR_REG, 0xFFFFFFFF},
-    {"GPIO_MODE_MAUDIO_SYS_PWR_REG", GPIO_MODE_MAUDIO_SYS_PWR_REG, 0xFFFFFFFF},
-    {"CAM_SYS_PWR_REG", CAM_SYS_PWR_REG, 0xFFFFFFFF},
-    {"TV_SYS_PWR_REG", TV_SYS_PWR_REG, 0xFFFFFFFF},
-    {"MFC_SYS_PWR_REG", MFC_SYS_PWR_REG, 0xFFFFFFFF},
-    {"G3D_SYS_PWR_REG", G3D_SYS_PWR_REG, 0xFFFFFFFF},
-    {"LCD0_SYS_PWR_REG", LCD0_SYS_PWR_REG, 0xFFFFFFFF},
-    {"LCD1_SYS_PWR_REG", LCD1_SYS_PWR_REG, 0xFFFFFFFF},
-    {"MAUDIO_SYS_PWR_REG", MAUDIO_SYS_PWR_REG, 0xFFFFFFFF},
-    {"GPS_SYS_PWR_REG", GPS_SYS_PWR_REG, 0xFFFFFFFF},
-    {"GPS_ALIVE_SYS_PWR_REG", GPS_ALIVE_SYS_PWR_REG, 0xFFFFFFFF},
-    {"ARM_CORE0_CONFIGURATION", ARM_CORE0_CONFIGURATION, 0x00000003},
-    {"ARM_CORE0_STATUS", ARM_CORE0_STATUS, 0x00030003},
-    {"ARM_CORE0_OPTION", ARM_CORE0_OPTION, 0x01010001},
-    {"ARM_CORE1_CONFIGURATION", ARM_CORE1_CONFIGURATION, 0x00000003},
-    {"ARM_CORE1_STATUS", ARM_CORE1_STATUS, 0x00030003},
-    {"ARM_CORE1_OPTION", ARM_CORE1_OPTION, 0x01010001},
-    {"ARM_COMMON_OPTION", ARM_COMMON_OPTION, 0x00000001},
-    {"ARM_CPU_L2_0_CONFIGURATION", ARM_CPU_L2_0_CONFIGURATION, 0x00000003},
-    {"ARM_CPU_L2_0_STATUS", ARM_CPU_L2_0_STATUS, 0x00000003},
-    {"ARM_CPU_L2_1_CONFIGURATION", ARM_CPU_L2_1_CONFIGURATION, 0x00000003},
-    {"ARM_CPU_L2_1_STATUS", ARM_CPU_L2_1_STATUS, 0x00000003},
-    {"PAD_RETENTION_MAUDIO_OPTION", PAD_RETENTION_MAUDIO_OPTION, 0x00000000},
-    {"PAD_RETENTION_GPIO_OPTION", PAD_RETENTION_GPIO_OPTION, 0x00000000},
-    {"PAD_RETENTION_UART_OPTION", PAD_RETENTION_UART_OPTION, 0x00000000},
-    {"PAD_RETENTION_MMCA_OPTION", PAD_RETENTION_MMCA_OPTION, 0x00000000},
-    {"PAD_RETENTION_MMCB_OPTION", PAD_RETENTION_MMCB_OPTION, 0x00000000},
-    {"PAD_RETENTION_EBIA_OPTION", PAD_RETENTION_EBIA_OPTION, 0x00000000},
-    {"PAD_RETENTION_EBIB_OPTION", PAD_RETENTION_EBIB_OPTION, 0x00000000},
-    {"PS_HOLD_CONTROL", PS_HOLD_CONTROL, 0x00005200},
-    {"XUSBXTI_CONFIGURATION", XUSBXTI_CONFIGURATION, 0x00000001},
-    {"XUSBXTI_STATUS", XUSBXTI_STATUS, 0x00000001},
-    {"XUSBXTI_DURATION", XUSBXTI_DURATION, 0xFFF00000},
-    {"XXTI_CONFIGURATION", XXTI_CONFIGURATION, 0x00000001},
-    {"XXTI_STATUS", XXTI_STATUS, 0x00000001},
-    {"XXTI_DURATION", XXTI_DURATION, 0xFFF00000},
-    {"EXT_REGULATOR_DURATION", EXT_REGULATOR_DURATION, 0xFFF03FFF},
-    {"CAM_CONFIGURATION", CAM_CONFIGURATION, 0x00000007},
-    {"CAM_STATUS", CAM_STATUS, 0x00060007},
-    {"CAM_OPTION", CAM_OPTION, 0x00000001},
-    {"TV_CONFIGURATION", TV_CONFIGURATION, 0x00000007},
-    {"TV_STATUS", TV_STATUS, 0x00060007},
-    {"TV_OPTION", TV_OPTION, 0x00000001},
-    {"MFC_CONFIGURATION", MFC_CONFIGURATION, 0x00000007},
-    {"MFC_STATUS", MFC_STATUS, 0x00060007},
-    {"MFC_OPTION", MFC_OPTION, 0x00000001},
-    {"G3D_CONFIGURATION", G3D_CONFIGURATION, 0x00000007},
-    {"G3D_STATUS", G3D_STATUS, 0x00060007},
-    {"G3D_OPTION", G3D_OPTION, 0x00000001},
-    {"LCD0_CONFIGURATION", LCD0_CONFIGURATION, 0x00000007},
-    {"LCD0_STATUS", LCD0_STATUS, 0x00060007},
-    {"LCD0_OPTION", LCD0_OPTION, 0x00000001},
-    {"LCD1_CONFIGURATION", LCD1_CONFIGURATION, 0x00000007},
-    {"LCD1_STATUS", LCD1_STATUS, 0x00060007},
-    {"LCD1_OPTION", LCD1_OPTION, 0x00000001},
-    {"GPS_CONFIGURATION", GPS_CONFIGURATION, 0x00000007},
-    {"GPS_STATUS", GPS_STATUS, 0x00060007},
-    {"GPS_OPTION", GPS_OPTION, 0x00000001},
-    {"GPS_ALIVE_CONFIGURATION", GPS_ALIVE_CONFIGURATION, 0x00000007},
-    {"GPS_ALIVE_STATUS", GPS_ALIVE_STATUS, 0x00060007},
-    {"GPS_ALIVE_OPTION", GPS_ALIVE_OPTION, 0x00000001},
-};
-
-#define PMU_NUM_OF_REGISTERS     \
-    (sizeof(exynos4210_pmu_regs) / sizeof(Exynos4210PmuReg))
-
-typedef struct Exynos4210PmuState {
-    SysBusDevice busdev;
-    MemoryRegion iomem;
-    uint32_t reg[PMU_NUM_OF_REGISTERS];
-
-    ptimer_state *ptimer;
-} Exynos4210PmuState;
-
-static uint64_t exynos4210_pmu_read(void *opaque, target_phys_addr_t offset,
-                                    unsigned size)
-{
-    Exynos4210PmuState *s = (Exynos4210PmuState *)opaque;
-    unsigned i;
-    const Exynos4210PmuReg *reg_p = exynos4210_pmu_regs;
-
-    for (i = 0; i < PMU_NUM_OF_REGISTERS; i++) {
-        if (reg_p->offset == offset) {
-            PRINT_DEBUG_EXTEND("%s [0x%04x] -> 0x%04x\n", reg_p->name,
-                                   (uint32_t)offset, s->reg[i]);
-            return s->reg[i];
-        }
-        reg_p++;
-    }
-    PRINT_DEBUG("QEMU PMU ERROR: bad read offset 0x%04x\n", (uint32_t)offset);
-    return 0;
-}
-
-static void exynos4210_pmu_write(void *opaque, target_phys_addr_t offset,
-                                 uint64_t val, unsigned size)
-{
-    Exynos4210PmuState *s = (Exynos4210PmuState *)opaque;
-    unsigned i;
-    const Exynos4210PmuReg *reg_p = exynos4210_pmu_regs;
-
-    for (i = 0; i < PMU_NUM_OF_REGISTERS; i++) {
-        if (reg_p->offset == offset) {
-            PRINT_DEBUG_EXTEND("%s <0x%04x> <- 0x%04x\n", reg_p->name,
-                    (uint32_t)offset, (uint32_t)val);
-            s->reg[i] = val;
-            break;
-        }
-        reg_p++;
-    }
-
-    switch (offset) {
-    case SYSTEM_POWER_DOWN_CTRL:
-        if (!(val & (1 << 16))) {
-            qemu_system_shutdown_request();
-            return;
-        }
-    case SWRESET:
-        if (val & 1) {
-            qemu_system_reset_request();
-            return;
-        }
-    default:
-        break;
-    }
-}
-
-static const MemoryRegionOps exynos4210_pmu_ops = {
-    .read = exynos4210_pmu_read,
-    .write = exynos4210_pmu_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-    .valid = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-        .unaligned = false
-    }
-};
-
-static void exynos4210_pmu_reset(DeviceState *dev)
-{
-    Exynos4210PmuState *s =
-            container_of(dev, Exynos4210PmuState, busdev.qdev);
-    unsigned i;
-
-    /* Set default values for registers */
-    for (i = 0; i < PMU_NUM_OF_REGISTERS; i++) {
-        s->reg[i] = exynos4210_pmu_regs[i].reset_value;
-    }
-}
-
-static int exynos4210_pmu_init(SysBusDevice *dev)
-{
-    Exynos4210PmuState *s = FROM_SYSBUS(Exynos4210PmuState, dev);
-
-    /* memory mapping */
-    memory_region_init_io(&s->iomem, &exynos4210_pmu_ops, s, "maru_arm.pmu",
-                          EXYNOS4210_PMU_REGS_MEM_SIZE);
-    sysbus_init_mmio(dev, &s->iomem);
-
-    return 0;
-}
-
-static const VMStateDescription exynos4210_pmu_vmstate = {
-    .name = "maru_arm.pmu",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .fields      = (VMStateField[]) {
-        VMSTATE_UINT32_ARRAY(reg, Exynos4210PmuState, PMU_NUM_OF_REGISTERS),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static void exynos4210_pmu_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
-
-    k->init = exynos4210_pmu_init;
-    dc->reset = exynos4210_pmu_reset;
-    dc->vmsd = &exynos4210_pmu_vmstate;
-}
-
-static TypeInfo exynos4210_pmu_info = {
-    .name          = "maru_arm.pmu",
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(Exynos4210PmuState),
-    .class_init    = exynos4210_pmu_class_init,
-};
-
-static void exynos4210_pmu_register(void)
-{
-    type_register_static(&exynos4210_pmu_info);
-}
-
-type_init(exynos4210_pmu_register)
diff --git a/tizen/src/hw/maru_arm_soc.c b/tizen/src/hw/maru_arm_soc.c
deleted file mode 100644 (file)
index ba72bd8..0000000
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- *  Samsung Maru ARM SoC emulation
- *
- *  Based on exynos4210.c
- *
- *  Copyright (c) 2011 Samsung Electronics Co., Ltd.
- *    Maksim Kozlov <m.kozlov@samsung.com>
- *    Evgeny Voevodin <e.voevodin@samsung.com>
- *    Igor Mitsyanko  <i.mitsyanko@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, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "boards.h"
-#include "arm-misc.h"
-#include "sysbus.h"
-#include "pci.h"
-#include "maru_arm.h"
-#include "i2c.h"
-#include "exec-memory.h"
-
-#include "loader.h"
-#include "exynos4210_i2s.h"
-extern int enable_vigs;
-
-#define EXYNOS4210_CHIPID_ADDR         0x10000000
-
-/* CMUs */
-#define EXYNOS4210_CMU_LEFTBUS_BASE_ADDR     0x10034000
-#define EXYNOS4210_CMU_RIGHTBUS_BASE_ADDR    0x10038000
-#define EXYNOS4210_CMU_TOP_BASE_ADDR         0x1003C000
-#define EXYNOS4210_CMU_DMC_BASE_ADDR         0x10040000
-#define EXYNOS4210_CMU_CPU_BASE_ADDR         0x10044000
-
-/* PWM */
-#define EXYNOS4210_PWM_BASE_ADDR       0x139D0000
-
-/* RTC */
-#define EXYNOS4210_RTC_BASE_ADDR       0x10070000
-
-/* MCT */
-#define EXYNOS4210_MCT_BASE_ADDR       0x10050000
-
-/* DMA */
-#define EXYNOS4210_DMAMEM_BASE_ADDR    0x12840000
-#define EXYNOS4210_DMAPERI0_BASE_ADDR  0x12680000
-#define EXYNOS4210_DMAPERI1_BASE_ADDR  0x12690000
-
-/* I2C */
-#define EXYNOS4210_I2C_SHIFT           0x00010000
-#define EXYNOS4210_I2C_BASE_ADDR       0x13860000
-/* Interrupt Group of External Interrupt Combiner for I2C */
-#define EXYNOS4210_I2C_INTG            27
-#define EXYNOS4210_HDMI_INTG           16
-
-/* There are two set of touch screen interfaces, which share one ADC */
-#define EXYNOS4210_TS0_BASE_ADDR       0x13910000
-#define EXYNOS4210_TS1_BASE_ADDR       0x13911000
-#define EXYNOS4210_TS_INTG             19
-
-/* UART's definitions */
-#define EXYNOS4210_UART0_BASE_ADDR     0x13800000
-#define EXYNOS4210_UART1_BASE_ADDR     0x13810000
-#define EXYNOS4210_UART2_BASE_ADDR     0x13820000
-#define EXYNOS4210_UART3_BASE_ADDR     0x13830000
-#define EXYNOS4210_UART0_FIFO_SIZE     256
-#define EXYNOS4210_UART1_FIFO_SIZE     64
-#define EXYNOS4210_UART2_FIFO_SIZE     16
-#define EXYNOS4210_UART3_FIFO_SIZE     16
-/* Interrupt Group of External Interrupt Combiner for UART */
-#define EXYNOS4210_UART_INT_GRP        26
-
-/* External GIC */
-#define EXYNOS4210_EXT_GIC_CPU_BASE_ADDR    0x10480000
-#define EXYNOS4210_EXT_GIC_DIST_BASE_ADDR   0x10490000
-
-/* Combiner */
-#define EXYNOS4210_EXT_COMBINER_BASE_ADDR   0x10440000
-#define EXYNOS4210_INT_COMBINER_BASE_ADDR   0x10448000
-
-/* SD/MMC host controllers SFR base addresses */
-#define EXYNOS4210_SDHC0_BASE_ADDR          0x12510000
-#define EXYNOS4210_SDHC1_BASE_ADDR          0x12520000
-#define EXYNOS4210_SDHC2_BASE_ADDR          0x12530000
-#define EXYNOS4210_SDHC3_BASE_ADDR          0x12540000
-
-/* PMU SFR base address */
-#define EXYNOS4210_PMU_BASE_ADDR            0x10020000
-
-/* Display controllers (FIMD) */
-#define EXYNOS4210_FIMD0_BASE_ADDR          0x11C00000
-#define EXYNOS4210_FIMD1_BASE_ADDR          0x12000000
-
-/* MALI400 (G3D) */
-#define EXYNOS4210_G3D_BASE_ADDR            0x13000000
-#define EXYNOS4210_G3D_PIXEL_PROC_0_IRQ     0
-#define EXYNOS4210_G3D_PIXEL_PROC_1_IRQ     1
-#define EXYNOS4210_G3D_PIXEL_PROC_2_IRQ     2
-#define EXYNOS4210_G3D_PIXEL_PROC_3_IRQ     3
-#define EXYNOS4210_G3D_GEOM_PROC_IRQ        4
-#define EXYNOS4210_G3D_PMU_IRQ              5
-#define EXYNOS4210_G3D_PPMMU0_IRQ           0
-#define EXYNOS4210_G3D_PPMMU1_IRQ           1
-#define EXYNOS4210_G3D_PPMMU2_IRQ           2
-#define EXYNOS4210_G3D_PPMMU3_IRQ           3
-#define EXYNOS4210_G3D_GPMMU_IRQ            4
-
-/* PPMU */
-#define EXYNOS4210_PPMU_CPU_BASE_ADDR       0x106C0000
-/* DMC */
-#define EXYNOS4210_DMC0_BASE_ADDR           0x10400000
-#define EXYNOS4210_DMC1_BASE_ADDR           0x10410000
-
-/* I2S */
-#define EXYNOS4210_I2S0_BASE_ADDR           0x03830000
-
-/* pl050 ps/2 interface */
-#define EXYNOS4210_PL050_BASE_ADDR          0x12E30000
-
-static uint8_t chipid_and_omr[TARGET_PAGE_SIZE] = { 0x11, 0x02, 0x21, 0x43,
-                                    0x09, 0x00, 0x00, 0x00 };
-
-void maru_arm_write_secondary(ARMCPU *cpu,
-        const struct arm_boot_info *info)
-{
-    int n;
-    uint32_t smpboot[] = {
-        0xe59f3024, /* ldr r3, External gic_cpu_if */
-        0xe59f2024, /* ldr r2, Internal gic_cpu_if */
-        0xe59f0024, /* ldr r0, startaddr */
-        0xe3a01001, /* mov r1, #1 */
-        0xe5821000, /* str r1, [r2] */
-        0xe5831000, /* str r1, [r3] */
-        0xe320f003, /* wfi */
-        0xe5901000, /* ldr     r1, [r0] */
-        0xe1110001, /* tst     r1, r1 */
-        0x0afffffb, /* beq     <wfi> */
-        0xe12fff11, /* bx      r1 */
-        EXYNOS4210_EXT_GIC_CPU_BASE_ADDR,
-        0,          /* gic_cpu_if: base address of Internal GIC CPU interface */
-        0           /* bootreg: Boot register address is held here */
-    };
-    smpboot[ARRAY_SIZE(smpboot) - 1] = info->smp_bootreg_addr;
-    smpboot[ARRAY_SIZE(smpboot) - 2] = info->gic_cpu_if_addr;
-    for (n = 0; n < ARRAY_SIZE(smpboot); n++) {
-        smpboot[n] = tswap32(smpboot[n]);
-    }
-    rom_add_blob_fixed("smpboot", smpboot, sizeof(smpboot),
-                       info->smp_loader_start);
-}
-
-Exynos4210State *maru_arm_soc_init(MemoryRegion *system_mem,
-        unsigned long ram_size)
-{
-    qemu_irq cpu_irq[EXYNOS4210_NCPUS];
-    int i, n;
-    Exynos4210State *s = g_new(Exynos4210State, 1);
-    qemu_irq *irqp;
-    qemu_irq gate_irq[EXYNOS4210_NCPUS][EXYNOS4210_IRQ_GATE_NINPUTS];
-    unsigned long mem_size;
-    DeviceState *dev;
-    SysBusDevice *busdev;
-
-    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
-        s->cpu[n] = cpu_arm_init("cortex-a9");
-        if (!s->cpu[n]) {
-            fprintf(stderr, "Unable to find CPU %d definition\n", n);
-            exit(1);
-        }
-
-        /* Create PIC controller for each processor instance */
-        irqp = arm_pic_init_cpu(s->cpu[n]);
-
-        /*
-         * Get GICs gpio_in cpu_irq to connect a combiner to them later.
-         * Use only IRQ for a while.
-         */
-        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];
-    }
-
-    /*** IRQs ***/
-
-    s->irq_table = exynos4210_init_irq(&s->irqs);
-
-    /* IRQ Gate */
-    for (i = 0; i < EXYNOS4210_NCPUS; i++) {
-        dev = qdev_create(NULL, "exynos4210.irq_gate");
-        qdev_prop_set_uint32(dev, "n_in", EXYNOS4210_IRQ_GATE_NINPUTS);
-        qdev_init_nofail(dev);
-        /* Get IRQ Gate input in gate_irq */
-        for (n = 0; n < EXYNOS4210_IRQ_GATE_NINPUTS; n++) {
-            gate_irq[i][n] = qdev_get_gpio_in(dev, n);
-        }
-        busdev = sysbus_from_qdev(dev);
-
-        /* Connect IRQ Gate output to cpu_irq */
-        sysbus_connect_irq(busdev, 0, cpu_irq[i]);
-    }
-
-    /* Private memory region and Internal GIC */
-    dev = qdev_create(NULL, "a9mpcore_priv");
-    qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
-    qdev_init_nofail(dev);
-    busdev = sysbus_from_qdev(dev);
-    sysbus_mmio_map(busdev, 0, EXYNOS4210_SMP_PRIVATE_BASE_ADDR);
-    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
-        sysbus_connect_irq(busdev, n, gate_irq[n][0]);
-    }
-    for (n = 0; n < EXYNOS4210_INT_GIC_NIRQ; n++) {
-        s->irqs.int_gic_irq[n] = qdev_get_gpio_in(dev, n);
-    }
-
-    /* Cache controller */
-    sysbus_create_simple("l2x0", EXYNOS4210_L2X0_BASE_ADDR, NULL);
-
-    /* External GIC */
-    dev = qdev_create(NULL, "exynos4210.gic");
-    qdev_prop_set_uint32(dev, "num-cpu", EXYNOS4210_NCPUS);
-    qdev_init_nofail(dev);
-    busdev = sysbus_from_qdev(dev);
-    /* Map CPU interface */
-    sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_GIC_CPU_BASE_ADDR);
-    /* Map Distributer interface */
-    sysbus_mmio_map(busdev, 1, EXYNOS4210_EXT_GIC_DIST_BASE_ADDR);
-    for (n = 0; n < EXYNOS4210_NCPUS; n++) {
-        sysbus_connect_irq(busdev, n, gate_irq[n][1]);
-    }
-    for (n = 0; n < EXYNOS4210_EXT_GIC_NIRQ; n++) {
-        s->irqs.ext_gic_irq[n] = qdev_get_gpio_in(dev, n);
-    }
-
-    /* Internal Interrupt Combiner */
-    dev = qdev_create(NULL, "exynos4210.combiner");
-    qdev_init_nofail(dev);
-    busdev = sysbus_from_qdev(dev);
-    for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
-        sysbus_connect_irq(busdev, n, s->irqs.int_gic_irq[n]);
-    }
-    exynos4210_combiner_get_gpioin(&s->irqs, dev, 0);
-    sysbus_mmio_map(busdev, 0, EXYNOS4210_INT_COMBINER_BASE_ADDR);
-
-    /* External Interrupt Combiner */
-    dev = qdev_create(NULL, "exynos4210.combiner");
-    qdev_prop_set_uint32(dev, "external", 1);
-    qdev_init_nofail(dev);
-    busdev = sysbus_from_qdev(dev);
-    for (n = 0; n < EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ; n++) {
-        sysbus_connect_irq(busdev, n, s->irqs.ext_gic_irq[n]);
-    }
-    exynos4210_combiner_get_gpioin(&s->irqs, dev, 1);
-    sysbus_mmio_map(busdev, 0, EXYNOS4210_EXT_COMBINER_BASE_ADDR);
-
-    /* Initialize board IRQs. */
-    exynos4210_init_board_irqs(&s->irqs);
-
-    /*** Memory ***/
-
-    /* Chip-ID and OMR */
-    memory_region_init_ram_ptr(&s->chipid_mem, "exynos4210.chipid",
-            sizeof(chipid_and_omr), chipid_and_omr);
-    memory_region_set_readonly(&s->chipid_mem, true);
-    memory_region_add_subregion(system_mem, EXYNOS4210_CHIPID_ADDR,
-                                &s->chipid_mem);
-
-    /* Internal ROM */
-    memory_region_init_ram(&s->irom_mem, "exynos4210.irom",
-                           EXYNOS4210_IROM_SIZE);
-    memory_region_set_readonly(&s->irom_mem, true);
-    memory_region_add_subregion(system_mem, EXYNOS4210_IROM_BASE_ADDR,
-                                &s->irom_mem);
-    /* mirror of iROM */
-    memory_region_init_alias(&s->irom_alias_mem, "exynos4210.irom_alias",
-                             &s->irom_mem,
-                             0,
-                             EXYNOS4210_IROM_SIZE);
-    memory_region_set_readonly(&s->irom_alias_mem, true);
-    memory_region_add_subregion(system_mem, EXYNOS4210_IROM_MIRROR_BASE_ADDR,
-                                &s->irom_alias_mem);
-
-    /* Internal RAM */
-    memory_region_init_ram(&s->iram_mem, "exynos4210.iram",
-                           EXYNOS4210_IRAM_SIZE);
-    vmstate_register_ram_global(&s->iram_mem);
-    memory_region_add_subregion(system_mem, EXYNOS4210_IRAM_BASE_ADDR,
-                                &s->iram_mem);
-
-    /* DRAM */
-    mem_size = ram_size;
-    if (mem_size > EXYNOS4210_DRAM_MAX_SIZE) {
-        memory_region_init_ram(&s->dram1_mem, "exynos4210.dram1",
-                mem_size - EXYNOS4210_DRAM_MAX_SIZE);
-        vmstate_register_ram_global(&s->dram1_mem);
-        memory_region_add_subregion(system_mem, EXYNOS4210_DRAM1_BASE_ADDR,
-                &s->dram1_mem);
-        mem_size = EXYNOS4210_DRAM_MAX_SIZE;
-    }
-    memory_region_init_ram(&s->dram0_mem, "exynos4210.dram0", mem_size);
-    vmstate_register_ram_global(&s->dram0_mem);
-    memory_region_add_subregion(system_mem, EXYNOS4210_DRAM0_BASE_ADDR,
-            &s->dram0_mem);
-
-    /* Audio Subsystem Internal Memory */
-    memory_region_init_ram(&s->audss_intmem, "exynos4210.audss",
-                           EXYNOS4210_AUDSS_INTMEM_SIZE);
-    vmstate_register_ram_global(&s->audss_intmem);
-    memory_region_add_subregion(system_mem, EXYNOS4210_AUDSS_INTMEM_BASE_ADDR,
-                                &s->audss_intmem);
-
-   /* PMU.
-    * The only reason of existence at the moment is that secondary CPU boot
-    * loader uses PMU INFORM5 register as a holding pen.
-    */
-    sysbus_create_simple("maru_arm.pmu", EXYNOS4210_PMU_BASE_ADDR, NULL);
-
-    /* CMUs */
-    exynos4210_cmu_create(EXYNOS4210_CMU_LEFTBUS_BASE_ADDR,
-                                                       EXYNOS4210_CMU_LEFTBUS);
-    exynos4210_cmu_create(EXYNOS4210_CMU_RIGHTBUS_BASE_ADDR,
-                                                      EXYNOS4210_CMU_RIGHTBUS);
-    exynos4210_cmu_create(EXYNOS4210_CMU_TOP_BASE_ADDR, EXYNOS4210_CMU_TOP);
-    exynos4210_cmu_create(EXYNOS4210_CMU_DMC_BASE_ADDR, EXYNOS4210_CMU_DMC);
-    exynos4210_cmu_create(EXYNOS4210_CMU_CPU_BASE_ADDR, EXYNOS4210_CMU_CPU);
-
-    /* PWM */
-    sysbus_create_varargs("exynos4210.pwm", EXYNOS4210_PWM_BASE_ADDR,
-                          s->irq_table[exynos4210_get_irq(22, 0)],
-                          s->irq_table[exynos4210_get_irq(22, 1)],
-                          s->irq_table[exynos4210_get_irq(22, 2)],
-                          s->irq_table[exynos4210_get_irq(22, 3)],
-                          s->irq_table[exynos4210_get_irq(22, 4)],
-                          NULL);
-    /* RTC */
-    sysbus_create_varargs("exynos4210.rtc", EXYNOS4210_RTC_BASE_ADDR,
-                          s->irq_table[exynos4210_get_irq(23, 0)],
-                          s->irq_table[exynos4210_get_irq(23, 1)],
-                          NULL);
-
-    /* Multi Core Timer */
-    dev = qdev_create(NULL, "exynos4210.mct");
-    qdev_init_nofail(dev);
-    busdev = sysbus_from_qdev(dev);
-    for (n = 0; n < 4; n++) {
-        /* Connect global timer interrupts to Combiner gpio_in */
-        sysbus_connect_irq(busdev, n,
-                s->irq_table[exynos4210_get_irq(1, 4 + n)]);
-    }
-    /* Connect local timer interrupts to Combiner gpio_in */
-    sysbus_connect_irq(busdev, 4,
-            s->irq_table[exynos4210_get_irq(51, 0)]);
-    sysbus_connect_irq(busdev, 5,
-            s->irq_table[exynos4210_get_irq(35, 3)]);
-    sysbus_mmio_map(busdev, 0, EXYNOS4210_MCT_BASE_ADDR);
-
-    /*** I2C ***/
-    for (n = 0; n < EXYNOS4210_I2C_NUMBER; n++) {
-        uint32_t addr = EXYNOS4210_I2C_BASE_ADDR + EXYNOS4210_I2C_SHIFT * n;
-        qemu_irq i2c_irq;
-
-        if (n < 8) {
-            i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_I2C_INTG, n)];
-        } else {
-            i2c_irq = s->irq_table[exynos4210_get_irq(EXYNOS4210_HDMI_INTG, 1)];
-        }
-
-        dev = qdev_create(NULL, "exynos4210.i2c");
-        qdev_init_nofail(dev);
-        busdev = sysbus_from_qdev(dev);
-        sysbus_connect_irq(busdev, 0, i2c_irq);
-        sysbus_mmio_map(busdev, 0, addr);
-        s->i2c_if[n] = (i2c_bus *)qdev_get_child_bus(dev, "i2c");
-    }
-
-
-    /*** UARTs ***/
-    exynos4210_uart_create(EXYNOS4210_UART0_BASE_ADDR,
-                           EXYNOS4210_UART0_FIFO_SIZE, 0, NULL,
-                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 0)]);
-
-    exynos4210_uart_create(EXYNOS4210_UART1_BASE_ADDR,
-                           EXYNOS4210_UART1_FIFO_SIZE, 1, NULL,
-                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 1)]);
-
-    exynos4210_uart_create(EXYNOS4210_UART2_BASE_ADDR,
-                           EXYNOS4210_UART2_FIFO_SIZE, 2, NULL,
-                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 2)]);
-
-    exynos4210_uart_create(EXYNOS4210_UART3_BASE_ADDR,
-                           EXYNOS4210_UART3_FIFO_SIZE, 3, NULL,
-                  s->irq_table[exynos4210_get_irq(EXYNOS4210_UART_INT_GRP, 3)]);
-
-    if (!enable_vigs) {
-        /*** Display controller (FIMD) ***/
-        sysbus_create_varargs("exynos4210.fimd", EXYNOS4210_FIMD0_BASE_ADDR,
-                s->irq_table[exynos4210_get_irq(11, 0)],
-                s->irq_table[exynos4210_get_irq(11, 1)],
-                s->irq_table[exynos4210_get_irq(11, 2)],
-                NULL);
-    }
-
-    /* I2S0 */
-    s->i2s_bus[0] = exynos4210_i2s_bus_new("exynos4210.i2s",
-                                 EXYNOS4210_I2S0_BASE_ADDR,
-                                 s->irqs.ext_gic_irq[97]);
-
-    /* PL050 PS/2 if keyboard */
-    sysbus_create_simple("pl050_keyboard", EXYNOS4210_PL050_BASE_ADDR,
-            s->irq_table[exynos4210_get_irq(28, 2)]);
-
-    return s;
-}
diff --git a/tizen/src/hw/maru_arm_vpci.c b/tizen/src/hw/maru_arm_vpci.c
deleted file mode 100644 (file)
index 66e714b..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Samsung Tizen Virtual PCI driver
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd.
- *  Vorobiov Stanislav <s.vorobiov@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, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "sysbus.h"
-#include "pci.h"
-#include "pci_host.h"
-#include "exec-memory.h"
-
-#define TIZEN_VPCI_VENDOR_ID 0x10ee
-#define TIZEN_VPCI_DEVICE_ID 0x0300
-#define TIZEN_VPCI_CLASS_ID  PCI_CLASS_PROCESSOR_CO
-
-#define TIZEN_VPCI_IO_ADDR 0xC3000000
-#define TIZEN_VPCI_IO_SIZE 0xFFFF
-
-typedef struct {
-    SysBusDevice busdev;
-    qemu_irq irq[4];
-    MemoryRegion mem_config;
-    MemoryRegion iospace_alias_mem;
-} TizenVPCIState;
-
-static uint64_t tizen_vpci_io_read(void *opaque, target_phys_addr_t addr,
-                                   unsigned size)
-{
-    switch (size) {
-    case 1:
-        return cpu_inb(addr);
-    case 2:
-        return cpu_inw(addr);
-    case 4:
-        return cpu_inl(addr);
-    default:
-        break;
-    }
-    assert(0);
-}
-
-static void tizen_vpci_io_write(void *opaque, target_phys_addr_t addr,
-                                uint64_t data, unsigned size)
-{
-    switch (size) {
-    case 1:
-        cpu_outb(addr, data);
-        return;
-    case 2:
-        cpu_outw(addr, data);
-        return;
-    case 4:
-        cpu_outl(addr, data);
-        return;
-    }
-    assert(0);
-}
-
-static const MemoryRegionOps tizen_vpci_io_ops = {
-    .endianness = DEVICE_LITTLE_ENDIAN,
-    .read = tizen_vpci_io_read,
-    .write = tizen_vpci_io_write
-};
-
-static inline uint32_t tizen_vpci_config_addr(target_phys_addr_t addr)
-{
-    return addr & 0xffffff;
-}
-
-static void tizen_vpci_config_write(void *opaque, target_phys_addr_t addr,
-                                 uint64_t val, unsigned size)
-{
-    pci_data_write(opaque, tizen_vpci_config_addr(addr), val, size);
-}
-
-static uint64_t tizen_vpci_config_read(void *opaque, target_phys_addr_t addr,
-                                    unsigned size)
-{
-    uint32_t val;
-    val = pci_data_read(opaque, tizen_vpci_config_addr(addr), size);
-    return val;
-}
-
-static const MemoryRegionOps tizen_vpci_config_ops = {
-    .read = tizen_vpci_config_read,
-    .write = tizen_vpci_config_write,
-    .endianness = DEVICE_NATIVE_ENDIAN,
-};
-
-static int tizen_vpci_map_irq(PCIDevice *d, int irq_num)
-{
-    return irq_num;
-}
-
-static void tizen_vpci_set_irq(void *opaque, int irq_num, int level)
-{
-    qemu_irq *pic = opaque;
-
-    qemu_set_irq(pic[irq_num], level);
-}
-
-static int tizen_vpci_init(SysBusDevice *dev)
-{
-    TizenVPCIState *s = FROM_SYSBUS(TizenVPCIState, dev);
-    PCIBus *bus;
-    int i;
-
-    for (i = 0; i < 4; i++) {
-        sysbus_init_irq(dev, &s->irq[i]);
-    }
-
-    /* On ARM, we only have MMIO no specific IO space from the CPU
-     * perspective.  In theory we ought to be able to embed the PCI IO
-     * memory region direction in the system memory space.  However,
-     * if any of the IO BAR subregions use the old_portio mechanism,
-     * that won't be processed properly unless accessed from the
-     * system io address space.  This hack to bounce things via
-     * system_io works around the problem until all the users of
-     * old_portion are updated */
-
-    memory_region_init_io(&s->iospace_alias_mem, &tizen_vpci_io_ops, s,
-                          "tizen_vpci.io-alias", TIZEN_VPCI_IO_SIZE);
-    memory_region_add_subregion(get_system_memory(), TIZEN_VPCI_IO_ADDR,
-                                &s->iospace_alias_mem);
-
-    bus = pci_register_bus(&dev->qdev, "pci",
-                           tizen_vpci_set_irq, tizen_vpci_map_irq, s->irq,
-                           get_system_memory(), get_system_io(),
-                           0, 4);
-
-    memory_region_init_io(&s->mem_config, &tizen_vpci_config_ops, bus,
-                          "tizen-vpci-config", 0x1000000);
-    sysbus_init_mmio(dev, &s->mem_config);
-
-    pci_create_simple(bus, -1, "tizen_vpci_host");
-
-    return 0;
-}
-
-static int tizen_vpci_host_init(PCIDevice *d)
-{
-    pci_set_word(d->config + PCI_STATUS,
-         PCI_STATUS_66MHZ | PCI_STATUS_DEVSEL_FAST);
-    return 0;
-}
-
-static void tizen_vpci_host_class_init(ObjectClass *klass, void *data)
-{
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = tizen_vpci_host_init;
-    k->vendor_id = TIZEN_VPCI_VENDOR_ID;
-    k->device_id = TIZEN_VPCI_DEVICE_ID;
-    k->class_id = TIZEN_VPCI_CLASS_ID;
-}
-
-static TypeInfo tizen_vpci_host_info = {
-    .name          = "tizen_vpci_host",
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(PCIDevice),
-    .class_init    = tizen_vpci_host_class_init,
-};
-
-static void tizen_vpci_class_init(ObjectClass *klass, void *data)
-{
-    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
-
-    sdc->init = tizen_vpci_init;
-}
-
-static TypeInfo tizen_vpci_info = {
-    .name          = "tizen_vpci",
-    .parent        = TYPE_SYS_BUS_DEVICE,
-    .instance_size = sizeof(TizenVPCIState),
-    .class_init    = tizen_vpci_class_init,
-};
-
-static void tizen_vpci_register_types(void)
-{
-    type_register_static(&tizen_vpci_info);
-    type_register_static(&tizen_vpci_host_info);
-}
-
-type_init(tizen_vpci_register_types)
diff --git a/tizen/src/hw/maru_brightness.c b/tizen/src/hw/maru_brightness.c
deleted file mode 100644 (file)
index 3d04d6c..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * Maru brightness device for VGA
- *
- * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact:
- * JinHyung Jo <jinhyung.jo@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- * DongKyun Yun
- * DoHyung Hong
- * Hyunjun Son
- *
- * 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 "hw/i386/pc.h"
-#include "ui/console.h"
-#include "hw/pci/pci.h"
-#include "maru_device_ids.h"
-#include "maru_brightness.h"
-#include "skin/maruskin_server.h"
-#include "debug_ch.h"
-
-MULTI_DEBUG_CHANNEL(tizen, maru-brightness);
-
-#define QEMU_DEV_NAME           "maru-brightness"
-
-#define BRIGHTNESS_MEM_SIZE    (4 * 1024)    /* 4KB */
-#define BRIGHTNESS_REG_SIZE    256
-
-typedef struct BrightnessState {
-    PCIDevice       dev;
-    MemoryRegion    mmio_addr;
-} BrightnessState;
-
-enum {
-    BRIGHTNESS_LEVEL = 0x00,
-    BRIGHTNESS_OFF = 0x04,
-};
-
-uint32_t brightness_level = BRIGHTNESS_MAX;
-bool display_off;
-pixman_color_t level_color;
-pixman_image_t *brightness_image;
-
-/* level : 1 ~ 100, interval : 1 or 2 */
-uint8_t brightness_tbl[] = {155, /* level 0 : for dimming */
-/* level 01 ~ 10 */         149, 147, 146, 144, 143, 141, 140, 138, 137, 135,
-/* level 11 ~ 20 */         134, 132, 131, 129, 128, 126, 125, 123, 122, 120,
-/* level 21 ~ 30 */         119, 117, 116, 114, 113, 111, 110, 108, 107, 105,
-/* level 31 ~ 40 */         104, 102, 101,  99,  98,  96,  95,  93,  92,  90,
-/* level 41 ~ 50 */          89,  87,  86,  84,  83,  81,  80,  78,  77,  75,
-/* level 51 ~ 60 */          74,  72,  71,  69,  68,  66,  65,  63,  62,  60,
-/* level 61 ~ 70 */          59,  57,  56,  54,  53,  51,  50,  48,  47,  45,
-/* level 71 ~ 80 */          44,  42,  41,  39,  38,  36,  35,  33,  32,  30,
-/* level 81 ~ 90 */          29,  27,  26,  24,  23,  21,  20,  18,  17,  15,
-/* level 91 ~ 99 */          14,  12,  11,   9,   8,   6,   5,   3,   2,   0};
-
-QEMUBH *display_bh;
-
-static uint64_t brightness_reg_read(void *opaque,
-                                    hwaddr addr,
-                                    unsigned size)
-{
-    switch (addr & 0xFF) {
-    case BRIGHTNESS_LEVEL:
-        INFO("current brightness level = %lu\n", brightness_level);
-        return brightness_level;
-    case BRIGHTNESS_OFF:
-        INFO("device is turned %s\n", display_off ? "off" : "on");
-        return display_off;
-    default:
-        ERR("wrong brightness register read - addr : %d\n", (int)addr);
-        break;
-    }
-
-    return 0;
-}
-
-static void maru_pixman_image_set_alpha(uint8_t value)
-{
-    if (brightness_image) {
-        pixman_image_unref(brightness_image);
-    }
-    level_color.alpha = value << 8;
-    brightness_image = pixman_image_create_solid_fill(&level_color);
-
-    graphic_hw_invalidate(NULL);
-}
-
-static void brightness_reg_write(void *opaque,
-                                 hwaddr addr,
-                                 uint64_t val,
-                                 unsigned size)
-{
-    switch (addr & 0xFF) {
-    case BRIGHTNESS_LEVEL:
-        if (brightness_level == val) {
-            return;
-        }
-#if BRIGHTNESS_MIN > 0
-        if (val < BRIGHTNESS_MIN || val > BRIGHTNESS_MAX) {
-#else
-        if (val > BRIGHTNESS_MAX) {
-#endif
-            ERR("input value is out of range(%llu)\n", val);
-        } else {
-            INFO("level changes: %lu -> %llu\n", brightness_level, val);
-            brightness_level = val;
-            maru_pixman_image_set_alpha(brightness_tbl[brightness_level]);
-        }
-        return;
-    case BRIGHTNESS_OFF:
-        if (display_off == val) {
-            return;
-        }
-
-        INFO("status changes: %s\n", val ? "OFF" : "ON");
-
-        display_off = val;
-        if (display_off) {
-            maru_pixman_image_set_alpha(0xFF); /* set black */
-        } else {
-            maru_pixman_image_set_alpha(brightness_tbl[brightness_level]);
-        }
-
-        /* notify to skin process */
-        qemu_bh_schedule(display_bh);
-
-        return;
-    default:
-        ERR("wrong brightness register write - addr : %d\n", (int)addr);
-        break;
-    }
-}
-
-static const MemoryRegionOps brightness_mmio_ops = {
-    .read = brightness_reg_read,
-    .write = brightness_reg_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static void brightness_exitfn(PCIDevice *dev)
-{
-    BrightnessState *s = DO_UPCAST(BrightnessState, dev, dev);
-
-    if (display_bh) {
-        qemu_bh_delete(display_bh);
-    }
-    if (brightness_image) {
-        pixman_image_unref(brightness_image);
-        brightness_image = NULL;
-    }
-
-    memory_region_destroy(&s->mmio_addr);
-    INFO("finalize maru-brightness device\n");
-}
-
-static void maru_display_bh(void *opaque)
-{
-    notify_display_power(!display_off);
-}
-
-static int brightness_initfn(PCIDevice *dev)
-{
-    BrightnessState *s = DO_UPCAST(BrightnessState, dev, dev);
-    uint8_t *pci_conf = s->dev.config;
-
-    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_TIZEN);
-    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIRTUAL_BRIGHTNESS);
-    pci_config_set_class(pci_conf, PCI_CLASS_DISPLAY_OTHER);
-
-    memory_region_init_io(&s->mmio_addr, OBJECT(s), &brightness_mmio_ops, s,
-                            "maru-brightness-mmio", BRIGHTNESS_REG_SIZE);
-    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio_addr);
-
-    display_bh = qemu_bh_new(maru_display_bh, s);
-    brightness_level = BRIGHTNESS_MAX;
-    level_color.alpha = 0x0000;
-    level_color.red = 0x0000;
-    level_color.green = 0x0000;
-    level_color.blue = 0x0000;
-    brightness_image = pixman_image_create_solid_fill(&level_color);
-    INFO("initialize maru-brightness device\n");
-
-    return 0;
-}
-
-static void brightness_classinit(ObjectClass *klass, void *data)
-{
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = brightness_initfn;
-    k->exit = brightness_exitfn;
-}
-
-static TypeInfo brightness_info = {
-    .name = QEMU_DEV_NAME,
-    .parent = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(BrightnessState),
-    .class_init = brightness_classinit,
-};
-
-static void brightness_register_types(void)
-{
-    type_register_static(&brightness_info);
-}
-
-type_init(brightness_register_types);
diff --git a/tizen/src/hw/maru_brightness.h b/tizen/src/hw/maru_brightness.h
deleted file mode 100644 (file)
index 96f081a..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Maru brightness device for VGA
- *
- * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
- *
- * Contact:
- * Jinhyung Jo <jinhyung.jo@samsung.com>
- * GiWoong Kim <giwoong.kim@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- * Hyunjun Son
- *
- * 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_BRIGHTNESS_H_
-#define MARU_BRIGHTNESS_H_
-
-#include "qemu-common.h"
-#include "ui/qemu-pixman.h"
-
-#define BRIGHTNESS_MIN          (0)
-#define BRIGHTNESS_MAX          (100)
-
-extern uint32_t brightness_level;
-extern bool display_off;
-extern uint8_t brightness_tbl[];
-extern pixman_image_t *brightness_image;
-
-#endif /* MARU_BRIGHTNESS_H_ */
diff --git a/tizen/src/hw/maru_brill_codec.c b/tizen/src/hw/maru_brill_codec.c
deleted file mode 100644 (file)
index 2287bcb..0000000
+++ /dev/null
@@ -1,2006 +0,0 @@
-/*
- * Virtual Codec Device
- *
- * Copyright (c) 2013 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Kitae Kim <kt920.kim@samsung.com>
- *  SeokYeon Hwang <syeon.hwang@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 "maru_brill_codec.h"
-
-/* define debug channel */
-MULTI_DEBUG_CHANNEL(qemu, brillcodec);
-
-// device
-#define CODEC_DEVICE_NAME   "codec-pci"
-#define CODEC_DEVICE_THREAD "codec-workthread"
-#define CODEC_VERSION       2
-
-// device memory
-#define CODEC_META_DATA_SIZE    (256)
-
-#define CODEC_MEM_SIZE          (32 * 1024 * 1024)
-#define CODEC_REG_SIZE          (256)
-
-// libav
-#define GEN_MASK(x) ((1 << (x)) - 1)
-#define ROUND_UP_X(v, x) (((v) + GEN_MASK(x)) & ~GEN_MASK(x))
-#define ROUND_UP_2(x) ROUND_UP_X(x, 1)
-#define ROUND_UP_4(x) ROUND_UP_X(x, 2)
-#define ROUND_UP_8(x) ROUND_UP_X(x, 3)
-#define DIV_ROUND_UP_X(v, x) (((v) + GEN_MASK(x)) >> (x))
-
-#define DEFAULT_VIDEO_GOP_SIZE 15
-
-
-// define a queue to manage ioparam, context data
-typedef struct DeviceMemEntry {
-    uint8_t *buf;
-    uint32_t buf_size;
-    uint32_t ctx_id;
-
-    QTAILQ_ENTRY(DeviceMemEntry) node;
-} DeviceMemEntry;
-
-typedef struct CodecDataStg {
-    CodecParam *param_buf;
-    DeviceMemEntry *data_buf;
-
-    QTAILQ_ENTRY(CodecDataStg) node;
-} CodecDataStg;
-
-// define two queue to store input and output buffers.
-static QTAILQ_HEAD(codec_wq, DeviceMemEntry) codec_wq =
-   QTAILQ_HEAD_INITIALIZER(codec_wq);
-
-static QTAILQ_HEAD(codec_rq, CodecDataStg) codec_rq =
-   QTAILQ_HEAD_INITIALIZER(codec_rq);
-
-static DeviceMemEntry *entry[CODEC_CONTEXT_MAX];
-
-// pixel info
-typedef struct PixFmtInfo {
-    uint8_t x_chroma_shift;
-    uint8_t y_chroma_shift;
-} PixFmtInfo;
-
-static PixFmtInfo pix_fmt_info[PIX_FMT_NB];
-
-// thread
-#define DEFAULT_WORKER_THREAD_CNT 8
-
-static void *maru_brill_codec_threads(void *opaque);
-
-// static void maru_brill_codec_reset_parser_info(MaruBrillCodecState *s, int32_t ctx_index);
-static int maru_brill_codec_query_list(MaruBrillCodecState *s);
-static void maru_brill_codec_release_context(MaruBrillCodecState *s, int32_t value);
-
-// codec functions
-static bool codec_init(MaruBrillCodecState *, int, void *);
-static bool codec_deinit(MaruBrillCodecState *, int, void *);
-static bool codec_decode_video(MaruBrillCodecState *, int, void *);
-static bool codec_encode_video(MaruBrillCodecState *, int, void *);
-static bool codec_decode_audio(MaruBrillCodecState *, int, void *);
-static bool codec_encode_audio(MaruBrillCodecState *, int, void *);
-static bool codec_picture_copy(MaruBrillCodecState *, int, void *);
-static bool codec_flush_buffers(MaruBrillCodecState *, int, void *);
-
-typedef bool (*CodecFuncEntry)(MaruBrillCodecState *, int, void *);
-static CodecFuncEntry codec_func_handler[] = {
-    codec_init,
-    codec_decode_video,
-    codec_encode_video,
-    codec_decode_audio,
-    codec_encode_audio,
-    codec_picture_copy,
-    codec_deinit,
-    codec_flush_buffers,
-};
-
-static AVCodecParserContext *maru_brill_codec_parser_init(AVCodecContext *avctx);
-
-static void maru_brill_codec_pop_writequeue(MaruBrillCodecState *s, uint32_t ctx_idx);
-static void maru_brill_codec_push_readqueue(MaruBrillCodecState *s, CodecParam *ioparam);
-static void maru_brill_codec_push_writequeue(MaruBrillCodecState *s, void* buf,
-                                            uint32_t buf_size, int ctx_id);
-
-static void *maru_brill_codec_store_inbuf(uint8_t *mem_base, CodecParam *ioparam);
-
-static void maru_brill_codec_reset(DeviceState *s);
-
-static void maru_brill_codec_get_cpu_cores(MaruBrillCodecState *s)
-{
-    s->worker_thread_cnt = get_number_of_processors();
-    if (s->worker_thread_cnt < DEFAULT_WORKER_THREAD_CNT) {
-        s->worker_thread_cnt = DEFAULT_WORKER_THREAD_CNT;
-    }
-
-    TRACE("number of threads: %d\n", s->worker_thread_cnt);
-}
-
-static void maru_brill_codec_threads_create(MaruBrillCodecState *s)
-{
-    int index;
-    QemuThread *pthread = NULL;
-
-    TRACE("enter: %s\n", __func__);
-
-    pthread = g_malloc(sizeof(QemuThread) * s->worker_thread_cnt);
-    if (!pthread) {
-        ERR("failed to allocate threadpool memory.\n");
-        return;
-    }
-
-    qemu_cond_init(&s->threadpool.cond);
-    qemu_mutex_init(&s->threadpool.mutex);
-
-    s->is_thread_running = true;
-
-    qemu_mutex_lock(&s->context_mutex);
-    s->idle_thread_cnt = 0;
-    qemu_mutex_unlock(&s->context_mutex);
-
-    for (index = 0; index < s->worker_thread_cnt; index++) {
-        qemu_thread_create(&pthread[index], CODEC_DEVICE_THREAD,
-            maru_brill_codec_threads, (void *)s, QEMU_THREAD_JOINABLE);
-    }
-
-    s->threadpool.threads = pthread;
-
-    TRACE("leave: %s\n", __func__);
-}
-
-static void maru_brill_codec_thread_exit(MaruBrillCodecState *s)
-{
-    int index;
-
-    TRACE("enter: %s\n", __func__);
-
-    /* stop to run dedicated threads. */
-    s->is_thread_running = false;
-
-    for (index = 0; index < s->worker_thread_cnt; index++) {
-        qemu_thread_join(&s->threadpool.threads[index]);
-    }
-
-    TRACE("destroy mutex and conditional.\n");
-    qemu_mutex_destroy(&s->threadpool.mutex);
-    qemu_cond_destroy(&s->threadpool.cond);
-
-    if (s->threadpool.threads) {
-        g_free(s->threadpool.threads);
-        s->threadpool.threads = NULL;
-    }
-
-    TRACE("leave: %s\n", __func__);
-}
-
-static void maru_brill_codec_wakeup_threads(MaruBrillCodecState *s, int api_index)
-{
-    CodecParam *ioparam = NULL;
-
-    ioparam = g_malloc0(sizeof(CodecParam));
-    if (!ioparam) {
-        ERR("failed to allocate ioparam\n");
-        return;
-    }
-
-    memcpy(ioparam, &s->ioparam, sizeof(CodecParam));
-
-    TRACE("wakeup thread. ctx_id: %u, api_id: %u, mem_offset: 0x%x\n",
-        ioparam->ctx_index, ioparam->api_index, ioparam->mem_offset);
-
-    qemu_mutex_lock(&s->context_mutex);
-
-    if (ioparam->api_index != CODEC_INIT) {
-        if (!s->context[ioparam->ctx_index].opened_context) {
-            INFO("abandon api %d for context %d\n",
-                    ioparam->api_index, ioparam->ctx_index);
-            qemu_mutex_unlock(&s->context_mutex);
-            return;
-        }
-    }
-
-    qemu_mutex_unlock(&s->context_mutex);
-
-    maru_brill_codec_push_readqueue(s, ioparam);
-
-    qemu_mutex_lock(&s->context_mutex);
-    // W/A for threads starvation.
-    while (s->idle_thread_cnt == 0) {
-        qemu_mutex_unlock(&s->context_mutex);
-        TRACE("Worker threads are exhausted\n");
-        usleep(2000); // wait 2ms.
-        qemu_mutex_lock(&s->context_mutex);
-    }
-    qemu_cond_signal(&s->threadpool.cond);
-    qemu_mutex_unlock(&s->context_mutex);
-
-    TRACE("after sending conditional signal\n");
-}
-
-static void *maru_brill_codec_threads(void *opaque)
-{
-    MaruBrillCodecState *s = (MaruBrillCodecState *)opaque;
-    bool ret = false;
-
-    TRACE("enter: %s\n", __func__);
-
-    while (s->is_thread_running) {
-        int ctx_id = 0, api_id = 0;
-        CodecDataStg *elem = NULL;
-        DeviceMemEntry *indata_buf = NULL;
-
-        qemu_mutex_lock(&s->context_mutex);
-        ++(s->idle_thread_cnt); // protected under mutex.
-        qemu_cond_wait(&s->threadpool.cond, &s->context_mutex);
-        --(s->idle_thread_cnt); // protected under mutex.
-        qemu_mutex_unlock(&s->context_mutex);
-
-        qemu_mutex_lock(&s->ioparam_queue_mutex);
-        elem = QTAILQ_FIRST(&codec_rq);
-        if (elem) {
-            QTAILQ_REMOVE(&codec_rq, elem, node);
-            qemu_mutex_unlock(&s->ioparam_queue_mutex);
-        } else {
-            qemu_mutex_unlock(&s->ioparam_queue_mutex);
-            continue;
-        }
-
-        if (!elem->param_buf) {
-            continue;
-        }
-
-        api_id = elem->param_buf->api_index;
-        ctx_id = elem->param_buf->ctx_index;
-        indata_buf = elem->data_buf;
-
-        TRACE("api_id: %d ctx_id: %d\n", api_id, ctx_id);
-
-        qemu_mutex_lock(&s->context_mutex);
-        s->context[ctx_id].occupied_thread = true;
-        qemu_mutex_unlock(&s->context_mutex);
-
-        ret = codec_func_handler[api_id](s, ctx_id, indata_buf);
-        if (!ret) {
-            ERR("fail api %d for context %d\n", api_id, ctx_id);
-            g_free(elem->param_buf);
-            continue;
-        }
-
-        TRACE("release a buffer of CodecParam\n");
-        g_free(elem->param_buf);
-        elem->param_buf = NULL;
-
-        if (elem->data_buf) {
-            if (elem->data_buf->buf) {
-                TRACE("release inbuf\n");
-                g_free(elem->data_buf->buf);
-                elem->data_buf->buf = NULL;
-            }
-
-            TRACE("release a buffer indata_buf\n");
-            g_free(elem->data_buf);
-            elem->data_buf = NULL;
-        }
-
-        TRACE("release an element of CodecDataStg\n");
-        g_free(elem);
-
-        qemu_mutex_lock(&s->context_mutex);
-        if (s->context[ctx_id].requested_close) {
-            INFO("make worker thread to handle deinit\n");
-            // codec_deinit(s, ctx_id, NULL);
-            maru_brill_codec_release_context(s, ctx_id);
-            s->context[ctx_id].requested_close = false;
-        }
-        qemu_mutex_unlock(&s->context_mutex);
-
-        TRACE("switch context to raise interrupt.\n");
-        qemu_bh_schedule(s->codec_bh);
-
-        qemu_mutex_lock(&s->context_mutex);
-        s->context[ctx_id].occupied_thread = false;
-        qemu_mutex_unlock(&s->context_mutex);
-    }
-
-    maru_brill_codec_thread_exit(s);
-
-    TRACE("leave: %s\n", __func__);
-    return NULL;
-}
-
-// queue
-static void maru_brill_codec_push_readqueue(MaruBrillCodecState *s,
-                                            CodecParam *ioparam)
-{
-    CodecDataStg *elem = NULL;
-    DeviceMemEntry *data_buf = NULL;
-
-    elem = g_malloc0(sizeof(CodecDataStg));
-    if (!elem) {
-        ERR("failed to allocate ioparam_queue. %d\n", sizeof(CodecDataStg));
-        return;
-    }
-
-    elem->param_buf = ioparam;
-
-    switch(ioparam->api_index) {
-    case CODEC_INIT ... CODEC_ENCODE_AUDIO:
-        data_buf = maru_brill_codec_store_inbuf((uint8_t *)s->vaddr, ioparam);
-        break;
-    default:
-        TRACE("no buffer from guest\n");
-        break;
-    }
-
-    elem->data_buf = data_buf;
-
-    qemu_mutex_lock(&s->ioparam_queue_mutex);
-    QTAILQ_INSERT_TAIL(&codec_rq, elem, node);
-    qemu_mutex_unlock(&s->ioparam_queue_mutex);
-}
-
-static void *maru_brill_codec_store_inbuf(uint8_t *mem_base,
-                                        CodecParam *ioparam)
-{
-    DeviceMemEntry *elem = NULL;
-    int readbuf_size, size = 0;
-    uint8_t *readbuf = NULL;
-    uint8_t *device_mem = mem_base + ioparam->mem_offset;
-
-    elem = g_malloc0(sizeof(DeviceMemEntry));
-    if (!elem) {
-        ERR("failed to allocate readqueue node. size: %d\n",
-            sizeof(DeviceMemEntry));
-        return NULL;
-    }
-
-    memcpy(&readbuf_size, device_mem, sizeof(readbuf_size));
-    size = sizeof(readbuf_size);
-
-    TRACE("readbuf size: %d\n", readbuf_size);
-    if (readbuf_size <= 0) {
-        TRACE("inbuf size is 0. api_id %d, ctx_id %d, mem_offset %x\n",
-            ioparam->api_index, ioparam->ctx_index, ioparam->mem_offset);
-    } else {
-        readbuf = g_malloc0(readbuf_size);
-        if (!readbuf) {
-            ERR("failed to allocate a read buffer. size: %d\n", readbuf_size);
-        } else {
-            TRACE("copy input buffer from guest. ctx_id: %d, mem_offset: %x\n",
-                ioparam->ctx_index, ioparam->mem_offset);
-            memcpy(readbuf, device_mem + size, readbuf_size);
-        }
-    }
-    memset(device_mem, 0x00, sizeof(readbuf_size));
-
-    elem->buf = readbuf;
-    elem->buf_size = readbuf_size;
-    elem->ctx_id = ioparam->ctx_index;
-
-    return elem;
-}
-
-static void maru_brill_codec_push_writequeue(MaruBrillCodecState *s, void* buf,
-                                            uint32_t buf_size, int ctx_id)
-{
-    DeviceMemEntry *elem = NULL;
-    elem = g_malloc0(sizeof(DeviceMemEntry));
-
-    elem->buf = buf;
-    elem->buf_size = buf_size;
-    elem->ctx_id = ctx_id;
-
-    qemu_mutex_lock(&s->context_queue_mutex);
-    QTAILQ_INSERT_TAIL(&codec_wq, elem, node);
-    qemu_mutex_unlock(&s->context_queue_mutex);
-}
-
-static void maru_brill_codec_pop_writequeue(MaruBrillCodecState *s, uint32_t ctx_idx)
-{
-    DeviceMemEntry *elem = NULL;
-    uint32_t mem_offset = 0;
-
-    TRACE("enter: %s\n", __func__);
-
-    if (ctx_idx < 1 || ctx_idx > (CODEC_CONTEXT_MAX - 1)) {
-        ERR("invalid buffer index. %d\n", ctx_idx);
-        return;
-    }
-
-    TRACE("pop_writeqeue. context index: %d\n", ctx_idx);
-    elem = entry[ctx_idx];
-    if (elem) {
-        mem_offset = s->ioparam.mem_offset;
-
-        // check corrupted mem_offset
-        if (mem_offset < CODEC_MEM_SIZE) {
-            if (elem->buf) {
-                TRACE("write data %d to guest.  mem_offset: 0x%x\n",
-                        elem->buf_size, mem_offset);
-                memcpy(s->vaddr + mem_offset, elem->buf, elem->buf_size);
-
-                TRACE("release output buffer: %p\n", elem->buf);
-                g_free(elem->buf);
-            }
-        } else {
-            TRACE("mem_offset is corrupted!!\n");
-        }
-
-        TRACE("pop_writequeue. release elem: %p\n", elem);
-        g_free(elem);
-
-        entry[ctx_idx] = NULL;
-    } else {
-        TRACE("there is no buffer to copy data to guest\n");
-    }
-
-    TRACE("leave: %s\n", __func__);
-}
-
-static void serialize_video_data(const struct video_data *video,
-                                AVCodecContext *avctx)
-{
-    if (video->width) {
-        avctx->width = video->width;
-    }
-    if (video->height) {
-        avctx->height = video->height;
-    }
-    if (video->fps_n) {
-        avctx->time_base.num = video->fps_n;
-    }
-    if (video->fps_d) {
-        avctx->time_base.den = video->fps_d;
-    }
-    if (video->pix_fmt > PIX_FMT_NONE) {
-        avctx->pix_fmt = video->pix_fmt;
-    }
-    if (video->par_n) {
-        avctx->sample_aspect_ratio.num = video->par_n;
-    }
-    if (video->par_d) {
-        avctx->sample_aspect_ratio.den = video->par_d;
-    }
-    if (video->bpp) {
-        avctx->bits_per_coded_sample = video->bpp;
-    }
-    if (video->ticks_per_frame) {
-        avctx->ticks_per_frame = video->ticks_per_frame;
-    }
-
-    INFO("codec_init. video, resolution: %dx%d, framerate: %d/%d "
-        "pixel_fmt: %d sample_aspect_ratio: %d/%d bpp %d\n",
-        avctx->width, avctx->height, avctx->time_base.num,
-        avctx->time_base.den, avctx->pix_fmt, avctx->sample_aspect_ratio.num,
-        avctx->sample_aspect_ratio.den, avctx->bits_per_coded_sample);
-}
-
-static void deserialize_video_data (const AVCodecContext *avctx,
-                                    struct video_data *video)
-{
-    memset(video, 0x00, sizeof(struct video_data));
-
-    video->width = avctx->width;
-    video->height = avctx->height;
-    video->fps_n = avctx->time_base.num;
-    video->fps_d = avctx->time_base.den;
-    video->pix_fmt = avctx->pix_fmt;
-    video->par_n = avctx->sample_aspect_ratio.num;
-    video->par_d = avctx->sample_aspect_ratio.den;
-    video->bpp = avctx->bits_per_coded_sample;
-    video->ticks_per_frame = avctx->ticks_per_frame;
-}
-
-static void serialize_audio_data (const struct audio_data *audio,
-                                  AVCodecContext *avctx)
-{
-    if (audio->channels) {
-        avctx->channels = audio->channels;
-    }
-    if (audio->sample_rate) {
-        avctx->sample_rate = audio->sample_rate;
-    }
-    if (audio->block_align) {
-        avctx->block_align = audio->block_align;
-    }
-
-    if (audio->sample_fmt > AV_SAMPLE_FMT_NONE) {
-        avctx->sample_fmt = audio->sample_fmt;
-    }
-
-    INFO("codec_init. audio, channel %d sample_rate %d sample_fmt %d ch_layout %lld\n",
-        avctx->channels, avctx->sample_rate, avctx->sample_fmt, avctx->channel_layout);
-}
-
-#if 0
-static void maru_brill_codec_reset_parser_info(MaruBrillCodecState *s, int32_t ctx_index)
-{
-    s->context[ctx_index].parser_buf = NULL;
-    s->context[ctx_index].parser_use = false;
-}
-#endif
-
-static void maru_brill_codec_release_context(MaruBrillCodecState *s, int32_t context_id)
-{
-    DeviceMemEntry *wq_elem = NULL, *wnext = NULL;
-    CodecDataStg *rq_elem = NULL, *rnext = NULL;
-
-    TRACE("enter: %s\n", __func__);
-
-    TRACE("release %d of context\n", context_id);
-
-    qemu_mutex_lock(&s->threadpool.mutex);
-    if (s->context[context_id].opened_context) {
-        // qemu_mutex_unlock(&s->threadpool.mutex);
-        codec_deinit(s, context_id, NULL);
-        // qemu_mutex_lock(&s->threadpool.mutex);
-    }
-    s->context[context_id].occupied_context = false;
-    qemu_mutex_unlock(&s->threadpool.mutex);
-
-    // TODO: check if foreach statment needs lock or not.
-    QTAILQ_FOREACH_SAFE(rq_elem, &codec_rq, node, rnext) {
-        if (rq_elem && rq_elem->data_buf &&
-            (rq_elem->data_buf->ctx_id == context_id)) {
-
-            TRACE("remove unused node from codec_rq. ctx_id: %d\n", context_id);
-            qemu_mutex_lock(&s->context_queue_mutex);
-            QTAILQ_REMOVE(&codec_rq, rq_elem, node);
-            qemu_mutex_unlock(&s->context_queue_mutex);
-            if (rq_elem && rq_elem->data_buf) {
-                TRACE("release rq_buffer: %p\n", rq_elem->data_buf);
-                g_free(rq_elem->data_buf);
-            }
-
-            TRACE("release rq_elem: %p\n", rq_elem);
-            g_free(rq_elem);
-        } else {
-            TRACE("no elem of %d context in the codec_rq.\n", context_id);
-        }
-    }
-
-    QTAILQ_FOREACH_SAFE(wq_elem, &codec_wq, node, wnext) {
-        if (wq_elem && wq_elem->ctx_id == context_id) {
-            TRACE("remove unused node from codec_wq. ctx_id: %d\n", context_id);
-            qemu_mutex_lock(&s->context_queue_mutex);
-            QTAILQ_REMOVE(&codec_wq, wq_elem, node);
-            qemu_mutex_unlock(&s->context_queue_mutex);
-
-            if (wq_elem && wq_elem->buf) {
-                TRACE("release wq_buffer: %p\n", wq_elem->buf);
-                g_free(wq_elem->buf);
-                wq_elem->buf = NULL;
-            }
-
-            TRACE("release wq_elem: %p\n", wq_elem);
-            g_free(wq_elem);
-        } else {
-            TRACE("no elem of %d context in the codec_wq.\n", context_id);
-        }
-    }
-
-    TRACE("leave: %s\n", __func__);
-}
-
-
-// initialize each pixel format.
-static void maru_brill_codec_pixfmt_info_init(void)
-{
-    /* YUV formats */
-    pix_fmt_info[PIX_FMT_YUV420P].x_chroma_shift = 1;
-    pix_fmt_info[PIX_FMT_YUV420P].y_chroma_shift = 1;
-
-    pix_fmt_info[PIX_FMT_YUV422P].x_chroma_shift = 1;
-    pix_fmt_info[PIX_FMT_YUV422P].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_YUV444P].x_chroma_shift = 0;
-    pix_fmt_info[PIX_FMT_YUV444P].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_YUYV422].x_chroma_shift = 1;
-    pix_fmt_info[PIX_FMT_YUYV422].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_YUV410P].x_chroma_shift = 2;
-    pix_fmt_info[PIX_FMT_YUV410P].y_chroma_shift = 2;
-
-    pix_fmt_info[PIX_FMT_YUV411P].x_chroma_shift = 2;
-    pix_fmt_info[PIX_FMT_YUV411P].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_YUVJ420P].x_chroma_shift = 1;
-    pix_fmt_info[PIX_FMT_YUVJ420P].y_chroma_shift = 1;
-
-    pix_fmt_info[PIX_FMT_YUVJ422P].x_chroma_shift = 1;
-    pix_fmt_info[PIX_FMT_YUVJ422P].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_YUVJ444P].x_chroma_shift = 0;
-    pix_fmt_info[PIX_FMT_YUVJ444P].y_chroma_shift = 0;
-
-    /* RGB formats */
-    pix_fmt_info[PIX_FMT_RGB24].x_chroma_shift = 0;
-    pix_fmt_info[PIX_FMT_RGB24].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_BGR24].x_chroma_shift = 0;
-    pix_fmt_info[PIX_FMT_BGR24].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_RGB32].x_chroma_shift = 0;
-    pix_fmt_info[PIX_FMT_RGB32].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_RGB565].x_chroma_shift = 0;
-    pix_fmt_info[PIX_FMT_RGB565].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_RGB555].x_chroma_shift = 0;
-    pix_fmt_info[PIX_FMT_RGB555].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_YUVA420P].x_chroma_shift = 1;
-    pix_fmt_info[PIX_FMT_YUVA420P].y_chroma_shift = 1;
-}
-
-static int maru_brill_codec_get_picture_size(AVPicture *picture, uint8_t *ptr,
-                                    int pix_fmt, int width,
-                                    int height, bool encode)
-{
-    int size, w2, h2, size2;
-    int stride, stride2;
-    int fsize;
-    PixFmtInfo *pinfo;
-
-    pinfo = &pix_fmt_info[pix_fmt];
-
-    switch (pix_fmt) {
-    case PIX_FMT_YUV420P:
-    case PIX_FMT_YUV422P:
-    case PIX_FMT_YUV444P:
-    case PIX_FMT_YUV410P:
-    case PIX_FMT_YUV411P:
-    case PIX_FMT_YUVJ420P:
-    case PIX_FMT_YUVJ422P:
-    case PIX_FMT_YUVJ444P:
-        stride = ROUND_UP_4(width);
-        h2 = ROUND_UP_X(height, pinfo->y_chroma_shift);
-        size = stride * h2;
-        w2 = DIV_ROUND_UP_X(width, pinfo->x_chroma_shift);
-        stride2 = ROUND_UP_4(w2);
-        h2 = DIV_ROUND_UP_X(height, pinfo->y_chroma_shift);
-        size2 = stride2 * h2;
-        fsize = size + 2 * size2;
-        TRACE("stride: %d, stride2: %d, size: %d, size2: %d, fsize: %d\n",
-            stride, stride2, size, size2, fsize);
-
-        if (!encode && !ptr) {
-            TRACE("allocate a buffer for a decoded picture.\n");
-            ptr = av_mallocz(fsize);
-            if (!ptr) {
-                ERR("[%d] failed to allocate memory.\n", __LINE__);
-                return -1;
-            }
-        }
-        picture->data[0] = ptr;
-        picture->data[1] = picture->data[0] + size;
-        picture->data[2] = picture->data[1] + size2;
-        picture->data[3] = NULL;
-        picture->linesize[0] = stride;
-        picture->linesize[1] = stride2;
-        picture->linesize[2] = stride2;
-        picture->linesize[3] = 0;
-        TRACE("planes %d %d %d\n", 0, size, size + size2);
-        TRACE("strides %d %d %d\n", 0, stride, stride2, stride2);
-        break;
-    case PIX_FMT_YUVA420P:
-        stride = ROUND_UP_4(width);
-        h2 = ROUND_UP_X(height, pinfo->y_chroma_shift);
-        size = stride * h2;
-        w2 = DIV_ROUND_UP_X(width, pinfo->x_chroma_shift);
-        stride2 = ROUND_UP_4(w2);
-        h2 = DIV_ROUND_UP_X(height, pinfo->y_chroma_shift);
-        size2 = stride2 * h2;
-        fsize = 2 * size + 2 * size2;
-        if (!encode && !ptr) {
-            TRACE("allocate a buffer for a decoded picture.\n");
-            ptr = av_mallocz(fsize);
-            if (!ptr) {
-                ERR("[%d] failed to allocate memory.\n", __LINE__);
-                return -1;
-            }
-        }
-        picture->data[0] = ptr;
-        picture->data[1] = picture->data[0] + size;
-        picture->data[2] = picture->data[1] + size2;
-        picture->data[3] = picture->data[2] + size2;
-        picture->linesize[0] = stride;
-        picture->linesize[1] = stride2;
-        picture->linesize[2] = stride2;
-        picture->linesize[3] = stride;
-        TRACE("planes %d %d %d\n", 0, size, size + size2);
-        TRACE("strides %d %d %d\n", 0, stride, stride2, stride2);
-        break;
-    case PIX_FMT_RGB24:
-    case PIX_FMT_BGR24:
-        stride = ROUND_UP_4 (width * 3);
-        fsize = stride * height;
-        TRACE("stride: %d, size: %d\n", stride, fsize);
-
-        if (!encode && !ptr) {
-            TRACE("allocate a buffer for a decoded picture.\n");
-            ptr = av_mallocz(fsize);
-            if (!ptr) {
-                ERR("[%d] failed to allocate memory.\n", __LINE__);
-                return -1;
-            }
-        }
-        picture->data[0] = ptr;
-        picture->data[1] = NULL;
-        picture->data[2] = NULL;
-        picture->data[3] = NULL;
-        picture->linesize[0] = stride;
-        picture->linesize[1] = 0;
-        picture->linesize[2] = 0;
-        picture->linesize[3] = 0;
-        break;
-    case PIX_FMT_RGB32:
-        stride = width * 4;
-        fsize = stride * height;
-        TRACE("stride: %d, size: %d\n", stride, fsize);
-
-        if (!encode && !ptr) {
-            TRACE("allocate a buffer for a decoded picture.\n");
-            ptr = av_mallocz(fsize);
-            if (!ptr) {
-                ERR("[%d] failed to allocate memory.\n", __LINE__);
-                return -1;
-            }
-        }
-        picture->data[0] = ptr;
-        picture->data[1] = NULL;
-        picture->data[2] = NULL;
-        picture->data[3] = NULL;
-        picture->linesize[0] = stride;
-        picture->linesize[1] = 0;
-        picture->linesize[2] = 0;
-        picture->linesize[3] = 0;
-        break;
-    case PIX_FMT_RGB555:
-    case PIX_FMT_RGB565:
-        stride = ROUND_UP_4 (width * 2);
-        fsize = stride * height;
-        TRACE("stride: %d, size: %d\n", stride, fsize);
-
-        if (!encode && !ptr) {
-            TRACE("allocate a buffer for a decoded picture.\n");
-            ptr = av_mallocz(fsize);
-            if (!ptr) {
-                ERR("[%d] failed to allocate memory.\n", __LINE__);
-                return -1;
-            }
-        }
-        picture->data[0] = ptr;
-        picture->data[1] = NULL;
-        picture->data[2] = NULL;
-        picture->data[3] = NULL;
-        picture->linesize[0] = stride;
-        picture->linesize[1] = 0;
-        picture->linesize[2] = 0;
-        picture->linesize[3] = 0;
-        break;
-    case PIX_FMT_PAL8:
-        stride = ROUND_UP_4(width);
-        size = stride * height;
-        fsize = size + 256 * 4;
-        TRACE("stride: %d, size: %d\n", stride, fsize);
-
-        if (!encode && !ptr) {
-            TRACE("allocate a buffer for a decoded picture.\n");
-            ptr = av_mallocz(fsize);
-            if (!ptr) {
-                ERR("[%d] failed to allocate memory.\n", __LINE__);
-                return -1;
-            }
-        }
-        picture->data[0] = ptr;
-        picture->data[1] = ptr + size;
-        picture->data[2] = NULL;
-        picture->data[3] = NULL;
-        picture->linesize[0] = stride;
-        picture->linesize[1] = 4;
-        picture->linesize[2] = 0;
-        picture->linesize[3] = 0;
-        break;
-    default:
-        picture->data[0] = NULL;
-        picture->data[1] = NULL;
-        picture->data[2] = NULL;
-        picture->data[3] = NULL;
-        fsize = -1;
-        ERR("pixel format: %d was wrong.\n", pix_fmt);
-        break;
-    }
-
-    return fsize;
-}
-
-static int maru_brill_codec_query_list (MaruBrillCodecState *s)
-{
-    AVCodec *codec = NULL;
-    uint32_t size = 0, mem_size = 0;
-    uint32_t data_len = 0, length = 0;
-    int32_t codec_type, media_type;
-    int32_t codec_fmts[4], i;
-
-    /* register avcodec */
-    TRACE("register avcodec\n");
-    av_register_all();
-
-    codec = av_codec_next(NULL);
-    if (!codec) {
-        ERR("failed to get codec info.\n");
-        return -1;
-    }
-
-    // a region to store the number of codecs.
-    length = 32 + 64 + 6 * sizeof(int32_t);
-    mem_size = size = sizeof(uint32_t);
-
-    while (codec) {
-        codec_type =
-            codec->decode ? CODEC_TYPE_DECODE : CODEC_TYPE_ENCODE;
-        media_type = codec->type;
-
-        memset(codec_fmts, -1, sizeof(codec_fmts));
-        if (media_type == AVMEDIA_TYPE_VIDEO) {
-            if (codec->pix_fmts) {
-                for (i = 0; codec->pix_fmts[i] != -1; i++) {
-                    codec_fmts[i] = codec->pix_fmts[i];
-                }
-            }
-        } else if (media_type == AVMEDIA_TYPE_AUDIO) {
-            if (codec->sample_fmts) {
-                for (i = 0; codec->sample_fmts[i] != -1; i++) {
-                    codec_fmts[i] = codec->sample_fmts[i];
-                }
-            }
-        } else {
-            ERR("%s of media type is unknown.\n", codec->name);
-        }
-
-        memset(s->vaddr + mem_size, 0x00, length);
-        mem_size += length;
-
-        data_len += length;
-        memcpy(s->vaddr, &data_len, sizeof(data_len));
-
-        memcpy(s->vaddr + size, &codec_type, sizeof(codec_type));
-        size += sizeof(codec_type);
-        memcpy(s->vaddr + size, &media_type, sizeof(media_type));
-        size += sizeof(media_type);
-        memcpy(s->vaddr + size, codec->name, strlen(codec->name));
-        size += 32;
-        memcpy(s->vaddr + size,
-           codec->long_name, strlen(codec->long_name));
-        size += 64;
-        memcpy(s->vaddr + size, codec_fmts, sizeof(codec_fmts));
-        size += sizeof(codec_fmts);
-
-        codec = av_codec_next(codec);
-    }
-
-    return 0;
-}
-
-static int maru_brill_codec_get_context_index(MaruBrillCodecState *s)
-{
-    int index;
-
-    TRACE("enter: %s\n", __func__);
-
-    // requires mutex_lock? its function is protected by critical section.
-    qemu_mutex_lock(&s->threadpool.mutex);
-    for (index = 1; index < CODEC_CONTEXT_MAX; index++) {
-        if (s->context[index].occupied_context == false) {
-            TRACE("get %d of codec context successfully.\n", index);
-            s->context[index].occupied_context = true;
-            break;
-        }
-    }
-    qemu_mutex_unlock(&s->threadpool.mutex);
-
-    if (index == CODEC_CONTEXT_MAX) {
-        ERR("failed to get available codec context. ");
-        ERR("try to run codec again.\n");
-        index = -1;
-    }
-
-    TRACE("leave: %s\n", __func__);
-
-    return index;
-}
-
-// allocate avcontext and avframe struct.
-static AVCodecContext *maru_brill_codec_alloc_context(MaruBrillCodecState *s, int index)
-{
-    TRACE("enter: %s\n", __func__);
-
-    TRACE("allocate %d of context and frame.\n", index);
-    s->context[index].avctx = avcodec_alloc_context3(NULL);
-    s->context[index].frame = avcodec_alloc_frame();
-    s->context[index].opened_context = false;
-
-#if 0
-    s->context[index].parser_buf = NULL;
-    s->context[index].parser_use = false;
-#endif
-    TRACE("leave: %s\n", __func__);
-
-    return s->context[index].avctx;
-}
-
-static AVCodec *maru_brill_codec_find_avcodec(uint8_t *mem_buf)
-{
-    AVCodec *codec = NULL;
-    int32_t encode, size = 0;
-    char codec_name[32] = {0, };
-
-    memcpy(&encode, mem_buf, sizeof(encode));
-    size = sizeof(encode);
-    memcpy(codec_name, mem_buf + size, sizeof(codec_name));
-    size += sizeof(codec_name);
-
-    TRACE("type: %d, name: %s\n", encode, codec_name);
-
-    if (encode) {
-        codec = avcodec_find_encoder_by_name (codec_name);
-    } else {
-        codec = avcodec_find_decoder_by_name (codec_name);
-    }
-    INFO("%s!! find %s %s\n",
-        codec ? "success" : "failure",
-        codec_name, encode ? "encoder" : "decoder");
-
-    return codec;
-}
-
-static void read_codec_init_data(AVCodecContext *avctx, uint8_t *mem_buf)
-{
-    struct video_data video = { 0, };
-    struct audio_data audio = { 0, };
-    int bitrate = 0, size = 0;
-
-    memcpy(&video, mem_buf + size, sizeof(video));
-    size = sizeof(video);
-    serialize_video_data(&video, avctx);
-
-#if 0
-    memcpy(&audio, mem_buf + size, sizeof(int32_t) * 7);
-    size += (sizeof(int32_t) * 7);
-    memcpy(&audio.channel_layout, mem_buf + size, sizeof(audio.channel_layout));
-    size += sizeof(audio.channel_layout);
-#endif
-    memcpy(&audio, mem_buf + size, sizeof(audio));
-    size += sizeof(audio);
-    serialize_audio_data(&audio, avctx);
-
-    memcpy(&bitrate, mem_buf + size, sizeof(bitrate));
-    size += sizeof(bitrate);
-    if (bitrate) {
-        avctx->bit_rate = bitrate;
-    }
-
-    memcpy(&avctx->codec_tag, mem_buf + size, sizeof(avctx->codec_tag));
-    size += sizeof(avctx->codec_tag);
-    memcpy(&avctx->extradata_size,
-            mem_buf + size, sizeof(avctx->extradata_size));
-    size += sizeof(avctx->extradata_size);
-    INFO("extradata size: %d.\n", avctx->extradata_size);
-
-    if (avctx->extradata_size > 0) {
-        avctx->extradata =
-            av_mallocz(ROUND_UP_X(avctx->extradata_size +
-                        FF_INPUT_BUFFER_PADDING_SIZE, 4));
-        if (avctx->extradata) {
-            memcpy(avctx->extradata, mem_buf + size, avctx->extradata_size);
-        }
-    } else {
-        TRACE("no extra data.\n");
-        avctx->extradata =
-            av_mallocz(ROUND_UP_X(FF_INPUT_BUFFER_PADDING_SIZE, 4));
-    }
-}
-
-// write the result of codec_init
-static int write_codec_init_data(AVCodecContext *avctx, uint8_t *mem_buf)
-{
-    int size = 0;
-
-    if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) {
-        int osize = av_get_bytes_per_sample(avctx->sample_fmt);
-
-        memcpy(mem_buf, &avctx->sample_fmt, sizeof(avctx->sample_fmt));
-        size = sizeof(avctx->sample_fmt);
-
-        // frame_size: samples per packet, initialized when calling 'init'
-        memcpy(mem_buf + size, &avctx->frame_size, sizeof(avctx->frame_size));
-        size += sizeof(avctx->frame_size);
-
-        memcpy(mem_buf + size, &osize, sizeof(osize));
-        size += sizeof(osize);
-    }
-
-    return size;
-}
-
-static uint8_t *resample_audio(AVCodecContext * avctx, AVFrame *samples, int *out_size)
-{
-    AVAudioResampleContext *avr = NULL;
-    uint8_t *resample_audio = NULL;
-    int buffer_size = 0, out_linesize = 0;
-    int nb_samples = samples->nb_samples;
-    int out_sample_fmt = avctx->sample_fmt - 5;
-
-    avr = avresample_alloc_context();
-    if (!avr) {
-        ERR("failed to allocate avresample context\n");
-        return NULL;
-    }
-
-    av_opt_set_int(avr, "in_channel_layout", avctx->channel_layout, 0);
-    av_opt_set_int(avr, "in_sample_fmt", avctx->sample_fmt, 0);
-    av_opt_set_int(avr, "in_sample_rate", avctx->sample_rate, 0);
-    av_opt_set_int(avr, "out_channel_layout", avctx->channel_layout, 0);
-    av_opt_set_int(avr, "out_sample_fmt", out_sample_fmt, 0);
-    av_opt_set_int(avr, "out_sample_rate", avctx->sample_rate, 0);
-
-    TRACE("open avresample context\n");
-    if (avresample_open(avr) < 0) {
-        ERR("failed to open avresample context\n");
-        avresample_free(&avr);
-        return NULL;
-    }
-
-    *out_size =
-        av_samples_get_buffer_size(&out_linesize, avctx->channels,
-                                    nb_samples, out_sample_fmt, 0);
-
-    resample_audio = av_mallocz(*out_size);
-    if (!resample_audio) {
-        ERR("failed to allocate resample buffer\n");
-        avresample_close(avr);
-        avresample_free(&avr);
-        return NULL;
-    }
-
-    buffer_size = avresample_convert(avr, &resample_audio,
-        out_linesize, nb_samples,
-        samples->data, samples->linesize[0],
-        samples->nb_samples);
-
-    TRACE("resample_audio out_size %d buffer_size %d\n", *out_size, buffer_size);
-
-    avresample_close(avr);
-    avresample_free(&avr);
-
-    return resample_audio;
-}
-
-
-// codec functions
-static bool codec_init(MaruBrillCodecState *s, int ctx_id, void *data_buf)
-{
-    AVCodecContext *avctx = NULL;
-    AVCodec *codec = NULL;
-    int size = 0, ret = -1;
-    DeviceMemEntry *elem = NULL;
-    uint8_t *tempbuf = NULL;
-    int tempbuf_size = 0;
-
-    TRACE("enter: %s\n", __func__);
-
-    elem = (DeviceMemEntry *)data_buf;
-
-    // allocate AVCodecContext
-    avctx = maru_brill_codec_alloc_context(s, ctx_id);
-    if (!avctx) {
-        ERR("[%d] failed to allocate context.\n", __LINE__);
-        ret = -1;
-    } else {
-#if 0
-        avcodec_get_context_defaults(avctx);
-
-        avctx->rc_strategy = 2;
-        avctx->b_frame_strategy = 0;
-        avctx->coder_type = 0;
-        avctx->context_model = 0;
-        avctx->scenechange_threshold = 0;
-        avctx->inter_threshold = 0;
-
-        avctx->gop_size = DEFAULT_VIDEO_GOP_SIZE;
-        avctx->lmin = (2 * FF_QP2LAMBDA + 0.5);
-        avctx->lmax = (31 * FF_QP2LAMBDA + 0.5);
-#endif
-
-        codec = maru_brill_codec_find_avcodec(elem->buf);
-        if (codec) {
-            size = sizeof(int32_t) + 32; // buffer size of codec_name
-            read_codec_init_data(avctx, elem->buf + size);
-
-            ret = avcodec_open2(avctx, codec, NULL);
-            INFO("avcodec_open success! ret %d ctx_id %d\n", ret, ctx_id);
-
-            TRACE("channels %d sample_rate %d sample_fmt %d ch_layout %lld\n",
-                avctx->channels, avctx->sample_rate,
-                avctx->sample_fmt, avctx->channel_layout);
-
-            tempbuf_size = (sizeof(avctx->sample_fmt) + sizeof(avctx->frame_size)
-                           + sizeof(avctx->extradata_size) + avctx->extradata_size)
-                           + sizeof(int);
-
-            s->context[ctx_id].opened_context = true;
-            s->context[ctx_id].parser_ctx =
-                maru_brill_codec_parser_init(avctx);
-        } else {
-            ERR("failed to find codec. ctx_id: %d\n", ctx_id);
-            ret = -1;
-        }
-    }
-
-    tempbuf_size += sizeof(ret);
-
-    tempbuf = g_malloc(tempbuf_size);
-    if (!tempbuf) {
-        ERR("failed to allocate a buffer\n");
-        tempbuf_size = 0;
-    } else {
-        memcpy(tempbuf, &ret, sizeof(ret));
-        size = sizeof(ret);
-        if (ret < 0) {
-            ERR("failed to open codec contex.\n");
-        } else {
-            size += write_codec_init_data(avctx, tempbuf + size);
-            TRACE("codec_init. copyback!! size %d\n", size);
-            {
-                memcpy(tempbuf + size, &avctx->extradata_size, sizeof(avctx->extradata_size));
-                size += sizeof(avctx->extradata_size);
-                if (avctx->extradata) {
-                    memcpy(tempbuf + size, avctx->extradata, avctx->extradata_size);
-                    size += avctx->extradata_size;
-                }
-            }
-        }
-    }
-
-    maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id);
-
-    TRACE("leave: %s\n", __func__);
-
-    return true;
-}
-
-static bool codec_deinit(MaruBrillCodecState *s, int ctx_id, void *data_buf)
-{
-    AVCodecContext *avctx = NULL;
-    AVFrame *frame = NULL;
-    AVCodecParserContext *parserctx = NULL;
-
-    TRACE("enter: %s\n", __func__);
-
-    avctx = s->context[ctx_id].avctx;
-    frame = s->context[ctx_id].frame;
-    parserctx = s->context[ctx_id].parser_ctx;
-    if (!avctx || !frame) {
-        TRACE("%d of AVCodecContext or AVFrame is NULL. "
-            " Those resources have been released before.\n", ctx_id);
-        return false;
-    }
-
-    INFO("close avcontext of %d\n", ctx_id);
-    // qemu_mutex_lock(&s->threadpool.mutex);
-    avcodec_close(avctx);
-    s->context[ctx_id].opened_context = false;
-    // qemu_mutex_unlock(&s->threadpool.mutex);
-
-    if (avctx->extradata) {
-        TRACE("free context extradata\n");
-        av_free(avctx->extradata);
-        s->context[ctx_id].avctx->extradata = NULL;
-    }
-
-    if (frame) {
-        TRACE("free frame\n");
-        av_free(frame);
-        s->context[ctx_id].frame = NULL;
-    }
-
-    if (avctx) {
-        TRACE("free codec context\n");
-        av_free(avctx);
-        s->context[ctx_id].avctx = NULL;
-    }
-
-    if (parserctx) {
-        av_parser_close(parserctx);
-        s->context[ctx_id].parser_ctx = NULL;
-    }
-
-    maru_brill_codec_push_writequeue(s, NULL, 0, ctx_id);
-
-    TRACE("leave: %s\n", __func__);
-
-    return true;
-}
-
-static bool codec_flush_buffers(MaruBrillCodecState *s, int ctx_id, void *data_buf)
-{
-    AVCodecContext *avctx = NULL;
-    bool ret = true;
-
-    TRACE("enter: %s\n", __func__);
-
-    avctx = s->context[ctx_id].avctx;
-    if (!avctx) {
-        ERR("%d of AVCodecContext is NULL.\n", ctx_id);
-        ret = false;
-    } else if (!avctx->codec) {
-        ERR("%d of AVCodec is NULL.\n", ctx_id);
-        ret = false;
-    } else {
-        TRACE("flush %d context of buffers.\n", ctx_id);
-        avcodec_flush_buffers(avctx);
-    }
-
-    maru_brill_codec_push_writequeue(s, NULL, 0, ctx_id);
-
-    TRACE("leave: %s\n", __func__);
-
-    return ret;
-}
-
-static bool codec_decode_video(MaruBrillCodecState *s, int ctx_id, void *data_buf)
-{
-    AVCodecContext *avctx = NULL;
-    AVFrame *picture = NULL;
-    AVPacket avpkt;
-    int got_picture = 0, len = -1;
-    uint8_t *inbuf = NULL;
-    int inbuf_size = 0, idx, size = 0;
-    int64_t in_offset;
-    DeviceMemEntry *elem = NULL;
-    uint8_t *tempbuf = NULL;
-    int tempbuf_size = 0;
-
-    TRACE("enter: %s\n", __func__);
-
-    elem = (DeviceMemEntry *)data_buf;
-    if (elem && elem->buf) {
-        memcpy(&inbuf_size, elem->buf, sizeof(inbuf_size));
-        size += sizeof(inbuf_size);
-        memcpy(&idx, elem->buf + size, sizeof(idx));
-        size += sizeof(idx);
-        memcpy(&in_offset, elem->buf + size, sizeof(in_offset));
-        size += sizeof(in_offset);
-        TRACE("decode_video. inbuf_size %d\n", inbuf_size);
-
-        if (inbuf_size > 0) {
-            inbuf = elem->buf + size;
-        }
-    } else {
-        TRACE("decode_video. no input buffer\n");
-        // FIXME: improve error handling
-        // return false;
-    }
-
-    av_init_packet(&avpkt);
-    avpkt.data = inbuf;
-    avpkt.size = inbuf_size;
-
-    avctx = s->context[ctx_id].avctx;
-    picture = s->context[ctx_id].frame;
-    if (!avctx) {
-        ERR("decode_video. %d of AVCodecContext is NULL.\n", ctx_id);
-    } else if (!avctx->codec) {
-        ERR("decode_video. %d of AVCodec is NULL.\n", ctx_id);
-    } else if (!picture) {
-        ERR("decode_video. %d of AVFrame is NULL.\n", ctx_id);
-    } else {
-        // in case of skipping frames
-        // picture->pict_type = -1;
-
-        TRACE("decode_video. bitrate %d\n", avctx->bit_rate);
-        // avctx->reordered_opaque = idx;
-        // picture->reordered_opaque = idx;
-
-        len =
-            avcodec_decode_video2(avctx, picture, &got_picture, &avpkt);
-        TRACE("decode_video. in_size %d len %d, frame_size %d\n", avpkt.size, len, got_picture);
-    }
-
-    tempbuf_size =
-            sizeof(len) + sizeof(got_picture) + sizeof(struct video_data);
-
-    if (len < 0) {
-        ERR("failed to decode video. ctx_id: %d, len: %d\n", ctx_id, len);
-        got_picture = 0;
-    }
-
-    tempbuf = g_malloc(tempbuf_size);
-    if (!tempbuf) {
-        ERR("failed to allocate decoded audio buffer\n");
-        // FIXME: how to handle this case?
-    } else {
-        struct video_data video;
-
-        memcpy(tempbuf, &len, sizeof(len));
-        size = sizeof(len);
-        memcpy(tempbuf + size, &got_picture, sizeof(got_picture));
-        size += sizeof(got_picture);
-        if (avctx) {
-            deserialize_video_data(avctx, &video);
-            memcpy(tempbuf + size, &video, sizeof(struct video_data));
-        }
-    }
-
-    maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id);
-
-    TRACE("leave: %s\n", __func__);
-
-    return true;
-}
-
-static bool codec_picture_copy (MaruBrillCodecState *s, int ctx_id, void *elem)
-{
-    AVCodecContext *avctx = NULL;
-    AVPicture *src = NULL;
-    AVPicture dst;
-    uint8_t *out_buffer = NULL, *tempbuf = NULL;
-    int pict_size = 0;
-    bool ret = true;
-
-    TRACE("enter: %s\n", __func__);
-
-    TRACE("copy decoded image of %d context.\n", ctx_id);
-
-    avctx = s->context[ctx_id].avctx;
-    src = (AVPicture *)s->context[ctx_id].frame;
-    if (!avctx) {
-        ERR("picture_copy. %d of AVCodecContext is NULL.\n", ctx_id);
-        ret = false;
-    } else if (!avctx->codec) {
-        ERR("picture_copy. %d of AVCodec is NULL.\n", ctx_id);
-        ret = false;
-    } else if (!src) {
-        ERR("picture_copy. %d of AVFrame is NULL.\n", ctx_id);
-        ret = false;
-    } else {
-        TRACE("decoded image. pix_fmt: %d width: %d, height: %d\n",
-                avctx->pix_fmt, avctx->width, avctx->height);
-
-        pict_size =
-            maru_brill_codec_get_picture_size(&dst, NULL, avctx->pix_fmt,
-                    avctx->width, avctx->height, false);
-        if ((pict_size) < 0) {
-            ERR("picture size: %d\n", pict_size);
-            ret = false;
-        } else {
-            TRACE("picture size: %d\n", pict_size);
-            av_picture_copy(&dst, src, avctx->pix_fmt,
-                            avctx->width, avctx->height);
-
-            tempbuf = g_malloc0(pict_size);
-            if (!tempbuf) {
-                ERR("failed to allocate a picture buffer. size: %d\n", pict_size);
-            } else {
-                out_buffer = dst.data[0];
-                memcpy(tempbuf, out_buffer, pict_size);
-            }
-            av_free(out_buffer);
-        }
-    }
-
-    maru_brill_codec_push_writequeue(s, tempbuf, pict_size, ctx_id);
-
-    TRACE("leave: %s\n", __func__);
-
-    return ret;
-}
-
-static bool codec_decode_audio(MaruBrillCodecState *s, int ctx_id, void *data_buf)
-{
-    AVCodecContext *avctx;
-    AVPacket avpkt;
-    AVFrame *samples = NULL;
-    uint8_t *inbuf = NULL;
-    int inbuf_size = 0, size = 0;
-    int len = -1, got_frame = 0;
-
-    DeviceMemEntry *elem = NULL;
-    uint8_t *tempbuf = NULL;
-    int tempbuf_size = 0;
-
-    uint8_t *outbuf = NULL;
-    int buffer_size = 0;
-    int out_sample_fmt = -1;
-
-    TRACE("enter: %s\n", __func__);
-
-    elem = (DeviceMemEntry *)data_buf;
-    if (elem && elem->buf) {
-        memcpy(&inbuf_size, elem->buf, sizeof(inbuf_size));
-        size = sizeof(inbuf_size);
-        TRACE("decode_audio. inbuf_size %d\n", inbuf_size);
-
-        if (inbuf_size > 0) {
-            inbuf = elem->buf + size;
-        }
-    } else {
-        ERR("decode_audio. no input buffer\n");
-        // FIXME: improve error handling
-        // return false;
-    }
-
-    av_init_packet(&avpkt);
-    avpkt.data = inbuf;
-    avpkt.size = inbuf_size;
-
-    avctx = s->context[ctx_id].avctx;
-    samples = s->context[ctx_id].frame;
-    if (!avctx) {
-        ERR("decode_audio. %d of AVCodecContext is NULL\n", ctx_id);
-    } else if (!avctx->codec) {
-        ERR("decode_audio. %d of AVCodec is NULL\n", ctx_id);
-    } else if (!samples) {
-        ERR("decode_audio. %d of AVFrame is NULL\n", ctx_id);
-    } else {
-        avcodec_get_frame_defaults(samples);
-
-        len = avcodec_decode_audio4(avctx, samples, &got_frame, &avpkt);
-        TRACE("decode_audio. len %d, channel_layout %lld, frame_size %d\n",
-            len, avctx->channel_layout, got_frame);
-        if (got_frame) {
-            if (av_sample_fmt_is_planar(avctx->sample_fmt)) {
-                out_sample_fmt = avctx->sample_fmt - 5;
-
-                outbuf = resample_audio (avctx, samples, &buffer_size);
-            } else {
-                // TODO: not planar format
-            }
-        }
-    }
-
-    tempbuf_size = (sizeof(len) + sizeof(got_frame));
-    if (len < 0) {
-        ERR("failed to decode audio. ctx_id: %d len: %d got_frame: %d\n",
-            ctx_id, len, got_frame);
-        got_frame = 0;
-    } else {
-        tempbuf_size += (sizeof(out_sample_fmt) + sizeof(avctx->sample_rate)
-                        + sizeof(avctx->channels) +  sizeof(avctx->channel_layout)
-                        + sizeof(buffer_size) + buffer_size);
-    }
-
-    tempbuf = g_malloc(tempbuf_size);
-    if (!tempbuf) {
-        ERR("failed to allocate decoded audio buffer\n");
-    } else {
-        memcpy(tempbuf, &len, sizeof(len));
-        size = sizeof(len);
-        memcpy(tempbuf + size, &got_frame, sizeof(got_frame));
-        size += sizeof(got_frame);
-        if (got_frame) {
-            memcpy(tempbuf + size, &out_sample_fmt, sizeof(out_sample_fmt));
-            size += sizeof(out_sample_fmt);
-            memcpy(tempbuf + size, &avctx->sample_rate, sizeof(avctx->sample_rate));
-            size += sizeof(avctx->sample_rate);
-            memcpy(tempbuf + size, &avctx->channels, sizeof(avctx->channels));
-            size += sizeof(avctx->channels);
-            memcpy(tempbuf + size, &avctx->channel_layout, sizeof(avctx->channel_layout));
-            size += sizeof(avctx->channel_layout);
-
-            memcpy(tempbuf + size, &buffer_size, sizeof(buffer_size));
-            size += sizeof(buffer_size);
-
-            if (outbuf) {
-                memcpy(tempbuf + size, outbuf, buffer_size);
-                av_free(outbuf);
-            }
-        }
-    }
-
-    maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id);
-
-    TRACE("leave: %s\n", __func__);
-    return true;
-}
-
-static bool codec_encode_video(MaruBrillCodecState *s, int ctx_id, void *data_buf)
-{
-    AVCodecContext *avctx = NULL;
-    AVFrame *pict = NULL;
-    AVPacket avpkt;
-    uint8_t *inbuf = NULL, *outbuf = NULL;
-    int inbuf_size = 0, outbuf_size = 0;
-    int got_frame = 0, ret = 0, size = 0;
-    int64_t in_timestamp = 0;
-    int coded_frame = 0, key_frame = 0;
-
-    DeviceMemEntry *elem = NULL;
-    uint8_t *tempbuf = NULL;
-    int tempbuf_size = 0;
-
-    TRACE("enter: %s\n", __func__);
-
-    elem = (DeviceMemEntry *)data_buf;
-    if (elem && elem->buf) {
-        memcpy(&inbuf_size, elem->buf, sizeof(inbuf_size));
-        size += sizeof(inbuf_size);
-        memcpy(&in_timestamp, elem->buf + size, sizeof(in_timestamp));
-        size += sizeof(in_timestamp);
-        TRACE("encode video. inbuf_size %d\n", inbuf_size);
-
-        if (inbuf_size > 0) {
-            inbuf = elem->buf + size;
-        }
-    } else {
-        TRACE("encode video. no input buffer.\n");
-        // FIXME: improve error handling
-        // return false;
-    }
-
-    av_init_packet(&avpkt);
-    avpkt.data = NULL;
-    avpkt.size = 0;
-
-    avctx = s->context[ctx_id].avctx;
-    pict = s->context[ctx_id].frame;
-    if (!avctx || !pict) {
-        ERR("%d of context or frame is NULL\n", ctx_id);
-    } else if (!avctx->codec) {
-        ERR("%d of AVCodec is NULL.\n", ctx_id);
-    } else {
-        TRACE("pixel format: %d inbuf: %p, picture data: %p\n",
-            avctx->pix_fmt, inbuf, pict->data[0]);
-
-        ret =
-            maru_brill_codec_get_picture_size((AVPicture *)pict, inbuf,
-                                            avctx->pix_fmt, avctx->width,
-                                            avctx->height, true);
-        if (ret < 0) {
-            ERR("after avpicture_fill, ret:%d\n", ret);
-        } else {
-            if (avctx->time_base.num == 0) {
-                pict->pts = AV_NOPTS_VALUE;
-            } else {
-                AVRational bq =
-                            {1, (G_USEC_PER_SEC * G_GINT64_CONSTANT(1000))};
-                pict->pts = av_rescale_q(in_timestamp, bq, avctx->time_base);
-            }
-            TRACE("encode video. ticks_per_frame:%d, pts:%lld\n",
-                avctx->ticks_per_frame, pict->pts);
-
-            outbuf_size =
-                (avctx->width * avctx->height * 6) + FF_MIN_BUFFER_SIZE;
-
-            outbuf = g_malloc0(outbuf_size);
-
-            avpkt.data = outbuf;
-            avpkt.size = outbuf_size;
-
-            if (!outbuf) {
-                ERR("failed to allocate a buffer of encoding video.\n");
-            } else {
-                ret = avcodec_encode_video2(avctx, &avpkt, pict, &got_frame);
-
-                TRACE("encode video. ret %d got_picture %d outbuf_size %d\n", ret, got_frame, avpkt.size);
-                if (avctx->coded_frame) {
-                    TRACE("encode video. keyframe %d\n", avctx->coded_frame->key_frame);
-                }
-            }
-        }
-    }
-
-    tempbuf_size = sizeof(ret);
-    if (ret < 0) {
-        ERR("failed to encode video. ctx_id %d ret %d\n", ctx_id, ret);
-    } else {
-        tempbuf_size += avpkt.size + sizeof(coded_frame) + sizeof(key_frame);
-    }
-
-    // write encoded video data
-    tempbuf = g_malloc0(tempbuf_size);
-    if (!tempbuf) {
-        ERR("encode video. failed to allocate encoded out buffer.\n");
-    } else {
-        memcpy(tempbuf, &avpkt.size, sizeof(avpkt.size));
-        size = sizeof(avpkt.size);
-
-        if ((got_frame) && outbuf) {
-            // inform gstreamer plugin about the status of encoded frames
-            // A flag for output buffer in gstreamer is depending on the status.
-            if (avctx->coded_frame) {
-                coded_frame = 1;
-                // if key_frame is 0, this frame cannot be decoded independently.
-                key_frame = avctx->coded_frame->key_frame;
-            }
-            memcpy(tempbuf + size, &coded_frame, sizeof(coded_frame));
-            size += sizeof(coded_frame);
-            memcpy(tempbuf + size, &key_frame, sizeof(key_frame));
-            size += sizeof(key_frame);
-            memcpy(tempbuf + size, outbuf, avpkt.size);
-        }
-    }
-
-    if (outbuf) {
-        TRACE("release encoded output buffer. %p\n", outbuf);
-        g_free(outbuf);
-    }
-
-    maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id);
-
-    TRACE("leave: %s\n", __func__);
-    return true;
-}
-
-static bool codec_encode_audio(MaruBrillCodecState *s, int ctx_id, void *data_buf)
-{
-    AVCodecContext *avctx;
-    AVPacket avpkt;
-    uint8_t *inbuf = NULL, *outbuf = NULL;
-    int32_t inbuf_size = 0, max_size = 0;
-    int ret = 0, got_pkt = 0, size = 0;
-
-    DeviceMemEntry *elem = NULL;
-    uint8_t *tempbuf = NULL;
-    int tempbuf_size = 0;
-
-    TRACE("enter: %s\n", __func__);
-
-    elem = (DeviceMemEntry *)data_buf;
-    if (elem && elem->buf) {
-        memcpy(&inbuf_size, elem->buf, sizeof(inbuf_size));
-        size += sizeof(inbuf_size);
-        // memcpy(&max_size, elem->buf + size, sizeof(max_size));
-        // size += sizeof(max_size);
-        max_size = inbuf_size * 4; // + FF_MIN_BUFFER_SIZE;
-        TRACE("encode_video. inbuf_size %d max_size %d\n", inbuf_size, max_size);
-
-        if (inbuf_size > 0) {
-            // inbuf = g_malloc(inbuf_size);
-            // memcpy(inbuf, elem->buf + size, inbuf_size);
-            inbuf = elem->buf + size;
-        }
-    } else {
-        TRACE("encode_audio. no input buffer\n");
-        // FIXME: improve error handling
-        // return false;
-    }
-
-    av_init_packet(&avpkt);
-    avpkt.data = NULL;
-    avpkt.size = 0;
-
-    avctx = s->context[ctx_id].avctx;
-    if (!avctx) {
-        ERR("[%s] %d of Context is NULL!\n", __func__, ctx_id);
-    } else if (!avctx->codec) {
-        ERR("%d of AVCodec is NULL.\n", ctx_id);
-    } else {
-        outbuf = g_malloc0(max_size + FF_MIN_BUFFER_SIZE);
-        // outbuf = g_malloc0(max_size);
-
-        avpkt.data = outbuf;
-        avpkt.size = max_size;
-
-        if (!outbuf) {
-            ERR("failed to allocate a buffer of encoding audio.\n");
-        } else {
-            ret = avcodec_encode_audio2(avctx, &avpkt, (const AVFrame *)inbuf, &got_pkt);
-            TRACE("encode audio. ret %d got_pkt %d outbuf_size %d\n", ret, got_pkt, avpkt.size);
-        }
-    }
-
-    tempbuf_size = sizeof(ret);
-    if (ret < 0) {
-        ERR("failed to encode audio. ctx_id %d ret %d\n", ctx_id, ret);
-    } else {
-        // tempbuf_size += (max_size); // len;
-        tempbuf_size += avpkt.size;
-    }
-
-    // write encoded audio data
-    tempbuf = g_malloc0(tempbuf_size);
-    if (!tempbuf) {
-        ERR("encode audio. failed to allocate encoded out buffer.\n");
-    } else {
-        memcpy(tempbuf, &avpkt.size, sizeof(avpkt.size));
-        size = sizeof(avpkt.size);
-        if (got_pkt && outbuf) {
-            // memcpy(tempbuf + size, outbuf, max_size); // len);
-            memcpy(tempbuf + size, outbuf, avpkt.size);
-        }
-    }
-
-    if (outbuf) {
-        av_free(outbuf);
-    }
-
-    maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id);
-
-    TRACE("[%s] leave:\n", __func__);
-
-    return true;
-}
-
-static AVCodecParserContext *maru_brill_codec_parser_init(AVCodecContext *avctx)
-{
-    AVCodecParserContext *parser = NULL;
-
-    if (!avctx) {
-        ERR("context is NULL\n");
-        return NULL;
-    }
-
-    switch (avctx->codec_id) {
-    case CODEC_ID_MPEG4:
-    case CODEC_ID_VC1:
-        TRACE("not using parser.\n");
-        break;
-    case CODEC_ID_H264:
-        if (avctx->extradata_size == 0) {
-            TRACE("H.264 with no extradata, creating parser.\n");
-            parser = av_parser_init (avctx->codec_id);
-        }
-        break;
-    default:
-        parser = av_parser_init (avctx->codec_id);
-        if (parser) {
-            INFO("using parser. %d\n", avctx->codec_id);
-        }
-        break;
-    }
-
-    return parser;
-}
-
-static void maru_brill_codec_bh_callback(void *opaque)
-{
-    MaruBrillCodecState *s = (MaruBrillCodecState *)opaque;
-
-    TRACE("enter: %s\n", __func__);
-
-    qemu_mutex_lock(&s->context_queue_mutex);
-    if (!QTAILQ_EMPTY(&codec_wq)) {
-        qemu_mutex_unlock(&s->context_queue_mutex);
-
-        TRACE("raise irq\n");
-        pci_set_irq(&s->dev, 1);
-        s->irq_raised = 1;
-    } else {
-        qemu_mutex_unlock(&s->context_queue_mutex);
-        TRACE("codec_wq is empty!!\n");
-    }
-
-    TRACE("leave: %s\n", __func__);
-}
-
-/*
- *  Codec Device APIs
- */
-static uint64_t maru_brill_codec_read(void *opaque,
-                                        hwaddr addr,
-                                        unsigned size)
-{
-    MaruBrillCodecState *s = (MaruBrillCodecState *)opaque;
-    uint64_t ret = 0;
-
-    switch (addr) {
-    case CODEC_CMD_GET_THREAD_STATE:
-        qemu_mutex_lock(&s->context_queue_mutex);
-        if (s->irq_raised) {
-            ret = CODEC_TASK_END;
-            pci_set_irq(&s->dev, 0);
-            s->irq_raised = 0;
-        }
-        qemu_mutex_unlock(&s->context_queue_mutex);
-
-        TRACE("get thread_state. ret: %d\n", ret);
-        break;
-
-    case CODEC_CMD_GET_CTX_FROM_QUEUE:
-    {
-        DeviceMemEntry *head = NULL;
-
-        qemu_mutex_lock(&s->context_queue_mutex);
-        head = QTAILQ_FIRST(&codec_wq);
-        if (head) {
-            ret = head->ctx_id;
-            QTAILQ_REMOVE(&codec_wq, head, node);
-            entry[ret] = head;
-            TRACE("get a elem from codec_wq. 0x%x\n", head);
-        } else {
-            ret = 0;
-        }
-        qemu_mutex_unlock(&s->context_queue_mutex);
-
-        TRACE("get a head from a writequeue. head: %x\n", ret);
-    }
-        break;
-
-    case CODEC_CMD_GET_VERSION:
-        ret = CODEC_VERSION;
-        TRACE("codec version: %d\n", ret);
-        break;
-
-    case CODEC_CMD_GET_ELEMENT:
-        ret = maru_brill_codec_query_list(s);
-        break;
-
-    case CODEC_CMD_GET_CONTEXT_INDEX:
-        ret = maru_brill_codec_get_context_index(s);
-        TRACE("get context index: %d\n", ret);
-        break;
-
-    default:
-        ERR("no avaiable command for read. %d\n", addr);
-    }
-
-    return ret;
-}
-
-static void maru_brill_codec_write(void *opaque, hwaddr addr,
-                                    uint64_t value, unsigned size)
-{
-    MaruBrillCodecState *s = (MaruBrillCodecState *)opaque;
-
-    switch (addr) {
-    case CODEC_CMD_API_INDEX:
-        TRACE("set codec_cmd value: %d\n", value);
-        s->ioparam.api_index = value;
-        maru_brill_codec_wakeup_threads(s, value);
-        break;
-
-    case CODEC_CMD_CONTEXT_INDEX:
-        TRACE("set context_index value: %d\n", value);
-        s->ioparam.ctx_index = value;
-        break;
-
-    case CODEC_CMD_DEVICE_MEM_OFFSET:
-        TRACE("set mem_offset value: 0x%x\n", value);
-        s->ioparam.mem_offset = value;
-        break;
-
-    case CODEC_CMD_RELEASE_CONTEXT:
-    {
-        int ctx_index = (int32_t)value;
-
-        if (s->context[ctx_index].occupied_thread) {
-            s->context[ctx_index].requested_close = true;
-            INFO("make running thread to handle deinit\n");
-        } else {
-            maru_brill_codec_release_context(s, ctx_index);
-        }
-    }
-        break;
-
-    case CODEC_CMD_GET_DATA_FROM_QUEUE:
-        maru_brill_codec_pop_writequeue(s, (uint32_t)value);
-        break;
-
-    default:
-        ERR("no available command for write. %d\n", addr);
-    }
-}
-
-static const MemoryRegionOps maru_brill_codec_mmio_ops = {
-    .read = maru_brill_codec_read,
-    .write = maru_brill_codec_write,
-    .valid = {
-        .min_access_size = 4,
-        .max_access_size = 4,
-        .unaligned = false
-    },
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static int maru_brill_codec_initfn(PCIDevice *dev)
-{
-    MaruBrillCodecState *s = DO_UPCAST(MaruBrillCodecState, dev, dev);
-    uint8_t *pci_conf = s->dev.config;
-
-    INFO("device initialization.\n");
-    pci_config_set_interrupt_pin(pci_conf, 1);
-
-    memory_region_init_ram(&s->vram, OBJECT(s), "maru_brill_codec.vram", CODEC_MEM_SIZE);
-    s->vaddr = (uint8_t *)memory_region_get_ram_ptr(&s->vram);
-
-    memory_region_init_io(&s->mmio, OBJECT(s), &maru_brill_codec_mmio_ops, s,
-                        "maru_brill_codec.mmio", CODEC_REG_SIZE);
-
-    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
-    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);
-
-    qemu_mutex_init(&s->context_mutex);
-    qemu_mutex_init(&s->context_queue_mutex);
-    qemu_mutex_init(&s->ioparam_queue_mutex);
-
-    maru_brill_codec_get_cpu_cores(s);
-    maru_brill_codec_threads_create(s);
-
-    // register a function to qemu bottom-halves to switch context.
-    s->codec_bh = qemu_bh_new(maru_brill_codec_bh_callback, s);
-
-    return 0;
-}
-
-static void maru_brill_codec_exitfn(PCIDevice *dev)
-{
-    MaruBrillCodecState *s = DO_UPCAST(MaruBrillCodecState, dev, dev);
-    INFO("device exit\n");
-
-    qemu_mutex_destroy(&s->context_mutex);
-    qemu_mutex_destroy(&s->context_queue_mutex);
-    qemu_mutex_destroy(&s->ioparam_queue_mutex);
-
-    qemu_bh_delete(s->codec_bh);
-
-    memory_region_destroy(&s->vram);
-    memory_region_destroy(&s->mmio);
-}
-
-static void maru_brill_codec_reset(DeviceState *d)
-{
-    MaruBrillCodecState *s = (MaruBrillCodecState *)d;
-    INFO("device reset\n");
-
-    s->irq_raised = 0;
-
-    memset(&s->context, 0, sizeof(CodecContext) * CODEC_CONTEXT_MAX);
-    memset(&s->ioparam, 0, sizeof(CodecParam));
-
-    maru_brill_codec_pixfmt_info_init();
-}
-
-static void maru_brill_codec_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = maru_brill_codec_initfn;
-    k->exit = maru_brill_codec_exitfn;
-    k->vendor_id = PCI_VENDOR_ID_TIZEN;
-    k->device_id = PCI_DEVICE_ID_VIRTUAL_BRILL_CODEC;
-    k->class_id = PCI_CLASS_OTHERS;
-    dc->reset = maru_brill_codec_reset;
-    dc->desc = "Virtual new codec device for Tizen emulator";
-}
-
-static TypeInfo codec_device_info = {
-    .name          = CODEC_DEVICE_NAME,
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(MaruBrillCodecState),
-    .class_init    = maru_brill_codec_class_init,
-};
-
-static void codec_register_types(void)
-{
-    type_register_static(&codec_device_info);
-}
-
-type_init(codec_register_types)
diff --git a/tizen/src/hw/maru_brill_codec.h b/tizen/src/hw/maru_brill_codec.h
deleted file mode 100644 (file)
index 5a0cc6d..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Virtual Codec device
- *
- * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Kitae Kim <kt920.kim@samsung.com>
- *  SeokYeon Hwang <syeon.hwang@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 <stdio.h>
-#include <sys/types.h>
-
-#include "hw/hw.h"
-#include "sysemu/kvm.h"
-#include "qemu/main-loop.h"
-#include "hw/pci/pci.h"
-#include "hw/pci/pci_ids.h"
-#include "qemu-common.h"
-#include "qemu/thread.h"
-
-#include "util/osutil.h"
-#include "debug_ch.h"
-#include "maru_device_ids.h"
-
-#include "libavformat/avformat.h"
-#include "libavresample/avresample.h"
-#include "libavutil/mathematics.h"
-#include "libavutil/opt.h"
-
-#define CODEC_CONTEXT_MAX           1024
-
-/*
- *  Codec Device Structures
- */
-typedef struct CodecParam {
-    int32_t     api_index;
-    int32_t     ctx_index;
-    uint32_t    mem_offset;
-} CodecParam;
-
-struct video_data {
-    int32_t width;
-    int32_t height;
-    int32_t fps_n;
-    int32_t fps_d;
-    int32_t par_n;
-    int32_t par_d;
-    int32_t pix_fmt;
-    int32_t bpp;
-    int32_t ticks_per_frame;
-};
-
-struct audio_data {
-    int32_t channels;
-    int32_t sample_rate;
-    int32_t block_align;
-    int32_t depth;
-    int32_t sample_fmt;
-    int32_t frame_size;
-    int32_t bits_per_smp_fmt;
-    int32_t reserved;
-    int64_t channel_layout;
-};
-
-typedef struct CodecContext {
-    AVCodecContext          *avctx;
-    AVFrame                 *frame;
-    AVCodecParserContext    *parser_ctx;
-    uint8_t                 *parser_buf;
-    uint16_t                parser_use;
-    bool                    occupied_context;
-    bool                    occupied_thread;
-    bool                    opened_context;
-    bool                    requested_close;
-} CodecContext;
-
-typedef struct CodecThreadPool {
-    QemuThread          *threads;
-    QemuMutex           mutex;
-    QemuCond            cond;
-} CodecThreadPool;
-
-typedef struct MaruBrillCodecState {
-    PCIDevice           dev;
-
-    uint8_t             *vaddr;
-    MemoryRegion        vram;
-    MemoryRegion        mmio;
-
-    QEMUBH              *codec_bh;
-    QemuMutex           context_mutex;
-    QemuMutex           context_queue_mutex;
-    QemuMutex           ioparam_queue_mutex;
-
-    CodecThreadPool     threadpool;
-    bool                is_thread_running;
-    uint32_t            worker_thread_cnt;
-    uint32_t            idle_thread_cnt;
-
-    int                 irq_raised;
-
-    CodecContext        context[CODEC_CONTEXT_MAX];
-    CodecParam          ioparam;
-} MaruBrillCodecState;
-
-enum codec_io_cmd {
-    CODEC_CMD_API_INDEX             = 0x28,
-    CODEC_CMD_CONTEXT_INDEX         = 0x2C,
-    CODEC_CMD_DEVICE_MEM_OFFSET     = 0x34,
-    CODEC_CMD_GET_THREAD_STATE      = 0x38,
-    CODEC_CMD_GET_CTX_FROM_QUEUE    = 0x3C,
-    CODEC_CMD_GET_DATA_FROM_QUEUE   = 0x40,
-    CODEC_CMD_RELEASE_CONTEXT       = 0x44,
-    CODEC_CMD_GET_VERSION           = 0x50,
-    CODEC_CMD_GET_ELEMENT           = 0x54,
-    CODEC_CMD_GET_CONTEXT_INDEX     = 0x58,
-};
-
-enum codec_api_type {
-    CODEC_INIT = 0,
-    CODEC_DECODE_VIDEO,
-    CODEC_ENCODE_VIDEO,
-    CODEC_DECODE_AUDIO,
-    CODEC_ENCODE_AUDIO,
-    CODEC_PICTURE_COPY,
-    CODEC_DEINIT,
-    CODEC_FLUSH_BUFFERS,
- };
-
-enum codec_type {
-    CODEC_TYPE_UNKNOWN = -1,
-    CODEC_TYPE_DECODE,
-    CODEC_TYPE_ENCODE,
-};
-
-enum thread_state {
-    CODEC_TASK_START    = 0,
-    CODEC_TASK_END      = 0x1f,
-};
-
-/*
- *  Codec Device Functions
- */
-int maru_brill_codec_pci_device_init(PCIBus *bus);
diff --git a/tizen/src/hw/maru_camera_common.h b/tizen/src/hw/maru_camera_common.h
deleted file mode 100644 (file)
index 45b1a38..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Common header of MARU Virtual Camera device.
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- * JinHyung Jo <jinhyung.jo@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_CAMERA_COMMON_H_
-#define _MARU_CAMERA_COMMON_H_
-
-#include "hw/pci/pci.h"
-#include "qemu/thread.h"
-
-#define MARUCAM_MAX_PARAM    20
-#define MARUCAM_SKIPFRAMES    2
-
-/* must sync with GUEST camera_driver */
-#define MARUCAM_CMD_INIT           0x00
-#define MARUCAM_CMD_OPEN           0x04
-#define MARUCAM_CMD_CLOSE          0x08
-#define MARUCAM_CMD_ISR            0x0C
-#define MARUCAM_CMD_START_PREVIEW  0x10
-#define MARUCAM_CMD_STOP_PREVIEW   0x14
-#define MARUCAM_CMD_S_PARAM        0x18
-#define MARUCAM_CMD_G_PARAM        0x1C
-#define MARUCAM_CMD_ENUM_FMT       0x20
-#define MARUCAM_CMD_TRY_FMT        0x24
-#define MARUCAM_CMD_S_FMT          0x28
-#define MARUCAM_CMD_G_FMT          0x2C
-#define MARUCAM_CMD_QCTRL          0x30
-#define MARUCAM_CMD_S_CTRL         0x34
-#define MARUCAM_CMD_G_CTRL         0x38
-#define MARUCAM_CMD_ENUM_FSIZES    0x3C
-#define MARUCAM_CMD_ENUM_FINTV     0x40
-#define MARUCAM_CMD_S_DATA         0x44
-#define MARUCAM_CMD_G_DATA         0x48
-#define MARUCAM_CMD_DATACLR        0x50
-#define MARUCAM_CMD_REQFRAME       0x54
-
-typedef struct MaruCamState MaruCamState;
-typedef struct MaruCamParam MaruCamParam;
-
-struct MaruCamParam {
-    uint32_t    top;
-    uint32_t    retVal;
-    uint32_t    errCode;
-    uint32_t    stack[MARUCAM_MAX_PARAM];
-};
-
-struct MaruCamState {
-    PCIDevice           dev;
-    MaruCamParam        *param;
-    QemuThread          thread_id;
-    QemuMutex           thread_mutex;;
-    QemuCond            thread_cond;
-    QEMUBH              *tx_bh;
-
-    bool                initialized;
-    bool                destroying;
-    void                *vaddr;     /* vram ptr */
-    uint32_t            isr;
-    uint32_t            streamon;
-    uint32_t            buf_size;
-    uint32_t            req_frame;
-
-    MemoryRegion        vram;
-    MemoryRegion        mmio;
-};
-
-/* ------------------------------------------------------------------------- */
-/* Fucntion prototype                                                        */
-/* ------------------------------------------------------------------------- */
-int marucam_device_check(int log_flag);
-void marucam_device_init(MaruCamState *state);
-void marucam_device_exit(MaruCamState *state);
-void marucam_device_open(MaruCamState *state);
-void marucam_device_close(MaruCamState *state);
-void marucam_device_start_preview(MaruCamState *state);
-void marucam_device_stop_preview(MaruCamState *state);
-void marucam_device_s_param(MaruCamState *state);
-void marucam_device_g_param(MaruCamState *state);
-void marucam_device_s_fmt(MaruCamState *state);
-void marucam_device_g_fmt(MaruCamState *state);
-void marucam_device_try_fmt(MaruCamState *state);
-void marucam_device_enum_fmt(MaruCamState *state);
-void marucam_device_qctrl(MaruCamState *state);
-void marucam_device_s_ctrl(MaruCamState *state);
-void marucam_device_g_ctrl(MaruCamState *state);
-void marucam_device_enum_fsizes(MaruCamState *state);
-void marucam_device_enum_fintv(MaruCamState *state);
-
-int maru_camera_pci_init(PCIBus *bus);
-
-#endif  /* _MARU_CAMERA_COMMON_H_ */
diff --git a/tizen/src/hw/maru_camera_common_pci.c b/tizen/src/hw/maru_camera_common_pci.c
deleted file mode 100644 (file)
index 4618f4b..0000000
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * Common implementation of MARU Virtual Camera device by PCI bus.
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- * JinHyung Jo <jinhyung.jo@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 <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <signal.h>
-
-#include "qemu-common.h"
-#include "qemu/main-loop.h"
-#include "exec/cpu-common.h"
-
-#include "maru_camera_common.h"
-#include "maru_device_ids.h"
-#include "debug_ch.h"
-
-MULTI_DEBUG_CHANNEL(tizen, maru-camera);
-
-#define MARU_PCI_CAMERA_DEVICE_NAME     "maru-camera"
-
-#define MARUCAM_MEM_SIZE    (4 * 1024 * 1024)   /* 4MB */
-#define MARUCAM_REG_SIZE    (256)               /* 64 * 4Byte */
-
-/*
- *  I/O functions
- */
-static inline uint32_t
-marucam_mmio_read(void *opaque, hwaddr offset)
-{
-    uint32_t ret = 0;
-    MaruCamState *state = (MaruCamState *)opaque;
-
-    switch (offset & 0xFF) {
-    case MARUCAM_CMD_ISR:
-        qemu_mutex_lock(&state->thread_mutex);
-        ret = state->isr;
-        if (ret != 0) {
-            pci_set_irq(&state->dev, 0);
-            state->isr = 0;
-        }
-        qemu_mutex_unlock(&state->thread_mutex);
-        break;
-    case MARUCAM_CMD_G_DATA:
-        ret = state->param->stack[state->param->top++];
-        break;
-    case MARUCAM_CMD_OPEN:
-    case MARUCAM_CMD_CLOSE:
-    case MARUCAM_CMD_START_PREVIEW:
-    case MARUCAM_CMD_STOP_PREVIEW:
-    case MARUCAM_CMD_S_PARAM:
-    case MARUCAM_CMD_G_PARAM:
-    case MARUCAM_CMD_ENUM_FMT:
-    case MARUCAM_CMD_TRY_FMT:
-    case MARUCAM_CMD_S_FMT:
-    case MARUCAM_CMD_G_FMT:
-    case MARUCAM_CMD_QCTRL:
-    case MARUCAM_CMD_S_CTRL:
-    case MARUCAM_CMD_G_CTRL:
-    case MARUCAM_CMD_ENUM_FSIZES:
-    case MARUCAM_CMD_ENUM_FINTV:
-        ret = state->param->errCode;
-        state->param->errCode = 0;
-        break;
-    default:
-        ERR("Not supported command: 0x%x\n", offset);
-        ret = EINVAL;
-        break;
-    }
-    return ret;
-}
-
-static inline void
-marucam_mmio_write(void *opaque, hwaddr offset, uint32_t value)
-{
-    MaruCamState *state = (MaruCamState *)opaque;
-
-    switch (offset & 0xFF) {
-    case MARUCAM_CMD_OPEN:
-        marucam_device_open(state);
-        break;
-    case MARUCAM_CMD_CLOSE:
-        marucam_device_close(state);
-        break;
-    case MARUCAM_CMD_START_PREVIEW:
-        marucam_device_start_preview(state);
-        break;
-    case MARUCAM_CMD_STOP_PREVIEW:
-        marucam_device_stop_preview(state);
-        memset(state->vaddr, 0, MARUCAM_MEM_SIZE);
-        break;
-    case MARUCAM_CMD_S_PARAM:
-        marucam_device_s_param(state);
-        break;
-    case MARUCAM_CMD_G_PARAM:
-        marucam_device_g_param(state);
-        break;
-    case MARUCAM_CMD_ENUM_FMT:
-        marucam_device_enum_fmt(state);
-        break;
-    case MARUCAM_CMD_TRY_FMT:
-        marucam_device_try_fmt(state);
-        break;
-    case MARUCAM_CMD_S_FMT:
-        marucam_device_s_fmt(state);
-        break;
-    case MARUCAM_CMD_G_FMT:
-        marucam_device_g_fmt(state);
-        break;
-    case MARUCAM_CMD_QCTRL:
-        marucam_device_qctrl(state);
-        break;
-    case MARUCAM_CMD_S_CTRL:
-        marucam_device_s_ctrl(state);
-        break;
-    case MARUCAM_CMD_G_CTRL:
-        marucam_device_g_ctrl(state);
-        break;
-    case MARUCAM_CMD_ENUM_FSIZES:
-        marucam_device_enum_fsizes(state);
-        break;
-    case MARUCAM_CMD_ENUM_FINTV:
-        marucam_device_enum_fintv(state);
-        break;
-    case MARUCAM_CMD_S_DATA:
-        state->param->stack[state->param->top++] = value;
-        break;
-    case MARUCAM_CMD_DATACLR:
-        memset(state->param, 0, sizeof(MaruCamParam));
-        break;
-    case MARUCAM_CMD_REQFRAME:
-        qemu_mutex_lock(&state->thread_mutex);
-        state->req_frame = value + 1;
-        qemu_mutex_unlock(&state->thread_mutex);
-        break;
-    default:
-        ERR("Not supported command: 0x%x\n", offset);
-        break;
-    }
-}
-
-static const MemoryRegionOps maru_camera_mmio_ops = {
-    .old_mmio = {
-        .read = {
-            marucam_mmio_read,
-            marucam_mmio_read,
-            marucam_mmio_read,
-        },
-        .write = {
-            marucam_mmio_write,
-            marucam_mmio_write,
-            marucam_mmio_write,
-        },
-    },
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-/*
- *  QEMU bottom half funtion
- */
-static void marucam_tx_bh(void *opaque)
-{
-    MaruCamState *state = (MaruCamState *)opaque;
-
-    qemu_mutex_lock(&state->thread_mutex);
-    if (state->isr) {
-        pci_set_irq(&state->dev, 1);
-    }
-    qemu_mutex_unlock(&state->thread_mutex);
-}
-
-/*
- *  Initialization function
- */
-
-static int marucam_initfn(PCIDevice *dev)
-{
-    MaruCamState *s = DO_UPCAST(MaruCamState, dev, dev);
-    uint8_t *pci_conf = s->dev.config;
-
-    /* Check available webcam
-     * If there is not one, you can't use the camera.
-     */
-    if (!marucam_device_check(1)) {
-        s->initialized = false;
-        ERR("Failed to check the camera device, "
-            "You can *not* use the camera\n");
-        return 0;
-    }
-
-    pci_config_set_interrupt_pin(pci_conf, 0x03);
-
-    memory_region_init_ram(&s->vram, OBJECT(s), "marucamera.ram", MARUCAM_MEM_SIZE);
-    s->vaddr = memory_region_get_ram_ptr(&s->vram);
-    memset(s->vaddr, 0, MARUCAM_MEM_SIZE);
-
-    memory_region_init_io(&s->mmio, OBJECT(s),
-                          &maru_camera_mmio_ops,
-                          s,
-                          "maru-camera-mmio",
-                          MARUCAM_REG_SIZE);
-
-    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
-    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);
-
-    /* for worker thread */
-    s->param = (MaruCamParam *)g_malloc0(sizeof(MaruCamParam));
-    qemu_cond_init(&s->thread_cond);
-    qemu_mutex_init(&s->thread_mutex);
-
-    marucam_device_init(s);
-
-    s->tx_bh = qemu_bh_new(marucam_tx_bh, s);
-    s->initialized = true;
-    INFO("initialize maru-camera device\n");
-
-    return 0;
-}
-
-/*
- *  Termination function
- */
-static void marucam_exitfn(PCIDevice *pci_dev)
-{
-    MaruCamState *s =
-        OBJECT_CHECK(MaruCamState, pci_dev, MARU_PCI_CAMERA_DEVICE_NAME);
-
-    if (s->initialized) {
-        marucam_device_exit(s);
-        g_free(s->param);
-        qemu_cond_destroy(&s->thread_cond);
-        qemu_mutex_destroy(&s->thread_mutex);
-
-        memory_region_destroy(&s->vram);
-        memory_region_destroy(&s->mmio);
-    }
-
-    INFO("finalize maru-camera device\n");
-}
-
-static void marucam_resetfn(DeviceState *d)
-{
-    MaruCamState *s = (MaruCamState *)d;
-
-    if (s->initialized) {
-        marucam_device_close(s);
-        qemu_mutex_lock(&s->thread_mutex);
-        s->isr = s->streamon = s->req_frame = s->buf_size = 0;
-        qemu_mutex_unlock(&s->thread_mutex);
-        memset(s->vaddr, 0, MARUCAM_MEM_SIZE);
-        memset(s->param, 0x00, sizeof(MaruCamParam));
-        INFO("reset maru-camera device\n");
-    }
-}
-
-int maru_camera_pci_init(PCIBus *bus)
-{
-    pci_create_simple(bus, -1, MARU_PCI_CAMERA_DEVICE_NAME);
-    return 0;
-}
-
-static void maru_camera_pci_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = marucam_initfn;
-    k->exit = marucam_exitfn;
-    k->vendor_id = PCI_VENDOR_ID_TIZEN;
-    k->device_id = PCI_DEVICE_ID_VIRTUAL_CAMERA;
-    k->class_id = PCI_CLASS_OTHERS;
-    dc->reset = marucam_resetfn;
-    dc->desc = "MARU Virtual Camera device for Tizen emulator";
-}
-
-static TypeInfo maru_camera_info = {
-    .name          = MARU_PCI_CAMERA_DEVICE_NAME,
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(MaruCamState),
-    .class_init    = maru_camera_pci_class_init,
-};
-
-static void maru_camera_pci_register_types(void)
-{
-    type_register_static(&maru_camera_info);
-}
-
-type_init(maru_camera_pci_register_types)
diff --git a/tizen/src/hw/maru_camera_darwin.h b/tizen/src/hw/maru_camera_darwin.h
deleted file mode 100644 (file)
index 2ac39f9..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Header of MARU Virtual Camera device for MacOS.
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- * Jun Tian <jun.j.tian@intel.com>
- * JinHyung Jo <jinhyung.jo@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_CAMERA_DARWIN_H_
-#define _MARU_CAMERA_DARWIN_H_
-
-#define MAKEFOURCC(a, b, c, d) \
-    (((uint32_t)(a) << 0) | \
-     ((uint32_t)(b) << 8) | \
-     ((uint32_t)(c) << 16) | \
-     ((uint32_t)(d) << 24))
-
-/* 16  RGB-5-5-5     */
-#define V4L2_PIX_FMT_RGB555  MAKEFOURCC('R', 'G', 'B', 'O')
-/* 16  RGB-5-6-5     */
-#define V4L2_PIX_FMT_RGB565  MAKEFOURCC('R', 'G', 'B', 'P')
-/* 16  RGB-5-5-5 BE  */
-#define V4L2_PIX_FMT_RGB555X MAKEFOURCC('R', 'G', 'B', 'Q')
-/* 16  RGB-5-6-5 BE  */
-#define V4L2_PIX_FMT_RGB565X MAKEFOURCC('R', 'G', 'B', 'R')
-/* 24  BGR-8-8-8     */
-#define V4L2_PIX_FMT_BGR24   MAKEFOURCC('B', 'G', 'R', '3')
-/* 24  RGB-8-8-8     */
-#define V4L2_PIX_FMT_RGB24   MAKEFOURCC('R', 'G', 'B', '3')
-/* 32  BGR-8-8-8-8   */
-#define V4L2_PIX_FMT_BGR32   MAKEFOURCC('B', 'G', 'R', '4')
-/* 32  RGB-8-8-8-8   */
-#define V4L2_PIX_FMT_RGB32   MAKEFOURCC('R', 'G', 'B', '4')
-/*  9  YVU 4:1:0     */
-#define V4L2_PIX_FMT_YVU410  MAKEFOURCC('Y', 'V', 'U', '9')
-/* 12  YVU 4:2:0     */
-#define V4L2_PIX_FMT_YVU420  MAKEFOURCC('Y', 'V', '1', '2')
-/* 16  YUV 4:2:2     */
-#define V4L2_PIX_FMT_YUYV    MAKEFOURCC('Y', 'U', 'Y', 'V')
-/* 16  YUV 4:2:2     */
-#define V4L2_PIX_FMT_UYVY    MAKEFOURCC('U', 'Y', 'V', 'Y')
-/* 16  YVU422 planar */
-#define V4L2_PIX_FMT_YUV422P MAKEFOURCC('4', '2', '2', 'P')
-/* 16  YVU411 planar */
-#define V4L2_PIX_FMT_YUV411P MAKEFOURCC('4', '1', '1', 'P')
-/* 12  YUV 4:1:1     */
-#define V4L2_PIX_FMT_Y41P    MAKEFOURCC('Y', '4', '1', 'P')
-/* 16  xxxxyyyy uuuuvvvv */
-#define V4L2_PIX_FMT_YUV444  MAKEFOURCC('Y', '4', '4', '4')
-/* 16  YUV-5-5-5     */
-#define V4L2_PIX_FMT_YUV555  MAKEFOURCC('Y', 'U', 'V', 'O')
-/* 16  YUV-5-6-5     */
-#define V4L2_PIX_FMT_YUV565  MAKEFOURCC('Y', 'U', 'V', 'P')
-/* 32  YUV-8-8-8-8   */
-#define V4L2_PIX_FMT_YUV32   MAKEFOURCC('Y', 'U', 'V', '4')
-/*  9  YUV 4:1:0     */
-#define V4L2_PIX_FMT_YUV410  MAKEFOURCC('Y', 'U', 'V', '9')
-/* 12  YUV 4:2:0     */
-#define V4L2_PIX_FMT_YUV420  MAKEFOURCC('Y', 'U', '1', '2')
-/* 16  YUV 4:2:2     */
-#define V4L2_PIX_FMT_YYUV    MAKEFOURCC('Y', 'Y', 'U', 'V')
-
-void convert_frame(uint32_t pixel_format, int frame_width, int frame_height,
-                   size_t frame_size, void *frame_pixels, void *video_buf);
-
-#endif /* _MARU_CAMERA_DARWIN_H_ */
diff --git a/tizen/src/hw/maru_camera_darwin_converter.c b/tizen/src/hw/maru_camera_darwin_converter.c
deleted file mode 100644 (file)
index 24c560f..0000000
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * Implementation of color conversion for MARU Virtual Camera device on MacOS.
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- * Jun Tian <jun.j.tian@intel.com>
- * JinHyung Jo <jinhyung.jo@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 "qemu-common.h"
-#include "maru_camera_darwin.h"
-#include "debug_ch.h"
-
-MULTI_DEBUG_CHANNEL(tizen, camera_darwin);
-
-static void UYVYToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
-                         int width, int height);
-static void YVU420ToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
-                           int width, int height);
-static void YUYVToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
-                         int width, int height);
-
-/* Convert pixel format to YUV420 */
-void convert_frame(uint32_t pixel_format, int frame_width, int frame_height,
-                   size_t frame_size, void *frame_pixels, void *video_buf)
-{
-    switch (pixel_format) {
-    case V4L2_PIX_FMT_YUV420:
-        memcpy(video_buf, (void *)frame_pixels, (size_t)frame_size);
-        break;
-    case V4L2_PIX_FMT_YVU420:
-        YVU420ToYUV420(frame_pixels, video_buf, frame_width, frame_height);
-        break;
-    case V4L2_PIX_FMT_YUYV:
-        YUYVToYUV420(frame_pixels, video_buf, frame_width, frame_height);
-        break;
-    case V4L2_PIX_FMT_UYVY: /* Mac default format */
-        UYVYToYUV420(frame_pixels, video_buf, frame_width, frame_height);
-        break;
-    default:
-        ERR("Cannot convert the pixel format (%.4s)...\n",
-               (const char *)&pixel_format);
-        break;
-    }
-}
-
-static void UYVYToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
-                         int width, int height)
-{
-    int i, j;
-
-    /* Source */
-    unsigned char *ptrsrcy1, *ptrsrcy2;
-    unsigned char *ptrsrcy3, *ptrsrcy4;
-    unsigned char *ptrsrccb1;
-    unsigned char *ptrsrccb3;
-    unsigned char *ptrsrccr1;
-    unsigned char *ptrsrccr3;
-    int srcystride, srcccstride;
-
-    ptrsrcy1  = bufsrc + 1;
-    ptrsrcy2  = bufsrc + (width << 1) + 1;
-    ptrsrcy3  = bufsrc + (width << 1) * 2 + 1;
-    ptrsrcy4  = bufsrc + (width << 1) * 3 + 1;
-
-    ptrsrccb1 = bufsrc;
-    ptrsrccb3 = bufsrc + (width << 1) * 2;
-
-    ptrsrccr1 = bufsrc + 2;
-    ptrsrccr3 = bufsrc + (width << 1) * 2 + 2;
-
-    srcystride  = (width << 1) * 3;
-    srcccstride = (width << 1) * 3;
-
-    /* Destination */
-    unsigned char *ptrdesty1, *ptrdesty2;
-    unsigned char *ptrdesty3, *ptrdesty4;
-    unsigned char *ptrdestcb1, *ptrdestcb2;
-    unsigned char *ptrdestcr1, *ptrdestcr2;
-    int destystride, destccstride;
-
-    ptrdesty1 = bufdest;
-    ptrdesty2 = bufdest + width;
-    ptrdesty3 = bufdest + width * 2;
-    ptrdesty4 = bufdest + width * 3;
-
-    ptrdestcb1 = bufdest + width * height;
-    ptrdestcb2 = bufdest + width * height + (width >> 1);
-
-    ptrdestcr1 = bufdest + width * height + ((width*height) >> 2);
-    ptrdestcr2 = bufdest + width * height + ((width*height) >> 2)
-                 + (width >> 1);
-
-    destystride  = (width)*3;
-    destccstride = (width>>1);
-
-    for (j = 0; j < (height / 4); j++) {
-        for (i = 0; i < (width / 2); i++) {
-            (*ptrdesty1++) = (*ptrsrcy1);
-            (*ptrdesty2++) = (*ptrsrcy2);
-            (*ptrdesty3++) = (*ptrsrcy3);
-            (*ptrdesty4++) = (*ptrsrcy4);
-
-            ptrsrcy1 += 2;
-            ptrsrcy2 += 2;
-            ptrsrcy3 += 2;
-            ptrsrcy4 += 2;
-
-            (*ptrdesty1++) = (*ptrsrcy1);
-            (*ptrdesty2++) = (*ptrsrcy2);
-            (*ptrdesty3++) = (*ptrsrcy3);
-            (*ptrdesty4++) = (*ptrsrcy4);
-
-            ptrsrcy1 += 2;
-            ptrsrcy2 += 2;
-            ptrsrcy3 += 2;
-            ptrsrcy4 += 2;
-
-            (*ptrdestcb1++) = (*ptrsrccb1);
-            (*ptrdestcb2++) = (*ptrsrccb3);
-
-            ptrsrccb1 += 4;
-            ptrsrccb3 += 4;
-
-            (*ptrdestcr1++) = (*ptrsrccr1);
-            (*ptrdestcr2++) = (*ptrsrccr3);
-
-            ptrsrccr1 += 4;
-            ptrsrccr3 += 4;
-
-        }
-
-        /* Update src pointers */
-        ptrsrcy1  += srcystride;
-        ptrsrcy2  += srcystride;
-        ptrsrcy3  += srcystride;
-        ptrsrcy4  += srcystride;
-
-        ptrsrccb1 += srcccstride;
-        ptrsrccb3 += srcccstride;
-
-        ptrsrccr1 += srcccstride;
-        ptrsrccr3 += srcccstride;
-
-        /* Update dest pointers */
-        ptrdesty1 += destystride;
-        ptrdesty2 += destystride;
-        ptrdesty3 += destystride;
-        ptrdesty4 += destystride;
-
-        ptrdestcb1 += destccstride;
-        ptrdestcb2 += destccstride;
-
-        ptrdestcr1 += destccstride;
-        ptrdestcr2 += destccstride;
-    }
-}
-
-static void YVU420ToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
-                           int width, int height)
-{
-    int i, j;
-
-    /* Source*/
-    unsigned char *ptrsrcy1, *ptrsrcy2;
-    unsigned char *ptrsrcy3, *ptrsrcy4;
-    unsigned char *ptrsrccb1, *ptrsrccb2;
-    unsigned char *ptrsrccr1, *ptrsrccr2;
-    int srcystride, srcccstride;
-
-    ptrsrcy1 = bufsrc;
-    ptrsrcy2 = bufsrc + width;
-    ptrsrcy3 = bufsrc + width*2;
-    ptrsrcy4 = bufsrc + width*3;
-
-    ptrsrccr1 = bufsrc + width*height;
-    ptrsrccr2 = bufsrc + width*height + (width>>1);
-
-    ptrsrccb1 = bufsrc + width*height + ((width*height) >> 2);
-    ptrsrccb2 = bufsrc + width*height + ((width*height) >> 2) + (width>>1);
-
-    srcystride  = (width)*3;
-    srcccstride = (width>>1);
-
-    /* Destination */
-    unsigned char *ptrdesty1, *ptrdesty2;
-    unsigned char *ptrdesty3, *ptrdesty4;
-    unsigned char *ptrdestcb1, *ptrdestcb2;
-    unsigned char *ptrdestcr1, *ptrdestcr2;
-    int destystride, destccstride;
-
-    ptrdesty1 = bufdest;
-    ptrdesty2 = bufdest + width;
-    ptrdesty3 = bufdest + width * 2;
-    ptrdesty4 = bufdest + width * 3;
-
-    ptrdestcb1 = bufdest + width * height;
-    ptrdestcb2 = bufdest + width * height + (width >> 1);
-
-    ptrdestcr1 = bufdest + width * height + ((width*height) >> 2);
-    ptrdestcr2 = bufdest + width * height + ((width*height) >> 2)
-                 + (width >> 1);
-
-    destystride  = (width)*3;
-    destccstride = (width>>1);
-
-    for (j = 0; j < (height / 4); j++) {
-        for (i = 0; i < (width / 2); i++) {
-
-            (*ptrdesty1++) = (*ptrsrcy1++);
-            (*ptrdesty2++) = (*ptrsrcy2++);
-            (*ptrdesty3++) = (*ptrsrcy3++);
-            (*ptrdesty4++) = (*ptrsrcy4++);
-            (*ptrdesty1++) = (*ptrsrcy1++);
-            (*ptrdesty2++) = (*ptrsrcy2++);
-            (*ptrdesty3++) = (*ptrsrcy3++);
-            (*ptrdesty4++) = (*ptrsrcy4++);
-
-            (*ptrdestcb1++) = (*ptrsrccb1++);
-            (*ptrdestcr1++) = (*ptrsrccr1++);
-            (*ptrdestcb2++) = (*ptrsrccb2++);
-            (*ptrdestcr2++) = (*ptrsrccr2++);
-
-        }
-
-        /* Update src pointers */
-        ptrsrcy1  += srcystride;
-        ptrsrcy2  += srcystride;
-        ptrsrcy3  += srcystride;
-        ptrsrcy4  += srcystride;
-
-        ptrsrccb1 += srcccstride;
-        ptrsrccb2 += srcccstride;
-
-        ptrsrccr1 += srcccstride;
-        ptrsrccr2 += srcccstride;
-
-        /* Update dest pointers */
-        ptrdesty1 += destystride;
-        ptrdesty2 += destystride;
-        ptrdesty3 += destystride;
-        ptrdesty4 += destystride;
-
-        ptrdestcb1 += destccstride;
-        ptrdestcb2 += destccstride;
-
-        ptrdestcr1 += destccstride;
-        ptrdestcr2 += destccstride;
-
-    }
-
-}
-
-static void YUYVToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
-                         int width, int height)
-{
-    int i, j;
-
-    /* Source*/
-    unsigned char *ptrsrcy1, *ptrsrcy2;
-    unsigned char *ptrsrcy3, *ptrsrcy4;
-    unsigned char *ptrsrccb1;
-    unsigned char *ptrsrccb3;
-    unsigned char *ptrsrccr1;
-    unsigned char *ptrsrccr3;
-    int srcystride, srcccstride;
-
-    ptrsrcy1  = bufsrc ;
-    ptrsrcy2  = bufsrc + (width << 1);
-    ptrsrcy3  = bufsrc + (width << 1) * 2;
-    ptrsrcy4  = bufsrc + (width << 1) * 3;
-
-    ptrsrccb1 = bufsrc + 1;
-    ptrsrccb3 = bufsrc + (width << 1) * 2 + 1;
-
-    ptrsrccr1 = bufsrc + 3;
-    ptrsrccr3 = bufsrc + (width << 1) * 2 + 3;
-
-    srcystride  = (width << 1) * 3;
-    srcccstride = (width << 1) * 3;
-
-    /* Destination */
-    unsigned char *ptrdesty1, *ptrdesty2;
-    unsigned char *ptrdesty3, *ptrdesty4;
-    unsigned char *ptrdestcb1, *ptrdestcb2;
-    unsigned char *ptrdestcr1, *ptrdestcr2;
-    int destystride, destccstride;
-
-    ptrdesty1 = bufdest;
-    ptrdesty2 = bufdest + width;
-    ptrdesty3 = bufdest + width * 2;
-    ptrdesty4 = bufdest + width * 3;
-
-    ptrdestcb1 = bufdest + width * height;
-    ptrdestcb2 = bufdest + width * height + (width >> 1);
-
-    ptrdestcr1 = bufdest + width * height + ((width * height) >> 2);
-    ptrdestcr2 = bufdest + width * height + ((width * height) >> 2)
-                 + (width >> 1);
-
-    destystride  = width * 3;
-    destccstride = (width >> 1);
-
-    for (j = 0; j < (height / 4); j++) {
-        for (i = 0; i < (width / 2); i++) {
-            (*ptrdesty1++) = (*ptrsrcy1);
-            (*ptrdesty2++) = (*ptrsrcy2);
-            (*ptrdesty3++) = (*ptrsrcy3);
-            (*ptrdesty4++) = (*ptrsrcy4);
-
-            ptrsrcy1 += 2;
-            ptrsrcy2 += 2;
-            ptrsrcy3 += 2;
-            ptrsrcy4 += 2;
-
-            (*ptrdesty1++) = (*ptrsrcy1);
-            (*ptrdesty2++) = (*ptrsrcy2);
-            (*ptrdesty3++) = (*ptrsrcy3);
-            (*ptrdesty4++) = (*ptrsrcy4);
-
-            ptrsrcy1 += 2;
-            ptrsrcy2 += 2;
-            ptrsrcy3 += 2;
-            ptrsrcy4 += 2;
-
-            (*ptrdestcb1++) = (*ptrsrccb1);
-            (*ptrdestcb2++) = (*ptrsrccb3);
-
-            ptrsrccb1 += 4;
-            ptrsrccb3 += 4;
-
-            (*ptrdestcr1++) = (*ptrsrccr1);
-            (*ptrdestcr2++) = (*ptrsrccr3);
-
-            ptrsrccr1 += 4;
-            ptrsrccr3 += 4;
-
-        }
-
-        /* Update src pointers */
-        ptrsrcy1  += srcystride;
-        ptrsrcy2  += srcystride;
-        ptrsrcy3  += srcystride;
-        ptrsrcy4  += srcystride;
-
-        ptrsrccb1 += srcccstride;
-        ptrsrccb3 += srcccstride;
-
-        ptrsrccr1 += srcccstride;
-        ptrsrccr3 += srcccstride;
-
-        /* Update dest pointers */
-        ptrdesty1 += destystride;
-        ptrdesty2 += destystride;
-        ptrdesty3 += destystride;
-        ptrdesty4 += destystride;
-
-        ptrdestcb1 += destccstride;
-        ptrdestcb2 += destccstride;
-
-        ptrdestcr1 += destccstride;
-        ptrdestcr2 += destccstride;
-    }
-}
diff --git a/tizen/src/hw/maru_camera_darwin_pci.m b/tizen/src/hw/maru_camera_darwin_pci.m
deleted file mode 100644 (file)
index d90b490..0000000
+++ /dev/null
@@ -1,909 +0,0 @@
-/*
- * Implementation of MARU Virtual Camera device by PCI bus on MacOS.
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- * Jun Tian <jun.j.tian@intel.com>
- * JinHyung Jo <jinhyung.jo@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
- *
- */
-
-#import <Cocoa/Cocoa.h>
-#import <QTKit/QTKit.h>
-#import <CoreAudio/CoreAudio.h>
-
-#include <pthread.h>
-#include "qemu-common.h"
-#include "maru_camera_common.h"
-#include "maru_camera_darwin.h"
-#include "debug_ch.h"
-
-MULTI_DEBUG_CHANNEL(tizen, maru-camera);
-
-#define MARUCAM_THREAD_NAME    "marucam_worker_thread"
-
-/* V4L2 defines copy from videodev2.h */
-#define V4L2_CTRL_FLAG_SLIDER       0x0020
-
-#define V4L2_CTRL_CLASS_USER        0x00980000
-#define V4L2_CID_BASE               (V4L2_CTRL_CLASS_USER | 0x900)
-#define V4L2_CID_BRIGHTNESS         (V4L2_CID_BASE + 0)
-#define V4L2_CID_CONTRAST           (V4L2_CID_BASE + 1)
-#define V4L2_CID_SATURATION         (V4L2_CID_BASE + 2)
-#define V4L2_CID_SHARPNESS          (V4L2_CID_BASE + 27)
-
-typedef struct tagMaruCamConvertPixfmt {
-    uint32_t fmt;   /* fourcc */
-    uint32_t bpp;   /* bits per pixel, 0 for compressed formats */
-    uint32_t needs_conversion;
-} MaruCamConvertPixfmt;
-
-
-static MaruCamConvertPixfmt supported_dst_pixfmts[] = {
-    { V4L2_PIX_FMT_YUYV, 16, 0 },
-    { V4L2_PIX_FMT_UYVY, 16, 0 },
-    { V4L2_PIX_FMT_YUV420, 12, 0 },
-    { V4L2_PIX_FMT_YVU420, 12, 0 },
-};
-
-typedef struct tagMaruCamConvertFrameInfo {
-    uint32_t width;
-    uint32_t height;
-} MaruCamConvertFrameInfo;
-
-static MaruCamConvertFrameInfo supported_dst_frames[] = {
-    { 640, 480 },
-    { 352, 288 },
-    { 320, 240 },
-    { 176, 144 },
-    { 160, 120 },
-};
-
-#define MARUCAM_CTRL_VALUE_MAX      20
-#define MARUCAM_CTRL_VALUE_MIN      1
-#define MARUCAM_CTRL_VALUE_MID      10
-#define MARUCAM_CTRL_VALUE_STEP     1
-
-enum {
-    _MC_THREAD_PAUSED,
-    _MC_THREAD_STREAMON,
-    _MC_THREAD_STREAMOFF,
-};
-
-#if 0
-struct marucam_qctrl {
-    uint32_t id;
-    uint32_t hit;
-    long min;
-    long max;
-    long step;
-    long init_val;
-};
-
-static struct marucam_qctrl qctrl_tbl[] = {
-    { V4L2_CID_BRIGHTNESS, 0, },
-    { V4L2_CID_CONTRAST, 0, },
-    { V4L2_CID_SATURATION, 0, },
-    { V4L2_CID_SHARPNESS, 0, },
-};
-#endif
-
-static MaruCamState *g_state;
-
-static uint32_t ready_count;
-static uint32_t cur_fmt_idx;
-static uint32_t cur_frame_idx;
-
-/***********************************
- * Mac camera helper functions
- ***********************************/
-
-/* Convert Core Video format to FOURCC */
-static uint32_t corevideo_to_fourcc(uint32_t cv_pix_fmt)
-{
-    switch (cv_pix_fmt) {
-    case kCVPixelFormatType_420YpCbCr8Planar:
-        return V4L2_PIX_FMT_YVU420;
-    case kCVPixelFormatType_422YpCbCr8:
-        return V4L2_PIX_FMT_UYVY;
-    case kCVPixelFormatType_422YpCbCr8_yuvs:
-        return V4L2_PIX_FMT_YUYV;
-    case kCVPixelFormatType_32ARGB:
-    case kCVPixelFormatType_32RGBA:
-        return V4L2_PIX_FMT_RGB32;
-    case kCVPixelFormatType_32BGRA:
-    case kCVPixelFormatType_32ABGR:
-        return V4L2_PIX_FMT_BGR32;
-    case kCVPixelFormatType_24RGB:
-        return V4L2_PIX_FMT_RGB24;
-    case kCVPixelFormatType_24BGR:
-        return V4L2_PIX_FMT_BGR32;
-    default:
-        ERR("Unknown pixel format '%.4s'", (const char *)&cv_pix_fmt);
-        return 0;
-    }
-}
-
-static uint32_t get_bytesperline(uint32_t pixfmt, uint32_t width)
-{
-    uint32_t bytesperline;
-
-    switch (pixfmt) {
-    case V4L2_PIX_FMT_YUV420:
-    case V4L2_PIX_FMT_YVU420:
-        bytesperline = (width * 12) >> 3;
-        break;
-    case V4L2_PIX_FMT_YUYV:
-    case V4L2_PIX_FMT_UYVY:
-    default:
-        bytesperline = width * 2;
-        break;
-    }
-
-    return bytesperline;
-}
-
-static uint32_t get_sizeimage(uint32_t pixfmt, uint32_t width, uint32_t height)
-{
-    return get_bytesperline(pixfmt, width) * height;
-}
-
-/******************************************************************
- **   Maru Camera Implementation
- *****************************************************************/
-
-@interface MaruCameraDriver : NSObject {
-    QTCaptureSession               *mCaptureSession;
-    QTCaptureDeviceInput           *mCaptureVideoDeviceInput;
-    QTCaptureVideoPreviewOutput    *mCaptureVideoPreviewOutput;
-
-    CVImageBufferRef               mCurrentImageBuffer;
-    BOOL mDeviceIsOpened;
-    BOOL mCaptureIsStarted;
-}
-
-- (MaruCameraDriver *)init;
-- (int)startCapture:(int)width:(int)height;
-- (void)stopCapture;
-- (int)readFrame:(void *)video_buf;
-- (int)setCaptureFormat:(int)width:(int)height:(int)pix_format;
-- (int)getCaptureFormat:(int)width:(int)height:(int)pix_format;
-- (BOOL)deviceStatus;
-
-@end
-
-@implementation MaruCameraDriver
-
-- (MaruCameraDriver *)init
-{
-    BOOL success = NO;
-    NSError *error;
-    mDeviceIsOpened = NO;
-    mCaptureIsStarted = NO;
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
-    /* Create the capture session */
-    mCaptureSession = [[QTCaptureSession alloc] init];
-
-    /* Find a video device */
-    QTCaptureDevice *videoDevice = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeVideo];
-    success = [videoDevice open:&error];
-
-    /* If a video input device can't be found or opened, try to find and open a muxed input device */
-    if (!success) {
-        videoDevice = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeMuxed];
-        success = [videoDevice open:&error];
-        [pool release];
-        return nil;
-    }
-
-    if (!success) {
-        videoDevice = nil;
-        [pool release];
-        return nil;
-    }
-
-    if (videoDevice) {
-        /* Add the video device to the session as a device input */
-        mCaptureVideoDeviceInput = [[QTCaptureDeviceInput alloc] initWithDevice:videoDevice];
-        success = [mCaptureSession addInput:mCaptureVideoDeviceInput error:&error];
-
-        if (!success) {
-            [pool release];
-            return nil;
-        }
-
-        mCaptureVideoPreviewOutput = [[QTCaptureVideoPreviewOutput alloc] init];
-        success = [mCaptureSession addOutput:mCaptureVideoPreviewOutput error:&error];
-        if (!success) {
-            [pool release];
-            return nil;
-        }
-
-        mDeviceIsOpened = YES;
-        [mCaptureVideoPreviewOutput setDelegate:self];
-        INFO("Camera session bundling successfully!\n");
-        [pool release];
-        return self;
-    } else {
-        [pool release];
-        return nil;
-    }
-}
-
-- (int)startCapture:(int)width:(int)height
-{
-    int ret = -1;
-
-    if (![mCaptureSession isRunning]) {
-        /* Set width & height, using default pixel format to capture */
-        NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
-                                                      [NSNumber numberWithInt: width], (id)kCVPixelBufferWidthKey,
-                                                      [NSNumber numberWithInt: height], (id)kCVPixelBufferHeightKey,
-                                                 nil];
-        [mCaptureVideoPreviewOutput setPixelBufferAttributes:attributes];
-        [mCaptureSession startRunning];
-    } else {
-        ERR("Capture session is already running, exit\n");
-        return ret;
-    }
-
-    if ([mCaptureSession isRunning]) {
-        while(!mCaptureIsStarted) {
-            /* Wait Until Capture is started */
-            [[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.5]];
-        }
-        ret = 0;
-    }
-    return ret;
-}
-
-- (void)stopCapture
-{
-    if ([mCaptureSession isRunning]) {
-        [mCaptureSession stopRunning];
-        while([mCaptureSession isRunning]) {
-            /* Wait Until Capture is stopped */
-            [[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.1]];
-        }
-
-    }
-    mCaptureIsStarted = NO;
-}
-
-- (int)readFrame:(void *)video_buf
-{
-    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
-
-    @synchronized (self) {
-        if (mCaptureIsStarted == NO) {
-            [pool release];
-            return 0;
-        }
-        if (mCurrentImageBuffer != nil) {
-            CVPixelBufferLockBaseAddress(mCurrentImageBuffer, 0);
-            const uint32_t pixel_format = corevideo_to_fourcc(CVPixelBufferGetPixelFormatType(mCurrentImageBuffer));
-            const int frame_width = CVPixelBufferGetWidth(mCurrentImageBuffer);
-            const int frame_height = CVPixelBufferGetHeight(mCurrentImageBuffer);
-            const size_t frame_size = CVPixelBufferGetBytesPerRow(mCurrentImageBuffer) * frame_height;
-            const void *frame_pixels = CVPixelBufferGetBaseAddress(mCurrentImageBuffer);
-
-            TRACE("buffer(%p), pixel_format(%d,%.4s), frame_width(%d), "
-                  "frame_height(%d), frame_size(%d)\n",
-                  mCurrentImageBuffer, (int)pixel_format,
-                  (const char *)&pixel_format, frame_width,
-                  frame_height, (int)frame_size);
-
-            /* convert frame to v4l2 format */
-            convert_frame(pixel_format, frame_width, frame_height,
-                          frame_size, (void *)frame_pixels, video_buf);
-            CVPixelBufferUnlockBaseAddress(mCurrentImageBuffer, 0);
-            [pool release];
-            return 1;
-        }
-    }
-
-    [pool release];
-    return -1;
-}
-
-- (int)setCaptureFormat:(int)width:(int)height:(int)pix_format
-{
-    int ret = -1;
-    NSDictionary *attributes;
-
-    if (mCaptureSession == nil || mCaptureVideoPreviewOutput == nil) {
-        ERR("Capture session is not initiated.\n");
-        return ret;
-    }
-
-    /* Set the pixel buffer attributes before running the capture session */
-    if (![mCaptureSession isRunning]) {
-        if (pix_format) {
-            attributes = [NSDictionary dictionaryWithObjectsAndKeys:
-                                            [NSNumber numberWithInt: width], (id)kCVPixelBufferWidthKey,
-                                            [NSNumber numberWithInt: height], (id)kCVPixelBufferHeightKey,
-                                            [NSNumber numberWithInt: pix_format], (id)kCVPixelBufferPixelFormatTypeKey,
-                                       nil];
-        } else {
-            attributes = [NSDictionary dictionaryWithObjectsAndKeys:
-                                            [NSNumber numberWithInt: width], (id)kCVPixelBufferWidthKey,
-                                            [NSNumber numberWithInt: height], (id)kCVPixelBufferHeightKey,
-                                       nil];
-        }
-        [mCaptureVideoPreviewOutput setPixelBufferAttributes:attributes];
-        ret = 0;
-    } else {
-        ERR("Cannot set pixel buffer attributes when it's running.\n");
-        return ret;
-    }
-
-    return ret;
-}
-
-- (int)getCaptureFormat:(int)width:(int)height:(int)pix_format
-{
-    return 0;
-}
-
-/* Get the device bundling status */
-- (BOOL)deviceStatus
-{
-    return mDeviceIsOpened;
-}
-
-/* Handle deallocation of memory for your capture objects */
-
-- (void)dealloc
-{
-    [mCaptureSession release];
-    [mCaptureVideoDeviceInput release];
-    [mCaptureVideoPreviewOutput release];
-    [super dealloc];
-}
-
-/* Receive this method whenever the output decompresses and outputs a new video frame */
-- (void)captureOutput:(QTCaptureOutput *)captureOutput didOutputVideoFrame:(CVImageBufferRef)videoFrame
-     withSampleBuffer:(QTSampleBuffer *)sampleBuffer fromConnection:(QTCaptureConnection *)connection
-{
-    CVImageBufferRef imageBufferToRelease;
-    CVBufferRetain(videoFrame);
-
-    @synchronized (self)
-    {
-        imageBufferToRelease = mCurrentImageBuffer;
-        mCurrentImageBuffer = videoFrame;
-        mCaptureIsStarted = YES;
-    }
-    CVBufferRelease(imageBufferToRelease);
-}
-
-@end
-
-/******************************************************************
- **   Maru Camera APIs
- *****************************************************************/
-
-typedef struct MaruCameraDevice MaruCameraDevice;
-struct MaruCameraDevice {
-    /* Maru camera device object. */
-    MaruCameraDriver *driver;
-};
-
-/* Golbal representation of the Maru camera */
-MaruCameraDevice *mcd = NULL;
-
-static int is_streamon()
-{
-    int st;
-    qemu_mutex_lock(&g_state->thread_mutex);
-    st = g_state->streamon;
-    qemu_mutex_unlock(&g_state->thread_mutex);
-    return (st == _MC_THREAD_STREAMON);
-}
-
-static void __raise_err_intr()
-{
-    qemu_mutex_lock(&g_state->thread_mutex);
-    if (g_state->streamon == _MC_THREAD_STREAMON) {
-        g_state->req_frame = 0; /* clear request */
-        g_state->isr = 0x08;   /* set a error flag of rasing a interrupt */
-        qemu_bh_schedule(g_state->tx_bh);
-    }
-    qemu_mutex_unlock(&g_state->thread_mutex);
-}
-
-static int marucam_device_read_frame()
-{
-    int ret;
-    void *tmp_buf;
-
-    qemu_mutex_lock(&g_state->thread_mutex);
-    if (g_state->streamon == _MC_THREAD_STREAMON) {
-#if 0
-        if (ready_count < MARUCAM_SKIPFRAMES) {
-            /* skip a frame cause first some frame are distorted */
-            ++ready_count;
-            TRACE("Skip %d frame\n", ready_count);
-            qemu_mutex_unlock(&g_state->thread_mutex);
-            return 0;
-        }
-#endif
-        if (g_state->req_frame == 0) {
-            TRACE("There is no request\n");
-            qemu_mutex_unlock(&g_state->thread_mutex);
-            return 0;
-        }
-
-        /* Grab the camera frame into temp buffer */
-        tmp_buf = g_state->vaddr + g_state->buf_size * (g_state->req_frame - 1);
-        ret =  [mcd->driver readFrame: tmp_buf];
-        if (ret < 0) {
-            ERR("%s, Capture error\n", __func__);
-            qemu_mutex_unlock(&g_state->thread_mutex);
-            __raise_err_intr();
-            return -1;
-        } else if (!ret) {
-            qemu_mutex_unlock(&g_state->thread_mutex);
-            return 0;
-        }
-
-        g_state->req_frame = 0; /* clear request */
-        g_state->isr |= 0x01;   /* set a flag of rasing a interrupt */
-        qemu_bh_schedule(g_state->tx_bh);
-    } else {
-        qemu_mutex_unlock(&g_state->thread_mutex);
-        return -1;
-    }
-    qemu_mutex_unlock(&g_state->thread_mutex);
-    return 0;
-}
-
-/* Worker thread to grab frames to the preview window */
-static void *marucam_worker_thread(void *thread_param)
-{
-    while (1) {
-        qemu_mutex_lock(&g_state->thread_mutex);
-        g_state->streamon = _MC_THREAD_PAUSED;
-        qemu_cond_wait(&g_state->thread_cond, &g_state->thread_mutex);
-        qemu_mutex_unlock(&g_state->thread_mutex);
-
-        if (g_state->destroying) {
-            break;
-        }
-
-        ready_count = 0;
-        qemu_mutex_lock(&g_state->thread_mutex);
-        g_state->streamon = _MC_THREAD_STREAMON;
-        qemu_mutex_unlock(&g_state->thread_mutex);
-        INFO("Streaming on ......\n");
-
-        /* Loop: capture frame -> convert format -> render to screen */
-        while (1) {
-            if (is_streamon()) {
-                if (marucam_device_read_frame() < 0) {
-                    INFO("Streaming is off ...\n");
-                    break;
-                } else {
-                    /* wait until next frame is avalilable */
-                    usleep(22000);
-                }
-            } else {
-                INFO("Streaming is off ...\n");
-                break;
-            }
-        }
-    }
-
-    return NULL;
-}
-
-int marucam_device_check(int log_flag)
-{
-    /* FIXME: check the device parameters */
-    INFO("Checking camera device\n");
-    return 1;
-}
-
-/**********************************************
- * MARU camera routines
- **********************************************/
-void marucam_device_init(MaruCamState *state)
-{
-    g_state = state;
-    g_state->destroying = false;
-    qemu_thread_create(&state->thread_id,
-                       MARUCAM_THREAD_NAME,
-                       marucam_worker_thread,
-                       NULL,
-                       QEMU_THREAD_JOINABLE);
-}
-
-void marucam_device_exit(MaruCamState *state)
-{
-    state->destroying = true;
-    qemu_mutex_lock(&state->thread_mutex);
-    qemu_cond_signal(&state->thread_cond);
-    qemu_mutex_unlock(&state->thread_mutex);
-    qemu_thread_join(&state->thread_id);
-}
-
-/* MARUCAM_CMD_OPEN */
-void marucam_device_open(MaruCamState *state)
-{
-    MaruCamParam *param = state->param;
-    param->top = 0;
-
-    mcd = (MaruCameraDevice *)malloc(sizeof(MaruCameraDevice));
-    if (mcd == NULL) {
-        ERR("%s: MaruCameraDevice allocate failed\n", __func__);
-        param->errCode = EINVAL;
-        return;
-    }
-    memset(mcd, 0, sizeof(MaruCameraDevice));
-    mcd->driver = [[MaruCameraDriver alloc] init];
-    if (mcd->driver == nil) {
-        ERR("Camera device open failed\n");
-        [mcd->driver dealloc];
-        free(mcd);
-        param->errCode = EINVAL;
-        return;
-    }
-    INFO("Camera opened!\n");
-}
-
-/* MARUCAM_CMD_CLOSE */
-void marucam_device_close(MaruCamState *state)
-{
-    MaruCamParam *param = state->param;
-    param->top = 0;
-
-    if (mcd != NULL) {
-        if (is_streamon()) {
-            marucam_device_stop_preview(state);
-        }
-        [mcd->driver dealloc];
-        free(mcd);
-        mcd = NULL;
-    }
-
-    /* marucam_reset_controls(); */
-    INFO("Camera closed\n");
-}
-
-/* MARUCAM_CMD_START_PREVIEW */
-void marucam_device_start_preview(MaruCamState *state)
-{
-    uint32_t width, height, pixfmt;
-    MaruCamParam *param = state->param;
-    param->top = 0;
-
-    width = supported_dst_frames[cur_frame_idx].width;
-    height = supported_dst_frames[cur_frame_idx].height;
-    pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
-    state->buf_size = get_sizeimage(pixfmt, width, height);
-
-    INFO("Pixfmt(%c%c%c%c), W:H(%d:%d), buf size(%u), frame idx(%d), fmt idx(%d)\n",
-      (char)(pixfmt), (char)(pixfmt >> 8),
-      (char)(pixfmt >> 16), (char)(pixfmt >> 24),
-      width, height, state->buf_size,
-      cur_frame_idx, cur_fmt_idx);
-
-    if (mcd->driver == nil) {
-        ERR("%s: Start capture failed: vaild device", __func__);
-        param->errCode = EINVAL;
-        return;
-    }
-    
-    INFO("Starting preview ...\n");
-    [mcd->driver startCapture: width: height];
-
-    /* Enable the condition to capture frames now */
-    qemu_mutex_lock(&state->thread_mutex);
-    qemu_cond_signal(&state->thread_cond);
-    qemu_mutex_unlock(&state->thread_mutex);
-
-    while (!is_streamon()) {
-        usleep(10000);
-    }
-}
-
-/* MARUCAM_CMD_STOP_PREVIEW */
-void marucam_device_stop_preview(MaruCamState *state)
-{
-    MaruCamParam *param = state->param;
-    param->top = 0;
-
-    if (is_streamon()) {
-        qemu_mutex_lock(&state->thread_mutex);
-        state->streamon = _MC_THREAD_STREAMOFF;
-        qemu_mutex_unlock(&state->thread_mutex);
-
-        while (is_streamon()) {
-            usleep(10000);
-        }
-    }
-
-    if (mcd->driver != nil) {
-        [mcd->driver stopCapture];
-    }
-
-    state->buf_size = 0;
-    INFO("Stopping preview ...\n");
-}
-
-/* MARUCAM_CMD_S_PARAM */
-void marucam_device_s_param(MaruCamState *state)
-{
-    MaruCamParam *param = state->param;
-
-    /* We use default FPS of the webcam */
-    param->top = 0;
-}
-
-/* MARUCAM_CMD_G_PARAM */
-void marucam_device_g_param(MaruCamState *state)
-{
-    MaruCamParam *param = state->param;
-    /* We use default FPS of the webcam
-     * return a fixed value on guest ini file (1/30).
-     */
-    param->top = 0;
-    param->stack[0] = 0x1000; /* V4L2_CAP_TIMEPERFRAME */
-    param->stack[1] = 1; /* numerator */
-    param->stack[2] = 30; /* denominator */
-}
-
-/* MARUCAM_CMD_S_FMT */
-void marucam_device_s_fmt(MaruCamState *state)
-{
-    MaruCamParam *param = state->param;
-    uint32_t width, height, pixfmt, pidx, fidx;
-
-    param->top = 0;
-    width = param->stack[0];
-    height = param->stack[1];
-    pixfmt = param->stack[2];
-
-    TRACE("Set format: width(%d), height(%d), pixfmt(%d, %.4s)\n",
-         width, height, pixfmt, (const char*)&pixfmt);
-
-    for (fidx = 0; fidx < ARRAY_SIZE(supported_dst_frames); fidx++) {
-        if ((supported_dst_frames[fidx].width == width) &&
-            (supported_dst_frames[fidx].height == height)) {
-            break;
-        }
-    }
-    if (fidx == ARRAY_SIZE(supported_dst_frames)) {
-        param->errCode = EINVAL;
-        return;
-    }
-
-    for (pidx = 0; pidx < ARRAY_SIZE(supported_dst_pixfmts); pidx++) {
-        if (supported_dst_pixfmts[pidx].fmt == pixfmt) {
-            TRACE("pixfmt index is match: %d\n", pidx);
-            break;
-        }
-    }
-    if (pidx == ARRAY_SIZE(supported_dst_pixfmts)) {
-        param->errCode = EINVAL;
-        return;
-    }
-
-    if ((supported_dst_frames[cur_frame_idx].width != width) &&
-        (supported_dst_frames[cur_frame_idx].height != height)) {
-        if (mcd->driver == nil || [mcd->driver setCaptureFormat: width: height: 0] < 0) {
-            ERR("Set pixel format failed\n");
-            param->errCode = EINVAL;
-            return;
-        }
-
-        TRACE("cur_frame_idx:%d, supported_dst_frames[cur_frame_idx].width:%d\n",
-             cur_frame_idx, supported_dst_frames[cur_frame_idx].width);
-    }
-
-    cur_frame_idx = fidx;
-    cur_fmt_idx = pidx;
-
-    pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
-    width = supported_dst_frames[cur_frame_idx].width;
-    height = supported_dst_frames[cur_frame_idx].height;
-
-    param->stack[0] = width;
-    param->stack[1] = height;
-    param->stack[2] = 1; /* V4L2_FIELD_NONE */
-    param->stack[3] = pixfmt;
-    param->stack[4] = get_bytesperline(pixfmt, width);
-    param->stack[5] = get_sizeimage(pixfmt, width, height);
-    param->stack[6] = 0;
-    param->stack[7] = 0;
-
-    TRACE("Set device pixel format ...\n");
-}
-
-/* MARUCAM_CMD_G_FMT */
-void marucam_device_g_fmt(MaruCamState *state)
-{
-    uint32_t width, height, pixfmt;
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
-    width = supported_dst_frames[cur_frame_idx].width;
-    height = supported_dst_frames[cur_frame_idx].height;
-
-    param->stack[0] = width;
-    param->stack[1] = height;
-    param->stack[2] = 1; /* V4L2_FIELD_NONE */
-    param->stack[3] = pixfmt;
-    param->stack[4] = get_bytesperline(pixfmt, width);
-    param->stack[5] = get_sizeimage(pixfmt, width, height);
-    param->stack[6] = 0;
-    param->stack[7] = 0;
-
-    TRACE("Get device frame format ...\n");
-}
-
-void marucam_device_try_fmt(MaruCamState *state)
-{
-    TRACE("Try device frame format, use default setting ...\n");
-}
-
-/* Get specific pixelformat description */
-void marucam_device_enum_fmt(MaruCamState *state)
-{
-    uint32_t index;
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    index = param->stack[0];
-
-    if (index >= ARRAY_SIZE(supported_dst_pixfmts)) {
-        param->errCode = EINVAL;
-        return;
-    }
-    param->stack[1] = 0; /* flags = NONE */
-    param->stack[2] = supported_dst_pixfmts[index].fmt; /* pixelformat */
-    switch (supported_dst_pixfmts[index].fmt) {
-    case V4L2_PIX_FMT_YUYV:
-        memcpy(&param->stack[3], "YUYV", 32);
-        break;
-    case V4L2_PIX_FMT_UYVY:
-        memcpy(&param->stack[3], "UYVY", 32);
-        break;
-    case V4L2_PIX_FMT_YUV420:
-        memcpy(&param->stack[3], "YU12", 32);
-        break;
-    case V4L2_PIX_FMT_YVU420:
-        memcpy(&param->stack[3], "YV12", 32);
-        break;
-    default:
-        param->errCode = EINVAL;
-        break;
-    }
-}
-
-/*
- * QTKit don't support setting brightness, contrast, saturation & sharpness
- */
-void marucam_device_qctrl(MaruCamState *state)
-{
-    uint32_t id, i;
-    /* long property, min, max, step, def_val, set_val; */
-    char name[32] = {0,};
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    id = param->stack[0];
-
-    switch (id) {
-    case V4L2_CID_BRIGHTNESS:
-        TRACE("V4L2_CID_BRIGHTNESS\n");
-        memcpy((void *)name, (void *)"brightness", 32);
-        i = 0;
-        break;
-    case V4L2_CID_CONTRAST:
-        TRACE("V4L2_CID_CONTRAST\n");
-        memcpy((void *)name, (void *)"contrast", 32);
-        i = 1;
-        break;
-    case V4L2_CID_SATURATION:
-        TRACE("V4L2_CID_SATURATION\n");
-        memcpy((void *)name, (void *)"saturation", 32);
-        i = 2;
-        break;
-    case V4L2_CID_SHARPNESS:
-        TRACE("V4L2_CID_SHARPNESS\n");
-        memcpy((void *)name, (void *)"sharpness", 32);
-        i = 3;
-        break;
-    default:
-        param->errCode = EINVAL;
-        return;
-    }
-
-    param->stack[0] = id;
-    param->stack[1] = MARUCAM_CTRL_VALUE_MIN;  /* minimum */
-    param->stack[2] = MARUCAM_CTRL_VALUE_MAX;  /* maximum */
-    param->stack[3] = MARUCAM_CTRL_VALUE_STEP; /*  step   */
-    param->stack[4] = MARUCAM_CTRL_VALUE_MID;  /* default_value */
-    param->stack[5] = V4L2_CTRL_FLAG_SLIDER;
-    /* name field setting */
-    memcpy(&param->stack[6], (void *)name, sizeof(name)/sizeof(name[0]));
-}
-
-void marucam_device_s_ctrl(MaruCamState *state)
-{
-    INFO("Set control\n");
-}
-
-void marucam_device_g_ctrl(MaruCamState *state)
-{
-    INFO("Get control\n");
-}
-
-/* Get frame width & height */
-void marucam_device_enum_fsizes(MaruCamState *state)
-{
-    uint32_t index, pixfmt, i;
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    index = param->stack[0];
-    pixfmt = param->stack[1];
-
-    if (index >= ARRAY_SIZE(supported_dst_frames)) {
-        param->errCode = EINVAL;
-        return;
-    }
-    for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) {
-        if (supported_dst_pixfmts[i].fmt == pixfmt) {
-            break;
-        }
-    }
-
-    if (i == ARRAY_SIZE(supported_dst_pixfmts)) {
-        param->errCode = EINVAL;
-        return;
-    }
-
-    param->stack[0] = supported_dst_frames[index].width;
-    param->stack[1] = supported_dst_frames[index].height;
-}
-
-void marucam_device_enum_fintv(MaruCamState *state)
-{
-    MaruCamParam *param = state->param;
-    param->top = 0;
-
-    /* switch by index(param->stack[0]) */
-    switch (param->stack[0]) {
-    case 0:
-        param->stack[1] = 30; /* denominator */
-        break;
-    default:
-        param->errCode = EINVAL;
-        return;
-    }
-    param->stack[0] = 1; /* numerator */
-}
diff --git a/tizen/src/hw/maru_camera_linux_pci.c b/tizen/src/hw/maru_camera_linux_pci.c
deleted file mode 100644 (file)
index c4e1340..0000000
+++ /dev/null
@@ -1,1366 +0,0 @@
-/*
- * Implementation of MARU Virtual Camera device by PCI bus on Linux.
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- * JinHyung Jo <jinhyung.jo@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 "qemu-common.h"
-#include "sysemu/kvm.h"
-#include "maru_camera_common.h"
-#include "debug_ch.h"
-
-#include <linux/videodev2.h>
-
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-
-#include <libv4l2.h>
-#include <libv4lconvert.h>
-
-MULTI_DEBUG_CHANNEL(tizen, maru-camera);
-
-#define MARUCAM_THREAD_NAME    "marucam_worker_thread"
-
-#define CLEAR(x) memset(&(x), 0, sizeof(x))
-
-#define MARUCAM_DEFAULT_BUFFER_COUNT    4
-
-#define MARUCAM_CTRL_VALUE_MAX      20
-#define MARUCAM_CTRL_VALUE_MIN      1
-#define MARUCAM_CTRL_VALUE_MID      10
-#define MARUCAM_CTRL_VALUE_STEP     1
-
-enum {
-    _MC_THREAD_PAUSED,
-    _MC_THREAD_STREAMON,
-    _MC_THREAD_STREAMOFF,
-};
-
-typedef struct marucam_framebuffer {
-    void *data;
-    size_t size;
-} marucam_framebuffer;
-
-struct marucam_saved_frame {
-    void *data;
-    uint32_t pixelformat;
-    uint32_t width;
-    uint32_t height;
-    uint32_t size;
-};
-
-static struct marucam_saved_frame saved_frame;
-static char has_success_frame;
-static int n_framebuffer;
-static int previous_frame_index = -1;
-static struct marucam_framebuffer *framebuffer;
-
-static const char *dev_name = "/dev/video0";
-static int v4l2_fd;
-static int convert_trial;
-static int ready_count;
-static int timeout_n;
-
-static struct v4l2_format dst_fmt;
-
-static void ScalePlaneSimple(int src_width, int src_height,
-                             int dst_width, int dst_height,
-                             int src_stride, int dst_stride,
-                             const uint8_t *src_ptr, uint8_t *dst_ptr) {
-    int i, j;
-    int dx = (src_width << 16) / dst_width;
-    int dy = (src_height << 16) / dst_height;
-    int y = (dy >= 65536) ? ((dy >> 1) - 32768) : (dy >> 1);
-    for (j = 0; j < dst_height; ++j) {
-        int x = (dx >= 65536) ? ((dx >> 1) - 32768) : (dx >> 1);
-        int yi = y >> 16;
-        const uint8_t *src = src_ptr + yi * src_stride;
-        uint8_t *dst = dst_ptr;
-        for (i = 0; i < dst_width; ++i) {
-            *dst++ = src[x >> 16];
-            x += dx;
-        }
-        dst_ptr += dst_stride;
-        y += dy;
-    }
-}
-
-static void make_yu12_black(unsigned char *dest, uint32_t width, uint32_t height)
-{
-    uint32_t x, y;
-    unsigned char *udest, *vdest;
-
-    /* Y */
-    for (y = 0; y < height; y++) {
-        for (x = 0; x < width; x++) {
-            *dest++ = 16;
-        }
-    }
-
-    /* U + V */
-    udest = dest;
-    vdest = dest + width * height / 4;
-
-    for (y = 0; y < height / 2; y++) {
-        for (x = 0; x < width / 2; x++) {
-            *udest++ = *vdest++ = 128;
-        }
-    }
-}
-
-static void marucam_scale_yuv420(void *src,
-                    uint32_t src_width, uint32_t src_height,
-                    void *dst, uint32_t dst_width, uint32_t dst_height)
-{
-    uint32_t src_halfwidth = (src_width + 1) >> 1;
-    uint32_t src_halfheight = (src_height + 1) >> 1;
-    uint32_t dst_halfwidth = (dst_width + 1) >> 1;
-    uint32_t dst_halfheight = (dst_height + 1) >> 1;
-
-    uint8_t *src_u = src + (src_width * src_height);
-    uint8_t *src_v = src_u + (src_width * src_height / 4);
-
-    uint8_t *dst_u = dst + (dst_width * dst_height);
-    uint8_t *dst_v = dst_u + (dst_width * dst_height /4);
-
-    ScalePlaneSimple(src_width, src_height,
-                     dst_width, dst_height,
-                     src_width, dst_width,
-                     src, dst);
-    ScalePlaneSimple(src_halfwidth, src_halfheight,
-                     dst_halfwidth, dst_halfheight,
-                     src_halfwidth, dst_halfwidth,
-                     src_u, dst_u);
-    ScalePlaneSimple(src_halfwidth, src_halfheight,
-                     dst_halfwidth, dst_halfheight,
-                     src_halfwidth, dst_halfwidth,
-                     src_v, dst_v);
-}
-
-static int yioctl(int fd, int req, void *arg)
-{
-    int r;
-
-    do {
-        r = ioctl(fd, req, arg);
-    } while (r < 0 && errno == EINTR);
-
-    return r;
-}
-
-static int xioctl(int fd, int req, void *arg)
-{
-    int r;
-
-    do {
-        r = v4l2_ioctl(fd, req, arg);
-    } while (r < 0 && errno == EINTR);
-
-    return r;
-}
-
-typedef struct tagMaruCamConvertPixfmt {
-    uint32_t fmt;   /* fourcc */
-} MaruCamConvertPixfmt;
-
-static MaruCamConvertPixfmt supported_dst_pixfmts[] = {
-        { V4L2_PIX_FMT_YUYV },
-        { V4L2_PIX_FMT_YUV420 },
-        { V4L2_PIX_FMT_YVU420 },
-};
-
-typedef struct tagMaruCamConvertFrameInfo {
-    uint32_t width;
-    uint32_t height;
-} MaruCamConvertFrameInfo;
-
-static MaruCamConvertFrameInfo supported_dst_frames[] = {
-        { 640, 480 },
-        { 352, 288 },
-        { 320, 240 },
-        { 176, 144 },
-        { 160, 120 },
-};
-
-struct marucam_qctrl {
-    uint32_t id;
-    uint32_t hit;
-    int32_t min;
-    int32_t max;
-    int32_t step;
-    int32_t init_val;
-};
-
-static struct marucam_qctrl qctrl_tbl[] = {
-    { V4L2_CID_BRIGHTNESS, 0, },
-    { V4L2_CID_CONTRAST, 0, },
-    { V4L2_CID_SATURATION, 0, },
-    { V4L2_CID_SHARPNESS, 0, },
-};
-
-static void marucam_reset_controls(void)
-{
-    uint32_t i;
-    for (i = 0; i < ARRAY_SIZE(qctrl_tbl); i++) {
-        if (qctrl_tbl[i].hit) {
-            struct v4l2_control ctrl = {0,};
-            qctrl_tbl[i].hit = 0;
-            ctrl.id = qctrl_tbl[i].id;
-            ctrl.value = qctrl_tbl[i].init_val;
-            if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &ctrl) < 0) {
-                ERR("Failed to reset control value: id(0x%x), errstr(%s)\n",
-                    ctrl.id, strerror(errno));
-            }
-        }
-    }
-}
-
-static int32_t value_convert_from_guest(int32_t min, int32_t max, int32_t value)
-{
-    double rate = 0.0;
-    int32_t dist = 0, ret = 0;
-
-    dist = max - min;
-
-    if (dist < MARUCAM_CTRL_VALUE_MAX) {
-        rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;
-        ret = min + (int32_t)(value / rate);
-    } else {
-        rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;
-        ret = min + (int32_t)(rate * value);
-    }
-    return ret;
-}
-
-static int32_t value_convert_to_guest(int32_t min, int32_t max, int32_t value)
-{
-    double rate  = 0.0;
-    int32_t dist = 0, ret = 0;
-
-    dist = max - min;
-
-    if (dist < MARUCAM_CTRL_VALUE_MAX) {
-        rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;
-        ret = (int32_t)((double)(value - min) * rate);
-    } else {
-        rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;
-        ret = (int32_t)((double)(value - min) / rate);
-    }
-
-    return ret;
-}
-
-static void set_maxframeinterval(MaruCamState *state, uint32_t pixel_format,
-                        uint32_t width, uint32_t height)
-{
-    struct v4l2_frmivalenum fival;
-    struct v4l2_streamparm sp;
-    uint32_t min_num = 0, min_denom = 0;
-
-    CLEAR(fival);
-    fival.pixel_format = pixel_format;
-    fival.width = width;
-    fival.height = height;
-
-    if (xioctl(v4l2_fd, VIDIOC_ENUM_FRAMEINTERVALS, &fival) < 0) {
-        ERR("Unable to enumerate intervals for pixelformat(0x%x), (%d:%d)\n",
-            pixel_format, width, height);
-        return;
-    }
-
-    if (fival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
-        float max_ival = -1.0;
-        do {
-            float cur_ival = (float)fival.discrete.numerator
-                        / (float)fival.discrete.denominator;
-            if (cur_ival > max_ival) {
-                max_ival = cur_ival;
-                min_num = fival.discrete.numerator;
-                min_denom = fival.discrete.denominator;
-            }
-            TRACE("Discrete frame interval %u/%u supported\n",
-                 fival.discrete.numerator, fival.discrete.denominator);
-            fival.index++;
-        } while (xioctl(v4l2_fd, VIDIOC_ENUM_FRAMEINTERVALS, &fival) >= 0);
-    } else if ((fival.type == V4L2_FRMIVAL_TYPE_STEPWISE) ||
-                (fival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS)) {
-        TRACE("Frame intervals from %u/%u to %u/%u supported",
-            fival.stepwise.min.numerator, fival.stepwise.min.denominator,
-            fival.stepwise.max.numerator, fival.stepwise.max.denominator);
-        if (fival.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
-            TRACE("with %u/%u step", fival.stepwise.step.numerator,
-                  fival.stepwise.step.denominator);
-        }
-        if (((float)fival.stepwise.max.denominator /
-             (float)fival.stepwise.max.numerator) >
-            ((float)fival.stepwise.min.denominator /
-             (float)fival.stepwise.min.numerator)) {
-            min_num = fival.stepwise.max.numerator;
-            min_denom = fival.stepwise.max.denominator;
-        } else {
-            min_num = fival.stepwise.min.numerator;
-            min_denom = fival.stepwise.min.denominator;
-        }
-    }
-    TRACE("The actual min values: %u/%u\n", min_num, min_denom);
-
-    CLEAR(sp);
-    sp.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    sp.parm.capture.timeperframe.numerator = min_num;
-    sp.parm.capture.timeperframe.denominator = min_denom;
-
-    if (xioctl(v4l2_fd, VIDIOC_S_PARM, &sp) < 0) {
-        ERR("Failed to set to minimum FPS(%u/%u)\n", min_num, min_denom);
-    }
-}
-
-static uint32_t stop_capturing(void)
-{
-    enum v4l2_buf_type type;
-
-    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    if (xioctl(v4l2_fd, VIDIOC_STREAMOFF, &type) < 0) {
-        ERR("Failed to ioctl() with VIDIOC_STREAMOFF: %s\n", strerror(errno));
-        return errno;
-    }
-    return 0;
-}
-
-static uint32_t start_capturing(void)
-{
-    enum v4l2_buf_type type;
-
-    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    if (xioctl(v4l2_fd, VIDIOC_STREAMON, &type) < 0) {
-        ERR("Failed to ioctl() with VIDIOC_STREAMON: %s\n", strerror(errno));
-        return errno;
-    }
-    return 0;
-}
-
-static void free_framebuffers(marucam_framebuffer *fb, int buf_num)
-{
-    int i;
-
-    if (fb == NULL) {
-        ERR("The framebuffer is NULL. Failed to release the framebuffer\n");
-        return;
-    } else if (buf_num == 0) {
-        ERR("The buffer count is 0. Failed to release the framebuffer\n");
-        return;
-    } else {
-        TRACE("[%s]:fb(0x%p), buf_num(%d)\n", __func__, fb, buf_num);
-    }
-
-    /* Unmap framebuffers. */
-    for (i = 0; i < buf_num; i++) {
-        if (fb[i].data != NULL) {
-            v4l2_munmap(fb[i].data, fb[i].size);
-            fb[i].data = NULL;
-            fb[i].size = 0;
-        } else {
-            ERR("framebuffer[%d].data is NULL.\n", i);
-        }
-    }
-    previous_frame_index = -1;
-}
-
-static uint32_t
-mmap_framebuffers(marucam_framebuffer **fb, int *buf_num)
-{
-    struct v4l2_requestbuffers req;
-
-    CLEAR(req);
-    req.count   = MARUCAM_DEFAULT_BUFFER_COUNT;
-    req.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    req.memory  = V4L2_MEMORY_MMAP;
-    if (xioctl(v4l2_fd, VIDIOC_REQBUFS, &req) < 0) {
-        if (errno == EINVAL) {
-            ERR("%s does not support memory mapping: %s\n",
-                dev_name, strerror(errno));
-        } else {
-            ERR("Failed to request bufs: %s\n", strerror(errno));
-        }
-        return errno;
-    }
-    if (req.count == 0) {
-        ERR("Insufficient buffer memory on %s\n", dev_name);
-        return EINVAL;
-    }
-
-    *fb = g_new0(marucam_framebuffer, req.count);
-    if (*fb == NULL) {
-        ERR("Not enough memory to allocate framebuffers\n");
-        return ENOMEM;
-    }
-
-    for (*buf_num = 0; *buf_num < req.count; ++*buf_num) {
-        struct v4l2_buffer buf;
-        CLEAR(buf);
-        buf.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-        buf.memory  = V4L2_MEMORY_MMAP;
-        buf.index   = *buf_num;
-        if (xioctl(v4l2_fd, VIDIOC_QUERYBUF, &buf) < 0) {
-            ERR("Failed to ioctl() with VIDIOC_QUERYBUF: %s\n",
-                strerror(errno));
-            return errno;
-        }
-
-        (*fb)[*buf_num].size = buf.length;
-        (*fb)[*buf_num].data = v4l2_mmap(NULL,
-                     buf.length,
-                     PROT_READ | PROT_WRITE,
-                     MAP_SHARED,
-                     v4l2_fd, buf.m.offset);
-        if (MAP_FAILED == (*fb)[*buf_num].data) {
-            ERR("Failed to mmap: %s\n", strerror(errno));
-            return errno;
-        }
-
-        /* Queue the mapped buffer. */
-        CLEAR(buf);
-        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-        buf.memory = V4L2_MEMORY_MMAP;
-        buf.index = *buf_num;
-        if (xioctl(v4l2_fd, VIDIOC_QBUF, &buf) < 0) {
-            ERR("Failed to ioctl() with VIDIOC_QBUF: %s\n", strerror(errno));
-            return errno;
-        }
-    }
-    return 0;
-}
-
-static int is_streamon(MaruCamState *state)
-{
-    int st;
-    qemu_mutex_lock(&state->thread_mutex);
-    st = state->streamon;
-    qemu_mutex_unlock(&state->thread_mutex);
-    return (st == _MC_THREAD_STREAMON);
-}
-
-static int is_stream_paused(MaruCamState *state)
-{
-    int st;
-    qemu_mutex_lock(&state->thread_mutex);
-    st = state->streamon;
-    qemu_mutex_unlock(&state->thread_mutex);
-    return (st == _MC_THREAD_PAUSED);
-}
-
-/* sends a frame, YU12/black color  */
-/* TODO: add other pixel format method */
-static void __raise_dummy_intr(MaruCamState *state)
-{
-    void *buf = NULL;
-    qemu_mutex_lock(&state->thread_mutex);
-    if (state->streamon == _MC_THREAD_STREAMON && state->req_frame) {
-        buf = state->vaddr + state->buf_size * (state->req_frame - 1);
-        if (saved_frame.data) {
-            if (saved_frame.width == dst_fmt.fmt.pix.width &&
-                saved_frame.height == dst_fmt.fmt.pix.height) {
-                TRACE("Copies the previuos frame\n");
-                memcpy(buf, saved_frame.data, state->buf_size);
-            } else {
-                TRACE("Resizes the previous frame\n");
-                marucam_scale_yuv420(saved_frame.data, saved_frame.width,
-                                     saved_frame.height,
-                                     buf, dst_fmt.fmt.pix.width,
-                                     dst_fmt.fmt.pix.height);
-            }
-        } else {
-            TRACE("Sends a black frame\n");
-            make_yu12_black(buf,
-                            dst_fmt.fmt.pix.width,
-                            dst_fmt.fmt.pix.height);
-        }
-        state->req_frame = 0; /* clear request */
-        state->isr |= 0x01;   /* set a flag of raising a interrupt */
-        qemu_bh_schedule(state->tx_bh);
-    }
-    qemu_mutex_unlock(&state->thread_mutex);
-}
-
-static void __raise_err_intr(MaruCamState *state)
-{
-    qemu_mutex_lock(&state->thread_mutex);
-    if (state->streamon == _MC_THREAD_STREAMON) {
-        state->req_frame = 0; /* clear request */
-        state->isr = 0x08;   /* set a error flag of raising a interrupt */
-        qemu_bh_schedule(state->tx_bh);
-    }
-    qemu_mutex_unlock(&state->thread_mutex);
-}
-
-static void
-notify_buffer_ready(MaruCamState *state, uint32_t buf_index)
-{
-    void *buf = NULL;
-
-    qemu_mutex_lock(&state->thread_mutex);
-    if (state->streamon == _MC_THREAD_STREAMON) {
-        if (ready_count < MARUCAM_SKIPFRAMES) {
-            /* skip a frame cause first some frame are distorted */
-            ++ready_count;
-            TRACE("Skip %d frame\n", ready_count);
-            qemu_mutex_unlock(&state->thread_mutex);
-            return;
-        }
-        if (state->req_frame == 0) {
-            TRACE("There is no request\n");
-            qemu_mutex_unlock(&state->thread_mutex);
-            return;
-        }
-        buf = state->vaddr + state->buf_size * (state->req_frame - 1);
-        memcpy(buf, framebuffer[buf_index].data, state->buf_size);
-        previous_frame_index = buf_index;
-        has_success_frame = 1;
-        state->req_frame = 0; /* clear request */
-        state->isr |= 0x01;   /* set a flag of rasing a interrupt */
-        qemu_bh_schedule(state->tx_bh);
-    }
-    qemu_mutex_unlock(&state->thread_mutex);
-}
-
-static int read_frame(MaruCamState *state)
-{
-    struct v4l2_buffer buf;
-
-    CLEAR(buf);
-    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    buf.memory = V4L2_MEMORY_MMAP;
-    if (xioctl(v4l2_fd, VIDIOC_DQBUF, &buf) < 0) {
-        switch (errno) {
-        case EAGAIN:
-        case EINTR:
-            ERR("DQBUF error, try again: %s\n", strerror(errno));
-            return 0;
-        case EIO:
-            ERR("The v4l2_read() met the EIO\n");
-            if (convert_trial-- == -1) {
-                ERR("Try count for v4l2_read is exceeded: %s\n",
-                    strerror(errno));
-                return -1;
-            }
-            return 0;
-        default:
-            ERR("DQBUF error: %s\n", strerror(errno));
-            return -1;
-        }
-    }
-
-    notify_buffer_ready(state, buf.index);
-
-    if (xioctl(v4l2_fd, VIDIOC_QBUF, &buf) < 0) {
-        ERR("QBUF error: %s\n", strerror(errno));
-        return -1;
-    }
-    return 0;
-}
-
-static int __v4l2_streaming(MaruCamState *state)
-{
-    fd_set fds;
-    struct timeval tv;
-    int ret;
-
-    FD_ZERO(&fds);
-    FD_SET(v4l2_fd, &fds);
-
-    tv.tv_sec = 1;
-    tv.tv_usec = 0;
-
-    ret = select(v4l2_fd + 1, &fds, NULL, NULL, &tv);
-    if (ret < 0) {
-        if (errno == EAGAIN || errno == EINTR) {
-            ERR("Select again: %s\n", strerror(errno));
-            return 0;
-        }
-        ERR("Failed to select: %s\n", strerror(errno));
-        __raise_err_intr(state);
-        return -1;
-    } else if (!ret) {
-        timeout_n++;
-        ERR("Select timed out: count(%u)\n", timeout_n);
-        if (ready_count <= MARUCAM_SKIPFRAMES) {
-            switch (timeout_n) {
-            case 1:
-                ERR("Waiting for reading a frame data\n");
-                return 0;
-            case 2:
-            case 3:
-            case 4:
-                ERR("Sends dummy data to initialize the camera\n");
-                __raise_dummy_intr(state);
-                return 0;
-            default:
-                ERR("Webcam is busy, failed to a read frame."
-                    " Raises an error\n");
-                __raise_err_intr(state);
-                return -1;
-            }
-        }
-        if (timeout_n >= 5) {
-            ERR("Webcam is busy, failed to a read frame. Raises an error\n");
-            __raise_err_intr(state);
-            return -1;
-        }
-        if (previous_frame_index != -1) {
-            ERR("Sends previous frame data\n");
-            notify_buffer_ready(state, previous_frame_index);
-        }
-        return 0;
-    }
-
-    if (!v4l2_fd || (v4l2_fd == -1)) {
-        ERR("The file descriptor is closed or not opened\n");
-        __raise_err_intr(state);
-        return -1;
-    }
-
-    ret = read_frame(state);
-    if (ret < 0) {
-        ERR("Failed to operate the read_frame()\n");
-        __raise_err_intr(state);
-        return -1;
-    }
-
-    /* clear the skip count for select time-out */
-    if (timeout_n > 0) {
-        timeout_n = 0;
-    }
-
-    return 0;
-}
-
-/* Worker thread */
-static void *marucam_worker_thread(void *thread_param)
-{
-    MaruCamState *state = (MaruCamState *)thread_param;
-
-    while (1) {
-        qemu_mutex_lock(&state->thread_mutex);
-        state->streamon = _MC_THREAD_PAUSED;
-        qemu_cond_wait(&state->thread_cond, &state->thread_mutex);
-        qemu_mutex_unlock(&state->thread_mutex);
-
-        if (state->destroying) {
-            break;
-        }
-
-        convert_trial = 10;
-        ready_count = 0;
-        timeout_n = 0;
-        has_success_frame = 0;
-        qemu_mutex_lock(&state->thread_mutex);
-        state->streamon = _MC_THREAD_STREAMON;
-        qemu_mutex_unlock(&state->thread_mutex);
-        INFO("Streaming on ......\n");
-
-        while (1) {
-            if (is_streamon(state)) {
-                if (__v4l2_streaming(state) < 0) {
-                    INFO("...... Streaming off\n");
-                    break;
-                }
-            } else {
-                INFO("...... Streaming off\n");
-                break;
-            }
-        }
-    }
-
-    return NULL;
-}
-
-int marucam_device_check(int log_flag)
-{
-    int tmp_fd;
-    struct timeval t1, t2;
-    struct stat st;
-    struct v4l2_fmtdesc format;
-    struct v4l2_frmsizeenum size;
-    struct v4l2_capability cap;
-    int ret = 0;
-
-    gettimeofday(&t1, NULL);
-    if (stat(dev_name, &st) < 0) {
-        INFO("<WARNING> Cannot identify '%s': %s\n",
-                dev_name, strerror(errno));
-    } else {
-        if (!S_ISCHR(st.st_mode)) {
-            INFO("<WARNING>%s is no character device\n",
-                    dev_name);
-        }
-    }
-
-    tmp_fd = open(dev_name, O_RDWR | O_NONBLOCK, 0);
-    if (tmp_fd < 0) {
-        ERR("Camera device open failed: %s\n", dev_name);
-        gettimeofday(&t2, NULL);
-        ERR("Elapsed time: %lu:%06lu\n",
-                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-        return ret;
-    }
-    if (ioctl(tmp_fd, VIDIOC_QUERYCAP, &cap) < 0) {
-        ERR("Could not qeury video capabilities\n");
-        close(tmp_fd);
-        gettimeofday(&t2, NULL);
-        ERR("Elapsed time: %lu:%06lu\n",
-                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-        return ret;
-    }
-    if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) ||
-            !(cap.capabilities & V4L2_CAP_STREAMING)) {
-        ERR("Not supported video driver\n");
-        close(tmp_fd);
-        gettimeofday(&t2, NULL);
-        ERR("Elapsed time: %lu:%06lu\n",
-                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-        return ret;
-    }
-    ret = 1;
-
-    if (log_flag) {
-        INFO("Driver: %s\n", cap.driver);
-        INFO("Card:  %s\n", cap.card);
-        INFO("Bus info: %s\n", cap.bus_info);
-
-        CLEAR(format);
-        format.index = 0;
-        format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-        if (yioctl(tmp_fd, VIDIOC_ENUM_FMT, &format) < 0) {
-            close(tmp_fd);
-            gettimeofday(&t2, NULL);
-            ERR("Elapsed time: %lu:%06lu\n",
-                    t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-            return ret;
-        }
-
-        do {
-            CLEAR(size);
-            size.index = 0;
-            size.pixel_format = format.pixelformat;
-
-            INFO("PixelFormat: %c%c%c%c\n",
-                             (char)(format.pixelformat),
-                             (char)(format.pixelformat >> 8),
-                             (char)(format.pixelformat >> 16),
-                             (char)(format.pixelformat >> 24));
-
-            if (yioctl(tmp_fd, VIDIOC_ENUM_FRAMESIZES, &size) < 0) {
-                close(tmp_fd);
-                gettimeofday(&t2, NULL);
-                ERR("Elapsed time: %lu:%06lu\n",
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-                return ret;
-            }
-
-            if (size.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
-                do {
-                    INFO("\tGot a discrete frame size %dx%d\n",
-                                    size.discrete.width, size.discrete.height);
-                    size.index++;
-                } while (yioctl(tmp_fd, VIDIOC_ENUM_FRAMESIZES, &size) >= 0);
-            } else if (size.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
-                INFO("We have stepwise frame sizes:\n");
-                INFO("\tmin width: %d, min height: %d\n",
-                        size.stepwise.min_width, size.stepwise.min_height);
-                INFO("\tmax width: %d, max height: %d\n",
-                        size.stepwise.max_width, size.stepwise.max_height);
-                INFO("\tstep width: %d, step height: %d\n",
-                        size.stepwise.step_width, size.stepwise.step_height);
-            } else if (size.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) {
-                INFO("We have continuous frame sizes:\n");
-                INFO("\tmin width: %d, min height: %d\n",
-                        size.stepwise.min_width, size.stepwise.min_height);
-                INFO("\tmax width: %d, max height: %d\n",
-                        size.stepwise.max_width, size.stepwise.max_height);
-
-            }
-            format.index++;
-        } while (yioctl(tmp_fd, VIDIOC_ENUM_FMT, &format) >= 0);
-    }
-
-    close(tmp_fd);
-    gettimeofday(&t2, NULL);
-    INFO("Elapsed time: %lu:%06lu\n",
-                    t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-    return ret;
-}
-
-void marucam_device_init(MaruCamState *state)
-{
-    state->destroying = false;
-    qemu_thread_create(&state->thread_id,
-                       MARUCAM_THREAD_NAME,
-                       marucam_worker_thread,
-                       (void *)state,
-                       QEMU_THREAD_JOINABLE);
-}
-
-void marucam_device_exit(MaruCamState *state)
-{
-    state->destroying = true;
-    qemu_mutex_lock(&state->thread_mutex);
-    qemu_cond_signal(&state->thread_cond);
-    qemu_mutex_unlock(&state->thread_mutex);
-    qemu_thread_join(&state->thread_id);
-}
-
-void marucam_device_open(MaruCamState *state)
-{
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    v4l2_fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0);
-    if (v4l2_fd < 0) {
-        ERR("The v4l2 device open failed: %s\n", dev_name);
-        param->errCode = EINVAL;
-        return;
-    }
-    INFO("Opened\n");
-
-    /* FIXME : Do not use fixed values */
-    CLEAR(dst_fmt);
-    dst_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    dst_fmt.fmt.pix.width = 640;
-    dst_fmt.fmt.pix.height = 480;
-    dst_fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
-    dst_fmt.fmt.pix.field = V4L2_FIELD_ANY;
-
-    if (xioctl(v4l2_fd, VIDIOC_S_FMT, &dst_fmt) < 0) {
-        ERR("Failed to set video format: format(0x%x), width:height(%d:%d), "
-          "errstr(%s)\n", dst_fmt.fmt.pix.pixelformat, dst_fmt.fmt.pix.width,
-          dst_fmt.fmt.pix.height, strerror(errno));
-        param->errCode = errno;
-        return;
-    }
-    TRACE("Set the default format: w:h(%dx%d), fmt(0x%x), size(%d), "
-         "color(%d), field(%d)\n",
-         dst_fmt.fmt.pix.width, dst_fmt.fmt.pix.height,
-         dst_fmt.fmt.pix.pixelformat, dst_fmt.fmt.pix.sizeimage,
-         dst_fmt.fmt.pix.colorspace, dst_fmt.fmt.pix.field);
-}
-
-void marucam_device_start_preview(MaruCamState *state)
-{
-    struct timespec req;
-    MaruCamParam *param = state->param;
-    param->top = 0;
-    req.tv_sec = 0;
-    req.tv_nsec = 10000000;
-
-    INFO("Pixfmt(%c%c%c%C), W:H(%d:%d), buf size(%u)\n",
-         (char)(dst_fmt.fmt.pix.pixelformat),
-         (char)(dst_fmt.fmt.pix.pixelformat >> 8),
-         (char)(dst_fmt.fmt.pix.pixelformat >> 16),
-         (char)(dst_fmt.fmt.pix.pixelformat >> 24),
-         dst_fmt.fmt.pix.width,
-         dst_fmt.fmt.pix.height,
-         dst_fmt.fmt.pix.sizeimage);
-
-    param->errCode = mmap_framebuffers(&framebuffer, &n_framebuffer);
-    if (param->errCode) {
-        ERR("Failed to mmap framebuffers\n");
-        if (framebuffer != NULL) {
-            free_framebuffers(framebuffer, n_framebuffer);
-            g_free(framebuffer);
-            framebuffer = NULL;
-            n_framebuffer = 0;
-        }
-        return;
-    }
-
-    param->errCode = start_capturing();
-    if (param->errCode) {
-        if (framebuffer != NULL) {
-            free_framebuffers(framebuffer, n_framebuffer);
-            g_free(framebuffer);
-            framebuffer = NULL;
-            n_framebuffer = 0;
-        }
-        return;
-    }
-
-    INFO("Starting preview\n");
-    state->buf_size = dst_fmt.fmt.pix.sizeimage;
-    qemu_mutex_lock(&state->thread_mutex);
-    qemu_cond_signal(&state->thread_cond);
-    qemu_mutex_unlock(&state->thread_mutex);
-
-    /* nanosleep until thread is streamon  */
-    while (!is_streamon(state)) {
-        nanosleep(&req, NULL);
-    }
-}
-
-void marucam_device_stop_preview(MaruCamState *state)
-{
-    struct timespec req;
-    struct v4l2_requestbuffers reqbuf;
-    MaruCamParam *param = state->param;
-    param->top = 0;
-    req.tv_sec = 0;
-    req.tv_nsec = 50000000;
-
-    if (is_streamon(state)) {
-        qemu_mutex_lock(&state->thread_mutex);
-        state->streamon = _MC_THREAD_STREAMOFF;
-        qemu_mutex_unlock(&state->thread_mutex);
-
-        /* nanosleep until thread is paused  */
-        while (!is_stream_paused(state)) {
-            nanosleep(&req, NULL);
-        }
-    }
-
-    if (has_success_frame) {
-        saved_frame.width = dst_fmt.fmt.pix.width;
-        saved_frame.height = dst_fmt.fmt.pix.height;
-        saved_frame.size = dst_fmt.fmt.pix.sizeimage;
-        if (saved_frame.data) {
-            g_free(saved_frame.data);
-            saved_frame.data = NULL;
-        }
-        saved_frame.data = (void *)g_malloc0(saved_frame.size);
-        memcpy(saved_frame.data,
-               framebuffer[previous_frame_index].data,
-               saved_frame.size);
-        TRACE("Saves a frame data\n");
-    }
-
-    param->errCode = stop_capturing();
-    if (framebuffer != NULL) {
-        free_framebuffers(framebuffer, n_framebuffer);
-        g_free(framebuffer);
-        framebuffer = NULL;
-        n_framebuffer = 0;
-    }
-    state->buf_size = 0;
-
-    reqbuf.count = 0;
-    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    reqbuf.memory = V4L2_MEMORY_MMAP;
-    if (xioctl(v4l2_fd, VIDIOC_REQBUFS, &reqbuf) < 0) {
-        ERR("Failed to ioctl() with VIDIOC_REQBUF in stop_preview: %s\n",
-            strerror(errno));
-    }
-    INFO("Stopping preview\n");
-}
-
-void marucam_device_s_param(MaruCamState *state)
-{
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-
-    /* If KVM enabled, We use default FPS of the webcam.
-     * If KVM disabled, we use mininum FPS of the webcam */
-    if (!kvm_enabled()) {
-        set_maxframeinterval(state, dst_fmt.fmt.pix.pixelformat,
-                     dst_fmt.fmt.pix.width,
-                     dst_fmt.fmt.pix.height);
-    }
-}
-
-void marucam_device_g_param(MaruCamState *state)
-{
-    MaruCamParam *param = state->param;
-
-    /* We use default FPS of the webcam
-     * return a fixed value on guest ini file (1/30).
-     */
-    param->top = 0;
-    param->stack[0] = 0x1000; /* V4L2_CAP_TIMEPERFRAME */
-    param->stack[1] = 1; /* numerator */
-    param->stack[2] = 30; /* denominator */
-}
-
-void marucam_device_s_fmt(MaruCamState *state)
-{
-    struct v4l2_format format;
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    CLEAR(format);
-    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    format.fmt.pix.width = param->stack[0];
-    format.fmt.pix.height = param->stack[1];
-    format.fmt.pix.pixelformat = param->stack[2];
-    format.fmt.pix.field = V4L2_FIELD_ANY;
-
-    if (xioctl(v4l2_fd, VIDIOC_S_FMT, &format) < 0) {
-        ERR("Failed to set video format: format(0x%x), width:height(%d:%d), "
-          "errstr(%s)\n", format.fmt.pix.pixelformat, format.fmt.pix.width,
-          format.fmt.pix.height, strerror(errno));
-        param->errCode = errno;
-        return;
-    }
-
-    memcpy(&dst_fmt, &format, sizeof(format));
-    param->stack[0] = dst_fmt.fmt.pix.width;
-    param->stack[1] = dst_fmt.fmt.pix.height;
-    param->stack[2] = dst_fmt.fmt.pix.field;
-    param->stack[3] = dst_fmt.fmt.pix.pixelformat;
-    param->stack[4] = dst_fmt.fmt.pix.bytesperline;
-    param->stack[5] = dst_fmt.fmt.pix.sizeimage;
-    param->stack[6] = dst_fmt.fmt.pix.colorspace;
-    param->stack[7] = dst_fmt.fmt.pix.priv;
-    TRACE("Set the format: w:h(%dx%d), fmt(0x%x), size(%d), "
-         "color(%d), field(%d)\n",
-         dst_fmt.fmt.pix.width, dst_fmt.fmt.pix.height,
-         dst_fmt.fmt.pix.pixelformat, dst_fmt.fmt.pix.sizeimage,
-         dst_fmt.fmt.pix.colorspace, dst_fmt.fmt.pix.field);
-}
-
-void marucam_device_g_fmt(MaruCamState *state)
-{
-    struct v4l2_format format;
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    CLEAR(format);
-    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
-    if (xioctl(v4l2_fd, VIDIOC_G_FMT, &format) < 0) {
-        ERR("Failed to get video format: %s\n", strerror(errno));
-        param->errCode = errno;
-    } else {
-        param->stack[0] = format.fmt.pix.width;
-        param->stack[1] = format.fmt.pix.height;
-        param->stack[2] = format.fmt.pix.field;
-        param->stack[3] = format.fmt.pix.pixelformat;
-        param->stack[4] = format.fmt.pix.bytesperline;
-        param->stack[5] = format.fmt.pix.sizeimage;
-        param->stack[6] = format.fmt.pix.colorspace;
-        param->stack[7] = format.fmt.pix.priv;
-        TRACE("Get the format: w:h(%dx%d), fmt(0x%x), size(%d), "
-             "color(%d), field(%d)\n",
-             format.fmt.pix.width, format.fmt.pix.height,
-             format.fmt.pix.pixelformat, format.fmt.pix.sizeimage,
-             format.fmt.pix.colorspace, format.fmt.pix.field);
-    }
-}
-
-void marucam_device_try_fmt(MaruCamState *state)
-{
-    struct v4l2_format format;
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    CLEAR(format);
-    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-    format.fmt.pix.width = param->stack[0];
-    format.fmt.pix.height = param->stack[1];
-    format.fmt.pix.pixelformat = param->stack[2];
-    format.fmt.pix.field = V4L2_FIELD_ANY;
-
-    if (xioctl(v4l2_fd, VIDIOC_TRY_FMT, &format) < 0) {
-        ERR("Failed to check video format: format(0x%x), width:height(%d:%d),"
-            " errstr(%s)\n", format.fmt.pix.pixelformat, format.fmt.pix.width,
-            format.fmt.pix.height, strerror(errno));
-        param->errCode = errno;
-        return;
-    }
-    param->stack[0] = format.fmt.pix.width;
-    param->stack[1] = format.fmt.pix.height;
-    param->stack[2] = format.fmt.pix.field;
-    param->stack[3] = format.fmt.pix.pixelformat;
-    param->stack[4] = format.fmt.pix.bytesperline;
-    param->stack[5] = format.fmt.pix.sizeimage;
-    param->stack[6] = format.fmt.pix.colorspace;
-    param->stack[7] = format.fmt.pix.priv;
-    TRACE("Check the format: w:h(%dx%d), fmt(0x%x), size(%d), "
-         "color(%d), field(%d)\n",
-         format.fmt.pix.width, format.fmt.pix.height,
-         format.fmt.pix.pixelformat, format.fmt.pix.sizeimage,
-         format.fmt.pix.colorspace, format.fmt.pix.field);
-}
-
-void marucam_device_enum_fmt(MaruCamState *state)
-{
-    uint32_t index;
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    index = param->stack[0];
-
-    if (index >= ARRAY_SIZE(supported_dst_pixfmts)) {
-        param->errCode = EINVAL;
-        return;
-    }
-    param->stack[1] = 0; /* flags = NONE */
-    param->stack[2] = supported_dst_pixfmts[index].fmt; /* pixelformat */
-    /* set description */
-    switch (supported_dst_pixfmts[index].fmt) {
-    case V4L2_PIX_FMT_YUYV:
-        strcpy((char *)&param->stack[3], "YUYV");
-        break;
-    case V4L2_PIX_FMT_YUV420:
-        strcpy((char *)&param->stack[3], "YU12");
-        break;
-    case V4L2_PIX_FMT_YVU420:
-        strcpy((char *)&param->stack[3], "YV12");
-        break;
-    default:
-        ERR("Invalid fixel format\n");
-        param->errCode = EINVAL;
-        break;
-    }
-}
-
-void marucam_device_qctrl(MaruCamState *state)
-{
-    uint32_t i;
-    char name[32] = {0,};
-    struct v4l2_queryctrl ctrl;
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    CLEAR(ctrl);
-    ctrl.id = param->stack[0];
-
-    switch (ctrl.id) {
-    case V4L2_CID_BRIGHTNESS:
-        TRACE("Query : BRIGHTNESS\n");
-        strcpy(name, "brightness");
-        i = 0;
-        break;
-    case V4L2_CID_CONTRAST:
-        TRACE("Query : CONTRAST\n");
-        strcpy(name, "contrast");
-        i = 1;
-        break;
-    case V4L2_CID_SATURATION:
-        TRACE("Query : SATURATION\n");
-        strcpy(name, "saturation");
-        i = 2;
-        break;
-    case V4L2_CID_SHARPNESS:
-        TRACE("Query : SHARPNESS\n");
-        strcpy(name, "sharpness");
-        i = 3;
-        break;
-    default:
-        ERR("Invalid control ID\n");
-        param->errCode = EINVAL;
-        return;
-    }
-
-    if (xioctl(v4l2_fd, VIDIOC_QUERYCTRL, &ctrl) < 0) {
-        if (errno != EINVAL) {
-            ERR("Failed to query video controls: %s\n", strerror(errno));
-        }
-        param->errCode = errno;
-        return;
-    } else {
-        struct v4l2_control sctrl;
-        CLEAR(sctrl);
-        sctrl.id = ctrl.id;
-        if ((ctrl.maximum + ctrl.minimum) == 0) {
-            sctrl.value = 0;
-        } else {
-            sctrl.value = (ctrl.maximum + ctrl.minimum) / 2;
-        }
-        if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &sctrl) < 0) {
-            ERR("Failed to set control value: id(0x%x), value(%d), "
-                "errstr(%s)\n", sctrl.id, sctrl.value, strerror(errno));
-            param->errCode = errno;
-            return;
-        }
-        qctrl_tbl[i].hit = 1;
-        qctrl_tbl[i].min = ctrl.minimum;
-        qctrl_tbl[i].max = ctrl.maximum;
-        qctrl_tbl[i].step = ctrl.step;
-        qctrl_tbl[i].init_val = ctrl.default_value;
-    }
-
-    /* set fixed values by FW configuration file */
-    param->stack[0] = ctrl.id;
-    param->stack[1] = MARUCAM_CTRL_VALUE_MIN;    /* minimum */
-    param->stack[2] = MARUCAM_CTRL_VALUE_MAX;    /* maximum */
-    param->stack[3] = MARUCAM_CTRL_VALUE_STEP;   /* step */
-    param->stack[4] = MARUCAM_CTRL_VALUE_MID;    /* default_value */
-    param->stack[5] = ctrl.flags;
-    /* name field setting */
-    memcpy(&param->stack[6], (void *)name, sizeof(ctrl.name));
-}
-
-void marucam_device_s_ctrl(MaruCamState *state)
-{
-    uint32_t i;
-    struct v4l2_control ctrl;
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    CLEAR(ctrl);
-    ctrl.id = param->stack[0];
-
-    switch (ctrl.id) {
-    case V4L2_CID_BRIGHTNESS:
-        i = 0;
-        TRACE("%d is set to the value of the BRIGHTNESS\n", param->stack[1]);
-        break;
-    case V4L2_CID_CONTRAST:
-        i = 1;
-        TRACE("%d is set to the value of the CONTRAST\n", param->stack[1]);
-        break;
-    case V4L2_CID_SATURATION:
-        i = 2;
-        TRACE("%d is set to the value of the SATURATION\n", param->stack[1]);
-        break;
-    case V4L2_CID_SHARPNESS:
-        i = 3;
-        TRACE("%d is set to the value of the SHARPNESS\n", param->stack[1]);
-        break;
-    default:
-        ERR("Our emulator does not support this control: 0x%x\n", ctrl.id);
-        param->errCode = EINVAL;
-        return;
-    }
-
-    ctrl.value = value_convert_from_guest(qctrl_tbl[i].min,
-            qctrl_tbl[i].max, param->stack[1]);
-    if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &ctrl) < 0) {
-        ERR("Failed to set control value: id(0x%x), value(r:%d, c:%d), "
-            "errstr(%s)\n", ctrl.id, param->stack[1], ctrl.value,
-            strerror(errno));
-        param->errCode = errno;
-        return;
-    }
-}
-
-void marucam_device_g_ctrl(MaruCamState *state)
-{
-    uint32_t i;
-    struct v4l2_control ctrl;
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    CLEAR(ctrl);
-    ctrl.id = param->stack[0];
-
-    switch (ctrl.id) {
-    case V4L2_CID_BRIGHTNESS:
-        TRACE("Gets the value of the BRIGHTNESS\n");
-        i = 0;
-        break;
-    case V4L2_CID_CONTRAST:
-        TRACE("Gets the value of the CONTRAST\n");
-        i = 1;
-        break;
-    case V4L2_CID_SATURATION:
-        TRACE("Gets the value of the SATURATION\n");
-        i = 2;
-        break;
-    case V4L2_CID_SHARPNESS:
-        TRACE("Gets the value of the SHARPNESS\n");
-        i = 3;
-        break;
-    default:
-        ERR("Our emulator does not support this control: 0x%x\n", ctrl.id);
-        param->errCode = EINVAL;
-        return;
-    }
-
-    if (xioctl(v4l2_fd, VIDIOC_G_CTRL, &ctrl) < 0) {
-        ERR("Failed to get video control value: %s\n", strerror(errno));
-        param->errCode = errno;
-        return;
-    }
-    param->stack[0] = value_convert_to_guest(qctrl_tbl[i].min,
-            qctrl_tbl[i].max, ctrl.value);
-    TRACE("Value: %d\n", param->stack[0]);
-}
-
-void marucam_device_enum_fsizes(MaruCamState *state)
-{
-    uint32_t index, pixfmt, i;
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    index = param->stack[0];
-    pixfmt = param->stack[1];
-
-    if (index >= ARRAY_SIZE(supported_dst_frames)) {
-        param->errCode = EINVAL;
-        return;
-    }
-    for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) {
-        if (supported_dst_pixfmts[i].fmt == pixfmt) {
-            break;
-        }
-    }
-
-    if (i == ARRAY_SIZE(supported_dst_pixfmts)) {
-        param->errCode = EINVAL;
-        return;
-    }
-
-    param->stack[0] = supported_dst_frames[index].width;
-    param->stack[1] = supported_dst_frames[index].height;
-}
-
-void marucam_device_enum_fintv(MaruCamState *state)
-{
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-
-    /* switch by index(param->stack[0]) */
-    switch (param->stack[0]) {
-    case 0:
-        /* we only use 1/30 frame interval */
-        param->stack[1] = 30;   /* denominator */
-        break;
-    default:
-        param->errCode = EINVAL;
-        return;
-    }
-    param->stack[0] = 1;    /* numerator */
-}
-
-void marucam_device_close(MaruCamState *state)
-{
-    if (!is_stream_paused(state)) {
-        marucam_device_stop_preview(state);
-    }
-
-    marucam_reset_controls();
-
-    if (saved_frame.data) {
-        g_free(saved_frame.data);
-        saved_frame.data = NULL;
-    }
-    memset(&saved_frame, 0x00, sizeof(saved_frame));
-
-    v4l2_close(v4l2_fd);
-    v4l2_fd = 0;
-    INFO("Closed\n");
-}
diff --git a/tizen/src/hw/maru_camera_win32_interface.h b/tizen/src/hw/maru_camera_win32_interface.h
deleted file mode 100644 (file)
index 11e0e24..0000000
+++ /dev/null
@@ -1,934 +0,0 @@
-/*
- * Interface definition header for Windows host.
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- * JinHyung Jo <jinhyung.jo@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_CAMERA_INTERFACE_H_
-#define _MARU_CAMERA_INTERFACE_H_
-
-extern int hax_enabled(void);
-
-static const WCHAR HWCPinName[] = L"HWCInputPin\0";
-static const WCHAR HWCFilterName[] = L"HWCFilter\0";
-
-/* Forward Declarations */
-FWD_DECL(IBaseFilter);
-FWD_DECL(IFilterGraph);
-
-/* defines */
-#define MAX_PIN_NAME     128
-#define MAX_FILTER_NAME  128
-
-#define DECLARE_INTERFACE2(i) \
-   _COM_interface i { CONST_VTABLE struct i##Vtbl *lpVtbl; }; \
-   typedef CONST_VTABLE struct i##Vtbl i##Vtbl; \
-   CONST_VTABLE struct i##Vtbl
-#define DECLARE_INTERFACE2_(i, b) DECLARE_INTERFACE2(i)
-
-typedef LONGLONG REFERENCE_TIME;
-typedef long OAFilterState;
-typedef DWORD_PTR HSEMAPHORE;
-typedef DWORD_PTR HEVENT;
-
-typedef enum _FilterState {
-  State_Stopped,
-  State_Paused,
-  State_Running
-} FILTER_STATE;
-
-typedef struct _FilterInfo {
-  WCHAR achName[MAX_FILTER_NAME];
-  IFilterGraph *pGraph;
-} FILTER_INFO;
-
-typedef enum _PinDirection {
-    PINDIR_INPUT    = 0,
-    PINDIR_OUTPUT   = (PINDIR_INPUT + 1)
-} PIN_DIRECTION;
-
-typedef struct _PinInfo {
-  IBaseFilter *pFilter;
-  PIN_DIRECTION dir;
-  WCHAR achName[MAX_PIN_NAME];
-} PIN_INFO;
-
-typedef struct _AllocatorProperties {
-  long cBuffers;
-  long cbBuffer;
-  long cbAlign;
-  long cbPrefix;
-} ALLOCATOR_PROPERTIES;
-
-typedef struct _AMMediaType {
-  GUID majortype;
-  GUID subtype;
-  BOOL bFixedSizeSamples;
-  BOOL bTemporalCompression;
-  ULONG lSampleSize;
-  GUID formattype;
-  IUnknown *pUnk;
-  ULONG cbFormat;
-  BYTE *pbFormat;
-} AM_MEDIA_TYPE;
-
-typedef enum tagVideoProcAmpFlags {
-    VideoProcAmp_Flags_Auto = 0x0001,
-    VideoProcAmp_Flags_Manual = 0x0002
-} VideoProcAmpFlags;
-
-typedef enum tagVideoProcAmpProperty {
-    VideoProcAmp_Brightness,
-    VideoProcAmp_Contrast,
-    VideoProcAmp_Hue,
-    VideoProcAmp_Saturation,
-    VideoProcAmp_Sharpness,
-    VideoProcAmp_Gamma,
-    VideoProcAmp_ColorEnable,
-    VideoProcAmp_WhiteBalance,
-    VideoProcAmp_BacklightCompensation,
-    VideoProcAmp_Gain
-} VideoProcAmpProperty;
-
-typedef struct tagVIDEOINFOHEADER {
-    RECT rcSource;
-    RECT rcTarget;
-    DWORD dwBitRate;
-    DWORD dwBitErrorRate;
-    REFERENCE_TIME AvgTimePerFrame;
-    BITMAPINFOHEADER bmiHeader;
-} VIDEOINFOHEADER;
-
-typedef struct _VIDEO_STREAM_CONFIG_CAPS {
-  GUID guid;
-  ULONG VideoStandard;
-  SIZE InputSize;
-  SIZE MinCroppingSize;
-  SIZE MaxCroppingSize;
-  int CropGranularityX;
-  int CropGranularityY;
-  int CropAlignX;
-  int CropAlignY;
-  SIZE MinOutputSize;
-  SIZE MaxOutputSize;
-  int OutputGranularityX;
-  int OutputGranularityY;
-  int StretchTapsX;
-  int StretchTapsY;
-  int ShrinkTapsX;
-  int ShrinkTapsY;
-  LONGLONG MinFrameInterval;
-  LONGLONG MaxFrameInterval;
-  LONG MinBitsPerSecond;
-  LONG MaxBitsPerSecond;
-} VIDEO_STREAM_CONFIG_CAPS;
-
-
-/* Interface & Class GUIDs */
-static const IID IID_IGrabCallback   = {0x4C337035,0xC89E,0x4B42,{0x9B,0x0C,0x36,0x74,0x44,0xDD,0x70,0xDD}};
-
-EXTERN_C const IID IID_IBaseFilter;
-EXTERN_C const IID IID_ICreateDevEnum;
-EXTERN_C const IID IID_IGraphBuilder;
-EXTERN_C const IID IID_IMediaSeeking;
-EXTERN_C const IID IID_IMediaEventSink;
-EXTERN_C const IID IID_IMemInputPin;
-EXTERN_C const IID IID_IEnumPins;
-EXTERN_C const IID IID_IMediaFilter;
-EXTERN_C const IID IID_IEnumMediaTypes;
-EXTERN_C const IID IID_IMemAllocator;
-EXTERN_C const IID IID_IPin;
-EXTERN_C const IID IID_ICaptureGraphBuilder2;
-EXTERN_C const IID IID_IFileSinkFilter;
-EXTERN_C const IID IID_IAMCopyCaptureFileProgress;
-EXTERN_C const IID IID_IEnumFilters;
-EXTERN_C const IID IID_IMediaSample;
-EXTERN_C const IID IID_IMediaControl;
-EXTERN_C const IID IID_IAMStreamConfig;
-EXTERN_C const IID IID_IAMVideoProcAmp;
-
-EXTERN_C const IID CLSID_CaptureGraphBuilder2;
-EXTERN_C const IID CLSID_VideoInputDeviceCategory;
-EXTERN_C const IID CLSID_AudioRender;
-EXTERN_C const IID CLSID_SystemDeviceEnum;
-EXTERN_C const IID CLSID_AudioRendererCategory;
-EXTERN_C const IID CLSID_FilterGraph;
-EXTERN_C const IID CLSID_InfTee;
-EXTERN_C const IID CLSID_VideoMixingRenderer9;
-EXTERN_C const IID CLSID_MemoryAllocator;
-
-
-/* other types GUIDs*/
-EXTERN_C const IID MEDIATYPE_Audio;
-EXTERN_C const IID MEDIATYPE_Video;
-EXTERN_C const IID MEDIATYPE_Stream;
-EXTERN_C const IID MEDIASUBTYPE_PCM;
-EXTERN_C const IID MEDIASUBTYPE_WAVE;
-EXTERN_C const IID MEDIASUBTYPE_Avi;
-EXTERN_C const IID MEDIASUBTYPE_RGB32;
-EXTERN_C const IID MEDIASUBTYPE_YV12;
-EXTERN_C const IID MEDIASUBTYPE_YUY2;
-EXTERN_C const IID MEDIASUBTYPE_I420;
-EXTERN_C const IID MEDIASUBTYPE_YUYV;
-EXTERN_C const IID FORMAT_WaveFormatEx;
-EXTERN_C const IID FORMAT_VideoInfo;
-EXTERN_C const IID FORMAT_VideoInfo2;
-EXTERN_C const IID PIN_CATEGORY_CAPTURE;
-EXTERN_C const IID PIN_CATEGORY_PREVIEW;
-
-
-#define MEDIATYPE_NULL       GUID_NULL
-#define MEDIASUBTYPE_NULL    GUID_NULL
-
-#define INTERFACE IGrabCallback
-DECLARE_INTERFACE_(IGrabCallback, IUnknown)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(Grab)(THIS_ ULONG,BYTE*) PURE;
-};
-#undef INTERFACE
-
-#ifdef COBJMACROS
-#define IGrabCallback_QueryInterface(T,a,b) (T)->lpVtbl->QueryInterface(T,a,b)
-#define IGrabCallback_AddRef(T) (T)->lpVtbl->AddRef(T)
-#define IGrabCallback_Release(T) (T)->lpVtbl->Release(T)
-#define IGrabCallback_Grab(T,a,b) (T)->lpVtbl->Grab(T,a,b)
-#endif /* COBJMACROS */
-
-#define INTERFACE IAMCopyCaptureFileProgress
-DECLARE_INTERFACE_(IAMCopyCaptureFileProgress, IUnknown)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(Progress)(THIS_ int) PURE;
-};
-#undef INTERFACE
-#define INTERFACE IReferenceClock
-DECLARE_INTERFACE_(IReferenceClock, IUnknown)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(GetTime)(THIS_ REFERENCE_TIME *) PURE;
-    STDMETHOD(AdviseTime)(THIS_ REFERENCE_TIME, REFERENCE_TIME, HEVENT, DWORD_PTR *) PURE;
-    STDMETHOD(AdvisePeriodic)(THIS_ REFERENCE_TIME, REFERENCE_TIME, HSEMAPHORE, DWORD_PTR *) PURE;
-    STDMETHOD(Unadvise)(THIS_ DWORD_PTR) PURE;
-};
-#undef INTERFACE
-#define INTERFACE IEnumFilters
-DECLARE_INTERFACE_(IEnumFilters, IUnknown)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(Next)(THIS_ ULONG, IBaseFilter **, ULONG *) PURE;
-    STDMETHOD(Skip)(THIS_ ULONG) PURE;
-    STDMETHOD(Reset)(THIS) PURE;
-    STDMETHOD(Clone)(THIS_ IEnumFilters **) PURE;
-};
-#undef INTERFACE
-#define INTERFACE IEnumMediaTypes
-DECLARE_INTERFACE_(IEnumMediaTypes, IUnknown)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(Next)(THIS_ ULONG, AM_MEDIA_TYPE **, ULONG *) PURE;
-    STDMETHOD(Skip)(THIS_ ULONG) PURE;
-    STDMETHOD(Reset)(THIS) PURE;
-    STDMETHOD(Clone)(THIS_ IEnumMediaTypes **) PURE;
-};
-#undef INTERFACE
-#define INTERFACE IPin
-DECLARE_INTERFACE_(IPin, IUnknown)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(Connect)(THIS_ IPin *, const AM_MEDIA_TYPE *) PURE;
-    STDMETHOD(ReceiveConnection)(THIS_ IPin *, const AM_MEDIA_TYPE *) PURE;
-    STDMETHOD(Disconnect)(THIS) PURE;
-    STDMETHOD(ConnectedTo)(THIS_ IPin **) PURE;
-    STDMETHOD(ConnectionMediaType)(THIS_ AM_MEDIA_TYPE *) PURE;
-    STDMETHOD(QueryPinInfo)(THIS_ PIN_INFO *) PURE;
-    STDMETHOD(QueryDirection)(THIS_ PIN_DIRECTION *) PURE;
-    STDMETHOD(QueryId)(THIS_ LPWSTR *) PURE;
-    STDMETHOD(QueryAccept)(THIS_ const AM_MEDIA_TYPE *) PURE;
-    STDMETHOD(EnumMediaTypes)(THIS_ IEnumMediaTypes **) PURE;
-    STDMETHOD(QueryInternalConnections)(THIS_ IPin **, ULONG *) PURE;
-    STDMETHOD(EndOfStream)(THIS) PURE;
-    STDMETHOD(BeginFlush)(THIS) PURE;
-    STDMETHOD(EndFlush)(THIS) PURE;
-    STDMETHOD(NewSegment)(THIS_ REFERENCE_TIME, REFERENCE_TIME, double) PURE;
-};
-#undef INTERFACE
-#define INTERFACE IEnumPins
-DECLARE_INTERFACE_(IEnumPins, IUnknown)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(Next)(THIS_ ULONG, IPin **, ULONG *) PURE;
-    STDMETHOD(Skip)(THIS_ ULONG) PURE;
-    STDMETHOD(Reset)(THIS) PURE;
-    STDMETHOD(Clone)(THIS_ IEnumPins **) PURE;
-};
-#undef INTERFACE
-#define INTERFACE IMediaFilter
-DECLARE_INTERFACE_(IMediaFilter, IPersist)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(GetClassID)(THIS_ CLSID*) PURE;
-    STDMETHOD(Stop)(THIS) PURE;
-    STDMETHOD(Pause)(THIS) PURE;
-    STDMETHOD(Run)(THIS_ REFERENCE_TIME) PURE;
-    STDMETHOD(GetState)(THIS_ DWORD, FILTER_STATE *) PURE;
-    STDMETHOD(SetSyncSource)(THIS_ IReferenceClock *) PURE;
-    STDMETHOD(GetSyncSource)(THIS_ IReferenceClock **) PURE;
-};
-#undef INTERFACE
-#define INTERFACE IBaseFilter
-DECLARE_INTERFACE2_(IBaseFilter, IMediaFilter)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(GetClassID)(THIS_ CLSID*) PURE;
-    STDMETHOD(Stop)(THIS) PURE;
-    STDMETHOD(Pause)(THIS) PURE;
-    STDMETHOD(Run)(THIS_ REFERENCE_TIME) PURE;
-    STDMETHOD(GetState)(THIS_ DWORD, FILTER_STATE *) PURE;
-    STDMETHOD(SetSyncSource)(THIS_ IReferenceClock *) PURE;
-    STDMETHOD(GetSyncSource)(THIS_ IReferenceClock **) PURE;
-    STDMETHOD(EnumPins)(THIS_ IEnumPins **) PURE;
-    STDMETHOD(FindPin)(THIS_ LPCWSTR, IPin **) PURE;
-    STDMETHOD(QueryFilterInfo)(THIS_ FILTER_INFO *) PURE;
-    STDMETHOD(JoinFilterGraph)(THIS_ IFilterGraph *, LPCWSTR) PURE;
-    STDMETHOD(QueryVendorInfo)(THIS_ LPWSTR *) PURE;
-};
-#undef INTERFACE
-#define INTERFACE IFilterGraph
-DECLARE_INTERFACE2_(IFilterGraph, IUnknown)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(AddFilter)(THIS_ IBaseFilter *, LPCWSTR) PURE;
-    STDMETHOD(RemoveFilter)(THIS_ IBaseFilter *) PURE;
-    STDMETHOD(EnumFilters)(THIS_ IEnumFilters **) PURE;
-    STDMETHOD(FindFilterByName)(THIS_ LPCWSTR, IBaseFilter **) PURE;
-    STDMETHOD(ConnectDirect)(THIS_ IPin *, IPin *, const AM_MEDIA_TYPE *) PURE;
-    STDMETHOD(Reconnect)(THIS_ IPin *) PURE;
-    STDMETHOD(Disconnect)(THIS_ IPin *) PURE;
-    STDMETHOD(SetDefaultSyncSource)(THIS) PURE;
-};
-#undef INTERFACE
-#define INTERFACE IGraphBuilder
-DECLARE_INTERFACE_(IGraphBuilder ,IFilterGraph)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(AddFilter)(THIS_ IBaseFilter *, LPCWSTR) PURE;
-    STDMETHOD(RemoveFilter)(THIS_ IBaseFilter *) PURE;
-    STDMETHOD(EnumFilters)(THIS_ IEnumFilters **) PURE;
-    STDMETHOD(FindFilterByName)(THIS_ LPCWSTR, IBaseFilter **) PURE;
-    STDMETHOD(ConnectDirect)(THIS_ IPin *, IPin *, const AM_MEDIA_TYPE *) PURE;
-    STDMETHOD(Reconnect)(THIS_ IPin *) PURE;
-    STDMETHOD(Disconnect)(THIS_ IPin *) PURE;
-    STDMETHOD(SetDefaultSyncSource)(THIS) PURE;
-    STDMETHOD(Connect)(THIS_ IPin *, IPin *) PURE;
-    STDMETHOD(Render)(THIS_ IPin *) PURE;
-    STDMETHOD(RenderFile)(THIS_ LPCWSTR, LPCWSTR) PURE;
-    STDMETHOD(AddSourceFilter)(THIS_ LPCWSTR, LPCWSTR, IBaseFilter **) PURE;
-    STDMETHOD(SetLogFile)(THIS_ DWORD_PTR) PURE;
-    STDMETHOD(Abort)(THIS) PURE;
-    STDMETHOD(ShouldOperationContinue)(THIS) PURE;
-};
-#undef INTERFACE
-#define INTERFACE ICreateDevEnum
-DECLARE_INTERFACE_(ICreateDevEnum, IUnknown)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(CreateClassEnumerator)(THIS_ REFCLSID, IEnumMoniker **, DWORD) PURE;
-};
-#undef INTERFACE
-#define INTERFACE IMediaSample
-DECLARE_INTERFACE_(IMediaSample, IUnknown)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(GetPointer)(THIS_ BYTE **) PURE;
-    STDMETHOD_(long, GetSize)(THIS) PURE;
-    STDMETHOD(GetTime)(THIS_ REFERENCE_TIME *, REFERENCE_TIME *) PURE;
-    STDMETHOD(SetTime)(THIS_ REFERENCE_TIME *, REFERENCE_TIME *) PURE;
-    STDMETHOD(IsSyncPoint)(THIS) PURE;
-    STDMETHOD(SetSyncPoint)(THIS_ BOOL) PURE;
-    STDMETHOD(IsPreroll)(THIS) PURE;
-    STDMETHOD(SetPreroll)(THIS_ BOOL) PURE;
-    STDMETHOD_(long, GetActualDataLength)(THIS) PURE;
-    STDMETHOD(SetActualDataLength)(THIS_ long) PURE;
-    STDMETHOD(GetMediaType)(THIS_ AM_MEDIA_TYPE **) PURE;
-    STDMETHOD(SetMediaType)(THIS_ AM_MEDIA_TYPE *) PURE;
-    STDMETHOD(IsDiscontinuity)(THIS) PURE;
-    STDMETHOD(SetDiscontinuity)(THIS_ BOOL) PURE;
-    STDMETHOD(GetMediaTime)(THIS_ LONGLONG *, LONGLONG *) PURE;
-    STDMETHOD(SetMediaTime)(THIS_ LONGLONG *, LONGLONG *) PURE;
-};
-#undef INTERFACE
-#define INTERFACE IMemAllocator
-DECLARE_INTERFACE_(IMemAllocator, IUnknown)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(SetProperties)(THIS_ ALLOCATOR_PROPERTIES *, ALLOCATOR_PROPERTIES *) PURE;
-    STDMETHOD(GetProperties)(THIS_ ALLOCATOR_PROPERTIES *) PURE;
-    STDMETHOD(Commit)(THIS) PURE;
-    STDMETHOD(Decommit)(THIS) PURE;
-    STDMETHOD(GetBuffer)(THIS_ IMediaSample **, REFERENCE_TIME *, REFERENCE_TIME *, DWORD) PURE;
-    STDMETHOD(ReleaseBuffer)(THIS_ IMediaSample *) PURE;
-
-};
-#undef INTERFACE
-#define INTERFACE IMemInputPin
-DECLARE_INTERFACE_(IMemInputPin, IUnknown)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(GetAllocator)(THIS_ IMemAllocator **) PURE;
-    STDMETHOD(NotifyAllocator)(THIS_ IMemAllocator *, BOOL) PURE;
-    STDMETHOD(GetAllocatorRequirements)(THIS_ ALLOCATOR_PROPERTIES *) PURE;
-    STDMETHOD(Receive)(THIS_ IMediaSample *) PURE;
-    STDMETHOD(ReceiveMultiple)(THIS_ IMediaSample **, long, long *) PURE;
-    STDMETHOD(ReceiveCanBlock)(THIS) PURE;
-};
-#undef INTERFACE
-#define INTERFACE IFileSinkFilter
-DECLARE_INTERFACE_(IFileSinkFilter, IUnknown)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(SetFileName)(THIS_ LPCOLESTR,const AM_MEDIA_TYPE *) PURE;
-    STDMETHOD(GetCurFile)(THIS_ LPOLESTR *,AM_MEDIA_TYPE*) PURE;
-};
-#undef INTERFACE
-#define INTERFACE ICaptureGraphBuilder2
-DECLARE_INTERFACE_(ICaptureGraphBuilder2, IUnknown)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(SetFiltergraph)(THIS_ IGraphBuilder*) PURE;
-    STDMETHOD(GetFiltergraph)(THIS_ IGraphBuilder**) PURE;
-    STDMETHOD(SetOutputFileName)(THIS_ const GUID*,LPCOLESTR,IBaseFilter**,IFileSinkFilter**) PURE;
-    STDMETHOD(FindInterface)(THIS_ const GUID*,const GUID*,IBaseFilter*,REFIID,void**) PURE;
-    STDMETHOD(RenderStream)(THIS_ const GUID*,const GUID*,IUnknown*,IBaseFilter*,IBaseFilter*) PURE;
-    STDMETHOD(ControlStream)(THIS_ const GUID*,const GUID*,IBaseFilter*,REFERENCE_TIME*,REFERENCE_TIME*,WORD,WORD) PURE;
-    STDMETHOD(AllocCapFile)(THIS_ LPCOLESTR,DWORDLONG) PURE;
-    STDMETHOD(CopyCaptureFile)(THIS_ LPOLESTR,LPOLESTR,int,IAMCopyCaptureFileProgress*) PURE;
-    STDMETHOD(FindPin)(THIS_ IUnknown*,PIN_DIRECTION,const GUID*,const GUID*,BOOL,int,IPin**) PURE;
-};
-#undef INTERFACE
-#define INTERFACE IAMStreamConfig
-DECLARE_INTERFACE_(IAMStreamConfig, IUnknown)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(SetFormat)(THIS_ AM_MEDIA_TYPE*) PURE;
-    STDMETHOD(GetFormat)(THIS_ AM_MEDIA_TYPE**) PURE;
-    STDMETHOD(GetNumberOfCapabilities)(THIS_ int*,int*) PURE;
-    STDMETHOD(GetStreamCaps)(THIS_ int,AM_MEDIA_TYPE**,BYTE*) PURE;
-};
-#undef INTERFACE
-#define INTERFACE IAMVideoProcAmp
-DECLARE_INTERFACE_(IAMVideoProcAmp, IUnknown)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(GetRange)(THIS_ long,long*,long*,long*,long*,long*) PURE;
-    STDMETHOD(Set)(THIS_ long,long,long) PURE;
-    STDMETHOD(Get)(THIS_ long,long*,long*) PURE;
-};
-#undef INTERFACE
-#define INTERFACE IMediaControl
-DECLARE_INTERFACE_(IMediaControl, IDispatch)
-{
-    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
-    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
-    STDMETHOD_(ULONG, Release)(THIS) PURE;
-    STDMETHOD(GetTypeInfoCount)(THIS_ UINT*);
-    STDMETHOD(GetTypeInfo)(THIS_ UINT,LCID,ITypeInfo**);
-    STDMETHOD(GetIDsOfNames)(THIS_ REFIID,LPOLESTR*,UINT,LCID,DISPID*);
-    STDMETHOD(Invoke)(THIS_ DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*);
-    STDMETHOD(Run)(THIS);
-    STDMETHOD(Pause)(THIS);
-    STDMETHOD(Stop)(THIS);
-    STDMETHOD(GetState)(THIS_ LONG, OAFilterState*);
-    STDMETHOD(RenderFile)(THIS_ BSTR);
-    STDMETHOD(AddSourceFilter)(THIS_ BSTR,IDispatch**);
-    STDMETHOD(get_FilterCollection)(THIS_ IDispatch**);
-    STDMETHOD(get_RegFilterCollection)(THIS_ IDispatch**);
-    STDMETHOD(StopWhenReady)(THIS);
-};
-#undef INTERFACE
-
-#ifdef COBJMACROS
-#define ICreateDevEnum_QueryInterface(This,riid,ppvObject)  \
-    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
-#define ICreateDevEnum_AddRef(This) \
-    ((This)->lpVtbl->AddRef(This))
-#define ICreateDevEnum_Release(This)    \
-    ((This)->lpVtbl->Release(This))
-#define ICreateDevEnum_CreateClassEnumerator(This,clsidDeviceClass,ppEnumMoniker,dwFlags)   \
-    ((This)->lpVtbl->CreateClassEnumerator(This,clsidDeviceClass,ppEnumMoniker,dwFlags))
-#endif /* COBJMACROS */
-
-#ifdef COBJMACROS
-#define IPin_QueryInterface(This,riid,ppvObject)    \
-    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
-#define IPin_AddRef(This)   \
-    ((This)->lpVtbl->AddRef(This))
-#define IPin_Release(This)  \
-    ((This)->lpVtbl->Release(This))
-#define IPin_Connect(This,pReceivePin,pmt)  \
-    ((This)->lpVtbl->Connect(This,pReceivePin,pmt))
-#define IPin_ReceiveConnection(This,pConnector,pmt) \
-    ((This)->lpVtbl->ReceiveConnection(This,pConnector,pmt))
-#define IPin_Disconnect(This)   \
-    ((This)->lpVtbl->Disconnect(This))
-#define IPin_ConnectedTo(This,pPin) \
-    ((This)->lpVtbl->ConnectedTo(This,pPin))
-#define IPin_ConnectionMediaType(This,pmt)  \
-    ((This)->lpVtbl->ConnectionMediaType(This,pmt))
-#define IPin_QueryPinInfo(This,pInfo)   \
-    ((This)->lpVtbl->QueryPinInfo(This,pInfo))
-#define IPin_QueryDirection(This,pPinDir)   \
-    ((This)->lpVtbl->QueryDirection(This,pPinDir))
-#define IPin_QueryId(This,Id)   \
-    ((This)->lpVtbl->QueryId(This,Id))
-#define IPin_QueryAccept(This,pmt)  \
-    ((This)->lpVtbl->QueryAccept(This,pmt))
-#define IPin_EnumMediaTypes(This,ppEnum)    \
-    ((This)->lpVtbl->EnumMediaTypes(This,ppEnum))
-#define IPin_QueryInternalConnections(This,apPin,nPin)  \
-    ((This)->lpVtbl->QueryInternalConnections(This,apPin,nPin))
-#define IPin_EndOfStream(This)  \
-    ((This)->lpVtbl->EndOfStream(This))
-#define IPin_BeginFlush(This)   \
-    ((This)->lpVtbl->BeginFlush(This))
-#define IPin_EndFlush(This) \
-    ((This)->lpVtbl->EndFlush(This))
-#define IPin_NewSegment(This,tStart,tStop,dRate)    \
-    ((This)->lpVtbl->NewSegment(This,tStart,tStop,dRate))
-#endif /* COBJMACROS */
-
-#ifdef COBJMACROS
-#define IEnumPins_QueryInterface(This,riid,ppvObject)   \
-    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
-#define IEnumPins_AddRef(This)  \
-    ((This)->lpVtbl->AddRef(This))
-#define IEnumPins_Release(This) \
-    ((This)->lpVtbl->Release(This))
-#define IEnumPins_Next(This,cPins,ppPins,pcFetched) \
-    ((This)->lpVtbl->Next(This,cPins,ppPins,pcFetched))
-#define IEnumPins_Skip(This,cPins)  \
-    ((This)->lpVtbl->Skip(This,cPins))
-#define IEnumPins_Reset(This)   \
-    ((This)->lpVtbl->Reset(This))
-#define IEnumPins_Clone(This,ppEnum)    \
-    ((This)->lpVtbl->Clone(This,ppEnum))
-#endif /* COBJMACROS */
-
-#ifdef COBJMACROS
-#define IAMStreamConfig_QueryInterface(This,riid,ppvObject) \
-    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
-#define IAMStreamConfig_AddRef(This)    \
-    ((This)->lpVtbl->AddRef(This))
-#define IAMStreamConfig_Release(This)   \
-    ((This)->lpVtbl->Release(This))
-#define IAMStreamConfig_SetFormat(This,pmt) \
-    ((This)->lpVtbl->SetFormat(This,pmt))
-#define IAMStreamConfig_GetFormat(This,ppmt)    \
-    ((This)->lpVtbl->GetFormat(This,ppmt))
-#define IAMStreamConfig_GetNumberOfCapabilities(This,piCount,piSize)    \
-    ((This)->lpVtbl->GetNumberOfCapabilities(This,piCount,piSize))
-#define IAMStreamConfig_GetStreamCaps(This,iIndex,ppmt,pSCC)    \
-    ((This)->lpVtbl->GetStreamCaps(This,iIndex,ppmt,pSCC))
-#endif /* COBJMACROS */
-
-#ifdef COBJMACROS
-#define IFilterGraph_QueryInterface(This,riid,ppvObject)    \
-    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
-#define IFilterGraph_AddRef(This)   \
-    ((This)->lpVtbl->AddRef(This))
-#define IFilterGraph_Release(This)  \
-    ((This)->lpVtbl->Release(This))
-#define IFilterGraph_AddFilter(This,pFilter,pName)  \
-    ((This)->lpVtbl->AddFilter(This,pFilter,pName))
-#define IFilterGraph_RemoveFilter(This,pFilter) \
-    ((This)->lpVtbl->RemoveFilter(This,pFilter))
-#define IFilterGraph_EnumFilters(This,ppEnum)   \
-    ((This)->lpVtbl->EnumFilters(This,ppEnum))
-#define IFilterGraph_FindFilterByName(This,pName,ppFilter)  \
-    ((This)->lpVtbl->FindFilterByName(This,pName,ppFilter))
-#define IFilterGraph_ConnectDirect(This,ppinOut,ppinIn,pmt) \
-    ((This)->lpVtbl->ConnectDirect(This,ppinOut,ppinIn,pmt))
-#define IFilterGraph_Reconnect(This,ppin)   \
-    ((This)->lpVtbl->Reconnect(This,ppin))
-#define IFilterGraph_Disconnect(This,ppin)  \
-    ((This)->lpVtbl->Disconnect(This,ppin))
-#define IFilterGraph_SetDefaultSyncSource(This) \
-    ((This)->lpVtbl->SetDefaultSyncSource(This))
-#endif /* COBJMACROS */
-
-#ifdef COBJMACROS
-#define IMediaFilter_QueryInterface(This,riid,ppvObject)    \
-    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
-#define IMediaFilter_AddRef(This)   \
-    ((This)->lpVtbl->AddRef(This))
-#define IMediaFilter_Release(This)  \
-    ((This)->lpVtbl->Release(This))
-#define IMediaFilter_GetClassID(This,pClassID)  \
-    ((This)->lpVtbl->GetClassID(This,pClassID))
-#define IMediaFilter_Stop(This) \
-    ((This)->lpVtbl->Stop(This))
-#define IMediaFilter_Pause(This)    \
-    ((This)->lpVtbl->Pause(This))
-#define IMediaFilter_Run(This,tStart)   \
-    ((This)->lpVtbl->Run(This,tStart))
-#define IMediaFilter_GetState(This,dwMilliSecsTimeout,State)    \
-    ((This)->lpVtbl->GetState(This,dwMilliSecsTimeout,State))
-#define IMediaFilter_SetSyncSource(This,pClock) \
-    ((This)->lpVtbl->SetSyncSource(This,pClock))
-#define IMediaFilter_GetSyncSource(This,pClock) \
-    ((This)->lpVtbl->GetSyncSource(This,pClock))
-#endif /* COBJMACROS */
-
-#ifdef COBJMACROS
-#define IBaseFilter_QueryInterface(This,riid,ppvObject) \
-    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
-#define IBaseFilter_AddRef(This)    \
-    ((This)->lpVtbl->AddRef(This))
-#define IBaseFilter_Release(This)   \
-    ((This)->lpVtbl->Release(This))
-#define IBaseFilter_GetClassID(This,pClassID)   \
-    ((This)->lpVtbl->GetClassID(This,pClassID))
-#define IBaseFilter_Stop(This)  \
-    ((This)->lpVtbl->Stop(This))
-#define IBaseFilter_Pause(This) \
-    ((This)->lpVtbl->Pause(This))
-#define IBaseFilter_Run(This,tStart)    \
-    ((This)->lpVtbl->Run(This,tStart))
-#define IBaseFilter_GetState(This,dwMilliSecsTimeout,State) \
-    ((This)->lpVtbl->GetState(This,dwMilliSecsTimeout,State))
-#define IBaseFilter_SetSyncSource(This,pClock)  \
-    ((This)->lpVtbl->SetSyncSource(This,pClock))
-#define IBaseFilter_GetSyncSource(This,pClock)  \
-    ((This)->lpVtbl->GetSyncSource(This,pClock))
-#define IBaseFilter_EnumPins(This,ppEnum)   \
-    ((This)->lpVtbl->EnumPins(This,ppEnum))
-#define IBaseFilter_FindPin(This,Id,ppPin)  \
-    ((This)->lpVtbl->FindPin(This,Id,ppPin))
-#define IBaseFilter_QueryFilterInfo(This,pInfo) \
-    ((This)->lpVtbl->QueryFilterInfo(This,pInfo))
-#define IBaseFilter_JoinFilterGraph(This,pGraph,pName)  \
-    ((This)->lpVtbl->JoinFilterGraph(This,pGraph,pName))
-#define IBaseFilter_QueryVendorInfo(This,pVendorInfo)   \
-    ((This)->lpVtbl->QueryVendorInfo(This,pVendorInfo))
-#endif /* COBJMACROS */
-
-#ifdef COBJMACROS
-#define IMediaSample_QueryInterface(This,riid,ppvObject)    \
-    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
-#define IMediaSample_AddRef(This)   \
-    ((This)->lpVtbl->AddRef(This))
-#define IMediaSample_Release(This)  \
-    ((This)->lpVtbl->Release(This))
-#define IMediaSample_GetPointer(This,ppBuffer)  \
-    ((This)->lpVtbl->GetPointer(This,ppBuffer))
-#define IMediaSample_GetSize(This)  \
-        ((This)->lpVtbl->GetSize(This))
-#define IMediaSample_GetTime(This,pTimeStart,pTimeEnd)  \
-    ((This)->lpVtbl->GetTime(This,pTimeStart,pTimeEnd))
-#define IMediaSample_SetTime(This,pTimeStart,pTimeEnd)  \
-    ((This)->lpVtbl->SetTime(This,pTimeStart,pTimeEnd))
-#define IMediaSample_IsSyncPoint(This)  \
-    ((This)->lpVtbl->IsSyncPoint(This))
-#define IMediaSample_SetSyncPoint(This,bIsSyncPoint)    \
-    ((This)->lpVtbl->SetSyncPoint(This,bIsSyncPoint))
-#define IMediaSample_IsPreroll(This)    \
-    ((This)->lpVtbl->IsPreroll(This))
-#define IMediaSample_SetPreroll(This,bIsPreroll)    \
-    ((This)->lpVtbl->SetPreroll(This,bIsPreroll))
-#define IMediaSample_GetActualDataLength(This)  \
-    ((This)->lpVtbl->GetActualDataLength(This))
-#define IMediaSample_SetActualDataLength(This,length)   \
-    ((This)->lpVtbl->SetActualDataLength(This,length))
-#define IMediaSample_GetMediaType(This,ppMediaType) \
-    ((This)->lpVtbl->GetMediaType(This,ppMediaType))
-#define IMediaSample_SetMediaType(This,pMediaType)  \
-    ((This)->lpVtbl->SetMediaType(This,pMediaType))
-#define IMediaSample_IsDiscontinuity(This)  \
-    ((This)->lpVtbl->IsDiscontinuity(This))
-#define IMediaSample_SetDiscontinuity(This,bDiscontinuity)  \
-    ((This)->lpVtbl->SetDiscontinuity(This,bDiscontinuity))
-#define IMediaSample_GetMediaTime(This,pTimeStart,pTimeEnd) \
-    ((This)->lpVtbl->GetMediaTime(This,pTimeStart,pTimeEnd))
-#define IMediaSample_SetMediaTime(This,pTimeStart,pTimeEnd) \
-    ((This)->lpVtbl->SetMediaTime(This,pTimeStart,pTimeEnd))
-#endif /* COBJMACROS */
-
-#ifdef COBJMACROS
-#define IEnumFilters_QueryInterface(This,riid,ppvObject)    \
-    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
-#define IEnumFilters_AddRef(This)   \
-    ((This)->lpVtbl->AddRef(This))
-#define IEnumFilters_Release(This)  \
-    ((This)->lpVtbl->Release(This))
-#define IEnumFilters_Next(This,cFilters,ppFilter,pcFetched) \
-    ((This)->lpVtbl->Next(This,cFilters,ppFilter,pcFetched))
-#define IEnumFilters_Skip(This,cFilters)    \
-    ((This)->lpVtbl->Skip(This,cFilters))
-#define IEnumFilters_Reset(This)    \
-    ((This)->lpVtbl->Reset(This))
-#define IEnumFilters_Clone(This,ppEnum) \
-    ((This)->lpVtbl->Clone(This,ppEnum))
-#endif /* COBJMACROS */
-
-#ifdef COBJMACROS
-#define IMemAllocator_QueryInterface(This,riid,ppvObject)   \
-    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
-#define IMemAllocator_AddRef(This)  \
-    ((This)->lpVtbl->AddRef(This))
-#define IMemAllocator_Release(This) \
-    ((This)->lpVtbl->Release(This))
-#define IMemAllocator_SetProperties(This,pRequest,pActual)  \
-    ((This)->lpVtbl->SetProperties(This,pRequest,pActual))
-#define IMemAllocator_GetProperties(This,pProps)    \
-    ((This)->lpVtbl->GetProperties(This,pProps))
-#define IMemAllocator_Commit(This)  \
-    ((This)->lpVtbl->Commit(This))
-#define IMemAllocator_Decommit(This)    \
-    ((This)->lpVtbl->Decommit(This))
-#define IMemAllocator_GetBuffer(This,ppBuffer,pStartTime,pEndTime,dwFlags)  \
-    ((This)->lpVtbl->GetBuffer(This,ppBuffer,pStartTime,pEndTime,dwFlags))
-#define IMemAllocator_ReleaseBuffer(This,pBuffer)   \
-    ((This)->lpVtbl->ReleaseBuffer(This,pBuffer))
-#endif /* COBJMACROS */
-
-#ifdef COBJMACROS
-#define IMemInputPin_QueryInterface(This,riid,ppvObject)    \
-    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
-#define IMemInputPin_AddRef(This)   \
-    ((This)->lpVtbl->AddRef(This))
-#define IMemInputPin_Release(This)  \
-    ((This)->lpVtbl->Release(This))
-#define IMemInputPin_GetAllocator(This,ppAllocator) \
-    ((This)->lpVtbl->GetAllocator(This,ppAllocator))
-#define IMemInputPin_NotifyAllocator(This,pAllocator,bReadOnly) \
-    ((This)->lpVtbl->NotifyAllocator(This,pAllocator,bReadOnly))
-#define IMemInputPin_GetAllocatorRequirements(This,pProps)  \
-    ((This)->lpVtbl->GetAllocatorRequirements(This,pProps))
-#define IMemInputPin_Receive(This,pSample)  \
-    ((This)->lpVtbl->Receive(This,pSample))
-#define IMemInputPin_ReceiveMultiple(This,pSamples,nSamples,nSamplesProcessed)  \
-    ((This)->lpVtbl->ReceiveMultiple(This,pSamples,nSamples,nSamplesProcessed))
-#define IMemInputPin_ReceiveCanBlock(This)  \
-    ((This)->lpVtbl->ReceiveCanBlock(This))
-#endif /* COBJMACROS */
-
-#ifdef COBJMACROS
-#define IGraphBuilder_QueryInterface(This,riid,ppvObject)   \
-    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
-#define IGraphBuilder_AddRef(This)  \
-    ((This)->lpVtbl->AddRef(This))
-#define IGraphBuilder_Release(This) \
-    ((This)->lpVtbl->Release(This))
-#define IGraphBuilder_AddFilter(This,pFilter,pName) \
-    ((This)->lpVtbl->AddFilter(This,pFilter,pName))
-#define IGraphBuilder_RemoveFilter(This,pFilter)    \
-    ((This)->lpVtbl->RemoveFilter(This,pFilter))
-#define IGraphBuilder_EnumFilters(This,ppEnum)  \
-    ((This)->lpVtbl->EnumFilters(This,ppEnum))
-#define IGraphBuilder_FindFilterByName(This,pName,ppFilter) \
-    ((This)->lpVtbl->FindFilterByName(This,pName,ppFilter))
-#define IGraphBuilder_ConnectDirect(This,ppinOut,ppinIn,pmt)    \
-    ((This)->lpVtbl->ConnectDirect(This,ppinOut,ppinIn,pmt))
-#define IGraphBuilder_Reconnect(This,ppin)  \
-    ((This)->lpVtbl->Reconnect(This,ppin))
-#define IGraphBuilder_Disconnect(This,ppin) \
-    ((This)->lpVtbl->Disconnect(This,ppin))
-#define IGraphBuilder_SetDefaultSyncSource(This)    \
-    ((This)->lpVtbl->SetDefaultSyncSource(This))
-#define IGraphBuilder_Connect(This,ppinOut,ppinIn)  \
-    ((This)->lpVtbl->Connect(This,ppinOut,ppinIn))
-#define IGraphBuilder_Render(This,ppinOut)  \
-    ((This)->lpVtbl->Render(This,ppinOut))
-#define IGraphBuilder_RenderFile(This,lpcwstrFile,lpcwstrPlayList)  \
-    ((This)->lpVtbl->RenderFile(This,lpcwstrFile,lpcwstrPlayList))
-#define IGraphBuilder_AddSourceFilter(This,lpcwstrFileName,lpcwstrFilterName,ppFilter)  \
-    ((This)->lpVtbl->AddSourceFilter(This,lpcwstrFileName,lpcwstrFilterName,ppFilter))
-#define IGraphBuilder_SetLogFile(This,hFile)    \
-    ((This)->lpVtbl->SetLogFile(This,hFile))
-#define IGraphBuilder_Abort(This)   \
-    ((This)->lpVtbl->Abort(This))
-#define IGraphBuilder_ShouldOperationContinue(This) \
-    ((This)->lpVtbl->ShouldOperationContinue(This))
-#endif /* COBJMACROS */
-
-#ifdef COBJMACROS
-#define IEnumMediaTypes_QueryInterface(This,riid,ppvObject) \
-    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
-#define IEnumMediaTypes_AddRef(This)    \
-    ((This)->lpVtbl->AddRef(This))
-#define IEnumMediaTypes_Release(This)   \
-    ((This)->lpVtbl->Release(This))
-#define IEnumMediaTypes_Next(This,cMediaTypes,ppMediaTypes,pcFetched)   \
-    ((This)->lpVtbl->Next(This,cMediaTypes,ppMediaTypes,pcFetched))
-#define IEnumMediaTypes_Skip(This,cMediaTypes)  \
-    ((This)->lpVtbl->Skip(This,cMediaTypes))
-#define IEnumMediaTypes_Reset(This) \
-    ((This)->lpVtbl->Reset(This))
-#define IEnumMediaTypes_Clone(This,ppEnum)  \
-    ((This)->lpVtbl->Clone(This,ppEnum))
-#endif /* COBJMACROS */
-
-#ifdef COBJMACROS
-#define IMediaControl_QueryInterface(This,riid,ppvObject)   \
-    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
-#define IMediaControl_AddRef(This)  \
-    ((This)->lpVtbl->AddRef(This))
-#define IMediaControl_Release(This) \
-    ((This)->lpVtbl->Release(This))
-#define IMediaControl_GetTypeInfoCount(This,pctinfo)    \
-    ((This)->lpVtbl->GetTypeInfoCount(This,pctinfo))
-#define IMediaControl_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
-    ((This)->lpVtbl->GetTypeInfo(This,iTInfo,lcid,ppTInfo))
-#define IMediaControl_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)   \
-    ((This)->lpVtbl->GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId))
-#define IMediaControl_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
-    ((This)->lpVtbl->Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr))
-#define IMediaControl_Run(This) \
-    ((This)->lpVtbl->Run(This))
-#define IMediaControl_Pause(This)   \
-    ((This)->lpVtbl->Pause(This))
-#define IMediaControl_Stop(This)    \
-    ((This)->lpVtbl->Stop(This))
-#define IMediaControl_GetState(This,msTimeout,pfs)  \
-    ((This)->lpVtbl->GetState(This,msTimeout,pfs))
-#define IMediaControl_RenderFile(This,strFilename)  \
-    ((This)->lpVtbl->RenderFile(This,strFilename))
-#define IMediaControl_AddSourceFilter(This,strFilename,ppUnk)   \
-    ((This)->lpVtbl->AddSourceFilter(This,strFilename,ppUnk))
-#define IMediaControl_get_FilterCollection(This,ppUnk)  \
-    ((This)->lpVtbl->get_FilterCollection(This,ppUnk))
-#define IMediaControl_get_RegFilterCollection(This,ppUnk)   \
-    ((This)->lpVtbl->get_RegFilterCollection(This,ppUnk))
-#define IMediaControl_StopWhenReady(This)   \
-    ((This)->lpVtbl->StopWhenReady(This))
-#endif /* COBJMACROS */
-
-#ifdef COBJMACROS
-#define IAMVideoProcAmp_QueryInterface(This,riid,ppvObject) \
-    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
-#define IAMVideoProcAmp_AddRef(This)    \
-    ((This)->lpVtbl->AddRef(This))
-#define IAMVideoProcAmp_Release(This)   \
-    ((This)->lpVtbl->Release(This))
-#define IAMVideoProcAmp_GetRange(This,Property,pMin,pMax,pSteppingDelta,pDefault,pCapsFlags)    \
-    ((This)->lpVtbl->GetRange(This,Property,pMin,pMax,pSteppingDelta,pDefault,pCapsFlags))
-#define IAMVideoProcAmp_Set(This,Property,lValue,Flags) \
-    ((This)->lpVtbl->Set(This,Property,lValue,Flags))
-#define IAMVideoProcAmp_Get(This,Property,lValue,Flags) \
-    ((This)->lpVtbl->Get(This,Property,lValue,Flags))
-#endif /* COBJMACROS */
-
-#ifdef COBJMACROS
-#define IFileSinkFilter_QueryInterface(This,riid,ppvObject) \
-    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
-#define IFileSinkFilter_AddRef(This)    \
-    ((This)->lpVtbl->AddRef(This))
-#define IFileSinkFilter_Release(This)   \
-    ((This)->lpVtbl->Release(This))
-#define IFileSinkFilter_SetFileName(This,pszFileName,pmt)   \
-    ((This)->lpVtbl->SetFileName(This,pszFileName,pmt))
-#define IFileSinkFilter_GetCurFile(This,ppszFileName,pmt)   \
-    ((This)->lpVtbl->GetCurFile(This,ppszFileName,pmt))
-#endif /* COBJMACROS */
-
-#ifdef COBJMACROS
-#define IAMCopyCaptureFileProgress_QueryInterface(This,riid,ppvObject)  \
-    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
-#define IAMCopyCaptureFileProgress_AddRef(This) \
-    ((This)->lpVtbl->AddRef(This))
-#define IAMCopyCaptureFileProgress_Release(This)    \
-    ((This)->lpVtbl->Release(This))
-#define IAMCopyCaptureFileProgress_Progress(This,iProgress) \
-    ((This)->lpVtbl->Progress(This,iProgress))
-#endif /* COBJMACROS */
-
-
-#ifdef COBJMACROS
-#define ICaptureGraphBuilder2_QueryInterface(This,riid,ppvObject)   \
-    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
-#define ICaptureGraphBuilder2_AddRef(This)  \
-    ((This)->lpVtbl->AddRef(This))
-#define ICaptureGraphBuilder2_Release(This) \
-    ((This)->lpVtbl->Release(This))
-#define ICaptureGraphBuilder2_SetFiltergraph(This,pfg)  \
-    ((This)->lpVtbl->SetFiltergraph(This,pfg))
-#define ICaptureGraphBuilder2_GetFiltergraph(This,ppfg) \
-    ((This)->lpVtbl->GetFiltergraph(This,ppfg))
-#define ICaptureGraphBuilder2_SetOutputFileName(This,pType,lpstrFile,ppf,ppSink)    \
-    ((This)->lpVtbl->SetOutputFileName(This,pType,lpstrFile,ppf,ppSink))
-#define ICaptureGraphBuilder2_FindInterface(This,pCategory,pType,pf,riid,ppint) \
-    ((This)->lpVtbl->FindInterface(This,pCategory,pType,pf,riid,ppint))
-#define ICaptureGraphBuilder2_RenderStream(This,pCategory,pType,pSource,pfCompressor,pfRenderer)    \
-    ((This)->lpVtbl->RenderStream(This,pCategory,pType,pSource,pfCompressor,pfRenderer))
-#define ICaptureGraphBuilder2_ControlStream(This,pCategory,pType,pFilter,pstart,pstop,wStartCookie,wStopCookie) \
-    ((This)->lpVtbl->ControlStream(This,pCategory,pType,pFilter,pstart,pstop,wStartCookie,wStopCookie))
-#define ICaptureGraphBuilder2_AllocCapFile(This,lpstr,dwlSize)  \
-    ((This)->lpVtbl->AllocCapFile(This,lpstr,dwlSize))
-#define ICaptureGraphBuilder2_CopyCaptureFile(This,lpwstrOld,lpwstrNew,fAllowEscAbort,pCallback)    \
-    ((This)->lpVtbl->CopyCaptureFile(This,lpwstrOld,lpwstrNew,fAllowEscAbort,pCallback))
-#define ICaptureGraphBuilder2_FindPin(This,pSource,pindir,pCategory,pType,fUnconnected,num,ppPin)   \
-    ((This)->lpVtbl->FindPin(This,pSource,pindir,pCategory,pType,fUnconnected,num,ppPin))
-#endif /* COBJMACROS */
-
-#endif /* _MARU_CAMERA_INTERFACE_H_ */
diff --git a/tizen/src/hw/maru_camera_win32_pci.c b/tizen/src/hw/maru_camera_win32_pci.c
deleted file mode 100644 (file)
index 60ae648..0000000
+++ /dev/null
@@ -1,2798 +0,0 @@
-/*
- * Implementation of MARU Virtual Camera device by PCI bus on Windows.
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- * JinHyung Jo <jinhyung.jo@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 "qemu-common.h"
-#include "maru_camera_common.h"
-#include "debug_ch.h"
-
-#define CINTERFACE
-#define COBJMACROS
-#include "ocidl.h"
-#include "errors.h"      /* for VFW_E_XXXX */
-#include "mmsystem.h"    /* for MAKEFOURCC macro */
-#include "maru_camera_win32_interface.h"
-
-MULTI_DEBUG_CHANNEL(tizen, maru-camera);
-
-/*
- * COM Interface implementations
- *
- */
-
-#define SAFE_RELEASE(x) \
-    do { \
-        if (x) { \
-            (x)->lpVtbl->Release(x); \
-            x = NULL; \
-        } \
-    } while (0)
-
-typedef HRESULT (STDAPICALLTYPE *CallbackFn)(ULONG dwSize, BYTE *pBuffer);
-
-/*
- * HWCGrabCallback
- */
-
-typedef struct HWCGrabCallback {
-    IGrabCallback IGrabCallback_iface;
-    long m_cRef;
-    CallbackFn m_pCallback;
-    STDMETHODIMP (*SetCallback)(IGrabCallback *iface, CallbackFn pCallbackFn);
-} HWCGrabCallback;
-
-static inline HWCGrabCallback *impl_from_IGrabCallback(IGrabCallback *iface)
-{
-    return CONTAINING_RECORD(iface, HWCGrabCallback, IGrabCallback_iface);
-}
-
-static STDMETHODIMP HWCGrabCallback_QueryInterface(IGrabCallback *iface,
-                                                   REFIID riid, void **ppv)
-{
-    if (IsEqualIID(riid, &IID_IUnknown)) {
-        *ppv = (IUnknown *)iface;
-    } else if (IsEqualIID(riid, &IID_IGrabCallback)) {
-        *ppv = (IGrabCallback *)iface;
-    } else {
-        *ppv = NULL;
-        return E_NOINTERFACE;
-    }
-
-    IGrabCallback_AddRef(iface);
-    return S_OK;
-}
-
-static STDMETHODIMP_(ULONG) HWCGrabCallback_AddRef(IGrabCallback *iface)
-{
-    HWCGrabCallback *This = impl_from_IGrabCallback(iface);
-
-    return InterlockedIncrement(&This->m_cRef);
-}
-
-static STDMETHODIMP_(ULONG) HWCGrabCallback_Release(IGrabCallback *iface)
-{
-    HWCGrabCallback *This = impl_from_IGrabCallback(iface);
-
-    if (InterlockedDecrement(&This->m_cRef) == 0) {
-        This->m_pCallback = NULL;
-        g_free((void *)This);
-        This = NULL;
-        return 0;
-    }
-
-    return This->m_cRef;
-}
-
-static STDMETHODIMP HWCGrabCallback_Grab(IGrabCallback *iface,
-                                         ULONG dwSize, BYTE *pBuffer)
-{
-    HWCGrabCallback *This = impl_from_IGrabCallback(iface);
-
-    if (This->m_pCallback) {
-        HRESULT hr = This->m_pCallback(dwSize, pBuffer);
-        if (FAILED(hr)) {
-            return E_FAIL;
-        } else {
-            return S_OK;
-        }
-    }
-
-    return E_FAIL;
-}
-
-static STDMETHODIMP HWCGrabCallback_SetCallback(IGrabCallback *iface,
-                                                CallbackFn pCallbackFn)
-{
-    HWCGrabCallback *This = impl_from_IGrabCallback(iface);
-
-    This->m_pCallback = pCallbackFn;
-    return S_OK;
-}
-
-static IGrabCallbackVtbl HWCGrabCallback_Vtbl = {
-        HWCGrabCallback_QueryInterface,
-        HWCGrabCallback_AddRef,
-        HWCGrabCallback_Release,
-        HWCGrabCallback_Grab
-};
-
-static STDMETHODIMP HWCGrabCallback_Construct(IGrabCallback **ppv)
-{
-    HWCGrabCallback *This =
-            (HWCGrabCallback *)g_malloc0(sizeof(HWCGrabCallback));
-
-    if (!This) {
-        ERR("failed to HWCGrabCallback_Construct, E_OUTOFMEMORY\n");
-        return E_OUTOFMEMORY;
-    }
-
-    This->IGrabCallback_iface.lpVtbl = &HWCGrabCallback_Vtbl;
-    This->m_cRef = 1;
-    This->m_pCallback = NULL;
-    This->SetCallback = HWCGrabCallback_SetCallback;
-    *ppv = &This->IGrabCallback_iface;
-    return S_OK;
-}
-
-/*
- * HWCPin
- */
-
-typedef struct HWCInPin {
-    IPin IPin_iface;
-    IMemInputPin IMemInputPin_iface;
-    IBaseFilter *m_pCFilter;
-    IPin *m_pConnectedPin;
-    IGrabCallback *m_pCallback;
-    IMemAllocator *m_pAllocator;
-    BOOL m_bReadOnly;
-    long m_cRef;
-    STDMETHODIMP (*SetGrabCallbackIF)(IPin *iface, IGrabCallback *pCaptureCB);
-} HWCInPin;
-
-static inline HWCInPin *impl_from_IPin(IPin *iface)
-{
-    return CONTAINING_RECORD(iface, HWCInPin, IPin_iface);
-}
-
-static inline HWCInPin *impl_from_IMemInputPin(IMemInputPin *iface)
-{
-    return CONTAINING_RECORD(iface, HWCInPin, IMemInputPin_iface);
-}
-
-static STDMETHODIMP HWCPin_QueryInterface(IPin *iface, REFIID riid, void **ppv)
-{
-    HWCInPin *This = impl_from_IPin(iface);
-
-    if (IsEqualIID(riid, &IID_IUnknown)) {
-        *ppv = (IUnknown *)(&This->IPin_iface);
-        IPin_AddRef((IPin *)*ppv);
-    } else if (IsEqualIID(riid, &IID_IPin)) {
-        *ppv = (IPin *)(&This->IPin_iface);
-        IPin_AddRef((IPin *)*ppv);
-    } else if (IsEqualIID(riid, &IID_IMemInputPin)) {
-        *ppv = (IMemInputPin *)(&This->IMemInputPin_iface);
-        IPin_AddRef((IMemInputPin *)*ppv);
-    } else {
-        *ppv = NULL;
-        return E_NOINTERFACE;
-    }
-
-    return S_OK;
-}
-
-static STDMETHODIMP_(ULONG) HWCPin_AddRef(IPin *iface)
-{
-    HWCInPin *This = impl_from_IPin(iface);
-
-    return InterlockedIncrement(&This->m_cRef);
-}
-
-static STDMETHODIMP_(ULONG) HWCPin_Release(IPin *iface)
-{
-    HWCInPin *This = impl_from_IPin(iface);
-
-    if (InterlockedDecrement(&This->m_cRef) == 0) {
-        if (This->m_pCallback) {
-            SAFE_RELEASE(This->m_pCallback);
-        }
-        if (This->m_pConnectedPin) {
-            SAFE_RELEASE(This->m_pConnectedPin);
-        }
-        if (This->m_pAllocator) {
-            IMemAllocator_Decommit(This->m_pAllocator);
-            SAFE_RELEASE(This->m_pAllocator);
-        }
-        g_free((void *)This);
-        This = NULL;
-        return 0;
-    }
-    return This->m_cRef;
-}
-
-static STDMETHODIMP HWCPin_Connect(IPin *iface,
-                                   IPin *pReceivePin,
-                                   const AM_MEDIA_TYPE *pmt)
-{
-    HWCInPin *This = impl_from_IPin(iface);
-
-    if (!pReceivePin) {
-        return E_POINTER;
-    }
-
-    if (This->m_pConnectedPin) {
-        return VFW_E_ALREADY_CONNECTED;
-    }
-
-    if (!pmt) {
-        return S_OK;
-    }
-    return S_FALSE;
-}
-
-static STDMETHODIMP HWCPin_ReceiveConnection(IPin *iface, IPin *pConnector,
-                                             const AM_MEDIA_TYPE *pmt)
-{
-    PIN_DIRECTION pd;
-    FILTER_STATE fs;
-    HWCInPin *This = impl_from_IPin(iface);
-
-    if (pConnector == NULL || pmt == NULL) {
-        return E_POINTER;
-    }
-
-    if (This->m_pConnectedPin) {
-        return VFW_E_ALREADY_CONNECTED;
-    }
-    IBaseFilter_GetState(This->m_pCFilter, 0, &fs);
-    if (fs != State_Stopped) {
-        return VFW_E_NOT_STOPPED;
-    }
-    IPin_QueryDirection(pConnector, &pd);
-    if (pd == PINDIR_INPUT) {
-        return VFW_E_INVALID_DIRECTION;
-    }
-
-    This->m_pConnectedPin = pConnector;
-    IPin_AddRef(This->m_pConnectedPin);
-    return S_OK;
-}
-
-static STDMETHODIMP HWCPin_Disconnect(IPin *iface)
-{
-    HWCInPin *This = impl_from_IPin(iface);
-
-    HRESULT hr;
-    FILTER_STATE fs;
-    IBaseFilter_GetState(This->m_pCFilter, 0, &fs);
-    if (fs != State_Stopped) {
-        return VFW_E_NOT_STOPPED;
-    }
-    if (This->m_pConnectedPin == NULL) {
-        hr = S_FALSE;
-    } else {
-        if (This->m_pAllocator) {
-            hr = IMemAllocator_Decommit(This->m_pAllocator);
-            if (FAILED(hr)) {
-                return hr;
-            }
-            SAFE_RELEASE(This->m_pAllocator);
-        }
-        SAFE_RELEASE(This->m_pConnectedPin);
-        hr = S_OK;
-    }
-    return hr;
-}
-
-static STDMETHODIMP HWCPin_ConnectedTo(IPin *iface, IPin **ppPin)
-{
-    HWCInPin *This = impl_from_IPin(iface);
-
-    if (ppPin == NULL) {
-        return E_POINTER;
-    }
-
-    if (This->m_pConnectedPin == NULL) {
-        *ppPin = NULL;
-        return VFW_E_NOT_CONNECTED;
-    } else {
-        *ppPin = This->m_pConnectedPin;
-        IPin_AddRef(This->m_pConnectedPin);
-    }
-    return S_OK;
-}
-
-static STDMETHODIMP HWCPin_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *pmt)
-{
-    if (pmt == NULL) {
-        return E_POINTER;
-    }
-    return VFW_E_NOT_CONNECTED;
-}
-
-static STDMETHODIMP HWCPin_QueryPinInfo(IPin *iface, PIN_INFO *pInfo)
-{
-    HWCInPin *This = impl_from_IPin(iface);
-
-    if (pInfo == NULL) {
-        return E_POINTER;
-    }
-
-    pInfo->pFilter = This->m_pCFilter;
-    if (This->m_pCFilter) {
-        IBaseFilter_AddRef(This->m_pCFilter);
-    }
-    memcpy((void *)pInfo->achName, (void *)HWCPinName, sizeof(HWCPinName));
-    pInfo->dir = PINDIR_INPUT;
-    return S_OK;
-}
-
-static STDMETHODIMP HWCPin_QueryDirection(IPin *iface, PIN_DIRECTION *pPinDir)
-{
-    if (pPinDir == NULL) {
-        return E_POINTER;
-    }
-    *pPinDir = PINDIR_INPUT;
-    return S_OK;
-}
-
-static STDMETHODIMP HWCPin_QueryId(IPin *iface, LPWSTR *Id)
-{
-    PVOID pId;
-    if (Id == NULL) {
-        return E_POINTER;
-    }
-    pId = CoTaskMemAlloc(sizeof(HWCPinName));
-    memcpy((void *)pId, (void *)HWCPinName, sizeof(HWCPinName));
-    *Id = (LPWSTR)pId;
-    return S_OK;
-}
-
-static STDMETHODIMP HWCPin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt)
-{
-    if (pmt == NULL) {
-        return E_POINTER;
-    }
-    return S_OK;
-}
-
-static STDMETHODIMP HWCPin_EnumMediaTypes(IPin *iface,
-                                          IEnumMediaTypes **ppEnum)
-{
-    if (ppEnum == NULL) {
-            return E_POINTER;
-    }
-    return E_NOTIMPL;
-}
-
-static STDMETHODIMP HWCPin_QueryInternalConnections(IPin *iface,
-                                                    IPin **ppPin,
-                                                    ULONG *nPin)
-{
-    return E_NOTIMPL;
-}
-
-static STDMETHODIMP HWCPin_EndOfStream(IPin *iface)
-{
-    return S_OK;
-}
-
-static STDMETHODIMP HWCPin_BeginFlush(IPin *iface)
-{
-    return S_OK;
-}
-
-static STDMETHODIMP HWCPin_EndFlush(IPin *iface)
-{
-    return S_OK;
-}
-
-static STDMETHODIMP HWCPin_NewSegment(IPin *iface, REFERENCE_TIME tStart,
-                                      REFERENCE_TIME tStop, double dRate)
-{
-    return S_OK;
-}
-
-static STDMETHODIMP HWCMemInputPin_QueryInterface(IMemInputPin *iface,
-                                                  REFIID riid, void **ppv)
-{
-    HWCInPin *This = impl_from_IMemInputPin(iface);
-
-    if (IsEqualIID(riid, &IID_IUnknown)) {
-        *ppv = (IUnknown *)(&This->IMemInputPin_iface);
-        IPin_AddRef((IPin *)*ppv);
-    } else if (IsEqualIID(riid, &IID_IPin)) {
-        *ppv = (IPin *)(&This->IPin_iface);
-        IPin_AddRef((IPin *)*ppv);
-    } else if (IsEqualIID(riid, &IID_IMemInputPin)) {
-        *ppv = (IMemInputPin *)(&This->IMemInputPin_iface);
-        IPin_AddRef((IMemInputPin *)*ppv);
-    } else {
-        *ppv = NULL;
-        return E_NOINTERFACE;
-    }
-
-    return S_OK;
-}
-
-static STDMETHODIMP_(ULONG) HWCMemInputPin_AddRef(IMemInputPin *iface)
-{
-    HWCInPin *This = impl_from_IMemInputPin(iface);
-
-    return InterlockedIncrement(&This->m_cRef);
-}
-
-static STDMETHODIMP_(ULONG) HWCMemInputPin_Release(IMemInputPin *iface)
-{
-    HWCInPin *This = impl_from_IMemInputPin(iface);
-
-    if (InterlockedDecrement(&This->m_cRef) == 0) {
-        if (This->m_pCallback) {
-            SAFE_RELEASE(This->m_pCallback);
-        }
-        if (This->m_pConnectedPin) {
-            SAFE_RELEASE(This->m_pConnectedPin);
-        }
-        if (This->m_pAllocator) {
-            IMemAllocator_Decommit(This->m_pAllocator);
-            SAFE_RELEASE(This->m_pAllocator);
-        }
-        g_free((void *)This);
-        This = NULL;
-        return 0;
-    }
-    return This->m_cRef;
-}
-
-static STDMETHODIMP HWCMemInputPin_GetAllocator(IMemInputPin *iface,
-                                                IMemAllocator **ppAllocator)
-{
-    HWCInPin *This = impl_from_IMemInputPin(iface);
-
-    if (ppAllocator == NULL) {
-        return E_POINTER;
-    }
-
-    if (This->m_pAllocator == NULL) {
-        HRESULT hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL,
-                                        CLSCTX_INPROC_SERVER,
-                                        &IID_IMemAllocator,
-                                        (void **)&(This->m_pAllocator));
-        if (FAILED(hr)) {
-            ERR("Failed to CoCreateInstance for retrieving MemoryAllocator\n");
-            return hr;
-        }
-    }
-    ASSERT(This->m_pAllocator != NULL);
-    *ppAllocator = This->m_pAllocator;
-    IMemAllocator_AddRef(This->m_pAllocator);
-
-    return S_OK;
-}
-
-static STDMETHODIMP HWCMemInputPin_NotifyAllocator(IMemInputPin *iface,
-                                                   IMemAllocator *pAllocator,
-                                                   BOOL bReadOnly)
-{
-    HWCInPin *This = impl_from_IMemInputPin(iface);
-
-    if (pAllocator == NULL) {
-        return E_POINTER;
-    }
-
-    IMemAllocator *pOldAllocator = This->m_pAllocator;
-    IMemAllocator_AddRef(pAllocator);
-    This->m_pAllocator = pAllocator;
-
-    if (pOldAllocator != NULL) {
-        SAFE_RELEASE(pOldAllocator);
-    }
-
-    This->m_bReadOnly = bReadOnly;
-
-    return S_OK;
-}
-
-static STDMETHODIMP HWCMemInputPin_GetAllocatorRequirements(
-                                   IMemInputPin *iface,
-                                   ALLOCATOR_PROPERTIES *pProps)
-{
-    return E_NOTIMPL;
-}
-
-static STDMETHODIMP HWCMemInputPin_Receive(IMemInputPin *iface,
-                                           IMediaSample *pSample)
-{
-    HWCInPin *This = impl_from_IMemInputPin(iface);
-
-    if (pSample == NULL) {
-        ERR("pSample is NULL\n");
-        return E_POINTER;
-    }
-    if (This->m_pCallback != NULL) {
-        HRESULT hr;
-        BYTE *pBuffer = NULL;
-        DWORD dwSize = 0;
-        dwSize = IMediaSample_GetSize(pSample);
-        hr = IMediaSample_GetPointer(pSample, &pBuffer);
-        if (FAILED(hr)) {
-            ERR("Receive function : "
-                "failed to IMediaSample_GetPointer, 0x%ld\n", hr);
-            return hr;
-        }
-        hr = IGrabCallback_Grab(This->m_pCallback, dwSize, pBuffer);
-        if (FAILED(hr)) {
-            ERR("Receive function : failed to IGrabCallback_Grab, 0x%ld\n",
-                hr);
-            return hr;
-        }
-    }
-    return S_OK;
-}
-
-static STDMETHODIMP HWCMemInputPin_ReceiveMultiple(IMemInputPin *iface,
-                                                   IMediaSample **pSamples,
-                                                   long nSamples,
-                                                   long *nSamplesProcessed)
-{
-    HRESULT hr = S_OK;
-
-    if (pSamples == NULL) {
-        return E_POINTER;
-    }
-
-    *nSamplesProcessed = 0;
-
-    while (nSamples-- > 0) {
-        hr = IMemInputPin_Receive(iface, pSamples[*nSamplesProcessed]);
-        if (hr != S_OK) {
-            break;
-        }
-        (*nSamplesProcessed)++;
-    }
-    return hr;
-}
-
-static STDMETHODIMP HWCMemInputPin_ReceiveCanBlock(IMemInputPin *iface)
-{
-    return S_FALSE;
-}
-
-static STDMETHODIMP HWCPin_SetCallback(IPin *iface, IGrabCallback *pCaptureCB)
-{
-    HWCInPin *This = impl_from_IPin(iface);
-
-    if (pCaptureCB == NULL) {
-        SAFE_RELEASE(This->m_pCallback);
-    } else {
-        This->m_pCallback = pCaptureCB;
-        IGrabCallback_AddRef(This->m_pCallback);
-    }
-
-    return S_OK;
-}
-
-
-static IPinVtbl HWCPin_Vtbl = {
-    HWCPin_QueryInterface,
-    HWCPin_AddRef,
-    HWCPin_Release,
-    HWCPin_Connect,
-    HWCPin_ReceiveConnection,
-    HWCPin_Disconnect,
-    HWCPin_ConnectedTo,
-    HWCPin_ConnectionMediaType,
-    HWCPin_QueryPinInfo,
-    HWCPin_QueryDirection,
-    HWCPin_QueryId,
-    HWCPin_QueryAccept,
-    HWCPin_EnumMediaTypes,
-    HWCPin_QueryInternalConnections,
-    HWCPin_EndOfStream,
-    HWCPin_BeginFlush,
-    HWCPin_EndFlush,
-    HWCPin_NewSegment
-};
-
-static IMemInputPinVtbl HWCMemInputPin_Vtbl = {
-    HWCMemInputPin_QueryInterface,
-    HWCMemInputPin_AddRef,
-    HWCMemInputPin_Release,
-    HWCMemInputPin_GetAllocator,
-    HWCMemInputPin_NotifyAllocator,
-    HWCMemInputPin_GetAllocatorRequirements,
-    HWCMemInputPin_Receive,
-    HWCMemInputPin_ReceiveMultiple,
-    HWCMemInputPin_ReceiveCanBlock
-};
-
-static STDMETHODIMP HWCInPin_Construct(IBaseFilter *pFilter, IPin **ppv)
-{
-    HWCInPin *This = (HWCInPin *)g_malloc0(sizeof(HWCInPin));
-
-    if (!This) {
-        ERR("failed to HWCInPin_Construct, E_OUTOFMEMORY\n");
-        return E_OUTOFMEMORY;
-    }
-
-    This->IPin_iface.lpVtbl = &HWCPin_Vtbl;
-    This->IMemInputPin_iface.lpVtbl = &HWCMemInputPin_Vtbl;
-    This->m_bReadOnly = FALSE;
-    This->m_pCFilter = pFilter;
-    This->m_pConnectedPin = NULL;
-    This->m_pCallback = NULL;
-    This->m_pAllocator = NULL;
-    This->m_cRef = 1;
-    This->SetGrabCallbackIF = HWCPin_SetCallback;
-    *ppv = &This->IPin_iface;
-
-    return S_OK;
-}
-
-/*
- * HWCEnumPins
- */
-
-typedef struct HWCEnumPins {
-    IEnumPins IEnumPins_iface;
-    IBaseFilter *m_pFilter;
-    int m_nPos;
-    long m_cRef;
-} HWCEnumPins;
-
-static inline HWCEnumPins *impl_from_IEnumPins(IEnumPins *iface)
-{
-    return CONTAINING_RECORD(iface, HWCEnumPins, IEnumPins_iface);
-}
-
-static STDMETHODIMP HWCEnumPins_QueryInterface(IEnumPins *iface,
-                                               REFIID riid, void **ppv)
-{
-    if (ppv == NULL) {
-        return E_POINTER;
-    }
-
-    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumPins)) {
-        *ppv = iface;
-    } else {
-        *ppv = NULL;
-        return E_NOINTERFACE;
-    }
-
-    IEnumPins_AddRef(iface);
-    return S_OK;
-}
-
-static STDMETHODIMP_(ULONG) HWCEnumPins_AddRef(IEnumPins *iface)
-{
-    HWCEnumPins *This = impl_from_IEnumPins(iface);
-
-    return InterlockedIncrement(&This->m_cRef);
-}
-
-static STDMETHODIMP_(ULONG) HWCEnumPins_Release(IEnumPins *iface)
-{
-    HWCEnumPins *This = impl_from_IEnumPins(iface);
-
-    if (InterlockedDecrement(&This->m_cRef) == 0) {
-        if (This->m_pFilter) {
-            SAFE_RELEASE(This->m_pFilter);
-        }
-        This->m_nPos = 0;
-        g_free((void *)This);
-        This = NULL;
-        return 0;
-    }
-    return This->m_cRef;
-}
-
-static STDMETHODIMP HWCEnumPins_Next(IEnumPins *iface, ULONG cPins,
-                                     IPin **ppPins, ULONG *pcFetched)
-{
-    ULONG fetched;
-    HWCEnumPins *This = impl_from_IEnumPins(iface);
-
-    if (ppPins == NULL) {
-        return E_POINTER;
-    }
-
-    if (This->m_nPos < 1 && cPins > 0) {
-        IPin *pPin;
-        IBaseFilter_FindPin(This->m_pFilter, HWCPinName, &pPin);
-        *ppPins = pPin;
-        fetched = 1;
-        This->m_nPos++;
-    } else {
-        fetched = 0;
-    }
-
-    if (pcFetched != NULL) {
-        *pcFetched = fetched;
-    }
-
-    return (fetched == cPins) ? S_OK : S_FALSE;
-}
-
-static STDMETHODIMP HWCEnumPins_Skip(IEnumPins *iface, ULONG cPins)
-{
-    HWCEnumPins *This = impl_from_IEnumPins(iface);
-    This->m_nPos += cPins;
-    return (This->m_nPos >= 1) ? S_FALSE : S_OK;
-}
-
-static STDMETHODIMP HWCEnumPins_Reset(IEnumPins *iface)
-{
-    HWCEnumPins *This = impl_from_IEnumPins(iface);
-    This->m_nPos = 0;
-    return S_OK;
-}
-
-static STDMETHODIMP HWCEnumPins_Construct(IBaseFilter *pFilter,
-                                          int nPos, IEnumPins **ppv);
-
-static STDMETHODIMP HWCEnumPins_Clone(IEnumPins *iface, IEnumPins **ppEnum)
-{
-    HWCEnumPins *This = impl_from_IEnumPins(iface);
-
-    if (ppEnum == NULL) {
-        return E_POINTER;
-    }
-
-    HWCEnumPins_Construct(This->m_pFilter, This->m_nPos, ppEnum);
-    if (*ppEnum == NULL) {
-        ERR("failed to HWCEnumPins_Construct in clone, E_OUTOFMEMORY\n");
-        return E_OUTOFMEMORY;
-    }
-
-    return S_OK;
-}
-
-static IEnumPinsVtbl HWCEnumPins_Vtbl = {
-    HWCEnumPins_QueryInterface,
-    HWCEnumPins_AddRef,
-    HWCEnumPins_Release,
-    HWCEnumPins_Next,
-    HWCEnumPins_Skip,
-    HWCEnumPins_Reset,
-    HWCEnumPins_Clone
-};
-
-
-static STDMETHODIMP HWCEnumPins_Construct(IBaseFilter *pFilter,
-                                          int nPos, IEnumPins **ppv)
-{
-    HWCEnumPins *This = (HWCEnumPins *)g_malloc0(sizeof(HWCEnumPins));
-
-    if (!This) {
-        ERR("failed to HWCEnumPins_Construct, E_OUTOFMEMORY\n");
-        return E_OUTOFMEMORY;
-    }
-
-    This->IEnumPins_iface.lpVtbl = &HWCEnumPins_Vtbl;
-    This->m_pFilter = pFilter;
-    if (This->m_pFilter) {
-        IBaseFilter_AddRef(This->m_pFilter);
-    }
-    This->m_cRef = 1;
-    This->m_nPos = nPos;
-    *ppv = &This->IEnumPins_iface;
-
-    return S_OK;
-}
-
-/*
- * HWCFilter
- */
-
-typedef struct HWCFilter {
-    IBaseFilter IBaseFilter_iface;
-    IPin *m_pPin;
-    IFilterGraph *m_pFilterGraph;
-    FILTER_STATE m_state;
-    long m_cRef;
-} HWCFilter;
-
-static inline HWCFilter *impl_from_IBaseFilter(IBaseFilter *iface)
-{
-    return CONTAINING_RECORD(iface, HWCFilter, IBaseFilter_iface);
-}
-
-static STDMETHODIMP HWCFilter_QueryInterface(IBaseFilter *iface,
-                                             REFIID riid, void **ppv)
-{
-    if (IsEqualIID(riid, &IID_IUnknown)) {
-        *ppv = (IUnknown *)iface;
-    } else if (IsEqualIID(riid, &IID_IPersist)) {
-        *ppv = (IPersist *)iface;
-    } else if (IsEqualIID(riid, &IID_IMediaFilter)) {
-        *ppv = (IMediaFilter *)iface;
-    } else if (IsEqualIID(riid, &IID_IBaseFilter)) {
-        *ppv = (IBaseFilter *)iface;
-    } else {
-        *ppv = NULL;
-        return E_NOINTERFACE;
-    }
-
-    IBaseFilter_AddRef(iface);
-    return S_OK;
-}
-
-static STDMETHODIMP_(ULONG) HWCFilter_AddRef(IBaseFilter *iface)
-{
-    HWCFilter *This = impl_from_IBaseFilter(iface);
-
-    return InterlockedIncrement(&This->m_cRef);
-}
-
-static STDMETHODIMP_(ULONG) HWCFilter_Release(IBaseFilter *iface)
-{
-    HWCFilter *This = impl_from_IBaseFilter(iface);
-
-    if (InterlockedDecrement(&This->m_cRef) == 0) {
-        if (This->m_pPin) {
-            SAFE_RELEASE(This->m_pPin);
-        }
-        g_free((void *)This);
-        This = NULL;
-        return 0;
-    }
-    return This->m_cRef;
-}
-
-static STDMETHODIMP HWCFilter_GetClassID(IBaseFilter *iface, CLSID *pClsID)
-{
-    if (pClsID == NULL) {
-        return E_POINTER;
-    }
-    return E_NOTIMPL;
-}
-
-static STDMETHODIMP HWCFilter_GetState(IBaseFilter *iface, DWORD dwMSecs,
-                                       FILTER_STATE *State)
-{
-    HWCFilter *This = impl_from_IBaseFilter(iface);
-    *State = This->m_state;
-    return S_OK;
-}
-
-static STDMETHODIMP HWCFilter_SetSyncSource(IBaseFilter *iface,
-                                            IReferenceClock *pClock)
-{
-    return S_OK;
-}
-
-static STDMETHODIMP HWCFilter_GetSyncSource(IBaseFilter *iface,
-                                            IReferenceClock **pClock)
-{
-    *pClock = NULL;
-    return S_OK;
-}
-
-static STDMETHODIMP HWCFilter_Stop(IBaseFilter *iface)
-{
-    HWCFilter *This = impl_from_IBaseFilter(iface);
-
-    IPin_EndFlush(This->m_pPin);
-    This->m_state = State_Stopped;
-    return S_OK;
-}
-
-static STDMETHODIMP HWCFilter_Pause(IBaseFilter *iface)
-{
-    HWCFilter *This = impl_from_IBaseFilter(iface);
-    This->m_state = State_Paused;
-    return S_OK;
-}
-
-static STDMETHODIMP HWCFilter_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
-{
-    HWCFilter *This = impl_from_IBaseFilter(iface);
-
-    if (This->m_state == State_Stopped) {
-        HRESULT hr;
-        hr = IBaseFilter_Pause(iface);
-        if (FAILED(hr)) {
-            ERR("HWCFilter_Run : Failed to IBaseFilter_Pause, ret=0xld%\n", hr);
-            return hr;
-        }
-    }
-
-    This->m_state = State_Running;
-    return S_OK;
-}
-
-static STDMETHODIMP HWCFilter_EnumPins(IBaseFilter *iface, IEnumPins **ppEnum)
-{
-    if (ppEnum == NULL) {
-        return E_POINTER;
-    }
-
-    HWCEnumPins_Construct(iface, 0, ppEnum);
-    return *ppEnum == NULL ? E_OUTOFMEMORY : S_OK;
-}
-
-static STDMETHODIMP HWCFilter_FindPin(IBaseFilter *iface, LPCWSTR Id,
-                                      IPin **ppPin)
-{
-    HWCFilter *This = impl_from_IBaseFilter(iface);
-
-    if (ppPin == NULL) {
-        return E_POINTER;
-    }
-
-    if (memcmp((void *)Id, (void *)HWCPinName, sizeof(HWCPinName))) {
-        return VFW_E_NOT_FOUND;
-    }
-
-    if (!This->m_pPin) {
-        HWCInPin_Construct(iface, &This->m_pPin);
-    }
-    *ppPin = This->m_pPin;
-
-    IPin_AddRef(This->m_pPin);
-    return S_OK;
-}
-
-static STDMETHODIMP HWCFilter_QueryFilterInfo(IBaseFilter *iface,
-                                              FILTER_INFO *pInfo)
-{
-    HWCFilter *This = impl_from_IBaseFilter(iface);
-
-    if (pInfo == NULL) {
-        return E_POINTER;
-    }
-
-    memcpy((void *)pInfo->achName,
-           (void *)HWCFilterName,
-           sizeof(HWCFilterName));
-    pInfo->pGraph = This->m_pFilterGraph;
-    if (This->m_pFilterGraph) {
-        IFilterGraph_AddRef(This->m_pFilterGraph);
-    }
-    return S_OK;
-}
-
-static STDMETHODIMP HWCFilter_JoinFilterGraph(IBaseFilter *iface,
-                                              IFilterGraph *pGraph,
-                                              LPCWSTR pName)
-{
-    HWCFilter *This = impl_from_IBaseFilter(iface);
-
-    This->m_pFilterGraph = pGraph;
-    return S_OK;
-}
-
-static STDMETHODIMP HWCFilter_QueryVendorInfo(IBaseFilter *iface,
-                                              LPWSTR *pVendorInfo)
-{
-    return E_NOTIMPL;
-}
-
-static IBaseFilterVtbl HWCFilter_Vtbl = {
-    HWCFilter_QueryInterface,
-    HWCFilter_AddRef,
-    HWCFilter_Release,
-    HWCFilter_GetClassID,
-    HWCFilter_Stop,
-    HWCFilter_Pause,
-    HWCFilter_Run,
-    HWCFilter_GetState,
-    HWCFilter_SetSyncSource,
-    HWCFilter_GetSyncSource,
-    HWCFilter_EnumPins,
-    HWCFilter_FindPin,
-    HWCFilter_QueryFilterInfo,
-    HWCFilter_JoinFilterGraph,
-    HWCFilter_QueryVendorInfo
-};
-
-static STDMETHODIMP HWCFilter_Construct(IBaseFilter **ppv)
-{
-    HWCFilter *This = (HWCFilter *)g_malloc0(sizeof(HWCFilter));
-
-    if (!This) {
-        ERR("failed to HWCFilter_Construct, E_OUTOFMEMORY\n");
-        return E_OUTOFMEMORY;
-    }
-
-    This->IBaseFilter_iface.lpVtbl = &HWCFilter_Vtbl;
-    This->m_pFilterGraph = NULL;
-    This->m_state = State_Stopped;
-    This->m_cRef = 1;
-    HWCInPin_Construct(&This->IBaseFilter_iface, &This->m_pPin);
-    *ppv = &This->IBaseFilter_iface;
-
-    return S_OK;
-}
-
-/**********************************************************
- *
- * Virtual device implementations
- *
- **********************************************************/
-
-
-/*
- * Declaration global variables for Win32 COM Interfaces
- */
-IGraphBuilder *g_pGB ;
-ICaptureGraphBuilder2 *g_pCGB;
-IMediaControl *g_pMediaControl;
-
-IPin *g_pOutputPin;
-IPin *g_pInputPin;
-IBaseFilter *g_pDstFilter;
-IBaseFilter *g_pSrcFilter;
-
-IGrabCallback *g_pCallback;
-
-/* V4L2 defines copy from videodev2.h */
-#define V4L2_CTRL_FLAG_SLIDER       0x0020
-
-#define V4L2_CTRL_CLASS_USER        0x00980000
-#define V4L2_CID_BASE               (V4L2_CTRL_CLASS_USER | 0x900)
-#define V4L2_CID_BRIGHTNESS         (V4L2_CID_BASE+0)
-#define V4L2_CID_CONTRAST           (V4L2_CID_BASE+1)
-#define V4L2_CID_SATURATION         (V4L2_CID_BASE+2)
-#define V4L2_CID_SHARPNESS          (V4L2_CID_BASE+27)
-
-#define V4L2_PIX_FMT_YUYV    MAKEFOURCC('Y', 'U', 'Y', 'V') /* 16  YUV 4:2:2 */
-#define V4L2_PIX_FMT_YUV420  MAKEFOURCC('Y', 'U', '1', '2') /* 12  YUV 4:2:0 */
-#define V4L2_PIX_FMT_YVU420  MAKEFOURCC('Y', 'V', '1', '2') /* 12  YVU 4:2:0 */
-#define V4L2_PIX_FMT_RGB24   MAKEFOURCC('R', 'G', 'B', '3') /* 24  RGB-8-8-8 */
-
-typedef struct tagMaruCamConvertPixfmt {
-    uint32_t fmt;   /* fourcc */
-    uint32_t bpp;   /* bits per pixel, 0 for compressed formats */
-    uint32_t needs_conversion;
-} MaruCamConvertPixfmt;
-
-static MaruCamConvertPixfmt supported_dst_pixfmts[] = {
-        { V4L2_PIX_FMT_YUYV, 16, 0 },
-        { V4L2_PIX_FMT_YUV420, 12, 0 },
-        { V4L2_PIX_FMT_YVU420, 12, 0 },
-};
-
-typedef struct tagMaruCamConvertFrameInfo {
-    uint32_t width;
-    uint32_t height;
-} MaruCamConvertFrameInfo;
-
-static MaruCamConvertFrameInfo supported_dst_frames[] = {
-        { 640, 480 },
-        { 352, 288 },
-        { 320, 240 },
-        { 176, 144 },
-        { 160, 120 },
-};
-
-#define MARUCAM_CTRL_VALUE_MAX      20
-#define MARUCAM_CTRL_VALUE_MIN      1
-#define MARUCAM_CTRL_VALUE_MID      10
-#define MARUCAM_CTRL_VALUE_STEP     1
-
-struct marucam_qctrl {
-    uint32_t id;
-    uint32_t hit;
-    long min;
-    long max;
-    long step;
-    long init_val;
-};
-
-static struct marucam_qctrl qctrl_tbl[] = {
-    { V4L2_CID_BRIGHTNESS, 0, },
-    { V4L2_CID_CONTRAST, 0, },
-    { V4L2_CID_SATURATION, 0, },
-    { V4L2_CID_SHARPNESS, 0, },
-};
-
-static MaruCamState *g_state;
-
-static uint32_t ready_count;
-static uint32_t cur_fmt_idx;
-static uint32_t cur_frame_idx;
-static void *grab_buf;
-static uint32_t g_dwSrcFmt;
-
-
-/*
- * Helper functions - converting image formats, converting values
- */
-
-static uint32_t get_bytesperline(uint32_t pixfmt, uint32_t width)
-{
-    uint32_t bytesperline;
-
-    switch (pixfmt) {
-    case V4L2_PIX_FMT_YUV420:
-    case V4L2_PIX_FMT_YVU420:
-        bytesperline = (width * 12) >> 3;
-        break;
-    case V4L2_PIX_FMT_YUYV:
-    default:
-        bytesperline = width * 2;
-        break;
-    }
-
-    return bytesperline;
-}
-
-static uint32_t get_sizeimage(uint32_t pixfmt, uint32_t width, uint32_t height)
-{
-    return get_bytesperline(pixfmt, width) * height;
-}
-
-void yuyv_to_yuv420(const unsigned char *src, unsigned char *dest,
-        uint32_t width, uint32_t height, uint32_t yvu);
-void rgb24_to_yuv420(const unsigned char *src, unsigned char *dest,
-        uint32_t width, uint32_t height, uint32_t yvu);
-void rgb24_to_yuyv(unsigned char *src, unsigned char *dest,
-        uint32_t width, uint32_t height);
-void yuv420_to_yvu420(unsigned char *src, unsigned char *dest,
-        uint32_t width, uint32_t height);
-void yuv420_to_yuyv(unsigned char *src, unsigned char *dest,
-        uint32_t width, uint32_t height);
-
-static long value_convert_from_guest(long min, long max, long value)
-{
-    double rate = 0.0;
-    long dist = 0, ret = 0;
-
-    dist = max - min;
-
-    if (dist < MARUCAM_CTRL_VALUE_MAX) {
-        rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;
-        ret = min + (int32_t)(value / rate);
-    } else {
-        rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;
-        ret = min + (int32_t)(rate * value);
-    }
-    return ret;
-}
-
-static long value_convert_to_guest(long min, long max, long value)
-{
-    double rate  = 0.0;
-    long dist = 0, ret = 0;
-
-    dist = max - min;
-
-    if (dist < MARUCAM_CTRL_VALUE_MAX) {
-        rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;
-        ret = (int32_t)((double)(value - min) * rate);
-    } else {
-        rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;
-        ret = (int32_t)((double)(value - min) / rate);
-    }
-
-    return ret;
-}
-
-/*
- * Callback function for grab frames
- */
-static STDMETHODIMP marucam_device_callbackfn(ULONG dwSize, BYTE *pBuffer)
-{
-    void *tmp_buf;
-    uint32_t width, height, fmt, imgsize;
-
-    width = supported_dst_frames[cur_frame_idx].width;
-    height = supported_dst_frames[cur_frame_idx].height;
-    fmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
-    imgsize = get_sizeimage(fmt, width, height);
-
-    if (imgsize > (uint32_t)dwSize) {
-        ERR("Image size is mismatched\n");
-        return E_FAIL;
-    }
-
-    switch (g_dwSrcFmt) {
-    case V4L2_PIX_FMT_YUYV:
-        switch (fmt) {
-        case V4L2_PIX_FMT_YUV420:
-            yuyv_to_yuv420(pBuffer, grab_buf, width, height, 0);
-            break;
-        case V4L2_PIX_FMT_YVU420:
-            yuyv_to_yuv420(pBuffer, grab_buf, width, height, 1);
-            break;
-        case V4L2_PIX_FMT_YUYV:
-            memcpy(grab_buf, (void *)pBuffer, (size_t)dwSize);
-            break;
-        default:
-            ERR("Invalid pixel format\n");
-            return E_FAIL;
-        }
-        break;
-    case V4L2_PIX_FMT_RGB24:
-        switch (fmt) {
-        case V4L2_PIX_FMT_YUV420:
-            rgb24_to_yuv420(pBuffer, grab_buf, width, height, 0);
-            break;
-        case V4L2_PIX_FMT_YVU420:
-            rgb24_to_yuv420(pBuffer, grab_buf, width, height, 1);
-            break;
-        case V4L2_PIX_FMT_YUYV:
-            rgb24_to_yuyv(pBuffer, grab_buf, width, height);
-            break;
-        default:
-            ERR("Invalid pixel format\n");
-            return E_FAIL;
-        }
-        break;
-    case V4L2_PIX_FMT_YUV420:
-        switch (fmt) {
-        case V4L2_PIX_FMT_YUV420:
-            memcpy(grab_buf, (void *)pBuffer, (size_t)dwSize);
-            break;
-        case V4L2_PIX_FMT_YVU420:
-            yuv420_to_yvu420(pBuffer, grab_buf, width, height);
-            break;
-        case V4L2_PIX_FMT_YUYV:
-            yuv420_to_yuyv(pBuffer, grab_buf, width, height);
-            break;
-        default:
-            ERR("Invalid pixel format\n");
-            return E_FAIL;
-        }
-        break;
-    default:
-        ERR("Invalid pixel format\n");
-        return E_FAIL;
-    }
-
-    qemu_mutex_lock(&g_state->thread_mutex);
-    if (g_state->streamon) {
-        if (ready_count < MARUCAM_SKIPFRAMES) {
-            /* skip a frame cause first some frame are distorted */
-            ++ready_count;
-            TRACE("skip %d frame\n", ready_count);
-            qemu_mutex_unlock(&g_state->thread_mutex);
-            return S_OK;
-        }
-        if (g_state->req_frame == 0) {
-            TRACE("there is no request\n");
-            qemu_mutex_unlock(&g_state->thread_mutex);
-            return S_OK;
-        }
-        tmp_buf = g_state->vaddr + g_state->buf_size * (g_state->req_frame - 1);
-        memcpy(tmp_buf, grab_buf, g_state->buf_size);
-        g_state->req_frame = 0; /* clear request */
-        g_state->isr |= 0x01;   /* set a flag of rasing a interrupt */
-        qemu_bh_schedule(g_state->tx_bh);
-    }
-    qemu_mutex_unlock(&g_state->thread_mutex);
-    return S_OK;
-}
-
-/*
- * Internal functions for manipulate interfaces
- */
-
-static STDMETHODIMP_(void) CloseInterfaces(void)
-{
-    if (g_pMediaControl) {
-        g_pMediaControl->lpVtbl->Stop(g_pMediaControl);
-    }
-
-    if (g_pOutputPin) {
-        g_pOutputPin->lpVtbl->Disconnect(g_pOutputPin);
-    }
-
-    SAFE_RELEASE(g_pGB);
-    SAFE_RELEASE(g_pCGB);
-    SAFE_RELEASE(g_pMediaControl);
-    SAFE_RELEASE(g_pOutputPin);
-    SAFE_RELEASE(g_pInputPin);
-    SAFE_RELEASE(g_pDstFilter);
-    SAFE_RELEASE(g_pSrcFilter);
-    SAFE_RELEASE(g_pCallback);
-}
-
-static STDMETHODIMP_(void) DeleteMediaType(AM_MEDIA_TYPE *pmt)
-{
-    if (pmt == NULL) {
-        return;
-    }
-
-    if (pmt->cbFormat != 0) {
-        CoTaskMemFree((PVOID)pmt->pbFormat);
-        pmt->cbFormat = 0;
-        pmt->pbFormat = NULL;
-    }
-    if (pmt->pUnk != NULL) {
-        pmt->pUnk->lpVtbl->Release(pmt->pUnk);
-        pmt->pUnk = NULL;
-    }
-
-    CoTaskMemFree((PVOID)pmt);
-}
-
-static STDMETHODIMP GetPin(IBaseFilter *pFilter,
-                           PIN_DIRECTION PinDir, IPin **ppPin)
-{
-    HRESULT hr;
-    IEnumPins *pEnum = NULL;
-    IPin *pPin = NULL;
-
-    if (ppPin == NULL) {
-        return E_POINTER;
-    }
-
-    hr = pFilter->lpVtbl->EnumPins(pFilter, &pEnum);
-    if (FAILED(hr)) {
-        return hr;
-    }
-
-    while (pEnum->lpVtbl->Next(pEnum, 1, &pPin, 0) == S_OK) {
-        PIN_DIRECTION PinDirThis;
-        hr = pPin->lpVtbl->QueryDirection(pPin, &PinDirThis);
-        if (FAILED(hr)) {
-            SAFE_RELEASE(pPin);
-            SAFE_RELEASE(pEnum);
-            return hr;
-        }
-        if (PinDir == PinDirThis) {
-            *ppPin = pPin;
-            SAFE_RELEASE(pEnum);
-            return S_OK;
-        }
-        SAFE_RELEASE(pPin);
-    }
-
-    SAFE_RELEASE(pEnum);
-    return S_FALSE;
-}
-
-static STDMETHODIMP GraphBuilder_Init(void)
-{
-    HRESULT hr;
-
-    hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC,
-                          &IID_IGraphBuilder, (void **)&g_pGB);
-    if (FAILED(hr)) {
-        ERR("Failed to create instance of GraphBuilder, 0x%x\n", hr);
-        return hr;
-    }
-
-    hr = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,
-                          &IID_ICaptureGraphBuilder2, (void **)&g_pCGB);
-    if (FAILED(hr)) {
-        ERR("Failed to create instance of CaptureGraphBuilder2, 0x%x\n", hr);
-        return hr;
-    }
-
-    hr = g_pCGB->lpVtbl->SetFiltergraph(g_pCGB, g_pGB);
-    if (FAILED(hr)) {
-        ERR("Failed to SetFiltergraph, 0x%x\n", hr);
-        return hr;
-    }
-
-    hr = g_pGB->lpVtbl->QueryInterface(g_pGB, &IID_IMediaControl,
-                                       (void **)&g_pMediaControl);
-    if (FAILED(hr)) {
-        ERR("Failed to QueryInterface for IMediaControl, 0x%x\n", hr);
-        return hr;
-    }
-
-    hr = HWCGrabCallback_Construct(&g_pCallback);
-    if (g_pCallback == NULL) {
-        hr = E_OUTOFMEMORY;
-    }
-
-    hr = ((HWCGrabCallback *)g_pCallback)->SetCallback(g_pCallback,
-                            (CallbackFn)marucam_device_callbackfn);
-
-    return hr;
-}
-
-static STDMETHODIMP BindSourceFilter(void)
-{
-    HRESULT hr;
-    ICreateDevEnum *pCreateDevEnum = NULL;
-    IEnumMoniker *pEnumMK = NULL;
-    IMoniker *pMoniKer;
-
-    hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
-                          &IID_ICreateDevEnum,
-                          (void **)&pCreateDevEnum);
-    if (FAILED(hr)) {
-        ERR("Failed to create instance of CreateDevEnum, 0x%x\n", hr);
-        return hr;
-    }
-
-    hr = pCreateDevEnum->lpVtbl->CreateClassEnumerator(pCreateDevEnum,
-                                      &CLSID_VideoInputDeviceCategory,
-                                      &pEnumMK, 0);
-    if (FAILED(hr)) {
-        ERR("Failed to get VideoInputDeviceCategory, 0x%x\n", hr);
-        SAFE_RELEASE(pCreateDevEnum);
-        return hr;
-    }
-
-    if (!pEnumMK) {
-        ERR("ClassEnumerator moniker is NULL\n");
-        SAFE_RELEASE(pCreateDevEnum);
-        return E_FAIL;
-    }
-    pEnumMK->lpVtbl->Reset(pEnumMK);
-
-    hr = pEnumMK->lpVtbl->Next(pEnumMK, 1, &pMoniKer, NULL);
-    if (hr == S_FALSE) {
-        hr = E_FAIL;
-    }
-    if (SUCCEEDED(hr)) {
-        IPropertyBag *pBag = NULL;
-        hr = pMoniKer->lpVtbl->BindToStorage(pMoniKer, 0, 0,
-                                             &IID_IPropertyBag,
-                                             (void **)&pBag);
-        if (SUCCEEDED(hr)) {
-            VARIANT var;
-            var.vt = VT_BSTR;
-            hr = pBag->lpVtbl->Read(pBag, L"FriendlyName", &var, NULL);
-            if (hr == NOERROR) {
-                hr = pMoniKer->lpVtbl->BindToObject(pMoniKer, NULL, NULL,
-                                                    &IID_IBaseFilter,
-                                                    (void **)&g_pSrcFilter);
-                if (FAILED(hr)) {
-                    ERR("Counldn't bind moniker to filter object!!\n");
-                } else {
-                    g_pSrcFilter->lpVtbl->AddRef(g_pSrcFilter);
-                }
-                SysFreeString(var.bstrVal);
-            }
-            SAFE_RELEASE(pBag);
-        }
-        SAFE_RELEASE(pMoniKer);
-    }
-
-    if (SUCCEEDED(hr)) {
-        hr = g_pGB->lpVtbl->AddFilter(g_pGB, g_pSrcFilter, L"Video Capture");
-        if (hr != S_OK && hr != S_FALSE) {
-            ERR("Counldn't add Video Capture filter to our graph!\n");
-            SAFE_RELEASE(g_pSrcFilter);
-        }
-    }
-    SAFE_RELEASE(pEnumMK);
-    SAFE_RELEASE(pCreateDevEnum);
-
-    return hr;
-}
-
-static STDMETHODIMP BindTargetFilter(void)
-{
-    HRESULT hr;
-    hr = HWCFilter_Construct(&g_pDstFilter);
-
-    if (SUCCEEDED(hr) && g_pDstFilter) {
-        hr = g_pGB->lpVtbl->AddFilter(g_pGB, g_pDstFilter, L"HWCFilter");
-        if (FAILED(hr)) {
-            ERR("Counldn't add HWCFilterr to our graph!\n");
-            SAFE_RELEASE(g_pDstFilter);
-        }
-    }
-    return hr;
-}
-
-static STDMETHODIMP ConnectFilters(void)
-{
-    HRESULT hr;
-
-    hr = GetPin(g_pSrcFilter, PINDIR_OUTPUT , &g_pOutputPin);
-    if (FAILED(hr)) {
-        ERR("Failed to get output pin. 0x%x\n", hr);
-        return hr;
-    }
-
-    hr = GetPin(g_pDstFilter, PINDIR_INPUT , &g_pInputPin);
-    if (FAILED(hr)) {
-        ERR("Failed to get input pin. 0x%x\n", hr);
-        return hr;
-    }
-
-    hr = g_pGB->lpVtbl->Connect(g_pGB, g_pOutputPin, g_pInputPin);
-    if (FAILED(hr)) {
-        ERR("Failed to connect pins. 0x%x\n", hr);
-    }
-    return hr;
-}
-
-static STDMETHODIMP DisconnectPins(void)
-{
-    HRESULT hr;
-
-    hr = g_pGB->lpVtbl->Disconnect(g_pGB, g_pOutputPin);
-    if (FAILED(hr)) {
-        ERR("Failed to disconnect output pin. 0x%x\n", hr);
-        return hr;
-    }
-
-    hr = g_pGB->lpVtbl->Disconnect(g_pGB, g_pInputPin);
-    if (FAILED(hr)) {
-        ERR("Failed to disconnect input pin. 0x%x\n", hr);
-    }
-
-    return hr;
-}
-
-static STDMETHODIMP RemoveFilters(void)
-{
-    HRESULT hr;
-
-    hr = g_pGB->lpVtbl->RemoveFilter(g_pGB, g_pSrcFilter);
-    if (FAILED(hr)) {
-        ERR("Failed to remove source filer. 0x%x\n", hr);
-        return hr;
-    }
-
-    hr = g_pGB->lpVtbl->RemoveFilter(g_pGB, g_pDstFilter);
-    if (FAILED(hr)) {
-        ERR("Failed to remove destination filer. 0x%x\n", hr);
-    }
-
-    return hr;
-}
-
-/* default fps is 15 */
-#define MARUCAM_DEFAULT_FRAMEINTERVAL    666666
-
-static STDMETHODIMP SetFormat(uint32_t dwWidth, uint32_t dwHeight,
-                              uint32_t dwDstFmt, uint32_t *dwSrcFmt)
-{
-    HRESULT hr;
-    IAMStreamConfig *pSConfig;
-    int iCount = 0, iSize = 0;
-    DWORD dwYUY2 = MAKEFOURCC('Y', 'U', 'Y', '2');
-    DWORD dwI420 = MAKEFOURCC('I', '4', '2', '0');
-
-    if (dwSrcFmt == NULL) {
-        ERR("invalid the source format pointer\n");
-        return E_FAIL;
-    }
-
-    hr = g_pCGB->lpVtbl->FindInterface(g_pCGB, &PIN_CATEGORY_CAPTURE, 0,
-                                       g_pSrcFilter, &IID_IAMStreamConfig,
-                                       (void **)&pSConfig);
-    if (FAILED(hr)) {
-        ERR("failed to FindInterface method\n");
-        return hr;
-    }
-
-    hr = pSConfig->lpVtbl->GetNumberOfCapabilities(pSConfig, &iCount, &iSize);
-    if (FAILED(hr)) {
-        ERR("failed to GetNumberOfCapabilities method\n");
-        SAFE_RELEASE(pSConfig);
-        return hr;
-    }
-
-    if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS)) {
-        int iFormat = 0;
-        for (iFormat = 0; iFormat < iCount; iFormat++) {
-            VIDEO_STREAM_CONFIG_CAPS scc;
-            AM_MEDIA_TYPE *pmtConfig;
-
-            hr = pSConfig->lpVtbl->GetStreamCaps(pSConfig, iFormat,
-                                                 &pmtConfig, (BYTE *)&scc);
-            if (hr == S_OK) {
-                if (IsEqualIID(&pmtConfig->formattype, &FORMAT_VideoInfo)) {
-                    VIDEOINFOHEADER *pvi =
-                                         (VIDEOINFOHEADER *)pmtConfig->pbFormat;
-                    if ((pvi->bmiHeader.biWidth == (LONG)dwWidth) &&
-                        (pvi->bmiHeader.biHeight == (LONG)dwHeight)) {
-                        if (pvi->bmiHeader.biCompression == dwYUY2) {
-                            *dwSrcFmt = V4L2_PIX_FMT_YUYV;
-                        } else if ((pvi->bmiHeader.biCompression == BI_RGB) &&
-                                (pvi->bmiHeader.biBitCount == 24)) {
-                            *dwSrcFmt = V4L2_PIX_FMT_RGB24;
-                        } else if (pvi->bmiHeader.biCompression == dwI420) {
-                            *dwSrcFmt = V4L2_PIX_FMT_YUV420;
-                        } else { /* not support format */
-                            DeleteMediaType(pmtConfig);
-                            continue;
-                        }
-                        /* use minimum FPS(maximum frameinterval)
-                           with non-VT system  */
-#ifdef CONFIG_HAX
-                        if (!hax_enabled()) {
-                            pvi->AvgTimePerFrame =
-                                    (REFERENCE_TIME)scc.MaxFrameInterval;
-                        } else {
-                            pvi->AvgTimePerFrame =
-                                (REFERENCE_TIME)MARUCAM_DEFAULT_FRAMEINTERVAL;
-                        }
-#else
-                        pvi->AvgTimePerFrame =
-                                (REFERENCE_TIME)scc.MaxFrameInterval;
-#endif
-                        hr = pSConfig->lpVtbl->SetFormat(pSConfig, pmtConfig);
-                        DeleteMediaType(pmtConfig);
-                        break;
-                    }
-                }
-                DeleteMediaType(pmtConfig);
-            }
-        }
-        if (iFormat >= iCount) {
-            ERR("Failed to Set format. "
-                "Maybe connected webcam does not support the (%ldx%ld) "
-                "resolution or image formats(YUY2, RGB24, I420).\n",
-                dwWidth, dwHeight);
-            hr = E_FAIL;
-        }
-    }
-    SAFE_RELEASE(pSConfig);
-    return hr;
-}
-
-static STDMETHODIMP QueryVideoProcAmp(long nProperty, long *pMin, long *pMax,
-                                      long *pStep, long *pDefault)
-{
-    HRESULT hr;
-    long Flags;
-    IAMVideoProcAmp *pProcAmp = NULL;
-
-    hr = g_pSrcFilter->lpVtbl->QueryInterface(g_pSrcFilter,
-                                              &IID_IAMVideoProcAmp,
-                                              (void **)&pProcAmp);
-    if (FAILED(hr)) {
-        return hr;
-    }
-
-    hr = pProcAmp->lpVtbl->GetRange(pProcAmp, nProperty, pMin, pMax,
-                                    pStep, pDefault, &Flags);
-
-    SAFE_RELEASE(pProcAmp);
-    return hr;
-}
-
-static STDMETHODIMP GetVideoProcAmp(long nProperty, long *pValue)
-{
-    HRESULT hr;
-    long Flags;
-    IAMVideoProcAmp *pProcAmp = NULL;
-
-    hr = g_pSrcFilter->lpVtbl->QueryInterface(g_pSrcFilter,
-                                              &IID_IAMVideoProcAmp,
-                                              (void **)&pProcAmp);
-    if (FAILED(hr)) {
-        return hr;
-    }
-
-    hr = pProcAmp->lpVtbl->Get(pProcAmp, nProperty, pValue, &Flags);
-    if (FAILED(hr)) {
-        ERR("Failed to get property for video\n");
-    }
-
-    SAFE_RELEASE(pProcAmp);
-    return hr;
-}
-
-static STDMETHODIMP SetVideoProcAmp(long nProperty, long value)
-{
-    HRESULT hr;
-
-    IAMVideoProcAmp *pProcAmp = NULL;
-    hr = g_pSrcFilter->lpVtbl->QueryInterface(g_pSrcFilter,
-                                              &IID_IAMVideoProcAmp,
-                                              (void **)&pProcAmp);
-    if (FAILED(hr)) {
-        return hr;
-    }
-
-    hr = pProcAmp->lpVtbl->Set(pProcAmp, nProperty, value,
-                               VideoProcAmp_Flags_Manual);
-    if (FAILED(hr)) {
-        ERR("Failed to set property for video\n");
-    }
-    SAFE_RELEASE(pProcAmp);
-    return hr;
-}
-
-static char *__wchar_to_char(const WCHAR *pwstr)
-{
-    char *pstr = NULL;
-    int len = 0;
-
-    len = wcslen(pwstr) + 1;
-    pstr = (char *)g_malloc0(sizeof(char) * len);
-    wcstombs(pstr, pwstr, len + 1);
-
-    return pstr;
-}
-
-int marucam_device_check(int log_flag)
-{
-    struct timeval t1, t2;
-    int ret = 0;
-    char *device_name = NULL;
-    HRESULT hr = E_FAIL;
-    ICreateDevEnum *pCreateDevEnum = NULL;
-    IGraphBuilder *pGB = NULL;
-    ICaptureGraphBuilder2 *pCGB = NULL;
-    IBaseFilter *pSrcFilter = NULL;
-    IEnumMoniker *pEnumMK = NULL;
-    IMoniker *pMoniKer = NULL;
-    IAMStreamConfig *pSConfig = NULL;
-    int iCount = 0, iSize = 0;
-
-    gettimeofday(&t1, NULL);
-    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
-    if (FAILED(hr)) {
-        ERR("Failed to CoInitailizeEx\n");
-        gettimeofday(&t2, NULL);
-        ERR("Elapsed time : %lu.%06lu\n",
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-        return ret;
-    }
-
-    hr = CoCreateInstance(&CLSID_FilterGraph, NULL,
-                          CLSCTX_INPROC,
-                          &IID_IGraphBuilder,
-                          (void **)&pGB);
-    if (FAILED(hr)) {
-        ERR("Failed to create GraphBuilder, 0x%x\n", hr);
-        CoUninitialize();
-        gettimeofday(&t2, NULL);
-        ERR("Elapsed time : %lu.%06lu\n",
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-        return ret;
-    }
-
-    hr = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL,
-                          CLSCTX_INPROC,
-                          &IID_ICaptureGraphBuilder2,
-                          (void **)&pCGB);
-    if (FAILED(hr)) {
-        ERR("Failed to create CaptureGraphBuilder2, 0x%x\n", hr);
-        SAFE_RELEASE(pGB);
-        CoUninitialize();
-        gettimeofday(&t2, NULL);
-        ERR("Elapsed time : %lu.%06lu\n",
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-        return ret;
-    }
-
-    hr = pCGB->lpVtbl->SetFiltergraph(pCGB, pGB);
-    if (FAILED(hr)) {
-        ERR("Failed to SetFiltergraph, 0x%x\n", hr);
-        SAFE_RELEASE(pCGB);
-        SAFE_RELEASE(pGB);
-        CoUninitialize();
-        gettimeofday(&t2, NULL);
-        ERR("Elapsed time : %lu.%06lu\n",
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-        return ret;
-    }
-
-    hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL,
-                          CLSCTX_INPROC,
-                          &IID_ICreateDevEnum,
-                          (void **)&pCreateDevEnum);
-    if (FAILED(hr)) {
-        ERR("Failed to create instance of CLSID_SystemDeviceEnum\n");
-        SAFE_RELEASE(pCGB);
-        SAFE_RELEASE(pGB);
-        CoUninitialize();
-        gettimeofday(&t2, NULL);
-        ERR("Elapsed time : %lu.%06lu\n",
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-        return ret;
-    }
-
-    hr = pCreateDevEnum->lpVtbl->CreateClassEnumerator(pCreateDevEnum,
-                                  &CLSID_VideoInputDeviceCategory, &pEnumMK, 0);
-    if (FAILED(hr)) {
-        ERR("Failed to create class enumerator\n");
-        SAFE_RELEASE(pCreateDevEnum);
-        SAFE_RELEASE(pCGB);
-        SAFE_RELEASE(pGB);
-        CoUninitialize();
-        gettimeofday(&t2, NULL);
-        ERR("Elapsed time : %lu.%06lu\n",
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-        return ret;
-    }
-
-    if (!pEnumMK) {
-        ERR("Class enumerator is NULL!!\n");
-        SAFE_RELEASE(pCreateDevEnum);
-        SAFE_RELEASE(pCGB);
-        SAFE_RELEASE(pGB);
-        CoUninitialize();
-        gettimeofday(&t2, NULL);
-        ERR("Elapsed time : %lu.%06lu\n",
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-        return ret;
-    }
-    pEnumMK->lpVtbl->Reset(pEnumMK);
-
-    hr = pEnumMK->lpVtbl->Next(pEnumMK, 1, &pMoniKer, NULL);
-    if (FAILED(hr) || (hr == S_FALSE)) {
-        ERR("Enum moniker returns a invalid value.\n");
-        SAFE_RELEASE(pEnumMK);
-        SAFE_RELEASE(pCreateDevEnum);
-        SAFE_RELEASE(pCGB);
-        SAFE_RELEASE(pGB);
-        CoUninitialize();
-        gettimeofday(&t2, NULL);
-        ERR("Elapsed time : %lu.%06lu\n",
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-        return ret;
-    }
-
-    IPropertyBag *pBag = NULL;
-    hr = pMoniKer->lpVtbl->BindToStorage(pMoniKer, 0, 0,
-                                         &IID_IPropertyBag,
-                                         (void **)&pBag);
-    if (FAILED(hr)) {
-        ERR("Failed to bind to storage.\n");
-        SAFE_RELEASE(pEnumMK);
-        SAFE_RELEASE(pCreateDevEnum);
-        SAFE_RELEASE(pCGB);
-        SAFE_RELEASE(pGB);
-        CoUninitialize();
-        gettimeofday(&t2, NULL);
-        ERR("Elapsed time : %lu.%06lu\n",
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-        return ret;
-    } else {
-        VARIANT var;
-        var.vt = VT_BSTR;
-        hr = pBag->lpVtbl->Read(pBag, L"FriendlyName", &var, NULL);
-        if (hr == S_OK) {
-            ret = 1;
-            if (!log_flag) {
-                SysFreeString(var.bstrVal);
-                SAFE_RELEASE(pBag);
-                SAFE_RELEASE(pMoniKer);
-                SAFE_RELEASE(pEnumMK);
-                SAFE_RELEASE(pCreateDevEnum);
-                SAFE_RELEASE(pCGB);
-                SAFE_RELEASE(pGB);
-                CoUninitialize();
-                gettimeofday(&t2, NULL);
-                ERR("Elapsed time : %lu.%06lu\n",
-                                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-                return ret;
-            }
-            device_name = __wchar_to_char(var.bstrVal);
-            INFO("Device name : %s\n", device_name);
-            g_free(device_name);
-            hr = pMoniKer->lpVtbl->BindToObject(pMoniKer, NULL, NULL,
-                                                &IID_IBaseFilter,
-                                                (void **)&pSrcFilter);
-            if (FAILED(hr)) {
-                ERR("Counldn't bind moniker to filter object!!\n");
-                SysFreeString(var.bstrVal);
-                SAFE_RELEASE(pBag);
-                SAFE_RELEASE(pMoniKer);
-                SAFE_RELEASE(pEnumMK);
-                SAFE_RELEASE(pCreateDevEnum);
-                SAFE_RELEASE(pCGB);
-                SAFE_RELEASE(pGB);
-                CoUninitialize();
-                gettimeofday(&t2, NULL);
-                ERR("Elapsed time : %lu.%06lu\n",
-                                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-                return ret;
-            } else {
-                pSrcFilter->lpVtbl->AddRef(pSrcFilter);
-            }
-            SysFreeString(var.bstrVal);
-        }
-        SAFE_RELEASE(pBag);
-    }
-    SAFE_RELEASE(pMoniKer);
-
-    hr = pGB->lpVtbl->AddFilter(pGB, pSrcFilter, L"Video Capture");
-    if (hr != S_OK && hr != S_FALSE) {
-        ERR("Counldn't add Video Capture filter to our graph!\n");
-        SAFE_RELEASE(pSrcFilter);
-        SAFE_RELEASE(pEnumMK);
-        SAFE_RELEASE(pCreateDevEnum);
-        SAFE_RELEASE(pCGB);
-        SAFE_RELEASE(pGB);
-        CoUninitialize();
-        gettimeofday(&t2, NULL);
-        ERR("Elapsed time : %lu.%06lu\n",
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-        return ret;
-    }
-
-    hr = pCGB->lpVtbl->FindInterface(pCGB, &PIN_CATEGORY_CAPTURE, 0,
-                                       pSrcFilter, &IID_IAMStreamConfig,
-                                       (void **)&pSConfig);
-    if (FAILED(hr)) {
-        ERR("Failed to FindInterface method\n");
-        SAFE_RELEASE(pSrcFilter);
-        SAFE_RELEASE(pEnumMK);
-        SAFE_RELEASE(pCreateDevEnum);
-        SAFE_RELEASE(pCGB);
-        SAFE_RELEASE(pGB);
-        CoUninitialize();
-        gettimeofday(&t2, NULL);
-        ERR("Elapsed time : %lu.%06lu\n",
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-        return ret;
-    }
-
-    hr = pSConfig->lpVtbl->GetNumberOfCapabilities(pSConfig, &iCount, &iSize);
-    if (FAILED(hr)) {
-        ERR("Failed to GetNumberOfCapabilities method\n");
-        SAFE_RELEASE(pSConfig);
-        SAFE_RELEASE(pSrcFilter);
-        SAFE_RELEASE(pEnumMK);
-        SAFE_RELEASE(pCreateDevEnum);
-        SAFE_RELEASE(pCGB);
-        SAFE_RELEASE(pGB);
-        CoUninitialize();
-        gettimeofday(&t2, NULL);
-        ERR("Elapsed time : %lu.%06lu\n",
-                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-        return ret;
-    }
-
-    if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS)) {
-        int iFormat = 0;
-        for (iFormat = 0; iFormat < iCount; iFormat++) {
-            VIDEO_STREAM_CONFIG_CAPS scc;
-            AM_MEDIA_TYPE *pmtConfig;
-
-            hr = pSConfig->lpVtbl->GetStreamCaps(pSConfig, iFormat, &pmtConfig,
-                                                 (BYTE *)&scc);
-            if (hr == S_OK) {
-                if (IsEqualIID(&pmtConfig->formattype, &FORMAT_VideoInfo)) {
-                    VIDEOINFOHEADER *pvi =
-                                         (VIDEOINFOHEADER *)pmtConfig->pbFormat;
-                    if (pvi->bmiHeader.biCompression == BI_RGB) {
-                        INFO("RGB BitCount: %d, Frame size: %ux%u\n",
-                                pvi->bmiHeader.biBitCount,
-                                pvi->bmiHeader.biWidth,
-                                pvi->bmiHeader.biHeight);
-                    } else {
-                        INFO("PixelFormat: %c%c%c%c, Frame size: %ux%u\n",
-                            (char)(pvi->bmiHeader.biCompression),
-                            (char)(pvi->bmiHeader.biCompression >> 8),
-                            (char)(pvi->bmiHeader.biCompression >> 16),
-                            (char)(pvi->bmiHeader.biCompression >> 24),
-                            pvi->bmiHeader.biWidth,
-                            pvi->bmiHeader.biHeight);
-                    }
-                }
-                DeleteMediaType(pmtConfig);
-            }
-        }
-    }
-
-    hr = pGB->lpVtbl->RemoveFilter(pGB, pSrcFilter);
-    if (FAILED(hr)) {
-        ERR("Failed to remove source filer. 0x%x\n", hr);
-    }
-
-    SAFE_RELEASE(pSConfig);
-    SAFE_RELEASE(pSrcFilter);
-    SAFE_RELEASE(pCGB);
-    SAFE_RELEASE(pGB);
-    SAFE_RELEASE(pEnumMK);
-    SAFE_RELEASE(pCreateDevEnum);
-    CoUninitialize();
-    gettimeofday(&t2, NULL);
-    ERR("Elapsed time : %lu.%06lu\n",
-                    t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
-
-    return ret;
-}
-
-/* MARUCAM_CMD_INIT */
-void marucam_device_init(MaruCamState *state)
-{
-    g_state = state;
-}
-
-void marucam_device_exit(MaruCamState *state)
-{
-}
-
-/* MARUCAM_CMD_OPEN */
-void marucam_device_open(MaruCamState *state)
-{
-    HRESULT hr;
-    uint32_t dwHeight, dwWidth, dwDstFmt;
-    MaruCamParam *param = state->param;
-    param->top = 0;
-
-    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
-    if (FAILED(hr)) {
-        ERR("CoInitailizeEx\n");
-        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
-        param->errCode = EINVAL;
-        return;
-    }
-
-    hr = GraphBuilder_Init();
-    if (FAILED(hr)) {
-        ERR("GraphBuilder_Init\n");
-        DisconnectPins();
-        RemoveFilters();
-        CloseInterfaces();
-        CoUninitialize();
-        param->errCode = EINVAL;
-        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
-        return;
-    }
-
-    hr = BindSourceFilter();
-    if (FAILED(hr)) {
-        ERR("BindSourceFilter\n");
-        DisconnectPins();
-        RemoveFilters();
-        CloseInterfaces();
-        CoUninitialize();
-        param->errCode = EINVAL;
-        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
-        return;
-    }
-
-    hr = BindTargetFilter();
-    if (FAILED(hr)) {
-        ERR("BindTargetFilter\n");
-        DisconnectPins();
-        RemoveFilters();
-        CloseInterfaces();
-        CoUninitialize();
-        param->errCode = EINVAL;
-        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
-        return;
-    }
-
-    hr = ConnectFilters();
-    if (FAILED(hr)) {
-        ERR("ConnectFilters\n");
-        DisconnectPins();
-        RemoveFilters();
-        CloseInterfaces();
-        CoUninitialize();
-        param->errCode = EINVAL;
-        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
-        return;
-    }
-
-    cur_frame_idx = 0;
-    cur_fmt_idx = 0;
-
-    dwHeight = supported_dst_frames[cur_frame_idx].height;
-    dwWidth = supported_dst_frames[cur_frame_idx].width;
-    dwDstFmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
-    hr = SetFormat(dwWidth, dwHeight, dwDstFmt, &g_dwSrcFmt);
-    if (hr != S_OK) {
-        ERR("failed to Set default values\n");
-        DisconnectPins();
-        RemoveFilters();
-        CloseInterfaces();
-        CoUninitialize();
-        param->errCode = EINVAL;
-        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
-        return;
-    }
-
-    INFO("Opened\n");
-    return;
-}
-
-/* MARUCAM_CMD_CLOSE */
-void marucam_device_close(MaruCamState *state)
-{
-    MaruCamParam *param = state->param;
-    int ret = 0;
-    param->top = 0;
-
-    qemu_mutex_lock(&state->thread_mutex);
-    ret = state->streamon;
-    qemu_mutex_unlock(&state->thread_mutex);
-    if (ret) {
-        marucam_device_stop_preview(state);
-    }
-
-    if (g_pGB) {
-        DisconnectPins();
-        RemoveFilters();
-    }
-    CloseInterfaces();
-    CoUninitialize();
-    INFO("Closed\n");
-}
-
-/* MARUCAM_CMD_START_PREVIEW */
-void marucam_device_start_preview(MaruCamState *state)
-{
-    HRESULT hr;
-    uint32_t pixfmt, width, height;
-    MaruCamParam *param = state->param;
-    param->top = 0;
-
-    ready_count = 0;
-    width = supported_dst_frames[cur_frame_idx].width;
-    height = supported_dst_frames[cur_frame_idx].height;
-    pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
-    state->buf_size = get_sizeimage(pixfmt, width, height);
-
-    INFO("Pixfmt(%c%c%c%c), W:H(%d:%d), buf size(%u)\n",
-         (char)(pixfmt), (char)(pixfmt >> 8),
-         (char)(pixfmt >> 16), (char)(pixfmt >> 24),
-         width, height, state->buf_size);
-    INFO("Starting preview\n");
-
-    assert(g_pCallback != NULL);
-    hr = ((HWCInPin *)g_pInputPin)->SetGrabCallbackIF(g_pInputPin,
-                                                       g_pCallback);
-    if (FAILED(hr)) {
-        ERR("Failed to set IGrabCallback interface.\n");
-        param->errCode = EINVAL;
-        return;
-    }
-
-    if (grab_buf) {
-        g_free(grab_buf);
-        grab_buf = NULL;
-    }
-    grab_buf = (void *)g_malloc0(state->buf_size);
-    if (grab_buf == NULL) {
-        param->errCode = ENOMEM;
-        return;
-    }
-
-    hr = g_pMediaControl->lpVtbl->Run(g_pMediaControl);
-    if (FAILED(hr)) {
-        ERR("Failed to run media control. hr=0x%x\n", hr);
-        param->errCode = EINVAL;
-        return;
-    }
-
-    qemu_mutex_lock(&state->thread_mutex);
-    state->streamon = 1;
-    qemu_mutex_unlock(&state->thread_mutex);
-
-    INFO("Streaming on ......\n");
-}
-
-/* MARUCAM_CMD_STOP_PREVIEW */
-void marucam_device_stop_preview(MaruCamState *state)
-{
-    HRESULT hr;
-    MaruCamParam *param = state->param;
-    param->top = 0;
-
-    INFO("...... Streaming off\n");
-    qemu_mutex_lock(&state->thread_mutex);
-    state->streamon = 0;
-    qemu_mutex_unlock(&state->thread_mutex);
-
-    hr = ((HWCInPin *)g_pInputPin)->SetGrabCallbackIF(g_pInputPin, NULL);
-    if (FAILED(hr)) {
-        ERR("Failed to set IGrabCallback interface.\n");
-        param->errCode = EINVAL;
-        return;
-    }
-
-    hr = g_pMediaControl->lpVtbl->Stop(g_pMediaControl);
-    if (FAILED(hr)) {
-        ERR("Failed to stop media control.\n");
-        param->errCode = EINVAL;
-        return;
-    }
-
-    if (grab_buf) {
-        g_free(grab_buf);
-        grab_buf = NULL;
-    }
-    state->buf_size = 0;
-
-    INFO("Stopping preview\n");
-}
-
-/* MARUCAM_CMD_S_PARAM */
-void marucam_device_s_param(MaruCamState *state)
-{
-    MaruCamParam *param = state->param;
-
-    /* We use default FPS of the webcam */
-    param->top = 0;
-}
-
-/* MARUCAM_CMD_G_PARAM */
-void marucam_device_g_param(MaruCamState *state)
-{
-    MaruCamParam *param = state->param;
-
-    /* We use default FPS of the webcam
-     * return a fixed value on guest ini file (1/30).
-     */
-    param->top = 0;
-    param->stack[0] = 0x1000; /* V4L2_CAP_TIMEPERFRAME */
-    param->stack[1] = 1; /* numerator */
-    param->stack[2] = 30; /* denominator */
-}
-
-/* MARUCAM_CMD_S_FMT */
-void marucam_device_s_fmt(MaruCamState *state)
-{
-    uint32_t width, height, pixfmt, pidx, fidx;
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    width = param->stack[0];
-    height = param->stack[1];
-    pixfmt = param->stack[2];
-
-    for (fidx = 0; fidx < ARRAY_SIZE(supported_dst_frames); fidx++) {
-        if ((supported_dst_frames[fidx].width == width) &&
-                (supported_dst_frames[fidx].height == height)) {
-            break;
-        }
-    }
-    if (fidx == ARRAY_SIZE(supported_dst_frames)) {
-        param->errCode = EINVAL;
-        return;
-    }
-    for (pidx = 0; pidx < ARRAY_SIZE(supported_dst_pixfmts); pidx++) {
-        if (supported_dst_pixfmts[pidx].fmt == pixfmt) {
-            break;
-        }
-    }
-    if (pidx == ARRAY_SIZE(supported_dst_pixfmts)) {
-        param->errCode = EINVAL;
-        return;
-    }
-
-    if ((supported_dst_frames[cur_frame_idx].width != width) &&
-            (supported_dst_frames[cur_frame_idx].height != height)) {
-        HRESULT hr = SetFormat(width, height, pixfmt, &g_dwSrcFmt);
-        if (FAILED(hr)) {
-            param->errCode = EINVAL;
-            return;
-        }
-    }
-
-    cur_frame_idx = fidx;
-    cur_fmt_idx = pidx;
-
-    pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
-    width = supported_dst_frames[cur_frame_idx].width;
-    height = supported_dst_frames[cur_frame_idx].height;
-
-    param->stack[0] = width;
-    param->stack[1] = height;
-    param->stack[2] = 1; /* V4L2_FIELD_NONE */
-    param->stack[3] = pixfmt;
-    param->stack[4] = get_bytesperline(pixfmt, width);
-    param->stack[5] = get_sizeimage(pixfmt, width, height);
-    param->stack[6] = 0;
-    param->stack[7] = 0;
-
-    TRACE("Set format...\n");
-}
-
-/* MARUCAM_CMD_G_FMT */
-void marucam_device_g_fmt(MaruCamState *state)
-{
-    uint32_t width, height, pixfmt;
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
-    width = supported_dst_frames[cur_frame_idx].width;
-    height = supported_dst_frames[cur_frame_idx].height;
-
-    param->stack[0] = width;
-    param->stack[1] = height;
-    param->stack[2] = 1; /* V4L2_FIELD_NONE */
-    param->stack[3] = pixfmt;
-    param->stack[4] = get_bytesperline(pixfmt, width);
-    param->stack[5] = get_sizeimage(pixfmt, width, height);
-    param->stack[6] = 0;
-    param->stack[7] = 0;
-
-    TRACE("Get format...\n");
-}
-
-void marucam_device_try_fmt(MaruCamState *state)
-{
-    uint32_t width, height, pixfmt, i;
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    width = param->stack[0];
-    height = param->stack[1];
-    pixfmt = param->stack[2];
-
-    for (i = 0; i < ARRAY_SIZE(supported_dst_frames); i++) {
-        if ((supported_dst_frames[i].width == width) &&
-                (supported_dst_frames[i].height == height)) {
-            break;
-        }
-    }
-    if (i == ARRAY_SIZE(supported_dst_frames)) {
-        param->errCode = EINVAL;
-        return;
-    }
-    for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) {
-        if (supported_dst_pixfmts[i].fmt == pixfmt) {
-            break;
-        }
-    }
-    if (i == ARRAY_SIZE(supported_dst_pixfmts)) {
-        param->errCode = EINVAL;
-        return;
-    }
-
-    param->stack[0] = width;
-    param->stack[1] = height;
-    param->stack[2] = 1; /* V4L2_FIELD_NONE */
-    param->stack[3] = pixfmt;
-    param->stack[4] = get_bytesperline(pixfmt, width);
-    param->stack[5] = get_sizeimage(pixfmt, width, height);
-    param->stack[6] = 0;
-    param->stack[7] = 0;
-}
-
-void marucam_device_enum_fmt(MaruCamState *state)
-{
-    uint32_t index;
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    index = param->stack[0];
-
-    if (index >= ARRAY_SIZE(supported_dst_pixfmts)) {
-        param->errCode = EINVAL;
-        return;
-    }
-    param->stack[1] = 0; /* flags = NONE */
-    param->stack[2] = supported_dst_pixfmts[index].fmt; /* pixelformat */
-    /* set description */
-    switch (supported_dst_pixfmts[index].fmt) {
-    case V4L2_PIX_FMT_YUYV:
-        memcpy(&param->stack[3], "YUYV", 32);
-        break;
-    case V4L2_PIX_FMT_YUV420:
-        memcpy(&param->stack[3], "YU12", 32);
-        break;
-    case V4L2_PIX_FMT_YVU420:
-        memcpy(&param->stack[3], "YV12", 32);
-        break;
-    default:
-        ERR("Invalid pixel format\n");
-        param->errCode = EINVAL;
-        break;
-    }
-}
-
-void marucam_device_qctrl(MaruCamState *state)
-{
-    HRESULT hr;
-    uint32_t id, i;
-    long property, min, max, step, def_val, set_val;
-    char name[32] = {0,};
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    id = param->stack[0];
-
-    switch (id) {
-    case V4L2_CID_BRIGHTNESS:
-        TRACE("V4L2_CID_BRIGHTNESS\n");
-        property = VideoProcAmp_Brightness;
-        memcpy((void *)name, (void *)"brightness", 32);
-        i = 0;
-        break;
-    case V4L2_CID_CONTRAST:
-        TRACE("V4L2_CID_CONTRAST\n");
-        property = VideoProcAmp_Contrast;
-        memcpy((void *)name, (void *)"contrast", 32);
-        i = 1;
-        break;
-    case V4L2_CID_SATURATION:
-        TRACE("V4L2_CID_SATURATION\n");
-        property = VideoProcAmp_Saturation;
-        memcpy((void *)name, (void *)"saturation", 32);
-        i = 2;
-        break;
-    case V4L2_CID_SHARPNESS:
-        TRACE("V4L2_CID_SHARPNESS\n");
-        property = VideoProcAmp_Sharpness;
-        memcpy((void *)name, (void *)"sharpness", 32);
-        i = 3;
-        break;
-    default:
-        ERR("Invalid control ID\n");
-        param->errCode = EINVAL;
-        return;
-    }
-    hr = QueryVideoProcAmp(property, &min, &max, &step, &def_val);
-    if (FAILED(hr)) {
-        param->errCode = EINVAL;
-        ERR("failed to query video controls [HRESULT : 0x%x]\n", hr);
-        return;
-    } else {
-        qctrl_tbl[i].hit = 1;
-        qctrl_tbl[i].min = min;
-        qctrl_tbl[i].max = max;
-        qctrl_tbl[i].step = step;
-        qctrl_tbl[i].init_val = def_val;
-
-        if ((qctrl_tbl[i].min + qctrl_tbl[i].max) == 0) {
-            set_val = 0;
-        } else {
-            set_val = (qctrl_tbl[i].min + qctrl_tbl[i].max) / 2;
-        }
-        hr = SetVideoProcAmp(property, set_val);
-        if (FAILED(hr)) {
-            param->errCode = EINVAL;
-            ERR("failed to set video control value, [HRESULT : 0x%x]\n", hr);
-            return;
-        }
-    }
-
-    param->stack[0] = id;
-    param->stack[1] = MARUCAM_CTRL_VALUE_MIN;  /* minimum */
-    param->stack[2] = MARUCAM_CTRL_VALUE_MAX;  /* maximum */
-    param->stack[3] = MARUCAM_CTRL_VALUE_STEP; /*  step   */
-    param->stack[4] = MARUCAM_CTRL_VALUE_MID;  /* default_value */
-    param->stack[5] = V4L2_CTRL_FLAG_SLIDER;
-    /* name field setting */
-    memcpy(&param->stack[6], (void *)name, sizeof(name)/sizeof(name[0]));
-}
-
-void marucam_device_s_ctrl(MaruCamState *state)
-{
-    HRESULT hr;
-    uint32_t i;
-    long property, set_val;
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-
-    switch (param->stack[0]) {
-    case V4L2_CID_BRIGHTNESS:
-        i = 0;
-        property = VideoProcAmp_Brightness;
-        break;
-    case V4L2_CID_CONTRAST:
-        i = 1;
-        property = VideoProcAmp_Contrast;
-        break;
-    case V4L2_CID_SATURATION:
-        i = 2;
-        property = VideoProcAmp_Saturation;
-        break;
-    case V4L2_CID_SHARPNESS:
-        i = 3;
-        property = VideoProcAmp_Sharpness;
-        break;
-    default:
-        param->errCode = EINVAL;
-        return;
-    }
-    set_val = value_convert_from_guest(qctrl_tbl[i].min,
-            qctrl_tbl[i].max, (long)param->stack[1]);
-    hr = SetVideoProcAmp(property, set_val);
-    if (FAILED(hr)) {
-        param->errCode = EINVAL;
-        ERR("failed to set video control value, [HRESULT : 0x%x]\n", hr);
-        return;
-    }
-}
-
-void marucam_device_g_ctrl(MaruCamState *state)
-{
-    HRESULT hr;
-    uint32_t i;
-    long property, get_val;
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    switch (param->stack[0]) {
-    case V4L2_CID_BRIGHTNESS:
-        i = 0;
-        property = VideoProcAmp_Brightness;
-        break;
-    case V4L2_CID_CONTRAST:
-        i = 1;
-        property = VideoProcAmp_Contrast;
-        break;
-    case V4L2_CID_SATURATION:
-        i = 2;
-        property = VideoProcAmp_Saturation;
-        break;
-    case V4L2_CID_SHARPNESS:
-        i = 3;
-        property = VideoProcAmp_Sharpness;
-        break;
-    default:
-        param->errCode = EINVAL;
-        return;
-    }
-
-    hr = GetVideoProcAmp(property, &get_val);
-    if (FAILED(hr)) {
-        param->errCode = EINVAL;
-        ERR("failed to get video control value!!!, [HRESULT : 0x%x]\n", hr);
-        return;
-    }
-    param->stack[0] = (uint32_t)value_convert_to_guest(qctrl_tbl[i].min,
-                qctrl_tbl[i].max, get_val);
-}
-
-void marucam_device_enum_fsizes(MaruCamState *state)
-{
-    uint32_t index, pixfmt, i;
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-    index = param->stack[0];
-    pixfmt = param->stack[1];
-
-    if (index >= ARRAY_SIZE(supported_dst_frames)) {
-        param->errCode = EINVAL;
-        return;
-    }
-    for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) {
-        if (supported_dst_pixfmts[i].fmt == pixfmt) {
-            break;
-        }
-    }
-
-    if (i == ARRAY_SIZE(supported_dst_pixfmts)) {
-        param->errCode = EINVAL;
-        return;
-    }
-
-    param->stack[0] = supported_dst_frames[index].width;
-    param->stack[1] = supported_dst_frames[index].height;
-}
-
-void marucam_device_enum_fintv(MaruCamState *state)
-{
-    MaruCamParam *param = state->param;
-
-    param->top = 0;
-
-    /* switch by index(param->stack[0]) */
-    switch (param->stack[0]) {
-    case 0:
-        param->stack[1] = 30; /* denominator */
-        break;
-    default:
-        param->errCode = EINVAL;
-        return;
-    }
-    param->stack[0] = 1; /* numerator */
-}
-
-void yuyv_to_yuv420(const unsigned char *src, unsigned char *dest,
-        uint32_t width, uint32_t height, uint32_t yvu)
-{
-    uint32_t i, j;
-    const unsigned char *src1;
-    unsigned char *udest, *vdest;
-
-    /* copy the Y values */
-    src1 = src;
-    for (i = 0; i < height; i++) {
-        for (j = 0; j < width; j += 2) {
-            *dest++ = src1[0];
-            *dest++ = src1[2];
-            src1 += 4;
-        }
-    }
-
-    /* copy the U and V values */
-    src++;              /* point to V */
-    src1 = src + width * 2;     /* next line */
-    if (yvu) {
-        vdest = dest;
-        udest = dest + width * height / 4;
-    } else {
-        udest = dest;
-        vdest = dest + width * height / 4;
-    }
-    for (i = 0; i < height; i += 2) {
-        for (j = 0; j < width; j += 2) {
-            *udest++ = ((int) src[0] + src1[0]) / 2;    /* U */
-            *vdest++ = ((int) src[2] + src1[2]) / 2;    /* V */
-            src += 4;
-            src1 += 4;
-        }
-        src = src1;
-        src1 += width * 2;
-    }
-}
-
-#define RGB2Y(r, g, b, y)   \
-    (y) = ((8453 * (r) + 16594 * (g) + 3223 * (b) + 524288) >> 15)
-
-#define RGB2UV(r, g, b, u, v)   \
-    do {    \
-        (u) = ((-4878 * (r) - 9578 * (g) + 14456 * (b) + 4210688) >> 15);   \
-        (v) = ((14456 * (r) - 12105 * (g) - 2351 * (b) + 4210688) >> 15);   \
-    } while (0)
-
-#define CLIP(color) \
-    (unsigned char)(((color) > 0xFF) ? 0xff : (((color) < 0) ? 0 : (color)))
-
-void rgb24_to_yuv420(const unsigned char *src, unsigned char *dest,
-                     uint32_t width, uint32_t height, uint32_t yvu)
-{
-    uint32_t x, y;
-    uint32_t halfWidth;
-    uint8_t *yplane, *uplane, *vplane;
-    uint8_t *yline, *uline, *vline;
-    const uint8_t *rgbIndex;
-
-    halfWidth = width >> 1;
-    yplane = dest;
-
-    if (yvu) {
-        vplane = dest + width * height;
-        uplane = vplane + ((width * height) >> 2);
-    } else {
-        uplane = dest + width * height;
-        vplane = uplane + ((width * height) >> 2);
-    }
-
-    for (y = 0; y < height; y++) {
-        yline = yplane + (y * width);
-        uline = uplane + ((y >> 1) * halfWidth);
-        vline = vplane + ((y >> 1) * halfWidth);
-
-        rgbIndex = src + (width * (height - 1 - y) * 3);
-        for (x = 0; x < (int)width; x+=2) {
-            RGB2Y(rgbIndex[2], rgbIndex[1], rgbIndex[0], *yline++);
-            rgbIndex += 3;
-            RGB2Y(rgbIndex[2], rgbIndex[1], rgbIndex[0], *yline++);
-            RGB2UV(rgbIndex[2], rgbIndex[1], rgbIndex[0], *uline++, *vline++);
-            rgbIndex += 3;
-        }
-    }
-}
-
-void rgb24_to_yuyv(unsigned char *src, unsigned char *dest,
-                   uint32_t width, uint32_t height)
-{
-    uint32_t i, j;
-    uint8_t *ptr;
-
-    for (i = 0; i < height; i++) {
-        ptr = src + (width * (height - 1 - i) * 3);
-        for (j = 0; j < width; j += 2) {
-            /* y */
-            *dest++ = CLIP(0.299 * (ptr[2] - 128) +
-                           0.587 * (ptr[1] - 128) +
-                           0.114 * (ptr[0] - 128) + 128);
-            /* u */
-            *dest++ = CLIP(((-0.147 * (ptr[2] - 128) -
-                           0.289 * (ptr[1] - 128) +
-                           0.436 * (ptr[0] - 128) + 128) +
-                           (-0.147 * (ptr[5] - 128) -
-                           0.289 * (ptr[4] - 128) +
-                           0.436 * (ptr[3] - 128) + 128)) / 2);
-            /* y1 */
-            *dest++ = CLIP(0.299 * (ptr[5] - 128) +
-                           0.587 * (ptr[4] - 128) +
-                           0.114 * (ptr[3] - 128) + 128);
-            /* v */
-            *dest++ = CLIP(((0.615 * (ptr[2] - 128) -
-                           0.515 * (ptr[1] - 128) -
-                           0.100 * (ptr[0] - 128) + 128) +
-                           (0.615 * (ptr[5] - 128) -
-                           0.515 * (ptr[4] - 128) -
-                           0.100 * (ptr[3] - 128) + 128)) / 2);
-            ptr += 6;
-        }
-    }
-}
-
-void yuv420_to_yvu420(unsigned char *src, unsigned char *dest,
-                      uint32_t width, uint32_t height)
-{
-    unsigned char *psrc_y, *pdst_y;
-    unsigned char *psrc_u, *pdst_u;
-    unsigned char *psrc_v, *pdst_v;
-
-    psrc_y = src;
-    psrc_u = psrc_y + (width * height);
-    psrc_v = psrc_u + (width * height / 4);
-
-    pdst_y = dest;
-    pdst_v = pdst_y + (width * height);
-    pdst_u = pdst_v + (width * height / 4);
-
-    memcpy(pdst_y, psrc_y, width * height);
-    memcpy(pdst_v, psrc_v, width * height / 4);
-    memcpy(pdst_u, psrc_u, width * height / 4);
-}
-
-void yuv420_to_yuyv(unsigned char *src, unsigned char *dest,
-                    uint32_t width, uint32_t height)
-{
-    unsigned char *py;
-    unsigned char *pu;
-    unsigned char *pv;
-
-    uint32_t linesize = width * 2;
-    uint32_t uvlinesize = width / 2;
-    uint32_t offset = 0;
-    uint32_t offset1 = 0;
-    uint32_t offsety = 0;
-    uint32_t offsety1 = 0;
-    uint32_t offsetuv = 0;
-    uint32_t h = 0;
-    uint32_t w = 0;
-    uint32_t wy = 0;
-    uint32_t huv = 0;
-    uint32_t wuv = 0;
-
-    py = src;
-    pu = py + (width * height);
-    pv = pu + (width * height / 4);
-
-    for (h = 0; h < height; h += 2) {
-        wy = 0;
-        wuv = 0;
-        offset = h * linesize;
-        offset1 = (h + 1) * linesize;
-        offsety = h * width;
-        offsety1 = (h + 1) * width;
-        offsetuv = huv * uvlinesize;
-
-        for (w = 0; w < linesize; w += 4) {
-            /* y00 */
-            dest[w + offset] = py[wy + offsety];
-            /* u0 */
-            dest[(w + 1) + offset] = pu[wuv + offsetuv];
-            /* y01 */
-            dest[(w + 2) + offset] = py[(wy + 1) + offsety];
-            /* v0 */
-            dest[(w + 3) + offset] = pv[wuv + offsetuv];
-
-            /* y10 */
-            dest[w + offset1] = py[wy + offsety1];
-            /* u0 */
-            dest[(w + 1) + offset1] = pu[wuv + offsetuv];
-            /* y11 */
-            dest[(w + 2) + offset1] = py[(wy + 1) + offsety1];
-            /* v0 */
-            dest[(w + 3) + offset1] = pv[wuv + offsetuv];
-
-            wuv++;
-            wy += 2;
-        }
-        huv++;
-    }
-}
diff --git a/tizen/src/hw/maru_codec.c b/tizen/src/hw/maru_codec.c
deleted file mode 100644 (file)
index 2c9b2db..0000000
+++ /dev/null
@@ -1,1690 +0,0 @@
-/*
- * Virtual Codec device
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Kitae Kim <kt920.kim@samsung.com>
- *  SeokYeon Hwang <syeon.hwang@samsung.com>
- *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- *  DongKyun Yun
- *
- * 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 "maru_codec.h"
-#include "qemu-common.h"
-
-#define MARU_CODEC_DEV_NAME     "codec"
-#define MARU_CODEC_VERSION      14
-
-/*  Needs 16M to support 1920x1080 video resolution.
- *  Output size for encoding has to be greater than (width * height * 6)
- */
-#define MARU_CODEC_MEM_SIZE     (2 * 16 * 1024 * 1024)
-#define MARU_CODEC_REG_SIZE     (256)
-#define MARU_CODEC_IRQ 0x7f
-
-#define GEN_MASK(x) ((1<<(x))-1)
-#define ROUND_UP_X(v, x) (((v) + GEN_MASK(x)) & ~GEN_MASK(x))
-#define ROUND_UP_2(x) ROUND_UP_X(x, 1)
-#define ROUND_UP_4(x) ROUND_UP_X(x, 2)
-#define ROUND_UP_8(x) ROUND_UP_X(x, 3)
-#define DIV_ROUND_UP_X(v, x) (((v) + GEN_MASK(x)) >> (x))
-
-typedef struct PixFmtInfo {
-    uint8_t x_chroma_shift;
-    uint8_t y_chroma_shift;
-} PixFmtInfo;
-
-static PixFmtInfo pix_fmt_info[PIX_FMT_NB];
-
-/* define debug channel */
-MULTI_DEBUG_CHANNEL(qemu, marucodec);
-
-void codec_thread_init(SVCodecState *s)
-{
-    int index = 0;
-    QemuThread *pthread = NULL;
-    TRACE("Enter, %s\n", __func__);
-
-    pthread = g_malloc0(sizeof(QemuThread) * CODEC_MAX_THREAD);
-    if (!pthread) {
-        ERR("Failed to allocate wrk_thread memory.\n");
-        return;
-    }
-    qemu_cond_init(&s->codec_thread.cond);
-    qemu_mutex_init(&s->codec_thread.mutex);
-
-    qemu_mutex_lock(&s->thread_mutex);
-    s->isrunning = 1;
-    qemu_mutex_unlock(&s->thread_mutex);
-
-    for (; index < CODEC_MAX_THREAD; index++) {
-        qemu_thread_create(&pthread[index], codec_worker_thread, (void *)s,
-            QEMU_THREAD_JOINABLE);
-    }
-
-    s->codec_thread.wrk_thread = pthread;
-    TRACE("Leave, %s\n", __func__);
-}
-
-void codec_thread_exit(SVCodecState *s)
-{
-    TRACE("Enter, %s\n", __func__);
-    int index;
-
-    /* stop to run dedicated threads. */
-    s->isrunning = 0;
-
-    for (index = 0; index < CODEC_MAX_THREAD; index++) {
-        qemu_thread_join(&s->codec_thread.wrk_thread[index]);
-    }
-
-    TRACE("destroy mutex and conditional.\n");
-    qemu_mutex_destroy(&s->codec_thread.mutex);
-    qemu_cond_destroy(&s->codec_thread.cond);
-
-    TRACE("Leave, %s\n", __func__);
-}
-
-void wake_codec_worker_thread(SVCodecState *s)
-{
-    TRACE("Enter, %s\n", __func__);
-
-    qemu_cond_signal(&s->codec_thread.cond);
-    TRACE("sent a conditional signal to a worker thread.\n");
-
-    TRACE("Leave, %s\n", __func__);
-}
-
-void *codec_worker_thread(void *opaque)
-{
-    SVCodecState *s = (SVCodecState *)opaque;
-    QemuThread thread;
-    AVCodecContext *avctx;
-
-    TRACE("Enter, %s\n", __func__);
-    qemu_mutex_lock(&s->thread_mutex);
-
-    while (s->isrunning) {
-        TRACE("wait for conditional signal.\n");
-        qemu_cond_wait(&s->codec_thread.cond, &s->thread_mutex);
-
-        qemu_thread_get_self(&thread);
-#ifdef CONFIG_LINUX
-        TRACE("wake up a worker thread. :%x\n", thread.thread);
-#endif
-        avctx = s->codec_ctx[s->codec_param.ctx_index].avctx;
-        if (avctx) {
-            if (avctx->codec->decode) {
-                decode_codec(s);
-            } else {
-                encode_codec(s);
-            }
-        } else {
-            ERR("there is a synchrous problem "
-                "between each context.\n");
-            continue;
-        }
-
-        s->codec_thread.state = MARU_CODEC_IRQ;
-        qemu_bh_schedule(s->tx_bh);
-    }
-    qemu_mutex_unlock(&s->thread_mutex);
-    TRACE("Leave, %s\n", __func__);
-
-    return NULL;
-}
-
-int decode_codec(SVCodecState *s)
-{
-    AVCodecContext *avctx;
-    uint32_t len = 0, ctx_index;
-
-    TRACE("Enter, %s\n", __func__);
-
-    qemu_mutex_lock(&s->codec_thread.mutex);
-    ctx_index = s->codec_param.ctx_index;
-    qemu_mutex_unlock(&s->codec_thread.mutex);
-
-    avctx = s->codec_ctx[ctx_index].avctx;
-    if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
-        len = qemu_avcodec_decode_video(s, ctx_index);
-    } else {
-        len = qemu_avcodec_decode_audio(s, ctx_index);
-    }
-
-    TRACE("Leave, %s\n", __func__);
-    return len;
-}
-
-int encode_codec(SVCodecState *s)
-{
-    AVCodecContext *avctx;
-    uint32_t len = 0, ctx_index;
-
-    TRACE("Enter, %s\n", __func__);
-
-    qemu_mutex_unlock(&s->thread_mutex);
-
-    ctx_index = s->codec_param.ctx_index;
-    avctx = s->codec_ctx[ctx_index].avctx;
-    if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
-        len = qemu_avcodec_encode_video(s, ctx_index);
-    } else {
-        len = qemu_avcodec_encode_audio(s, ctx_index);
-    }
-
-    qemu_mutex_lock(&s->thread_mutex);
-
-    TRACE("Leave, %s\n", __func__);
-    return len;
-}
-
-static int qemu_serialize_rational(const AVRational *elem, uint8_t *buff)
-{
-    int size = 0;
-
-    memcpy(buff + size, &elem->num, sizeof(elem->num));
-    size += sizeof(elem->num);
-    memcpy(buff + size, &elem->den, sizeof(elem->den));
-    size += sizeof(elem->den);
-
-    return size;
-}
-
-static int qemu_deserialize_rational(const uint8_t *buff, AVRational *elem)
-{
-    int size = 0;
-
-    memset(elem, 0, sizeof(*elem));
-
-    memcpy(&elem->num, buff + size, sizeof(elem->num));
-    size += sizeof(elem->num);
-    memcpy(&elem->den, buff + size, sizeof(elem->den));
-    size += sizeof(elem->den);
-
-    return size;
-}
-
-static int qemu_serialize_frame(const AVFrame *elem, uint8_t *buff)
-{
-    int size = 0;
-
-    memcpy(buff + size, &elem->key_frame, sizeof(elem->key_frame));
-    size += sizeof(elem->key_frame);
-    memcpy(buff + size, &elem->pict_type, sizeof(elem->pict_type));
-    size += sizeof(elem->pict_type);
-    memcpy(buff + size, &elem->pts, sizeof(elem->pts));
-    size += sizeof(elem->pts);
-    memcpy(buff + size, &elem->coded_picture_number,
-            sizeof(elem->coded_picture_number));
-    size += sizeof(elem->coded_picture_number);
-    memcpy(buff + size, &elem->display_picture_number,
-            sizeof(elem->display_picture_number));
-    size += sizeof(elem->display_picture_number);
-    memcpy(buff + size, &elem->quality, sizeof(elem->quality));
-    size += sizeof(elem->quality);
-    memcpy(buff + size, &elem->age, sizeof(elem->age));
-    size += sizeof(elem->age);
-    memcpy(buff + size, &elem->reference, sizeof(elem->reference));
-    size += sizeof(elem->reference);
-    memcpy(buff + size, &elem->reordered_opaque,
-            sizeof(elem->reordered_opaque));
-    size += sizeof(elem->reordered_opaque);
-    memcpy(buff + size, &elem->repeat_pict, sizeof(elem->repeat_pict));
-    size += sizeof(elem->repeat_pict);
-    memcpy(buff + size, &elem->interlaced_frame,
-            sizeof(elem->interlaced_frame));
-    size += sizeof(elem->interlaced_frame);
-
-    return size;
-}
-
-static int qemu_deserialize_frame(const uint8_t *buff, AVFrame *elem)
-{
-    int size = 0;
-
-    memset(elem, 0, sizeof(*elem));
-
-    memcpy(&elem->linesize, buff + size, sizeof(elem->linesize));
-    size += sizeof(elem->linesize);
-    memcpy(&elem->key_frame, buff + size, sizeof(elem->key_frame));
-    size += sizeof(elem->key_frame);
-    memcpy(&elem->pict_type, buff + size, sizeof(elem->pict_type));
-    size += sizeof(elem->pict_type);
-    memcpy(&elem->pts, buff + size, sizeof(elem->pts));
-    size += sizeof(elem->pts);
-    memcpy(&elem->coded_picture_number, buff + size,
-            sizeof(elem->coded_picture_number));
-    size += sizeof(elem->coded_picture_number);
-    memcpy(&elem->display_picture_number, buff + size,
-            sizeof(elem->display_picture_number));
-    size += sizeof(elem->display_picture_number);
-    memcpy(&elem->quality, buff + size, sizeof(elem->quality));
-    size += sizeof(elem->quality);
-    memcpy(&elem->age, buff + size, sizeof(elem->age));
-    size += sizeof(elem->age);
-    memcpy(&elem->reference, buff + size, sizeof(elem->reference));
-    size += sizeof(elem->reference);
-    memcpy(&elem->qstride, buff + size, sizeof(elem->qstride));
-    size += sizeof(elem->qstride);
-    memcpy(&elem->motion_subsample_log2, buff + size,
-            sizeof(elem->motion_subsample_log2));
-    size += sizeof(elem->motion_subsample_log2);
-    memcpy(&elem->error, buff + size, sizeof(elem->error));
-    size += sizeof(elem->error);
-    memcpy(&elem->type, buff + size, sizeof(elem->type));
-    size += sizeof(elem->type);
-    memcpy(&elem->repeat_pict, buff + size, sizeof(elem->repeat_pict));
-    size += sizeof(elem->repeat_pict);
-    memcpy(&elem->qscale_type, buff + size, sizeof(elem->qscale_type));
-    size += sizeof(elem->qscale_type);
-    memcpy(&elem->interlaced_frame, buff + size,
-            sizeof(elem->interlaced_frame));
-    size += sizeof(elem->interlaced_frame);
-    memcpy(&elem->top_field_first, buff + size, sizeof(elem->top_field_first));
-    size += sizeof(elem->top_field_first);
-    memcpy(&elem->palette_has_changed, buff + size,
-            sizeof(elem->palette_has_changed));
-    size += sizeof(elem->palette_has_changed);
-    memcpy(&elem->buffer_hints, buff + size, sizeof(elem->buffer_hints));
-    size += sizeof(elem->buffer_hints);
-    memcpy(&elem->reordered_opaque, buff + size,
-            sizeof(elem->reordered_opaque));
-    size += sizeof(elem->reordered_opaque);
-
-    return size;
-}
-
-void qemu_parser_init(SVCodecState *s, int ctx_index)
-{
-    TRACE("[%s] Enter\n", __func__);
-
-    s->codec_ctx[ctx_index].parser_buf = NULL;
-    s->codec_ctx[ctx_index].parser_use = false;
-
-    TRACE("[%s] Leave\n", __func__);
-}
-
-void qemu_reset_codec_info(SVCodecState *s, uint32_t value)
-{
-    int ctx_idx;
-
-    TRACE("[%s] Enter\n", __func__);
-    qemu_mutex_lock(&s->thread_mutex);
-
-    for (ctx_idx = 0; ctx_idx < CODEC_CONTEXT_MAX; ctx_idx++) {
-        if (s->codec_ctx[ctx_idx].file_index == value) {
-            TRACE("reset %d context\n", ctx_idx);
-            qemu_mutex_unlock(&s->thread_mutex);
-            qemu_av_free(s, ctx_idx);
-            qemu_mutex_lock(&s->thread_mutex);
-            s->codec_ctx[ctx_idx].avctx_use = false;
-            break;
-        }
-    }
-    qemu_parser_init(s, ctx_idx);
-
-    qemu_mutex_unlock(&s->thread_mutex);
-    TRACE("[%s] Leave\n", __func__);
-}
-
-/* void av_register_all() */
-void qemu_av_register_all(void)
-{
-    av_register_all();
-    TRACE("av_register_all\n");
-}
-
-/* int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic) */
-int qemu_avcodec_get_buffer(AVCodecContext *context, AVFrame *picture)
-{
-    int ret;
-    TRACE("avcodec_default_get_buffer\n");
-
-    picture->reordered_opaque = context->reordered_opaque;
-    picture->opaque = NULL;
-
-    ret = avcodec_default_get_buffer(context, picture);
-
-    return ret;
-}
-
-/* void avcodec_default_release_buffer(AVCodecContext *ctx, AVFrame *frame) */
-void qemu_avcodec_release_buffer(AVCodecContext *context, AVFrame *picture)
-{
-    TRACE("avcodec_default_release_buffer\n");
-    avcodec_default_release_buffer(context, picture);
-}
-
-static void qemu_init_pix_fmt_info(void)
-{
-    /* YUV formats */
-    pix_fmt_info[PIX_FMT_YUV420P].x_chroma_shift = 1;
-    pix_fmt_info[PIX_FMT_YUV420P].y_chroma_shift = 1;
-
-    pix_fmt_info[PIX_FMT_YUV422P].x_chroma_shift = 1;
-    pix_fmt_info[PIX_FMT_YUV422P].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_YUV444P].x_chroma_shift = 1;
-    pix_fmt_info[PIX_FMT_YUV444P].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_YUYV422].x_chroma_shift = 1;
-    pix_fmt_info[PIX_FMT_YUYV422].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_YUV410P].x_chroma_shift = 2;
-    pix_fmt_info[PIX_FMT_YUV410P].y_chroma_shift = 2;
-
-    pix_fmt_info[PIX_FMT_YUV411P].x_chroma_shift = 2;
-    pix_fmt_info[PIX_FMT_YUV411P].y_chroma_shift = 0;
-
-    /* JPEG YUV */
-    pix_fmt_info[PIX_FMT_YUVJ420P].x_chroma_shift = 1;
-    pix_fmt_info[PIX_FMT_YUVJ420P].y_chroma_shift = 1;
-
-    pix_fmt_info[PIX_FMT_YUVJ422P].x_chroma_shift = 1;
-    pix_fmt_info[PIX_FMT_YUVJ422P].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_YUVJ444P].x_chroma_shift = 0;
-    pix_fmt_info[PIX_FMT_YUVJ444P].y_chroma_shift = 0;
-
-    /* RGB formats */
-    pix_fmt_info[PIX_FMT_RGB24].x_chroma_shift = 0;
-    pix_fmt_info[PIX_FMT_RGB24].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_BGR24].x_chroma_shift = 0;
-    pix_fmt_info[PIX_FMT_BGR24].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_RGB32].x_chroma_shift = 0;
-    pix_fmt_info[PIX_FMT_RGB32].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_RGB565].x_chroma_shift = 0;
-    pix_fmt_info[PIX_FMT_RGB565].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_RGB555].x_chroma_shift = 0;
-    pix_fmt_info[PIX_FMT_RGB555].y_chroma_shift = 0;
-
-    pix_fmt_info[PIX_FMT_YUVA420P].x_chroma_shift = 1,
-    pix_fmt_info[PIX_FMT_YUVA420P].y_chroma_shift = 1;
-}
-
-static uint8_t *qemu_malloc_avpicture (int picture_size)
-{
-    uint8_t *ptr = NULL;
-
-    ptr = av_mallocz(picture_size);
-    if (!ptr) {
-        ERR("failed to allocate memory.\n");
-        return NULL;
-    }
-
-    return ptr;
-}
-
-static int qemu_avpicture_fill(AVPicture *picture, uint8_t *ptr,
-                                int pix_fmt, int width,
-                                int height, bool encode)
-{
-    int size, w2, h2, size2;
-    int stride, stride2;
-    int fsize;
-    PixFmtInfo *pinfo;
-
-    pinfo = &pix_fmt_info[pix_fmt];
-
-    switch (pix_fmt) {
-    case PIX_FMT_YUV420P:
-    case PIX_FMT_YUV422P:
-    case PIX_FMT_YUV444P:
-    case PIX_FMT_YUV410P:
-    case PIX_FMT_YUV411P:
-    case PIX_FMT_YUVJ420P:
-    case PIX_FMT_YUVJ422P:
-    case PIX_FMT_YUVJ444P:
-        stride = ROUND_UP_4(width);
-        h2 = ROUND_UP_X(height, pinfo->y_chroma_shift);
-        size = stride * h2;
-        w2 = DIV_ROUND_UP_X(width, pinfo->x_chroma_shift);
-        stride2 = ROUND_UP_4(w2);
-        h2 = DIV_ROUND_UP_X(height, pinfo->y_chroma_shift);
-        size2 = stride2 * h2;
-        fsize = size + 2 * size2;
-        TRACE("stride: %d, stride2: %d, size: %d, size2: %d, fsize: %d\n",
-            stride, stride2, size, size2, fsize);
-        if (!encode && !ptr) {
-            ptr = qemu_malloc_avpicture(fsize);
-        }
-        picture->data[0] = ptr;
-        picture->data[1] = picture->data[0] + size;
-        picture->data[2] = picture->data[1] + size2;
-        picture->data[3] = NULL;
-        picture->linesize[0] = stride;
-        picture->linesize[1] = stride2;
-        picture->linesize[2] = stride2;
-        picture->linesize[3] = 0;
-        TRACE("planes %d %d %d\n", 0, size, size + size2);
-        TRACE("strides %d %d %d\n", stride, stride2, stride2);
-        break;
-    case PIX_FMT_YUVA420P:
-        stride = ROUND_UP_4 (width);
-        h2 = ROUND_UP_X (height, pinfo->y_chroma_shift);
-        size = stride * h2;
-        w2 = DIV_ROUND_UP_X (width, pinfo->x_chroma_shift);
-        stride2 = ROUND_UP_4 (w2);
-        h2 = DIV_ROUND_UP_X (height, pinfo->y_chroma_shift);
-        size2 = stride2 * h2;
-        fsize = 2 * size + 2 * size2;
-        TRACE("stride %d, stride2 %d, size %d, size2 %d, fsize %d\n",
-            stride, stride2, size, size2, fsize);
-        if (!encode && !ptr) {
-            ptr = qemu_malloc_avpicture(fsize);
-        }
-        picture->data[0] = ptr;
-        picture->data[1] = picture->data[0] + size;
-        picture->data[2] = picture->data[1] + size2;
-        picture->data[3] = picture->data[2] + size2;
-        picture->linesize[0] = stride;
-        picture->linesize[1] = stride2;
-        picture->linesize[2] = stride2;
-        picture->linesize[3] = stride;
-        TRACE("planes %d %d %d %d\n", 0, size, size + size2, size + 2 * size2);
-        TRACE("strides %d %d %d %d\n", stride, stride2, stride2, stride);
-        break;
-    case PIX_FMT_RGB24:
-    case PIX_FMT_BGR24:
-        stride = ROUND_UP_4 (width * 3);
-        fsize = stride * height;
-        TRACE("stride: %d, fsize: %d\n", stride, fsize);
-        if (!encode && !ptr) {
-            ptr = qemu_malloc_avpicture(fsize);
-        }
-        picture->data[0] = ptr;
-        picture->data[1] = NULL;
-        picture->data[2] = NULL;
-        picture->data[3] = NULL;
-        picture->linesize[0] = stride;
-        picture->linesize[1] = 0;
-        picture->linesize[2] = 0;
-        picture->linesize[3] = 0;
-        break;
-    case PIX_FMT_RGB32:
-        stride = width * 4;
-        fsize = stride * height;
-        TRACE("stride: %d, fsize: %d\n", stride, fsize);
-        if (!encode && !ptr) {
-            ptr = qemu_malloc_avpicture(fsize);
-        }
-        picture->data[0] = ptr;
-        picture->data[1] = NULL;
-        picture->data[2] = NULL;
-        picture->data[3] = NULL;
-        picture->linesize[0] = stride;
-        picture->linesize[1] = 0;
-        picture->linesize[2] = 0;
-        picture->linesize[3] = 0;
-        break;
-    case PIX_FMT_RGB555:
-    case PIX_FMT_RGB565:
-    case PIX_FMT_YUYV422:
-    case PIX_FMT_UYVY422:
-        stride = ROUND_UP_4 (width * 2);
-        fsize = stride * height;
-        TRACE("stride: %d, fsize: %d\n", stride, fsize);
-        if (!encode && !ptr) {
-            ptr = qemu_malloc_avpicture(fsize);
-        }
-        picture->data[0] = ptr;
-        picture->data[1] = NULL;
-        picture->data[2] = NULL;
-        picture->data[3] = NULL;
-        picture->linesize[0] = stride;
-        picture->linesize[1] = 0;
-        picture->linesize[2] = 0;
-        picture->linesize[3] = 0;
-        break;
-    case PIX_FMT_UYYVYY411:
-        /* FIXME, probably not the right stride */
-        stride = ROUND_UP_4 (width);
-        size = stride * height;
-        fsize = size + size / 2;
-        TRACE("stride %d, size %d, fsize %d\n", stride, size, fsize);
-        if (!encode && !ptr) {
-            ptr = qemu_malloc_avpicture(fsize);
-        }
-        picture->data[0] = ptr;
-        picture->data[1] = NULL;
-        picture->data[2] = NULL;
-        picture->data[3] = NULL;
-        picture->linesize[0] = width + width / 2;
-        picture->linesize[1] = 0;
-        picture->linesize[2] = 0;
-        picture->linesize[3] = 0;
-        break;
-    case PIX_FMT_GRAY8:
-        stride = ROUND_UP_4 (width);
-        fsize = stride * height;
-        TRACE("stride %d, fsize %d\n", stride, fsize);
-        if (!encode && !ptr) {
-            ptr = qemu_malloc_avpicture(fsize);
-        }
-        picture->data[0] = ptr;
-        picture->data[1] = NULL;
-        picture->data[2] = NULL;
-        picture->data[3] = NULL;
-        picture->linesize[0] = stride;
-        picture->linesize[1] = 0;
-        picture->linesize[2] = 0;
-        picture->linesize[3] = 0;
-        break;
-    case PIX_FMT_MONOWHITE:
-    case PIX_FMT_MONOBLACK:
-        stride = ROUND_UP_4 ((width + 7) >> 3);
-        fsize = stride * height;
-        TRACE("stride %d, fsize %d\n", stride, fsize);
-        if (!encode && !ptr) {
-            ptr = qemu_malloc_avpicture(fsize);
-        }
-        picture->data[0] = ptr;
-        picture->data[1] = NULL;
-        picture->data[2] = NULL;
-        picture->data[3] = NULL;
-        picture->linesize[0] = stride;
-        picture->linesize[1] = 0;
-        picture->linesize[2] = 0;
-        picture->linesize[3] = 0;
-        break;
-    case PIX_FMT_PAL8:
-        /* already forced to be with stride, so same result as other function */
-        stride = ROUND_UP_4 (width);
-        size = stride * height;
-        fsize = size + 256 * 4;
-        TRACE("stride %d, size %d, fsize %d\n", stride, size, fsize);
-        if (!encode && !ptr) {
-            ptr = qemu_malloc_avpicture(fsize);
-        }
-        picture->data[0] = ptr;
-        picture->data[1] = ptr + size;    /* palette is stored here as 256 32 bit words */
-        picture->data[2] = NULL;
-        picture->data[3] = NULL;
-        picture->linesize[0] = stride;
-        picture->linesize[1] = 4;
-        picture->linesize[2] = 0;
-        picture->linesize[3] = 0;
-        break;
-    default:
-        picture->data[0] = NULL;
-        picture->data[1] = NULL;
-        picture->data[2] = NULL;
-        picture->data[3] = NULL;
-        fsize = -1;
-        ERR("pixel format: %d was wrong.\n", pix_fmt);
-        break;
-    }
-
-    return fsize;
-}
-
-/* int avcodec_open(AVCodecContext *avctx, AVCodec *codec) */
-int qemu_avcodec_open(SVCodecState *s)
-{
-    AVCodecContext *avctx;
-    AVCodec *codec;
-    enum CodecID codec_id;
-    off_t offset;
-    int ret = -1;
-    int bEncode = 0;
-    int size = 0;
-    int ctx_index = 0;
-
-    av_register_all();
-    TRACE("av_register_all\n");
-
-    ctx_index = qemu_avcodec_alloc_context(s);
-    if (ctx_index < 0) {
-        return ret;
-    }
-
-    qemu_mutex_lock(&s->thread_mutex);
-    offset = s->codec_param.mmap_offset;
-    qemu_mutex_unlock(&s->thread_mutex);
-
-    avctx = s->codec_ctx[ctx_index].avctx;
-    if (!avctx) {
-        ERR("[%s] %d of AVCodecContext is NULL!\n", __func__, ctx_index);
-        qemu_mutex_unlock(&s->thread_mutex);
-        return ret;
-    }
-
-    TRACE("[%s] Context Index:%d, offset:%d\n", __func__, ctx_index, offset);
-    memcpy(&avctx->bit_rate, (uint8_t *)s->vaddr + offset, sizeof(int));
-    size = sizeof(int);
-    memcpy(&avctx->bit_rate_tolerance,
-            (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    memcpy(&avctx->flags, (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    size += qemu_deserialize_rational((uint8_t *)s->vaddr + offset + size,
-                                        &avctx->time_base);
-    memcpy(&avctx->width, (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    memcpy(&avctx->height, (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    memcpy(&avctx->gop_size, (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    memcpy(&avctx->pix_fmt, (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    memcpy(&avctx->sample_rate,
-            (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    memcpy(&avctx->channels, (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    memcpy(&avctx->codec_tag, (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    memcpy(&avctx->block_align,
-            (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    memcpy(&avctx->rc_strategy,
-            (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    memcpy(&avctx->strict_std_compliance,
-            (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    memcpy(&avctx->rc_qsquish,
-            (uint8_t *)s->vaddr + offset + size, sizeof(float));
-    size += sizeof(float);
-    size += qemu_deserialize_rational((uint8_t *)s->vaddr + offset + size,
-            &avctx->sample_aspect_ratio);
-    memcpy(&avctx->qmin, (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    memcpy(&avctx->qmax, (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    memcpy(&avctx->pre_me, (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    memcpy(&avctx->trellis, (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    memcpy(&avctx->extradata_size,
-            (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    memcpy(&codec_id, (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    memcpy(&bEncode, (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    TRACE("Context Index:%d, width:%d, height:%d\n",
-            ctx_index, avctx->width, avctx->height);
-
-    if (avctx->extradata_size > 0) {
-        avctx->extradata = (uint8_t *)av_mallocz(avctx->extradata_size +
-                             ROUND_UP_X(FF_INPUT_BUFFER_PADDING_SIZE, 4));
-        memcpy(avctx->extradata,
-                (uint8_t *)s->vaddr + offset + size, avctx->extradata_size);
-        size += avctx->extradata_size;
-    } else {
-        TRACE("[%s] allocate dummy extradata\n", __func__);
-        avctx->extradata =
-                av_mallocz(ROUND_UP_X(FF_INPUT_BUFFER_PADDING_SIZE, 4));
-    }
-
-    if (bEncode) {
-        TRACE("[%s] find encoder :%d\n", __func__, codec_id);
-        codec = avcodec_find_encoder(codec_id);
-    } else {
-        TRACE("[%s] find decoder :%d\n", __func__, codec_id);
-        codec = avcodec_find_decoder(codec_id);
-    }
-
-    if (!codec) {
-        ERR("[%s] failed to find codec of %d\n", __func__, codec_id);
-    }
-
-    if (codec->type == AVMEDIA_TYPE_AUDIO) {
-        s->codec_ctx[ctx_index].mem_index = s->codec_param.mem_index;
-        TRACE("set mem_index: %d into ctx_index: %d.\n",
-            s->codec_ctx[ctx_index].mem_index, ctx_index);
-    }
-
-#if 0
-    avctx->get_buffer = qemu_avcodec_get_buffer;
-    avctx->release_buffer = qemu_avcodec_release_buffer;
-#endif
-
-    ret = avcodec_open(avctx, codec);
-    if (ret != 0) {
-        ERR("[%s] avcodec_open failure, %d\n", __func__, ret);
-    }
-
-    memcpy((uint8_t *)s->vaddr + offset, &ctx_index, sizeof(int));
-    size = sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->pix_fmt, sizeof(int));
-    size += sizeof(int);
-    size += qemu_serialize_rational(&avctx->time_base,
-            (uint8_t *)s->vaddr + offset + size);
-    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->channels, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size,
-            &avctx->sample_fmt, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size,
-            &avctx->codec_type, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->codec_id, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size,
-            &avctx->coded_width, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size,
-            &avctx->coded_height, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size,
-            &avctx->ticks_per_frame, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size,
-            &avctx->chroma_sample_location, sizeof(int));
-    size += sizeof(int);
-#if 0
-    memcpy((uint8_t *)s->vaddr + offset + size,
-            avctx->priv_data, codec->priv_data_size);
-    size += codec->priv_data_size;
-#endif
-    memcpy((uint8_t *)s->vaddr + offset + size, &ret, sizeof(int));
-    size += sizeof(int);
-
-    TRACE("Leave, %s\n", __func__);
-    return ret;
-}
-
-/* int avcodec_close(AVCodecContext *avctx) */
-int qemu_avcodec_close(SVCodecState *s, int ctx_index)
-{
-    AVCodecContext *avctx;
-    off_t offset;
-    int ret = -1;
-
-    TRACE("Enter, %s\n", __func__);
-    qemu_mutex_lock(&s->thread_mutex);
-
-    offset = s->codec_param.mmap_offset;
-
-    avctx = s->codec_ctx[ctx_index].avctx;
-    if (!avctx) {
-        ERR("[%s] %d of AVCodecContext is NULL\n", __func__, ctx_index);
-        memcpy((uint8_t *)s->vaddr + offset, &ret, sizeof(int));
-        qemu_mutex_unlock(&s->thread_mutex);
-        return ret;
-    }
-
-    ret = avcodec_close(avctx);
-    TRACE("after avcodec_close. ret:%d\n", ret);
-
-    memcpy((uint8_t *)s->vaddr + offset, &ret, sizeof(int));
-
-    qemu_mutex_unlock(&s->thread_mutex);
-
-    TRACE("[%s] Leave\n", __func__);
-    return ret;
-}
-
-/* AVCodecContext* avcodec_alloc_context (void) */
-int qemu_avcodec_alloc_context(SVCodecState *s)
-{
-    int index;
-
-    TRACE("[%s] Enter\n", __func__);
-
-    for (index = 0; index < CODEC_CONTEXT_MAX; index++) {
-        if (s->codec_ctx[index].avctx_use == false) {
-            TRACE("Succeeded to get %d of context.\n", index);
-            s->codec_ctx[index].avctx_use = true;
-            break;
-        }
-        TRACE("Failed to get context.\n");
-    }
-
-    if (index == CODEC_CONTEXT_MAX) {
-        ERR("Failed to get available codec context.");
-        ERR(" Try to run codec again.\n");
-        return -1;
-    }
-
-    TRACE("allocate %d of context and frame.\n", index);
-    s->codec_ctx[index].avctx = avcodec_alloc_context();
-    s->codec_ctx[index].frame = avcodec_alloc_frame();
-
-    s->codec_ctx[index].file_index = s->codec_param.file_index;
-    qemu_parser_init(s, index);
-    qemu_init_pix_fmt_info();
-
-    TRACE("[%s] Leave\n", __func__);
-
-    return index;
-}
-
-/* void av_free(void *ptr) */
-void qemu_av_free(SVCodecState *s, int ctx_index)
-{
-    AVCodecContext *avctx;
-    AVFrame *avframe;
-
-    TRACE("enter %s\n", __func__);
-    qemu_mutex_lock(&s->thread_mutex);
-
-    avctx = s->codec_ctx[ctx_index].avctx;
-    avframe = s->codec_ctx[ctx_index].frame;
-
-    if (avctx && avctx->palctrl) {
-        av_free(avctx->palctrl);
-        avctx->palctrl = NULL;
-    }
-
-    if (avctx && avctx->extradata) {
-        TRACE("free extradata\n");
-        av_free(avctx->extradata);
-        avctx->extradata = NULL;
-    }
-
-    if (avctx && avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
-        int audio_idx = s->codec_ctx[ctx_index].mem_index;
-        TRACE("reset audio mem_idex: %d\n", __LINE__, audio_idx);
-        s->audio_codec_offset[audio_idx] = 0;
-    }
-
-    if (avctx) {
-        TRACE("free codec context of %d.\n", ctx_index);
-        av_free(avctx);
-        s->codec_ctx[ctx_index].avctx = NULL;
-    }
-
-    if (avframe) {
-        TRACE("free codec frame of %d.\n", ctx_index);
-        av_free(avframe);
-        s->codec_ctx[ctx_index].frame = NULL;
-    }
-
-    qemu_mutex_unlock(&s->thread_mutex);
-    TRACE("leave %s\n", __func__);
-}
-
-/* void avcodec_flush_buffers(AVCodecContext *avctx) */
-void qemu_avcodec_flush_buffers(SVCodecState *s, int ctx_index)
-{
-    AVCodecContext *avctx;
-
-    TRACE("Enter\n");
-    qemu_mutex_lock(&s->thread_mutex);
-
-    avctx = s->codec_ctx[ctx_index].avctx;
-    if (avctx) {
-        avcodec_flush_buffers(avctx);
-    } else {
-        ERR("[%s] %d of AVCodecContext is NULL\n", __func__, ctx_index);
-    }
-
-    qemu_mutex_unlock(&s->thread_mutex);
-    TRACE("[%s] Leave\n", __func__);
-}
-
-/* int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture,
- *                          int *got_picture_ptr, const uint8_t *buf,
- *                          int buf_size)
- */
-int qemu_avcodec_decode_video(SVCodecState *s, int ctx_index)
-{
-    AVCodecContext *avctx;
-    AVFrame *picture;
-    AVPacket avpkt;
-    int got_picture_ptr;
-    uint8_t *buf;
-    uint8_t *parser_buf;
-    bool parser_use;
-    int buf_size;
-    int size = 0;
-    int ret = -1;
-    off_t offset;
-
-    TRACE("Enter, %s\n", __func__);
-    qemu_mutex_lock(&s->codec_thread.mutex);
-
-    TRACE("[%s] Video Context Index : %d\n", __func__, ctx_index);
-
-    avctx = s->codec_ctx[ctx_index].avctx;
-    picture = s->codec_ctx[ctx_index].frame;
-    if (!avctx || !picture) {
-        ERR("[%s] %d of Context or Frame is NULL!\n", __func__, ctx_index);
-        qemu_mutex_unlock(&s->codec_thread.mutex);
-        return ret;
-    }
-
-    offset = s->codec_param.mmap_offset;
-
-    parser_buf = s->codec_ctx[ctx_index].parser_buf;
-    parser_use = s->codec_ctx[ctx_index].parser_use;
-    TRACE("[%s] Parser Buffer : %p, Parser:%d\n", __func__,
-            parser_buf, parser_use);
-
-    memcpy(&avctx->reordered_opaque,
-            (uint8_t *)s->vaddr + offset, sizeof(int64_t));
-    size = sizeof(int64_t);
-    memcpy(&avctx->skip_frame,
-            (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-    memcpy(&buf_size, (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-
-    picture->reordered_opaque = avctx->reordered_opaque;
-
-    if (parser_buf && parser_use) {
-        buf = parser_buf;
-    } else if (buf_size > 0) {
-        TRACE("[%s] not use parser, codec_id:%x\n", __func__, avctx->codec_id);
-        buf = (uint8_t *)s->vaddr + offset + size;
-        size += buf_size;
-    } else {
-        TRACE("There is no input buffer\n");
-        buf = NULL;
-    }
-
-    memset(&avpkt, 0, sizeof(AVPacket));
-    avpkt.data = buf;
-    avpkt.size = buf_size;
-    TRACE("packet buf:%p, size:%d\n", buf, buf_size);
-
-    ret = avcodec_decode_video2(avctx, picture, &got_picture_ptr, &avpkt);
-
-    TRACE("[%s] after decoding video, ret:%d\n", __func__, ret);
-    if (ret < 0) {
-        ERR("[%s] failed to decode video!!, ret:%d\n", __func__, ret);
-    } else {
-        if (ret == 0) {
-            TRACE("[%s] no frame. packet size:%d\n", __func__, avpkt.size);
-        }
-        TRACE("decoded frame number:%d\n", avctx->frame_number);
-    }
-
-    memcpy((uint8_t *)s->vaddr + offset, &avctx->pix_fmt, sizeof(int));
-    size = sizeof(int);
-    size += qemu_serialize_rational(&avctx->time_base,
-                                    (uint8_t *)s->vaddr + offset + size);
-    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->width, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->height, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size,
-            &avctx->has_b_frames, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size,
-            &avctx->frame_number, sizeof(int));
-    size += sizeof(int);
-    size += qemu_serialize_rational(&avctx->sample_aspect_ratio,
-                                    (uint8_t *)s->vaddr + offset + size);
-    memcpy((uint8_t *)s->vaddr + offset + size,
-            &avctx->internal_buffer_count, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->profile, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->level, sizeof(int));
-    size += sizeof(int);
-    size += qemu_serialize_frame(picture, (uint8_t *)s->vaddr + offset + size);
-
-    memcpy((uint8_t *)s->vaddr + offset + size, &got_picture_ptr, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size, &ret, sizeof(int));
-    size += sizeof(int);
-
-#if 0
-    memcpy((uint8_t *)s->vaddr + offset + size, dst.data[0], numbytes);
-    av_free(buffer);
-
-    if (parser_buf && parser_use) {
-        TRACE("[%s] Free input buffer after decoding video\n", __func__);
-        TRACE("[%s] input buffer : %p, %p\n",
-            __func__, avpkt.data, parser_buf);
-        av_free(avpkt.data);
-        s->codec_ctx[ctx_index].parser_buf = NULL;
-    }
-#endif
-
-    qemu_mutex_unlock(&s->codec_thread.mutex);
-    TRACE("Leave, %s\n", __func__);
-
-    return ret;
-}
-
-/* int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf,
- *                          int buf_size, const AVFrame *pict)
- */
-int qemu_avcodec_encode_video(SVCodecState *s, int ctx_index)
-{
-    AVCodecContext *avctx = NULL;
-    AVFrame *pict = NULL;
-    uint8_t *inputBuf = NULL;
-    int outbufSize = 0;
-    int bPict = -1;
-    int size = 0;
-    int ret = -1;
-    off_t offset;
-
-    TRACE("Enter, %s\n", __func__);
-    qemu_mutex_lock(&s->codec_thread.mutex);
-
-    avctx = s->codec_ctx[ctx_index].avctx;
-    pict = s->codec_ctx[ctx_index].frame;
-    if (!avctx || !pict) {
-        ERR("[%s] %d of Context or Frame is NULL\n", __func__, ctx_index);
-        qemu_mutex_unlock(&s->thread_mutex);
-        return ret;
-    }
-
-    offset = s->codec_param.mmap_offset;
-
-    size = sizeof(int);
-    memcpy(&bPict, (uint8_t *)s->vaddr + offset, size);
-    TRACE("[%s] avframe is :%d\n", __func__, bPict);
-
-    if (bPict == 0) {
-        memcpy(&outbufSize, (uint8_t *)s->vaddr + offset + size, size);
-        size += sizeof(int);
-        size +=
-            qemu_deserialize_frame((uint8_t *)s->vaddr + offset + size, pict);
-
-        inputBuf = (uint8_t *)s->vaddr + offset + size;
-        if (!inputBuf) {
-            ERR("[%s] failed to get input buffer\n", __func__);
-            return ret;
-        }
-
-        ret = qemu_avpicture_fill((AVPicture *)pict, inputBuf, avctx->pix_fmt,
-                            avctx->width, avctx->height, true);
-
-        if (ret < 0) {
-            ERR("after avpicture_fill, ret:%d\n", ret);
-        }
-        TRACE("before encode video, ticks_per_frame:%d, pts:%lld\n",
-               avctx->ticks_per_frame, pict->pts);
-    } else {
-        TRACE("flush encoded buffers\n");
-        pict = NULL;
-    }
-
-    ret = avcodec_encode_video(avctx, (uint8_t *)s->vaddr + offset,
-                                outbufSize, pict);
-    TRACE("encode video, ret:%d, pts:%lld, outbuf size:%d\n",
-            ret, pict->pts, outbufSize);
-
-    if (ret < 0) {
-        ERR("failed to encode video.\n");
-    }
-
-    memcpy((uint8_t *)s->vaddr + offset + outbufSize, &ret, sizeof(int));
-
-    qemu_mutex_unlock(&s->codec_thread.mutex);
-    TRACE("Leave, %s\n", __func__);
-
-    return ret;
-}
-
-/*
- *  int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
- *                            int *frame_size_ptr, AVPacket *avpkt)
- */
-int qemu_avcodec_decode_audio(SVCodecState *s, int ctx_index)
-{
-    AVCodecContext *avctx;
-    AVPacket avpkt;
-    int16_t *samples;
-    int frame_size_ptr;
-    uint8_t *buf;
-    uint8_t *parser_buf;
-    bool parser_use;
-    int buf_size, outbuf_size;
-    int size;
-    int ret = -1;
-    off_t offset;
-
-    TRACE("Enter, %s\n", __func__);
-
-    TRACE("Audio Context Index : %d\n", ctx_index);
-    avctx = s->codec_ctx[ctx_index].avctx;
-    if (!avctx) {
-        ERR("[%s] %d of Context is NULL!\n", __func__, ctx_index);
-        qemu_mutex_unlock(&s->codec_thread.mutex);
-        return ret;
-    }
-
-    if (!avctx->codec) {
-        ERR("[%s] %d of Codec is NULL\n", __func__, ctx_index);
-        qemu_mutex_unlock(&s->codec_thread.mutex);
-        return ret;
-    }
-
-    offset = s->codec_param.mmap_offset;
-
-    parser_buf = s->codec_ctx[ctx_index].parser_buf;
-    parser_use = s->codec_ctx[ctx_index].parser_use;
-
-    memcpy(&buf_size, (uint8_t *)s->vaddr + offset, sizeof(int));
-    size = sizeof(int);
-    if (parser_buf && parser_use) {
-        TRACE("[%s] use parser, buf:%p codec_id:%x\n",
-                __func__, parser_buf, avctx->codec_id);
-        buf = parser_buf;
-    } else if (buf_size > 0) {
-        TRACE("[%s] not use parser, codec_id:%x\n", __func__, avctx->codec_id);
-        buf = (uint8_t *)s->vaddr + offset + size;
-        size += buf_size;
-    } else {
-        TRACE("no input buffer\n");
-        buf = NULL;
-    }
-
-    av_init_packet(&avpkt);
-    avpkt.data = buf;
-    avpkt.size = buf_size;
-
-    frame_size_ptr = AVCODEC_MAX_AUDIO_FRAME_SIZE;
-    outbuf_size = frame_size_ptr;
-    samples = av_malloc(frame_size_ptr);
-
-    ret = avcodec_decode_audio3(avctx, samples, &frame_size_ptr, &avpkt);
-    TRACE("after decoding audio!, ret:%d\n", ret);
-
-    memcpy((uint8_t *)s->vaddr + offset, &avctx->bit_rate, sizeof(int));
-    size = sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size,
-            &avctx->sample_rate, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->channels, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size,
-        &avctx->channel_layout, sizeof(int64_t));
-    size += sizeof(int64_t);
-    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->sub_id, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size,
-            &avctx->frame_size, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size,
-            &avctx->frame_number, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size, samples, outbuf_size);
-    size += outbuf_size;
-    memcpy((uint8_t *)s->vaddr + offset + size, &frame_size_ptr, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size, &ret, sizeof(int));
-    size += sizeof(int);
-
-    TRACE("before free input buffer and output buffer!\n");
-    if (samples) {
-        TRACE("release allocated audio buffer.\n");
-        av_free(samples);
-        samples = NULL;
-    }
-
-    if (parser_buf && parser_use) {
-        TRACE("[%s] free parser buf\n", __func__);
-        av_free(avpkt.data);
-        s->codec_ctx[ctx_index].parser_buf = NULL;
-    }
-
-    TRACE("[%s] Leave\n", __func__);
-
-    return ret;
-}
-
-int qemu_avcodec_encode_audio(SVCodecState *s, int ctx_index)
-{
-    WARN("[%s] Does not support audio encoder using FFmpeg\n", __func__);
-    return 0;
-}
-
-/* void av_picture_copy(AVPicture *dst, const AVPicture *src,
- *                      enum PixelFormat pix_fmt, int width, int height)
- */
-void qemu_av_picture_copy(SVCodecState *s, int ctx_index)
-{
-    AVCodecContext *avctx = NULL;
-    AVPicture dst;
-    AVPicture *src = NULL;
-    int numBytes = 0;
-    uint8_t *buffer = NULL;
-    off_t offset = 0;
-
-    TRACE("Enter :%s\n", __func__);
-    qemu_mutex_lock(&s->thread_mutex);
-
-    avctx = s->codec_ctx[ctx_index].avctx;
-    src = (AVPicture *)s->codec_ctx[ctx_index].frame;
-    if (!avctx && !src) {
-        ERR("[%s] %d of context or frame is NULL\n", __func__, ctx_index);
-        qemu_mutex_unlock(&s->thread_mutex);
-        return;
-    }
-
-    offset = s->codec_param.mmap_offset;
-
-    numBytes = qemu_avpicture_fill(&dst, NULL, avctx->pix_fmt,
-                                  avctx->width, avctx->height, false);
-    TRACE("after avpicture_fill: %d\n", numBytes);
-    if (numBytes < 0) {
-        ERR("picture size:%d is wrong.\n", numBytes);
-        qemu_mutex_unlock(&s->thread_mutex);
-        return;
-    }
-
-    av_picture_copy(&dst, src, avctx->pix_fmt, avctx->width, avctx->height);
-    buffer = dst.data[0];
-    memcpy((uint8_t *)s->vaddr + offset, buffer, numBytes);
-    TRACE("after copy image buffer from host to guest.\n");
-
-    if (buffer) {
-        TRACE("release allocated video frame.\n");
-        av_free(buffer);
-    }
-
-    qemu_mutex_unlock(&s->thread_mutex);
-    TRACE("Leave :%s\n", __func__);
-}
-
-/* AVCodecParserContext *av_parser_init(int codec_id) */
-void qemu_av_parser_init(SVCodecState *s, int ctx_index)
-{
-    AVCodecParserContext *parser_ctx = NULL;
-    AVCodecContext *avctx;
-
-    TRACE("Enter :%s\n", __func__);
-    qemu_mutex_lock(&s->thread_mutex);
-
-    avctx = s->codec_ctx[ctx_index].avctx;
-    if (!avctx) {
-        ERR("[%s] %d of AVCodecContext is NULL!!\n", __func__, ctx_index);
-        qemu_mutex_unlock(&s->thread_mutex);
-        return;
-    }
-
-    TRACE("before av_parser_init, codec_type:%d codec_id:%x\n",
-            avctx->codec_type, avctx->codec_id);
-
-    parser_ctx = av_parser_init(avctx->codec_id);
-    if (parser_ctx) {
-        TRACE("[%s] using parser\n", __func__);
-        s->codec_ctx[ctx_index].parser_use = true;
-    } else {
-        TRACE("[%s] no parser\n", __func__);
-        s->codec_ctx[ctx_index].parser_use = false;
-    }
-    s->codec_ctx[ctx_index].parser_ctx = parser_ctx;
-
-    qemu_mutex_unlock(&s->thread_mutex);
-    TRACE("[%s] Leave\n", __func__);
-}
-
-/* int av_parser_parse(AVCodecParserContext *s, AVCodecContext *avctx,
- *                     uint8_t **poutbuf, int *poutbuf_size,
- *                     const uint8_t *buf, int buf_size,
- *                     int64_t pts, int64_t dts)
- */
-int qemu_av_parser_parse(SVCodecState *s, int ctx_index)
-{
-    AVCodecParserContext *parser_ctx = NULL;
-    AVCodecContext *avctx = NULL;
-    uint8_t *poutbuf;
-    int poutbuf_size = 0;
-    uint8_t *inbuf = NULL;
-    int inbuf_size;
-    int64_t pts;
-    int64_t dts;
-    int64_t pos;
-    int size, ret = -1;
-    off_t offset;
-
-    TRACE("Enter %s\n", __func__);
-    qemu_mutex_lock(&s->thread_mutex);
-
-    parser_ctx = s->codec_ctx[ctx_index].parser_ctx;
-    avctx = s->codec_ctx[ctx_index].avctx;
-    if (!avctx) {
-        ERR("[%s] %d of AVCodecContext is NULL\n", __func__, ctx_index);
-        qemu_mutex_unlock(&s->thread_mutex);
-        return ret;
-    }
-
-    if (!parser_ctx) {
-        ERR("[%s] %d of AVCodecParserContext is NULL\n", __func__, ctx_index);
-        qemu_mutex_unlock(&s->thread_mutex);
-        return ret;
-    }
-
-    offset = s->codec_param.mmap_offset;
-
-    memcpy(&parser_ctx->pts,
-        (uint8_t *)s->vaddr + offset, sizeof(int64_t));
-    size = sizeof(int64_t);
-    memcpy(&parser_ctx->dts,
-        (uint8_t *)s->vaddr + offset + size, sizeof(int64_t));
-    size += sizeof(int64_t);
-    memcpy(&parser_ctx->pos,
-        (uint8_t *)s->vaddr + offset + size, sizeof(int64_t));
-    size += sizeof(int64_t);
-    memcpy(&pts, (uint8_t *)s->vaddr + offset + size, sizeof(int64_t));
-    size += sizeof(int64_t);
-    memcpy(&dts, (uint8_t *)s->vaddr + offset + size, sizeof(int64_t));
-    size += sizeof(int64_t);
-    memcpy(&pos, (uint8_t *)s->vaddr + offset + size, sizeof(int64_t));
-    size += sizeof(int64_t);
-    memcpy(&inbuf_size, (uint8_t *)s->vaddr + offset + size, sizeof(int));
-    size += sizeof(int);
-
-    if (inbuf_size > 0) {
-        inbuf = av_mallocz(inbuf_size);
-        memcpy(inbuf, (uint8_t *)s->vaddr + offset + size, inbuf_size);
-    } else {
-        inbuf = NULL;
-        INFO("input buffer size for parser is zero.\n");
-    }
-
-    TRACE("[%s] inbuf:%p inbuf_size :%d\n", __func__, inbuf, inbuf_size);
-    ret = av_parser_parse2(parser_ctx, avctx, &poutbuf, &poutbuf_size,
-                           inbuf, inbuf_size, pts, dts, pos);
-    TRACE("after parsing, outbuf size :%d, ret:%d\n", poutbuf_size, ret);
-
-    if (poutbuf) {
-        s->codec_ctx[ctx_index].parser_buf = poutbuf;
-    }
-
-    TRACE("[%s] inbuf : %p, outbuf : %p\n", __func__, inbuf, poutbuf);
-    memcpy((uint8_t *)s->vaddr + offset, &parser_ctx->pts, sizeof(int64_t));
-    size = sizeof(int64_t);
-    memcpy((uint8_t *)s->vaddr + offset + size, &poutbuf_size, sizeof(int));
-    size += sizeof(int);
-    memcpy((uint8_t *)s->vaddr + offset + size, &ret, sizeof(int));
-    size += sizeof(int);
-    if (poutbuf && poutbuf_size > 0) {
-        memcpy((uint8_t *)s->vaddr + offset + size, poutbuf, poutbuf_size);
-    } else {
-        av_free(inbuf);
-    }
-
-#if 0
-    if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
-        TRACE("[%s] free parser inbuf\n", __func__);
-        av_free(inbuf);
-    }
-#endif
-
-    qemu_mutex_unlock(&s->thread_mutex);
-    TRACE("Leave, %s\n", __func__);
-
-    return ret;
-}
-
-/* void av_parser_close(AVCodecParserContext *s) */
-void qemu_av_parser_close(SVCodecState *s, int ctx_index)
-{
-    AVCodecParserContext *parser_ctx;
-
-    TRACE("Enter, %s\n", __func__);
-    qemu_mutex_lock(&s->thread_mutex);
-
-    parser_ctx = s->codec_ctx[ctx_index].parser_ctx;
-    if (!parser_ctx) {
-        ERR("AVCodecParserContext is NULL\n");
-        qemu_mutex_unlock(&s->thread_mutex);
-        return;
-    }
-    av_parser_close(parser_ctx);
-
-    qemu_mutex_unlock(&s->thread_mutex);
-    TRACE("Leave, %s\n", __func__);
-}
-
-int codec_operate(uint32_t api_index, uint32_t ctx_index, SVCodecState *s)
-{
-    int ret = -1;
-
-    TRACE("[%s] context : %d\n", __func__, ctx_index);
-    switch (api_index) {
-    /* FFMPEG API */
-    case EMUL_AV_REGISTER_ALL:
-        qemu_av_register_all();
-        break;
-    case EMUL_AVCODEC_OPEN:
-        ret = qemu_avcodec_open(s);
-        break;
-    case EMUL_AVCODEC_CLOSE:
-        ret = qemu_avcodec_close(s, ctx_index);
-        qemu_av_free(s, ctx_index);
-        break;
-    case EMUL_AVCODEC_FLUSH_BUFFERS:
-        qemu_avcodec_flush_buffers(s, ctx_index);
-        break;
-    case EMUL_AVCODEC_DECODE_VIDEO:
-    case EMUL_AVCODEC_ENCODE_VIDEO:
-    case EMUL_AVCODEC_DECODE_AUDIO:
-    case EMUL_AVCODEC_ENCODE_AUDIO:
-        wake_codec_worker_thread(s);
-        break;
-    case EMUL_AV_PICTURE_COPY:
-        qemu_av_picture_copy(s, ctx_index);
-        break;
-    case EMUL_AV_PARSER_INIT:
-        qemu_av_parser_init(s, ctx_index);
-        break;
-    case EMUL_AV_PARSER_PARSE:
-        ret = qemu_av_parser_parse(s, ctx_index);
-        break;
-    case EMUL_AV_PARSER_CLOSE:
-        qemu_av_parser_close(s, ctx_index);
-        break;
-    default:
-        WARN("api index %d does not exist!.\n", api_index);
-    }
-    return ret;
-}
-
-static uint32_t qemu_get_mmap_offset(SVCodecState *s)
-{
-    int index = 0;
-
-    for (; index < AUDIO_CODEC_MEM_OFFSET_MAX; index++)  {
-        if (s->audio_codec_offset[index] == 0) {
-            s->audio_codec_offset[index] = 1;
-            break;
-        }
-    }
-    TRACE("return mmap offset: %d\n", index);
-
-    return index;
-}
-
-/*
- *  Codec Device APIs
- */
-uint64_t codec_read(void *opaque, hwaddr addr, unsigned size)
-{
-    SVCodecState *s = (SVCodecState *)opaque;
-    uint64_t ret = 0;
-
-    switch (addr) {
-    case CODEC_CMD_GET_THREAD_STATE:
-        qemu_mutex_lock(&s->thread_mutex);
-        ret = s->codec_thread.state;
-        s->codec_thread.state = 0;
-        qemu_mutex_unlock(&s->thread_mutex);
-        TRACE("ret: %d, thread state: %d\n", ret, s->codec_thread.state);
-        qemu_irq_lower(s->dev.irq[0]);
-        break;
-    case CODEC_CMD_GET_VERSION:
-        ret = MARU_CODEC_VERSION;
-        TRACE("codec version: %d\n", ret);
-        break;
-    case CODEC_CMD_GET_DEVICE_MEM:
-        qemu_mutex_lock(&s->thread_mutex);
-        ret = s->device_mem_avail;
-        if (s->device_mem_avail != 1) {
-            s->device_mem_avail = 1;
-        }
-        qemu_mutex_unlock(&s->thread_mutex);
-        break;
-    case CODEC_CMD_GET_MMAP_OFFSET:
-        ret = qemu_get_mmap_offset(s);
-        TRACE("mem index: %d\n", ret);
-        break;
-    default:
-        ERR("no avaiable command for read. %d\n", addr);
-    }
-
-    return ret;
-}
-
-void codec_write(void *opaque, hwaddr addr,
-                uint64_t value, unsigned size)
-{
-    SVCodecState *s = (SVCodecState *)opaque;
-
-    switch (addr) {
-    case CODEC_CMD_API_INDEX:
-        codec_operate(value, s->codec_param.ctx_index, s);
-        break;
-    case CODEC_CMD_CONTEXT_INDEX:
-        s->codec_param.ctx_index = value;
-        TRACE("Context Index: %d\n", s->codec_param.ctx_index);
-        break;
-    case CODEC_CMD_FILE_INDEX:
-        s->codec_param.file_index = value;
-        break;
-    case CODEC_CMD_DEVICE_MEM_OFFSET:
-        s->codec_param.mmap_offset = value;
-        TRACE("MMAP Offset: %d\n", s->codec_param.mmap_offset);
-        break;
-    case CODEC_CMD_RESET_CODEC_INFO:
-        qemu_reset_codec_info(s, value);
-        break;
-    case CODEC_CMD_SET_DEVICE_MEM:
-        qemu_mutex_lock(&s->thread_mutex);
-        s->device_mem_avail = value;
-        qemu_mutex_unlock(&s->thread_mutex);
-        break;
-    case CODEC_CMD_SET_MMAP_OFFSET:
-        s->codec_param.mem_index = value;
-        break;
-    default:
-        ERR("no avaiable command for write. %d\n", addr);
-    }
-}
-
-static const MemoryRegionOps codec_mmio_ops = {
-    .read = codec_read,
-    .write = codec_write,
-    .endianness = DEVICE_LITTLE_ENDIAN,
-};
-
-static void codec_tx_bh(void *opaque)
-{
-    SVCodecState *s = (SVCodecState *)opaque;
-
-    int ctx_index;
-    AVCodecContext *ctx;
-
-    ctx_index = s->codec_param.ctx_index;
-    ctx = s->codec_ctx[ctx_index].avctx;
-
-    TRACE("Enter, %s\n", __func__);
-
-    /* raise irq as soon as a worker thread had finished a job*/
-    if (s->codec_thread.state) {
-        TRACE("raise codec irq. state:%d, codec:%d\n",
-              s->codec_thread.state, ctx->codec_type);
-        qemu_irq_raise(s->dev.irq[0]);
-    }
-
-    TRACE("Leave, %s\n", __func__);
-}
-
-static int codec_initfn(PCIDevice *dev)
-{
-    SVCodecState *s = DO_UPCAST(SVCodecState, dev, dev);
-    uint8_t *pci_conf = s->dev.config;
-
-    INFO("[%s] device init\n", __func__);
-
-    memset(&s->codec_param, 0, sizeof(SVCodecParam));
-
-    qemu_mutex_init(&s->thread_mutex);
-    codec_thread_init(s);
-    s->tx_bh = qemu_bh_new(codec_tx_bh, s);
-
-    pci_config_set_interrupt_pin(pci_conf, 1);
-
-    memory_region_init_ram(&s->vram, OBJECT(s), "codec.ram", MARU_CODEC_MEM_SIZE);
-    s->vaddr = memory_region_get_ram_ptr(&s->vram);
-
-    memory_region_init_io(&s->mmio, OBJECT(s), &codec_mmio_ops, s,
-                        "codec-mmio", MARU_CODEC_REG_SIZE);
-
-    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
-    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);
-
-    return 0;
-}
-
-static void codec_exitfn(PCIDevice *dev)
-{
-    SVCodecState *s = DO_UPCAST(SVCodecState, dev, dev);
-    INFO("[%s] device exit\n", __func__);
-
-    qemu_bh_delete(s->tx_bh);
-
-    memory_region_destroy(&s->vram);
-    memory_region_destroy(&s->mmio);
-}
-
-int codec_init(PCIBus *bus)
-{
-    INFO("[%s] device create\n", __func__);
-    pci_create_simple(bus, -1, MARU_CODEC_DEV_NAME);
-    return 0;
-}
-
-static void codec_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
-
-    k->init = codec_initfn;
-    k->exit = codec_exitfn;
-    k->vendor_id = PCI_VENDOR_ID_TIZEN;
-    k->device_id = PCI_DEVICE_ID_VIRTUAL_CODEC;
-    k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
-    dc->desc = "Virtual Codec device for Tizen emulator";
-}
-
-static TypeInfo codec_info = {
-    .name          = MARU_CODEC_DEV_NAME,
-    .parent        = TYPE_PCI_DEVICE,
-    .instance_size = sizeof(SVCodecState),
-    .class_init    = codec_class_init,
-};
-
-static void codec_register_types(void)
-{
-    type_register_static(&codec_info);
-}
-
-type_init(codec_register_types)
diff --git a/tizen/src/hw/maru_codec.h b/tizen/src/hw/maru_codec.h
deleted file mode 100644 (file)
index 999d232..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Virtual Codec device
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Kitae Kim <kt920.kim@samsung.com>
- *  SeokYeon Hwang <syeon.hwang@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 <stdio.h>
-#include <sys/types.h>
-#include "hw/hw.h"
-#include "sysemu/kvm.h"
-#include "hw/pci/pci.h"
-#include "hw/pci/pci_ids.h"
-#include "qemu/thread.h"
-#include "debug_ch.h"
-#include "maru_device_ids.h"
-
-#include <libavformat/avformat.h>
-
-#define CODEC_CONTEXT_MAX                      1024
-#define VIDEO_CODEC_MEM_OFFSET_MAX     16
-#define AUDIO_CODEC_MEM_OFFSET_MAX     64
-
-#define CODEC_MAX_THREAD       10
-
-/*
- *  Codec Device Structures
- */
-typedef struct _SVCodecParam {
-    uint32_t        api_index;
-    uint32_t        ctx_index;
-    uint32_t        file_index;
-    uint32_t        mem_index;
-    uint32_t        mmap_offset;
-} SVCodecParam;
-
-typedef struct _SVCodecContext {
-    AVCodecContext          *avctx;
-    AVFrame                 *frame;
-    AVCodecParserContext    *parser_ctx;
-    uint8_t                 *parser_buf;
-    uint8_t                 parser_use;
-    uint8_t                 avctx_use;
-    uint32_t                file_index;
-       uint32_t                                mem_index;
-} SVCodecContext;
-
-typedef struct _SVCodecThreadPool {
-       QemuThread                      *wrk_thread;
-       QemuMutex                       mutex;
-       QemuCond                        cond;
-       uint32_t                        state;
-       uint8_t                         isrunning;
-} SVCodecThreadPool;
-
-typedef struct _SVCodecState {
-    PCIDevice           dev;
-
-    uint8_t             *vaddr;
-    MemoryRegion        vram;
-    MemoryRegion        mmio;
-
-    QEMUBH              *tx_bh;
-    QemuMutex           thread_mutex;
-
-    SVCodecContext      codec_ctx[CODEC_CONTEXT_MAX];
-    SVCodecParam        codec_param;
-       SVCodecThreadPool       codec_thread;
-       uint8_t                         audio_codec_offset[AUDIO_CODEC_MEM_OFFSET_MAX];
-       uint8_t                         device_mem_avail;
-       uint8_t                         isrunning;
-} SVCodecState;
-
-enum codec_io_cmd {
-    CODEC_CMD_API_INDEX         = 0x00,
-    CODEC_CMD_CONTEXT_INDEX     = 0x04,
-       CODEC_CMD_FILE_INDEX            = 0x08,
-    CODEC_CMD_DEVICE_MEM_OFFSET        = 0x0c,
-    CODEC_CMD_GET_THREAD_STATE = 0x10,
-    CODEC_CMD_GET_VERSION       = 0x14,
-    CODEC_CMD_GET_DEVICE_MEM    = 0x18,
-    CODEC_CMD_SET_DEVICE_MEM   = 0x1C,
-    CODEC_CMD_GET_MMAP_OFFSET  = 0x20,
-    CODEC_CMD_SET_MMAP_OFFSET  = 0x24,
-    CODEC_CMD_RESET_CODEC_INFO  = 0x28,
-};
-
-enum {
-    EMUL_AV_REGISTER_ALL = 1,
-    EMUL_AVCODEC_OPEN,
-    EMUL_AVCODEC_CLOSE,
-    EMUL_AVCODEC_FLUSH_BUFFERS,
-    EMUL_AVCODEC_DECODE_VIDEO,
-    EMUL_AVCODEC_ENCODE_VIDEO,
-    EMUL_AVCODEC_DECODE_AUDIO,
-    EMUL_AVCODEC_ENCODE_AUDIO,
-    EMUL_AV_PICTURE_COPY,
-    EMUL_AV_PARSER_INIT,
-    EMUL_AV_PARSER_PARSE,
-    EMUL_AV_PARSER_CLOSE,
-};
-
-
-/*
- *  Codec Thread Functions
- */
-void codec_thread_init(SVCodecState *s);
-void codec_thread_exit(SVCodecState *s);
-void *codec_worker_thread(void *opaque);
-void wake_codec_worker_thread(SVCodecState *s);
-int decode_codec(SVCodecState *s);
-int encode_codec(SVCodecState *s);
-
-/*
- *  Codec Device Functions
- */
-int codec_init(PCIBus *bus);
-uint64_t codec_read(void *opaque, hwaddr addr,
-                    unsigned size);
-void codec_write(void *opaque, hwaddr addr,
-                uint64_t value, unsigned size);
-int codec_operate(uint32_t api_index, uint32_t ctx_index,
-                SVCodecState *state);
-
-/*
- *  Codec Helper Functions
- */
-void qemu_parser_init(SVCodecState *s, int ctx_index);
-void qemu_codec_close(SVCodecState *s, uint32_t value);
-void qemu_get_codec_ver(SVCodecState *s);
-void qemu_reset_codec_info(SVCodecState *s, uint32_t value);
-
-/*
- *  FFMPEG Functions
- */
-void qemu_av_register_all(void);
-int qemu_avcodec_open(SVCodecState *s);
-int qemu_avcodec_close(SVCodecState *s, int ctx_index);
-int qemu_avcodec_alloc_context(SVCodecState *s);
-void qemu_avcodec_flush_buffers(SVCodecState *s, int ctx_index);
-int qemu_avcodec_decode_video(SVCodecState *s, int ctx_index);
-int qemu_avcodec_encode_video(SVCodecState *s, int ctx_index);
-int qemu_avcodec_decode_audio(SVCodecState *s, int ctx_index);
-int qemu_avcodec_encode_audio(SVCodecState *s, int ctx_index);
-void qemu_av_picture_copy(SVCodecState *s, int ctx_index);
-void qemu_av_parser_init(SVCodecState *s, int ctx_index);
-int qemu_av_parser_parse(SVCodecState *s, int ctx_index);
-void qemu_av_parser_close(SVCodecState *s, int ctx_index);
-int qemu_avcodec_get_buffer(AVCodecContext *context, AVFrame *picture);
-void qemu_avcodec_release_buffer(AVCodecContext *context, AVFrame *picture);
-void qemu_av_free(SVCodecState *s, int ctx_index);
index abaf96ccd9ecdc45a010f00ccc8dfadf91470124..2b963e52d45268181643b3357e095b9b2a1ec928 100644 (file)
@@ -31,7 +31,7 @@
 #include "sysemu/sysemu.h"
 
 #include "debug_ch.h"
-#include "sdb_noti_server.h"
+#include "util/sdb_noti_server.h"
 
 /* define debug channel */
 MULTI_DEBUG_CHANNEL(tizen, maru_pm);
diff --git a/tizen/src/hw/maru_usb_touchscreen.c b/tizen/src/hw/maru_usb_touchscreen.c
deleted file mode 100644 (file)
index 3f1b7e8..0000000
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Maru USB Touchscreen Device
- * Based on hw/usb-wacom.c:
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  GiWoong Kim <giwoong.kim@samsung.com>
- *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- *  HyunJun Son
- *
- * 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 "maru_usb_touchscreen.h"
-#include "debug_ch.h"
-
-MULTI_DEBUG_CHANNEL(qemu, usb_touchscreen);
-
-
-#define MAX_TOUCH_EVENT_CNT 128
-
-//lock for between communication thread and main thread
-static pthread_mutex_t event_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static QTAILQ_HEAD(, TouchEventEntry) events_queue =
-    QTAILQ_HEAD_INITIALIZER(events_queue);
-
-static unsigned int event_cnt = 0;
-static unsigned int _processed_buf_cnt = 0;
-static TouchEventEntry _event_buf[MAX_TOUCH_EVENT_CNT];
-
-/**
- * @brief : qemu touch(host mouse) event handler
- * @param opaque : state of device
- * @param x : X-axis value
- * @param y : Y-axis value
- * @param z : event id for multiple touch
- */
-static void usb_touchscreen_event(void *opaque, int x, int y, int z, int buttons_state)
-{
-    TouchEventEntry *te;
-    USBTouchscreenState *s = opaque;
-
-    pthread_mutex_lock(&event_mutex);
-    if (event_cnt >= MAX_TOUCH_EVENT_CNT) {
-        pthread_mutex_unlock(&event_mutex);
-        INFO("full touch event queue, lose event\n", event_cnt);
-        return;
-    }
-
-    //using prepared memory
-    te = &(_event_buf[_processed_buf_cnt % MAX_TOUCH_EVENT_CNT]);
-    _processed_buf_cnt++;
-
-    /* mouse event is copied into the queue */
-    te->index = ++event_cnt;
-    te->queue_packet.x = x;
-    te->queue_packet.y = y;
-    te->queue_packet.z = z;
-    te->queue_packet.state = buttons_state;
-
-    QTAILQ_INSERT_TAIL(&events_queue, te, node);
-    s->changed = 1;
-    pthread_mutex_unlock(&event_mutex);
-
-    TRACE("touch event (%d) : x=%d, y=%d, z=%d, state=%d\n", te->index, x, y, z, buttons_state);
-}
-
-/**
- * @brief : fill the usb packet
- * @param s : state of device
- * @param buf : usb packet
- * @param len : size of packet
- */
-static int usb_touchscreen_poll(USBTouchscreenState *s, uint8_t *buf, int len)
-{
-    USBEmulTouchscreenPacket *packet = (USBEmulTouchscreenPacket *)buf;
-
-    if (s->mouse_grabbed == 0) {
-        s->eh_entry = qemu_add_mouse_event_handler(usb_touchscreen_event, s, 1, "QEMU USB touchscreen");
-        qemu_activate_mouse_event_handler(s->eh_entry);
-        s->mouse_grabbed = 1;
-    }
-
-    if (len < EMUL_TOUCHSCREEN_PACKET_LEN) {
-        return 0;
-    }
-
-    packet->x = s->dx & 0xffff;
-    packet->y = s->dy & 0xffff;
-    packet->z = s->dz & 0xffff;
-
-    if (s->buttons_state == 0) {
-        packet->state = 0;
-    } else {
-        packet->state = 1;
-    }
-
-    return EMUL_TOUCHSCREEN_PACKET_LEN;
-}
-
-static void usb_touchscreen_handle_reset(USBDevice *dev)
-{
-    USBTouchscreenState *s = (USBTouchscreenState *) dev;
-
-    pthread_mutex_lock(&event_mutex);
-
-    s->dx = 0;
-    s->dy = 0;
-    s->dz = 0;
-    s->buttons_state = 0;
-
-    event_cnt = 0;
-    _processed_buf_cnt = 0;
-
-    pthread_mutex_unlock(&event_mutex);
-}
-
-static void usb_touchscreen_handle_control(USBDevice *dev, USBPacket *p,
-    int request, int value, int index, int length, uint8_t *data)
-{
-    usb_desc_handle_control(dev, p, request, value, index, length, data);
-}
-
-/**
- * @brief : call by uhci frame timer
- * @param dev : state of device
- * @param p : usb packet
- */
-static void usb_touchscreen_handle_data(USBDevice *dev, USBPacket *p)
-{
-    USBTouchscreenState *s = (USBTouchscreenState *) dev;
-    uint8_t buf[p->iov.size];
-    int len = 0;
-
-    switch (p->pid) {
-    case USB_TOKEN_IN:
-        if (p->ep->nr == 1) {
-            pthread_mutex_lock(&event_mutex);
-
-            if (s->changed == 0) {
-                pthread_mutex_unlock(&event_mutex);
-                TRACE("USB_RET_NAK\n");
-            }
-
-            if (event_cnt != 0) {
-                if (!QTAILQ_EMPTY(&events_queue)) {
-                    TouchEventEntry *te = QTAILQ_FIRST(&events_queue);
-
-                    s->dx = te->queue_packet.x;
-                    s->dy = te->queue_packet.y;
-                    s->dz = te->queue_packet.z;
-                    s->buttons_state = te->queue_packet.state;
-
-                    QTAILQ_REMOVE(&events_queue, te, node);
-                    event_cnt--;
-                    TRACE("processed touch event (%d) : x=%d, y=%d, z=%d, state=%d\n",
-                        te->index, s->dx, s->dy, s->dz, s->buttons_state);
-
-                    if (QTAILQ_EMPTY(&events_queue)) {
-                        s->changed = 0;
-                        TRACE("processed all touch events (%d)\n", event_cnt);
-                    }
-                }
-            } else {
-                s->changed = 0;
-            }
-
-            pthread_mutex_unlock(&event_mutex);
-
-            memset(buf, 0, sizeof(buf));
-            len = usb_touchscreen_poll(s, buf, p->iov.size); //write event to packet
-            usb_packet_copy(p, buf, len);
-            break;
-        }
-        /* Fall through */
-    case USB_TOKEN_OUT:
-    default:
-        TRACE("USB_RET_STALL\n");
-        break;
-    }
-}
-
-static void usb_touchscreen_handle_destroy(USBDevice *dev)
-{
-    USBTouchscreenState *s = (USBTouchscreenState *) dev;
-
-    if (s->mouse_grabbed == 1) {
-        qemu_remove_mouse_event_handler(s->eh_entry);
-        s->mouse_grabbed = 0;
-    }
-}
-
-/**
- * @brief : initialize a touchscreen device
- * @param opaque : state of device
- */
-static int usb_touchscreen_initfn(USBDevice *dev)
-{
-    USBTouchscreenState *s = DO_UPCAST(USBTouchscreenState, dev, dev);
-    usb_desc_init(dev);
-
-    pthread_mutex_lock(&event_mutex);
-    s->changed = 1;
-    pthread_mutex_unlock(&event_mutex);
-
-    return 0;
-}
-
-/**
- * @brief : remove mouse handlers before loading
- * @param opaque : state of device
- */
-static int touchscreen_pre_load(void *opaque)
-{
-    USBTouchscreenState *s = (USBTouchscreenState *)opaque;
-
-    if (s->eh_entry) {
-        qemu_remove_mouse_event_handler(s->eh_entry);
-    }
-
-    return 0;
-}
-
-static int touchscreen_post_load(void *opaque, int version_id)
-{
-    USBTouchscreenState *s = (USBTouchscreenState *)opaque;
-
-    pthread_mutex_lock(&event_mutex);
-    s->changed = 1;
-    pthread_mutex_unlock(&event_mutex);
-
-    if (s->mouse_grabbed == 1) {
-        s->eh_entry = qemu_add_mouse_event_handler(usb_touchscreen_event, s, 1, "QEMU USB touchscreen");
-        qemu_activate_mouse_event_handler(s->eh_entry);
-    }
-
-    return 0;
-}
-
-static VMStateDescription vmsd_usbdevice = {
-    .name = "maru-touchscreen-usbdevice",
-    .version_id = 1,
-    .minimum_version_id = 1,
-    .minimum_version_id_old = 1,
-    .fields = (VMStateField []) {
-        VMSTATE_UINT8(addr, USBDevice),
-        VMSTATE_INT32(state, USBDevice),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static VMStateDescription vmsd = {
-    .name = "maru-touchscreen",
-    .version_id = 2,
-    .minimum_version_id = 1,
-    .minimum_version_id_old = 1,
-    .pre_load = touchscreen_pre_load,
-    .post_load = touchscreen_post_load,
-    .fields = (VMStateField []) {
-        VMSTATE_STRUCT(dev, USBTouchscreenState, 1, vmsd_usbdevice, USBDevice),
-        VMSTATE_INT32(dx, USBTouchscreenState),
-        VMSTATE_INT32(dy, USBTouchscreenState),
-        VMSTATE_INT32(dz, USBTouchscreenState),
-        VMSTATE_INT32(buttons_state, USBTouchscreenState),
-        VMSTATE_INT8(mouse_grabbed, USBTouchscreenState),
-        VMSTATE_INT8(changed, USBTouchscreenState),
-        VMSTATE_END_OF_LIST()
-    }
-};
-
-static void usb_touchscreen_class_initfn(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
-
-    uc->handle_reset   = usb_touchscreen_handle_reset;
-    uc->handle_control = usb_touchscreen_handle_control;
-    uc->handle_data    = usb_touchscreen_handle_data;
-    uc->handle_destroy = usb_touchscreen_handle_destroy;
-    uc->init           = usb_touchscreen_initfn;
-    uc->product_desc   = "Maru USB Touchscreen";
-    uc->usb_desc       = &desc_touchscreen;
-    dc->vmsd           = &vmsd;
-    dc->desc           = "Maru USB Touchscreen";
-}
-
-static TypeInfo touchscreen_info = {
-    .name          = "usb-maru-touchscreen",
-    .parent        = TYPE_USB_DEVICE,
-    .instance_size = sizeof(USBTouchscreenState),
-    .class_init    = usb_touchscreen_class_initfn,
-};
-
-/**
- * @brief : register a touchscreen device
- */
-static void usb_touchscreen_register_types(void)
-{
-    type_register_static(&touchscreen_info);
-    usb_legacy_register("usb-maru-touchscreen", "maru-touchscreen", NULL);
-}
-
-type_init(usb_touchscreen_register_types)
diff --git a/tizen/src/hw/maru_usb_touchscreen.h b/tizen/src/hw/maru_usb_touchscreen.h
deleted file mode 100644 (file)
index d285cfc..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Maru USB Touchscreen Device
- * Based on hw/usb-wacom.c:
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  GiWoong Kim <giwoong.kim@samsung.com>
- *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>
- *  HyunJun Son
- *
- * 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_TOUCH_H_
-#define MARU_TOUCH_H_
-
-#include <pthread.h>
-#include "hw/hw.h"
-#include "ui/console.h"
-#include "hw/usb.h"
-#include "hw/usb/desc.h"
-
-
-typedef struct USBTouchscreenState {
-    USBDevice dev;
-    QEMUPutMouseEntry *eh_entry;
-
-    int32_t dx, dy, dz, buttons_state;
-    int8_t mouse_grabbed;
-    int8_t changed;
-} USBTouchscreenState;
-
-/* This structure must match the kernel definitions */
-typedef struct USBEmulTouchscreenPacket {
-    uint16_t x, y, z;
-    uint8_t state;
-} USBEmulTouchscreenPacket;
-
-
-#define EMUL_TOUCHSCREEN_PACKET_LEN 7
-#define TOUCHSCREEN_RESOLUTION_X 5040
-#define TOUCHSCREEN_RESOLUTION_Y 3780
-
-enum {
-    STR_MANUFACTURER = 1,
-    STR_PRODUCT,
-    STR_SERIALNUMBER,
-};
-
-static const USBDescStrings desc_strings = {
-    [STR_MANUFACTURER]     = "QEMU " QEMU_VERSION,
-    [STR_PRODUCT]          = "Maru USB Touchscreen",
-    [STR_SERIALNUMBER]     = "1",
-};
-
-static const USBDescIface desc_iface_touchscreen = {
-    .bInterfaceNumber              = 0,
-    .bNumEndpoints                 = 1,
-    .bInterfaceClass               = USB_CLASS_HID,
-    .bInterfaceSubClass            = 0x01, /* boot */
-    .bInterfaceProtocol            = 0x02,
-    .ndesc                         = 1,
-    .descs = (USBDescOther[]) {
-        {
-            /* HID descriptor */
-            .data = (uint8_t[]) {
-                0x09,          /*  u8  bLength */
-                0x21,          /*  u8  bDescriptorType */
-                0x01, 0x10,    /*  u16 HID_class */
-                0x00,          /*  u8  country_code */
-                0x01,          /*  u8  num_descriptors */
-                0x22,          /*  u8  type: Report */
-                0x6e, 0,       /*  u16 len */
-            },
-        },
-    },
-    .eps = (USBDescEndpoint[]) {
-        {
-            .bEndpointAddress      = USB_DIR_IN | 0x01,
-            .bmAttributes          = USB_ENDPOINT_XFER_INT,
-            .wMaxPacketSize        = 8,
-            .bInterval             = 0x0a,
-        },
-    },
-};
-
-static const USBDescDevice desc_device_touchscreen = {
-    .bcdUSB                        = 0x0110,
-    .bMaxPacketSize0               = EMUL_TOUCHSCREEN_PACKET_LEN + 1,
-    .bNumConfigurations            = 1,
-    .confs = (USBDescConfig[]) {
-        {
-            .bNumInterfaces        = 1,
-            .bConfigurationValue   = 1,
-            .bmAttributes          = 0x80,
-            .bMaxPower             = 40,
-            .nif = 1,
-            .ifs = &desc_iface_touchscreen,
-        },
-    },
-};
-
-static const USBDesc desc_touchscreen = {
-    .id = {
-        .idVendor          = 0x056a,
-        .idProduct         = 0x0000,
-        .bcdDevice         = 0x0010,
-        .iManufacturer     = STR_MANUFACTURER,
-        .iProduct          = STR_PRODUCT,
-        .iSerialNumber     = STR_SERIALNUMBER,
-    },
-    .full = &desc_device_touchscreen,
-    .str = desc_strings,
-};
-
-typedef struct TouchEventEntry {
-    USBEmulTouchscreenPacket queue_packet;
-    int index;
-
-    /* used internally by qemu for handling mice */
-    QTAILQ_ENTRY(TouchEventEntry) node;
-} TouchEventEntry;
-
-#endif /* MARU_TOUCH_H_ */
diff --git a/tizen/src/hw/maru_virtio_esm.c b/tizen/src/hw/maru_virtio_esm.c
deleted file mode 100644 (file)
index e4568c1..0000000
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Virtio EmulatorStatusMedium Device
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  SeokYeon Hwang <syeon.hwang@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 "maru_device_ids.h"
-#include "maru_virtio_esm.h"
-#include "skin/maruskin_server.h"
-#include "emul_state.h"
-#include "debug_ch.h"
-
-MULTI_DEBUG_CHANNEL(qemu, virtio-esm);
-
-
-#define SYSTEM_MODE_LAYER 1
-#define USER_MODE_LAYER 0
-static uint8_t boot_complete;
-
-struct progress_info {
-    char mode;
-    uint16_t percentage;
-};
-
-static VirtQueueElement elem;
-struct progress_info progress;
-
-static void virtio_esm_handle(VirtIODevice *vdev, VirtQueue *vq)
-{
-    VirtIOESM *vesm = VIRTIO_ESM(vdev);
-    int index = 0;
-
-    TRACE("virtqueue handler.\n");
-    if (virtio_queue_empty(vesm->vq)) {
-        INFO("virtqueue is empty.\n");
-        return;
-    }
-
-    // Get a queue buffer.
-    index = virtqueue_pop(vq, &elem);
-    TRACE("virtqueue pop. index: %d\n", index);
-
-    TRACE("virtio element out number : %d\n", elem.out_num);
-    if (elem.out_num != 1) {
-        ERR("virtio element out number is wierd.\n");
-    }
-    else {
-        TRACE("caramis elem.out_sg[0].iov_len : %x\n", elem.out_sg[0].iov_len);
-        TRACE("caramis elem.out_sg[0].iov_base : %x\n", elem.out_sg[0].iov_base);
-        if (elem.out_sg[0].iov_len != 4) {
-            ERR("out lenth is wierd.\n");
-        }
-        else {
-            progress = *((struct progress_info*)elem.out_sg[0].iov_base);
-            TRACE("Boot up progress is [%u] percent done at %s.\n",
-                progress.percentage,
-                progress.mode == 's' || progress.mode == 'S' ? "system mode" : "user mode");
-
-            /* notify to skin */
-            if (progress.mode == 's' || progress.mode == 'S') {
-                if (progress.percentage >= 100) {
-                    boot_complete |= (1 << SYSTEM_MODE_LAYER);
-                }
-
-                notify_booting_progress(SYSTEM_MODE_LAYER, progress.percentage);
-            } else {
-                if (progress.percentage >= 100) {
-                    boot_complete |= (1 << USER_MODE_LAYER);
-                }
-
-                notify_booting_progress(USER_MODE_LAYER, progress.percentage);
-            }
-
-            /* booting complete check */
-            if ((boot_complete & (1 << SYSTEM_MODE_LAYER)) &&
-                (boot_complete & (1 << USER_MODE_LAYER))) {
-                set_emulator_condition(BOOT_COMPLETED);
-            }
-        }
-    }
-
-    // There is no data to copy into guest.
-    virtqueue_push(vesm->vq, &elem, 0);
-    virtio_notify(&vesm->vdev, vesm->vq);
-}
-
-static uint32_t virtio_esm_get_features(VirtIODevice *vdev, uint32_t feature)
-{
-    TRACE("virtio_esm_get_features.\n");
-    return feature;
-}
-
-static void virtio_esm_reset(VirtIODevice* vdev)
-{
-    TRACE("virtio_esm_reset.\n");
-
-    progress.mode = '\0';
-    progress.percentage = 0;
-}
-
-
-static void virtio_esm_device_realize(DeviceState *dev, Error **errp)
-{
-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-    VirtIOESM *vesm = VIRTIO_ESM(dev);
-
-    INFO("initialize virtio-esm device\n");
-    virtio_init(vdev, "virtio-esm", VIRTIO_ID_ESM, 0);
-
-    vesm->vq = virtio_add_queue(vdev, 1, virtio_esm_handle);
-
-    virtio_esm_reset(vdev);
-}
-
-static void virtio_esm_device_unrealize(DeviceState *dev, Error **errp)
-{
-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-
-    INFO("destroy device\n");
-    virtio_cleanup(vdev);
-}
-
-static void virtio_esm_class_init(ObjectClass *klass, void *data)
-{
-    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
-    vdc->realize = virtio_esm_device_realize;
-    vdc->unrealize = virtio_esm_device_unrealize;
-    vdc->get_features = virtio_esm_get_features;
-    // This device is no need to reset.
-    //vdc->reset = virtio_esm_reset;
-}
-
-static const TypeInfo virtio_device_info = {
-    .name = TYPE_VIRTIO_ESM,
-    .parent = TYPE_VIRTIO_DEVICE,
-    .instance_size = sizeof(VirtIOESM),
-    .class_init = virtio_esm_class_init,
-};
-
-static void virtio_register_types(void)
-{
-    type_register_static(&virtio_device_info);
-}
-
-type_init(virtio_register_types)
diff --git a/tizen/src/hw/maru_virtio_esm.h b/tizen/src/hw/maru_virtio_esm.h
deleted file mode 100644 (file)
index 934dfe9..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Virtio EmulatorStatusMedium Device
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  SeokYeon Hwang <syeon.hwang@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_VIRTIO_ESM_H_
-#define MARU_VIRTIO_ESM_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "hw/virtio/virtio.h"
-
-#define TYPE_VIRTIO_ESM "virtio-esm-device"
-#define VIRTIO_ESM(obj) \
-        OBJECT_CHECK(VirtIOESM, (obj), TYPE_VIRTIO_ESM)
-
-typedef struct VirtIOEmulatorStatusMedium {
-    VirtIODevice    vdev;
-    VirtQueue       *vq;
-    DeviceState     *qdev;
-} VirtIOESM;
-
-VirtIODevice *virtio_esm_init(DeviceState *dev);
-
-void virtio_esm_exit(VirtIODevice *vdev);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* MARU_VIRTIO_ESM_H_ */
diff --git a/tizen/src/hw/maru_virtio_evdi.c b/tizen/src/hw/maru_virtio_evdi.c
deleted file mode 100644 (file)
index b04c686..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Virtio EmulatorVirtualDeviceInterface Device
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  DaiYoung Kim <daiyoung777.kim.hwang@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 "maru_device_ids.h"
-#include "maru_virtio_evdi.h"
-#include "debug_ch.h"
-#include "ecs/ecs.h"
-
-MULTI_DEBUG_CHANNEL(qemu, virtio-evdi);
-
-#define EVDI_DEVICE_NAME "virtio-evdi"
-
-enum {
-    IOTYPE_INPUT = 0,
-    IOTYPE_OUTPUT = 1
-};
-
-
-#ifndef min
-#define min(a,b) ((a)<(b)?(a):(b))
-#endif
-
-
-VirtIOEVDI* vio_evdi;
-
-//
-
-typedef struct MsgInfo
-{
-    msg_info info;
-    QTAILQ_ENTRY(MsgInfo) next;
-}MsgInfo;
-
-static QTAILQ_HEAD(MsgInfoRecvHead , MsgInfo) evdi_recv_msg_queue =
-    QTAILQ_HEAD_INITIALIZER(evdi_recv_msg_queue);
-
-//
-
-typedef struct EvdiBuf {
-    VirtQueueElement elem;
-
-    QTAILQ_ENTRY(EvdiBuf) next;
-} EvdiBuf;
-
-static QTAILQ_HEAD(EvdiMsgHead , EvdiBuf) evdi_in_queue =
-    QTAILQ_HEAD_INITIALIZER(evdi_in_queue);
-
-
-static pthread_mutex_t recv_buf_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-bool send_to_evdi(const uint32_t route, char* data, const uint32_t len)
-{
-    int size;
-    int left = len;
-    int count = 0;
-    char* readptr = data;
-
-    if(vio_evdi == NULL) {
-        ERR("EVDI is not initialized\n");
-        return false;
-    }
-
-    if (unlikely(!virtio_queue_ready(vio_evdi->rvq))) {
-        ERR("virtio queue is not ready\n");
-        return false;
-    }
-
-    while (left > 0)
-    {
-        MsgInfo* _msg = (MsgInfo*) malloc(sizeof(MsgInfo));
-        if (!_msg)
-            return false;
-
-        memset(&_msg->info, 0, sizeof(msg_info));
-
-        size = min(left, __MAX_BUF_SIZE);
-        memcpy(_msg->info.buf, readptr, size);
-        readptr += size;
-        _msg->info.use = size;
-        _msg->info.index = count;
-
-        pthread_mutex_lock(&recv_buf_mutex);
-
-        QTAILQ_INSERT_TAIL(&evdi_recv_msg_queue, _msg, next);
-
-        pthread_mutex_unlock(&recv_buf_mutex);
-
-        left -= size;
-        count ++;
-    }
-
-    qemu_bh_schedule(vio_evdi->bh);
-
-    return true;
-}
-
-
-static void flush_evdi_recv_queue(void)
-{
-    int index;
-
-    if (unlikely(!virtio_queue_ready(vio_evdi->rvq))) {
-        INFO("virtio queue is not ready\n");
-        return;
-    }
-
-    if (unlikely(virtio_queue_empty(vio_evdi->rvq))) {
-        TRACE("virtqueue is empty\n");
-        return;
-    }
-
-
-    pthread_mutex_lock(&recv_buf_mutex);
-
-    while (!QTAILQ_EMPTY(&evdi_recv_msg_queue))
-    {
-         MsgInfo* msginfo = QTAILQ_FIRST(&evdi_recv_msg_queue);
-         if (!msginfo)
-             break;
-
-         VirtQueueElement elem;
-         index = virtqueue_pop(vio_evdi->rvq, &elem);
-         if (index == 0)
-         {
-             //ERR("unexpected empty queue");
-             break;
-         }
-
-         //INFO(">> virtqueue_pop. index: %d, out_num : %d, in_num : %d\n", index, elem.out_num, elem.in_num);
-
-         memset(elem.in_sg[0].iov_base, 0, elem.in_sg[0].iov_len);
-         memcpy(elem.in_sg[0].iov_base, &msginfo->info, sizeof(struct msg_info));
-
-         //INFO(">> send to guest count = %d, use = %d, msg = %s, iov_len = %d \n",
-                // ++g_cnt, msginfo->info.use, msginfo->info.buf, elem.in_sg[0].iov_len);
-
-         virtqueue_push(vio_evdi->rvq, &elem, sizeof(msg_info));
-         virtio_notify(&vio_evdi->vdev, vio_evdi->rvq);
-
-         QTAILQ_REMOVE(&evdi_recv_msg_queue, msginfo, next);
-         if (msginfo)
-             free(msginfo);
-    }
-
-    pthread_mutex_unlock(&recv_buf_mutex);
-
-}
-
-
-static void virtio_evdi_recv(VirtIODevice *vdev, VirtQueue *vq)
-{
-    flush_evdi_recv_queue();
-}
-
-static void virtio_evdi_send(VirtIODevice *vdev, VirtQueue *vq)
-{
-    VirtIOEVDI *vevdi = (VirtIOEVDI *)vdev;
-    int index = 0;
-    struct msg_info _msg;
-
-    if (virtio_queue_empty(vevdi->svq)) {
-        INFO("<< virtqueue is empty.\n");
-        return;
-    }
-
-    VirtQueueElement elem;
-
-    while ((index = virtqueue_pop(vq, &elem))) {
-
-        //INFO("<< virtqueue pop. index: %d, out_num : %d, in_num : %d\n", index,  elem.out_num, elem.in_num);
-
-        //INFO("<< use=%d, iov_len = %d\n", _msg.use, elem.out_sg[0].iov_len);
-
-        memset(&_msg, 0x00, sizeof(_msg));
-        memcpy(&_msg, elem.out_sg[0].iov_base, elem.out_sg[0].iov_len);
-
-        //INFO("<< recv from guest len = %d, msg = %s \n", _msg.use, _msg.buf);
-
-        send_injector_ntf(_msg.buf, _msg.use);
-    }
-
-    virtqueue_push(vq, &elem, sizeof(VirtIOEVDI));
-    virtio_notify(&vio_evdi->vdev, vq);
-}
-
-static uint32_t virtio_evdi_get_features(VirtIODevice *vdev,
-                                            uint32_t request_feature)
-{
-    TRACE("virtio_evdi_get_features.\n");
-    return 0;
-}
-
-static void maru_evdi_bh(void *opaque)
-{
-    flush_evdi_recv_queue();
-}
-
-static void virtio_evdi_realize(DeviceState *dev, Error **errp)
-{
-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-    vio_evdi = VIRTIO_EVDI(dev);
-    if (vio_evdi == NULL) {
-        ERR("failed to initialize evdi device\n");
-        return;
-    }
-
-    INFO("initialize evdi device\n");
-
-    virtio_init(vdev, TYPE_VIRTIO_EVDI, VIRTIO_ID_EVDI, 0); //EVDI_DEVICE_NAME
-
-    vio_evdi->rvq = virtio_add_queue(&vio_evdi->vdev, 256, virtio_evdi_recv);
-    vio_evdi->svq = virtio_add_queue(&vio_evdi->vdev, 256, virtio_evdi_send);
-
-    vio_evdi->bh = qemu_bh_new(maru_evdi_bh, vio_evdi);
-
-}
-
-static void virtio_evdi_unrealize(DeviceState *dev, Error **errp)
-{
-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-
-    INFO("destroy evdi device\n");
-
-    if (vio_evdi->bh) {
-            qemu_bh_delete(vio_evdi->bh);
-        }
-
-    virtio_cleanup(vdev);
-}
-
-static void virtio_evdi_reset(VirtIODevice *vdev)
-{
-    TRACE("virtio_evdi_reset.\n");
-}
-
-
-static void virtio_evdi_class_init(ObjectClass *klass, void *data)
-{
-    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
-    vdc->realize = virtio_evdi_realize;
-    vdc->unrealize = virtio_evdi_unrealize;
-    vdc->get_features = virtio_evdi_get_features;
-    vdc->reset = virtio_evdi_reset;
-}
-
-
-
-static const TypeInfo virtio_device_info = {
-    .name = TYPE_VIRTIO_EVDI,
-    .parent = TYPE_VIRTIO_DEVICE,
-    .instance_size = sizeof(VirtIOEVDI),
-    .class_init = virtio_evdi_class_init,
-};
-
-static void virtio_register_types(void)
-{
-    type_register_static(&virtio_device_info);
-}
-
-type_init(virtio_register_types)
diff --git a/tizen/src/hw/maru_virtio_evdi.h b/tizen/src/hw/maru_virtio_evdi.h
deleted file mode 100644 (file)
index a8c5fa0..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * maru_virtio_evdi.h
- *
- *  Created on: 2013. 3. 30.
- *      Author: dykim
- */
-
-#ifndef MARU_VIRTIO_EVDI_H_
-#define MARU_VIRTIO_EVDI_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "hw/virtio/virtio.h"
-
-/* device protocol */
-
-#define __MAX_BUF_SIZE 1024
-
-enum
-{
-       route_qemu = 0,
-       route_control_server = 1,
-       route_monitor = 2,
-       route_ij = 3
-};
-
-typedef unsigned int CSCliSN;
-
-typedef struct msg_info {
-       char buf[__MAX_BUF_SIZE];
-
-       uint32_t route;
-       uint32_t use;
-       uint16_t count;
-       uint16_t index;
-
-       CSCliSN cclisn;
-}msg_info;
-
-/* device protocol */
-
-typedef struct VirtIOEVDI{
-    VirtIODevice    vdev;
-    VirtQueue       *rvq;
-    VirtQueue          *svq;
-    DeviceState     *qdev;
-
-    QEMUBH *bh;
-} VirtIOEVDI;
-
-
-
-#define TYPE_VIRTIO_EVDI "virtio-evdi-device"
-#define VIRTIO_EVDI(obj) \
-        OBJECT_CHECK(VirtIOEVDI, (obj), TYPE_VIRTIO_EVDI)
-
-//VirtIODevice *virtio_evdi_init(DeviceState *dev);
-
-//void virtio_evdi_exit(VirtIODevice *vdev);
-bool send_to_evdi(const uint32_t route, char* data, const uint32_t len);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* MARU_VIRTIO_EVDI_H_ */
diff --git a/tizen/src/hw/maru_virtio_hwkey.c b/tizen/src/hw/maru_virtio_hwkey.c
deleted file mode 100644 (file)
index a76d77e..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * 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 "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);
-
-        printf("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 uint32_t virtio_hwkey_get_features(
-    VirtIODevice *vdev, uint32_t request_features)
-{
-    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_HWKEY(dev);
-
-    if (vdev == NULL) {
-        ERR("failed to initialize the hwkey device\n");
-        return;
-    }
-
-    virtio_init(vdev, TYPE_VIRTIO_HWKEY, VIRTIO_ID_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_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)
-
diff --git a/tizen/src/hw/maru_virtio_hwkey.h b/tizen/src/hw/maru_virtio_hwkey.h
deleted file mode 100644 (file)
index 9e48da8..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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_HWKEY "virtio-hwkey-device"
-#define VIRTIO_HWKEY(obj) \
-        OBJECT_CHECK(VirtIOHWKey, (obj), TYPE_VIRTIO_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_ */
diff --git a/tizen/src/hw/maru_virtio_jack.c b/tizen/src/hw/maru_virtio_jack.c
deleted file mode 100644 (file)
index a1a7173..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- * Virtio Jack Device
- *
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Jinhyung Choi <jinhyung2.choi@samsung.com>
- *  Daiyoung Kim <daiyoung777.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 "hw/pci/pci.h"
-
-#include "maru_device_ids.h"
-#include "debug_ch.h"
-
-#include "maru_virtio_jack.h"
-
-MULTI_DEBUG_CHANNEL(qemu, virtio-jack);
-
-#define JACK_DEVICE_NAME  "jack"
-#define _MAX_BUF          1024
-#define __MAX_BUF_JACK    32
-
-static int charger_online = 0;
-static int earjack_online = 0;
-static int earkey_online = 0;
-static int hdmi_online = 0;
-static int usb_online = 0;
-
-VirtIOJACK* vjack;
-static int jack_capability = 0;
-
-typedef struct msg_info {
-    char buf[_MAX_BUF];
-
-    uint16_t type;
-    uint16_t req;
-} msg_info;
-
-enum request_cmd {
-    request_get = 0,
-    request_set,
-    request_answer
-};
-
-void set_jack_charger(int online){
-    charger_online = online;
-}
-
-int get_jack_charger(void) {
-    return charger_online;
-}
-
-void set_jack_usb(int online){
-    usb_online = online;
-}
-
-int get_jack_usb(void) {
-    return usb_online;
-}
-
-static void set_jack_data (enum jack_types type, char* data, int len)
-{
-    if (len < 0 || len > __MAX_BUF_JACK) {
-        ERR("jack data size is wrong.\n");
-        return;
-    }
-
-    if (data == NULL) {
-        ERR("jack data is NULL.\n");
-        return;
-    }
-
-    switch (type) {
-        case jack_type_charger:
-            sscanf(data, "%d", &charger_online);
-            break;
-        case jack_type_earjack:
-            sscanf(data, "%d", &earjack_online);
-            break;
-        case jack_type_earkey:
-            sscanf(data, "%d", &earkey_online);
-            break;
-        case jack_type_hdmi:
-            sscanf(data, "%d", &hdmi_online);
-            break;
-        case jack_type_usb:
-            sscanf(data, "%d", &usb_online);
-            break;
-        default:
-            return;
-    }
-}
-
-static void get_jack_data(enum jack_types type, char* msg_info)
-{
-    if (msg_info == NULL) {
-        return;
-    }
-
-    switch (type) {
-        case jack_type_list:
-            sprintf(msg_info, "%d", jack_capability);
-            break;
-        case jack_type_charger:
-            sprintf(msg_info, "%d", charger_online);
-            break;
-        case jack_type_earjack:
-            sprintf(msg_info, "%d", earjack_online);
-            break;
-        case jack_type_earkey:
-            sprintf(msg_info, "%d", earkey_online);
-            break;
-        case jack_type_hdmi:
-            sprintf(msg_info, "%d", hdmi_online);
-            break;
-        case jack_type_usb:
-            sprintf(msg_info, "%d", usb_online);
-            break;
-        default:
-            return;
-    }
-}
-
-static void answer_jack_data_request(int type, char* data, VirtQueueElement *elem)
-{
-    msg_info* msginfo = (msg_info*) malloc(sizeof(msg_info));
-    if (!msginfo) {
-        ERR("msginfo is NULL!\n");
-        return;
-    }
-
-    msginfo->req = request_answer;
-    msginfo->type = type;
-    get_jack_data(type, msginfo->buf);
-
-    TRACE("sending message: %s, type: %d, req: %d\n", msginfo->buf, msginfo->type, msginfo->req);
-
-    memset(elem->in_sg[0].iov_base, 0, elem->in_sg[0].iov_len);
-    memcpy(elem->in_sg[0].iov_base, msginfo, sizeof(struct msg_info));
-
-    if (msginfo)
-        free(msginfo);
-}
-
-static void handle_msg(struct msg_info *msg, VirtQueueElement *elem)
-{
-    unsigned int len = 0;
-
-    if (msg == NULL) {
-        ERR("msg info structure is NULL.\n");
-        return;
-    }
-
-    if (msg->req == request_set) {
-        set_jack_data (msg->type, msg->buf, strlen(msg->buf));
-    } else if (msg->req == request_get) {
-        answer_jack_data_request(msg->type, msg->buf, elem);
-        len = sizeof(msg_info);
-    }
-
-    virtqueue_push(vjack->vq, elem, len);
-    virtio_notify(&vjack->vdev, vjack->vq);
-}
-
-static void virtio_jack_vq(VirtIODevice *vdev, VirtQueue *vq)
-{
-    VirtIOJACK *vjack = (VirtIOJACK*)vdev;
-    struct msg_info msg;
-    VirtQueueElement elem;
-    int index = 0;
-
-    if (vjack->vq == NULL) {
-        ERR("virt queue is not ready.\n");
-        return;
-    }
-
-    if (!virtio_queue_ready(vjack->vq)) {
-        ERR("virtqueue is not ready.");
-        return;
-    }
-
-    if (virtio_queue_empty(vjack->vq)) {
-        ERR("<< virtqueue is empty.\n");
-        return;
-    }
-
-    while ((index = virtqueue_pop(vq, &elem))) {
-        memset(&msg, 0x00, sizeof(msg));
-        memcpy(&msg, elem.out_sg[0].iov_base, elem.out_sg[0].iov_len);
-
-        TRACE("handling msg from driver: %s, len: %d, type: %d, req: %d, index: %d\n", msg.buf, strlen(msg.buf), msg.type, msg.req, index);
-
-        handle_msg(&msg, &elem);
-    }
-}
-
-static int set_capability(char* jack)
-{
-    if (!strncmp(jack, JACK_NAME_CHARGER, 7)) {
-        return jack_cap_charger;
-    } else if (!strncmp(jack, JACK_NAME_EARJACK, 7)) {
-        return jack_cap_earjack;
-    } else if (!strncmp(jack, JACK_NAME_EARKEY, 6)) {
-        return jack_cap_earkey;
-    } else if (!strncmp(jack, JACK_NAME_HDMI, 4)) {
-        return jack_cap_hdmi;
-    } else if (!strncmp(jack, JACK_NAME_USB, 3)) {
-        return jack_cap_usb;
-    }
-
-    return 0;
-}
-
-static void parse_jack_capability(char* lists)
-{
-    char token[] = JACK_CAP_TOKEN;
-    char* data = NULL;
-
-    if (lists == NULL)
-        return;
-
-    data = strtok(lists, token);
-    if (data != NULL) {
-        jack_capability |= set_capability(data);
-        while ((data = strtok(NULL, token)) != NULL) {
-            jack_capability |= set_capability(data);
-        }
-    }
-
-    INFO("jack device capabilty enabled with %02x\n", jack_capability);
-}
-
-static void virtio_jack_realize(DeviceState *dev, Error **errp)
-{
-    INFO("initialize virtio-jack device\n");
-
-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-    vjack = VIRTIO_JACK(vdev);
-
-    virtio_init(vdev, JACK_DEVICE_NAME, VIRTIO_ID_JACK, 0);
-
-    if (vjack == NULL) {
-        ERR("failed to initialize jack device\n");
-        return;
-    }
-
-    vjack->vq = virtio_add_queue(&vjack->vdev, 64, virtio_jack_vq);
-
-    INFO("initialized jack type: %s\n", vjack->jacks);
-
-    if (vjack->jacks) {
-        parse_jack_capability(vjack->jacks);
-    }
-}
-
-static void virtio_jack_unrealize(DeviceState *dev, Error **errp)
-{
-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-    INFO("destroy jack device\n");
-
-    virtio_cleanup(vdev);
-}
-
-
-static void virtio_jack_reset(VirtIODevice *vdev)
-{
-    TRACE("virtio_jack_reset.\n");
-}
-
-static uint32_t virtio_jack_get_features(VirtIODevice *vdev,
-                                            uint32_t request_feature)
-{
-    TRACE("virtio_jack_get_features.\n");
-    return 0;
-}
-
-static Property virtio_jack_properties[] = {
-    DEFINE_PROP_STRING(ATTRIBUTE_NAME_JACKS, VirtIOJACK, jacks),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_jack_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
-    dc->props = virtio_jack_properties;
-    vdc->realize = virtio_jack_realize;
-    vdc->unrealize = virtio_jack_unrealize;
-    vdc->get_features = virtio_jack_get_features;
-    vdc->reset = virtio_jack_reset;
-}
-
-static const TypeInfo virtio_device_info = {
-    .name = TYPE_VIRTIO_JACK,
-    .parent = TYPE_VIRTIO_DEVICE,
-    .instance_size = sizeof(VirtIOJACK),
-    .class_init = virtio_jack_class_init,
-};
-
-static void virtio_register_types(void)
-{
-    type_register_static(&virtio_device_info);
-}
-
-type_init(virtio_register_types)
-
diff --git a/tizen/src/hw/maru_virtio_jack.h b/tizen/src/hw/maru_virtio_jack.h
deleted file mode 100644 (file)
index 615db82..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Virtio Jack Device
- *
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Jinhyung choi   <jinhyung2.choi@samsung.com>
- *  Daiyoung Kim    <daiyoung777.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_VIRTIO_JACK_H_
-#define MARU_VIRTIO_JACK_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "hw/virtio/virtio.h"
-
-#define TYPE_VIRTIO_JACK "virtio-jack-device"
-#define VIRTIO_JACK(obj) \
-        OBJECT_CHECK(VirtIOJACK, (obj), TYPE_VIRTIO_JACK)
-
-enum jack_types {
-    jack_type_list = 0,
-    jack_type_charger,
-    jack_type_earjack,
-    jack_type_earkey,
-    jack_type_hdmi,
-    jack_type_usb,
-    jack_type_max
-};
-
-enum jack_capabilities {
-    jack_cap_charger = 0x01,
-    jack_cap_earjack = 0x02,
-    jack_cap_earkey  = 0x04,
-    jack_cap_hdmi    = 0x08,
-    jack_cap_usb     = 0x10
-};
-
-typedef struct VirtIOJACK {
-    VirtIODevice    vdev;
-    VirtQueue       *vq;
-    DeviceState     *qdev;
-
-    char            *jacks;
-} VirtIOJACK;
-
-#define ATTRIBUTE_NAME_JACKS "jacks"
-
-#define JACK_NAME_CHARGER "charger"
-#define JACK_NAME_EARJACK "earjack"
-#define JACK_NAME_EARKEY "earkey"
-#define JACK_NAME_HDMI "hdmi"
-#define JACK_NAME_USB "usb"
-
-#define JACK_CAP_TOKEN "&"
-
-void set_jack_charger(int online);
-int get_jack_charger(void);
-
-void set_jack_usb(int online);
-int get_jack_usb(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/tizen/src/hw/maru_virtio_keyboard.c b/tizen/src/hw/maru_virtio_keyboard.c
deleted file mode 100644 (file)
index 341b6f9..0000000
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Virtio Keyboard Device
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Kitae Kim <kt920.kim@samsung.com>
- *  GiWoong Kim <giwoong.kim@samsung.com>
- *  SeokYeon Hwang <syeon.hwang@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 "maru_device_ids.h"
-#include "maru_virtio_keyboard.h"
-#include "debug_ch.h"
-
-
-MULTI_DEBUG_CHANNEL(qemu, virtio-kbd);
-
-VirtIOKeyboard *vkbd;
-VirtQueueElement elem;
-
-static void virtio_keyboard_handle(VirtIODevice *vdev, VirtQueue *vq)
-{
-    VirtIOKeyboard *vkbd = (VirtIOKeyboard *)vdev;
-    int index = 0;
-
-    if (virtio_queue_empty(vkbd->vq)) {
-        INFO("virtqueue is empty.\n");
-        return;
-    }
-
-    /* Get a queue buffer which is written by guest side. */
-    do {
-        index = virtqueue_pop(vq, &elem);
-        TRACE("virtqueue pop.\n");
-    } while (index < VIRTIO_KBD_QUEUE_SIZE);
-}
-
-void virtio_keyboard_notify(void *opaque)
-{
-    VirtIOKeyboard *vkbd = (VirtIOKeyboard *)opaque;
-    EmulKbdEvent *kbdevt;
-    int written_cnt = 0;
-
-    if (!vkbd) {
-        ERR("VirtIOKeyboard is NULL.\n");
-        return;
-    }
-
-    TRACE("[Enter] virtqueue notifier.\n");
-
-    if (!virtio_queue_ready(vkbd->vq)) {
-        INFO("virtqueue is not ready.\n");
-        return;
-    }
-
-    if (vkbd->kbdqueue.rptr == VIRTIO_KBD_QUEUE_SIZE) {
-        vkbd->kbdqueue.rptr = 0;
-    }
-
-    qemu_mutex_lock(&vkbd->event_mutex);
-    written_cnt = vkbd->kbdqueue.wptr;
-
-    while ((written_cnt--)) {
-        kbdevt = &vkbd->kbdqueue.kbdevent[vkbd->kbdqueue.rptr];
-
-        if (((EmulKbdEvent*)(elem.in_sg[vkbd->kbdqueue.rptr].iov_base))->code != 0) {
-            TRACE("FIXME: virtio queue is full.\n");
-        }
-
-        /* Copy keyboard data into guest side. */
-        TRACE("copy: keycode %d, type %d, elem_index %d\n",
-            kbdevt->code, kbdevt->type, vkbd->kbdqueue.rptr);
-        memcpy(elem.in_sg[vkbd->kbdqueue.rptr].iov_base, kbdevt, sizeof(EmulKbdEvent));
-        memset(kbdevt, 0x00, sizeof(EmulKbdEvent));
-
-        if (vkbd->kbdqueue.wptr > 0) {
-            vkbd->kbdqueue.wptr--;
-            TRACE("written_cnt: %d, wptr: %d, qemu_index: %d\n",
-                written_cnt, vkbd->kbdqueue.wptr, vkbd->kbdqueue.rptr);
-        }
-
-        vkbd->kbdqueue.rptr++;
-        if (vkbd->kbdqueue.rptr == VIRTIO_KBD_QUEUE_SIZE) {
-            vkbd->kbdqueue.rptr = 0;
-        }
-    }
-    qemu_mutex_unlock(&vkbd->event_mutex);
-
-    virtqueue_push(vkbd->vq, &elem, sizeof(EmulKbdEvent));
-    virtio_notify(&vkbd->vdev, vkbd->vq);
-
-    TRACE("[Leave] virtqueue notifier.\n");
-}
-
-void virtio_keyboard_event(int keycode)
-{
-    EmulKbdEvent kbdevt = {0};
-    int *index = NULL;
-
-    if (!vkbd) {
-        ERR("VirtIOKeyboard is NULL.\n");
-        return;
-    }
-
-    if (!virtio_queue_ready(vkbd->vq)) {
-        INFO("virtqueue is not ready.\n");
-        return;
-    }
-
-    index = &(vkbd->kbdqueue.index);
-    TRACE("[Enter] input_event handler. cnt %d\n", vkbd->kbdqueue.wptr);
-
-    if (*index < 0) {
-        ERR("keyboard queue is overflow.\n");
-        return;
-    }
-
-    if (*index == VIRTIO_KBD_QUEUE_SIZE) {
-        *index = 0;
-    }
-
-    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);
-    memcpy(&vkbd->kbdqueue.kbdevent[(*index)++], &kbdevt, sizeof(kbdevt));
-    TRACE("event: keycode %d, type %d, index %d.\n",
-        kbdevt.code, kbdevt.type, ((*index) - 1));
-
-    vkbd->kbdqueue.wptr++;
-    qemu_mutex_unlock(&vkbd->event_mutex);
-
-    TRACE("[Leave] input_event handler. cnt:%d\n", vkbd->kbdqueue.wptr);
-
-    qemu_bh_schedule(vkbd->bh);
-}
-
-static uint32_t virtio_keyboard_get_features(VirtIODevice *vdev,
-                                            uint32_t request_feature)
-{
-    TRACE("virtio_keyboard_get_features.\n");
-    return 0;
-}
-
-static void virtio_keyboard_bh(void *opaque)
-{
-    virtio_keyboard_notify(opaque);
-}
-
-static void virtio_keyboard_device_realize(DeviceState *dev, Error **errp)
-{
-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-    vkbd = VIRTIO_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_KEYBOARD, VIRTIO_ID_KEYBOARD, 0);
-
-    memset(&vkbd->kbdqueue, 0x00, sizeof(vkbd->kbdqueue));
-    vkbd->extension_key = 0;
-    qemu_mutex_init(&vkbd->event_mutex);
-
-    vkbd->vq = virtio_add_queue(vdev, 128, virtio_keyboard_handle);
-    vkbd->qdev = dev;
-
-    /* bottom half */
-    vkbd->bh = qemu_bh_new(virtio_keyboard_bh, vkbd);
-}
-
-static void virtio_keyboard_device_unrealize(DeviceState *dev, Error **errp)
-{
-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-    VirtIOKeyboard *vkbd = (VirtIOKeyboard *)vdev;
-
-    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)
-{
-    vkbd = VIRTIO_KEYBOARD(vdev);
-
-    INFO("reset keyboard device\n");
-    vkbd->kbdqueue.rptr = 0;
-    vkbd->kbdqueue.index = 0;
-}
-
-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_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)
-
diff --git a/tizen/src/hw/maru_virtio_keyboard.h b/tizen/src/hw/maru_virtio_keyboard.h
deleted file mode 100644 (file)
index f3296bc..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Virtio Keyboard Device
- *
- * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Kitae Kim <kt920.kim@samsung.com>
- *  GiWoong Kim <giwoong.kim@samsung.com>
- *  SeokYeon Hwang <syeon.hwang@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 VIRTIO_KEYBOARD_H_
-#define VIRTIO_KEYBOARD_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "qemu/thread.h"
-#include "hw/virtio/virtio.h"
-
-#define TYPE_VIRTIO_KEYBOARD "virtio-keyboard-device"
-#define VIRTIO_KEYBOARD(obj) \
-        OBJECT_CHECK(VirtIOKeyboard, (obj), TYPE_VIRTIO_KEYBOARD)
-#define VIRTIO_KBD_QUEUE_SIZE  100
-
-typedef struct EmulKbdEvent {
-    uint16_t code;
-    uint16_t type;
-} EmulKbdEvent;
-
-typedef struct VirtIOKbdQueue {
-    EmulKbdEvent kbdevent[VIRTIO_KBD_QUEUE_SIZE];
-    int index;
-    int rptr, wptr;
-} VirtIOKbdQueue;
-
-typedef struct VirtIOKeyboard {
-    VirtIODevice    vdev;
-    VirtQueue       *vq;
-    DeviceState     *qdev;
-    uint16_t        extension_key;
-
-    VirtIOKbdQueue  kbdqueue;
-    QemuMutex       event_mutex;
-    QEMUBH          *bh;
-} VirtIOKeyboard;
-
-VirtIODevice *virtio_keyboard_init(DeviceState *dev);
-void virtio_keyboard_exit(VirtIODevice *vdev);
-
-void virtio_keyboard_event(int keycode);
-void virtio_keyboard_notify(void *opaque);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* VIRTIO_KEYBOARD_H_ */
diff --git a/tizen/src/hw/maru_virtio_nfc.c b/tizen/src/hw/maru_virtio_nfc.c
deleted file mode 100644 (file)
index 2afafef..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Virtio NFC Device
- *
- * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Munkyu Im <munkyu.im@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 "maru_device_ids.h"
-#include "maru_virtio_nfc.h"
-#include "debug_ch.h"
-#include "ecs/ecs.h"
-
-MULTI_DEBUG_CHANNEL(qemu, virtio-nfc);
-
-#define NFC_DEVICE_NAME "virtio-nfc"
-
-enum {
-    IOTYPE_INPUT = 0,
-    IOTYPE_OUTPUT = 1
-};
-
-
-#ifndef min
-#define min(a,b) ((a)<(b)?(a):(b))
-#endif
-
-VirtIONFC* vio_nfc;
-
-typedef struct MsgInfo
-{
-    nfc_msg_info info;
-    QTAILQ_ENTRY(MsgInfo) next;
-}MsgInfo;
-
-static QTAILQ_HEAD(MsgInfoRecvHead , MsgInfo) nfc_recv_msg_queue =
-QTAILQ_HEAD_INITIALIZER(nfc_recv_msg_queue);
-
-typedef struct NFCBuf {
-    VirtQueueElement elem;
-    QTAILQ_ENTRY(NFCBuf) next;
-} NFCBuf;
-
-static pthread_mutex_t recv_buf_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-bool send_to_nfc(unsigned char id, unsigned char type, const char* data, const uint32_t len)
-{
-    if(vio_nfc == NULL) {
-        ERR("NFC is not initialized\n");
-        return false;
-    }
-
-    if (unlikely(!virtio_queue_ready(vio_nfc->rvq))) {
-        ERR("virtio queue is not ready\n");
-        return false;
-    }
-
-    MsgInfo* _msg = (MsgInfo*) malloc(sizeof(MsgInfo));
-    if (!_msg) {
-        return false;
-    }
-
-    if(len > NFC_MAX_BUF_SIZE) {
-        ERR("the length of data is longer than max buffer size");
-        free(_msg);
-        return false;
-    }
-
-    memset(&_msg->info, 0, sizeof(nfc_msg_info));
-
-    memcpy(_msg->info.buf, data, len);
-    _msg->info.use = len;
-    _msg->info.client_id = id;
-    _msg->info.client_type = type;
-
-    pthread_mutex_lock(&recv_buf_mutex);
-
-    QTAILQ_INSERT_TAIL(&nfc_recv_msg_queue, _msg, next);
-
-    pthread_mutex_unlock(&recv_buf_mutex);
-
-    qemu_bh_schedule(vio_nfc->bh);
-
-    return true;
-}
-
-static void flush_nfc_recv_queue(void)
-{
-    int index;
-
-    if (unlikely(!virtio_queue_ready(vio_nfc->rvq))) {
-        INFO("virtio queue is not ready\n");
-        return;
-    }
-
-    if (unlikely(virtio_queue_empty(vio_nfc->rvq))) {
-        TRACE("virtqueue is empty\n");
-        return;
-    }
-
-
-    pthread_mutex_lock(&recv_buf_mutex);
-
-    while (!QTAILQ_EMPTY(&nfc_recv_msg_queue))
-    {
-        MsgInfo* msginfo = QTAILQ_FIRST(&nfc_recv_msg_queue);
-        if (!msginfo) {
-            break;
-        }
-
-        VirtQueueElement elem;
-        index = virtqueue_pop(vio_nfc->rvq, &elem);
-        if (index == 0)
-        {
-            //ERR("unexpected empty queue");
-            break;
-        }
-
-        INFO(">> virtqueue_pop. index: %d, out_num : %d, in_num : %d\n", index, elem.out_num, elem.in_num);
-
-        memcpy(elem.in_sg[0].iov_base, &msginfo->info, sizeof(struct nfc_msg_info));
-
-        INFO(">> send to guest use = %d, msg = %s, iov_len = %d \n",
-                msginfo->info.use, msginfo->info.buf, elem.in_sg[0].iov_len);
-
-        virtqueue_push(vio_nfc->rvq, &elem, sizeof(nfc_msg_info));
-        virtio_notify(&vio_nfc->vdev, vio_nfc->rvq);
-
-        QTAILQ_REMOVE(&nfc_recv_msg_queue, msginfo, next);
-        if (msginfo)
-            free(msginfo);
-    }
-
-    pthread_mutex_unlock(&recv_buf_mutex);
-
-}
-
-
-static void virtio_nfc_recv(VirtIODevice *vdev, VirtQueue *vq)
-{
-    flush_nfc_recv_queue();
-}
-
-static void virtio_nfc_send(VirtIODevice *vdev, VirtQueue *vq)
-{
-    VirtIONFC *vnfc = (VirtIONFC *)vdev;
-    int index = 0;
-    struct nfc_msg_info _msg;
-
-    if (virtio_queue_empty(vnfc->svq)) {
-        INFO("<< virtqueue is empty.\n");
-        return;
-    }
-
-    VirtQueueElement elem;
-
-    while ((index = virtqueue_pop(vq, &elem))) {
-
-        INFO("<< virtqueue pop. index: %d, out_num : %d, in_num : %d\n", index,  elem.out_num, elem.in_num);
-
-        INFO("<< iov_len = %d\n", elem.out_sg[0].iov_len);
-
-        memset(&_msg, 0x00, sizeof(_msg));
-        memcpy(&_msg, elem.out_sg[0].iov_base, elem.out_sg[0].iov_len);
-
-        INFO("<< recv from guest len = %d, msg = %s \n", _msg.use, _msg.buf);
-        send_nfc_ntf(&_msg);
-
-    }
-
-    virtqueue_push(vq, &elem, sizeof(VirtIONFC));
-    virtio_notify(&vio_nfc->vdev, vq);
-}
-
-static uint32_t virtio_nfc_get_features(VirtIODevice *vdev,
-        uint32_t request_feature)
-{
-    TRACE("virtio_nfc_get_features.\n");
-    return 0;
-}
-
-static void maru_nfc_bh(void *opaque)
-{
-    flush_nfc_recv_queue();
-}
-
-static void virtio_nfc_realize(DeviceState* dev, Error **errp)
-{
-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-    vio_nfc = VIRTIO_NFC(vdev);
-    if (vio_nfc == NULL) {
-        ERR("failed to initialize nfc device\n");
-        return;
-    }
-
-    INFO("initialize nfc device\n");
-
-    virtio_init(vdev, NFC_DEVICE_NAME, VIRTIO_ID_NFC, 0);
-
-    vio_nfc->rvq = virtio_add_queue(&vio_nfc->vdev, 256, virtio_nfc_recv);
-    vio_nfc->svq = virtio_add_queue(&vio_nfc->vdev, 256, virtio_nfc_send);
-
-    vio_nfc->bh = qemu_bh_new(maru_nfc_bh, vio_nfc);
-}
-
-static void virtio_nfc_unrealize(DeviceState* dev, Error **errp)
-{
-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-
-    INFO("destroy nfc device\n");
-
-    if (vio_nfc->bh) {
-        qemu_bh_delete(vio_nfc->bh);
-    }
-
-    virtio_cleanup(vdev);
-}
-
-static void virtio_nfc_reset(VirtIODevice *vdev)
-{
-    TRACE("virtio_sensor_reset.\n");
-}
-
-
-static void virtio_nfc_class_init(ObjectClass *klass, void *data)
-{
-    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
-    vdc->realize = virtio_nfc_realize;
-    vdc->unrealize = virtio_nfc_unrealize;
-    vdc->get_features = virtio_nfc_get_features;
-    vdc->reset = virtio_nfc_reset;
-}
-
-static const TypeInfo virtio_device_info = {
-    .name = TYPE_VIRTIO_NFC,
-    .parent = TYPE_VIRTIO_DEVICE,
-    .instance_size = sizeof(VirtIONFC),
-    .class_init = virtio_nfc_class_init,
-};
-
-static void virtio_register_types(void)
-{
-    type_register_static(&virtio_device_info);
-}
-
-type_init(virtio_register_types)
-
diff --git a/tizen/src/hw/maru_virtio_nfc.h b/tizen/src/hw/maru_virtio_nfc.h
deleted file mode 100644 (file)
index 17c539a..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-/*\r
- * Virtio NFC Device\r
- *\r
- * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Contact:\r
- *  Munkyu Im <munkyu.im@samsung.com>\r
- *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
- *\r
- * Contributors:\r
- * - S-Core Co., Ltd\r
- *\r
- */\r
-\r
-#ifndef MARU_VIRTIO_NFC_H_\r
-#define MARU_VIRTIO_NFC_H_\r
-\r
-#ifdef __cplusplus\r
-extern "C" {\r
-#endif\r
-\r
-#include "hw/virtio/virtio.h"\r
-\r
-enum request_cmd_nfc {\r
-       request_nfc_get = 0,\r
-       request_nfc_set,\r
-       request_nfc_answer\r
-};\r
-\r
-\r
-/* device protocol */\r
-\r
-#define __MAX_BUF_SIZE 1024\r
-\r
-\r
-typedef struct VirtIONFC{\r
-    VirtIODevice    vdev;\r
-    VirtQueue       *rvq;\r
-    VirtQueue          *svq;\r
-    DeviceState     *qdev;\r
-\r
-    QEMUBH *bh;\r
-} VirtIONFC;\r
-\r
-\r
-#define TYPE_VIRTIO_NFC "virtio-nfc-device"\r
-#define VIRTIO_NFC(obj) \\r
-        OBJECT_CHECK(VirtIONFC, (obj), TYPE_VIRTIO_NFC)\r
-\r
-\r
-bool send_to_nfc(unsigned char id, unsigned char type, const char* data, const uint32_t len);\r
-\r
-#ifdef __cplusplus\r
-}\r
-#endif\r
-\r
-\r
-#endif /* MARU_VIRTIO_NFC_H_ */\r
diff --git a/tizen/src/hw/maru_virtio_pci.c b/tizen/src/hw/maru_virtio_pci.c
deleted file mode 100644 (file)
index 1bc4efb..0000000
+++ /dev/null
@@ -1,625 +0,0 @@
-/*
- * Maru virtio pci
- *
- * Copyright (C) 2014 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
- *
- * refer to hw/virtio/virtio-pci.c
- */
-
-#include "hw/virtio/virtio-pci.h"
-
-#include "tizen/src/hw/maru_device_ids.h"
-#include "tizen/src/hw/maru_virtio_evdi.h"
-#include "tizen/src/hw/maru_virtio_esm.h"
-#include "tizen/src/hw/maru_virtio_hwkey.h"
-#include "tizen/src/hw/maru_virtio_keyboard.h"
-#include "tizen/src/hw/maru_virtio_touchscreen.h"
-#include "tizen/src/hw/maru_virtio_sensor.h"
-#include "tizen/src/hw/maru_virtio_jack.h"
-#include "tizen/src/hw/maru_virtio_power.h"
-#include "tizen/src/hw/maru_virtio_nfc.h"
-#include "tizen/src/hw/maru_virtio_vmodem.h"
-
-typedef struct VirtIOTouchscreenPCI VirtIOTouchscreenPCI;
-typedef struct VirtIOEVDIPCI VirtIOEVDIPCI;
-typedef struct VirtIOESMPCI VirtIOESMPCI;
-typedef struct VirtIOHWKeyPCI VirtIOHWKeyPCI;
-typedef struct VirtIOKeyboardPCI VirtIOKeyboardPCI;
-typedef struct VirtIOSENSORPCI VirtIOSENSORPCI;
-typedef struct VirtIONFCPCI VirtIONFCPCI;
-typedef struct VirtIOPOWERPCI VirtIOPOWERPCI;
-typedef struct VirtIOJACKPCI VirtIOJACKPCI;
-typedef struct VirtIOVModemPCI VirtIOVModemPCI;
-
-/*
- * virtio-touchscreen-pci: This extends VirtioPCIProxy.
- */
-#define TYPE_VIRTIO_TOUCHSCREEN_PCI "virtio-touchscreen-pci"
-#define VIRTIO_TOUCHSCREEN_PCI(obj) \
-        OBJECT_CHECK(VirtIOTouchscreenPCI, (obj), TYPE_VIRTIO_TOUCHSCREEN_PCI)
-
-struct VirtIOTouchscreenPCI {
-    VirtIOPCIProxy parent_obj;
-    VirtIOTouchscreen vdev;
-};
-
-/*
- * virtio-keyboard-pci: This extends VirtioPCIProxy.
- */
-#define TYPE_VIRTIO_KEYBOARD_PCI "virtio-keyboard-pci"
-#define VIRTIO_KEYBOARD_PCI(obj) \
-        OBJECT_CHECK(VirtIOKeyboardPCI, (obj), TYPE_VIRTIO_KEYBOARD_PCI)
-
-struct VirtIOKeyboardPCI {
-    VirtIOPCIProxy parent_obj;
-    VirtIOKeyboard vdev;
-};
-
-/*
- * virtio-evdi-pci: This extends VirtioPCIProxy.
- */
-#define TYPE_VIRTIO_EVDI_PCI "virtio-evdi-pci"
-#define VIRTIO_EVDI_PCI(obj) \
-        OBJECT_CHECK(VirtIOEVDIPCI, (obj), TYPE_VIRTIO_EVDI_PCI)
-
-struct VirtIOEVDIPCI {
-    VirtIOPCIProxy parent_obj;
-    VirtIOEVDI vdev;
-};
-
-/*
- * virtio-esm-pci: This extends VirtioPCIProxy.
- */
-#define TYPE_VIRTIO_ESM_PCI "virtio-esm-pci"
-#define VIRTIO_ESM_PCI(obj) \
-        OBJECT_CHECK(VirtIOESMPCI, (obj), TYPE_VIRTIO_ESM_PCI)
-struct VirtIOESMPCI {
-    VirtIOPCIProxy parent_obj;
-    VirtIOESM vdev;
-};
-
-/*
- * virtio-hwkey-pci: This extends VirtioPCIProxy.
- */
-#define TYPE_VIRTIO_HWKEY_PCI "virtio-hwkey-pci"
-#define VIRTIO_HWKEY_PCI(obj) \
-        OBJECT_CHECK(VirtIOHWKeyPCI, (obj), TYPE_VIRTIO_HWKEY_PCI)
-struct VirtIOHWKeyPCI {
-    VirtIOPCIProxy parent_obj;
-    VirtIOHWKey vdev;
-};
-
-/*
- * virtio-sensor-pci: This extends VirtioPCIProxy.
- */
-#define TYPE_VIRTIO_SENSOR_PCI "virtio-sensor-pci"
-#define VIRTIO_SENSOR_PCI(obj) \
-        OBJECT_CHECK(VirtIOSENSORPCI, (obj), TYPE_VIRTIO_SENSOR_PCI)
-
-struct VirtIOSENSORPCI {
-    VirtIOPCIProxy parent_obj;
-    VirtIOSENSOR vdev;
-};
-
-/*
- * virtio-nfc-pci: This extends VirtioPCIProxy.
- */
-#define TYPE_VIRTIO_NFC_PCI "virtio-nfc-pci"
-#define VIRTIO_NFC_PCI(obj) \
-        OBJECT_CHECK(VirtIONFCPCI, (obj), TYPE_VIRTIO_NFC_PCI)
-
-struct VirtIONFCPCI {
-    VirtIOPCIProxy parent_obj;
-    VirtIONFC vdev;
-};
-
-/*
- * virtio-jack-pci: This extends VirtioPCIProxy.
- */
-#define TYPE_VIRTIO_JACK_PCI "virtio-jack-pci"
-#define VIRTIO_JACK_PCI(obj) \
-        OBJECT_CHECK(VirtIOJACKPCI, (obj), TYPE_VIRTIO_JACK_PCI)
-
-struct VirtIOJACKPCI {
-    VirtIOPCIProxy parent_obj;
-    VirtIOJACK vdev;
-};
-
-/*
- * virtio-power-pci: This extends VirtioPCIProxy.
- */
-#define TYPE_VIRTIO_POWER_PCI "virtio-power-pci"
-#define VIRTIO_POWER_PCI(obj) \
-        OBJECT_CHECK(VirtIOPOWERPCI, (obj), TYPE_VIRTIO_POWER_PCI)
-
-struct VirtIOPOWERPCI {
-    VirtIOPCIProxy parent_obj;
-    VirtIOPOWER vdev;
-};
-
-/*
- * virtio-vmodem-pci: This extends VirtioPCIProxy.
- */
-#define TYPE_VIRTIO_VMODEM_PCI "virtio-vmodem-pci"
-#define VIRTIO_VMODEM_PCI(obj) \
-        OBJECT_CHECK(VirtIOVModemPCI, (obj), TYPE_VIRTIO_VMODEM_PCI)
-struct VirtIOVModemPCI {
-    VirtIOPCIProxy parent_obj;
-    VirtIOVModem vdev;
-};
-
-
-/* virtio-touchscreen-pci */
-
-static Property virtio_touchscreen_pci_properties[] = {
-    DEFINE_PROP_UINT32(TOUCHSCREEN_OPTION_NAME,
-        VirtIOTouchscreenPCI,vdev.max_finger, DEFAULT_MAX_FINGER),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static int virtio_touchscreen_pci_init(VirtIOPCIProxy *vpci_dev)
-{
-    VirtIOTouchscreenPCI *dev = VIRTIO_TOUCHSCREEN_PCI(vpci_dev);
-    DeviceState *vdev = DEVICE(&dev->vdev);
-
-    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
-    if (qdev_init(vdev) < 0) {
-        return -1;
-    }
-    return 0;
-}
-
-static void virtio_touchscreen_pci_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
-    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
-
-    dc->props = virtio_touchscreen_pci_properties;
-    k->init = virtio_touchscreen_pci_init;
-    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_TOUCHSCREEN;
-    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
-    pcidev_k->class_id = PCI_CLASS_OTHERS;
-}
-
-static void virtio_touchscreen_pci_instance_init(Object *obj)
-{
-    VirtIOTouchscreenPCI *dev = VIRTIO_TOUCHSCREEN_PCI(obj);
-    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_TOUCHSCREEN);
-    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
-
-    dev->vdev.max_finger = DEFAULT_MAX_FINGER;
-}
-
-static TypeInfo virtio_touchscreen_pci_info = {
-    .name          = TYPE_VIRTIO_TOUCHSCREEN_PCI,
-    .parent        = TYPE_VIRTIO_PCI,
-    .instance_size = sizeof(VirtIOTouchscreenPCI),
-    .instance_init = virtio_touchscreen_pci_instance_init,
-    .class_init    = virtio_touchscreen_pci_class_init,
-};
-
-/* virtio-keyboard-pci */
-
-static int virtio_keyboard_pci_init(VirtIOPCIProxy *vpci_dev)
-{
-    VirtIOKeyboardPCI *dev = VIRTIO_KEYBOARD_PCI(vpci_dev);
-    DeviceState *vdev = DEVICE(&dev->vdev);
-
-    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
-    if (qdev_init(vdev) < 0) {
-        return -1;
-    }
-    return 0;
-}
-
-static void virtio_keyboard_pci_class_init(ObjectClass *klass, void *data)
-{
-    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
-    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_keyboard_pci_init;
-    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_KEYBOARD;
-    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
-    pcidev_k->class_id = PCI_CLASS_OTHERS;
-}
-
-static void virtio_keyboard_pci_instance_init(Object *obj)
-{
-    VirtIOKeyboardPCI *dev = VIRTIO_KEYBOARD_PCI(obj);
-    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_KEYBOARD);
-    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
-}
-
-static TypeInfo virtio_keyboard_pci_info = {
-    .name          = TYPE_VIRTIO_KEYBOARD_PCI,
-    .parent        = TYPE_VIRTIO_PCI,
-    .instance_size = sizeof(VirtIOKeyboardPCI),
-    .instance_init = virtio_keyboard_pci_instance_init,
-    .class_init    = virtio_keyboard_pci_class_init,
-};
-
-/* virtio-esm-pci */
-
-static int virtio_esm_pci_init(VirtIOPCIProxy *vpci_dev)
-{
-    VirtIOESMPCI *dev = VIRTIO_ESM_PCI(vpci_dev);
-    DeviceState *vdev = DEVICE(&dev->vdev);
-
-    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
-    if (qdev_init(vdev) < 0) {
-        return -1;
-    }
-    return 0;
-}
-
-static void virtio_esm_pci_class_init(ObjectClass *klass, void *data)
-{
-    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
-    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_esm_pci_init;
-    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_ESM;
-    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
-    pcidev_k->class_id = PCI_CLASS_OTHERS;
-}
-
-static void virtio_esm_pci_instance_init(Object *obj)
-{
-    VirtIOESMPCI *dev = VIRTIO_ESM_PCI(obj);
-    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_ESM);
-    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
-}
-
-static TypeInfo virtio_esm_pci_info = {
-    .name          = TYPE_VIRTIO_ESM_PCI,
-    .parent        = TYPE_VIRTIO_PCI,
-    .instance_size = sizeof(VirtIOESMPCI),
-    .instance_init = virtio_esm_pci_instance_init,
-    .class_init    = virtio_esm_pci_class_init,
-};
-
-/* virtio-hwkey-pci */
-
-static int virtio_hwkey_pci_init(VirtIOPCIProxy *vpci_dev)
-{
-    VirtIOHWKeyPCI *dev = VIRTIO_HWKEY_PCI(vpci_dev);
-    DeviceState *vdev = DEVICE(&dev->vdev);
-
-    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
-    if (qdev_init(vdev) < 0) {
-        return -1;
-    }
-    return 0;
-}
-
-static void virtio_hwkey_pci_class_init(ObjectClass *klass, void *data)
-{
-//    DeviceClass *dc = DEVICE_CLASS(klass);
-    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
-    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_hwkey_pci_init;
-    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_HWKEY;
-    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
-    pcidev_k->class_id = PCI_CLASS_OTHERS;
-}
-
-static void virtio_hwkey_pci_instance_init(Object *obj)
-{
-    VirtIOHWKeyPCI *dev = VIRTIO_HWKEY_PCI(obj);
-    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_HWKEY);
-    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
-}
-
-static TypeInfo virtio_hwkey_pci_info = {
-    .name          = TYPE_VIRTIO_HWKEY_PCI,
-    .parent        = TYPE_VIRTIO_PCI,
-    .instance_size = sizeof(VirtIOHWKeyPCI),
-    .instance_init = virtio_hwkey_pci_instance_init,
-    .class_init    = virtio_hwkey_pci_class_init,
-};
-
-/* virtio-evdi-pci */
-
-static int virtio_evdi_pci_init(VirtIOPCIProxy *vpci_dev)
-{
-    VirtIOEVDIPCI *dev = VIRTIO_EVDI_PCI(vpci_dev);
-    DeviceState *vdev = DEVICE(&dev->vdev);
-
-    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
-    if (qdev_init(vdev) < 0) {
-        return -1;
-    }
-    return 0;
-}
-
-static void virtio_evdi_pci_class_init(ObjectClass *klass, void *data)
-{
-//    DeviceClass *dc = DEVICE_CLASS(klass);
-    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
-    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_evdi_pci_init;
-    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_EVDI;
-    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
-    pcidev_k->class_id = PCI_CLASS_OTHERS;
-}
-
-static void virtio_evdi_pci_instance_init(Object *obj)
-{
-    VirtIOEVDIPCI *dev = VIRTIO_EVDI_PCI(obj);
-    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_EVDI);
-    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
-}
-
-static TypeInfo virtio_evdi_pci_info = {
-    .name          = TYPE_VIRTIO_EVDI_PCI,
-    .parent        = TYPE_VIRTIO_PCI,
-    .instance_size = sizeof(VirtIOEVDIPCI),
-    .instance_init = virtio_evdi_pci_instance_init,
-    .class_init    = virtio_evdi_pci_class_init,
-};
-
-/* virtio-sensor-pci */
-
-static int virtio_sensor_pci_init(VirtIOPCIProxy *vpci_dev)
-{
-    VirtIOSENSORPCI *dev = VIRTIO_SENSOR_PCI(vpci_dev);
-    DeviceState *vdev = DEVICE(&dev->vdev);
-
-    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
-    if (qdev_init(vdev) < 0) {
-        return -1;
-    }
-    return 0;
-}
-
-static Property virtio_sensor_pci_properties[] = {
-    DEFINE_PROP_STRING(ATTRIBUTE_NAME_SENSORS, VirtIOSENSORPCI, vdev.sensors),
-    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_sensor_pci_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
-    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_sensor_pci_init;
-    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_SENSOR;
-    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
-    pcidev_k->class_id = PCI_CLASS_OTHERS;
-    dc->props = virtio_sensor_pci_properties;
-}
-
-static void virtio_sensor_pci_instance_init(Object *obj)
-{
-    VirtIOSENSORPCI *dev = VIRTIO_SENSOR_PCI(obj);
-    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SENSOR);
-    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
-}
-
-static TypeInfo virtio_sensor_pci_info = {
-    .name          = TYPE_VIRTIO_SENSOR_PCI,
-    .parent        = TYPE_VIRTIO_PCI,
-    .instance_size = sizeof(VirtIOSENSORPCI),
-    .instance_init = virtio_sensor_pci_instance_init,
-    .class_init    = virtio_sensor_pci_class_init,
-};
-
-/* virtio NFC */
-
-static int virtio_nfc_pci_init(VirtIOPCIProxy *vpci_dev)
-{
-    VirtIONFCPCI *dev = VIRTIO_NFC_PCI(vpci_dev);
-    DeviceState *vdev = DEVICE(&dev->vdev);
-
-    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
-    if (qdev_init(vdev) < 0) {
-        return -1;
-    }
-    return 0;
-}
-
-static void virtio_nfc_pci_class_init(ObjectClass *klass, void *data)
-{
-    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
-    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_nfc_pci_init;
-    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_NFC;
-    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
-    pcidev_k->class_id = PCI_CLASS_OTHERS;
-}
-
-static void virtio_nfc_pci_instance_init(Object *obj)
-{
-    VirtIONFCPCI *dev = VIRTIO_NFC_PCI(obj);
-    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NFC);
-    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
-}
-
-static TypeInfo virtio_nfc_pci_info = {
-    .name          = TYPE_VIRTIO_NFC_PCI,
-    .parent        = TYPE_VIRTIO_PCI,
-    .instance_size = sizeof(VirtIONFCPCI),
-    .instance_init = virtio_nfc_pci_instance_init,
-    .class_init    = virtio_nfc_pci_class_init,
-};
-
-/* virtio-jack-pci */
-
-static int virtio_jack_pci_init(VirtIOPCIProxy *vpci_dev)
-{
-    VirtIOJACKPCI *dev = VIRTIO_JACK_PCI(vpci_dev);
-    DeviceState *vdev = DEVICE(&dev->vdev);
-
-    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
-    if (qdev_init(vdev) < 0) {
-        return -1;
-    }
-    return 0;
-}
-
-static Property virtio_jack_pci_properties[] = {
-    DEFINE_PROP_STRING(ATTRIBUTE_NAME_JACKS, VirtIOJACKPCI, vdev.jacks),
-    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_jack_pci_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
-    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_jack_pci_init;
-    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_JACK;
-    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
-    pcidev_k->class_id = PCI_CLASS_OTHERS;
-    dc->props = virtio_jack_pci_properties;
-}
-
-static void virtio_jack_pci_instance_init(Object *obj)
-{
-    VirtIOJACKPCI *dev = VIRTIO_JACK_PCI(obj);
-    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_JACK);
-    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
-}
-
-static TypeInfo virtio_jack_pci_info = {
-    .name          = TYPE_VIRTIO_JACK_PCI,
-    .parent        = TYPE_VIRTIO_PCI,
-    .instance_size = sizeof(VirtIOJACKPCI),
-    .instance_init = virtio_jack_pci_instance_init,
-    .class_init    = virtio_jack_pci_class_init,
-};
-
-/* virtio-power-pci */
-
-static int virtio_power_pci_init(VirtIOPCIProxy *vpci_dev)
-{
-    VirtIOPOWERPCI *dev = VIRTIO_POWER_PCI(vpci_dev);
-    DeviceState *vdev = DEVICE(&dev->vdev);
-
-    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
-    if (qdev_init(vdev) < 0) {
-        return -1;
-    }
-    return 0;
-}
-
-static void virtio_power_pci_class_init(ObjectClass *klass, void *data)
-{
-    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
-    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_power_pci_init;
-    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_POWER;
-    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
-    pcidev_k->class_id = PCI_CLASS_OTHERS;
-}
-
-static void virtio_power_pci_instance_init(Object *obj)
-{
-    VirtIOPOWERPCI *dev = VIRTIO_POWER_PCI(obj);
-    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_POWER);
-    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
-}
-
-static TypeInfo virtio_power_pci_info = {
-    .name          = TYPE_VIRTIO_POWER_PCI,
-    .parent        = TYPE_VIRTIO_PCI,
-    .instance_size = sizeof(VirtIOPOWERPCI),
-    .instance_init = virtio_power_pci_instance_init,
-    .class_init    = virtio_power_pci_class_init,
-};
-
-/* virtio-vmodem-pci */
-
-static int virtio_vmodem_pci_init(VirtIOPCIProxy *vpci_dev)
-{
-    VirtIOVModemPCI *dev = VIRTIO_VMODEM_PCI(vpci_dev);
-    DeviceState *vdev = DEVICE(&dev->vdev);
-
-    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
-    if (qdev_init(vdev) < 0) {
-        return -1;
-    }
-    return 0;
-}
-
-static void virtio_vmodem_pci_class_init(ObjectClass *klass, void *data)
-{
-    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
-    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
-
-    k->init = virtio_vmodem_pci_init;
-    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
-    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_VMODEM;
-    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
-    pcidev_k->class_id = PCI_CLASS_OTHERS;
-}
-
-static void virtio_vmodem_pci_instance_init(Object *obj)
-{
-    VirtIOVModemPCI *dev = VIRTIO_VMODEM_PCI(obj);
-    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_VMODEM);
-    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
-}
-
-static TypeInfo virtio_vmodem_pci_info = {
-    .name          = TYPE_VIRTIO_VMODEM_PCI,
-    .parent        = TYPE_VIRTIO_PCI,
-    .instance_size = sizeof(VirtIOVModemPCI),
-    .instance_init = virtio_vmodem_pci_instance_init,
-    .class_init    = virtio_vmodem_pci_class_init,
-};
-
-static void maru_virtio_pci_register_types(void)
-{
-    type_register_static(&virtio_evdi_pci_info);
-    type_register_static(&virtio_esm_pci_info);
-    type_register_static(&virtio_hwkey_pci_info);
-    type_register_static(&virtio_keyboard_pci_info);
-    type_register_static(&virtio_touchscreen_pci_info);
-    type_register_static(&virtio_sensor_pci_info);
-    type_register_static(&virtio_nfc_pci_info);
-    type_register_static(&virtio_jack_pci_info);
-    type_register_static(&virtio_power_pci_info);
-    type_register_static(&virtio_vmodem_pci_info);
-}
-
-type_init(maru_virtio_pci_register_types)
diff --git a/tizen/src/hw/maru_virtio_power.c b/tizen/src/hw/maru_virtio_power.c
deleted file mode 100644 (file)
index 7e72a66..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Virtio Power Device
- *
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Jinhyung Choi <jinhyung2.choi@samsung.com>
- *  Daiyoung Kim <daiyoung777.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 "hw/pci/pci.h"
-
-#include "maru_device_ids.h"
-#include "debug_ch.h"
-
-#include "maru_virtio_power.h"
-
-MULTI_DEBUG_CHANNEL(qemu, virtio-power);
-
-#define POWER_DEVICE_NAME  "power_supply"
-#define _MAX_BUF           1024
-#define __MAX_BUF_POWER    32
-
-static int capacity = 50;
-static int charge_full = 0;
-static int charge_now = 0;
-
-VirtIOPOWER* vpower;
-
-typedef struct msg_info {
-    char buf[_MAX_BUF];
-
-    uint16_t type;
-    uint16_t req;
-} msg_info;
-
-enum request_cmd {
-    request_get = 0,
-    request_set,
-    request_answer
-};
-
-static void set_power_data (enum power_types type, char* data, int len)
-{
-    if (len < 0 || len > __MAX_BUF_POWER) {
-        ERR("power data size is wrong.\n");
-        return;
-    }
-
-    if (data == NULL) {
-        ERR("power data is NULL.\n");
-        return;
-    }
-
-    switch (type) {
-        case power_type_capacity:
-            sscanf(data, "%d", &capacity);
-            break;
-        case power_type_charge_full:
-            sscanf(data, "%d", &charge_full);
-            break;
-        case power_type_charge_now:
-            sscanf(data, "%d", &charge_now);
-            break;
-        default:
-            return;
-    }
-}
-
-static void get_power_data(enum power_types type, char* msg_info)
-{
-    if (msg_info == NULL) {
-        return;
-    }
-
-    switch (type) {
-        case power_type_capacity:
-            sprintf(msg_info, "%d", capacity);
-            break;
-        case power_type_charge_full:
-            sprintf(msg_info, "%d", charge_full);
-            break;
-        case power_type_charge_now:
-            sprintf(msg_info, "%d", charge_now);
-            break;
-        default:
-            return;
-    }
-}
-
-void set_power_capacity(int level) {
-    capacity = level;
-}
-
-int get_power_capacity(void) {
-    return capacity;
-}
-
-void set_power_charge_full(int full){
-    charge_full = full;
-}
-
-int get_power_charge_full(void){
-    return charge_full;
-}
-
-void set_power_charge_now(int now){
-    charge_now = now;
-}
-
-int get_power_charge_now(void){
-    return charge_now;
-}
-
-static void answer_power_data_request(int type, char* data, VirtQueueElement *elem)
-{
-    msg_info* msginfo = (msg_info*) malloc(sizeof(msg_info));
-    if (!msginfo) {
-        ERR("msginfo is NULL!\n");
-        return;
-    }
-
-    msginfo->req = request_answer;
-    msginfo->type = type;
-    get_power_data(type, msginfo->buf);
-
-    TRACE("sending message: %s, type: %d, req: %d\n", msginfo->buf, msginfo->type, msginfo->req);
-
-    memset(elem->in_sg[0].iov_base, 0, elem->in_sg[0].iov_len);
-    memcpy(elem->in_sg[0].iov_base, msginfo, sizeof(struct msg_info));
-
-    if (msginfo)
-        free(msginfo);
-}
-
-static void handle_msg(struct msg_info *msg, VirtQueueElement *elem)
-{
-    unsigned int len = 0;
-
-    if (msg == NULL) {
-        ERR("msg info structure is NULL.\n");
-        return;
-    }
-
-    if (msg->req == request_set) {
-        set_power_data (msg->type, msg->buf, strlen(msg->buf));
-    } else if (msg->req == request_get) {
-        answer_power_data_request(msg->type, msg->buf, elem);
-        len = sizeof(msg_info);
-    }
-
-    virtqueue_push(vpower->vq, elem, len);
-    virtio_notify(&vpower->vdev, vpower->vq);
-}
-
-static void virtio_power_vq(VirtIODevice *vdev, VirtQueue *vq)
-{
-    VirtIOPOWER *vpower = (VirtIOPOWER*)vdev;
-    struct msg_info msg;
-    VirtQueueElement elem;
-    int index = 0;
-
-    if (vpower->vq == NULL) {
-        ERR("virt queue is not ready.\n");
-        return;
-    }
-
-    if (!virtio_queue_ready(vpower->vq)) {
-        ERR("virtqueue is not ready.");
-        return;
-    }
-
-    if (virtio_queue_empty(vpower->vq)) {
-        ERR("<< virtqueue is empty.\n");
-        return;
-    }
-
-    while ((index = virtqueue_pop(vq, &elem))) {
-        memset(&msg, 0x00, sizeof(msg));
-        memcpy(&msg, elem.out_sg[0].iov_base, elem.out_sg[0].iov_len);
-
-        TRACE("handling msg from driver: %s, len: %d, type: %d, req: %d, index: %d\n", msg.buf, strlen(msg.buf), msg.type, msg.req, index);
-
-        handle_msg(&msg, &elem);
-    }
-}
-
-static void virtio_power_realize(DeviceState *dev, Error **errp)
-{
-    INFO("initialize virtio-power device\n");
-
-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-    vpower = VIRTIO_POWER(vdev);
-
-    virtio_init(vdev, POWER_DEVICE_NAME, VIRTIO_ID_POWER, 0);
-
-    if (vpower == NULL) {
-        ERR("failed to initialize power device\n");
-        return;
-    }
-
-    vpower->vq = virtio_add_queue(&vpower->vdev, 64, virtio_power_vq);
-}
-
-static void virtio_power_unrealize(DeviceState *dev, Error **errp)
-{
-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-    INFO("destroy power device\n");
-
-    virtio_cleanup(vdev);
-}
-
-
-static void virtio_power_reset(VirtIODevice *vdev)
-{
-    TRACE("virtio_power_reset.\n");
-}
-
-static uint32_t virtio_power_get_features(VirtIODevice *vdev,
-                                            uint32_t request_feature)
-{
-    TRACE("virtio_power_get_features.\n");
-    return 0;
-}
-
-static void virtio_power_class_init(ObjectClass *klass, void *data)
-{
-    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
-    vdc->realize = virtio_power_realize;
-    vdc->unrealize = virtio_power_unrealize;
-    vdc->get_features = virtio_power_get_features;
-    vdc->reset = virtio_power_reset;
-}
-
-static const TypeInfo virtio_device_info = {
-    .name = TYPE_VIRTIO_POWER,
-    .parent = TYPE_VIRTIO_DEVICE,
-    .instance_size = sizeof(VirtIOPOWER),
-    .class_init = virtio_power_class_init,
-};
-
-static void virtio_register_types(void)
-{
-    type_register_static(&virtio_device_info);
-}
-
-type_init(virtio_register_types)
-
diff --git a/tizen/src/hw/maru_virtio_power.h b/tizen/src/hw/maru_virtio_power.h
deleted file mode 100644 (file)
index 0a76fec..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Virtio Power Device
- *
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Jinhyung choi   <jinhyung2.choi@samsung.com>
- *  Daiyoung Kim    <daiyoung777.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_VIRTIO_POWER_H_
-#define MARU_VIRTIO_POWER_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "hw/virtio/virtio.h"
-
-#define TYPE_VIRTIO_POWER "virtio-power-device"
-#define VIRTIO_POWER(obj) \
-        OBJECT_CHECK(VirtIOPOWER, (obj), TYPE_VIRTIO_POWER)
-
-enum power_types {
-    power_type_capacity = 0,
-    power_type_charge_full,
-    power_type_charge_now,
-    power_type_max
-};
-
-typedef struct VirtIOPOWER {
-    VirtIODevice    vdev;
-    VirtQueue       *vq;
-    DeviceState     *qdev;
-
-    QEMUBH          *bh;
-} VirtIOPOWER;
-
-void set_power_capacity(int capacity);
-int get_power_capacity(void);
-void set_power_charge_full(int full);
-int get_power_charge_full(void);
-void set_power_charge_now(int now);
-int get_power_charge_now(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/tizen/src/hw/maru_virtio_sensor.c b/tizen/src/hw/maru_virtio_sensor.c
deleted file mode 100644 (file)
index 3c03392..0000000
+++ /dev/null
@@ -1,597 +0,0 @@
-/*
- * Virtio Sensor Device
- *
- * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Jinhyung Choi <jinhyung2.choi@samsung.com>
- *  Daiyoung Kim <daiyoung777.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 "hw/pci/pci.h"
-
-#include "maru_device_ids.h"
-#include "maru_virtio_sensor.h"
-#include "debug_ch.h"
-#include "ecs/ecs.h"
-
-MULTI_DEBUG_CHANNEL(qemu, virtio-sensor);
-
-#define SENSOR_DEVICE_NAME  "sensor"
-#define _MAX_BUF            1024
-#define __MAX_BUF_SENSOR    32
-
-static QemuMutex accel_mutex;
-static QemuMutex geo_mutex;
-static QemuMutex gyro_mutex;
-static QemuMutex light_mutex;
-static QemuMutex proxi_mutex;
-
-static char accel_xyz [__MAX_BUF_SENSOR] = {'0',',','9','8','0','6','6','5',',','0'};
-static int accel_enable = 0;
-static int accel_delay = 200000000;
-
-static char geo_raw [__MAX_BUF_SENSOR] = {'0',' ','-','9','0',' ','0',' ','3'};
-static char geo_tesla [__MAX_BUF_SENSOR] = {'1',' ','0',' ','-','1','0'};
-static int geo_enable = 0;
-static int geo_delay = 200000000;
-
-static int gyro_x_raw = 0;
-static int gyro_y_raw = 0;
-static int gyro_z_raw = 0;
-static int gyro_enable = 0;
-static int gyro_delay = 200000000;
-
-static int light_adc = 65535;
-static int light_level = 10;
-static int light_enable = 0;
-static int light_delay = 200000000;
-
-static int proxi_vo = 8;
-static int proxi_enable = 0;
-static int proxi_delay = 200000000;
-
-VirtIOSENSOR* vsensor;
-static int sensor_capability = 0;
-
-typedef struct msg_info {
-    char buf[_MAX_BUF];
-
-    uint16_t type;
-    uint16_t req;
-} msg_info;
-
-static type_action get_action(enum sensor_types type)
-{
-    type_action action = 0;
-
-    switch (type) {
-    case sensor_type_accel:
-        action = ACTION_ACCEL;
-        break;
-    case sensor_type_gyro:
-        action = ACTION_GYRO;
-        break;
-    case sensor_type_mag:
-        action = ACTION_MAG;
-        break;
-    case sensor_type_light:
-        action = ACTION_LIGHT;
-        break;
-    case sensor_type_proxi:
-        action = ACTION_PROXI;
-        break;
-    default:
-        break;
-    }
-
-    return action;
-}
-
-static void send_sensor_to_ecs(const char* data, enum sensor_types type)
-{
-    type_length length = 0;
-    type_group group = GROUP_STATUS;
-    type_action action = 0;
-    int buf_len = strlen(data);
-    int message_len =  buf_len + 14;
-
-    char* ecs_message = (char*) malloc(message_len + 1);
-    if (!ecs_message)
-        return;
-
-    memset(ecs_message, 0, message_len + 1);
-
-    length = (unsigned short) buf_len;
-    action = get_action(type);
-
-    memcpy(ecs_message, MESSAGE_TYPE_SENSOR, 6);
-    memcpy(ecs_message + 10, &length, sizeof(unsigned short));
-    memcpy(ecs_message + 12, &group, sizeof(unsigned char));
-    memcpy(ecs_message + 13, &action, sizeof(unsigned char));
-    memcpy(ecs_message + 14, data, buf_len);
-
-    TRACE("ntf_to_injector- len: %d, group: %d, action: %d, data: %s\n", length, group, action, data);
-
-    send_device_ntf(ecs_message, message_len);
-
-    if (ecs_message)
-        free(ecs_message);
-}
-
-static void __set_sensor_data (enum sensor_types type, char* data, int len)
-{
-    if (len < 0 || len > __MAX_BUF_SENSOR) {
-        ERR("sensor data size is wrong.\n");
-        return;
-    }
-
-    if (data == NULL) {
-        ERR("sensor data is NULL.\n");
-        return;
-    }
-
-    TRACE("set_sensor_data with type '%d' with data '%s'", type, data);
-
-    switch (type) {
-        case sensor_type_accel:
-            qemu_mutex_lock(&accel_mutex);
-            strcpy(accel_xyz, data);
-            qemu_mutex_unlock(&accel_mutex);
-            break;
-        case sensor_type_accel_enable:
-            qemu_mutex_lock(&accel_mutex);
-            sscanf(data, "%d", &accel_enable);
-            qemu_mutex_unlock(&accel_mutex);
-            break;
-        case sensor_type_accel_delay:
-            qemu_mutex_lock(&accel_mutex);
-            sscanf(data, "%d", &accel_delay);
-            qemu_mutex_unlock(&accel_mutex);
-            break;
-        case sensor_type_gyro_enable:
-            qemu_mutex_lock(&gyro_mutex);
-            sscanf(data, "%d", &gyro_enable);
-            qemu_mutex_unlock(&gyro_mutex);
-            break;
-        case sensor_type_gyro_delay:
-            qemu_mutex_lock(&gyro_mutex);
-            sscanf(data, "%d", &gyro_delay);
-            qemu_mutex_unlock(&gyro_mutex);
-            break;
-        case sensor_type_gyro_x:
-            qemu_mutex_lock(&gyro_mutex);
-            sscanf(data, "%d", &gyro_x_raw);
-            qemu_mutex_unlock(&gyro_mutex);
-            break;
-        case sensor_type_gyro_y:
-            qemu_mutex_lock(&gyro_mutex);
-            sscanf(data, "%d", &gyro_y_raw);
-            qemu_mutex_unlock(&gyro_mutex);
-            break;
-        case sensor_type_gyro_z:
-            qemu_mutex_lock(&gyro_mutex);
-            sscanf(data, "%d", &gyro_z_raw);
-            qemu_mutex_unlock(&gyro_mutex);
-            break;
-        case sensor_type_gyro:
-            qemu_mutex_lock(&gyro_mutex);
-            sscanf(data, "%d %d %d", &gyro_x_raw, &gyro_y_raw, &gyro_z_raw);
-            qemu_mutex_unlock(&gyro_mutex);
-            break;
-        case sensor_type_light_adc:
-            qemu_mutex_lock(&light_mutex);
-            sscanf(data, "%d", &light_adc);
-            light_level = (light_adc / 6554) % 10 + 1;
-            qemu_mutex_unlock(&light_mutex);
-            break;
-        case sensor_type_light_level:
-            qemu_mutex_lock(&light_mutex);
-            sscanf(data, "%d", &light_level);
-            qemu_mutex_unlock(&light_mutex);
-            break;
-        case sensor_type_light_enable:
-            qemu_mutex_lock(&light_mutex);
-            sscanf(data, "%d", &light_enable);
-            qemu_mutex_unlock(&light_mutex);
-            break;
-        case sensor_type_light_delay:
-            qemu_mutex_lock(&light_mutex);
-            sscanf(data, "%d", &light_delay);
-            qemu_mutex_unlock(&light_mutex);
-            break;
-        case sensor_type_proxi:
-            qemu_mutex_lock(&proxi_mutex);
-            sscanf(data, "%d", &proxi_vo);
-            qemu_mutex_unlock(&proxi_mutex);
-            break;
-        case sensor_type_proxi_enable:
-            qemu_mutex_lock(&proxi_mutex);
-            sscanf(data, "%d", &proxi_enable);
-            qemu_mutex_unlock(&proxi_mutex);
-            break;
-        case sensor_type_proxi_delay:
-            qemu_mutex_lock(&proxi_mutex);
-            sscanf(data, "%d", &proxi_delay);
-            qemu_mutex_unlock(&proxi_mutex);
-            break;
-        case sensor_type_mag:
-            qemu_mutex_lock(&geo_mutex);
-            strcpy(geo_tesla, data);
-            qemu_mutex_unlock(&geo_mutex);
-            break;
-        case sensor_type_tilt:
-            qemu_mutex_lock(&geo_mutex);
-            strcpy(geo_raw, data);
-            qemu_mutex_unlock(&geo_mutex);
-            break;
-        case sensor_type_geo_enable:
-            qemu_mutex_lock(&geo_mutex);
-            sscanf(data, "%d", &geo_enable);
-            qemu_mutex_unlock(&geo_mutex);
-            break;
-        case sensor_type_geo_delay:
-            qemu_mutex_lock(&geo_mutex);
-            sscanf(data, "%d", &geo_delay);
-            qemu_mutex_unlock(&geo_mutex);
-            break;
-        default:
-            return;
-    }
-}
-
-static void __get_sensor_data(enum sensor_types type, char* msg_info)
-{
-    if (msg_info == NULL) {
-        return;
-    }
-
-    switch (type) {
-        case sensor_type_list:
-            sprintf(msg_info, "%d", sensor_capability);
-            break;
-        case sensor_type_accel:
-            qemu_mutex_lock(&accel_mutex);
-            strcpy(msg_info, accel_xyz);
-            qemu_mutex_unlock(&accel_mutex);
-            break;
-        case sensor_type_accel_enable:
-            qemu_mutex_lock(&accel_mutex);
-            sprintf(msg_info, "%d", accel_enable);
-            qemu_mutex_unlock(&accel_mutex);
-            break;
-        case sensor_type_accel_delay:
-            qemu_mutex_lock(&accel_mutex);
-            sprintf(msg_info, "%d", accel_delay);
-            qemu_mutex_unlock(&accel_mutex);
-            break;
-        case sensor_type_mag:
-            qemu_mutex_lock(&geo_mutex);
-            strcpy(msg_info, geo_tesla);
-            qemu_mutex_unlock(&geo_mutex);
-            break;
-        case sensor_type_tilt:
-            qemu_mutex_lock(&geo_mutex);
-            strcpy(msg_info, geo_raw);
-            qemu_mutex_unlock(&geo_mutex);
-            break;
-        case sensor_type_geo_enable:
-            qemu_mutex_lock(&geo_mutex);
-            sprintf(msg_info, "%d", geo_enable);
-            qemu_mutex_unlock(&geo_mutex);
-            break;
-        case sensor_type_geo_delay:
-            qemu_mutex_lock(&geo_mutex);
-            sprintf(msg_info, "%d", geo_delay);
-            qemu_mutex_unlock(&geo_mutex);
-            break;
-        case sensor_type_gyro:
-            qemu_mutex_lock(&gyro_mutex);
-            sprintf(msg_info, "%d,%d,%d", gyro_x_raw, gyro_y_raw, gyro_z_raw);
-            qemu_mutex_unlock(&gyro_mutex);
-            break;
-        case sensor_type_gyro_enable:
-            qemu_mutex_lock(&gyro_mutex);
-            sprintf(msg_info, "%d", gyro_enable);
-            qemu_mutex_unlock(&gyro_mutex);
-            break;
-        case sensor_type_gyro_delay:
-            qemu_mutex_lock(&gyro_mutex);
-            sprintf(msg_info, "%d", gyro_delay);
-            qemu_mutex_unlock(&gyro_mutex);
-            break;
-        case sensor_type_gyro_x:
-            qemu_mutex_lock(&gyro_mutex);
-            sprintf(msg_info, "%d", gyro_x_raw);
-            qemu_mutex_unlock(&gyro_mutex);
-            break;
-        case sensor_type_gyro_y:
-            qemu_mutex_lock(&gyro_mutex);
-            sprintf(msg_info, "%d", gyro_y_raw);
-            qemu_mutex_unlock(&gyro_mutex);
-            break;
-        case sensor_type_gyro_z:
-            qemu_mutex_lock(&gyro_mutex);
-            sprintf(msg_info, "%d", gyro_z_raw);
-            qemu_mutex_unlock(&gyro_mutex);
-            break;
-        case sensor_type_light:
-        case sensor_type_light_adc:
-            qemu_mutex_lock(&light_mutex);
-            sprintf(msg_info, "%d", light_adc);
-            qemu_mutex_unlock(&light_mutex);
-            break;
-        case sensor_type_light_level:
-            qemu_mutex_lock(&light_mutex);
-            sprintf(msg_info, "%d", light_level);
-            qemu_mutex_unlock(&light_mutex);
-            break;
-        case sensor_type_light_enable:
-            qemu_mutex_lock(&light_mutex);
-            sprintf(msg_info, "%d", light_enable);
-            qemu_mutex_unlock(&light_mutex);
-            break;
-        case sensor_type_light_delay:
-            qemu_mutex_lock(&light_mutex);
-            sprintf(msg_info, "%d", light_delay);
-            qemu_mutex_unlock(&light_mutex);
-            break;
-        case sensor_type_proxi:
-            qemu_mutex_lock(&proxi_mutex);
-            sprintf(msg_info, "%d", proxi_vo);
-            qemu_mutex_unlock(&proxi_mutex);
-            break;
-        case sensor_type_proxi_enable:
-            qemu_mutex_lock(&proxi_mutex);
-            sprintf(msg_info, "%d", proxi_enable);
-            qemu_mutex_unlock(&proxi_mutex);
-            break;
-        case sensor_type_proxi_delay:
-            qemu_mutex_lock(&proxi_mutex);
-            sprintf(msg_info, "%d", proxi_delay);
-            qemu_mutex_unlock(&proxi_mutex);
-            break;
-        default:
-            return;
-    }
-}
-
-void req_sensor_data (enum sensor_types type, enum request_cmd req, char* data, int len)
-{
-    char msg_info [__MAX_BUF_SENSOR];
-    memset(msg_info, 0, __MAX_BUF_SENSOR);
-
-    if (type >= sensor_type_max || (req != request_get && req != request_set)) {
-        ERR("unavailable sensor type request.\n");
-        return;
-    }
-
-    if (req == request_set) {
-        __set_sensor_data (type, data, len);
-    } else if (req == request_get) {
-        __get_sensor_data(type, msg_info);
-        send_sensor_to_ecs(msg_info, type);
-    }
-}
-
-static void answer_sensor_data_request(int type, char* data, VirtQueueElement *elem)
-{
-    msg_info* msginfo = (msg_info*) malloc(sizeof(msg_info));
-    if (!msginfo) {
-        ERR("msginfo is NULL!\n");
-        return;
-    }
-
-    msginfo->req = request_answer;
-    msginfo->type = type;
-    __get_sensor_data(type, msginfo->buf);
-
-    TRACE("sending message: %s, type: %d, req: %d\n", msginfo->buf, msginfo->type, msginfo->req);
-
-    memset(elem->in_sg[0].iov_base, 0, elem->in_sg[0].iov_len);
-    memcpy(elem->in_sg[0].iov_base, msginfo, sizeof(struct msg_info));
-
-    if (msginfo)
-        free(msginfo);
-}
-
-static void handle_msg(struct msg_info *msg, VirtQueueElement *elem)
-{
-    unsigned int len = 0;
-
-    if (msg == NULL) {
-        ERR("msg info structure is NULL.\n");
-        return;
-    }
-
-    if (msg->req == request_set) {
-        __set_sensor_data (msg->type, msg->buf, strlen(msg->buf));
-    } else if (msg->req == request_get) {
-        answer_sensor_data_request(msg->type, msg->buf, elem);
-        len = sizeof(msg_info);
-    }
-
-    virtqueue_push(vsensor->vq, elem, len);
-    virtio_notify(&vsensor->vdev, vsensor->vq);
-}
-
-static void virtio_sensor_vq(VirtIODevice *vdev, VirtQueue *vq)
-{
-    VirtIOSENSOR *vsensor = (VirtIOSENSOR*)vdev;
-    struct msg_info msg;
-    VirtQueueElement elem;
-    int index = 0;
-
-    if (vsensor->vq == NULL) {
-        ERR("virt queue is not ready.\n");
-        return;
-    }
-
-    if (!virtio_queue_ready(vsensor->vq)) {
-        ERR("virtqueue is not ready.");
-        return;
-    }
-
-    if (virtio_queue_empty(vsensor->vq)) {
-        ERR("<< virtqueue is empty.\n");
-        return;
-    }
-
-    while ((index = virtqueue_pop(vq, &elem))) {
-        memset(&msg, 0x00, sizeof(msg));
-        memcpy(&msg, elem.out_sg[0].iov_base, elem.out_sg[0].iov_len);
-
-        TRACE("handling msg from driver: %s, len: %d, type: %d, req: %d, index: %d\n", msg.buf, strlen(msg.buf), msg.type, msg.req, index);
-
-        handle_msg(&msg, &elem);
-    }
-}
-
-static int set_capability(char* sensor)
-{
-    if (!strncmp(sensor, SENSOR_NAME_ACCEL, 5)) {
-        return sensor_cap_accel;
-    } else if (!strncmp(sensor, SENSOR_NAME_GEO, 3)) {
-        return sensor_cap_geo;
-    } else if (!strncmp(sensor, SENSOR_NAME_GYRO, 4)) {
-        return sensor_cap_gyro;
-    } else if (!strncmp(sensor, SENSOR_NAME_LIGHT, 5)) {
-        return sensor_cap_light;
-    } else if (!strncmp(sensor, SENSOR_NAME_PROXI, 5)) {
-        return sensor_cap_proxi;
-    } else if (!strncmp(sensor, SENSOR_NAME_HAPTIC, 6)) {
-        return sensor_cap_haptic;
-    } else {
-        ERR("unknown sensor request: %s", sensor);
-    }
-
-    return 0;
-}
-
-static void parse_sensor_capability(char* lists)
-{
-    char token[] = SENSOR_CAP_TOKEN;
-    char* data = NULL;
-
-    if (lists == NULL)
-        return;
-
-    data = strtok(lists, token);
-    if (data != NULL) {
-        sensor_capability |= set_capability(data);
-        while ((data = strtok(NULL, token)) != NULL) {
-            sensor_capability |= set_capability(data);
-        }
-    }
-
-    INFO("sensor device capabilty enabled with %02x\n", sensor_capability);
-}
-
-static void virtio_sensor_realize(DeviceState *dev, Error **errp)
-{
-    INFO("initialize virtio-sensor device\n");
-
-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-    vsensor = VIRTIO_SENSOR(vdev);
-
-    virtio_init(vdev, SENSOR_DEVICE_NAME, VIRTIO_ID_SENSOR, 0);
-
-    if (vsensor == NULL) {
-        ERR("failed to initialize sensor device\n");
-        error_set(errp, QERR_DEVICE_INIT_FAILED, SENSOR_DEVICE_NAME);
-        return;
-    }
-
-    qemu_mutex_init(&accel_mutex);
-    qemu_mutex_init(&gyro_mutex);
-    qemu_mutex_init(&geo_mutex);
-    qemu_mutex_init(&light_mutex);
-    qemu_mutex_init(&proxi_mutex);
-
-    vsensor->vq = virtio_add_queue(&vsensor->vdev, 64, virtio_sensor_vq);
-
-    INFO("initialized sensor type: %s\n", vsensor->sensors);
-
-    if (vsensor->sensors) {
-        parse_sensor_capability(vsensor->sensors);
-    }
-}
-
-static void virtio_sensor_unrealize(DeviceState *dev, Error **errp)
-{
-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-    INFO("destroy sensor device\n");
-
-    qemu_mutex_destroy(&accel_mutex);
-    qemu_mutex_destroy(&gyro_mutex);
-    qemu_mutex_destroy(&geo_mutex);
-    qemu_mutex_destroy(&light_mutex);
-    qemu_mutex_destroy(&proxi_mutex);
-
-    virtio_cleanup(vdev);
-}
-
-
-static void virtio_sensor_reset(VirtIODevice *vdev)
-{
-    TRACE("virtio_sensor_reset.\n");
-}
-
-static uint32_t virtio_sensor_get_features(VirtIODevice *vdev,
-                                            uint32_t request_feature)
-{
-    TRACE("virtio_sensor_get_features.\n");
-    return 0;
-}
-
-static Property virtio_sensor_properties[] = {
-    DEFINE_PROP_STRING(ATTRIBUTE_NAME_SENSORS, VirtIOSENSOR, sensors),
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_sensor_class_init(ObjectClass *klass, void *data)
-{
-    DeviceClass *dc = DEVICE_CLASS(klass);
-    dc->props = virtio_sensor_properties;
-    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
-    vdc->unrealize= virtio_sensor_unrealize;
-    vdc->realize = virtio_sensor_realize;
-    vdc->get_features = virtio_sensor_get_features;
-    vdc->reset = virtio_sensor_reset;
-}
-
-static const TypeInfo virtio_device_info = {
-    .name = TYPE_VIRTIO_SENSOR,
-    .parent = TYPE_VIRTIO_DEVICE,
-    .instance_size = sizeof(VirtIOSENSOR),
-    .class_init = virtio_sensor_class_init,
-};
-
-static void virtio_register_types(void)
-{
-    type_register_static(&virtio_device_info);
-}
-
-type_init(virtio_register_types)
-
diff --git a/tizen/src/hw/maru_virtio_sensor.h b/tizen/src/hw/maru_virtio_sensor.h
deleted file mode 100644 (file)
index 382c0c4..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Virtio Sensor Device
- *
- * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Jinhyung choi   <jinhyung2.choi@samsung.com>
- *  Daiyoung Kim    <daiyoung777.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_VIRTIO_SENSOR_H_
-#define MARU_VIRTIO_SENSOR_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "hw/virtio/virtio.h"
-
-enum request_cmd {
-    request_get = 0,
-    request_set,
-    request_answer
-};
-
-enum sensor_types {
-    sensor_type_list = 0,
-    sensor_type_accel,
-    sensor_type_accel_enable,
-    sensor_type_accel_delay,
-    sensor_type_geo,
-    sensor_type_geo_enable,
-    sensor_type_geo_delay,
-    sensor_type_gyro,
-    sensor_type_gyro_enable,
-    sensor_type_gyro_delay,
-    sensor_type_gyro_x,
-    sensor_type_gyro_y,
-    sensor_type_gyro_z,
-    sensor_type_light,
-    sensor_type_light_enable,
-    sensor_type_light_delay,
-    sensor_type_light_adc,
-    sensor_type_light_level,
-    sensor_type_proxi,
-    sensor_type_proxi_enable,
-    sensor_type_proxi_delay,
-    sensor_type_mag,
-    sensor_type_tilt,
-    sensor_type_max
-};
-
-enum sensor_capabilities {
-    sensor_cap_accel  = 0x01,
-    sensor_cap_geo    = 0x02,
-    sensor_cap_gyro   = 0x04,
-    sensor_cap_light  = 0x08,
-    sensor_cap_proxi  = 0x10,
-    sensor_cap_haptic = 0x20
-};
-
-#define MESSAGE_TYPE_SENSOR "sensor"
-
-#define GROUP_STATUS        15
-
-#define ACTION_ACCEL        110
-#define ACTION_GYRO         111
-#define ACTION_MAG          112
-#define ACTION_LIGHT        113
-#define ACTION_PROXI        114
-
-#define ATTRIBUTE_NAME_SENSORS "sensors"
-
-#define SENSOR_NAME_ACCEL  "accel"
-#define SENSOR_NAME_GYRO   "gyro"
-#define SENSOR_NAME_GEO    "geo"
-#define SENSOR_NAME_LIGHT  "light"
-#define SENSOR_NAME_PROXI  "proxi"
-#define SENSOR_NAME_HAPTIC "haptic"
-
-#define SENSOR_CAP_TOKEN "&"
-
-#define TYPE_VIRTIO_SENSOR "virtio-sensor-device"
-#define VIRTIO_SENSOR(obj) \
-        OBJECT_CHECK(VirtIOSENSOR, (obj), TYPE_VIRTIO_SENSOR)
-
-typedef struct VirtIOSENSOR {
-    VirtIODevice    vdev;
-    VirtQueue       *vq;
-    DeviceState     *qdev;
-
-    char            *sensors;
-} VirtIOSENSOR;
-
-void req_sensor_data(enum sensor_types type, enum request_cmd req, char* data, int len);
-
-#define get_sensor_accel()  \
-    req_sensor_data(sensor_type_accel, request_get, NULL, 0);
-
-#define get_sensor_gyro()   \
-    req_sensor_data(sensor_type_gyro, request_get, NULL, 0);
-
-#define get_sensor_mag()    \
-    req_sensor_data(sensor_type_mag, request_get, NULL, 0);
-
-#define get_sensor_light()  \
-    req_sensor_data(sensor_type_light_adc, request_get, NULL, 0);
-
-#define get_sensor_proxi()  \
-    req_sensor_data(sensor_type_proxi, request_get, NULL, 0);
-
-#define set_sensor_accel(data, len) \
-    req_sensor_data(sensor_type_accel, request_set, data, len);
-
-#define set_sensor_proxi(data, len) \
-    req_sensor_data(sensor_type_proxi, request_set, data, len);
-
-#define set_sensor_light(data, len) \
-    req_sensor_data(sensor_type_light_adc, request_set, data, len);
-
-#define set_sensor_gyro(data, len)  \
-    req_sensor_data(sensor_type_gyro, request_set, data, len);
-
-#define set_sensor_tilt(data, len)  \
-    req_sensor_data(sensor_type_tilt, request_set, data, len);
-
-#define set_sensor_mag(data, len)   \
-    req_sensor_data(sensor_type_mag, request_set, data, len);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/tizen/src/hw/maru_virtio_touchscreen.c b/tizen/src/hw/maru_virtio_touchscreen.c
deleted file mode 100644 (file)
index 42f2d96..0000000
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
- * Maru Virtio Touchscreen Device
- *
- * Copyright (c) 2011 - 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 "maru_virtio_touchscreen.h"
-#include "maru_device_ids.h"
-#include "emul_state.h"
-#include "debug_ch.h"
-
-MULTI_DEBUG_CHANNEL(qemu, touchscreen);
-
-
-#define DEVICE_NAME "virtio-touchscreen"
-
-/*
- * touch event queue
- */
-typedef struct TouchEventEntry {
-    unsigned int index;
-    EmulTouchEvent touch;
-
-    QTAILQ_ENTRY(TouchEventEntry) node;
-} TouchEventEntry;
-
-/* the maximum number of touch event that can be put into a queue */
-#define MAX_TOUCH_EVENT_CNT 256
-
-static TouchEventEntry _events_buf[MAX_TOUCH_EVENT_CNT];
-static QTAILQ_HEAD(, TouchEventEntry) 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 ElementEntry _elem_buf[10];
-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 */
-
-
-VirtIOTouchscreen *ts;
-
-/* lock for between communication thread and IO thread */
-static pthread_mutex_t event_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_mutex_t elem_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-
-void virtio_touchscreen_event(int x, int y, int z, int buttons_state)
-{
-    TouchEventEntry *entry = NULL;
-
-    if (unlikely(!virtio_queue_ready(ts->vq))) {
-        ERR("virtio queue is not ready\n");
-        return;
-    }
-
-    if (unlikely(event_queue_cnt >= MAX_TOUCH_EVENT_CNT)) {
-        INFO("full touch event queue, lose event\n", event_queue_cnt);
-
-        qemu_bh_schedule(ts->bh);
-        return;
-    }
-
-    entry = &(_events_buf[event_ringbuf_cnt % MAX_TOUCH_EVENT_CNT]);
-    event_ringbuf_cnt++;
-
-    /* mouse event is copied into the queue */
-    entry->touch.x = x;
-    entry->touch.y = y;
-    entry->touch.z = z;
-    entry->touch.state = buttons_state;
-
-    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_touchscreen_notify */
-    qemu_bh_schedule(ts->bh);
-
-    TRACE("touch event (%d) : x=%d, y=%d, z=%d, state=%d\n",
-        entry->index, entry->touch.x, entry->touch.y,
-        entry->touch.z, entry->touch.state);
-}
-
-static void maru_virtio_touchscreen_handle(VirtIODevice *vdev, VirtQueue *vq)
-{
-#if 0 /* not used yet */
-    if (ts->eh_entry == NULL) {
-        void *vbuf = NULL;
-        VirtQueueElement elem;
-        int max_trkid = 0;
-
-        virtqueue_pop(ts->vq, &elem);
-        vbuf = elem.in_sg[0].iov_base;
-        memcpy(&max_trkid, vbuf, sizeof(max_trkid));
-
-        if (max_trkid > 0) {
-            INFO("virtio touchscreen's maximum of tracking id = %d\n", max_trkid);
-
-            /* register a event handler */
-            ts->eh_entry = qemu_add_mouse_event_handler(
-                virtio_touchscreen_event, ts, 1, "QEMU Virtio Touchscreen");
-            qemu_activate_mouse_event_handler(ts->eh_entry);
-
-            //TODO:
-            virtqueue_push(ts->vq, &elem, 0);
-            virtio_notify(&(ts->vdev), ts->vq);
-        } else {
-            INFO("virtio touchscreen is not added to qemu mouse event handler\n");
-        }
-    }
-#endif
-
-    int virt_sg_index = 0;
-    ElementEntry *elem_entry = NULL;
-
-    TRACE("maru_virtio_touchscreen_handle\n");
-
-    if (unlikely(virtio_queue_empty(ts->vq))) {
-        TRACE("virtqueue is empty\n");
-        return;
-    }
-
-    while (true) {
-        elem_entry = &(_elem_buf[elem_ringbuf_cnt % 10]);
-        elem_ringbuf_cnt++;
-
-        virt_sg_index = virtqueue_pop(ts->vq, &elem_entry->elem);
-        if (virt_sg_index == 0) {
-            elem_ringbuf_cnt--;
-            break;
-        } else if (virt_sg_index < 0) {
-            ERR("virtqueue is broken\n");
-            elem_ringbuf_cnt--;
-            return;
-        }
-
-        pthread_mutex_lock(&elem_mutex);
-
-        elem_entry->el_index = ++elem_queue_cnt;
-        elem_entry->sg_index = (unsigned int)virt_sg_index;
-
-        /* save VirtQueueElement */
-        QTAILQ_INSERT_TAIL(&elem_queue, elem_entry, node);
-
-        if (ts->waitBuf == true) {
-            ts->waitBuf = false;
-
-            /* call maru_virtio_touchscreen_notify */
-            qemu_bh_schedule(ts->bh);
-        }
-
-        pthread_mutex_unlock(&elem_mutex);
-    }
-}
-
-void maru_virtio_touchscreen_notify(void)
-{
-    ElementEntry *elem_entry = NULL;
-    unsigned int ii = 0;
-
-    TRACE("maru_virtio_touchscreen_notify\n");
-
-    if (unlikely(!virtio_queue_ready(ts->vq))) {
-        ERR("virtio queue is not ready\n");
-        return;
-    }
-
-    while (true) {
-        if (event_queue_cnt == 0) {
-            TRACE("no event\n");
-            break;
-        } else if (elem_queue_cnt == 0) {
-            TRACE("no buffer\n");
-
-            pthread_mutex_lock(&elem_mutex);
-            /* maybe next time */
-            ts->waitBuf = true;
-            pthread_mutex_unlock(&elem_mutex);
-            break;
-        }
-
-        elem_entry = QTAILQ_FIRST(&elem_queue);
-
-        if (elem_entry->sg_index > 0) {
-            TouchEventEntry *event_entry = NULL;
-            VirtQueueElement *element = NULL;
-            void *vbuf = NULL;
-
-            element = &elem_entry->elem;
-            vbuf = element->in_sg[elem_entry->sg_index - 1].iov_base;
-
-            /* get touch event from host queue */
-            event_entry = QTAILQ_FIRST(&events_queue);
-
-            TRACE("touch(%d) : x=%d, y=%d, z=%d, state=%d | \
-                event_queue_cnt=%d, elem.index=%d, elem.in_num=%d, sg_index=%d\n",
-                event_entry->index, event_entry->touch.x, event_entry->touch.y,
-                event_entry->touch.z, event_entry->touch.state,
-                event_queue_cnt, element->index, element->in_num,
-                elem_entry->sg_index);
-
-            /* copy event into virtio buffer */
-            memcpy(vbuf, &(event_entry->touch), sizeof(event_entry->touch));
-
-            pthread_mutex_lock(&event_mutex);
-
-            /* remove host event */
-            QTAILQ_REMOVE(&events_queue, event_entry, node);
-            event_queue_cnt--;
-
-            pthread_mutex_unlock(&event_mutex);
-
-            /* put buffer into virtio queue */
-            virtqueue_fill(ts->vq, element, sizeof(EmulTouchEvent), ii++);
-        }
-
-        pthread_mutex_lock(&elem_mutex);
-
-        QTAILQ_REMOVE(&elem_queue, elem_entry, node);
-        elem_queue_cnt--;
-
-        pthread_mutex_unlock(&elem_mutex);
-    }
-
-    if (ii != 0) {
-        /* signal other side */
-        virtqueue_flush(ts->vq, ii);
-        /* notify to guest */
-        virtio_notify(&(ts->vdev), ts->vq);
-    }
-}
-
-static void virtio_touchscreen_get_config(
-    VirtIODevice *vdev, uint8_t *config_data)
-{
-    int max_trkid = 10;
-    INFO("virtio_touchscreen_get_config\n");
-
-    max_trkid = get_emul_max_touch_point();
-    memcpy(config_data, &max_trkid, 4);
-}
-
-static void virtio_touchscreen_set_config(
-    VirtIODevice *vdev, const uint8_t *config_data)
-{
-    /* do nothing */
-}
-
-static uint32_t virtio_touchscreen_get_features(
-    VirtIODevice *vdev, uint32_t request_features)
-{
-    /* do nothing */
-
-    return request_features;
-}
-
-static void maru_touchscreen_bh(void *opaque)
-{
-    //TouchscreenState *ts = (TouchscreenState *)opaque;
-
-    maru_virtio_touchscreen_notify();
-}
-
-static void virtio_touchscreen_device_realize(DeviceState *dev, Error **errp)
-{
-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-    ts = VIRTIO_TOUCHSCREEN(dev);
-
-    INFO("initialize touchscreen device : %d\n", ts->max_finger);
-
-    virtio_init(vdev, DEVICE_NAME, VIRTIO_ID_TOUCHSCREEN, 4);
-    /*if (ts == NULL) {
-        ERR("failed to initialize the touchscreen device\n");
-        return NULL;
-    }*/
-
-    // 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);
-}
-
-static void virtio_touchscreen_device_unrealize(DeviceState *dev, Error **errp)
-{
-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-
-    INFO("exit the touchscreen device\n");
-
-    if (ts->bh) {
-        qemu_bh_delete(ts->bh);
-    }
-
-    virtio_cleanup(vdev);
-
-    pthread_mutex_destroy(&event_mutex);
-    pthread_mutex_destroy(&elem_mutex);
-}
-
-static Property virtio_touchscreen_properties[] = {
-    DEFINE_PROP_END_OF_LIST(),
-};
-
-static void virtio_touchscreen_device_reset(VirtIODevice *vdev)
-{
-    TouchEventEntry *event_entry = NULL;
-    ElementEntry *elem_entry = NULL;
-
-    INFO("reset the touchscreen device\n");
-
-    /* reset the counters */
-    event_ringbuf_cnt = 0;
-    elem_ringbuf_cnt = 0;
-
-    /* reset queue */
-    pthread_mutex_lock(&event_mutex);
-    while (event_queue_cnt > 0) {
-        event_entry = QTAILQ_FIRST(&events_queue);
-        QTAILQ_REMOVE(&events_queue, event_entry, node);
-
-        event_queue_cnt--;
-    }
-    pthread_mutex_unlock(&event_mutex);
-
-    pthread_mutex_lock(&elem_mutex);
-    while (elem_queue_cnt > 0) {
-        elem_entry = QTAILQ_FIRST(&elem_queue);
-        QTAILQ_REMOVE(&elem_queue, elem_entry, node);
-
-        elem_queue_cnt--;
-    }
-
-    ts->waitBuf = false;
-    pthread_mutex_unlock(&elem_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_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)
diff --git a/tizen/src/hw/maru_virtio_touchscreen.h b/tizen/src/hw/maru_virtio_touchscreen.h
deleted file mode 100644 (file)
index 042c577..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Maru Virtio Touchscreen Device
- *
- * Copyright (c) 2011 - 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_TOUCHSCREEN_H_
-#define MARU_TOUCHSCREEN_H_
-
-#include "hw/virtio/virtio.h"
-
-#define TYPE_VIRTIO_TOUCHSCREEN "virtio-touchscreen-device"
-#define VIRTIO_TOUCHSCREEN(obj) \
-        OBJECT_CHECK(VirtIOTouchscreen, (obj), TYPE_VIRTIO_TOUCHSCREEN)
-
-#define TOUCHSCREEN_OPTION_NAME "max_point"
-#define DEFAULT_MAX_FINGER (1)
-
-typedef struct VirtIOTouchscreen {
-    VirtIODevice vdev;
-    /* simply a queue into which buffers are posted
-    by the guest for consumption by the host */
-    VirtQueue *vq;
-    bool waitBuf;
-
-    QEMUBH *bh;
-    DeviceState *qdev;
-
-    unsigned int max_finger;
-} VirtIOTouchscreen;
-
-/* This structure must match the kernel definitions */
-typedef struct EmulTouchEvent {
-    uint16_t x, y, z;
-    uint8_t state;
-} EmulTouchEvent;
-
-void virtio_touchscreen_event(int x, int y, int z, int buttons_state);
-void maru_virtio_touchscreen_notify(void);
-
-#endif /* MARU_TOUCHSCREEN_H_ */
diff --git a/tizen/src/hw/maru_virtio_vmodem.c b/tizen/src/hw/maru_virtio_vmodem.c
deleted file mode 100644 (file)
index bb4e4d5..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * Virtio Virtual Modem Device
- *
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Sooyoung Ha <yoosah.ha@samsung.com>
- *  SeokYeon Hwang <syeon.hwang@samsung.com>
- *  Sangho Park <sangho1206.park@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 "maru_device_ids.h"
-#include "maru_virtio_vmodem.h"
-#include "maru_virtio_evdi.h"
-#include "debug_ch.h"
-#include "ecs/ecs.h"
-
-MULTI_DEBUG_CHANNEL(qemu, virtio-vmodem);
-
-#define VMODEM_DEVICE_NAME "virtio-vmodem"
-
-enum {
-    IOTYPE_INPUT = 0,
-    IOTYPE_OUTPUT = 1
-};
-
-#ifndef min
-#define min(a,b) ((a)<(b)?(a):(b))
-#endif
-
-VirtIOVModem *vio_vmodem;
-
-typedef struct MsgInfo
-{
-    msg_info info;
-    QTAILQ_ENTRY(MsgInfo) next;
-}MsgInfo;
-
-static QTAILQ_HEAD(MsgInfoRecvHead , MsgInfo) vmodem_recv_msg_queue =
-    QTAILQ_HEAD_INITIALIZER(vmodem_recv_msg_queue);
-
-typedef struct EvdiBuf {
-    VirtQueueElement elem;
-
-    QTAILQ_ENTRY(EvdiBuf) next;
-} EvdiBuf;
-
-static QTAILQ_HEAD(EvdiMsgHead , EvdiBuf) vmodem_in_queue =
-    QTAILQ_HEAD_INITIALIZER(vmodem_in_queue);
-
-bool send_to_vmodem(const uint32_t route, char *data, const uint32_t len)
-{
-    int size;
-    int left = len;
-    int count = 0;
-    char *readptr = data;
-
-    while (left > 0) {
-        MsgInfo *_msg = (MsgInfo*) malloc(sizeof(MsgInfo));
-        if (!_msg) {
-            ERR("malloc failed\n");
-            return false;
-        }
-
-        memset(&_msg->info, 0, sizeof(msg_info));
-
-        size = min(left, __MAX_BUF_SIZE);
-        memcpy(_msg->info.buf, readptr, size);
-        readptr += size;
-        _msg->info.use = size;
-        _msg->info.index = count;
-
-        qemu_mutex_lock(&vio_vmodem->mutex);
-
-        QTAILQ_INSERT_TAIL(&vmodem_recv_msg_queue, _msg, next);
-
-        qemu_mutex_unlock(&vio_vmodem->mutex);
-
-        left -= size;
-        count ++;
-    }
-
-    qemu_bh_schedule(vio_vmodem->bh);
-
-    return true;
-}
-
-static void flush_vmodem_recv_queue(void)
-{
-    int index;
-
-    if (unlikely(!virtio_queue_ready(vio_vmodem->rvq))) {
-        ERR("virtio queue is not ready\n");
-        return;
-    }
-
-    if (unlikely(virtio_queue_empty(vio_vmodem->rvq))) {
-        ERR("virtqueue is empty\n");
-        return;
-    }
-
-    qemu_mutex_lock(&vio_vmodem->mutex);
-
-    while (!QTAILQ_EMPTY(&vmodem_recv_msg_queue))
-    {
-        MsgInfo *msginfo = QTAILQ_FIRST(&vmodem_recv_msg_queue);
-        if (!msginfo)
-            break;
-
-        VirtQueueElement elem;
-        index = virtqueue_pop(vio_vmodem->rvq, &elem);
-        if (index == 0) {
-            break;
-        }
-
-        memset(elem.in_sg[0].iov_base, 0, elem.in_sg[0].iov_len);
-        memcpy(elem.in_sg[0].iov_base, &msginfo->info, sizeof(struct msg_info));
-
-        virtqueue_push(vio_vmodem->rvq, &elem, sizeof(msg_info));
-        virtio_notify(&vio_vmodem->vdev, vio_vmodem->rvq);
-
-        QTAILQ_REMOVE(&vmodem_recv_msg_queue, msginfo, next);
-        if (msginfo)
-            free(msginfo);
-    }
-    qemu_mutex_unlock(&vio_vmodem->mutex);
-}
-
-
-static void virtio_vmodem_recv(VirtIODevice *vdev, VirtQueue *vq)
-{
-    flush_vmodem_recv_queue();
-}
-
-static void virtio_vmodem_send(VirtIODevice *vdev, VirtQueue *vq)
-{
-    VirtIOVModem *vvmodem = (VirtIOVModem *)vdev;
-    int index = 0;
-    struct msg_info _msg;
-
-    if (virtio_queue_empty(vvmodem->svq)) {
-        ERR("virtqueue is empty.\n");
-        return;
-    }
-
-    VirtQueueElement elem;
-
-    while ((index = virtqueue_pop(vq, &elem))) {
-        memset(&_msg, 0x00, sizeof(_msg));
-        memcpy(&_msg, elem.out_sg[0].iov_base, elem.out_sg[0].iov_len);
-
-        TRACE("vmodem send to ecp.\n");
-        send_injector_ntf(_msg.buf, _msg.use);
-    }
-
-    virtqueue_push(vq, &elem, sizeof(VirtIOVModem));
-    virtio_notify(&vio_vmodem->vdev, vq);
-}
-
-static uint32_t virtio_vmodem_get_features(VirtIODevice *vdev,
-                                            uint32_t request_feature)
-{
-    TRACE("virtio_vmodem_get_features.\n");
-    return 0;
-}
-
-static void maru_vmodem_bh(void *opaque)
-{
-    flush_vmodem_recv_queue();
-}
-
-static void virtio_vmodem_realize(DeviceState *dev, Error **errp)
-{
-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-
-    vio_vmodem = VIRTIO_VMODEM(vdev);
-
-    if (vio_vmodem == NULL) {
-        ERR("failed to initialize vmodem device\n");
-        return;
-    }
-
-    virtio_init(vdev, TYPE_VIRTIO_VMODEM, VIRTIO_ID_VMODEM, 0); //VMODEM_DEVICE_NAME
-    qemu_mutex_init(&vio_vmodem->mutex);
-
-    vio_vmodem->rvq = virtio_add_queue(&vio_vmodem->vdev, 256, virtio_vmodem_recv);
-    vio_vmodem->svq = virtio_add_queue(&vio_vmodem->vdev, 256, virtio_vmodem_send);
-    vio_vmodem->qdev = dev;
-
-    vio_vmodem->bh = qemu_bh_new(maru_vmodem_bh, vio_vmodem);
-
-    INFO("finish the vmodem device initialization.\n");
-}
-
-static void virtio_vmodem_unrealize(DeviceState *dev, Error **errp)
-{
-    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
-
-    INFO("destroy vmodem device\n");
-
-    if (vio_vmodem->bh) {
-        qemu_bh_delete(vio_vmodem->bh);
-    }
-
-    qemu_mutex_destroy(&vio_vmodem->mutex);
-    virtio_cleanup(vdev);
-}
-
-static void virtio_vmodem_reset(VirtIODevice *vdev)
-{
-    INFO("virtio_vmodem_reset.\n");
-}
-
-
-static void virtio_vmodem_class_init(ObjectClass *klass, void *data)
-{
-    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
-    vdc->realize = virtio_vmodem_realize;
-    vdc->unrealize = virtio_vmodem_unrealize;
-    vdc->get_features = virtio_vmodem_get_features;
-    vdc->reset = virtio_vmodem_reset;
-}
-
-
-
-static const TypeInfo virtio_device_info = {
-    .name = TYPE_VIRTIO_VMODEM,
-    .parent = TYPE_VIRTIO_DEVICE,
-    .instance_size = sizeof(VirtIOVModem),
-    .class_init = virtio_vmodem_class_init,
-};
-
-static void virtio_register_types(void)
-{
-    type_register_static(&virtio_device_info);
-}
-
-type_init(virtio_register_types)
diff --git a/tizen/src/hw/maru_virtio_vmodem.h b/tizen/src/hw/maru_virtio_vmodem.h
deleted file mode 100644 (file)
index 6248296..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Virtio Virtual Modem Device
- *
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Sooyoung Ha <yoosah.ha@samsung.com>
- *  SeokYeon Hwang <syeon.hwang@samsung.com>
- *  Sangho Park <sangho1206.park@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_VIRTIO_VMODEM_H_
-#define MARU_VIRTIO_VMODEM_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "hw/virtio/virtio.h"
-
-typedef struct VirtIOVirtualModem{
-    VirtIODevice    vdev;
-    VirtQueue       *rvq;
-    VirtQueue       *svq;
-    DeviceState     *qdev;
-
-    QemuMutex mutex;
-    QEMUBH *bh;
-} VirtIOVModem;
-
-#define TYPE_VIRTIO_VMODEM "virtio-vmodem-device"
-#define VIRTIO_VMODEM(obj) \
-        OBJECT_CHECK(VirtIOVModem, (obj), TYPE_VIRTIO_VMODEM)
-
-bool send_to_vmodem(const uint32_t route, char *data, const uint32_t len);
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* MARU_VIRTIO_VMODEM_H_ */
diff --git a/tizen/src/hw/pci/Makefile.objs b/tizen/src/hw/pci/Makefile.objs
new file mode 100644 (file)
index 0000000..7d142a3
--- /dev/null
@@ -0,0 +1,19 @@
+obj-y += maru_brill_codec.o
+obj-y += maru_brightness.o
+
+obj-y += maru_camera_common_pci.o
+ifdef CONFIG_LINUX
+obj-y += maru_camera_linux_pci.o
+LIBS += -lv4l2 -lv4lconvert
+endif
+ifdef CONFIG_WIN32
+obj-y += maru_camera_win32_pci.o
+LIBS += -lole32 -loleaut32 -luuid -lstrmiids
+endif
+ifdef CONFIG_DARWIN
+obj-y += maru_camera_darwin_converter.o
+obj-y += maru_camera_darwin_pci.o
+LIBS += -framework Foundation -framework SystemConfiguration
+LIBS += -framework Cocoa -framework QTKit -framework CoreVideo
+LIBS += -framework AppKit
+endif
diff --git a/tizen/src/hw/pci/maru_brightness.c b/tizen/src/hw/pci/maru_brightness.c
new file mode 100644 (file)
index 0000000..7cc309f
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * Maru brightness device for VGA
+ *
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * JinHyung Jo <jinhyung.jo@samsung.com>
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ * DongKyun Yun
+ * DoHyung Hong
+ * Hyunjun Son
+ *
+ * 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 "hw/i386/pc.h"
+#include "ui/console.h"
+#include "hw/pci/pci.h"
+#include "hw/maru_device_ids.h"
+#include "maru_brightness.h"
+#include "skin/maruskin_server.h"
+#include "debug_ch.h"
+
+MULTI_DEBUG_CHANNEL(tizen, maru-brightness);
+
+#define QEMU_DEV_NAME           "maru-brightness"
+
+#define BRIGHTNESS_MEM_SIZE    (4 * 1024)    /* 4KB */
+#define BRIGHTNESS_REG_SIZE    256
+
+typedef struct BrightnessState {
+    PCIDevice       dev;
+    MemoryRegion    mmio_addr;
+} BrightnessState;
+
+enum {
+    BRIGHTNESS_LEVEL = 0x00,
+    BRIGHTNESS_OFF = 0x04,
+};
+
+uint32_t brightness_level = BRIGHTNESS_MAX;
+bool display_off;
+pixman_color_t level_color;
+pixman_image_t *brightness_image;
+
+/* level : 1 ~ 100, interval : 1 or 2 */
+uint8_t brightness_tbl[] = {155, /* level 0 : for dimming */
+/* level 01 ~ 10 */         149, 147, 146, 144, 143, 141, 140, 138, 137, 135,
+/* level 11 ~ 20 */         134, 132, 131, 129, 128, 126, 125, 123, 122, 120,
+/* level 21 ~ 30 */         119, 117, 116, 114, 113, 111, 110, 108, 107, 105,
+/* level 31 ~ 40 */         104, 102, 101,  99,  98,  96,  95,  93,  92,  90,
+/* level 41 ~ 50 */          89,  87,  86,  84,  83,  81,  80,  78,  77,  75,
+/* level 51 ~ 60 */          74,  72,  71,  69,  68,  66,  65,  63,  62,  60,
+/* level 61 ~ 70 */          59,  57,  56,  54,  53,  51,  50,  48,  47,  45,
+/* level 71 ~ 80 */          44,  42,  41,  39,  38,  36,  35,  33,  32,  30,
+/* level 81 ~ 90 */          29,  27,  26,  24,  23,  21,  20,  18,  17,  15,
+/* level 91 ~ 99 */          14,  12,  11,   9,   8,   6,   5,   3,   2,   0};
+
+QEMUBH *display_bh;
+
+static uint64_t brightness_reg_read(void *opaque,
+                                    hwaddr addr,
+                                    unsigned size)
+{
+    switch (addr & 0xFF) {
+    case BRIGHTNESS_LEVEL:
+        INFO("current brightness level = %lu\n", brightness_level);
+        return brightness_level;
+    case BRIGHTNESS_OFF:
+        INFO("device is turned %s\n", display_off ? "off" : "on");
+        return display_off;
+    default:
+        ERR("wrong brightness register read - addr : %d\n", (int)addr);
+        break;
+    }
+
+    return 0;
+}
+
+static void maru_pixman_image_set_alpha(uint8_t value)
+{
+    if (brightness_image) {
+        pixman_image_unref(brightness_image);
+    }
+    level_color.alpha = value << 8;
+    brightness_image = pixman_image_create_solid_fill(&level_color);
+
+    graphic_hw_invalidate(NULL);
+}
+
+static void brightness_reg_write(void *opaque,
+                                 hwaddr addr,
+                                 uint64_t val,
+                                 unsigned size)
+{
+    switch (addr & 0xFF) {
+    case BRIGHTNESS_LEVEL:
+        if (brightness_level == val) {
+            return;
+        }
+#if BRIGHTNESS_MIN > 0
+        if (val < BRIGHTNESS_MIN || val > BRIGHTNESS_MAX) {
+#else
+        if (val > BRIGHTNESS_MAX) {
+#endif
+            ERR("input value is out of range(%llu)\n", val);
+        } else {
+            INFO("level changes: %lu -> %llu\n", brightness_level, val);
+            brightness_level = val;
+            maru_pixman_image_set_alpha(brightness_tbl[brightness_level]);
+        }
+        return;
+    case BRIGHTNESS_OFF:
+        if (display_off == val) {
+            return;
+        }
+
+        INFO("status changes: %s\n", val ? "OFF" : "ON");
+
+        display_off = val;
+        if (display_off) {
+            maru_pixman_image_set_alpha(0xFF); /* set black */
+        } else {
+            maru_pixman_image_set_alpha(brightness_tbl[brightness_level]);
+        }
+
+        /* notify to skin process */
+        qemu_bh_schedule(display_bh);
+
+        return;
+    default:
+        ERR("wrong brightness register write - addr : %d\n", (int)addr);
+        break;
+    }
+}
+
+static const MemoryRegionOps brightness_mmio_ops = {
+    .read = brightness_reg_read,
+    .write = brightness_reg_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void brightness_exitfn(PCIDevice *dev)
+{
+    BrightnessState *s = DO_UPCAST(BrightnessState, dev, dev);
+
+    if (display_bh) {
+        qemu_bh_delete(display_bh);
+    }
+    if (brightness_image) {
+        pixman_image_unref(brightness_image);
+        brightness_image = NULL;
+    }
+
+    memory_region_destroy(&s->mmio_addr);
+    INFO("finalize maru-brightness device\n");
+}
+
+static void maru_display_bh(void *opaque)
+{
+    notify_display_power(!display_off);
+}
+
+static int brightness_initfn(PCIDevice *dev)
+{
+    BrightnessState *s = DO_UPCAST(BrightnessState, dev, dev);
+    uint8_t *pci_conf = s->dev.config;
+
+    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_TIZEN);
+    pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_VIRTUAL_BRIGHTNESS);
+    pci_config_set_class(pci_conf, PCI_CLASS_DISPLAY_OTHER);
+
+    memory_region_init_io(&s->mmio_addr, OBJECT(s), &brightness_mmio_ops, s,
+                            "maru-brightness-mmio", BRIGHTNESS_REG_SIZE);
+    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio_addr);
+
+    display_bh = qemu_bh_new(maru_display_bh, s);
+    brightness_level = BRIGHTNESS_MAX;
+    level_color.alpha = 0x0000;
+    level_color.red = 0x0000;
+    level_color.green = 0x0000;
+    level_color.blue = 0x0000;
+    brightness_image = pixman_image_create_solid_fill(&level_color);
+    INFO("initialize maru-brightness device\n");
+
+    return 0;
+}
+
+static void brightness_classinit(ObjectClass *klass, void *data)
+{
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = brightness_initfn;
+    k->exit = brightness_exitfn;
+}
+
+static TypeInfo brightness_info = {
+    .name = QEMU_DEV_NAME,
+    .parent = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(BrightnessState),
+    .class_init = brightness_classinit,
+};
+
+static void brightness_register_types(void)
+{
+    type_register_static(&brightness_info);
+}
+
+type_init(brightness_register_types);
diff --git a/tizen/src/hw/pci/maru_brightness.h b/tizen/src/hw/pci/maru_brightness.h
new file mode 100644 (file)
index 0000000..96f081a
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Maru brightness device for VGA
+ *
+ * Copyright (C) 2011 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Jinhyung Jo <jinhyung.jo@samsung.com>
+ * GiWoong Kim <giwoong.kim@samsung.com>
+ * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ * Hyunjun Son
+ *
+ * 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_BRIGHTNESS_H_
+#define MARU_BRIGHTNESS_H_
+
+#include "qemu-common.h"
+#include "ui/qemu-pixman.h"
+
+#define BRIGHTNESS_MIN          (0)
+#define BRIGHTNESS_MAX          (100)
+
+extern uint32_t brightness_level;
+extern bool display_off;
+extern uint8_t brightness_tbl[];
+extern pixman_image_t *brightness_image;
+
+#endif /* MARU_BRIGHTNESS_H_ */
diff --git a/tizen/src/hw/pci/maru_brill_codec.c b/tizen/src/hw/pci/maru_brill_codec.c
new file mode 100644 (file)
index 0000000..2287bcb
--- /dev/null
@@ -0,0 +1,2006 @@
+/*
+ * Virtual Codec Device
+ *
+ * Copyright (c) 2013 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Kitae Kim <kt920.kim@samsung.com>
+ *  SeokYeon Hwang <syeon.hwang@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 "maru_brill_codec.h"
+
+/* define debug channel */
+MULTI_DEBUG_CHANNEL(qemu, brillcodec);
+
+// device
+#define CODEC_DEVICE_NAME   "codec-pci"
+#define CODEC_DEVICE_THREAD "codec-workthread"
+#define CODEC_VERSION       2
+
+// device memory
+#define CODEC_META_DATA_SIZE    (256)
+
+#define CODEC_MEM_SIZE          (32 * 1024 * 1024)
+#define CODEC_REG_SIZE          (256)
+
+// libav
+#define GEN_MASK(x) ((1 << (x)) - 1)
+#define ROUND_UP_X(v, x) (((v) + GEN_MASK(x)) & ~GEN_MASK(x))
+#define ROUND_UP_2(x) ROUND_UP_X(x, 1)
+#define ROUND_UP_4(x) ROUND_UP_X(x, 2)
+#define ROUND_UP_8(x) ROUND_UP_X(x, 3)
+#define DIV_ROUND_UP_X(v, x) (((v) + GEN_MASK(x)) >> (x))
+
+#define DEFAULT_VIDEO_GOP_SIZE 15
+
+
+// define a queue to manage ioparam, context data
+typedef struct DeviceMemEntry {
+    uint8_t *buf;
+    uint32_t buf_size;
+    uint32_t ctx_id;
+
+    QTAILQ_ENTRY(DeviceMemEntry) node;
+} DeviceMemEntry;
+
+typedef struct CodecDataStg {
+    CodecParam *param_buf;
+    DeviceMemEntry *data_buf;
+
+    QTAILQ_ENTRY(CodecDataStg) node;
+} CodecDataStg;
+
+// define two queue to store input and output buffers.
+static QTAILQ_HEAD(codec_wq, DeviceMemEntry) codec_wq =
+   QTAILQ_HEAD_INITIALIZER(codec_wq);
+
+static QTAILQ_HEAD(codec_rq, CodecDataStg) codec_rq =
+   QTAILQ_HEAD_INITIALIZER(codec_rq);
+
+static DeviceMemEntry *entry[CODEC_CONTEXT_MAX];
+
+// pixel info
+typedef struct PixFmtInfo {
+    uint8_t x_chroma_shift;
+    uint8_t y_chroma_shift;
+} PixFmtInfo;
+
+static PixFmtInfo pix_fmt_info[PIX_FMT_NB];
+
+// thread
+#define DEFAULT_WORKER_THREAD_CNT 8
+
+static void *maru_brill_codec_threads(void *opaque);
+
+// static void maru_brill_codec_reset_parser_info(MaruBrillCodecState *s, int32_t ctx_index);
+static int maru_brill_codec_query_list(MaruBrillCodecState *s);
+static void maru_brill_codec_release_context(MaruBrillCodecState *s, int32_t value);
+
+// codec functions
+static bool codec_init(MaruBrillCodecState *, int, void *);
+static bool codec_deinit(MaruBrillCodecState *, int, void *);
+static bool codec_decode_video(MaruBrillCodecState *, int, void *);
+static bool codec_encode_video(MaruBrillCodecState *, int, void *);
+static bool codec_decode_audio(MaruBrillCodecState *, int, void *);
+static bool codec_encode_audio(MaruBrillCodecState *, int, void *);
+static bool codec_picture_copy(MaruBrillCodecState *, int, void *);
+static bool codec_flush_buffers(MaruBrillCodecState *, int, void *);
+
+typedef bool (*CodecFuncEntry)(MaruBrillCodecState *, int, void *);
+static CodecFuncEntry codec_func_handler[] = {
+    codec_init,
+    codec_decode_video,
+    codec_encode_video,
+    codec_decode_audio,
+    codec_encode_audio,
+    codec_picture_copy,
+    codec_deinit,
+    codec_flush_buffers,
+};
+
+static AVCodecParserContext *maru_brill_codec_parser_init(AVCodecContext *avctx);
+
+static void maru_brill_codec_pop_writequeue(MaruBrillCodecState *s, uint32_t ctx_idx);
+static void maru_brill_codec_push_readqueue(MaruBrillCodecState *s, CodecParam *ioparam);
+static void maru_brill_codec_push_writequeue(MaruBrillCodecState *s, void* buf,
+                                            uint32_t buf_size, int ctx_id);
+
+static void *maru_brill_codec_store_inbuf(uint8_t *mem_base, CodecParam *ioparam);
+
+static void maru_brill_codec_reset(DeviceState *s);
+
+static void maru_brill_codec_get_cpu_cores(MaruBrillCodecState *s)
+{
+    s->worker_thread_cnt = get_number_of_processors();
+    if (s->worker_thread_cnt < DEFAULT_WORKER_THREAD_CNT) {
+        s->worker_thread_cnt = DEFAULT_WORKER_THREAD_CNT;
+    }
+
+    TRACE("number of threads: %d\n", s->worker_thread_cnt);
+}
+
+static void maru_brill_codec_threads_create(MaruBrillCodecState *s)
+{
+    int index;
+    QemuThread *pthread = NULL;
+
+    TRACE("enter: %s\n", __func__);
+
+    pthread = g_malloc(sizeof(QemuThread) * s->worker_thread_cnt);
+    if (!pthread) {
+        ERR("failed to allocate threadpool memory.\n");
+        return;
+    }
+
+    qemu_cond_init(&s->threadpool.cond);
+    qemu_mutex_init(&s->threadpool.mutex);
+
+    s->is_thread_running = true;
+
+    qemu_mutex_lock(&s->context_mutex);
+    s->idle_thread_cnt = 0;
+    qemu_mutex_unlock(&s->context_mutex);
+
+    for (index = 0; index < s->worker_thread_cnt; index++) {
+        qemu_thread_create(&pthread[index], CODEC_DEVICE_THREAD,
+            maru_brill_codec_threads, (void *)s, QEMU_THREAD_JOINABLE);
+    }
+
+    s->threadpool.threads = pthread;
+
+    TRACE("leave: %s\n", __func__);
+}
+
+static void maru_brill_codec_thread_exit(MaruBrillCodecState *s)
+{
+    int index;
+
+    TRACE("enter: %s\n", __func__);
+
+    /* stop to run dedicated threads. */
+    s->is_thread_running = false;
+
+    for (index = 0; index < s->worker_thread_cnt; index++) {
+        qemu_thread_join(&s->threadpool.threads[index]);
+    }
+
+    TRACE("destroy mutex and conditional.\n");
+    qemu_mutex_destroy(&s->threadpool.mutex);
+    qemu_cond_destroy(&s->threadpool.cond);
+
+    if (s->threadpool.threads) {
+        g_free(s->threadpool.threads);
+        s->threadpool.threads = NULL;
+    }
+
+    TRACE("leave: %s\n", __func__);
+}
+
+static void maru_brill_codec_wakeup_threads(MaruBrillCodecState *s, int api_index)
+{
+    CodecParam *ioparam = NULL;
+
+    ioparam = g_malloc0(sizeof(CodecParam));
+    if (!ioparam) {
+        ERR("failed to allocate ioparam\n");
+        return;
+    }
+
+    memcpy(ioparam, &s->ioparam, sizeof(CodecParam));
+
+    TRACE("wakeup thread. ctx_id: %u, api_id: %u, mem_offset: 0x%x\n",
+        ioparam->ctx_index, ioparam->api_index, ioparam->mem_offset);
+
+    qemu_mutex_lock(&s->context_mutex);
+
+    if (ioparam->api_index != CODEC_INIT) {
+        if (!s->context[ioparam->ctx_index].opened_context) {
+            INFO("abandon api %d for context %d\n",
+                    ioparam->api_index, ioparam->ctx_index);
+            qemu_mutex_unlock(&s->context_mutex);
+            return;
+        }
+    }
+
+    qemu_mutex_unlock(&s->context_mutex);
+
+    maru_brill_codec_push_readqueue(s, ioparam);
+
+    qemu_mutex_lock(&s->context_mutex);
+    // W/A for threads starvation.
+    while (s->idle_thread_cnt == 0) {
+        qemu_mutex_unlock(&s->context_mutex);
+        TRACE("Worker threads are exhausted\n");
+        usleep(2000); // wait 2ms.
+        qemu_mutex_lock(&s->context_mutex);
+    }
+    qemu_cond_signal(&s->threadpool.cond);
+    qemu_mutex_unlock(&s->context_mutex);
+
+    TRACE("after sending conditional signal\n");
+}
+
+static void *maru_brill_codec_threads(void *opaque)
+{
+    MaruBrillCodecState *s = (MaruBrillCodecState *)opaque;
+    bool ret = false;
+
+    TRACE("enter: %s\n", __func__);
+
+    while (s->is_thread_running) {
+        int ctx_id = 0, api_id = 0;
+        CodecDataStg *elem = NULL;
+        DeviceMemEntry *indata_buf = NULL;
+
+        qemu_mutex_lock(&s->context_mutex);
+        ++(s->idle_thread_cnt); // protected under mutex.
+        qemu_cond_wait(&s->threadpool.cond, &s->context_mutex);
+        --(s->idle_thread_cnt); // protected under mutex.
+        qemu_mutex_unlock(&s->context_mutex);
+
+        qemu_mutex_lock(&s->ioparam_queue_mutex);
+        elem = QTAILQ_FIRST(&codec_rq);
+        if (elem) {
+            QTAILQ_REMOVE(&codec_rq, elem, node);
+            qemu_mutex_unlock(&s->ioparam_queue_mutex);
+        } else {
+            qemu_mutex_unlock(&s->ioparam_queue_mutex);
+            continue;
+        }
+
+        if (!elem->param_buf) {
+            continue;
+        }
+
+        api_id = elem->param_buf->api_index;
+        ctx_id = elem->param_buf->ctx_index;
+        indata_buf = elem->data_buf;
+
+        TRACE("api_id: %d ctx_id: %d\n", api_id, ctx_id);
+
+        qemu_mutex_lock(&s->context_mutex);
+        s->context[ctx_id].occupied_thread = true;
+        qemu_mutex_unlock(&s->context_mutex);
+
+        ret = codec_func_handler[api_id](s, ctx_id, indata_buf);
+        if (!ret) {
+            ERR("fail api %d for context %d\n", api_id, ctx_id);
+            g_free(elem->param_buf);
+            continue;
+        }
+
+        TRACE("release a buffer of CodecParam\n");
+        g_free(elem->param_buf);
+        elem->param_buf = NULL;
+
+        if (elem->data_buf) {
+            if (elem->data_buf->buf) {
+                TRACE("release inbuf\n");
+                g_free(elem->data_buf->buf);
+                elem->data_buf->buf = NULL;
+            }
+
+            TRACE("release a buffer indata_buf\n");
+            g_free(elem->data_buf);
+            elem->data_buf = NULL;
+        }
+
+        TRACE("release an element of CodecDataStg\n");
+        g_free(elem);
+
+        qemu_mutex_lock(&s->context_mutex);
+        if (s->context[ctx_id].requested_close) {
+            INFO("make worker thread to handle deinit\n");
+            // codec_deinit(s, ctx_id, NULL);
+            maru_brill_codec_release_context(s, ctx_id);
+            s->context[ctx_id].requested_close = false;
+        }
+        qemu_mutex_unlock(&s->context_mutex);
+
+        TRACE("switch context to raise interrupt.\n");
+        qemu_bh_schedule(s->codec_bh);
+
+        qemu_mutex_lock(&s->context_mutex);
+        s->context[ctx_id].occupied_thread = false;
+        qemu_mutex_unlock(&s->context_mutex);
+    }
+
+    maru_brill_codec_thread_exit(s);
+
+    TRACE("leave: %s\n", __func__);
+    return NULL;
+}
+
+// queue
+static void maru_brill_codec_push_readqueue(MaruBrillCodecState *s,
+                                            CodecParam *ioparam)
+{
+    CodecDataStg *elem = NULL;
+    DeviceMemEntry *data_buf = NULL;
+
+    elem = g_malloc0(sizeof(CodecDataStg));
+    if (!elem) {
+        ERR("failed to allocate ioparam_queue. %d\n", sizeof(CodecDataStg));
+        return;
+    }
+
+    elem->param_buf = ioparam;
+
+    switch(ioparam->api_index) {
+    case CODEC_INIT ... CODEC_ENCODE_AUDIO:
+        data_buf = maru_brill_codec_store_inbuf((uint8_t *)s->vaddr, ioparam);
+        break;
+    default:
+        TRACE("no buffer from guest\n");
+        break;
+    }
+
+    elem->data_buf = data_buf;
+
+    qemu_mutex_lock(&s->ioparam_queue_mutex);
+    QTAILQ_INSERT_TAIL(&codec_rq, elem, node);
+    qemu_mutex_unlock(&s->ioparam_queue_mutex);
+}
+
+static void *maru_brill_codec_store_inbuf(uint8_t *mem_base,
+                                        CodecParam *ioparam)
+{
+    DeviceMemEntry *elem = NULL;
+    int readbuf_size, size = 0;
+    uint8_t *readbuf = NULL;
+    uint8_t *device_mem = mem_base + ioparam->mem_offset;
+
+    elem = g_malloc0(sizeof(DeviceMemEntry));
+    if (!elem) {
+        ERR("failed to allocate readqueue node. size: %d\n",
+            sizeof(DeviceMemEntry));
+        return NULL;
+    }
+
+    memcpy(&readbuf_size, device_mem, sizeof(readbuf_size));
+    size = sizeof(readbuf_size);
+
+    TRACE("readbuf size: %d\n", readbuf_size);
+    if (readbuf_size <= 0) {
+        TRACE("inbuf size is 0. api_id %d, ctx_id %d, mem_offset %x\n",
+            ioparam->api_index, ioparam->ctx_index, ioparam->mem_offset);
+    } else {
+        readbuf = g_malloc0(readbuf_size);
+        if (!readbuf) {
+            ERR("failed to allocate a read buffer. size: %d\n", readbuf_size);
+        } else {
+            TRACE("copy input buffer from guest. ctx_id: %d, mem_offset: %x\n",
+                ioparam->ctx_index, ioparam->mem_offset);
+            memcpy(readbuf, device_mem + size, readbuf_size);
+        }
+    }
+    memset(device_mem, 0x00, sizeof(readbuf_size));
+
+    elem->buf = readbuf;
+    elem->buf_size = readbuf_size;
+    elem->ctx_id = ioparam->ctx_index;
+
+    return elem;
+}
+
+static void maru_brill_codec_push_writequeue(MaruBrillCodecState *s, void* buf,
+                                            uint32_t buf_size, int ctx_id)
+{
+    DeviceMemEntry *elem = NULL;
+    elem = g_malloc0(sizeof(DeviceMemEntry));
+
+    elem->buf = buf;
+    elem->buf_size = buf_size;
+    elem->ctx_id = ctx_id;
+
+    qemu_mutex_lock(&s->context_queue_mutex);
+    QTAILQ_INSERT_TAIL(&codec_wq, elem, node);
+    qemu_mutex_unlock(&s->context_queue_mutex);
+}
+
+static void maru_brill_codec_pop_writequeue(MaruBrillCodecState *s, uint32_t ctx_idx)
+{
+    DeviceMemEntry *elem = NULL;
+    uint32_t mem_offset = 0;
+
+    TRACE("enter: %s\n", __func__);
+
+    if (ctx_idx < 1 || ctx_idx > (CODEC_CONTEXT_MAX - 1)) {
+        ERR("invalid buffer index. %d\n", ctx_idx);
+        return;
+    }
+
+    TRACE("pop_writeqeue. context index: %d\n", ctx_idx);
+    elem = entry[ctx_idx];
+    if (elem) {
+        mem_offset = s->ioparam.mem_offset;
+
+        // check corrupted mem_offset
+        if (mem_offset < CODEC_MEM_SIZE) {
+            if (elem->buf) {
+                TRACE("write data %d to guest.  mem_offset: 0x%x\n",
+                        elem->buf_size, mem_offset);
+                memcpy(s->vaddr + mem_offset, elem->buf, elem->buf_size);
+
+                TRACE("release output buffer: %p\n", elem->buf);
+                g_free(elem->buf);
+            }
+        } else {
+            TRACE("mem_offset is corrupted!!\n");
+        }
+
+        TRACE("pop_writequeue. release elem: %p\n", elem);
+        g_free(elem);
+
+        entry[ctx_idx] = NULL;
+    } else {
+        TRACE("there is no buffer to copy data to guest\n");
+    }
+
+    TRACE("leave: %s\n", __func__);
+}
+
+static void serialize_video_data(const struct video_data *video,
+                                AVCodecContext *avctx)
+{
+    if (video->width) {
+        avctx->width = video->width;
+    }
+    if (video->height) {
+        avctx->height = video->height;
+    }
+    if (video->fps_n) {
+        avctx->time_base.num = video->fps_n;
+    }
+    if (video->fps_d) {
+        avctx->time_base.den = video->fps_d;
+    }
+    if (video->pix_fmt > PIX_FMT_NONE) {
+        avctx->pix_fmt = video->pix_fmt;
+    }
+    if (video->par_n) {
+        avctx->sample_aspect_ratio.num = video->par_n;
+    }
+    if (video->par_d) {
+        avctx->sample_aspect_ratio.den = video->par_d;
+    }
+    if (video->bpp) {
+        avctx->bits_per_coded_sample = video->bpp;
+    }
+    if (video->ticks_per_frame) {
+        avctx->ticks_per_frame = video->ticks_per_frame;
+    }
+
+    INFO("codec_init. video, resolution: %dx%d, framerate: %d/%d "
+        "pixel_fmt: %d sample_aspect_ratio: %d/%d bpp %d\n",
+        avctx->width, avctx->height, avctx->time_base.num,
+        avctx->time_base.den, avctx->pix_fmt, avctx->sample_aspect_ratio.num,
+        avctx->sample_aspect_ratio.den, avctx->bits_per_coded_sample);
+}
+
+static void deserialize_video_data (const AVCodecContext *avctx,
+                                    struct video_data *video)
+{
+    memset(video, 0x00, sizeof(struct video_data));
+
+    video->width = avctx->width;
+    video->height = avctx->height;
+    video->fps_n = avctx->time_base.num;
+    video->fps_d = avctx->time_base.den;
+    video->pix_fmt = avctx->pix_fmt;
+    video->par_n = avctx->sample_aspect_ratio.num;
+    video->par_d = avctx->sample_aspect_ratio.den;
+    video->bpp = avctx->bits_per_coded_sample;
+    video->ticks_per_frame = avctx->ticks_per_frame;
+}
+
+static void serialize_audio_data (const struct audio_data *audio,
+                                  AVCodecContext *avctx)
+{
+    if (audio->channels) {
+        avctx->channels = audio->channels;
+    }
+    if (audio->sample_rate) {
+        avctx->sample_rate = audio->sample_rate;
+    }
+    if (audio->block_align) {
+        avctx->block_align = audio->block_align;
+    }
+
+    if (audio->sample_fmt > AV_SAMPLE_FMT_NONE) {
+        avctx->sample_fmt = audio->sample_fmt;
+    }
+
+    INFO("codec_init. audio, channel %d sample_rate %d sample_fmt %d ch_layout %lld\n",
+        avctx->channels, avctx->sample_rate, avctx->sample_fmt, avctx->channel_layout);
+}
+
+#if 0
+static void maru_brill_codec_reset_parser_info(MaruBrillCodecState *s, int32_t ctx_index)
+{
+    s->context[ctx_index].parser_buf = NULL;
+    s->context[ctx_index].parser_use = false;
+}
+#endif
+
+static void maru_brill_codec_release_context(MaruBrillCodecState *s, int32_t context_id)
+{
+    DeviceMemEntry *wq_elem = NULL, *wnext = NULL;
+    CodecDataStg *rq_elem = NULL, *rnext = NULL;
+
+    TRACE("enter: %s\n", __func__);
+
+    TRACE("release %d of context\n", context_id);
+
+    qemu_mutex_lock(&s->threadpool.mutex);
+    if (s->context[context_id].opened_context) {
+        // qemu_mutex_unlock(&s->threadpool.mutex);
+        codec_deinit(s, context_id, NULL);
+        // qemu_mutex_lock(&s->threadpool.mutex);
+    }
+    s->context[context_id].occupied_context = false;
+    qemu_mutex_unlock(&s->threadpool.mutex);
+
+    // TODO: check if foreach statment needs lock or not.
+    QTAILQ_FOREACH_SAFE(rq_elem, &codec_rq, node, rnext) {
+        if (rq_elem && rq_elem->data_buf &&
+            (rq_elem->data_buf->ctx_id == context_id)) {
+
+            TRACE("remove unused node from codec_rq. ctx_id: %d\n", context_id);
+            qemu_mutex_lock(&s->context_queue_mutex);
+            QTAILQ_REMOVE(&codec_rq, rq_elem, node);
+            qemu_mutex_unlock(&s->context_queue_mutex);
+            if (rq_elem && rq_elem->data_buf) {
+                TRACE("release rq_buffer: %p\n", rq_elem->data_buf);
+                g_free(rq_elem->data_buf);
+            }
+
+            TRACE("release rq_elem: %p\n", rq_elem);
+            g_free(rq_elem);
+        } else {
+            TRACE("no elem of %d context in the codec_rq.\n", context_id);
+        }
+    }
+
+    QTAILQ_FOREACH_SAFE(wq_elem, &codec_wq, node, wnext) {
+        if (wq_elem && wq_elem->ctx_id == context_id) {
+            TRACE("remove unused node from codec_wq. ctx_id: %d\n", context_id);
+            qemu_mutex_lock(&s->context_queue_mutex);
+            QTAILQ_REMOVE(&codec_wq, wq_elem, node);
+            qemu_mutex_unlock(&s->context_queue_mutex);
+
+            if (wq_elem && wq_elem->buf) {
+                TRACE("release wq_buffer: %p\n", wq_elem->buf);
+                g_free(wq_elem->buf);
+                wq_elem->buf = NULL;
+            }
+
+            TRACE("release wq_elem: %p\n", wq_elem);
+            g_free(wq_elem);
+        } else {
+            TRACE("no elem of %d context in the codec_wq.\n", context_id);
+        }
+    }
+
+    TRACE("leave: %s\n", __func__);
+}
+
+
+// initialize each pixel format.
+static void maru_brill_codec_pixfmt_info_init(void)
+{
+    /* YUV formats */
+    pix_fmt_info[PIX_FMT_YUV420P].x_chroma_shift = 1;
+    pix_fmt_info[PIX_FMT_YUV420P].y_chroma_shift = 1;
+
+    pix_fmt_info[PIX_FMT_YUV422P].x_chroma_shift = 1;
+    pix_fmt_info[PIX_FMT_YUV422P].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_YUV444P].x_chroma_shift = 0;
+    pix_fmt_info[PIX_FMT_YUV444P].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_YUYV422].x_chroma_shift = 1;
+    pix_fmt_info[PIX_FMT_YUYV422].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_YUV410P].x_chroma_shift = 2;
+    pix_fmt_info[PIX_FMT_YUV410P].y_chroma_shift = 2;
+
+    pix_fmt_info[PIX_FMT_YUV411P].x_chroma_shift = 2;
+    pix_fmt_info[PIX_FMT_YUV411P].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_YUVJ420P].x_chroma_shift = 1;
+    pix_fmt_info[PIX_FMT_YUVJ420P].y_chroma_shift = 1;
+
+    pix_fmt_info[PIX_FMT_YUVJ422P].x_chroma_shift = 1;
+    pix_fmt_info[PIX_FMT_YUVJ422P].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_YUVJ444P].x_chroma_shift = 0;
+    pix_fmt_info[PIX_FMT_YUVJ444P].y_chroma_shift = 0;
+
+    /* RGB formats */
+    pix_fmt_info[PIX_FMT_RGB24].x_chroma_shift = 0;
+    pix_fmt_info[PIX_FMT_RGB24].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_BGR24].x_chroma_shift = 0;
+    pix_fmt_info[PIX_FMT_BGR24].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_RGB32].x_chroma_shift = 0;
+    pix_fmt_info[PIX_FMT_RGB32].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_RGB565].x_chroma_shift = 0;
+    pix_fmt_info[PIX_FMT_RGB565].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_RGB555].x_chroma_shift = 0;
+    pix_fmt_info[PIX_FMT_RGB555].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_YUVA420P].x_chroma_shift = 1;
+    pix_fmt_info[PIX_FMT_YUVA420P].y_chroma_shift = 1;
+}
+
+static int maru_brill_codec_get_picture_size(AVPicture *picture, uint8_t *ptr,
+                                    int pix_fmt, int width,
+                                    int height, bool encode)
+{
+    int size, w2, h2, size2;
+    int stride, stride2;
+    int fsize;
+    PixFmtInfo *pinfo;
+
+    pinfo = &pix_fmt_info[pix_fmt];
+
+    switch (pix_fmt) {
+    case PIX_FMT_YUV420P:
+    case PIX_FMT_YUV422P:
+    case PIX_FMT_YUV444P:
+    case PIX_FMT_YUV410P:
+    case PIX_FMT_YUV411P:
+    case PIX_FMT_YUVJ420P:
+    case PIX_FMT_YUVJ422P:
+    case PIX_FMT_YUVJ444P:
+        stride = ROUND_UP_4(width);
+        h2 = ROUND_UP_X(height, pinfo->y_chroma_shift);
+        size = stride * h2;
+        w2 = DIV_ROUND_UP_X(width, pinfo->x_chroma_shift);
+        stride2 = ROUND_UP_4(w2);
+        h2 = DIV_ROUND_UP_X(height, pinfo->y_chroma_shift);
+        size2 = stride2 * h2;
+        fsize = size + 2 * size2;
+        TRACE("stride: %d, stride2: %d, size: %d, size2: %d, fsize: %d\n",
+            stride, stride2, size, size2, fsize);
+
+        if (!encode && !ptr) {
+            TRACE("allocate a buffer for a decoded picture.\n");
+            ptr = av_mallocz(fsize);
+            if (!ptr) {
+                ERR("[%d] failed to allocate memory.\n", __LINE__);
+                return -1;
+            }
+        }
+        picture->data[0] = ptr;
+        picture->data[1] = picture->data[0] + size;
+        picture->data[2] = picture->data[1] + size2;
+        picture->data[3] = NULL;
+        picture->linesize[0] = stride;
+        picture->linesize[1] = stride2;
+        picture->linesize[2] = stride2;
+        picture->linesize[3] = 0;
+        TRACE("planes %d %d %d\n", 0, size, size + size2);
+        TRACE("strides %d %d %d\n", 0, stride, stride2, stride2);
+        break;
+    case PIX_FMT_YUVA420P:
+        stride = ROUND_UP_4(width);
+        h2 = ROUND_UP_X(height, pinfo->y_chroma_shift);
+        size = stride * h2;
+        w2 = DIV_ROUND_UP_X(width, pinfo->x_chroma_shift);
+        stride2 = ROUND_UP_4(w2);
+        h2 = DIV_ROUND_UP_X(height, pinfo->y_chroma_shift);
+        size2 = stride2 * h2;
+        fsize = 2 * size + 2 * size2;
+        if (!encode && !ptr) {
+            TRACE("allocate a buffer for a decoded picture.\n");
+            ptr = av_mallocz(fsize);
+            if (!ptr) {
+                ERR("[%d] failed to allocate memory.\n", __LINE__);
+                return -1;
+            }
+        }
+        picture->data[0] = ptr;
+        picture->data[1] = picture->data[0] + size;
+        picture->data[2] = picture->data[1] + size2;
+        picture->data[3] = picture->data[2] + size2;
+        picture->linesize[0] = stride;
+        picture->linesize[1] = stride2;
+        picture->linesize[2] = stride2;
+        picture->linesize[3] = stride;
+        TRACE("planes %d %d %d\n", 0, size, size + size2);
+        TRACE("strides %d %d %d\n", 0, stride, stride2, stride2);
+        break;
+    case PIX_FMT_RGB24:
+    case PIX_FMT_BGR24:
+        stride = ROUND_UP_4 (width * 3);
+        fsize = stride * height;
+        TRACE("stride: %d, size: %d\n", stride, fsize);
+
+        if (!encode && !ptr) {
+            TRACE("allocate a buffer for a decoded picture.\n");
+            ptr = av_mallocz(fsize);
+            if (!ptr) {
+                ERR("[%d] failed to allocate memory.\n", __LINE__);
+                return -1;
+            }
+        }
+        picture->data[0] = ptr;
+        picture->data[1] = NULL;
+        picture->data[2] = NULL;
+        picture->data[3] = NULL;
+        picture->linesize[0] = stride;
+        picture->linesize[1] = 0;
+        picture->linesize[2] = 0;
+        picture->linesize[3] = 0;
+        break;
+    case PIX_FMT_RGB32:
+        stride = width * 4;
+        fsize = stride * height;
+        TRACE("stride: %d, size: %d\n", stride, fsize);
+
+        if (!encode && !ptr) {
+            TRACE("allocate a buffer for a decoded picture.\n");
+            ptr = av_mallocz(fsize);
+            if (!ptr) {
+                ERR("[%d] failed to allocate memory.\n", __LINE__);
+                return -1;
+            }
+        }
+        picture->data[0] = ptr;
+        picture->data[1] = NULL;
+        picture->data[2] = NULL;
+        picture->data[3] = NULL;
+        picture->linesize[0] = stride;
+        picture->linesize[1] = 0;
+        picture->linesize[2] = 0;
+        picture->linesize[3] = 0;
+        break;
+    case PIX_FMT_RGB555:
+    case PIX_FMT_RGB565:
+        stride = ROUND_UP_4 (width * 2);
+        fsize = stride * height;
+        TRACE("stride: %d, size: %d\n", stride, fsize);
+
+        if (!encode && !ptr) {
+            TRACE("allocate a buffer for a decoded picture.\n");
+            ptr = av_mallocz(fsize);
+            if (!ptr) {
+                ERR("[%d] failed to allocate memory.\n", __LINE__);
+                return -1;
+            }
+        }
+        picture->data[0] = ptr;
+        picture->data[1] = NULL;
+        picture->data[2] = NULL;
+        picture->data[3] = NULL;
+        picture->linesize[0] = stride;
+        picture->linesize[1] = 0;
+        picture->linesize[2] = 0;
+        picture->linesize[3] = 0;
+        break;
+    case PIX_FMT_PAL8:
+        stride = ROUND_UP_4(width);
+        size = stride * height;
+        fsize = size + 256 * 4;
+        TRACE("stride: %d, size: %d\n", stride, fsize);
+
+        if (!encode && !ptr) {
+            TRACE("allocate a buffer for a decoded picture.\n");
+            ptr = av_mallocz(fsize);
+            if (!ptr) {
+                ERR("[%d] failed to allocate memory.\n", __LINE__);
+                return -1;
+            }
+        }
+        picture->data[0] = ptr;
+        picture->data[1] = ptr + size;
+        picture->data[2] = NULL;
+        picture->data[3] = NULL;
+        picture->linesize[0] = stride;
+        picture->linesize[1] = 4;
+        picture->linesize[2] = 0;
+        picture->linesize[3] = 0;
+        break;
+    default:
+        picture->data[0] = NULL;
+        picture->data[1] = NULL;
+        picture->data[2] = NULL;
+        picture->data[3] = NULL;
+        fsize = -1;
+        ERR("pixel format: %d was wrong.\n", pix_fmt);
+        break;
+    }
+
+    return fsize;
+}
+
+static int maru_brill_codec_query_list (MaruBrillCodecState *s)
+{
+    AVCodec *codec = NULL;
+    uint32_t size = 0, mem_size = 0;
+    uint32_t data_len = 0, length = 0;
+    int32_t codec_type, media_type;
+    int32_t codec_fmts[4], i;
+
+    /* register avcodec */
+    TRACE("register avcodec\n");
+    av_register_all();
+
+    codec = av_codec_next(NULL);
+    if (!codec) {
+        ERR("failed to get codec info.\n");
+        return -1;
+    }
+
+    // a region to store the number of codecs.
+    length = 32 + 64 + 6 * sizeof(int32_t);
+    mem_size = size = sizeof(uint32_t);
+
+    while (codec) {
+        codec_type =
+            codec->decode ? CODEC_TYPE_DECODE : CODEC_TYPE_ENCODE;
+        media_type = codec->type;
+
+        memset(codec_fmts, -1, sizeof(codec_fmts));
+        if (media_type == AVMEDIA_TYPE_VIDEO) {
+            if (codec->pix_fmts) {
+                for (i = 0; codec->pix_fmts[i] != -1; i++) {
+                    codec_fmts[i] = codec->pix_fmts[i];
+                }
+            }
+        } else if (media_type == AVMEDIA_TYPE_AUDIO) {
+            if (codec->sample_fmts) {
+                for (i = 0; codec->sample_fmts[i] != -1; i++) {
+                    codec_fmts[i] = codec->sample_fmts[i];
+                }
+            }
+        } else {
+            ERR("%s of media type is unknown.\n", codec->name);
+        }
+
+        memset(s->vaddr + mem_size, 0x00, length);
+        mem_size += length;
+
+        data_len += length;
+        memcpy(s->vaddr, &data_len, sizeof(data_len));
+
+        memcpy(s->vaddr + size, &codec_type, sizeof(codec_type));
+        size += sizeof(codec_type);
+        memcpy(s->vaddr + size, &media_type, sizeof(media_type));
+        size += sizeof(media_type);
+        memcpy(s->vaddr + size, codec->name, strlen(codec->name));
+        size += 32;
+        memcpy(s->vaddr + size,
+           codec->long_name, strlen(codec->long_name));
+        size += 64;
+        memcpy(s->vaddr + size, codec_fmts, sizeof(codec_fmts));
+        size += sizeof(codec_fmts);
+
+        codec = av_codec_next(codec);
+    }
+
+    return 0;
+}
+
+static int maru_brill_codec_get_context_index(MaruBrillCodecState *s)
+{
+    int index;
+
+    TRACE("enter: %s\n", __func__);
+
+    // requires mutex_lock? its function is protected by critical section.
+    qemu_mutex_lock(&s->threadpool.mutex);
+    for (index = 1; index < CODEC_CONTEXT_MAX; index++) {
+        if (s->context[index].occupied_context == false) {
+            TRACE("get %d of codec context successfully.\n", index);
+            s->context[index].occupied_context = true;
+            break;
+        }
+    }
+    qemu_mutex_unlock(&s->threadpool.mutex);
+
+    if (index == CODEC_CONTEXT_MAX) {
+        ERR("failed to get available codec context. ");
+        ERR("try to run codec again.\n");
+        index = -1;
+    }
+
+    TRACE("leave: %s\n", __func__);
+
+    return index;
+}
+
+// allocate avcontext and avframe struct.
+static AVCodecContext *maru_brill_codec_alloc_context(MaruBrillCodecState *s, int index)
+{
+    TRACE("enter: %s\n", __func__);
+
+    TRACE("allocate %d of context and frame.\n", index);
+    s->context[index].avctx = avcodec_alloc_context3(NULL);
+    s->context[index].frame = avcodec_alloc_frame();
+    s->context[index].opened_context = false;
+
+#if 0
+    s->context[index].parser_buf = NULL;
+    s->context[index].parser_use = false;
+#endif
+    TRACE("leave: %s\n", __func__);
+
+    return s->context[index].avctx;
+}
+
+static AVCodec *maru_brill_codec_find_avcodec(uint8_t *mem_buf)
+{
+    AVCodec *codec = NULL;
+    int32_t encode, size = 0;
+    char codec_name[32] = {0, };
+
+    memcpy(&encode, mem_buf, sizeof(encode));
+    size = sizeof(encode);
+    memcpy(codec_name, mem_buf + size, sizeof(codec_name));
+    size += sizeof(codec_name);
+
+    TRACE("type: %d, name: %s\n", encode, codec_name);
+
+    if (encode) {
+        codec = avcodec_find_encoder_by_name (codec_name);
+    } else {
+        codec = avcodec_find_decoder_by_name (codec_name);
+    }
+    INFO("%s!! find %s %s\n",
+        codec ? "success" : "failure",
+        codec_name, encode ? "encoder" : "decoder");
+
+    return codec;
+}
+
+static void read_codec_init_data(AVCodecContext *avctx, uint8_t *mem_buf)
+{
+    struct video_data video = { 0, };
+    struct audio_data audio = { 0, };
+    int bitrate = 0, size = 0;
+
+    memcpy(&video, mem_buf + size, sizeof(video));
+    size = sizeof(video);
+    serialize_video_data(&video, avctx);
+
+#if 0
+    memcpy(&audio, mem_buf + size, sizeof(int32_t) * 7);
+    size += (sizeof(int32_t) * 7);
+    memcpy(&audio.channel_layout, mem_buf + size, sizeof(audio.channel_layout));
+    size += sizeof(audio.channel_layout);
+#endif
+    memcpy(&audio, mem_buf + size, sizeof(audio));
+    size += sizeof(audio);
+    serialize_audio_data(&audio, avctx);
+
+    memcpy(&bitrate, mem_buf + size, sizeof(bitrate));
+    size += sizeof(bitrate);
+    if (bitrate) {
+        avctx->bit_rate = bitrate;
+    }
+
+    memcpy(&avctx->codec_tag, mem_buf + size, sizeof(avctx->codec_tag));
+    size += sizeof(avctx->codec_tag);
+    memcpy(&avctx->extradata_size,
+            mem_buf + size, sizeof(avctx->extradata_size));
+    size += sizeof(avctx->extradata_size);
+    INFO("extradata size: %d.\n", avctx->extradata_size);
+
+    if (avctx->extradata_size > 0) {
+        avctx->extradata =
+            av_mallocz(ROUND_UP_X(avctx->extradata_size +
+                        FF_INPUT_BUFFER_PADDING_SIZE, 4));
+        if (avctx->extradata) {
+            memcpy(avctx->extradata, mem_buf + size, avctx->extradata_size);
+        }
+    } else {
+        TRACE("no extra data.\n");
+        avctx->extradata =
+            av_mallocz(ROUND_UP_X(FF_INPUT_BUFFER_PADDING_SIZE, 4));
+    }
+}
+
+// write the result of codec_init
+static int write_codec_init_data(AVCodecContext *avctx, uint8_t *mem_buf)
+{
+    int size = 0;
+
+    if (avctx->codec->type == AVMEDIA_TYPE_AUDIO) {
+        int osize = av_get_bytes_per_sample(avctx->sample_fmt);
+
+        memcpy(mem_buf, &avctx->sample_fmt, sizeof(avctx->sample_fmt));
+        size = sizeof(avctx->sample_fmt);
+
+        // frame_size: samples per packet, initialized when calling 'init'
+        memcpy(mem_buf + size, &avctx->frame_size, sizeof(avctx->frame_size));
+        size += sizeof(avctx->frame_size);
+
+        memcpy(mem_buf + size, &osize, sizeof(osize));
+        size += sizeof(osize);
+    }
+
+    return size;
+}
+
+static uint8_t *resample_audio(AVCodecContext * avctx, AVFrame *samples, int *out_size)
+{
+    AVAudioResampleContext *avr = NULL;
+    uint8_t *resample_audio = NULL;
+    int buffer_size = 0, out_linesize = 0;
+    int nb_samples = samples->nb_samples;
+    int out_sample_fmt = avctx->sample_fmt - 5;
+
+    avr = avresample_alloc_context();
+    if (!avr) {
+        ERR("failed to allocate avresample context\n");
+        return NULL;
+    }
+
+    av_opt_set_int(avr, "in_channel_layout", avctx->channel_layout, 0);
+    av_opt_set_int(avr, "in_sample_fmt", avctx->sample_fmt, 0);
+    av_opt_set_int(avr, "in_sample_rate", avctx->sample_rate, 0);
+    av_opt_set_int(avr, "out_channel_layout", avctx->channel_layout, 0);
+    av_opt_set_int(avr, "out_sample_fmt", out_sample_fmt, 0);
+    av_opt_set_int(avr, "out_sample_rate", avctx->sample_rate, 0);
+
+    TRACE("open avresample context\n");
+    if (avresample_open(avr) < 0) {
+        ERR("failed to open avresample context\n");
+        avresample_free(&avr);
+        return NULL;
+    }
+
+    *out_size =
+        av_samples_get_buffer_size(&out_linesize, avctx->channels,
+                                    nb_samples, out_sample_fmt, 0);
+
+    resample_audio = av_mallocz(*out_size);
+    if (!resample_audio) {
+        ERR("failed to allocate resample buffer\n");
+        avresample_close(avr);
+        avresample_free(&avr);
+        return NULL;
+    }
+
+    buffer_size = avresample_convert(avr, &resample_audio,
+        out_linesize, nb_samples,
+        samples->data, samples->linesize[0],
+        samples->nb_samples);
+
+    TRACE("resample_audio out_size %d buffer_size %d\n", *out_size, buffer_size);
+
+    avresample_close(avr);
+    avresample_free(&avr);
+
+    return resample_audio;
+}
+
+
+// codec functions
+static bool codec_init(MaruBrillCodecState *s, int ctx_id, void *data_buf)
+{
+    AVCodecContext *avctx = NULL;
+    AVCodec *codec = NULL;
+    int size = 0, ret = -1;
+    DeviceMemEntry *elem = NULL;
+    uint8_t *tempbuf = NULL;
+    int tempbuf_size = 0;
+
+    TRACE("enter: %s\n", __func__);
+
+    elem = (DeviceMemEntry *)data_buf;
+
+    // allocate AVCodecContext
+    avctx = maru_brill_codec_alloc_context(s, ctx_id);
+    if (!avctx) {
+        ERR("[%d] failed to allocate context.\n", __LINE__);
+        ret = -1;
+    } else {
+#if 0
+        avcodec_get_context_defaults(avctx);
+
+        avctx->rc_strategy = 2;
+        avctx->b_frame_strategy = 0;
+        avctx->coder_type = 0;
+        avctx->context_model = 0;
+        avctx->scenechange_threshold = 0;
+        avctx->inter_threshold = 0;
+
+        avctx->gop_size = DEFAULT_VIDEO_GOP_SIZE;
+        avctx->lmin = (2 * FF_QP2LAMBDA + 0.5);
+        avctx->lmax = (31 * FF_QP2LAMBDA + 0.5);
+#endif
+
+        codec = maru_brill_codec_find_avcodec(elem->buf);
+        if (codec) {
+            size = sizeof(int32_t) + 32; // buffer size of codec_name
+            read_codec_init_data(avctx, elem->buf + size);
+
+            ret = avcodec_open2(avctx, codec, NULL);
+            INFO("avcodec_open success! ret %d ctx_id %d\n", ret, ctx_id);
+
+            TRACE("channels %d sample_rate %d sample_fmt %d ch_layout %lld\n",
+                avctx->channels, avctx->sample_rate,
+                avctx->sample_fmt, avctx->channel_layout);
+
+            tempbuf_size = (sizeof(avctx->sample_fmt) + sizeof(avctx->frame_size)
+                           + sizeof(avctx->extradata_size) + avctx->extradata_size)
+                           + sizeof(int);
+
+            s->context[ctx_id].opened_context = true;
+            s->context[ctx_id].parser_ctx =
+                maru_brill_codec_parser_init(avctx);
+        } else {
+            ERR("failed to find codec. ctx_id: %d\n", ctx_id);
+            ret = -1;
+        }
+    }
+
+    tempbuf_size += sizeof(ret);
+
+    tempbuf = g_malloc(tempbuf_size);
+    if (!tempbuf) {
+        ERR("failed to allocate a buffer\n");
+        tempbuf_size = 0;
+    } else {
+        memcpy(tempbuf, &ret, sizeof(ret));
+        size = sizeof(ret);
+        if (ret < 0) {
+            ERR("failed to open codec contex.\n");
+        } else {
+            size += write_codec_init_data(avctx, tempbuf + size);
+            TRACE("codec_init. copyback!! size %d\n", size);
+            {
+                memcpy(tempbuf + size, &avctx->extradata_size, sizeof(avctx->extradata_size));
+                size += sizeof(avctx->extradata_size);
+                if (avctx->extradata) {
+                    memcpy(tempbuf + size, avctx->extradata, avctx->extradata_size);
+                    size += avctx->extradata_size;
+                }
+            }
+        }
+    }
+
+    maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id);
+
+    TRACE("leave: %s\n", __func__);
+
+    return true;
+}
+
+static bool codec_deinit(MaruBrillCodecState *s, int ctx_id, void *data_buf)
+{
+    AVCodecContext *avctx = NULL;
+    AVFrame *frame = NULL;
+    AVCodecParserContext *parserctx = NULL;
+
+    TRACE("enter: %s\n", __func__);
+
+    avctx = s->context[ctx_id].avctx;
+    frame = s->context[ctx_id].frame;
+    parserctx = s->context[ctx_id].parser_ctx;
+    if (!avctx || !frame) {
+        TRACE("%d of AVCodecContext or AVFrame is NULL. "
+            " Those resources have been released before.\n", ctx_id);
+        return false;
+    }
+
+    INFO("close avcontext of %d\n", ctx_id);
+    // qemu_mutex_lock(&s->threadpool.mutex);
+    avcodec_close(avctx);
+    s->context[ctx_id].opened_context = false;
+    // qemu_mutex_unlock(&s->threadpool.mutex);
+
+    if (avctx->extradata) {
+        TRACE("free context extradata\n");
+        av_free(avctx->extradata);
+        s->context[ctx_id].avctx->extradata = NULL;
+    }
+
+    if (frame) {
+        TRACE("free frame\n");
+        av_free(frame);
+        s->context[ctx_id].frame = NULL;
+    }
+
+    if (avctx) {
+        TRACE("free codec context\n");
+        av_free(avctx);
+        s->context[ctx_id].avctx = NULL;
+    }
+
+    if (parserctx) {
+        av_parser_close(parserctx);
+        s->context[ctx_id].parser_ctx = NULL;
+    }
+
+    maru_brill_codec_push_writequeue(s, NULL, 0, ctx_id);
+
+    TRACE("leave: %s\n", __func__);
+
+    return true;
+}
+
+static bool codec_flush_buffers(MaruBrillCodecState *s, int ctx_id, void *data_buf)
+{
+    AVCodecContext *avctx = NULL;
+    bool ret = true;
+
+    TRACE("enter: %s\n", __func__);
+
+    avctx = s->context[ctx_id].avctx;
+    if (!avctx) {
+        ERR("%d of AVCodecContext is NULL.\n", ctx_id);
+        ret = false;
+    } else if (!avctx->codec) {
+        ERR("%d of AVCodec is NULL.\n", ctx_id);
+        ret = false;
+    } else {
+        TRACE("flush %d context of buffers.\n", ctx_id);
+        avcodec_flush_buffers(avctx);
+    }
+
+    maru_brill_codec_push_writequeue(s, NULL, 0, ctx_id);
+
+    TRACE("leave: %s\n", __func__);
+
+    return ret;
+}
+
+static bool codec_decode_video(MaruBrillCodecState *s, int ctx_id, void *data_buf)
+{
+    AVCodecContext *avctx = NULL;
+    AVFrame *picture = NULL;
+    AVPacket avpkt;
+    int got_picture = 0, len = -1;
+    uint8_t *inbuf = NULL;
+    int inbuf_size = 0, idx, size = 0;
+    int64_t in_offset;
+    DeviceMemEntry *elem = NULL;
+    uint8_t *tempbuf = NULL;
+    int tempbuf_size = 0;
+
+    TRACE("enter: %s\n", __func__);
+
+    elem = (DeviceMemEntry *)data_buf;
+    if (elem && elem->buf) {
+        memcpy(&inbuf_size, elem->buf, sizeof(inbuf_size));
+        size += sizeof(inbuf_size);
+        memcpy(&idx, elem->buf + size, sizeof(idx));
+        size += sizeof(idx);
+        memcpy(&in_offset, elem->buf + size, sizeof(in_offset));
+        size += sizeof(in_offset);
+        TRACE("decode_video. inbuf_size %d\n", inbuf_size);
+
+        if (inbuf_size > 0) {
+            inbuf = elem->buf + size;
+        }
+    } else {
+        TRACE("decode_video. no input buffer\n");
+        // FIXME: improve error handling
+        // return false;
+    }
+
+    av_init_packet(&avpkt);
+    avpkt.data = inbuf;
+    avpkt.size = inbuf_size;
+
+    avctx = s->context[ctx_id].avctx;
+    picture = s->context[ctx_id].frame;
+    if (!avctx) {
+        ERR("decode_video. %d of AVCodecContext is NULL.\n", ctx_id);
+    } else if (!avctx->codec) {
+        ERR("decode_video. %d of AVCodec is NULL.\n", ctx_id);
+    } else if (!picture) {
+        ERR("decode_video. %d of AVFrame is NULL.\n", ctx_id);
+    } else {
+        // in case of skipping frames
+        // picture->pict_type = -1;
+
+        TRACE("decode_video. bitrate %d\n", avctx->bit_rate);
+        // avctx->reordered_opaque = idx;
+        // picture->reordered_opaque = idx;
+
+        len =
+            avcodec_decode_video2(avctx, picture, &got_picture, &avpkt);
+        TRACE("decode_video. in_size %d len %d, frame_size %d\n", avpkt.size, len, got_picture);
+    }
+
+    tempbuf_size =
+            sizeof(len) + sizeof(got_picture) + sizeof(struct video_data);
+
+    if (len < 0) {
+        ERR("failed to decode video. ctx_id: %d, len: %d\n", ctx_id, len);
+        got_picture = 0;
+    }
+
+    tempbuf = g_malloc(tempbuf_size);
+    if (!tempbuf) {
+        ERR("failed to allocate decoded audio buffer\n");
+        // FIXME: how to handle this case?
+    } else {
+        struct video_data video;
+
+        memcpy(tempbuf, &len, sizeof(len));
+        size = sizeof(len);
+        memcpy(tempbuf + size, &got_picture, sizeof(got_picture));
+        size += sizeof(got_picture);
+        if (avctx) {
+            deserialize_video_data(avctx, &video);
+            memcpy(tempbuf + size, &video, sizeof(struct video_data));
+        }
+    }
+
+    maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id);
+
+    TRACE("leave: %s\n", __func__);
+
+    return true;
+}
+
+static bool codec_picture_copy (MaruBrillCodecState *s, int ctx_id, void *elem)
+{
+    AVCodecContext *avctx = NULL;
+    AVPicture *src = NULL;
+    AVPicture dst;
+    uint8_t *out_buffer = NULL, *tempbuf = NULL;
+    int pict_size = 0;
+    bool ret = true;
+
+    TRACE("enter: %s\n", __func__);
+
+    TRACE("copy decoded image of %d context.\n", ctx_id);
+
+    avctx = s->context[ctx_id].avctx;
+    src = (AVPicture *)s->context[ctx_id].frame;
+    if (!avctx) {
+        ERR("picture_copy. %d of AVCodecContext is NULL.\n", ctx_id);
+        ret = false;
+    } else if (!avctx->codec) {
+        ERR("picture_copy. %d of AVCodec is NULL.\n", ctx_id);
+        ret = false;
+    } else if (!src) {
+        ERR("picture_copy. %d of AVFrame is NULL.\n", ctx_id);
+        ret = false;
+    } else {
+        TRACE("decoded image. pix_fmt: %d width: %d, height: %d\n",
+                avctx->pix_fmt, avctx->width, avctx->height);
+
+        pict_size =
+            maru_brill_codec_get_picture_size(&dst, NULL, avctx->pix_fmt,
+                    avctx->width, avctx->height, false);
+        if ((pict_size) < 0) {
+            ERR("picture size: %d\n", pict_size);
+            ret = false;
+        } else {
+            TRACE("picture size: %d\n", pict_size);
+            av_picture_copy(&dst, src, avctx->pix_fmt,
+                            avctx->width, avctx->height);
+
+            tempbuf = g_malloc0(pict_size);
+            if (!tempbuf) {
+                ERR("failed to allocate a picture buffer. size: %d\n", pict_size);
+            } else {
+                out_buffer = dst.data[0];
+                memcpy(tempbuf, out_buffer, pict_size);
+            }
+            av_free(out_buffer);
+        }
+    }
+
+    maru_brill_codec_push_writequeue(s, tempbuf, pict_size, ctx_id);
+
+    TRACE("leave: %s\n", __func__);
+
+    return ret;
+}
+
+static bool codec_decode_audio(MaruBrillCodecState *s, int ctx_id, void *data_buf)
+{
+    AVCodecContext *avctx;
+    AVPacket avpkt;
+    AVFrame *samples = NULL;
+    uint8_t *inbuf = NULL;
+    int inbuf_size = 0, size = 0;
+    int len = -1, got_frame = 0;
+
+    DeviceMemEntry *elem = NULL;
+    uint8_t *tempbuf = NULL;
+    int tempbuf_size = 0;
+
+    uint8_t *outbuf = NULL;
+    int buffer_size = 0;
+    int out_sample_fmt = -1;
+
+    TRACE("enter: %s\n", __func__);
+
+    elem = (DeviceMemEntry *)data_buf;
+    if (elem && elem->buf) {
+        memcpy(&inbuf_size, elem->buf, sizeof(inbuf_size));
+        size = sizeof(inbuf_size);
+        TRACE("decode_audio. inbuf_size %d\n", inbuf_size);
+
+        if (inbuf_size > 0) {
+            inbuf = elem->buf + size;
+        }
+    } else {
+        ERR("decode_audio. no input buffer\n");
+        // FIXME: improve error handling
+        // return false;
+    }
+
+    av_init_packet(&avpkt);
+    avpkt.data = inbuf;
+    avpkt.size = inbuf_size;
+
+    avctx = s->context[ctx_id].avctx;
+    samples = s->context[ctx_id].frame;
+    if (!avctx) {
+        ERR("decode_audio. %d of AVCodecContext is NULL\n", ctx_id);
+    } else if (!avctx->codec) {
+        ERR("decode_audio. %d of AVCodec is NULL\n", ctx_id);
+    } else if (!samples) {
+        ERR("decode_audio. %d of AVFrame is NULL\n", ctx_id);
+    } else {
+        avcodec_get_frame_defaults(samples);
+
+        len = avcodec_decode_audio4(avctx, samples, &got_frame, &avpkt);
+        TRACE("decode_audio. len %d, channel_layout %lld, frame_size %d\n",
+            len, avctx->channel_layout, got_frame);
+        if (got_frame) {
+            if (av_sample_fmt_is_planar(avctx->sample_fmt)) {
+                out_sample_fmt = avctx->sample_fmt - 5;
+
+                outbuf = resample_audio (avctx, samples, &buffer_size);
+            } else {
+                // TODO: not planar format
+            }
+        }
+    }
+
+    tempbuf_size = (sizeof(len) + sizeof(got_frame));
+    if (len < 0) {
+        ERR("failed to decode audio. ctx_id: %d len: %d got_frame: %d\n",
+            ctx_id, len, got_frame);
+        got_frame = 0;
+    } else {
+        tempbuf_size += (sizeof(out_sample_fmt) + sizeof(avctx->sample_rate)
+                        + sizeof(avctx->channels) +  sizeof(avctx->channel_layout)
+                        + sizeof(buffer_size) + buffer_size);
+    }
+
+    tempbuf = g_malloc(tempbuf_size);
+    if (!tempbuf) {
+        ERR("failed to allocate decoded audio buffer\n");
+    } else {
+        memcpy(tempbuf, &len, sizeof(len));
+        size = sizeof(len);
+        memcpy(tempbuf + size, &got_frame, sizeof(got_frame));
+        size += sizeof(got_frame);
+        if (got_frame) {
+            memcpy(tempbuf + size, &out_sample_fmt, sizeof(out_sample_fmt));
+            size += sizeof(out_sample_fmt);
+            memcpy(tempbuf + size, &avctx->sample_rate, sizeof(avctx->sample_rate));
+            size += sizeof(avctx->sample_rate);
+            memcpy(tempbuf + size, &avctx->channels, sizeof(avctx->channels));
+            size += sizeof(avctx->channels);
+            memcpy(tempbuf + size, &avctx->channel_layout, sizeof(avctx->channel_layout));
+            size += sizeof(avctx->channel_layout);
+
+            memcpy(tempbuf + size, &buffer_size, sizeof(buffer_size));
+            size += sizeof(buffer_size);
+
+            if (outbuf) {
+                memcpy(tempbuf + size, outbuf, buffer_size);
+                av_free(outbuf);
+            }
+        }
+    }
+
+    maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id);
+
+    TRACE("leave: %s\n", __func__);
+    return true;
+}
+
+static bool codec_encode_video(MaruBrillCodecState *s, int ctx_id, void *data_buf)
+{
+    AVCodecContext *avctx = NULL;
+    AVFrame *pict = NULL;
+    AVPacket avpkt;
+    uint8_t *inbuf = NULL, *outbuf = NULL;
+    int inbuf_size = 0, outbuf_size = 0;
+    int got_frame = 0, ret = 0, size = 0;
+    int64_t in_timestamp = 0;
+    int coded_frame = 0, key_frame = 0;
+
+    DeviceMemEntry *elem = NULL;
+    uint8_t *tempbuf = NULL;
+    int tempbuf_size = 0;
+
+    TRACE("enter: %s\n", __func__);
+
+    elem = (DeviceMemEntry *)data_buf;
+    if (elem && elem->buf) {
+        memcpy(&inbuf_size, elem->buf, sizeof(inbuf_size));
+        size += sizeof(inbuf_size);
+        memcpy(&in_timestamp, elem->buf + size, sizeof(in_timestamp));
+        size += sizeof(in_timestamp);
+        TRACE("encode video. inbuf_size %d\n", inbuf_size);
+
+        if (inbuf_size > 0) {
+            inbuf = elem->buf + size;
+        }
+    } else {
+        TRACE("encode video. no input buffer.\n");
+        // FIXME: improve error handling
+        // return false;
+    }
+
+    av_init_packet(&avpkt);
+    avpkt.data = NULL;
+    avpkt.size = 0;
+
+    avctx = s->context[ctx_id].avctx;
+    pict = s->context[ctx_id].frame;
+    if (!avctx || !pict) {
+        ERR("%d of context or frame is NULL\n", ctx_id);
+    } else if (!avctx->codec) {
+        ERR("%d of AVCodec is NULL.\n", ctx_id);
+    } else {
+        TRACE("pixel format: %d inbuf: %p, picture data: %p\n",
+            avctx->pix_fmt, inbuf, pict->data[0]);
+
+        ret =
+            maru_brill_codec_get_picture_size((AVPicture *)pict, inbuf,
+                                            avctx->pix_fmt, avctx->width,
+                                            avctx->height, true);
+        if (ret < 0) {
+            ERR("after avpicture_fill, ret:%d\n", ret);
+        } else {
+            if (avctx->time_base.num == 0) {
+                pict->pts = AV_NOPTS_VALUE;
+            } else {
+                AVRational bq =
+                            {1, (G_USEC_PER_SEC * G_GINT64_CONSTANT(1000))};
+                pict->pts = av_rescale_q(in_timestamp, bq, avctx->time_base);
+            }
+            TRACE("encode video. ticks_per_frame:%d, pts:%lld\n",
+                avctx->ticks_per_frame, pict->pts);
+
+            outbuf_size =
+                (avctx->width * avctx->height * 6) + FF_MIN_BUFFER_SIZE;
+
+            outbuf = g_malloc0(outbuf_size);
+
+            avpkt.data = outbuf;
+            avpkt.size = outbuf_size;
+
+            if (!outbuf) {
+                ERR("failed to allocate a buffer of encoding video.\n");
+            } else {
+                ret = avcodec_encode_video2(avctx, &avpkt, pict, &got_frame);
+
+                TRACE("encode video. ret %d got_picture %d outbuf_size %d\n", ret, got_frame, avpkt.size);
+                if (avctx->coded_frame) {
+                    TRACE("encode video. keyframe %d\n", avctx->coded_frame->key_frame);
+                }
+            }
+        }
+    }
+
+    tempbuf_size = sizeof(ret);
+    if (ret < 0) {
+        ERR("failed to encode video. ctx_id %d ret %d\n", ctx_id, ret);
+    } else {
+        tempbuf_size += avpkt.size + sizeof(coded_frame) + sizeof(key_frame);
+    }
+
+    // write encoded video data
+    tempbuf = g_malloc0(tempbuf_size);
+    if (!tempbuf) {
+        ERR("encode video. failed to allocate encoded out buffer.\n");
+    } else {
+        memcpy(tempbuf, &avpkt.size, sizeof(avpkt.size));
+        size = sizeof(avpkt.size);
+
+        if ((got_frame) && outbuf) {
+            // inform gstreamer plugin about the status of encoded frames
+            // A flag for output buffer in gstreamer is depending on the status.
+            if (avctx->coded_frame) {
+                coded_frame = 1;
+                // if key_frame is 0, this frame cannot be decoded independently.
+                key_frame = avctx->coded_frame->key_frame;
+            }
+            memcpy(tempbuf + size, &coded_frame, sizeof(coded_frame));
+            size += sizeof(coded_frame);
+            memcpy(tempbuf + size, &key_frame, sizeof(key_frame));
+            size += sizeof(key_frame);
+            memcpy(tempbuf + size, outbuf, avpkt.size);
+        }
+    }
+
+    if (outbuf) {
+        TRACE("release encoded output buffer. %p\n", outbuf);
+        g_free(outbuf);
+    }
+
+    maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id);
+
+    TRACE("leave: %s\n", __func__);
+    return true;
+}
+
+static bool codec_encode_audio(MaruBrillCodecState *s, int ctx_id, void *data_buf)
+{
+    AVCodecContext *avctx;
+    AVPacket avpkt;
+    uint8_t *inbuf = NULL, *outbuf = NULL;
+    int32_t inbuf_size = 0, max_size = 0;
+    int ret = 0, got_pkt = 0, size = 0;
+
+    DeviceMemEntry *elem = NULL;
+    uint8_t *tempbuf = NULL;
+    int tempbuf_size = 0;
+
+    TRACE("enter: %s\n", __func__);
+
+    elem = (DeviceMemEntry *)data_buf;
+    if (elem && elem->buf) {
+        memcpy(&inbuf_size, elem->buf, sizeof(inbuf_size));
+        size += sizeof(inbuf_size);
+        // memcpy(&max_size, elem->buf + size, sizeof(max_size));
+        // size += sizeof(max_size);
+        max_size = inbuf_size * 4; // + FF_MIN_BUFFER_SIZE;
+        TRACE("encode_video. inbuf_size %d max_size %d\n", inbuf_size, max_size);
+
+        if (inbuf_size > 0) {
+            // inbuf = g_malloc(inbuf_size);
+            // memcpy(inbuf, elem->buf + size, inbuf_size);
+            inbuf = elem->buf + size;
+        }
+    } else {
+        TRACE("encode_audio. no input buffer\n");
+        // FIXME: improve error handling
+        // return false;
+    }
+
+    av_init_packet(&avpkt);
+    avpkt.data = NULL;
+    avpkt.size = 0;
+
+    avctx = s->context[ctx_id].avctx;
+    if (!avctx) {
+        ERR("[%s] %d of Context is NULL!\n", __func__, ctx_id);
+    } else if (!avctx->codec) {
+        ERR("%d of AVCodec is NULL.\n", ctx_id);
+    } else {
+        outbuf = g_malloc0(max_size + FF_MIN_BUFFER_SIZE);
+        // outbuf = g_malloc0(max_size);
+
+        avpkt.data = outbuf;
+        avpkt.size = max_size;
+
+        if (!outbuf) {
+            ERR("failed to allocate a buffer of encoding audio.\n");
+        } else {
+            ret = avcodec_encode_audio2(avctx, &avpkt, (const AVFrame *)inbuf, &got_pkt);
+            TRACE("encode audio. ret %d got_pkt %d outbuf_size %d\n", ret, got_pkt, avpkt.size);
+        }
+    }
+
+    tempbuf_size = sizeof(ret);
+    if (ret < 0) {
+        ERR("failed to encode audio. ctx_id %d ret %d\n", ctx_id, ret);
+    } else {
+        // tempbuf_size += (max_size); // len;
+        tempbuf_size += avpkt.size;
+    }
+
+    // write encoded audio data
+    tempbuf = g_malloc0(tempbuf_size);
+    if (!tempbuf) {
+        ERR("encode audio. failed to allocate encoded out buffer.\n");
+    } else {
+        memcpy(tempbuf, &avpkt.size, sizeof(avpkt.size));
+        size = sizeof(avpkt.size);
+        if (got_pkt && outbuf) {
+            // memcpy(tempbuf + size, outbuf, max_size); // len);
+            memcpy(tempbuf + size, outbuf, avpkt.size);
+        }
+    }
+
+    if (outbuf) {
+        av_free(outbuf);
+    }
+
+    maru_brill_codec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id);
+
+    TRACE("[%s] leave:\n", __func__);
+
+    return true;
+}
+
+static AVCodecParserContext *maru_brill_codec_parser_init(AVCodecContext *avctx)
+{
+    AVCodecParserContext *parser = NULL;
+
+    if (!avctx) {
+        ERR("context is NULL\n");
+        return NULL;
+    }
+
+    switch (avctx->codec_id) {
+    case CODEC_ID_MPEG4:
+    case CODEC_ID_VC1:
+        TRACE("not using parser.\n");
+        break;
+    case CODEC_ID_H264:
+        if (avctx->extradata_size == 0) {
+            TRACE("H.264 with no extradata, creating parser.\n");
+            parser = av_parser_init (avctx->codec_id);
+        }
+        break;
+    default:
+        parser = av_parser_init (avctx->codec_id);
+        if (parser) {
+            INFO("using parser. %d\n", avctx->codec_id);
+        }
+        break;
+    }
+
+    return parser;
+}
+
+static void maru_brill_codec_bh_callback(void *opaque)
+{
+    MaruBrillCodecState *s = (MaruBrillCodecState *)opaque;
+
+    TRACE("enter: %s\n", __func__);
+
+    qemu_mutex_lock(&s->context_queue_mutex);
+    if (!QTAILQ_EMPTY(&codec_wq)) {
+        qemu_mutex_unlock(&s->context_queue_mutex);
+
+        TRACE("raise irq\n");
+        pci_set_irq(&s->dev, 1);
+        s->irq_raised = 1;
+    } else {
+        qemu_mutex_unlock(&s->context_queue_mutex);
+        TRACE("codec_wq is empty!!\n");
+    }
+
+    TRACE("leave: %s\n", __func__);
+}
+
+/*
+ *  Codec Device APIs
+ */
+static uint64_t maru_brill_codec_read(void *opaque,
+                                        hwaddr addr,
+                                        unsigned size)
+{
+    MaruBrillCodecState *s = (MaruBrillCodecState *)opaque;
+    uint64_t ret = 0;
+
+    switch (addr) {
+    case CODEC_CMD_GET_THREAD_STATE:
+        qemu_mutex_lock(&s->context_queue_mutex);
+        if (s->irq_raised) {
+            ret = CODEC_TASK_END;
+            pci_set_irq(&s->dev, 0);
+            s->irq_raised = 0;
+        }
+        qemu_mutex_unlock(&s->context_queue_mutex);
+
+        TRACE("get thread_state. ret: %d\n", ret);
+        break;
+
+    case CODEC_CMD_GET_CTX_FROM_QUEUE:
+    {
+        DeviceMemEntry *head = NULL;
+
+        qemu_mutex_lock(&s->context_queue_mutex);
+        head = QTAILQ_FIRST(&codec_wq);
+        if (head) {
+            ret = head->ctx_id;
+            QTAILQ_REMOVE(&codec_wq, head, node);
+            entry[ret] = head;
+            TRACE("get a elem from codec_wq. 0x%x\n", head);
+        } else {
+            ret = 0;
+        }
+        qemu_mutex_unlock(&s->context_queue_mutex);
+
+        TRACE("get a head from a writequeue. head: %x\n", ret);
+    }
+        break;
+
+    case CODEC_CMD_GET_VERSION:
+        ret = CODEC_VERSION;
+        TRACE("codec version: %d\n", ret);
+        break;
+
+    case CODEC_CMD_GET_ELEMENT:
+        ret = maru_brill_codec_query_list(s);
+        break;
+
+    case CODEC_CMD_GET_CONTEXT_INDEX:
+        ret = maru_brill_codec_get_context_index(s);
+        TRACE("get context index: %d\n", ret);
+        break;
+
+    default:
+        ERR("no avaiable command for read. %d\n", addr);
+    }
+
+    return ret;
+}
+
+static void maru_brill_codec_write(void *opaque, hwaddr addr,
+                                    uint64_t value, unsigned size)
+{
+    MaruBrillCodecState *s = (MaruBrillCodecState *)opaque;
+
+    switch (addr) {
+    case CODEC_CMD_API_INDEX:
+        TRACE("set codec_cmd value: %d\n", value);
+        s->ioparam.api_index = value;
+        maru_brill_codec_wakeup_threads(s, value);
+        break;
+
+    case CODEC_CMD_CONTEXT_INDEX:
+        TRACE("set context_index value: %d\n", value);
+        s->ioparam.ctx_index = value;
+        break;
+
+    case CODEC_CMD_DEVICE_MEM_OFFSET:
+        TRACE("set mem_offset value: 0x%x\n", value);
+        s->ioparam.mem_offset = value;
+        break;
+
+    case CODEC_CMD_RELEASE_CONTEXT:
+    {
+        int ctx_index = (int32_t)value;
+
+        if (s->context[ctx_index].occupied_thread) {
+            s->context[ctx_index].requested_close = true;
+            INFO("make running thread to handle deinit\n");
+        } else {
+            maru_brill_codec_release_context(s, ctx_index);
+        }
+    }
+        break;
+
+    case CODEC_CMD_GET_DATA_FROM_QUEUE:
+        maru_brill_codec_pop_writequeue(s, (uint32_t)value);
+        break;
+
+    default:
+        ERR("no available command for write. %d\n", addr);
+    }
+}
+
+static const MemoryRegionOps maru_brill_codec_mmio_ops = {
+    .read = maru_brill_codec_read,
+    .write = maru_brill_codec_write,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+        .unaligned = false
+    },
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static int maru_brill_codec_initfn(PCIDevice *dev)
+{
+    MaruBrillCodecState *s = DO_UPCAST(MaruBrillCodecState, dev, dev);
+    uint8_t *pci_conf = s->dev.config;
+
+    INFO("device initialization.\n");
+    pci_config_set_interrupt_pin(pci_conf, 1);
+
+    memory_region_init_ram(&s->vram, OBJECT(s), "maru_brill_codec.vram", CODEC_MEM_SIZE);
+    s->vaddr = (uint8_t *)memory_region_get_ram_ptr(&s->vram);
+
+    memory_region_init_io(&s->mmio, OBJECT(s), &maru_brill_codec_mmio_ops, s,
+                        "maru_brill_codec.mmio", CODEC_REG_SIZE);
+
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
+    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);
+
+    qemu_mutex_init(&s->context_mutex);
+    qemu_mutex_init(&s->context_queue_mutex);
+    qemu_mutex_init(&s->ioparam_queue_mutex);
+
+    maru_brill_codec_get_cpu_cores(s);
+    maru_brill_codec_threads_create(s);
+
+    // register a function to qemu bottom-halves to switch context.
+    s->codec_bh = qemu_bh_new(maru_brill_codec_bh_callback, s);
+
+    return 0;
+}
+
+static void maru_brill_codec_exitfn(PCIDevice *dev)
+{
+    MaruBrillCodecState *s = DO_UPCAST(MaruBrillCodecState, dev, dev);
+    INFO("device exit\n");
+
+    qemu_mutex_destroy(&s->context_mutex);
+    qemu_mutex_destroy(&s->context_queue_mutex);
+    qemu_mutex_destroy(&s->ioparam_queue_mutex);
+
+    qemu_bh_delete(s->codec_bh);
+
+    memory_region_destroy(&s->vram);
+    memory_region_destroy(&s->mmio);
+}
+
+static void maru_brill_codec_reset(DeviceState *d)
+{
+    MaruBrillCodecState *s = (MaruBrillCodecState *)d;
+    INFO("device reset\n");
+
+    s->irq_raised = 0;
+
+    memset(&s->context, 0, sizeof(CodecContext) * CODEC_CONTEXT_MAX);
+    memset(&s->ioparam, 0, sizeof(CodecParam));
+
+    maru_brill_codec_pixfmt_info_init();
+}
+
+static void maru_brill_codec_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = maru_brill_codec_initfn;
+    k->exit = maru_brill_codec_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_TIZEN;
+    k->device_id = PCI_DEVICE_ID_VIRTUAL_BRILL_CODEC;
+    k->class_id = PCI_CLASS_OTHERS;
+    dc->reset = maru_brill_codec_reset;
+    dc->desc = "Virtual new codec device for Tizen emulator";
+}
+
+static TypeInfo codec_device_info = {
+    .name          = CODEC_DEVICE_NAME,
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(MaruBrillCodecState),
+    .class_init    = maru_brill_codec_class_init,
+};
+
+static void codec_register_types(void)
+{
+    type_register_static(&codec_device_info);
+}
+
+type_init(codec_register_types)
diff --git a/tizen/src/hw/pci/maru_brill_codec.h b/tizen/src/hw/pci/maru_brill_codec.h
new file mode 100644 (file)
index 0000000..21c5bd5
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ * Virtual Codec device
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Kitae Kim <kt920.kim@samsung.com>
+ *  SeokYeon Hwang <syeon.hwang@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 <stdio.h>
+#include <sys/types.h>
+
+#include "hw/hw.h"
+#include "sysemu/kvm.h"
+#include "qemu/main-loop.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_ids.h"
+#include "qemu-common.h"
+#include "qemu/thread.h"
+
+#include "util/osutil.h"
+#include "debug_ch.h"
+#include "hw/maru_device_ids.h"
+
+#include "libavformat/avformat.h"
+#include "libavresample/avresample.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+
+#define CODEC_CONTEXT_MAX           1024
+
+/*
+ *  Codec Device Structures
+ */
+typedef struct CodecParam {
+    int32_t     api_index;
+    int32_t     ctx_index;
+    uint32_t    mem_offset;
+} CodecParam;
+
+struct video_data {
+    int32_t width;
+    int32_t height;
+    int32_t fps_n;
+    int32_t fps_d;
+    int32_t par_n;
+    int32_t par_d;
+    int32_t pix_fmt;
+    int32_t bpp;
+    int32_t ticks_per_frame;
+};
+
+struct audio_data {
+    int32_t channels;
+    int32_t sample_rate;
+    int32_t block_align;
+    int32_t depth;
+    int32_t sample_fmt;
+    int32_t frame_size;
+    int32_t bits_per_smp_fmt;
+    int32_t reserved;
+    int64_t channel_layout;
+};
+
+typedef struct CodecContext {
+    AVCodecContext          *avctx;
+    AVFrame                 *frame;
+    AVCodecParserContext    *parser_ctx;
+    uint8_t                 *parser_buf;
+    uint16_t                parser_use;
+    bool                    occupied_context;
+    bool                    occupied_thread;
+    bool                    opened_context;
+    bool                    requested_close;
+} CodecContext;
+
+typedef struct CodecThreadPool {
+    QemuThread          *threads;
+    QemuMutex           mutex;
+    QemuCond            cond;
+} CodecThreadPool;
+
+typedef struct MaruBrillCodecState {
+    PCIDevice           dev;
+
+    uint8_t             *vaddr;
+    MemoryRegion        vram;
+    MemoryRegion        mmio;
+
+    QEMUBH              *codec_bh;
+    QemuMutex           context_mutex;
+    QemuMutex           context_queue_mutex;
+    QemuMutex           ioparam_queue_mutex;
+
+    CodecThreadPool     threadpool;
+    bool                is_thread_running;
+    uint32_t            worker_thread_cnt;
+    uint32_t            idle_thread_cnt;
+
+    int                 irq_raised;
+
+    CodecContext        context[CODEC_CONTEXT_MAX];
+    CodecParam          ioparam;
+} MaruBrillCodecState;
+
+enum codec_io_cmd {
+    CODEC_CMD_API_INDEX             = 0x28,
+    CODEC_CMD_CONTEXT_INDEX         = 0x2C,
+    CODEC_CMD_DEVICE_MEM_OFFSET     = 0x34,
+    CODEC_CMD_GET_THREAD_STATE      = 0x38,
+    CODEC_CMD_GET_CTX_FROM_QUEUE    = 0x3C,
+    CODEC_CMD_GET_DATA_FROM_QUEUE   = 0x40,
+    CODEC_CMD_RELEASE_CONTEXT       = 0x44,
+    CODEC_CMD_GET_VERSION           = 0x50,
+    CODEC_CMD_GET_ELEMENT           = 0x54,
+    CODEC_CMD_GET_CONTEXT_INDEX     = 0x58,
+};
+
+enum codec_api_type {
+    CODEC_INIT = 0,
+    CODEC_DECODE_VIDEO,
+    CODEC_ENCODE_VIDEO,
+    CODEC_DECODE_AUDIO,
+    CODEC_ENCODE_AUDIO,
+    CODEC_PICTURE_COPY,
+    CODEC_DEINIT,
+    CODEC_FLUSH_BUFFERS,
+ };
+
+enum codec_type {
+    CODEC_TYPE_UNKNOWN = -1,
+    CODEC_TYPE_DECODE,
+    CODEC_TYPE_ENCODE,
+};
+
+enum thread_state {
+    CODEC_TASK_START    = 0,
+    CODEC_TASK_END      = 0x1f,
+};
+
+/*
+ *  Codec Device Functions
+ */
+int maru_brill_codec_pci_device_init(PCIBus *bus);
diff --git a/tizen/src/hw/pci/maru_camera_common.h b/tizen/src/hw/pci/maru_camera_common.h
new file mode 100644 (file)
index 0000000..45b1a38
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Common header of MARU Virtual Camera device.
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * JinHyung Jo <jinhyung.jo@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_CAMERA_COMMON_H_
+#define _MARU_CAMERA_COMMON_H_
+
+#include "hw/pci/pci.h"
+#include "qemu/thread.h"
+
+#define MARUCAM_MAX_PARAM    20
+#define MARUCAM_SKIPFRAMES    2
+
+/* must sync with GUEST camera_driver */
+#define MARUCAM_CMD_INIT           0x00
+#define MARUCAM_CMD_OPEN           0x04
+#define MARUCAM_CMD_CLOSE          0x08
+#define MARUCAM_CMD_ISR            0x0C
+#define MARUCAM_CMD_START_PREVIEW  0x10
+#define MARUCAM_CMD_STOP_PREVIEW   0x14
+#define MARUCAM_CMD_S_PARAM        0x18
+#define MARUCAM_CMD_G_PARAM        0x1C
+#define MARUCAM_CMD_ENUM_FMT       0x20
+#define MARUCAM_CMD_TRY_FMT        0x24
+#define MARUCAM_CMD_S_FMT          0x28
+#define MARUCAM_CMD_G_FMT          0x2C
+#define MARUCAM_CMD_QCTRL          0x30
+#define MARUCAM_CMD_S_CTRL         0x34
+#define MARUCAM_CMD_G_CTRL         0x38
+#define MARUCAM_CMD_ENUM_FSIZES    0x3C
+#define MARUCAM_CMD_ENUM_FINTV     0x40
+#define MARUCAM_CMD_S_DATA         0x44
+#define MARUCAM_CMD_G_DATA         0x48
+#define MARUCAM_CMD_DATACLR        0x50
+#define MARUCAM_CMD_REQFRAME       0x54
+
+typedef struct MaruCamState MaruCamState;
+typedef struct MaruCamParam MaruCamParam;
+
+struct MaruCamParam {
+    uint32_t    top;
+    uint32_t    retVal;
+    uint32_t    errCode;
+    uint32_t    stack[MARUCAM_MAX_PARAM];
+};
+
+struct MaruCamState {
+    PCIDevice           dev;
+    MaruCamParam        *param;
+    QemuThread          thread_id;
+    QemuMutex           thread_mutex;;
+    QemuCond            thread_cond;
+    QEMUBH              *tx_bh;
+
+    bool                initialized;
+    bool                destroying;
+    void                *vaddr;     /* vram ptr */
+    uint32_t            isr;
+    uint32_t            streamon;
+    uint32_t            buf_size;
+    uint32_t            req_frame;
+
+    MemoryRegion        vram;
+    MemoryRegion        mmio;
+};
+
+/* ------------------------------------------------------------------------- */
+/* Fucntion prototype                                                        */
+/* ------------------------------------------------------------------------- */
+int marucam_device_check(int log_flag);
+void marucam_device_init(MaruCamState *state);
+void marucam_device_exit(MaruCamState *state);
+void marucam_device_open(MaruCamState *state);
+void marucam_device_close(MaruCamState *state);
+void marucam_device_start_preview(MaruCamState *state);
+void marucam_device_stop_preview(MaruCamState *state);
+void marucam_device_s_param(MaruCamState *state);
+void marucam_device_g_param(MaruCamState *state);
+void marucam_device_s_fmt(MaruCamState *state);
+void marucam_device_g_fmt(MaruCamState *state);
+void marucam_device_try_fmt(MaruCamState *state);
+void marucam_device_enum_fmt(MaruCamState *state);
+void marucam_device_qctrl(MaruCamState *state);
+void marucam_device_s_ctrl(MaruCamState *state);
+void marucam_device_g_ctrl(MaruCamState *state);
+void marucam_device_enum_fsizes(MaruCamState *state);
+void marucam_device_enum_fintv(MaruCamState *state);
+
+int maru_camera_pci_init(PCIBus *bus);
+
+#endif  /* _MARU_CAMERA_COMMON_H_ */
diff --git a/tizen/src/hw/pci/maru_camera_common_pci.c b/tizen/src/hw/pci/maru_camera_common_pci.c
new file mode 100644 (file)
index 0000000..694dea4
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+ * Common implementation of MARU Virtual Camera device by PCI bus.
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * JinHyung Jo <jinhyung.jo@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 <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <signal.h>
+
+#include "qemu-common.h"
+#include "qemu/main-loop.h"
+#include "exec/cpu-common.h"
+
+#include "maru_camera_common.h"
+#include "hw/maru_device_ids.h"
+#include "debug_ch.h"
+
+MULTI_DEBUG_CHANNEL(tizen, maru-camera);
+
+#define MARU_PCI_CAMERA_DEVICE_NAME     "maru-camera"
+
+#define MARUCAM_MEM_SIZE    (4 * 1024 * 1024)   /* 4MB */
+#define MARUCAM_REG_SIZE    (256)               /* 64 * 4Byte */
+
+/*
+ *  I/O functions
+ */
+static inline uint32_t
+marucam_mmio_read(void *opaque, hwaddr offset)
+{
+    uint32_t ret = 0;
+    MaruCamState *state = (MaruCamState *)opaque;
+
+    switch (offset & 0xFF) {
+    case MARUCAM_CMD_ISR:
+        qemu_mutex_lock(&state->thread_mutex);
+        ret = state->isr;
+        if (ret != 0) {
+            pci_set_irq(&state->dev, 0);
+            state->isr = 0;
+        }
+        qemu_mutex_unlock(&state->thread_mutex);
+        break;
+    case MARUCAM_CMD_G_DATA:
+        ret = state->param->stack[state->param->top++];
+        break;
+    case MARUCAM_CMD_OPEN:
+    case MARUCAM_CMD_CLOSE:
+    case MARUCAM_CMD_START_PREVIEW:
+    case MARUCAM_CMD_STOP_PREVIEW:
+    case MARUCAM_CMD_S_PARAM:
+    case MARUCAM_CMD_G_PARAM:
+    case MARUCAM_CMD_ENUM_FMT:
+    case MARUCAM_CMD_TRY_FMT:
+    case MARUCAM_CMD_S_FMT:
+    case MARUCAM_CMD_G_FMT:
+    case MARUCAM_CMD_QCTRL:
+    case MARUCAM_CMD_S_CTRL:
+    case MARUCAM_CMD_G_CTRL:
+    case MARUCAM_CMD_ENUM_FSIZES:
+    case MARUCAM_CMD_ENUM_FINTV:
+        ret = state->param->errCode;
+        state->param->errCode = 0;
+        break;
+    default:
+        ERR("Not supported command: 0x%x\n", offset);
+        ret = EINVAL;
+        break;
+    }
+    return ret;
+}
+
+static inline void
+marucam_mmio_write(void *opaque, hwaddr offset, uint32_t value)
+{
+    MaruCamState *state = (MaruCamState *)opaque;
+
+    switch (offset & 0xFF) {
+    case MARUCAM_CMD_OPEN:
+        marucam_device_open(state);
+        break;
+    case MARUCAM_CMD_CLOSE:
+        marucam_device_close(state);
+        break;
+    case MARUCAM_CMD_START_PREVIEW:
+        marucam_device_start_preview(state);
+        break;
+    case MARUCAM_CMD_STOP_PREVIEW:
+        marucam_device_stop_preview(state);
+        memset(state->vaddr, 0, MARUCAM_MEM_SIZE);
+        break;
+    case MARUCAM_CMD_S_PARAM:
+        marucam_device_s_param(state);
+        break;
+    case MARUCAM_CMD_G_PARAM:
+        marucam_device_g_param(state);
+        break;
+    case MARUCAM_CMD_ENUM_FMT:
+        marucam_device_enum_fmt(state);
+        break;
+    case MARUCAM_CMD_TRY_FMT:
+        marucam_device_try_fmt(state);
+        break;
+    case MARUCAM_CMD_S_FMT:
+        marucam_device_s_fmt(state);
+        break;
+    case MARUCAM_CMD_G_FMT:
+        marucam_device_g_fmt(state);
+        break;
+    case MARUCAM_CMD_QCTRL:
+        marucam_device_qctrl(state);
+        break;
+    case MARUCAM_CMD_S_CTRL:
+        marucam_device_s_ctrl(state);
+        break;
+    case MARUCAM_CMD_G_CTRL:
+        marucam_device_g_ctrl(state);
+        break;
+    case MARUCAM_CMD_ENUM_FSIZES:
+        marucam_device_enum_fsizes(state);
+        break;
+    case MARUCAM_CMD_ENUM_FINTV:
+        marucam_device_enum_fintv(state);
+        break;
+    case MARUCAM_CMD_S_DATA:
+        state->param->stack[state->param->top++] = value;
+        break;
+    case MARUCAM_CMD_DATACLR:
+        memset(state->param, 0, sizeof(MaruCamParam));
+        break;
+    case MARUCAM_CMD_REQFRAME:
+        qemu_mutex_lock(&state->thread_mutex);
+        state->req_frame = value + 1;
+        qemu_mutex_unlock(&state->thread_mutex);
+        break;
+    default:
+        ERR("Not supported command: 0x%x\n", offset);
+        break;
+    }
+}
+
+static const MemoryRegionOps maru_camera_mmio_ops = {
+    .old_mmio = {
+        .read = {
+            marucam_mmio_read,
+            marucam_mmio_read,
+            marucam_mmio_read,
+        },
+        .write = {
+            marucam_mmio_write,
+            marucam_mmio_write,
+            marucam_mmio_write,
+        },
+    },
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+/*
+ *  QEMU bottom half funtion
+ */
+static void marucam_tx_bh(void *opaque)
+{
+    MaruCamState *state = (MaruCamState *)opaque;
+
+    qemu_mutex_lock(&state->thread_mutex);
+    if (state->isr) {
+        pci_set_irq(&state->dev, 1);
+    }
+    qemu_mutex_unlock(&state->thread_mutex);
+}
+
+/*
+ *  Initialization function
+ */
+
+static int marucam_initfn(PCIDevice *dev)
+{
+    MaruCamState *s = DO_UPCAST(MaruCamState, dev, dev);
+    uint8_t *pci_conf = s->dev.config;
+
+    /* Check available webcam
+     * If there is not one, you can't use the camera.
+     */
+    if (!marucam_device_check(1)) {
+        s->initialized = false;
+        ERR("Failed to check the camera device, "
+            "You can *not* use the camera\n");
+        return 0;
+    }
+
+    pci_config_set_interrupt_pin(pci_conf, 0x03);
+
+    memory_region_init_ram(&s->vram, OBJECT(s), "marucamera.ram", MARUCAM_MEM_SIZE);
+    s->vaddr = memory_region_get_ram_ptr(&s->vram);
+    memset(s->vaddr, 0, MARUCAM_MEM_SIZE);
+
+    memory_region_init_io(&s->mmio, OBJECT(s),
+                          &maru_camera_mmio_ops,
+                          s,
+                          "maru-camera-mmio",
+                          MARUCAM_REG_SIZE);
+
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
+    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);
+
+    /* for worker thread */
+    s->param = (MaruCamParam *)g_malloc0(sizeof(MaruCamParam));
+    qemu_cond_init(&s->thread_cond);
+    qemu_mutex_init(&s->thread_mutex);
+
+    marucam_device_init(s);
+
+    s->tx_bh = qemu_bh_new(marucam_tx_bh, s);
+    s->initialized = true;
+    INFO("initialize maru-camera device\n");
+
+    return 0;
+}
+
+/*
+ *  Termination function
+ */
+static void marucam_exitfn(PCIDevice *pci_dev)
+{
+    MaruCamState *s =
+        OBJECT_CHECK(MaruCamState, pci_dev, MARU_PCI_CAMERA_DEVICE_NAME);
+
+    if (s->initialized) {
+        marucam_device_exit(s);
+        g_free(s->param);
+        qemu_cond_destroy(&s->thread_cond);
+        qemu_mutex_destroy(&s->thread_mutex);
+
+        memory_region_destroy(&s->vram);
+        memory_region_destroy(&s->mmio);
+    }
+
+    INFO("finalize maru-camera device\n");
+}
+
+static void marucam_resetfn(DeviceState *d)
+{
+    MaruCamState *s = (MaruCamState *)d;
+
+    if (s->initialized) {
+        marucam_device_close(s);
+        qemu_mutex_lock(&s->thread_mutex);
+        s->isr = s->streamon = s->req_frame = s->buf_size = 0;
+        qemu_mutex_unlock(&s->thread_mutex);
+        memset(s->vaddr, 0, MARUCAM_MEM_SIZE);
+        memset(s->param, 0x00, sizeof(MaruCamParam));
+        INFO("reset maru-camera device\n");
+    }
+}
+
+int maru_camera_pci_init(PCIBus *bus)
+{
+    pci_create_simple(bus, -1, MARU_PCI_CAMERA_DEVICE_NAME);
+    return 0;
+}
+
+static void maru_camera_pci_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = marucam_initfn;
+    k->exit = marucam_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_TIZEN;
+    k->device_id = PCI_DEVICE_ID_VIRTUAL_CAMERA;
+    k->class_id = PCI_CLASS_OTHERS;
+    dc->reset = marucam_resetfn;
+    dc->desc = "MARU Virtual Camera device for Tizen emulator";
+}
+
+static TypeInfo maru_camera_info = {
+    .name          = MARU_PCI_CAMERA_DEVICE_NAME,
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(MaruCamState),
+    .class_init    = maru_camera_pci_class_init,
+};
+
+static void maru_camera_pci_register_types(void)
+{
+    type_register_static(&maru_camera_info);
+}
+
+type_init(maru_camera_pci_register_types)
diff --git a/tizen/src/hw/pci/maru_camera_darwin.h b/tizen/src/hw/pci/maru_camera_darwin.h
new file mode 100644 (file)
index 0000000..2ac39f9
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Header of MARU Virtual Camera device for MacOS.
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * Jun Tian <jun.j.tian@intel.com>
+ * JinHyung Jo <jinhyung.jo@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_CAMERA_DARWIN_H_
+#define _MARU_CAMERA_DARWIN_H_
+
+#define MAKEFOURCC(a, b, c, d) \
+    (((uint32_t)(a) << 0) | \
+     ((uint32_t)(b) << 8) | \
+     ((uint32_t)(c) << 16) | \
+     ((uint32_t)(d) << 24))
+
+/* 16  RGB-5-5-5     */
+#define V4L2_PIX_FMT_RGB555  MAKEFOURCC('R', 'G', 'B', 'O')
+/* 16  RGB-5-6-5     */
+#define V4L2_PIX_FMT_RGB565  MAKEFOURCC('R', 'G', 'B', 'P')
+/* 16  RGB-5-5-5 BE  */
+#define V4L2_PIX_FMT_RGB555X MAKEFOURCC('R', 'G', 'B', 'Q')
+/* 16  RGB-5-6-5 BE  */
+#define V4L2_PIX_FMT_RGB565X MAKEFOURCC('R', 'G', 'B', 'R')
+/* 24  BGR-8-8-8     */
+#define V4L2_PIX_FMT_BGR24   MAKEFOURCC('B', 'G', 'R', '3')
+/* 24  RGB-8-8-8     */
+#define V4L2_PIX_FMT_RGB24   MAKEFOURCC('R', 'G', 'B', '3')
+/* 32  BGR-8-8-8-8   */
+#define V4L2_PIX_FMT_BGR32   MAKEFOURCC('B', 'G', 'R', '4')
+/* 32  RGB-8-8-8-8   */
+#define V4L2_PIX_FMT_RGB32   MAKEFOURCC('R', 'G', 'B', '4')
+/*  9  YVU 4:1:0     */
+#define V4L2_PIX_FMT_YVU410  MAKEFOURCC('Y', 'V', 'U', '9')
+/* 12  YVU 4:2:0     */
+#define V4L2_PIX_FMT_YVU420  MAKEFOURCC('Y', 'V', '1', '2')
+/* 16  YUV 4:2:2     */
+#define V4L2_PIX_FMT_YUYV    MAKEFOURCC('Y', 'U', 'Y', 'V')
+/* 16  YUV 4:2:2     */
+#define V4L2_PIX_FMT_UYVY    MAKEFOURCC('U', 'Y', 'V', 'Y')
+/* 16  YVU422 planar */
+#define V4L2_PIX_FMT_YUV422P MAKEFOURCC('4', '2', '2', 'P')
+/* 16  YVU411 planar */
+#define V4L2_PIX_FMT_YUV411P MAKEFOURCC('4', '1', '1', 'P')
+/* 12  YUV 4:1:1     */
+#define V4L2_PIX_FMT_Y41P    MAKEFOURCC('Y', '4', '1', 'P')
+/* 16  xxxxyyyy uuuuvvvv */
+#define V4L2_PIX_FMT_YUV444  MAKEFOURCC('Y', '4', '4', '4')
+/* 16  YUV-5-5-5     */
+#define V4L2_PIX_FMT_YUV555  MAKEFOURCC('Y', 'U', 'V', 'O')
+/* 16  YUV-5-6-5     */
+#define V4L2_PIX_FMT_YUV565  MAKEFOURCC('Y', 'U', 'V', 'P')
+/* 32  YUV-8-8-8-8   */
+#define V4L2_PIX_FMT_YUV32   MAKEFOURCC('Y', 'U', 'V', '4')
+/*  9  YUV 4:1:0     */
+#define V4L2_PIX_FMT_YUV410  MAKEFOURCC('Y', 'U', 'V', '9')
+/* 12  YUV 4:2:0     */
+#define V4L2_PIX_FMT_YUV420  MAKEFOURCC('Y', 'U', '1', '2')
+/* 16  YUV 4:2:2     */
+#define V4L2_PIX_FMT_YYUV    MAKEFOURCC('Y', 'Y', 'U', 'V')
+
+void convert_frame(uint32_t pixel_format, int frame_width, int frame_height,
+                   size_t frame_size, void *frame_pixels, void *video_buf);
+
+#endif /* _MARU_CAMERA_DARWIN_H_ */
diff --git a/tizen/src/hw/pci/maru_camera_darwin_converter.c b/tizen/src/hw/pci/maru_camera_darwin_converter.c
new file mode 100644 (file)
index 0000000..24c560f
--- /dev/null
@@ -0,0 +1,385 @@
+/*
+ * Implementation of color conversion for MARU Virtual Camera device on MacOS.
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * Jun Tian <jun.j.tian@intel.com>
+ * JinHyung Jo <jinhyung.jo@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 "qemu-common.h"
+#include "maru_camera_darwin.h"
+#include "debug_ch.h"
+
+MULTI_DEBUG_CHANNEL(tizen, camera_darwin);
+
+static void UYVYToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
+                         int width, int height);
+static void YVU420ToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
+                           int width, int height);
+static void YUYVToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
+                         int width, int height);
+
+/* Convert pixel format to YUV420 */
+void convert_frame(uint32_t pixel_format, int frame_width, int frame_height,
+                   size_t frame_size, void *frame_pixels, void *video_buf)
+{
+    switch (pixel_format) {
+    case V4L2_PIX_FMT_YUV420:
+        memcpy(video_buf, (void *)frame_pixels, (size_t)frame_size);
+        break;
+    case V4L2_PIX_FMT_YVU420:
+        YVU420ToYUV420(frame_pixels, video_buf, frame_width, frame_height);
+        break;
+    case V4L2_PIX_FMT_YUYV:
+        YUYVToYUV420(frame_pixels, video_buf, frame_width, frame_height);
+        break;
+    case V4L2_PIX_FMT_UYVY: /* Mac default format */
+        UYVYToYUV420(frame_pixels, video_buf, frame_width, frame_height);
+        break;
+    default:
+        ERR("Cannot convert the pixel format (%.4s)...\n",
+               (const char *)&pixel_format);
+        break;
+    }
+}
+
+static void UYVYToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
+                         int width, int height)
+{
+    int i, j;
+
+    /* Source */
+    unsigned char *ptrsrcy1, *ptrsrcy2;
+    unsigned char *ptrsrcy3, *ptrsrcy4;
+    unsigned char *ptrsrccb1;
+    unsigned char *ptrsrccb3;
+    unsigned char *ptrsrccr1;
+    unsigned char *ptrsrccr3;
+    int srcystride, srcccstride;
+
+    ptrsrcy1  = bufsrc + 1;
+    ptrsrcy2  = bufsrc + (width << 1) + 1;
+    ptrsrcy3  = bufsrc + (width << 1) * 2 + 1;
+    ptrsrcy4  = bufsrc + (width << 1) * 3 + 1;
+
+    ptrsrccb1 = bufsrc;
+    ptrsrccb3 = bufsrc + (width << 1) * 2;
+
+    ptrsrccr1 = bufsrc + 2;
+    ptrsrccr3 = bufsrc + (width << 1) * 2 + 2;
+
+    srcystride  = (width << 1) * 3;
+    srcccstride = (width << 1) * 3;
+
+    /* Destination */
+    unsigned char *ptrdesty1, *ptrdesty2;
+    unsigned char *ptrdesty3, *ptrdesty4;
+    unsigned char *ptrdestcb1, *ptrdestcb2;
+    unsigned char *ptrdestcr1, *ptrdestcr2;
+    int destystride, destccstride;
+
+    ptrdesty1 = bufdest;
+    ptrdesty2 = bufdest + width;
+    ptrdesty3 = bufdest + width * 2;
+    ptrdesty4 = bufdest + width * 3;
+
+    ptrdestcb1 = bufdest + width * height;
+    ptrdestcb2 = bufdest + width * height + (width >> 1);
+
+    ptrdestcr1 = bufdest + width * height + ((width*height) >> 2);
+    ptrdestcr2 = bufdest + width * height + ((width*height) >> 2)
+                 + (width >> 1);
+
+    destystride  = (width)*3;
+    destccstride = (width>>1);
+
+    for (j = 0; j < (height / 4); j++) {
+        for (i = 0; i < (width / 2); i++) {
+            (*ptrdesty1++) = (*ptrsrcy1);
+            (*ptrdesty2++) = (*ptrsrcy2);
+            (*ptrdesty3++) = (*ptrsrcy3);
+            (*ptrdesty4++) = (*ptrsrcy4);
+
+            ptrsrcy1 += 2;
+            ptrsrcy2 += 2;
+            ptrsrcy3 += 2;
+            ptrsrcy4 += 2;
+
+            (*ptrdesty1++) = (*ptrsrcy1);
+            (*ptrdesty2++) = (*ptrsrcy2);
+            (*ptrdesty3++) = (*ptrsrcy3);
+            (*ptrdesty4++) = (*ptrsrcy4);
+
+            ptrsrcy1 += 2;
+            ptrsrcy2 += 2;
+            ptrsrcy3 += 2;
+            ptrsrcy4 += 2;
+
+            (*ptrdestcb1++) = (*ptrsrccb1);
+            (*ptrdestcb2++) = (*ptrsrccb3);
+
+            ptrsrccb1 += 4;
+            ptrsrccb3 += 4;
+
+            (*ptrdestcr1++) = (*ptrsrccr1);
+            (*ptrdestcr2++) = (*ptrsrccr3);
+
+            ptrsrccr1 += 4;
+            ptrsrccr3 += 4;
+
+        }
+
+        /* Update src pointers */
+        ptrsrcy1  += srcystride;
+        ptrsrcy2  += srcystride;
+        ptrsrcy3  += srcystride;
+        ptrsrcy4  += srcystride;
+
+        ptrsrccb1 += srcccstride;
+        ptrsrccb3 += srcccstride;
+
+        ptrsrccr1 += srcccstride;
+        ptrsrccr3 += srcccstride;
+
+        /* Update dest pointers */
+        ptrdesty1 += destystride;
+        ptrdesty2 += destystride;
+        ptrdesty3 += destystride;
+        ptrdesty4 += destystride;
+
+        ptrdestcb1 += destccstride;
+        ptrdestcb2 += destccstride;
+
+        ptrdestcr1 += destccstride;
+        ptrdestcr2 += destccstride;
+    }
+}
+
+static void YVU420ToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
+                           int width, int height)
+{
+    int i, j;
+
+    /* Source*/
+    unsigned char *ptrsrcy1, *ptrsrcy2;
+    unsigned char *ptrsrcy3, *ptrsrcy4;
+    unsigned char *ptrsrccb1, *ptrsrccb2;
+    unsigned char *ptrsrccr1, *ptrsrccr2;
+    int srcystride, srcccstride;
+
+    ptrsrcy1 = bufsrc;
+    ptrsrcy2 = bufsrc + width;
+    ptrsrcy3 = bufsrc + width*2;
+    ptrsrcy4 = bufsrc + width*3;
+
+    ptrsrccr1 = bufsrc + width*height;
+    ptrsrccr2 = bufsrc + width*height + (width>>1);
+
+    ptrsrccb1 = bufsrc + width*height + ((width*height) >> 2);
+    ptrsrccb2 = bufsrc + width*height + ((width*height) >> 2) + (width>>1);
+
+    srcystride  = (width)*3;
+    srcccstride = (width>>1);
+
+    /* Destination */
+    unsigned char *ptrdesty1, *ptrdesty2;
+    unsigned char *ptrdesty3, *ptrdesty4;
+    unsigned char *ptrdestcb1, *ptrdestcb2;
+    unsigned char *ptrdestcr1, *ptrdestcr2;
+    int destystride, destccstride;
+
+    ptrdesty1 = bufdest;
+    ptrdesty2 = bufdest + width;
+    ptrdesty3 = bufdest + width * 2;
+    ptrdesty4 = bufdest + width * 3;
+
+    ptrdestcb1 = bufdest + width * height;
+    ptrdestcb2 = bufdest + width * height + (width >> 1);
+
+    ptrdestcr1 = bufdest + width * height + ((width*height) >> 2);
+    ptrdestcr2 = bufdest + width * height + ((width*height) >> 2)
+                 + (width >> 1);
+
+    destystride  = (width)*3;
+    destccstride = (width>>1);
+
+    for (j = 0; j < (height / 4); j++) {
+        for (i = 0; i < (width / 2); i++) {
+
+            (*ptrdesty1++) = (*ptrsrcy1++);
+            (*ptrdesty2++) = (*ptrsrcy2++);
+            (*ptrdesty3++) = (*ptrsrcy3++);
+            (*ptrdesty4++) = (*ptrsrcy4++);
+            (*ptrdesty1++) = (*ptrsrcy1++);
+            (*ptrdesty2++) = (*ptrsrcy2++);
+            (*ptrdesty3++) = (*ptrsrcy3++);
+            (*ptrdesty4++) = (*ptrsrcy4++);
+
+            (*ptrdestcb1++) = (*ptrsrccb1++);
+            (*ptrdestcr1++) = (*ptrsrccr1++);
+            (*ptrdestcb2++) = (*ptrsrccb2++);
+            (*ptrdestcr2++) = (*ptrsrccr2++);
+
+        }
+
+        /* Update src pointers */
+        ptrsrcy1  += srcystride;
+        ptrsrcy2  += srcystride;
+        ptrsrcy3  += srcystride;
+        ptrsrcy4  += srcystride;
+
+        ptrsrccb1 += srcccstride;
+        ptrsrccb2 += srcccstride;
+
+        ptrsrccr1 += srcccstride;
+        ptrsrccr2 += srcccstride;
+
+        /* Update dest pointers */
+        ptrdesty1 += destystride;
+        ptrdesty2 += destystride;
+        ptrdesty3 += destystride;
+        ptrdesty4 += destystride;
+
+        ptrdestcb1 += destccstride;
+        ptrdestcb2 += destccstride;
+
+        ptrdestcr1 += destccstride;
+        ptrdestcr2 += destccstride;
+
+    }
+
+}
+
+static void YUYVToYUV420(unsigned char *bufsrc, unsigned char *bufdest,
+                         int width, int height)
+{
+    int i, j;
+
+    /* Source*/
+    unsigned char *ptrsrcy1, *ptrsrcy2;
+    unsigned char *ptrsrcy3, *ptrsrcy4;
+    unsigned char *ptrsrccb1;
+    unsigned char *ptrsrccb3;
+    unsigned char *ptrsrccr1;
+    unsigned char *ptrsrccr3;
+    int srcystride, srcccstride;
+
+    ptrsrcy1  = bufsrc ;
+    ptrsrcy2  = bufsrc + (width << 1);
+    ptrsrcy3  = bufsrc + (width << 1) * 2;
+    ptrsrcy4  = bufsrc + (width << 1) * 3;
+
+    ptrsrccb1 = bufsrc + 1;
+    ptrsrccb3 = bufsrc + (width << 1) * 2 + 1;
+
+    ptrsrccr1 = bufsrc + 3;
+    ptrsrccr3 = bufsrc + (width << 1) * 2 + 3;
+
+    srcystride  = (width << 1) * 3;
+    srcccstride = (width << 1) * 3;
+
+    /* Destination */
+    unsigned char *ptrdesty1, *ptrdesty2;
+    unsigned char *ptrdesty3, *ptrdesty4;
+    unsigned char *ptrdestcb1, *ptrdestcb2;
+    unsigned char *ptrdestcr1, *ptrdestcr2;
+    int destystride, destccstride;
+
+    ptrdesty1 = bufdest;
+    ptrdesty2 = bufdest + width;
+    ptrdesty3 = bufdest + width * 2;
+    ptrdesty4 = bufdest + width * 3;
+
+    ptrdestcb1 = bufdest + width * height;
+    ptrdestcb2 = bufdest + width * height + (width >> 1);
+
+    ptrdestcr1 = bufdest + width * height + ((width * height) >> 2);
+    ptrdestcr2 = bufdest + width * height + ((width * height) >> 2)
+                 + (width >> 1);
+
+    destystride  = width * 3;
+    destccstride = (width >> 1);
+
+    for (j = 0; j < (height / 4); j++) {
+        for (i = 0; i < (width / 2); i++) {
+            (*ptrdesty1++) = (*ptrsrcy1);
+            (*ptrdesty2++) = (*ptrsrcy2);
+            (*ptrdesty3++) = (*ptrsrcy3);
+            (*ptrdesty4++) = (*ptrsrcy4);
+
+            ptrsrcy1 += 2;
+            ptrsrcy2 += 2;
+            ptrsrcy3 += 2;
+            ptrsrcy4 += 2;
+
+            (*ptrdesty1++) = (*ptrsrcy1);
+            (*ptrdesty2++) = (*ptrsrcy2);
+            (*ptrdesty3++) = (*ptrsrcy3);
+            (*ptrdesty4++) = (*ptrsrcy4);
+
+            ptrsrcy1 += 2;
+            ptrsrcy2 += 2;
+            ptrsrcy3 += 2;
+            ptrsrcy4 += 2;
+
+            (*ptrdestcb1++) = (*ptrsrccb1);
+            (*ptrdestcb2++) = (*ptrsrccb3);
+
+            ptrsrccb1 += 4;
+            ptrsrccb3 += 4;
+
+            (*ptrdestcr1++) = (*ptrsrccr1);
+            (*ptrdestcr2++) = (*ptrsrccr3);
+
+            ptrsrccr1 += 4;
+            ptrsrccr3 += 4;
+
+        }
+
+        /* Update src pointers */
+        ptrsrcy1  += srcystride;
+        ptrsrcy2  += srcystride;
+        ptrsrcy3  += srcystride;
+        ptrsrcy4  += srcystride;
+
+        ptrsrccb1 += srcccstride;
+        ptrsrccb3 += srcccstride;
+
+        ptrsrccr1 += srcccstride;
+        ptrsrccr3 += srcccstride;
+
+        /* Update dest pointers */
+        ptrdesty1 += destystride;
+        ptrdesty2 += destystride;
+        ptrdesty3 += destystride;
+        ptrdesty4 += destystride;
+
+        ptrdestcb1 += destccstride;
+        ptrdestcb2 += destccstride;
+
+        ptrdestcr1 += destccstride;
+        ptrdestcr2 += destccstride;
+    }
+}
diff --git a/tizen/src/hw/pci/maru_camera_darwin_pci.m b/tizen/src/hw/pci/maru_camera_darwin_pci.m
new file mode 100644 (file)
index 0000000..d90b490
--- /dev/null
@@ -0,0 +1,909 @@
+/*
+ * Implementation of MARU Virtual Camera device by PCI bus on MacOS.
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * Jun Tian <jun.j.tian@intel.com>
+ * JinHyung Jo <jinhyung.jo@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
+ *
+ */
+
+#import <Cocoa/Cocoa.h>
+#import <QTKit/QTKit.h>
+#import <CoreAudio/CoreAudio.h>
+
+#include <pthread.h>
+#include "qemu-common.h"
+#include "maru_camera_common.h"
+#include "maru_camera_darwin.h"
+#include "debug_ch.h"
+
+MULTI_DEBUG_CHANNEL(tizen, maru-camera);
+
+#define MARUCAM_THREAD_NAME    "marucam_worker_thread"
+
+/* V4L2 defines copy from videodev2.h */
+#define V4L2_CTRL_FLAG_SLIDER       0x0020
+
+#define V4L2_CTRL_CLASS_USER        0x00980000
+#define V4L2_CID_BASE               (V4L2_CTRL_CLASS_USER | 0x900)
+#define V4L2_CID_BRIGHTNESS         (V4L2_CID_BASE + 0)
+#define V4L2_CID_CONTRAST           (V4L2_CID_BASE + 1)
+#define V4L2_CID_SATURATION         (V4L2_CID_BASE + 2)
+#define V4L2_CID_SHARPNESS          (V4L2_CID_BASE + 27)
+
+typedef struct tagMaruCamConvertPixfmt {
+    uint32_t fmt;   /* fourcc */
+    uint32_t bpp;   /* bits per pixel, 0 for compressed formats */
+    uint32_t needs_conversion;
+} MaruCamConvertPixfmt;
+
+
+static MaruCamConvertPixfmt supported_dst_pixfmts[] = {
+    { V4L2_PIX_FMT_YUYV, 16, 0 },
+    { V4L2_PIX_FMT_UYVY, 16, 0 },
+    { V4L2_PIX_FMT_YUV420, 12, 0 },
+    { V4L2_PIX_FMT_YVU420, 12, 0 },
+};
+
+typedef struct tagMaruCamConvertFrameInfo {
+    uint32_t width;
+    uint32_t height;
+} MaruCamConvertFrameInfo;
+
+static MaruCamConvertFrameInfo supported_dst_frames[] = {
+    { 640, 480 },
+    { 352, 288 },
+    { 320, 240 },
+    { 176, 144 },
+    { 160, 120 },
+};
+
+#define MARUCAM_CTRL_VALUE_MAX      20
+#define MARUCAM_CTRL_VALUE_MIN      1
+#define MARUCAM_CTRL_VALUE_MID      10
+#define MARUCAM_CTRL_VALUE_STEP     1
+
+enum {
+    _MC_THREAD_PAUSED,
+    _MC_THREAD_STREAMON,
+    _MC_THREAD_STREAMOFF,
+};
+
+#if 0
+struct marucam_qctrl {
+    uint32_t id;
+    uint32_t hit;
+    long min;
+    long max;
+    long step;
+    long init_val;
+};
+
+static struct marucam_qctrl qctrl_tbl[] = {
+    { V4L2_CID_BRIGHTNESS, 0, },
+    { V4L2_CID_CONTRAST, 0, },
+    { V4L2_CID_SATURATION, 0, },
+    { V4L2_CID_SHARPNESS, 0, },
+};
+#endif
+
+static MaruCamState *g_state;
+
+static uint32_t ready_count;
+static uint32_t cur_fmt_idx;
+static uint32_t cur_frame_idx;
+
+/***********************************
+ * Mac camera helper functions
+ ***********************************/
+
+/* Convert Core Video format to FOURCC */
+static uint32_t corevideo_to_fourcc(uint32_t cv_pix_fmt)
+{
+    switch (cv_pix_fmt) {
+    case kCVPixelFormatType_420YpCbCr8Planar:
+        return V4L2_PIX_FMT_YVU420;
+    case kCVPixelFormatType_422YpCbCr8:
+        return V4L2_PIX_FMT_UYVY;
+    case kCVPixelFormatType_422YpCbCr8_yuvs:
+        return V4L2_PIX_FMT_YUYV;
+    case kCVPixelFormatType_32ARGB:
+    case kCVPixelFormatType_32RGBA:
+        return V4L2_PIX_FMT_RGB32;
+    case kCVPixelFormatType_32BGRA:
+    case kCVPixelFormatType_32ABGR:
+        return V4L2_PIX_FMT_BGR32;
+    case kCVPixelFormatType_24RGB:
+        return V4L2_PIX_FMT_RGB24;
+    case kCVPixelFormatType_24BGR:
+        return V4L2_PIX_FMT_BGR32;
+    default:
+        ERR("Unknown pixel format '%.4s'", (const char *)&cv_pix_fmt);
+        return 0;
+    }
+}
+
+static uint32_t get_bytesperline(uint32_t pixfmt, uint32_t width)
+{
+    uint32_t bytesperline;
+
+    switch (pixfmt) {
+    case V4L2_PIX_FMT_YUV420:
+    case V4L2_PIX_FMT_YVU420:
+        bytesperline = (width * 12) >> 3;
+        break;
+    case V4L2_PIX_FMT_YUYV:
+    case V4L2_PIX_FMT_UYVY:
+    default:
+        bytesperline = width * 2;
+        break;
+    }
+
+    return bytesperline;
+}
+
+static uint32_t get_sizeimage(uint32_t pixfmt, uint32_t width, uint32_t height)
+{
+    return get_bytesperline(pixfmt, width) * height;
+}
+
+/******************************************************************
+ **   Maru Camera Implementation
+ *****************************************************************/
+
+@interface MaruCameraDriver : NSObject {
+    QTCaptureSession               *mCaptureSession;
+    QTCaptureDeviceInput           *mCaptureVideoDeviceInput;
+    QTCaptureVideoPreviewOutput    *mCaptureVideoPreviewOutput;
+
+    CVImageBufferRef               mCurrentImageBuffer;
+    BOOL mDeviceIsOpened;
+    BOOL mCaptureIsStarted;
+}
+
+- (MaruCameraDriver *)init;
+- (int)startCapture:(int)width:(int)height;
+- (void)stopCapture;
+- (int)readFrame:(void *)video_buf;
+- (int)setCaptureFormat:(int)width:(int)height:(int)pix_format;
+- (int)getCaptureFormat:(int)width:(int)height:(int)pix_format;
+- (BOOL)deviceStatus;
+
+@end
+
+@implementation MaruCameraDriver
+
+- (MaruCameraDriver *)init
+{
+    BOOL success = NO;
+    NSError *error;
+    mDeviceIsOpened = NO;
+    mCaptureIsStarted = NO;
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+    /* Create the capture session */
+    mCaptureSession = [[QTCaptureSession alloc] init];
+
+    /* Find a video device */
+    QTCaptureDevice *videoDevice = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeVideo];
+    success = [videoDevice open:&error];
+
+    /* If a video input device can't be found or opened, try to find and open a muxed input device */
+    if (!success) {
+        videoDevice = [QTCaptureDevice defaultInputDeviceWithMediaType:QTMediaTypeMuxed];
+        success = [videoDevice open:&error];
+        [pool release];
+        return nil;
+    }
+
+    if (!success) {
+        videoDevice = nil;
+        [pool release];
+        return nil;
+    }
+
+    if (videoDevice) {
+        /* Add the video device to the session as a device input */
+        mCaptureVideoDeviceInput = [[QTCaptureDeviceInput alloc] initWithDevice:videoDevice];
+        success = [mCaptureSession addInput:mCaptureVideoDeviceInput error:&error];
+
+        if (!success) {
+            [pool release];
+            return nil;
+        }
+
+        mCaptureVideoPreviewOutput = [[QTCaptureVideoPreviewOutput alloc] init];
+        success = [mCaptureSession addOutput:mCaptureVideoPreviewOutput error:&error];
+        if (!success) {
+            [pool release];
+            return nil;
+        }
+
+        mDeviceIsOpened = YES;
+        [mCaptureVideoPreviewOutput setDelegate:self];
+        INFO("Camera session bundling successfully!\n");
+        [pool release];
+        return self;
+    } else {
+        [pool release];
+        return nil;
+    }
+}
+
+- (int)startCapture:(int)width:(int)height
+{
+    int ret = -1;
+
+    if (![mCaptureSession isRunning]) {
+        /* Set width & height, using default pixel format to capture */
+        NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
+                                                      [NSNumber numberWithInt: width], (id)kCVPixelBufferWidthKey,
+                                                      [NSNumber numberWithInt: height], (id)kCVPixelBufferHeightKey,
+                                                 nil];
+        [mCaptureVideoPreviewOutput setPixelBufferAttributes:attributes];
+        [mCaptureSession startRunning];
+    } else {
+        ERR("Capture session is already running, exit\n");
+        return ret;
+    }
+
+    if ([mCaptureSession isRunning]) {
+        while(!mCaptureIsStarted) {
+            /* Wait Until Capture is started */
+            [[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.5]];
+        }
+        ret = 0;
+    }
+    return ret;
+}
+
+- (void)stopCapture
+{
+    if ([mCaptureSession isRunning]) {
+        [mCaptureSession stopRunning];
+        while([mCaptureSession isRunning]) {
+            /* Wait Until Capture is stopped */
+            [[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.1]];
+        }
+
+    }
+    mCaptureIsStarted = NO;
+}
+
+- (int)readFrame:(void *)video_buf
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
+    @synchronized (self) {
+        if (mCaptureIsStarted == NO) {
+            [pool release];
+            return 0;
+        }
+        if (mCurrentImageBuffer != nil) {
+            CVPixelBufferLockBaseAddress(mCurrentImageBuffer, 0);
+            const uint32_t pixel_format = corevideo_to_fourcc(CVPixelBufferGetPixelFormatType(mCurrentImageBuffer));
+            const int frame_width = CVPixelBufferGetWidth(mCurrentImageBuffer);
+            const int frame_height = CVPixelBufferGetHeight(mCurrentImageBuffer);
+            const size_t frame_size = CVPixelBufferGetBytesPerRow(mCurrentImageBuffer) * frame_height;
+            const void *frame_pixels = CVPixelBufferGetBaseAddress(mCurrentImageBuffer);
+
+            TRACE("buffer(%p), pixel_format(%d,%.4s), frame_width(%d), "
+                  "frame_height(%d), frame_size(%d)\n",
+                  mCurrentImageBuffer, (int)pixel_format,
+                  (const char *)&pixel_format, frame_width,
+                  frame_height, (int)frame_size);
+
+            /* convert frame to v4l2 format */
+            convert_frame(pixel_format, frame_width, frame_height,
+                          frame_size, (void *)frame_pixels, video_buf);
+            CVPixelBufferUnlockBaseAddress(mCurrentImageBuffer, 0);
+            [pool release];
+            return 1;
+        }
+    }
+
+    [pool release];
+    return -1;
+}
+
+- (int)setCaptureFormat:(int)width:(int)height:(int)pix_format
+{
+    int ret = -1;
+    NSDictionary *attributes;
+
+    if (mCaptureSession == nil || mCaptureVideoPreviewOutput == nil) {
+        ERR("Capture session is not initiated.\n");
+        return ret;
+    }
+
+    /* Set the pixel buffer attributes before running the capture session */
+    if (![mCaptureSession isRunning]) {
+        if (pix_format) {
+            attributes = [NSDictionary dictionaryWithObjectsAndKeys:
+                                            [NSNumber numberWithInt: width], (id)kCVPixelBufferWidthKey,
+                                            [NSNumber numberWithInt: height], (id)kCVPixelBufferHeightKey,
+                                            [NSNumber numberWithInt: pix_format], (id)kCVPixelBufferPixelFormatTypeKey,
+                                       nil];
+        } else {
+            attributes = [NSDictionary dictionaryWithObjectsAndKeys:
+                                            [NSNumber numberWithInt: width], (id)kCVPixelBufferWidthKey,
+                                            [NSNumber numberWithInt: height], (id)kCVPixelBufferHeightKey,
+                                       nil];
+        }
+        [mCaptureVideoPreviewOutput setPixelBufferAttributes:attributes];
+        ret = 0;
+    } else {
+        ERR("Cannot set pixel buffer attributes when it's running.\n");
+        return ret;
+    }
+
+    return ret;
+}
+
+- (int)getCaptureFormat:(int)width:(int)height:(int)pix_format
+{
+    return 0;
+}
+
+/* Get the device bundling status */
+- (BOOL)deviceStatus
+{
+    return mDeviceIsOpened;
+}
+
+/* Handle deallocation of memory for your capture objects */
+
+- (void)dealloc
+{
+    [mCaptureSession release];
+    [mCaptureVideoDeviceInput release];
+    [mCaptureVideoPreviewOutput release];
+    [super dealloc];
+}
+
+/* Receive this method whenever the output decompresses and outputs a new video frame */
+- (void)captureOutput:(QTCaptureOutput *)captureOutput didOutputVideoFrame:(CVImageBufferRef)videoFrame
+     withSampleBuffer:(QTSampleBuffer *)sampleBuffer fromConnection:(QTCaptureConnection *)connection
+{
+    CVImageBufferRef imageBufferToRelease;
+    CVBufferRetain(videoFrame);
+
+    @synchronized (self)
+    {
+        imageBufferToRelease = mCurrentImageBuffer;
+        mCurrentImageBuffer = videoFrame;
+        mCaptureIsStarted = YES;
+    }
+    CVBufferRelease(imageBufferToRelease);
+}
+
+@end
+
+/******************************************************************
+ **   Maru Camera APIs
+ *****************************************************************/
+
+typedef struct MaruCameraDevice MaruCameraDevice;
+struct MaruCameraDevice {
+    /* Maru camera device object. */
+    MaruCameraDriver *driver;
+};
+
+/* Golbal representation of the Maru camera */
+MaruCameraDevice *mcd = NULL;
+
+static int is_streamon()
+{
+    int st;
+    qemu_mutex_lock(&g_state->thread_mutex);
+    st = g_state->streamon;
+    qemu_mutex_unlock(&g_state->thread_mutex);
+    return (st == _MC_THREAD_STREAMON);
+}
+
+static void __raise_err_intr()
+{
+    qemu_mutex_lock(&g_state->thread_mutex);
+    if (g_state->streamon == _MC_THREAD_STREAMON) {
+        g_state->req_frame = 0; /* clear request */
+        g_state->isr = 0x08;   /* set a error flag of rasing a interrupt */
+        qemu_bh_schedule(g_state->tx_bh);
+    }
+    qemu_mutex_unlock(&g_state->thread_mutex);
+}
+
+static int marucam_device_read_frame()
+{
+    int ret;
+    void *tmp_buf;
+
+    qemu_mutex_lock(&g_state->thread_mutex);
+    if (g_state->streamon == _MC_THREAD_STREAMON) {
+#if 0
+        if (ready_count < MARUCAM_SKIPFRAMES) {
+            /* skip a frame cause first some frame are distorted */
+            ++ready_count;
+            TRACE("Skip %d frame\n", ready_count);
+            qemu_mutex_unlock(&g_state->thread_mutex);
+            return 0;
+        }
+#endif
+        if (g_state->req_frame == 0) {
+            TRACE("There is no request\n");
+            qemu_mutex_unlock(&g_state->thread_mutex);
+            return 0;
+        }
+
+        /* Grab the camera frame into temp buffer */
+        tmp_buf = g_state->vaddr + g_state->buf_size * (g_state->req_frame - 1);
+        ret =  [mcd->driver readFrame: tmp_buf];
+        if (ret < 0) {
+            ERR("%s, Capture error\n", __func__);
+            qemu_mutex_unlock(&g_state->thread_mutex);
+            __raise_err_intr();
+            return -1;
+        } else if (!ret) {
+            qemu_mutex_unlock(&g_state->thread_mutex);
+            return 0;
+        }
+
+        g_state->req_frame = 0; /* clear request */
+        g_state->isr |= 0x01;   /* set a flag of rasing a interrupt */
+        qemu_bh_schedule(g_state->tx_bh);
+    } else {
+        qemu_mutex_unlock(&g_state->thread_mutex);
+        return -1;
+    }
+    qemu_mutex_unlock(&g_state->thread_mutex);
+    return 0;
+}
+
+/* Worker thread to grab frames to the preview window */
+static void *marucam_worker_thread(void *thread_param)
+{
+    while (1) {
+        qemu_mutex_lock(&g_state->thread_mutex);
+        g_state->streamon = _MC_THREAD_PAUSED;
+        qemu_cond_wait(&g_state->thread_cond, &g_state->thread_mutex);
+        qemu_mutex_unlock(&g_state->thread_mutex);
+
+        if (g_state->destroying) {
+            break;
+        }
+
+        ready_count = 0;
+        qemu_mutex_lock(&g_state->thread_mutex);
+        g_state->streamon = _MC_THREAD_STREAMON;
+        qemu_mutex_unlock(&g_state->thread_mutex);
+        INFO("Streaming on ......\n");
+
+        /* Loop: capture frame -> convert format -> render to screen */
+        while (1) {
+            if (is_streamon()) {
+                if (marucam_device_read_frame() < 0) {
+                    INFO("Streaming is off ...\n");
+                    break;
+                } else {
+                    /* wait until next frame is avalilable */
+                    usleep(22000);
+                }
+            } else {
+                INFO("Streaming is off ...\n");
+                break;
+            }
+        }
+    }
+
+    return NULL;
+}
+
+int marucam_device_check(int log_flag)
+{
+    /* FIXME: check the device parameters */
+    INFO("Checking camera device\n");
+    return 1;
+}
+
+/**********************************************
+ * MARU camera routines
+ **********************************************/
+void marucam_device_init(MaruCamState *state)
+{
+    g_state = state;
+    g_state->destroying = false;
+    qemu_thread_create(&state->thread_id,
+                       MARUCAM_THREAD_NAME,
+                       marucam_worker_thread,
+                       NULL,
+                       QEMU_THREAD_JOINABLE);
+}
+
+void marucam_device_exit(MaruCamState *state)
+{
+    state->destroying = true;
+    qemu_mutex_lock(&state->thread_mutex);
+    qemu_cond_signal(&state->thread_cond);
+    qemu_mutex_unlock(&state->thread_mutex);
+    qemu_thread_join(&state->thread_id);
+}
+
+/* MARUCAM_CMD_OPEN */
+void marucam_device_open(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+    param->top = 0;
+
+    mcd = (MaruCameraDevice *)malloc(sizeof(MaruCameraDevice));
+    if (mcd == NULL) {
+        ERR("%s: MaruCameraDevice allocate failed\n", __func__);
+        param->errCode = EINVAL;
+        return;
+    }
+    memset(mcd, 0, sizeof(MaruCameraDevice));
+    mcd->driver = [[MaruCameraDriver alloc] init];
+    if (mcd->driver == nil) {
+        ERR("Camera device open failed\n");
+        [mcd->driver dealloc];
+        free(mcd);
+        param->errCode = EINVAL;
+        return;
+    }
+    INFO("Camera opened!\n");
+}
+
+/* MARUCAM_CMD_CLOSE */
+void marucam_device_close(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+    param->top = 0;
+
+    if (mcd != NULL) {
+        if (is_streamon()) {
+            marucam_device_stop_preview(state);
+        }
+        [mcd->driver dealloc];
+        free(mcd);
+        mcd = NULL;
+    }
+
+    /* marucam_reset_controls(); */
+    INFO("Camera closed\n");
+}
+
+/* MARUCAM_CMD_START_PREVIEW */
+void marucam_device_start_preview(MaruCamState *state)
+{
+    uint32_t width, height, pixfmt;
+    MaruCamParam *param = state->param;
+    param->top = 0;
+
+    width = supported_dst_frames[cur_frame_idx].width;
+    height = supported_dst_frames[cur_frame_idx].height;
+    pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
+    state->buf_size = get_sizeimage(pixfmt, width, height);
+
+    INFO("Pixfmt(%c%c%c%c), W:H(%d:%d), buf size(%u), frame idx(%d), fmt idx(%d)\n",
+      (char)(pixfmt), (char)(pixfmt >> 8),
+      (char)(pixfmt >> 16), (char)(pixfmt >> 24),
+      width, height, state->buf_size,
+      cur_frame_idx, cur_fmt_idx);
+
+    if (mcd->driver == nil) {
+        ERR("%s: Start capture failed: vaild device", __func__);
+        param->errCode = EINVAL;
+        return;
+    }
+    
+    INFO("Starting preview ...\n");
+    [mcd->driver startCapture: width: height];
+
+    /* Enable the condition to capture frames now */
+    qemu_mutex_lock(&state->thread_mutex);
+    qemu_cond_signal(&state->thread_cond);
+    qemu_mutex_unlock(&state->thread_mutex);
+
+    while (!is_streamon()) {
+        usleep(10000);
+    }
+}
+
+/* MARUCAM_CMD_STOP_PREVIEW */
+void marucam_device_stop_preview(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+    param->top = 0;
+
+    if (is_streamon()) {
+        qemu_mutex_lock(&state->thread_mutex);
+        state->streamon = _MC_THREAD_STREAMOFF;
+        qemu_mutex_unlock(&state->thread_mutex);
+
+        while (is_streamon()) {
+            usleep(10000);
+        }
+    }
+
+    if (mcd->driver != nil) {
+        [mcd->driver stopCapture];
+    }
+
+    state->buf_size = 0;
+    INFO("Stopping preview ...\n");
+}
+
+/* MARUCAM_CMD_S_PARAM */
+void marucam_device_s_param(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+
+    /* We use default FPS of the webcam */
+    param->top = 0;
+}
+
+/* MARUCAM_CMD_G_PARAM */
+void marucam_device_g_param(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+    /* We use default FPS of the webcam
+     * return a fixed value on guest ini file (1/30).
+     */
+    param->top = 0;
+    param->stack[0] = 0x1000; /* V4L2_CAP_TIMEPERFRAME */
+    param->stack[1] = 1; /* numerator */
+    param->stack[2] = 30; /* denominator */
+}
+
+/* MARUCAM_CMD_S_FMT */
+void marucam_device_s_fmt(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+    uint32_t width, height, pixfmt, pidx, fidx;
+
+    param->top = 0;
+    width = param->stack[0];
+    height = param->stack[1];
+    pixfmt = param->stack[2];
+
+    TRACE("Set format: width(%d), height(%d), pixfmt(%d, %.4s)\n",
+         width, height, pixfmt, (const char*)&pixfmt);
+
+    for (fidx = 0; fidx < ARRAY_SIZE(supported_dst_frames); fidx++) {
+        if ((supported_dst_frames[fidx].width == width) &&
+            (supported_dst_frames[fidx].height == height)) {
+            break;
+        }
+    }
+    if (fidx == ARRAY_SIZE(supported_dst_frames)) {
+        param->errCode = EINVAL;
+        return;
+    }
+
+    for (pidx = 0; pidx < ARRAY_SIZE(supported_dst_pixfmts); pidx++) {
+        if (supported_dst_pixfmts[pidx].fmt == pixfmt) {
+            TRACE("pixfmt index is match: %d\n", pidx);
+            break;
+        }
+    }
+    if (pidx == ARRAY_SIZE(supported_dst_pixfmts)) {
+        param->errCode = EINVAL;
+        return;
+    }
+
+    if ((supported_dst_frames[cur_frame_idx].width != width) &&
+        (supported_dst_frames[cur_frame_idx].height != height)) {
+        if (mcd->driver == nil || [mcd->driver setCaptureFormat: width: height: 0] < 0) {
+            ERR("Set pixel format failed\n");
+            param->errCode = EINVAL;
+            return;
+        }
+
+        TRACE("cur_frame_idx:%d, supported_dst_frames[cur_frame_idx].width:%d\n",
+             cur_frame_idx, supported_dst_frames[cur_frame_idx].width);
+    }
+
+    cur_frame_idx = fidx;
+    cur_fmt_idx = pidx;
+
+    pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
+    width = supported_dst_frames[cur_frame_idx].width;
+    height = supported_dst_frames[cur_frame_idx].height;
+
+    param->stack[0] = width;
+    param->stack[1] = height;
+    param->stack[2] = 1; /* V4L2_FIELD_NONE */
+    param->stack[3] = pixfmt;
+    param->stack[4] = get_bytesperline(pixfmt, width);
+    param->stack[5] = get_sizeimage(pixfmt, width, height);
+    param->stack[6] = 0;
+    param->stack[7] = 0;
+
+    TRACE("Set device pixel format ...\n");
+}
+
+/* MARUCAM_CMD_G_FMT */
+void marucam_device_g_fmt(MaruCamState *state)
+{
+    uint32_t width, height, pixfmt;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
+    width = supported_dst_frames[cur_frame_idx].width;
+    height = supported_dst_frames[cur_frame_idx].height;
+
+    param->stack[0] = width;
+    param->stack[1] = height;
+    param->stack[2] = 1; /* V4L2_FIELD_NONE */
+    param->stack[3] = pixfmt;
+    param->stack[4] = get_bytesperline(pixfmt, width);
+    param->stack[5] = get_sizeimage(pixfmt, width, height);
+    param->stack[6] = 0;
+    param->stack[7] = 0;
+
+    TRACE("Get device frame format ...\n");
+}
+
+void marucam_device_try_fmt(MaruCamState *state)
+{
+    TRACE("Try device frame format, use default setting ...\n");
+}
+
+/* Get specific pixelformat description */
+void marucam_device_enum_fmt(MaruCamState *state)
+{
+    uint32_t index;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    index = param->stack[0];
+
+    if (index >= ARRAY_SIZE(supported_dst_pixfmts)) {
+        param->errCode = EINVAL;
+        return;
+    }
+    param->stack[1] = 0; /* flags = NONE */
+    param->stack[2] = supported_dst_pixfmts[index].fmt; /* pixelformat */
+    switch (supported_dst_pixfmts[index].fmt) {
+    case V4L2_PIX_FMT_YUYV:
+        memcpy(&param->stack[3], "YUYV", 32);
+        break;
+    case V4L2_PIX_FMT_UYVY:
+        memcpy(&param->stack[3], "UYVY", 32);
+        break;
+    case V4L2_PIX_FMT_YUV420:
+        memcpy(&param->stack[3], "YU12", 32);
+        break;
+    case V4L2_PIX_FMT_YVU420:
+        memcpy(&param->stack[3], "YV12", 32);
+        break;
+    default:
+        param->errCode = EINVAL;
+        break;
+    }
+}
+
+/*
+ * QTKit don't support setting brightness, contrast, saturation & sharpness
+ */
+void marucam_device_qctrl(MaruCamState *state)
+{
+    uint32_t id, i;
+    /* long property, min, max, step, def_val, set_val; */
+    char name[32] = {0,};
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    id = param->stack[0];
+
+    switch (id) {
+    case V4L2_CID_BRIGHTNESS:
+        TRACE("V4L2_CID_BRIGHTNESS\n");
+        memcpy((void *)name, (void *)"brightness", 32);
+        i = 0;
+        break;
+    case V4L2_CID_CONTRAST:
+        TRACE("V4L2_CID_CONTRAST\n");
+        memcpy((void *)name, (void *)"contrast", 32);
+        i = 1;
+        break;
+    case V4L2_CID_SATURATION:
+        TRACE("V4L2_CID_SATURATION\n");
+        memcpy((void *)name, (void *)"saturation", 32);
+        i = 2;
+        break;
+    case V4L2_CID_SHARPNESS:
+        TRACE("V4L2_CID_SHARPNESS\n");
+        memcpy((void *)name, (void *)"sharpness", 32);
+        i = 3;
+        break;
+    default:
+        param->errCode = EINVAL;
+        return;
+    }
+
+    param->stack[0] = id;
+    param->stack[1] = MARUCAM_CTRL_VALUE_MIN;  /* minimum */
+    param->stack[2] = MARUCAM_CTRL_VALUE_MAX;  /* maximum */
+    param->stack[3] = MARUCAM_CTRL_VALUE_STEP; /*  step   */
+    param->stack[4] = MARUCAM_CTRL_VALUE_MID;  /* default_value */
+    param->stack[5] = V4L2_CTRL_FLAG_SLIDER;
+    /* name field setting */
+    memcpy(&param->stack[6], (void *)name, sizeof(name)/sizeof(name[0]));
+}
+
+void marucam_device_s_ctrl(MaruCamState *state)
+{
+    INFO("Set control\n");
+}
+
+void marucam_device_g_ctrl(MaruCamState *state)
+{
+    INFO("Get control\n");
+}
+
+/* Get frame width & height */
+void marucam_device_enum_fsizes(MaruCamState *state)
+{
+    uint32_t index, pixfmt, i;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    index = param->stack[0];
+    pixfmt = param->stack[1];
+
+    if (index >= ARRAY_SIZE(supported_dst_frames)) {
+        param->errCode = EINVAL;
+        return;
+    }
+    for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) {
+        if (supported_dst_pixfmts[i].fmt == pixfmt) {
+            break;
+        }
+    }
+
+    if (i == ARRAY_SIZE(supported_dst_pixfmts)) {
+        param->errCode = EINVAL;
+        return;
+    }
+
+    param->stack[0] = supported_dst_frames[index].width;
+    param->stack[1] = supported_dst_frames[index].height;
+}
+
+void marucam_device_enum_fintv(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+    param->top = 0;
+
+    /* switch by index(param->stack[0]) */
+    switch (param->stack[0]) {
+    case 0:
+        param->stack[1] = 30; /* denominator */
+        break;
+    default:
+        param->errCode = EINVAL;
+        return;
+    }
+    param->stack[0] = 1; /* numerator */
+}
diff --git a/tizen/src/hw/pci/maru_camera_linux_pci.c b/tizen/src/hw/pci/maru_camera_linux_pci.c
new file mode 100644 (file)
index 0000000..c4e1340
--- /dev/null
@@ -0,0 +1,1366 @@
+/*
+ * Implementation of MARU Virtual Camera device by PCI bus on Linux.
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * JinHyung Jo <jinhyung.jo@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 "qemu-common.h"
+#include "sysemu/kvm.h"
+#include "maru_camera_common.h"
+#include "debug_ch.h"
+
+#include <linux/videodev2.h>
+
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+
+#include <libv4l2.h>
+#include <libv4lconvert.h>
+
+MULTI_DEBUG_CHANNEL(tizen, maru-camera);
+
+#define MARUCAM_THREAD_NAME    "marucam_worker_thread"
+
+#define CLEAR(x) memset(&(x), 0, sizeof(x))
+
+#define MARUCAM_DEFAULT_BUFFER_COUNT    4
+
+#define MARUCAM_CTRL_VALUE_MAX      20
+#define MARUCAM_CTRL_VALUE_MIN      1
+#define MARUCAM_CTRL_VALUE_MID      10
+#define MARUCAM_CTRL_VALUE_STEP     1
+
+enum {
+    _MC_THREAD_PAUSED,
+    _MC_THREAD_STREAMON,
+    _MC_THREAD_STREAMOFF,
+};
+
+typedef struct marucam_framebuffer {
+    void *data;
+    size_t size;
+} marucam_framebuffer;
+
+struct marucam_saved_frame {
+    void *data;
+    uint32_t pixelformat;
+    uint32_t width;
+    uint32_t height;
+    uint32_t size;
+};
+
+static struct marucam_saved_frame saved_frame;
+static char has_success_frame;
+static int n_framebuffer;
+static int previous_frame_index = -1;
+static struct marucam_framebuffer *framebuffer;
+
+static const char *dev_name = "/dev/video0";
+static int v4l2_fd;
+static int convert_trial;
+static int ready_count;
+static int timeout_n;
+
+static struct v4l2_format dst_fmt;
+
+static void ScalePlaneSimple(int src_width, int src_height,
+                             int dst_width, int dst_height,
+                             int src_stride, int dst_stride,
+                             const uint8_t *src_ptr, uint8_t *dst_ptr) {
+    int i, j;
+    int dx = (src_width << 16) / dst_width;
+    int dy = (src_height << 16) / dst_height;
+    int y = (dy >= 65536) ? ((dy >> 1) - 32768) : (dy >> 1);
+    for (j = 0; j < dst_height; ++j) {
+        int x = (dx >= 65536) ? ((dx >> 1) - 32768) : (dx >> 1);
+        int yi = y >> 16;
+        const uint8_t *src = src_ptr + yi * src_stride;
+        uint8_t *dst = dst_ptr;
+        for (i = 0; i < dst_width; ++i) {
+            *dst++ = src[x >> 16];
+            x += dx;
+        }
+        dst_ptr += dst_stride;
+        y += dy;
+    }
+}
+
+static void make_yu12_black(unsigned char *dest, uint32_t width, uint32_t height)
+{
+    uint32_t x, y;
+    unsigned char *udest, *vdest;
+
+    /* Y */
+    for (y = 0; y < height; y++) {
+        for (x = 0; x < width; x++) {
+            *dest++ = 16;
+        }
+    }
+
+    /* U + V */
+    udest = dest;
+    vdest = dest + width * height / 4;
+
+    for (y = 0; y < height / 2; y++) {
+        for (x = 0; x < width / 2; x++) {
+            *udest++ = *vdest++ = 128;
+        }
+    }
+}
+
+static void marucam_scale_yuv420(void *src,
+                    uint32_t src_width, uint32_t src_height,
+                    void *dst, uint32_t dst_width, uint32_t dst_height)
+{
+    uint32_t src_halfwidth = (src_width + 1) >> 1;
+    uint32_t src_halfheight = (src_height + 1) >> 1;
+    uint32_t dst_halfwidth = (dst_width + 1) >> 1;
+    uint32_t dst_halfheight = (dst_height + 1) >> 1;
+
+    uint8_t *src_u = src + (src_width * src_height);
+    uint8_t *src_v = src_u + (src_width * src_height / 4);
+
+    uint8_t *dst_u = dst + (dst_width * dst_height);
+    uint8_t *dst_v = dst_u + (dst_width * dst_height /4);
+
+    ScalePlaneSimple(src_width, src_height,
+                     dst_width, dst_height,
+                     src_width, dst_width,
+                     src, dst);
+    ScalePlaneSimple(src_halfwidth, src_halfheight,
+                     dst_halfwidth, dst_halfheight,
+                     src_halfwidth, dst_halfwidth,
+                     src_u, dst_u);
+    ScalePlaneSimple(src_halfwidth, src_halfheight,
+                     dst_halfwidth, dst_halfheight,
+                     src_halfwidth, dst_halfwidth,
+                     src_v, dst_v);
+}
+
+static int yioctl(int fd, int req, void *arg)
+{
+    int r;
+
+    do {
+        r = ioctl(fd, req, arg);
+    } while (r < 0 && errno == EINTR);
+
+    return r;
+}
+
+static int xioctl(int fd, int req, void *arg)
+{
+    int r;
+
+    do {
+        r = v4l2_ioctl(fd, req, arg);
+    } while (r < 0 && errno == EINTR);
+
+    return r;
+}
+
+typedef struct tagMaruCamConvertPixfmt {
+    uint32_t fmt;   /* fourcc */
+} MaruCamConvertPixfmt;
+
+static MaruCamConvertPixfmt supported_dst_pixfmts[] = {
+        { V4L2_PIX_FMT_YUYV },
+        { V4L2_PIX_FMT_YUV420 },
+        { V4L2_PIX_FMT_YVU420 },
+};
+
+typedef struct tagMaruCamConvertFrameInfo {
+    uint32_t width;
+    uint32_t height;
+} MaruCamConvertFrameInfo;
+
+static MaruCamConvertFrameInfo supported_dst_frames[] = {
+        { 640, 480 },
+        { 352, 288 },
+        { 320, 240 },
+        { 176, 144 },
+        { 160, 120 },
+};
+
+struct marucam_qctrl {
+    uint32_t id;
+    uint32_t hit;
+    int32_t min;
+    int32_t max;
+    int32_t step;
+    int32_t init_val;
+};
+
+static struct marucam_qctrl qctrl_tbl[] = {
+    { V4L2_CID_BRIGHTNESS, 0, },
+    { V4L2_CID_CONTRAST, 0, },
+    { V4L2_CID_SATURATION, 0, },
+    { V4L2_CID_SHARPNESS, 0, },
+};
+
+static void marucam_reset_controls(void)
+{
+    uint32_t i;
+    for (i = 0; i < ARRAY_SIZE(qctrl_tbl); i++) {
+        if (qctrl_tbl[i].hit) {
+            struct v4l2_control ctrl = {0,};
+            qctrl_tbl[i].hit = 0;
+            ctrl.id = qctrl_tbl[i].id;
+            ctrl.value = qctrl_tbl[i].init_val;
+            if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &ctrl) < 0) {
+                ERR("Failed to reset control value: id(0x%x), errstr(%s)\n",
+                    ctrl.id, strerror(errno));
+            }
+        }
+    }
+}
+
+static int32_t value_convert_from_guest(int32_t min, int32_t max, int32_t value)
+{
+    double rate = 0.0;
+    int32_t dist = 0, ret = 0;
+
+    dist = max - min;
+
+    if (dist < MARUCAM_CTRL_VALUE_MAX) {
+        rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;
+        ret = min + (int32_t)(value / rate);
+    } else {
+        rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;
+        ret = min + (int32_t)(rate * value);
+    }
+    return ret;
+}
+
+static int32_t value_convert_to_guest(int32_t min, int32_t max, int32_t value)
+{
+    double rate  = 0.0;
+    int32_t dist = 0, ret = 0;
+
+    dist = max - min;
+
+    if (dist < MARUCAM_CTRL_VALUE_MAX) {
+        rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;
+        ret = (int32_t)((double)(value - min) * rate);
+    } else {
+        rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;
+        ret = (int32_t)((double)(value - min) / rate);
+    }
+
+    return ret;
+}
+
+static void set_maxframeinterval(MaruCamState *state, uint32_t pixel_format,
+                        uint32_t width, uint32_t height)
+{
+    struct v4l2_frmivalenum fival;
+    struct v4l2_streamparm sp;
+    uint32_t min_num = 0, min_denom = 0;
+
+    CLEAR(fival);
+    fival.pixel_format = pixel_format;
+    fival.width = width;
+    fival.height = height;
+
+    if (xioctl(v4l2_fd, VIDIOC_ENUM_FRAMEINTERVALS, &fival) < 0) {
+        ERR("Unable to enumerate intervals for pixelformat(0x%x), (%d:%d)\n",
+            pixel_format, width, height);
+        return;
+    }
+
+    if (fival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
+        float max_ival = -1.0;
+        do {
+            float cur_ival = (float)fival.discrete.numerator
+                        / (float)fival.discrete.denominator;
+            if (cur_ival > max_ival) {
+                max_ival = cur_ival;
+                min_num = fival.discrete.numerator;
+                min_denom = fival.discrete.denominator;
+            }
+            TRACE("Discrete frame interval %u/%u supported\n",
+                 fival.discrete.numerator, fival.discrete.denominator);
+            fival.index++;
+        } while (xioctl(v4l2_fd, VIDIOC_ENUM_FRAMEINTERVALS, &fival) >= 0);
+    } else if ((fival.type == V4L2_FRMIVAL_TYPE_STEPWISE) ||
+                (fival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS)) {
+        TRACE("Frame intervals from %u/%u to %u/%u supported",
+            fival.stepwise.min.numerator, fival.stepwise.min.denominator,
+            fival.stepwise.max.numerator, fival.stepwise.max.denominator);
+        if (fival.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
+            TRACE("with %u/%u step", fival.stepwise.step.numerator,
+                  fival.stepwise.step.denominator);
+        }
+        if (((float)fival.stepwise.max.denominator /
+             (float)fival.stepwise.max.numerator) >
+            ((float)fival.stepwise.min.denominator /
+             (float)fival.stepwise.min.numerator)) {
+            min_num = fival.stepwise.max.numerator;
+            min_denom = fival.stepwise.max.denominator;
+        } else {
+            min_num = fival.stepwise.min.numerator;
+            min_denom = fival.stepwise.min.denominator;
+        }
+    }
+    TRACE("The actual min values: %u/%u\n", min_num, min_denom);
+
+    CLEAR(sp);
+    sp.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    sp.parm.capture.timeperframe.numerator = min_num;
+    sp.parm.capture.timeperframe.denominator = min_denom;
+
+    if (xioctl(v4l2_fd, VIDIOC_S_PARM, &sp) < 0) {
+        ERR("Failed to set to minimum FPS(%u/%u)\n", min_num, min_denom);
+    }
+}
+
+static uint32_t stop_capturing(void)
+{
+    enum v4l2_buf_type type;
+
+    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    if (xioctl(v4l2_fd, VIDIOC_STREAMOFF, &type) < 0) {
+        ERR("Failed to ioctl() with VIDIOC_STREAMOFF: %s\n", strerror(errno));
+        return errno;
+    }
+    return 0;
+}
+
+static uint32_t start_capturing(void)
+{
+    enum v4l2_buf_type type;
+
+    type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    if (xioctl(v4l2_fd, VIDIOC_STREAMON, &type) < 0) {
+        ERR("Failed to ioctl() with VIDIOC_STREAMON: %s\n", strerror(errno));
+        return errno;
+    }
+    return 0;
+}
+
+static void free_framebuffers(marucam_framebuffer *fb, int buf_num)
+{
+    int i;
+
+    if (fb == NULL) {
+        ERR("The framebuffer is NULL. Failed to release the framebuffer\n");
+        return;
+    } else if (buf_num == 0) {
+        ERR("The buffer count is 0. Failed to release the framebuffer\n");
+        return;
+    } else {
+        TRACE("[%s]:fb(0x%p), buf_num(%d)\n", __func__, fb, buf_num);
+    }
+
+    /* Unmap framebuffers. */
+    for (i = 0; i < buf_num; i++) {
+        if (fb[i].data != NULL) {
+            v4l2_munmap(fb[i].data, fb[i].size);
+            fb[i].data = NULL;
+            fb[i].size = 0;
+        } else {
+            ERR("framebuffer[%d].data is NULL.\n", i);
+        }
+    }
+    previous_frame_index = -1;
+}
+
+static uint32_t
+mmap_framebuffers(marucam_framebuffer **fb, int *buf_num)
+{
+    struct v4l2_requestbuffers req;
+
+    CLEAR(req);
+    req.count   = MARUCAM_DEFAULT_BUFFER_COUNT;
+    req.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    req.memory  = V4L2_MEMORY_MMAP;
+    if (xioctl(v4l2_fd, VIDIOC_REQBUFS, &req) < 0) {
+        if (errno == EINVAL) {
+            ERR("%s does not support memory mapping: %s\n",
+                dev_name, strerror(errno));
+        } else {
+            ERR("Failed to request bufs: %s\n", strerror(errno));
+        }
+        return errno;
+    }
+    if (req.count == 0) {
+        ERR("Insufficient buffer memory on %s\n", dev_name);
+        return EINVAL;
+    }
+
+    *fb = g_new0(marucam_framebuffer, req.count);
+    if (*fb == NULL) {
+        ERR("Not enough memory to allocate framebuffers\n");
+        return ENOMEM;
+    }
+
+    for (*buf_num = 0; *buf_num < req.count; ++*buf_num) {
+        struct v4l2_buffer buf;
+        CLEAR(buf);
+        buf.type    = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+        buf.memory  = V4L2_MEMORY_MMAP;
+        buf.index   = *buf_num;
+        if (xioctl(v4l2_fd, VIDIOC_QUERYBUF, &buf) < 0) {
+            ERR("Failed to ioctl() with VIDIOC_QUERYBUF: %s\n",
+                strerror(errno));
+            return errno;
+        }
+
+        (*fb)[*buf_num].size = buf.length;
+        (*fb)[*buf_num].data = v4l2_mmap(NULL,
+                     buf.length,
+                     PROT_READ | PROT_WRITE,
+                     MAP_SHARED,
+                     v4l2_fd, buf.m.offset);
+        if (MAP_FAILED == (*fb)[*buf_num].data) {
+            ERR("Failed to mmap: %s\n", strerror(errno));
+            return errno;
+        }
+
+        /* Queue the mapped buffer. */
+        CLEAR(buf);
+        buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+        buf.memory = V4L2_MEMORY_MMAP;
+        buf.index = *buf_num;
+        if (xioctl(v4l2_fd, VIDIOC_QBUF, &buf) < 0) {
+            ERR("Failed to ioctl() with VIDIOC_QBUF: %s\n", strerror(errno));
+            return errno;
+        }
+    }
+    return 0;
+}
+
+static int is_streamon(MaruCamState *state)
+{
+    int st;
+    qemu_mutex_lock(&state->thread_mutex);
+    st = state->streamon;
+    qemu_mutex_unlock(&state->thread_mutex);
+    return (st == _MC_THREAD_STREAMON);
+}
+
+static int is_stream_paused(MaruCamState *state)
+{
+    int st;
+    qemu_mutex_lock(&state->thread_mutex);
+    st = state->streamon;
+    qemu_mutex_unlock(&state->thread_mutex);
+    return (st == _MC_THREAD_PAUSED);
+}
+
+/* sends a frame, YU12/black color  */
+/* TODO: add other pixel format method */
+static void __raise_dummy_intr(MaruCamState *state)
+{
+    void *buf = NULL;
+    qemu_mutex_lock(&state->thread_mutex);
+    if (state->streamon == _MC_THREAD_STREAMON && state->req_frame) {
+        buf = state->vaddr + state->buf_size * (state->req_frame - 1);
+        if (saved_frame.data) {
+            if (saved_frame.width == dst_fmt.fmt.pix.width &&
+                saved_frame.height == dst_fmt.fmt.pix.height) {
+                TRACE("Copies the previuos frame\n");
+                memcpy(buf, saved_frame.data, state->buf_size);
+            } else {
+                TRACE("Resizes the previous frame\n");
+                marucam_scale_yuv420(saved_frame.data, saved_frame.width,
+                                     saved_frame.height,
+                                     buf, dst_fmt.fmt.pix.width,
+                                     dst_fmt.fmt.pix.height);
+            }
+        } else {
+            TRACE("Sends a black frame\n");
+            make_yu12_black(buf,
+                            dst_fmt.fmt.pix.width,
+                            dst_fmt.fmt.pix.height);
+        }
+        state->req_frame = 0; /* clear request */
+        state->isr |= 0x01;   /* set a flag of raising a interrupt */
+        qemu_bh_schedule(state->tx_bh);
+    }
+    qemu_mutex_unlock(&state->thread_mutex);
+}
+
+static void __raise_err_intr(MaruCamState *state)
+{
+    qemu_mutex_lock(&state->thread_mutex);
+    if (state->streamon == _MC_THREAD_STREAMON) {
+        state->req_frame = 0; /* clear request */
+        state->isr = 0x08;   /* set a error flag of raising a interrupt */
+        qemu_bh_schedule(state->tx_bh);
+    }
+    qemu_mutex_unlock(&state->thread_mutex);
+}
+
+static void
+notify_buffer_ready(MaruCamState *state, uint32_t buf_index)
+{
+    void *buf = NULL;
+
+    qemu_mutex_lock(&state->thread_mutex);
+    if (state->streamon == _MC_THREAD_STREAMON) {
+        if (ready_count < MARUCAM_SKIPFRAMES) {
+            /* skip a frame cause first some frame are distorted */
+            ++ready_count;
+            TRACE("Skip %d frame\n", ready_count);
+            qemu_mutex_unlock(&state->thread_mutex);
+            return;
+        }
+        if (state->req_frame == 0) {
+            TRACE("There is no request\n");
+            qemu_mutex_unlock(&state->thread_mutex);
+            return;
+        }
+        buf = state->vaddr + state->buf_size * (state->req_frame - 1);
+        memcpy(buf, framebuffer[buf_index].data, state->buf_size);
+        previous_frame_index = buf_index;
+        has_success_frame = 1;
+        state->req_frame = 0; /* clear request */
+        state->isr |= 0x01;   /* set a flag of rasing a interrupt */
+        qemu_bh_schedule(state->tx_bh);
+    }
+    qemu_mutex_unlock(&state->thread_mutex);
+}
+
+static int read_frame(MaruCamState *state)
+{
+    struct v4l2_buffer buf;
+
+    CLEAR(buf);
+    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    buf.memory = V4L2_MEMORY_MMAP;
+    if (xioctl(v4l2_fd, VIDIOC_DQBUF, &buf) < 0) {
+        switch (errno) {
+        case EAGAIN:
+        case EINTR:
+            ERR("DQBUF error, try again: %s\n", strerror(errno));
+            return 0;
+        case EIO:
+            ERR("The v4l2_read() met the EIO\n");
+            if (convert_trial-- == -1) {
+                ERR("Try count for v4l2_read is exceeded: %s\n",
+                    strerror(errno));
+                return -1;
+            }
+            return 0;
+        default:
+            ERR("DQBUF error: %s\n", strerror(errno));
+            return -1;
+        }
+    }
+
+    notify_buffer_ready(state, buf.index);
+
+    if (xioctl(v4l2_fd, VIDIOC_QBUF, &buf) < 0) {
+        ERR("QBUF error: %s\n", strerror(errno));
+        return -1;
+    }
+    return 0;
+}
+
+static int __v4l2_streaming(MaruCamState *state)
+{
+    fd_set fds;
+    struct timeval tv;
+    int ret;
+
+    FD_ZERO(&fds);
+    FD_SET(v4l2_fd, &fds);
+
+    tv.tv_sec = 1;
+    tv.tv_usec = 0;
+
+    ret = select(v4l2_fd + 1, &fds, NULL, NULL, &tv);
+    if (ret < 0) {
+        if (errno == EAGAIN || errno == EINTR) {
+            ERR("Select again: %s\n", strerror(errno));
+            return 0;
+        }
+        ERR("Failed to select: %s\n", strerror(errno));
+        __raise_err_intr(state);
+        return -1;
+    } else if (!ret) {
+        timeout_n++;
+        ERR("Select timed out: count(%u)\n", timeout_n);
+        if (ready_count <= MARUCAM_SKIPFRAMES) {
+            switch (timeout_n) {
+            case 1:
+                ERR("Waiting for reading a frame data\n");
+                return 0;
+            case 2:
+            case 3:
+            case 4:
+                ERR("Sends dummy data to initialize the camera\n");
+                __raise_dummy_intr(state);
+                return 0;
+            default:
+                ERR("Webcam is busy, failed to a read frame."
+                    " Raises an error\n");
+                __raise_err_intr(state);
+                return -1;
+            }
+        }
+        if (timeout_n >= 5) {
+            ERR("Webcam is busy, failed to a read frame. Raises an error\n");
+            __raise_err_intr(state);
+            return -1;
+        }
+        if (previous_frame_index != -1) {
+            ERR("Sends previous frame data\n");
+            notify_buffer_ready(state, previous_frame_index);
+        }
+        return 0;
+    }
+
+    if (!v4l2_fd || (v4l2_fd == -1)) {
+        ERR("The file descriptor is closed or not opened\n");
+        __raise_err_intr(state);
+        return -1;
+    }
+
+    ret = read_frame(state);
+    if (ret < 0) {
+        ERR("Failed to operate the read_frame()\n");
+        __raise_err_intr(state);
+        return -1;
+    }
+
+    /* clear the skip count for select time-out */
+    if (timeout_n > 0) {
+        timeout_n = 0;
+    }
+
+    return 0;
+}
+
+/* Worker thread */
+static void *marucam_worker_thread(void *thread_param)
+{
+    MaruCamState *state = (MaruCamState *)thread_param;
+
+    while (1) {
+        qemu_mutex_lock(&state->thread_mutex);
+        state->streamon = _MC_THREAD_PAUSED;
+        qemu_cond_wait(&state->thread_cond, &state->thread_mutex);
+        qemu_mutex_unlock(&state->thread_mutex);
+
+        if (state->destroying) {
+            break;
+        }
+
+        convert_trial = 10;
+        ready_count = 0;
+        timeout_n = 0;
+        has_success_frame = 0;
+        qemu_mutex_lock(&state->thread_mutex);
+        state->streamon = _MC_THREAD_STREAMON;
+        qemu_mutex_unlock(&state->thread_mutex);
+        INFO("Streaming on ......\n");
+
+        while (1) {
+            if (is_streamon(state)) {
+                if (__v4l2_streaming(state) < 0) {
+                    INFO("...... Streaming off\n");
+                    break;
+                }
+            } else {
+                INFO("...... Streaming off\n");
+                break;
+            }
+        }
+    }
+
+    return NULL;
+}
+
+int marucam_device_check(int log_flag)
+{
+    int tmp_fd;
+    struct timeval t1, t2;
+    struct stat st;
+    struct v4l2_fmtdesc format;
+    struct v4l2_frmsizeenum size;
+    struct v4l2_capability cap;
+    int ret = 0;
+
+    gettimeofday(&t1, NULL);
+    if (stat(dev_name, &st) < 0) {
+        INFO("<WARNING> Cannot identify '%s': %s\n",
+                dev_name, strerror(errno));
+    } else {
+        if (!S_ISCHR(st.st_mode)) {
+            INFO("<WARNING>%s is no character device\n",
+                    dev_name);
+        }
+    }
+
+    tmp_fd = open(dev_name, O_RDWR | O_NONBLOCK, 0);
+    if (tmp_fd < 0) {
+        ERR("Camera device open failed: %s\n", dev_name);
+        gettimeofday(&t2, NULL);
+        ERR("Elapsed time: %lu:%06lu\n",
+                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+    if (ioctl(tmp_fd, VIDIOC_QUERYCAP, &cap) < 0) {
+        ERR("Could not qeury video capabilities\n");
+        close(tmp_fd);
+        gettimeofday(&t2, NULL);
+        ERR("Elapsed time: %lu:%06lu\n",
+                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+    if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) ||
+            !(cap.capabilities & V4L2_CAP_STREAMING)) {
+        ERR("Not supported video driver\n");
+        close(tmp_fd);
+        gettimeofday(&t2, NULL);
+        ERR("Elapsed time: %lu:%06lu\n",
+                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+    ret = 1;
+
+    if (log_flag) {
+        INFO("Driver: %s\n", cap.driver);
+        INFO("Card:  %s\n", cap.card);
+        INFO("Bus info: %s\n", cap.bus_info);
+
+        CLEAR(format);
+        format.index = 0;
+        format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+        if (yioctl(tmp_fd, VIDIOC_ENUM_FMT, &format) < 0) {
+            close(tmp_fd);
+            gettimeofday(&t2, NULL);
+            ERR("Elapsed time: %lu:%06lu\n",
+                    t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+            return ret;
+        }
+
+        do {
+            CLEAR(size);
+            size.index = 0;
+            size.pixel_format = format.pixelformat;
+
+            INFO("PixelFormat: %c%c%c%c\n",
+                             (char)(format.pixelformat),
+                             (char)(format.pixelformat >> 8),
+                             (char)(format.pixelformat >> 16),
+                             (char)(format.pixelformat >> 24));
+
+            if (yioctl(tmp_fd, VIDIOC_ENUM_FRAMESIZES, &size) < 0) {
+                close(tmp_fd);
+                gettimeofday(&t2, NULL);
+                ERR("Elapsed time: %lu:%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+                return ret;
+            }
+
+            if (size.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
+                do {
+                    INFO("\tGot a discrete frame size %dx%d\n",
+                                    size.discrete.width, size.discrete.height);
+                    size.index++;
+                } while (yioctl(tmp_fd, VIDIOC_ENUM_FRAMESIZES, &size) >= 0);
+            } else if (size.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
+                INFO("We have stepwise frame sizes:\n");
+                INFO("\tmin width: %d, min height: %d\n",
+                        size.stepwise.min_width, size.stepwise.min_height);
+                INFO("\tmax width: %d, max height: %d\n",
+                        size.stepwise.max_width, size.stepwise.max_height);
+                INFO("\tstep width: %d, step height: %d\n",
+                        size.stepwise.step_width, size.stepwise.step_height);
+            } else if (size.type == V4L2_FRMSIZE_TYPE_CONTINUOUS) {
+                INFO("We have continuous frame sizes:\n");
+                INFO("\tmin width: %d, min height: %d\n",
+                        size.stepwise.min_width, size.stepwise.min_height);
+                INFO("\tmax width: %d, max height: %d\n",
+                        size.stepwise.max_width, size.stepwise.max_height);
+
+            }
+            format.index++;
+        } while (yioctl(tmp_fd, VIDIOC_ENUM_FMT, &format) >= 0);
+    }
+
+    close(tmp_fd);
+    gettimeofday(&t2, NULL);
+    INFO("Elapsed time: %lu:%06lu\n",
+                    t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+    return ret;
+}
+
+void marucam_device_init(MaruCamState *state)
+{
+    state->destroying = false;
+    qemu_thread_create(&state->thread_id,
+                       MARUCAM_THREAD_NAME,
+                       marucam_worker_thread,
+                       (void *)state,
+                       QEMU_THREAD_JOINABLE);
+}
+
+void marucam_device_exit(MaruCamState *state)
+{
+    state->destroying = true;
+    qemu_mutex_lock(&state->thread_mutex);
+    qemu_cond_signal(&state->thread_cond);
+    qemu_mutex_unlock(&state->thread_mutex);
+    qemu_thread_join(&state->thread_id);
+}
+
+void marucam_device_open(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    v4l2_fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0);
+    if (v4l2_fd < 0) {
+        ERR("The v4l2 device open failed: %s\n", dev_name);
+        param->errCode = EINVAL;
+        return;
+    }
+    INFO("Opened\n");
+
+    /* FIXME : Do not use fixed values */
+    CLEAR(dst_fmt);
+    dst_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    dst_fmt.fmt.pix.width = 640;
+    dst_fmt.fmt.pix.height = 480;
+    dst_fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+    dst_fmt.fmt.pix.field = V4L2_FIELD_ANY;
+
+    if (xioctl(v4l2_fd, VIDIOC_S_FMT, &dst_fmt) < 0) {
+        ERR("Failed to set video format: format(0x%x), width:height(%d:%d), "
+          "errstr(%s)\n", dst_fmt.fmt.pix.pixelformat, dst_fmt.fmt.pix.width,
+          dst_fmt.fmt.pix.height, strerror(errno));
+        param->errCode = errno;
+        return;
+    }
+    TRACE("Set the default format: w:h(%dx%d), fmt(0x%x), size(%d), "
+         "color(%d), field(%d)\n",
+         dst_fmt.fmt.pix.width, dst_fmt.fmt.pix.height,
+         dst_fmt.fmt.pix.pixelformat, dst_fmt.fmt.pix.sizeimage,
+         dst_fmt.fmt.pix.colorspace, dst_fmt.fmt.pix.field);
+}
+
+void marucam_device_start_preview(MaruCamState *state)
+{
+    struct timespec req;
+    MaruCamParam *param = state->param;
+    param->top = 0;
+    req.tv_sec = 0;
+    req.tv_nsec = 10000000;
+
+    INFO("Pixfmt(%c%c%c%C), W:H(%d:%d), buf size(%u)\n",
+         (char)(dst_fmt.fmt.pix.pixelformat),
+         (char)(dst_fmt.fmt.pix.pixelformat >> 8),
+         (char)(dst_fmt.fmt.pix.pixelformat >> 16),
+         (char)(dst_fmt.fmt.pix.pixelformat >> 24),
+         dst_fmt.fmt.pix.width,
+         dst_fmt.fmt.pix.height,
+         dst_fmt.fmt.pix.sizeimage);
+
+    param->errCode = mmap_framebuffers(&framebuffer, &n_framebuffer);
+    if (param->errCode) {
+        ERR("Failed to mmap framebuffers\n");
+        if (framebuffer != NULL) {
+            free_framebuffers(framebuffer, n_framebuffer);
+            g_free(framebuffer);
+            framebuffer = NULL;
+            n_framebuffer = 0;
+        }
+        return;
+    }
+
+    param->errCode = start_capturing();
+    if (param->errCode) {
+        if (framebuffer != NULL) {
+            free_framebuffers(framebuffer, n_framebuffer);
+            g_free(framebuffer);
+            framebuffer = NULL;
+            n_framebuffer = 0;
+        }
+        return;
+    }
+
+    INFO("Starting preview\n");
+    state->buf_size = dst_fmt.fmt.pix.sizeimage;
+    qemu_mutex_lock(&state->thread_mutex);
+    qemu_cond_signal(&state->thread_cond);
+    qemu_mutex_unlock(&state->thread_mutex);
+
+    /* nanosleep until thread is streamon  */
+    while (!is_streamon(state)) {
+        nanosleep(&req, NULL);
+    }
+}
+
+void marucam_device_stop_preview(MaruCamState *state)
+{
+    struct timespec req;
+    struct v4l2_requestbuffers reqbuf;
+    MaruCamParam *param = state->param;
+    param->top = 0;
+    req.tv_sec = 0;
+    req.tv_nsec = 50000000;
+
+    if (is_streamon(state)) {
+        qemu_mutex_lock(&state->thread_mutex);
+        state->streamon = _MC_THREAD_STREAMOFF;
+        qemu_mutex_unlock(&state->thread_mutex);
+
+        /* nanosleep until thread is paused  */
+        while (!is_stream_paused(state)) {
+            nanosleep(&req, NULL);
+        }
+    }
+
+    if (has_success_frame) {
+        saved_frame.width = dst_fmt.fmt.pix.width;
+        saved_frame.height = dst_fmt.fmt.pix.height;
+        saved_frame.size = dst_fmt.fmt.pix.sizeimage;
+        if (saved_frame.data) {
+            g_free(saved_frame.data);
+            saved_frame.data = NULL;
+        }
+        saved_frame.data = (void *)g_malloc0(saved_frame.size);
+        memcpy(saved_frame.data,
+               framebuffer[previous_frame_index].data,
+               saved_frame.size);
+        TRACE("Saves a frame data\n");
+    }
+
+    param->errCode = stop_capturing();
+    if (framebuffer != NULL) {
+        free_framebuffers(framebuffer, n_framebuffer);
+        g_free(framebuffer);
+        framebuffer = NULL;
+        n_framebuffer = 0;
+    }
+    state->buf_size = 0;
+
+    reqbuf.count = 0;
+    reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    reqbuf.memory = V4L2_MEMORY_MMAP;
+    if (xioctl(v4l2_fd, VIDIOC_REQBUFS, &reqbuf) < 0) {
+        ERR("Failed to ioctl() with VIDIOC_REQBUF in stop_preview: %s\n",
+            strerror(errno));
+    }
+    INFO("Stopping preview\n");
+}
+
+void marucam_device_s_param(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+
+    /* If KVM enabled, We use default FPS of the webcam.
+     * If KVM disabled, we use mininum FPS of the webcam */
+    if (!kvm_enabled()) {
+        set_maxframeinterval(state, dst_fmt.fmt.pix.pixelformat,
+                     dst_fmt.fmt.pix.width,
+                     dst_fmt.fmt.pix.height);
+    }
+}
+
+void marucam_device_g_param(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+
+    /* We use default FPS of the webcam
+     * return a fixed value on guest ini file (1/30).
+     */
+    param->top = 0;
+    param->stack[0] = 0x1000; /* V4L2_CAP_TIMEPERFRAME */
+    param->stack[1] = 1; /* numerator */
+    param->stack[2] = 30; /* denominator */
+}
+
+void marucam_device_s_fmt(MaruCamState *state)
+{
+    struct v4l2_format format;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    CLEAR(format);
+    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    format.fmt.pix.width = param->stack[0];
+    format.fmt.pix.height = param->stack[1];
+    format.fmt.pix.pixelformat = param->stack[2];
+    format.fmt.pix.field = V4L2_FIELD_ANY;
+
+    if (xioctl(v4l2_fd, VIDIOC_S_FMT, &format) < 0) {
+        ERR("Failed to set video format: format(0x%x), width:height(%d:%d), "
+          "errstr(%s)\n", format.fmt.pix.pixelformat, format.fmt.pix.width,
+          format.fmt.pix.height, strerror(errno));
+        param->errCode = errno;
+        return;
+    }
+
+    memcpy(&dst_fmt, &format, sizeof(format));
+    param->stack[0] = dst_fmt.fmt.pix.width;
+    param->stack[1] = dst_fmt.fmt.pix.height;
+    param->stack[2] = dst_fmt.fmt.pix.field;
+    param->stack[3] = dst_fmt.fmt.pix.pixelformat;
+    param->stack[4] = dst_fmt.fmt.pix.bytesperline;
+    param->stack[5] = dst_fmt.fmt.pix.sizeimage;
+    param->stack[6] = dst_fmt.fmt.pix.colorspace;
+    param->stack[7] = dst_fmt.fmt.pix.priv;
+    TRACE("Set the format: w:h(%dx%d), fmt(0x%x), size(%d), "
+         "color(%d), field(%d)\n",
+         dst_fmt.fmt.pix.width, dst_fmt.fmt.pix.height,
+         dst_fmt.fmt.pix.pixelformat, dst_fmt.fmt.pix.sizeimage,
+         dst_fmt.fmt.pix.colorspace, dst_fmt.fmt.pix.field);
+}
+
+void marucam_device_g_fmt(MaruCamState *state)
+{
+    struct v4l2_format format;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    CLEAR(format);
+    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+    if (xioctl(v4l2_fd, VIDIOC_G_FMT, &format) < 0) {
+        ERR("Failed to get video format: %s\n", strerror(errno));
+        param->errCode = errno;
+    } else {
+        param->stack[0] = format.fmt.pix.width;
+        param->stack[1] = format.fmt.pix.height;
+        param->stack[2] = format.fmt.pix.field;
+        param->stack[3] = format.fmt.pix.pixelformat;
+        param->stack[4] = format.fmt.pix.bytesperline;
+        param->stack[5] = format.fmt.pix.sizeimage;
+        param->stack[6] = format.fmt.pix.colorspace;
+        param->stack[7] = format.fmt.pix.priv;
+        TRACE("Get the format: w:h(%dx%d), fmt(0x%x), size(%d), "
+             "color(%d), field(%d)\n",
+             format.fmt.pix.width, format.fmt.pix.height,
+             format.fmt.pix.pixelformat, format.fmt.pix.sizeimage,
+             format.fmt.pix.colorspace, format.fmt.pix.field);
+    }
+}
+
+void marucam_device_try_fmt(MaruCamState *state)
+{
+    struct v4l2_format format;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    CLEAR(format);
+    format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+    format.fmt.pix.width = param->stack[0];
+    format.fmt.pix.height = param->stack[1];
+    format.fmt.pix.pixelformat = param->stack[2];
+    format.fmt.pix.field = V4L2_FIELD_ANY;
+
+    if (xioctl(v4l2_fd, VIDIOC_TRY_FMT, &format) < 0) {
+        ERR("Failed to check video format: format(0x%x), width:height(%d:%d),"
+            " errstr(%s)\n", format.fmt.pix.pixelformat, format.fmt.pix.width,
+            format.fmt.pix.height, strerror(errno));
+        param->errCode = errno;
+        return;
+    }
+    param->stack[0] = format.fmt.pix.width;
+    param->stack[1] = format.fmt.pix.height;
+    param->stack[2] = format.fmt.pix.field;
+    param->stack[3] = format.fmt.pix.pixelformat;
+    param->stack[4] = format.fmt.pix.bytesperline;
+    param->stack[5] = format.fmt.pix.sizeimage;
+    param->stack[6] = format.fmt.pix.colorspace;
+    param->stack[7] = format.fmt.pix.priv;
+    TRACE("Check the format: w:h(%dx%d), fmt(0x%x), size(%d), "
+         "color(%d), field(%d)\n",
+         format.fmt.pix.width, format.fmt.pix.height,
+         format.fmt.pix.pixelformat, format.fmt.pix.sizeimage,
+         format.fmt.pix.colorspace, format.fmt.pix.field);
+}
+
+void marucam_device_enum_fmt(MaruCamState *state)
+{
+    uint32_t index;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    index = param->stack[0];
+
+    if (index >= ARRAY_SIZE(supported_dst_pixfmts)) {
+        param->errCode = EINVAL;
+        return;
+    }
+    param->stack[1] = 0; /* flags = NONE */
+    param->stack[2] = supported_dst_pixfmts[index].fmt; /* pixelformat */
+    /* set description */
+    switch (supported_dst_pixfmts[index].fmt) {
+    case V4L2_PIX_FMT_YUYV:
+        strcpy((char *)&param->stack[3], "YUYV");
+        break;
+    case V4L2_PIX_FMT_YUV420:
+        strcpy((char *)&param->stack[3], "YU12");
+        break;
+    case V4L2_PIX_FMT_YVU420:
+        strcpy((char *)&param->stack[3], "YV12");
+        break;
+    default:
+        ERR("Invalid fixel format\n");
+        param->errCode = EINVAL;
+        break;
+    }
+}
+
+void marucam_device_qctrl(MaruCamState *state)
+{
+    uint32_t i;
+    char name[32] = {0,};
+    struct v4l2_queryctrl ctrl;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    CLEAR(ctrl);
+    ctrl.id = param->stack[0];
+
+    switch (ctrl.id) {
+    case V4L2_CID_BRIGHTNESS:
+        TRACE("Query : BRIGHTNESS\n");
+        strcpy(name, "brightness");
+        i = 0;
+        break;
+    case V4L2_CID_CONTRAST:
+        TRACE("Query : CONTRAST\n");
+        strcpy(name, "contrast");
+        i = 1;
+        break;
+    case V4L2_CID_SATURATION:
+        TRACE("Query : SATURATION\n");
+        strcpy(name, "saturation");
+        i = 2;
+        break;
+    case V4L2_CID_SHARPNESS:
+        TRACE("Query : SHARPNESS\n");
+        strcpy(name, "sharpness");
+        i = 3;
+        break;
+    default:
+        ERR("Invalid control ID\n");
+        param->errCode = EINVAL;
+        return;
+    }
+
+    if (xioctl(v4l2_fd, VIDIOC_QUERYCTRL, &ctrl) < 0) {
+        if (errno != EINVAL) {
+            ERR("Failed to query video controls: %s\n", strerror(errno));
+        }
+        param->errCode = errno;
+        return;
+    } else {
+        struct v4l2_control sctrl;
+        CLEAR(sctrl);
+        sctrl.id = ctrl.id;
+        if ((ctrl.maximum + ctrl.minimum) == 0) {
+            sctrl.value = 0;
+        } else {
+            sctrl.value = (ctrl.maximum + ctrl.minimum) / 2;
+        }
+        if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &sctrl) < 0) {
+            ERR("Failed to set control value: id(0x%x), value(%d), "
+                "errstr(%s)\n", sctrl.id, sctrl.value, strerror(errno));
+            param->errCode = errno;
+            return;
+        }
+        qctrl_tbl[i].hit = 1;
+        qctrl_tbl[i].min = ctrl.minimum;
+        qctrl_tbl[i].max = ctrl.maximum;
+        qctrl_tbl[i].step = ctrl.step;
+        qctrl_tbl[i].init_val = ctrl.default_value;
+    }
+
+    /* set fixed values by FW configuration file */
+    param->stack[0] = ctrl.id;
+    param->stack[1] = MARUCAM_CTRL_VALUE_MIN;    /* minimum */
+    param->stack[2] = MARUCAM_CTRL_VALUE_MAX;    /* maximum */
+    param->stack[3] = MARUCAM_CTRL_VALUE_STEP;   /* step */
+    param->stack[4] = MARUCAM_CTRL_VALUE_MID;    /* default_value */
+    param->stack[5] = ctrl.flags;
+    /* name field setting */
+    memcpy(&param->stack[6], (void *)name, sizeof(ctrl.name));
+}
+
+void marucam_device_s_ctrl(MaruCamState *state)
+{
+    uint32_t i;
+    struct v4l2_control ctrl;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    CLEAR(ctrl);
+    ctrl.id = param->stack[0];
+
+    switch (ctrl.id) {
+    case V4L2_CID_BRIGHTNESS:
+        i = 0;
+        TRACE("%d is set to the value of the BRIGHTNESS\n", param->stack[1]);
+        break;
+    case V4L2_CID_CONTRAST:
+        i = 1;
+        TRACE("%d is set to the value of the CONTRAST\n", param->stack[1]);
+        break;
+    case V4L2_CID_SATURATION:
+        i = 2;
+        TRACE("%d is set to the value of the SATURATION\n", param->stack[1]);
+        break;
+    case V4L2_CID_SHARPNESS:
+        i = 3;
+        TRACE("%d is set to the value of the SHARPNESS\n", param->stack[1]);
+        break;
+    default:
+        ERR("Our emulator does not support this control: 0x%x\n", ctrl.id);
+        param->errCode = EINVAL;
+        return;
+    }
+
+    ctrl.value = value_convert_from_guest(qctrl_tbl[i].min,
+            qctrl_tbl[i].max, param->stack[1]);
+    if (xioctl(v4l2_fd, VIDIOC_S_CTRL, &ctrl) < 0) {
+        ERR("Failed to set control value: id(0x%x), value(r:%d, c:%d), "
+            "errstr(%s)\n", ctrl.id, param->stack[1], ctrl.value,
+            strerror(errno));
+        param->errCode = errno;
+        return;
+    }
+}
+
+void marucam_device_g_ctrl(MaruCamState *state)
+{
+    uint32_t i;
+    struct v4l2_control ctrl;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    CLEAR(ctrl);
+    ctrl.id = param->stack[0];
+
+    switch (ctrl.id) {
+    case V4L2_CID_BRIGHTNESS:
+        TRACE("Gets the value of the BRIGHTNESS\n");
+        i = 0;
+        break;
+    case V4L2_CID_CONTRAST:
+        TRACE("Gets the value of the CONTRAST\n");
+        i = 1;
+        break;
+    case V4L2_CID_SATURATION:
+        TRACE("Gets the value of the SATURATION\n");
+        i = 2;
+        break;
+    case V4L2_CID_SHARPNESS:
+        TRACE("Gets the value of the SHARPNESS\n");
+        i = 3;
+        break;
+    default:
+        ERR("Our emulator does not support this control: 0x%x\n", ctrl.id);
+        param->errCode = EINVAL;
+        return;
+    }
+
+    if (xioctl(v4l2_fd, VIDIOC_G_CTRL, &ctrl) < 0) {
+        ERR("Failed to get video control value: %s\n", strerror(errno));
+        param->errCode = errno;
+        return;
+    }
+    param->stack[0] = value_convert_to_guest(qctrl_tbl[i].min,
+            qctrl_tbl[i].max, ctrl.value);
+    TRACE("Value: %d\n", param->stack[0]);
+}
+
+void marucam_device_enum_fsizes(MaruCamState *state)
+{
+    uint32_t index, pixfmt, i;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    index = param->stack[0];
+    pixfmt = param->stack[1];
+
+    if (index >= ARRAY_SIZE(supported_dst_frames)) {
+        param->errCode = EINVAL;
+        return;
+    }
+    for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) {
+        if (supported_dst_pixfmts[i].fmt == pixfmt) {
+            break;
+        }
+    }
+
+    if (i == ARRAY_SIZE(supported_dst_pixfmts)) {
+        param->errCode = EINVAL;
+        return;
+    }
+
+    param->stack[0] = supported_dst_frames[index].width;
+    param->stack[1] = supported_dst_frames[index].height;
+}
+
+void marucam_device_enum_fintv(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+
+    /* switch by index(param->stack[0]) */
+    switch (param->stack[0]) {
+    case 0:
+        /* we only use 1/30 frame interval */
+        param->stack[1] = 30;   /* denominator */
+        break;
+    default:
+        param->errCode = EINVAL;
+        return;
+    }
+    param->stack[0] = 1;    /* numerator */
+}
+
+void marucam_device_close(MaruCamState *state)
+{
+    if (!is_stream_paused(state)) {
+        marucam_device_stop_preview(state);
+    }
+
+    marucam_reset_controls();
+
+    if (saved_frame.data) {
+        g_free(saved_frame.data);
+        saved_frame.data = NULL;
+    }
+    memset(&saved_frame, 0x00, sizeof(saved_frame));
+
+    v4l2_close(v4l2_fd);
+    v4l2_fd = 0;
+    INFO("Closed\n");
+}
diff --git a/tizen/src/hw/pci/maru_camera_win32_interface.h b/tizen/src/hw/pci/maru_camera_win32_interface.h
new file mode 100644 (file)
index 0000000..11e0e24
--- /dev/null
@@ -0,0 +1,934 @@
+/*
+ * Interface definition header for Windows host.
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * JinHyung Jo <jinhyung.jo@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_CAMERA_INTERFACE_H_
+#define _MARU_CAMERA_INTERFACE_H_
+
+extern int hax_enabled(void);
+
+static const WCHAR HWCPinName[] = L"HWCInputPin\0";
+static const WCHAR HWCFilterName[] = L"HWCFilter\0";
+
+/* Forward Declarations */
+FWD_DECL(IBaseFilter);
+FWD_DECL(IFilterGraph);
+
+/* defines */
+#define MAX_PIN_NAME     128
+#define MAX_FILTER_NAME  128
+
+#define DECLARE_INTERFACE2(i) \
+   _COM_interface i { CONST_VTABLE struct i##Vtbl *lpVtbl; }; \
+   typedef CONST_VTABLE struct i##Vtbl i##Vtbl; \
+   CONST_VTABLE struct i##Vtbl
+#define DECLARE_INTERFACE2_(i, b) DECLARE_INTERFACE2(i)
+
+typedef LONGLONG REFERENCE_TIME;
+typedef long OAFilterState;
+typedef DWORD_PTR HSEMAPHORE;
+typedef DWORD_PTR HEVENT;
+
+typedef enum _FilterState {
+  State_Stopped,
+  State_Paused,
+  State_Running
+} FILTER_STATE;
+
+typedef struct _FilterInfo {
+  WCHAR achName[MAX_FILTER_NAME];
+  IFilterGraph *pGraph;
+} FILTER_INFO;
+
+typedef enum _PinDirection {
+    PINDIR_INPUT    = 0,
+    PINDIR_OUTPUT   = (PINDIR_INPUT + 1)
+} PIN_DIRECTION;
+
+typedef struct _PinInfo {
+  IBaseFilter *pFilter;
+  PIN_DIRECTION dir;
+  WCHAR achName[MAX_PIN_NAME];
+} PIN_INFO;
+
+typedef struct _AllocatorProperties {
+  long cBuffers;
+  long cbBuffer;
+  long cbAlign;
+  long cbPrefix;
+} ALLOCATOR_PROPERTIES;
+
+typedef struct _AMMediaType {
+  GUID majortype;
+  GUID subtype;
+  BOOL bFixedSizeSamples;
+  BOOL bTemporalCompression;
+  ULONG lSampleSize;
+  GUID formattype;
+  IUnknown *pUnk;
+  ULONG cbFormat;
+  BYTE *pbFormat;
+} AM_MEDIA_TYPE;
+
+typedef enum tagVideoProcAmpFlags {
+    VideoProcAmp_Flags_Auto = 0x0001,
+    VideoProcAmp_Flags_Manual = 0x0002
+} VideoProcAmpFlags;
+
+typedef enum tagVideoProcAmpProperty {
+    VideoProcAmp_Brightness,
+    VideoProcAmp_Contrast,
+    VideoProcAmp_Hue,
+    VideoProcAmp_Saturation,
+    VideoProcAmp_Sharpness,
+    VideoProcAmp_Gamma,
+    VideoProcAmp_ColorEnable,
+    VideoProcAmp_WhiteBalance,
+    VideoProcAmp_BacklightCompensation,
+    VideoProcAmp_Gain
+} VideoProcAmpProperty;
+
+typedef struct tagVIDEOINFOHEADER {
+    RECT rcSource;
+    RECT rcTarget;
+    DWORD dwBitRate;
+    DWORD dwBitErrorRate;
+    REFERENCE_TIME AvgTimePerFrame;
+    BITMAPINFOHEADER bmiHeader;
+} VIDEOINFOHEADER;
+
+typedef struct _VIDEO_STREAM_CONFIG_CAPS {
+  GUID guid;
+  ULONG VideoStandard;
+  SIZE InputSize;
+  SIZE MinCroppingSize;
+  SIZE MaxCroppingSize;
+  int CropGranularityX;
+  int CropGranularityY;
+  int CropAlignX;
+  int CropAlignY;
+  SIZE MinOutputSize;
+  SIZE MaxOutputSize;
+  int OutputGranularityX;
+  int OutputGranularityY;
+  int StretchTapsX;
+  int StretchTapsY;
+  int ShrinkTapsX;
+  int ShrinkTapsY;
+  LONGLONG MinFrameInterval;
+  LONGLONG MaxFrameInterval;
+  LONG MinBitsPerSecond;
+  LONG MaxBitsPerSecond;
+} VIDEO_STREAM_CONFIG_CAPS;
+
+
+/* Interface & Class GUIDs */
+static const IID IID_IGrabCallback   = {0x4C337035,0xC89E,0x4B42,{0x9B,0x0C,0x36,0x74,0x44,0xDD,0x70,0xDD}};
+
+EXTERN_C const IID IID_IBaseFilter;
+EXTERN_C const IID IID_ICreateDevEnum;
+EXTERN_C const IID IID_IGraphBuilder;
+EXTERN_C const IID IID_IMediaSeeking;
+EXTERN_C const IID IID_IMediaEventSink;
+EXTERN_C const IID IID_IMemInputPin;
+EXTERN_C const IID IID_IEnumPins;
+EXTERN_C const IID IID_IMediaFilter;
+EXTERN_C const IID IID_IEnumMediaTypes;
+EXTERN_C const IID IID_IMemAllocator;
+EXTERN_C const IID IID_IPin;
+EXTERN_C const IID IID_ICaptureGraphBuilder2;
+EXTERN_C const IID IID_IFileSinkFilter;
+EXTERN_C const IID IID_IAMCopyCaptureFileProgress;
+EXTERN_C const IID IID_IEnumFilters;
+EXTERN_C const IID IID_IMediaSample;
+EXTERN_C const IID IID_IMediaControl;
+EXTERN_C const IID IID_IAMStreamConfig;
+EXTERN_C const IID IID_IAMVideoProcAmp;
+
+EXTERN_C const IID CLSID_CaptureGraphBuilder2;
+EXTERN_C const IID CLSID_VideoInputDeviceCategory;
+EXTERN_C const IID CLSID_AudioRender;
+EXTERN_C const IID CLSID_SystemDeviceEnum;
+EXTERN_C const IID CLSID_AudioRendererCategory;
+EXTERN_C const IID CLSID_FilterGraph;
+EXTERN_C const IID CLSID_InfTee;
+EXTERN_C const IID CLSID_VideoMixingRenderer9;
+EXTERN_C const IID CLSID_MemoryAllocator;
+
+
+/* other types GUIDs*/
+EXTERN_C const IID MEDIATYPE_Audio;
+EXTERN_C const IID MEDIATYPE_Video;
+EXTERN_C const IID MEDIATYPE_Stream;
+EXTERN_C const IID MEDIASUBTYPE_PCM;
+EXTERN_C const IID MEDIASUBTYPE_WAVE;
+EXTERN_C const IID MEDIASUBTYPE_Avi;
+EXTERN_C const IID MEDIASUBTYPE_RGB32;
+EXTERN_C const IID MEDIASUBTYPE_YV12;
+EXTERN_C const IID MEDIASUBTYPE_YUY2;
+EXTERN_C const IID MEDIASUBTYPE_I420;
+EXTERN_C const IID MEDIASUBTYPE_YUYV;
+EXTERN_C const IID FORMAT_WaveFormatEx;
+EXTERN_C const IID FORMAT_VideoInfo;
+EXTERN_C const IID FORMAT_VideoInfo2;
+EXTERN_C const IID PIN_CATEGORY_CAPTURE;
+EXTERN_C const IID PIN_CATEGORY_PREVIEW;
+
+
+#define MEDIATYPE_NULL       GUID_NULL
+#define MEDIASUBTYPE_NULL    GUID_NULL
+
+#define INTERFACE IGrabCallback
+DECLARE_INTERFACE_(IGrabCallback, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(Grab)(THIS_ ULONG,BYTE*) PURE;
+};
+#undef INTERFACE
+
+#ifdef COBJMACROS
+#define IGrabCallback_QueryInterface(T,a,b) (T)->lpVtbl->QueryInterface(T,a,b)
+#define IGrabCallback_AddRef(T) (T)->lpVtbl->AddRef(T)
+#define IGrabCallback_Release(T) (T)->lpVtbl->Release(T)
+#define IGrabCallback_Grab(T,a,b) (T)->lpVtbl->Grab(T,a,b)
+#endif /* COBJMACROS */
+
+#define INTERFACE IAMCopyCaptureFileProgress
+DECLARE_INTERFACE_(IAMCopyCaptureFileProgress, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(Progress)(THIS_ int) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IReferenceClock
+DECLARE_INTERFACE_(IReferenceClock, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(GetTime)(THIS_ REFERENCE_TIME *) PURE;
+    STDMETHOD(AdviseTime)(THIS_ REFERENCE_TIME, REFERENCE_TIME, HEVENT, DWORD_PTR *) PURE;
+    STDMETHOD(AdvisePeriodic)(THIS_ REFERENCE_TIME, REFERENCE_TIME, HSEMAPHORE, DWORD_PTR *) PURE;
+    STDMETHOD(Unadvise)(THIS_ DWORD_PTR) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IEnumFilters
+DECLARE_INTERFACE_(IEnumFilters, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(Next)(THIS_ ULONG, IBaseFilter **, ULONG *) PURE;
+    STDMETHOD(Skip)(THIS_ ULONG) PURE;
+    STDMETHOD(Reset)(THIS) PURE;
+    STDMETHOD(Clone)(THIS_ IEnumFilters **) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IEnumMediaTypes
+DECLARE_INTERFACE_(IEnumMediaTypes, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(Next)(THIS_ ULONG, AM_MEDIA_TYPE **, ULONG *) PURE;
+    STDMETHOD(Skip)(THIS_ ULONG) PURE;
+    STDMETHOD(Reset)(THIS) PURE;
+    STDMETHOD(Clone)(THIS_ IEnumMediaTypes **) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IPin
+DECLARE_INTERFACE_(IPin, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(Connect)(THIS_ IPin *, const AM_MEDIA_TYPE *) PURE;
+    STDMETHOD(ReceiveConnection)(THIS_ IPin *, const AM_MEDIA_TYPE *) PURE;
+    STDMETHOD(Disconnect)(THIS) PURE;
+    STDMETHOD(ConnectedTo)(THIS_ IPin **) PURE;
+    STDMETHOD(ConnectionMediaType)(THIS_ AM_MEDIA_TYPE *) PURE;
+    STDMETHOD(QueryPinInfo)(THIS_ PIN_INFO *) PURE;
+    STDMETHOD(QueryDirection)(THIS_ PIN_DIRECTION *) PURE;
+    STDMETHOD(QueryId)(THIS_ LPWSTR *) PURE;
+    STDMETHOD(QueryAccept)(THIS_ const AM_MEDIA_TYPE *) PURE;
+    STDMETHOD(EnumMediaTypes)(THIS_ IEnumMediaTypes **) PURE;
+    STDMETHOD(QueryInternalConnections)(THIS_ IPin **, ULONG *) PURE;
+    STDMETHOD(EndOfStream)(THIS) PURE;
+    STDMETHOD(BeginFlush)(THIS) PURE;
+    STDMETHOD(EndFlush)(THIS) PURE;
+    STDMETHOD(NewSegment)(THIS_ REFERENCE_TIME, REFERENCE_TIME, double) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IEnumPins
+DECLARE_INTERFACE_(IEnumPins, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(Next)(THIS_ ULONG, IPin **, ULONG *) PURE;
+    STDMETHOD(Skip)(THIS_ ULONG) PURE;
+    STDMETHOD(Reset)(THIS) PURE;
+    STDMETHOD(Clone)(THIS_ IEnumPins **) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IMediaFilter
+DECLARE_INTERFACE_(IMediaFilter, IPersist)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(GetClassID)(THIS_ CLSID*) PURE;
+    STDMETHOD(Stop)(THIS) PURE;
+    STDMETHOD(Pause)(THIS) PURE;
+    STDMETHOD(Run)(THIS_ REFERENCE_TIME) PURE;
+    STDMETHOD(GetState)(THIS_ DWORD, FILTER_STATE *) PURE;
+    STDMETHOD(SetSyncSource)(THIS_ IReferenceClock *) PURE;
+    STDMETHOD(GetSyncSource)(THIS_ IReferenceClock **) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IBaseFilter
+DECLARE_INTERFACE2_(IBaseFilter, IMediaFilter)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(GetClassID)(THIS_ CLSID*) PURE;
+    STDMETHOD(Stop)(THIS) PURE;
+    STDMETHOD(Pause)(THIS) PURE;
+    STDMETHOD(Run)(THIS_ REFERENCE_TIME) PURE;
+    STDMETHOD(GetState)(THIS_ DWORD, FILTER_STATE *) PURE;
+    STDMETHOD(SetSyncSource)(THIS_ IReferenceClock *) PURE;
+    STDMETHOD(GetSyncSource)(THIS_ IReferenceClock **) PURE;
+    STDMETHOD(EnumPins)(THIS_ IEnumPins **) PURE;
+    STDMETHOD(FindPin)(THIS_ LPCWSTR, IPin **) PURE;
+    STDMETHOD(QueryFilterInfo)(THIS_ FILTER_INFO *) PURE;
+    STDMETHOD(JoinFilterGraph)(THIS_ IFilterGraph *, LPCWSTR) PURE;
+    STDMETHOD(QueryVendorInfo)(THIS_ LPWSTR *) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IFilterGraph
+DECLARE_INTERFACE2_(IFilterGraph, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(AddFilter)(THIS_ IBaseFilter *, LPCWSTR) PURE;
+    STDMETHOD(RemoveFilter)(THIS_ IBaseFilter *) PURE;
+    STDMETHOD(EnumFilters)(THIS_ IEnumFilters **) PURE;
+    STDMETHOD(FindFilterByName)(THIS_ LPCWSTR, IBaseFilter **) PURE;
+    STDMETHOD(ConnectDirect)(THIS_ IPin *, IPin *, const AM_MEDIA_TYPE *) PURE;
+    STDMETHOD(Reconnect)(THIS_ IPin *) PURE;
+    STDMETHOD(Disconnect)(THIS_ IPin *) PURE;
+    STDMETHOD(SetDefaultSyncSource)(THIS) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IGraphBuilder
+DECLARE_INTERFACE_(IGraphBuilder ,IFilterGraph)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(AddFilter)(THIS_ IBaseFilter *, LPCWSTR) PURE;
+    STDMETHOD(RemoveFilter)(THIS_ IBaseFilter *) PURE;
+    STDMETHOD(EnumFilters)(THIS_ IEnumFilters **) PURE;
+    STDMETHOD(FindFilterByName)(THIS_ LPCWSTR, IBaseFilter **) PURE;
+    STDMETHOD(ConnectDirect)(THIS_ IPin *, IPin *, const AM_MEDIA_TYPE *) PURE;
+    STDMETHOD(Reconnect)(THIS_ IPin *) PURE;
+    STDMETHOD(Disconnect)(THIS_ IPin *) PURE;
+    STDMETHOD(SetDefaultSyncSource)(THIS) PURE;
+    STDMETHOD(Connect)(THIS_ IPin *, IPin *) PURE;
+    STDMETHOD(Render)(THIS_ IPin *) PURE;
+    STDMETHOD(RenderFile)(THIS_ LPCWSTR, LPCWSTR) PURE;
+    STDMETHOD(AddSourceFilter)(THIS_ LPCWSTR, LPCWSTR, IBaseFilter **) PURE;
+    STDMETHOD(SetLogFile)(THIS_ DWORD_PTR) PURE;
+    STDMETHOD(Abort)(THIS) PURE;
+    STDMETHOD(ShouldOperationContinue)(THIS) PURE;
+};
+#undef INTERFACE
+#define INTERFACE ICreateDevEnum
+DECLARE_INTERFACE_(ICreateDevEnum, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(CreateClassEnumerator)(THIS_ REFCLSID, IEnumMoniker **, DWORD) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IMediaSample
+DECLARE_INTERFACE_(IMediaSample, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(GetPointer)(THIS_ BYTE **) PURE;
+    STDMETHOD_(long, GetSize)(THIS) PURE;
+    STDMETHOD(GetTime)(THIS_ REFERENCE_TIME *, REFERENCE_TIME *) PURE;
+    STDMETHOD(SetTime)(THIS_ REFERENCE_TIME *, REFERENCE_TIME *) PURE;
+    STDMETHOD(IsSyncPoint)(THIS) PURE;
+    STDMETHOD(SetSyncPoint)(THIS_ BOOL) PURE;
+    STDMETHOD(IsPreroll)(THIS) PURE;
+    STDMETHOD(SetPreroll)(THIS_ BOOL) PURE;
+    STDMETHOD_(long, GetActualDataLength)(THIS) PURE;
+    STDMETHOD(SetActualDataLength)(THIS_ long) PURE;
+    STDMETHOD(GetMediaType)(THIS_ AM_MEDIA_TYPE **) PURE;
+    STDMETHOD(SetMediaType)(THIS_ AM_MEDIA_TYPE *) PURE;
+    STDMETHOD(IsDiscontinuity)(THIS) PURE;
+    STDMETHOD(SetDiscontinuity)(THIS_ BOOL) PURE;
+    STDMETHOD(GetMediaTime)(THIS_ LONGLONG *, LONGLONG *) PURE;
+    STDMETHOD(SetMediaTime)(THIS_ LONGLONG *, LONGLONG *) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IMemAllocator
+DECLARE_INTERFACE_(IMemAllocator, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(SetProperties)(THIS_ ALLOCATOR_PROPERTIES *, ALLOCATOR_PROPERTIES *) PURE;
+    STDMETHOD(GetProperties)(THIS_ ALLOCATOR_PROPERTIES *) PURE;
+    STDMETHOD(Commit)(THIS) PURE;
+    STDMETHOD(Decommit)(THIS) PURE;
+    STDMETHOD(GetBuffer)(THIS_ IMediaSample **, REFERENCE_TIME *, REFERENCE_TIME *, DWORD) PURE;
+    STDMETHOD(ReleaseBuffer)(THIS_ IMediaSample *) PURE;
+
+};
+#undef INTERFACE
+#define INTERFACE IMemInputPin
+DECLARE_INTERFACE_(IMemInputPin, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(GetAllocator)(THIS_ IMemAllocator **) PURE;
+    STDMETHOD(NotifyAllocator)(THIS_ IMemAllocator *, BOOL) PURE;
+    STDMETHOD(GetAllocatorRequirements)(THIS_ ALLOCATOR_PROPERTIES *) PURE;
+    STDMETHOD(Receive)(THIS_ IMediaSample *) PURE;
+    STDMETHOD(ReceiveMultiple)(THIS_ IMediaSample **, long, long *) PURE;
+    STDMETHOD(ReceiveCanBlock)(THIS) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IFileSinkFilter
+DECLARE_INTERFACE_(IFileSinkFilter, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(SetFileName)(THIS_ LPCOLESTR,const AM_MEDIA_TYPE *) PURE;
+    STDMETHOD(GetCurFile)(THIS_ LPOLESTR *,AM_MEDIA_TYPE*) PURE;
+};
+#undef INTERFACE
+#define INTERFACE ICaptureGraphBuilder2
+DECLARE_INTERFACE_(ICaptureGraphBuilder2, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(SetFiltergraph)(THIS_ IGraphBuilder*) PURE;
+    STDMETHOD(GetFiltergraph)(THIS_ IGraphBuilder**) PURE;
+    STDMETHOD(SetOutputFileName)(THIS_ const GUID*,LPCOLESTR,IBaseFilter**,IFileSinkFilter**) PURE;
+    STDMETHOD(FindInterface)(THIS_ const GUID*,const GUID*,IBaseFilter*,REFIID,void**) PURE;
+    STDMETHOD(RenderStream)(THIS_ const GUID*,const GUID*,IUnknown*,IBaseFilter*,IBaseFilter*) PURE;
+    STDMETHOD(ControlStream)(THIS_ const GUID*,const GUID*,IBaseFilter*,REFERENCE_TIME*,REFERENCE_TIME*,WORD,WORD) PURE;
+    STDMETHOD(AllocCapFile)(THIS_ LPCOLESTR,DWORDLONG) PURE;
+    STDMETHOD(CopyCaptureFile)(THIS_ LPOLESTR,LPOLESTR,int,IAMCopyCaptureFileProgress*) PURE;
+    STDMETHOD(FindPin)(THIS_ IUnknown*,PIN_DIRECTION,const GUID*,const GUID*,BOOL,int,IPin**) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IAMStreamConfig
+DECLARE_INTERFACE_(IAMStreamConfig, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(SetFormat)(THIS_ AM_MEDIA_TYPE*) PURE;
+    STDMETHOD(GetFormat)(THIS_ AM_MEDIA_TYPE**) PURE;
+    STDMETHOD(GetNumberOfCapabilities)(THIS_ int*,int*) PURE;
+    STDMETHOD(GetStreamCaps)(THIS_ int,AM_MEDIA_TYPE**,BYTE*) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IAMVideoProcAmp
+DECLARE_INTERFACE_(IAMVideoProcAmp, IUnknown)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(GetRange)(THIS_ long,long*,long*,long*,long*,long*) PURE;
+    STDMETHOD(Set)(THIS_ long,long,long) PURE;
+    STDMETHOD(Get)(THIS_ long,long*,long*) PURE;
+};
+#undef INTERFACE
+#define INTERFACE IMediaControl
+DECLARE_INTERFACE_(IMediaControl, IDispatch)
+{
+    STDMETHOD(QueryInterface)(THIS_ REFIID, PVOID *) PURE;
+    STDMETHOD_(ULONG, AddRef)(THIS) PURE;
+    STDMETHOD_(ULONG, Release)(THIS) PURE;
+    STDMETHOD(GetTypeInfoCount)(THIS_ UINT*);
+    STDMETHOD(GetTypeInfo)(THIS_ UINT,LCID,ITypeInfo**);
+    STDMETHOD(GetIDsOfNames)(THIS_ REFIID,LPOLESTR*,UINT,LCID,DISPID*);
+    STDMETHOD(Invoke)(THIS_ DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*);
+    STDMETHOD(Run)(THIS);
+    STDMETHOD(Pause)(THIS);
+    STDMETHOD(Stop)(THIS);
+    STDMETHOD(GetState)(THIS_ LONG, OAFilterState*);
+    STDMETHOD(RenderFile)(THIS_ BSTR);
+    STDMETHOD(AddSourceFilter)(THIS_ BSTR,IDispatch**);
+    STDMETHOD(get_FilterCollection)(THIS_ IDispatch**);
+    STDMETHOD(get_RegFilterCollection)(THIS_ IDispatch**);
+    STDMETHOD(StopWhenReady)(THIS);
+};
+#undef INTERFACE
+
+#ifdef COBJMACROS
+#define ICreateDevEnum_QueryInterface(This,riid,ppvObject)  \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define ICreateDevEnum_AddRef(This) \
+    ((This)->lpVtbl->AddRef(This))
+#define ICreateDevEnum_Release(This)    \
+    ((This)->lpVtbl->Release(This))
+#define ICreateDevEnum_CreateClassEnumerator(This,clsidDeviceClass,ppEnumMoniker,dwFlags)   \
+    ((This)->lpVtbl->CreateClassEnumerator(This,clsidDeviceClass,ppEnumMoniker,dwFlags))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IPin_QueryInterface(This,riid,ppvObject)    \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IPin_AddRef(This)   \
+    ((This)->lpVtbl->AddRef(This))
+#define IPin_Release(This)  \
+    ((This)->lpVtbl->Release(This))
+#define IPin_Connect(This,pReceivePin,pmt)  \
+    ((This)->lpVtbl->Connect(This,pReceivePin,pmt))
+#define IPin_ReceiveConnection(This,pConnector,pmt) \
+    ((This)->lpVtbl->ReceiveConnection(This,pConnector,pmt))
+#define IPin_Disconnect(This)   \
+    ((This)->lpVtbl->Disconnect(This))
+#define IPin_ConnectedTo(This,pPin) \
+    ((This)->lpVtbl->ConnectedTo(This,pPin))
+#define IPin_ConnectionMediaType(This,pmt)  \
+    ((This)->lpVtbl->ConnectionMediaType(This,pmt))
+#define IPin_QueryPinInfo(This,pInfo)   \
+    ((This)->lpVtbl->QueryPinInfo(This,pInfo))
+#define IPin_QueryDirection(This,pPinDir)   \
+    ((This)->lpVtbl->QueryDirection(This,pPinDir))
+#define IPin_QueryId(This,Id)   \
+    ((This)->lpVtbl->QueryId(This,Id))
+#define IPin_QueryAccept(This,pmt)  \
+    ((This)->lpVtbl->QueryAccept(This,pmt))
+#define IPin_EnumMediaTypes(This,ppEnum)    \
+    ((This)->lpVtbl->EnumMediaTypes(This,ppEnum))
+#define IPin_QueryInternalConnections(This,apPin,nPin)  \
+    ((This)->lpVtbl->QueryInternalConnections(This,apPin,nPin))
+#define IPin_EndOfStream(This)  \
+    ((This)->lpVtbl->EndOfStream(This))
+#define IPin_BeginFlush(This)   \
+    ((This)->lpVtbl->BeginFlush(This))
+#define IPin_EndFlush(This) \
+    ((This)->lpVtbl->EndFlush(This))
+#define IPin_NewSegment(This,tStart,tStop,dRate)    \
+    ((This)->lpVtbl->NewSegment(This,tStart,tStop,dRate))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IEnumPins_QueryInterface(This,riid,ppvObject)   \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IEnumPins_AddRef(This)  \
+    ((This)->lpVtbl->AddRef(This))
+#define IEnumPins_Release(This) \
+    ((This)->lpVtbl->Release(This))
+#define IEnumPins_Next(This,cPins,ppPins,pcFetched) \
+    ((This)->lpVtbl->Next(This,cPins,ppPins,pcFetched))
+#define IEnumPins_Skip(This,cPins)  \
+    ((This)->lpVtbl->Skip(This,cPins))
+#define IEnumPins_Reset(This)   \
+    ((This)->lpVtbl->Reset(This))
+#define IEnumPins_Clone(This,ppEnum)    \
+    ((This)->lpVtbl->Clone(This,ppEnum))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IAMStreamConfig_QueryInterface(This,riid,ppvObject) \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IAMStreamConfig_AddRef(This)    \
+    ((This)->lpVtbl->AddRef(This))
+#define IAMStreamConfig_Release(This)   \
+    ((This)->lpVtbl->Release(This))
+#define IAMStreamConfig_SetFormat(This,pmt) \
+    ((This)->lpVtbl->SetFormat(This,pmt))
+#define IAMStreamConfig_GetFormat(This,ppmt)    \
+    ((This)->lpVtbl->GetFormat(This,ppmt))
+#define IAMStreamConfig_GetNumberOfCapabilities(This,piCount,piSize)    \
+    ((This)->lpVtbl->GetNumberOfCapabilities(This,piCount,piSize))
+#define IAMStreamConfig_GetStreamCaps(This,iIndex,ppmt,pSCC)    \
+    ((This)->lpVtbl->GetStreamCaps(This,iIndex,ppmt,pSCC))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IFilterGraph_QueryInterface(This,riid,ppvObject)    \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IFilterGraph_AddRef(This)   \
+    ((This)->lpVtbl->AddRef(This))
+#define IFilterGraph_Release(This)  \
+    ((This)->lpVtbl->Release(This))
+#define IFilterGraph_AddFilter(This,pFilter,pName)  \
+    ((This)->lpVtbl->AddFilter(This,pFilter,pName))
+#define IFilterGraph_RemoveFilter(This,pFilter) \
+    ((This)->lpVtbl->RemoveFilter(This,pFilter))
+#define IFilterGraph_EnumFilters(This,ppEnum)   \
+    ((This)->lpVtbl->EnumFilters(This,ppEnum))
+#define IFilterGraph_FindFilterByName(This,pName,ppFilter)  \
+    ((This)->lpVtbl->FindFilterByName(This,pName,ppFilter))
+#define IFilterGraph_ConnectDirect(This,ppinOut,ppinIn,pmt) \
+    ((This)->lpVtbl->ConnectDirect(This,ppinOut,ppinIn,pmt))
+#define IFilterGraph_Reconnect(This,ppin)   \
+    ((This)->lpVtbl->Reconnect(This,ppin))
+#define IFilterGraph_Disconnect(This,ppin)  \
+    ((This)->lpVtbl->Disconnect(This,ppin))
+#define IFilterGraph_SetDefaultSyncSource(This) \
+    ((This)->lpVtbl->SetDefaultSyncSource(This))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IMediaFilter_QueryInterface(This,riid,ppvObject)    \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IMediaFilter_AddRef(This)   \
+    ((This)->lpVtbl->AddRef(This))
+#define IMediaFilter_Release(This)  \
+    ((This)->lpVtbl->Release(This))
+#define IMediaFilter_GetClassID(This,pClassID)  \
+    ((This)->lpVtbl->GetClassID(This,pClassID))
+#define IMediaFilter_Stop(This) \
+    ((This)->lpVtbl->Stop(This))
+#define IMediaFilter_Pause(This)    \
+    ((This)->lpVtbl->Pause(This))
+#define IMediaFilter_Run(This,tStart)   \
+    ((This)->lpVtbl->Run(This,tStart))
+#define IMediaFilter_GetState(This,dwMilliSecsTimeout,State)    \
+    ((This)->lpVtbl->GetState(This,dwMilliSecsTimeout,State))
+#define IMediaFilter_SetSyncSource(This,pClock) \
+    ((This)->lpVtbl->SetSyncSource(This,pClock))
+#define IMediaFilter_GetSyncSource(This,pClock) \
+    ((This)->lpVtbl->GetSyncSource(This,pClock))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IBaseFilter_QueryInterface(This,riid,ppvObject) \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IBaseFilter_AddRef(This)    \
+    ((This)->lpVtbl->AddRef(This))
+#define IBaseFilter_Release(This)   \
+    ((This)->lpVtbl->Release(This))
+#define IBaseFilter_GetClassID(This,pClassID)   \
+    ((This)->lpVtbl->GetClassID(This,pClassID))
+#define IBaseFilter_Stop(This)  \
+    ((This)->lpVtbl->Stop(This))
+#define IBaseFilter_Pause(This) \
+    ((This)->lpVtbl->Pause(This))
+#define IBaseFilter_Run(This,tStart)    \
+    ((This)->lpVtbl->Run(This,tStart))
+#define IBaseFilter_GetState(This,dwMilliSecsTimeout,State) \
+    ((This)->lpVtbl->GetState(This,dwMilliSecsTimeout,State))
+#define IBaseFilter_SetSyncSource(This,pClock)  \
+    ((This)->lpVtbl->SetSyncSource(This,pClock))
+#define IBaseFilter_GetSyncSource(This,pClock)  \
+    ((This)->lpVtbl->GetSyncSource(This,pClock))
+#define IBaseFilter_EnumPins(This,ppEnum)   \
+    ((This)->lpVtbl->EnumPins(This,ppEnum))
+#define IBaseFilter_FindPin(This,Id,ppPin)  \
+    ((This)->lpVtbl->FindPin(This,Id,ppPin))
+#define IBaseFilter_QueryFilterInfo(This,pInfo) \
+    ((This)->lpVtbl->QueryFilterInfo(This,pInfo))
+#define IBaseFilter_JoinFilterGraph(This,pGraph,pName)  \
+    ((This)->lpVtbl->JoinFilterGraph(This,pGraph,pName))
+#define IBaseFilter_QueryVendorInfo(This,pVendorInfo)   \
+    ((This)->lpVtbl->QueryVendorInfo(This,pVendorInfo))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IMediaSample_QueryInterface(This,riid,ppvObject)    \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IMediaSample_AddRef(This)   \
+    ((This)->lpVtbl->AddRef(This))
+#define IMediaSample_Release(This)  \
+    ((This)->lpVtbl->Release(This))
+#define IMediaSample_GetPointer(This,ppBuffer)  \
+    ((This)->lpVtbl->GetPointer(This,ppBuffer))
+#define IMediaSample_GetSize(This)  \
+        ((This)->lpVtbl->GetSize(This))
+#define IMediaSample_GetTime(This,pTimeStart,pTimeEnd)  \
+    ((This)->lpVtbl->GetTime(This,pTimeStart,pTimeEnd))
+#define IMediaSample_SetTime(This,pTimeStart,pTimeEnd)  \
+    ((This)->lpVtbl->SetTime(This,pTimeStart,pTimeEnd))
+#define IMediaSample_IsSyncPoint(This)  \
+    ((This)->lpVtbl->IsSyncPoint(This))
+#define IMediaSample_SetSyncPoint(This,bIsSyncPoint)    \
+    ((This)->lpVtbl->SetSyncPoint(This,bIsSyncPoint))
+#define IMediaSample_IsPreroll(This)    \
+    ((This)->lpVtbl->IsPreroll(This))
+#define IMediaSample_SetPreroll(This,bIsPreroll)    \
+    ((This)->lpVtbl->SetPreroll(This,bIsPreroll))
+#define IMediaSample_GetActualDataLength(This)  \
+    ((This)->lpVtbl->GetActualDataLength(This))
+#define IMediaSample_SetActualDataLength(This,length)   \
+    ((This)->lpVtbl->SetActualDataLength(This,length))
+#define IMediaSample_GetMediaType(This,ppMediaType) \
+    ((This)->lpVtbl->GetMediaType(This,ppMediaType))
+#define IMediaSample_SetMediaType(This,pMediaType)  \
+    ((This)->lpVtbl->SetMediaType(This,pMediaType))
+#define IMediaSample_IsDiscontinuity(This)  \
+    ((This)->lpVtbl->IsDiscontinuity(This))
+#define IMediaSample_SetDiscontinuity(This,bDiscontinuity)  \
+    ((This)->lpVtbl->SetDiscontinuity(This,bDiscontinuity))
+#define IMediaSample_GetMediaTime(This,pTimeStart,pTimeEnd) \
+    ((This)->lpVtbl->GetMediaTime(This,pTimeStart,pTimeEnd))
+#define IMediaSample_SetMediaTime(This,pTimeStart,pTimeEnd) \
+    ((This)->lpVtbl->SetMediaTime(This,pTimeStart,pTimeEnd))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IEnumFilters_QueryInterface(This,riid,ppvObject)    \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IEnumFilters_AddRef(This)   \
+    ((This)->lpVtbl->AddRef(This))
+#define IEnumFilters_Release(This)  \
+    ((This)->lpVtbl->Release(This))
+#define IEnumFilters_Next(This,cFilters,ppFilter,pcFetched) \
+    ((This)->lpVtbl->Next(This,cFilters,ppFilter,pcFetched))
+#define IEnumFilters_Skip(This,cFilters)    \
+    ((This)->lpVtbl->Skip(This,cFilters))
+#define IEnumFilters_Reset(This)    \
+    ((This)->lpVtbl->Reset(This))
+#define IEnumFilters_Clone(This,ppEnum) \
+    ((This)->lpVtbl->Clone(This,ppEnum))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IMemAllocator_QueryInterface(This,riid,ppvObject)   \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IMemAllocator_AddRef(This)  \
+    ((This)->lpVtbl->AddRef(This))
+#define IMemAllocator_Release(This) \
+    ((This)->lpVtbl->Release(This))
+#define IMemAllocator_SetProperties(This,pRequest,pActual)  \
+    ((This)->lpVtbl->SetProperties(This,pRequest,pActual))
+#define IMemAllocator_GetProperties(This,pProps)    \
+    ((This)->lpVtbl->GetProperties(This,pProps))
+#define IMemAllocator_Commit(This)  \
+    ((This)->lpVtbl->Commit(This))
+#define IMemAllocator_Decommit(This)    \
+    ((This)->lpVtbl->Decommit(This))
+#define IMemAllocator_GetBuffer(This,ppBuffer,pStartTime,pEndTime,dwFlags)  \
+    ((This)->lpVtbl->GetBuffer(This,ppBuffer,pStartTime,pEndTime,dwFlags))
+#define IMemAllocator_ReleaseBuffer(This,pBuffer)   \
+    ((This)->lpVtbl->ReleaseBuffer(This,pBuffer))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IMemInputPin_QueryInterface(This,riid,ppvObject)    \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IMemInputPin_AddRef(This)   \
+    ((This)->lpVtbl->AddRef(This))
+#define IMemInputPin_Release(This)  \
+    ((This)->lpVtbl->Release(This))
+#define IMemInputPin_GetAllocator(This,ppAllocator) \
+    ((This)->lpVtbl->GetAllocator(This,ppAllocator))
+#define IMemInputPin_NotifyAllocator(This,pAllocator,bReadOnly) \
+    ((This)->lpVtbl->NotifyAllocator(This,pAllocator,bReadOnly))
+#define IMemInputPin_GetAllocatorRequirements(This,pProps)  \
+    ((This)->lpVtbl->GetAllocatorRequirements(This,pProps))
+#define IMemInputPin_Receive(This,pSample)  \
+    ((This)->lpVtbl->Receive(This,pSample))
+#define IMemInputPin_ReceiveMultiple(This,pSamples,nSamples,nSamplesProcessed)  \
+    ((This)->lpVtbl->ReceiveMultiple(This,pSamples,nSamples,nSamplesProcessed))
+#define IMemInputPin_ReceiveCanBlock(This)  \
+    ((This)->lpVtbl->ReceiveCanBlock(This))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IGraphBuilder_QueryInterface(This,riid,ppvObject)   \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IGraphBuilder_AddRef(This)  \
+    ((This)->lpVtbl->AddRef(This))
+#define IGraphBuilder_Release(This) \
+    ((This)->lpVtbl->Release(This))
+#define IGraphBuilder_AddFilter(This,pFilter,pName) \
+    ((This)->lpVtbl->AddFilter(This,pFilter,pName))
+#define IGraphBuilder_RemoveFilter(This,pFilter)    \
+    ((This)->lpVtbl->RemoveFilter(This,pFilter))
+#define IGraphBuilder_EnumFilters(This,ppEnum)  \
+    ((This)->lpVtbl->EnumFilters(This,ppEnum))
+#define IGraphBuilder_FindFilterByName(This,pName,ppFilter) \
+    ((This)->lpVtbl->FindFilterByName(This,pName,ppFilter))
+#define IGraphBuilder_ConnectDirect(This,ppinOut,ppinIn,pmt)    \
+    ((This)->lpVtbl->ConnectDirect(This,ppinOut,ppinIn,pmt))
+#define IGraphBuilder_Reconnect(This,ppin)  \
+    ((This)->lpVtbl->Reconnect(This,ppin))
+#define IGraphBuilder_Disconnect(This,ppin) \
+    ((This)->lpVtbl->Disconnect(This,ppin))
+#define IGraphBuilder_SetDefaultSyncSource(This)    \
+    ((This)->lpVtbl->SetDefaultSyncSource(This))
+#define IGraphBuilder_Connect(This,ppinOut,ppinIn)  \
+    ((This)->lpVtbl->Connect(This,ppinOut,ppinIn))
+#define IGraphBuilder_Render(This,ppinOut)  \
+    ((This)->lpVtbl->Render(This,ppinOut))
+#define IGraphBuilder_RenderFile(This,lpcwstrFile,lpcwstrPlayList)  \
+    ((This)->lpVtbl->RenderFile(This,lpcwstrFile,lpcwstrPlayList))
+#define IGraphBuilder_AddSourceFilter(This,lpcwstrFileName,lpcwstrFilterName,ppFilter)  \
+    ((This)->lpVtbl->AddSourceFilter(This,lpcwstrFileName,lpcwstrFilterName,ppFilter))
+#define IGraphBuilder_SetLogFile(This,hFile)    \
+    ((This)->lpVtbl->SetLogFile(This,hFile))
+#define IGraphBuilder_Abort(This)   \
+    ((This)->lpVtbl->Abort(This))
+#define IGraphBuilder_ShouldOperationContinue(This) \
+    ((This)->lpVtbl->ShouldOperationContinue(This))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IEnumMediaTypes_QueryInterface(This,riid,ppvObject) \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IEnumMediaTypes_AddRef(This)    \
+    ((This)->lpVtbl->AddRef(This))
+#define IEnumMediaTypes_Release(This)   \
+    ((This)->lpVtbl->Release(This))
+#define IEnumMediaTypes_Next(This,cMediaTypes,ppMediaTypes,pcFetched)   \
+    ((This)->lpVtbl->Next(This,cMediaTypes,ppMediaTypes,pcFetched))
+#define IEnumMediaTypes_Skip(This,cMediaTypes)  \
+    ((This)->lpVtbl->Skip(This,cMediaTypes))
+#define IEnumMediaTypes_Reset(This) \
+    ((This)->lpVtbl->Reset(This))
+#define IEnumMediaTypes_Clone(This,ppEnum)  \
+    ((This)->lpVtbl->Clone(This,ppEnum))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IMediaControl_QueryInterface(This,riid,ppvObject)   \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IMediaControl_AddRef(This)  \
+    ((This)->lpVtbl->AddRef(This))
+#define IMediaControl_Release(This) \
+    ((This)->lpVtbl->Release(This))
+#define IMediaControl_GetTypeInfoCount(This,pctinfo)    \
+    ((This)->lpVtbl->GetTypeInfoCount(This,pctinfo))
+#define IMediaControl_GetTypeInfo(This,iTInfo,lcid,ppTInfo) \
+    ((This)->lpVtbl->GetTypeInfo(This,iTInfo,lcid,ppTInfo))
+#define IMediaControl_GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId)   \
+    ((This)->lpVtbl->GetIDsOfNames(This,riid,rgszNames,cNames,lcid,rgDispId))
+#define IMediaControl_Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr) \
+    ((This)->lpVtbl->Invoke(This,dispIdMember,riid,lcid,wFlags,pDispParams,pVarResult,pExcepInfo,puArgErr))
+#define IMediaControl_Run(This) \
+    ((This)->lpVtbl->Run(This))
+#define IMediaControl_Pause(This)   \
+    ((This)->lpVtbl->Pause(This))
+#define IMediaControl_Stop(This)    \
+    ((This)->lpVtbl->Stop(This))
+#define IMediaControl_GetState(This,msTimeout,pfs)  \
+    ((This)->lpVtbl->GetState(This,msTimeout,pfs))
+#define IMediaControl_RenderFile(This,strFilename)  \
+    ((This)->lpVtbl->RenderFile(This,strFilename))
+#define IMediaControl_AddSourceFilter(This,strFilename,ppUnk)   \
+    ((This)->lpVtbl->AddSourceFilter(This,strFilename,ppUnk))
+#define IMediaControl_get_FilterCollection(This,ppUnk)  \
+    ((This)->lpVtbl->get_FilterCollection(This,ppUnk))
+#define IMediaControl_get_RegFilterCollection(This,ppUnk)   \
+    ((This)->lpVtbl->get_RegFilterCollection(This,ppUnk))
+#define IMediaControl_StopWhenReady(This)   \
+    ((This)->lpVtbl->StopWhenReady(This))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IAMVideoProcAmp_QueryInterface(This,riid,ppvObject) \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IAMVideoProcAmp_AddRef(This)    \
+    ((This)->lpVtbl->AddRef(This))
+#define IAMVideoProcAmp_Release(This)   \
+    ((This)->lpVtbl->Release(This))
+#define IAMVideoProcAmp_GetRange(This,Property,pMin,pMax,pSteppingDelta,pDefault,pCapsFlags)    \
+    ((This)->lpVtbl->GetRange(This,Property,pMin,pMax,pSteppingDelta,pDefault,pCapsFlags))
+#define IAMVideoProcAmp_Set(This,Property,lValue,Flags) \
+    ((This)->lpVtbl->Set(This,Property,lValue,Flags))
+#define IAMVideoProcAmp_Get(This,Property,lValue,Flags) \
+    ((This)->lpVtbl->Get(This,Property,lValue,Flags))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IFileSinkFilter_QueryInterface(This,riid,ppvObject) \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IFileSinkFilter_AddRef(This)    \
+    ((This)->lpVtbl->AddRef(This))
+#define IFileSinkFilter_Release(This)   \
+    ((This)->lpVtbl->Release(This))
+#define IFileSinkFilter_SetFileName(This,pszFileName,pmt)   \
+    ((This)->lpVtbl->SetFileName(This,pszFileName,pmt))
+#define IFileSinkFilter_GetCurFile(This,ppszFileName,pmt)   \
+    ((This)->lpVtbl->GetCurFile(This,ppszFileName,pmt))
+#endif /* COBJMACROS */
+
+#ifdef COBJMACROS
+#define IAMCopyCaptureFileProgress_QueryInterface(This,riid,ppvObject)  \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define IAMCopyCaptureFileProgress_AddRef(This) \
+    ((This)->lpVtbl->AddRef(This))
+#define IAMCopyCaptureFileProgress_Release(This)    \
+    ((This)->lpVtbl->Release(This))
+#define IAMCopyCaptureFileProgress_Progress(This,iProgress) \
+    ((This)->lpVtbl->Progress(This,iProgress))
+#endif /* COBJMACROS */
+
+
+#ifdef COBJMACROS
+#define ICaptureGraphBuilder2_QueryInterface(This,riid,ppvObject)   \
+    ((This)->lpVtbl->QueryInterface(This,riid,ppvObject))
+#define ICaptureGraphBuilder2_AddRef(This)  \
+    ((This)->lpVtbl->AddRef(This))
+#define ICaptureGraphBuilder2_Release(This) \
+    ((This)->lpVtbl->Release(This))
+#define ICaptureGraphBuilder2_SetFiltergraph(This,pfg)  \
+    ((This)->lpVtbl->SetFiltergraph(This,pfg))
+#define ICaptureGraphBuilder2_GetFiltergraph(This,ppfg) \
+    ((This)->lpVtbl->GetFiltergraph(This,ppfg))
+#define ICaptureGraphBuilder2_SetOutputFileName(This,pType,lpstrFile,ppf,ppSink)    \
+    ((This)->lpVtbl->SetOutputFileName(This,pType,lpstrFile,ppf,ppSink))
+#define ICaptureGraphBuilder2_FindInterface(This,pCategory,pType,pf,riid,ppint) \
+    ((This)->lpVtbl->FindInterface(This,pCategory,pType,pf,riid,ppint))
+#define ICaptureGraphBuilder2_RenderStream(This,pCategory,pType,pSource,pfCompressor,pfRenderer)    \
+    ((This)->lpVtbl->RenderStream(This,pCategory,pType,pSource,pfCompressor,pfRenderer))
+#define ICaptureGraphBuilder2_ControlStream(This,pCategory,pType,pFilter,pstart,pstop,wStartCookie,wStopCookie) \
+    ((This)->lpVtbl->ControlStream(This,pCategory,pType,pFilter,pstart,pstop,wStartCookie,wStopCookie))
+#define ICaptureGraphBuilder2_AllocCapFile(This,lpstr,dwlSize)  \
+    ((This)->lpVtbl->AllocCapFile(This,lpstr,dwlSize))
+#define ICaptureGraphBuilder2_CopyCaptureFile(This,lpwstrOld,lpwstrNew,fAllowEscAbort,pCallback)    \
+    ((This)->lpVtbl->CopyCaptureFile(This,lpwstrOld,lpwstrNew,fAllowEscAbort,pCallback))
+#define ICaptureGraphBuilder2_FindPin(This,pSource,pindir,pCategory,pType,fUnconnected,num,ppPin)   \
+    ((This)->lpVtbl->FindPin(This,pSource,pindir,pCategory,pType,fUnconnected,num,ppPin))
+#endif /* COBJMACROS */
+
+#endif /* _MARU_CAMERA_INTERFACE_H_ */
diff --git a/tizen/src/hw/pci/maru_camera_win32_pci.c b/tizen/src/hw/pci/maru_camera_win32_pci.c
new file mode 100644 (file)
index 0000000..60ae648
--- /dev/null
@@ -0,0 +1,2798 @@
+/*
+ * Implementation of MARU Virtual Camera device by PCI bus on Windows.
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * JinHyung Jo <jinhyung.jo@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 "qemu-common.h"
+#include "maru_camera_common.h"
+#include "debug_ch.h"
+
+#define CINTERFACE
+#define COBJMACROS
+#include "ocidl.h"
+#include "errors.h"      /* for VFW_E_XXXX */
+#include "mmsystem.h"    /* for MAKEFOURCC macro */
+#include "maru_camera_win32_interface.h"
+
+MULTI_DEBUG_CHANNEL(tizen, maru-camera);
+
+/*
+ * COM Interface implementations
+ *
+ */
+
+#define SAFE_RELEASE(x) \
+    do { \
+        if (x) { \
+            (x)->lpVtbl->Release(x); \
+            x = NULL; \
+        } \
+    } while (0)
+
+typedef HRESULT (STDAPICALLTYPE *CallbackFn)(ULONG dwSize, BYTE *pBuffer);
+
+/*
+ * HWCGrabCallback
+ */
+
+typedef struct HWCGrabCallback {
+    IGrabCallback IGrabCallback_iface;
+    long m_cRef;
+    CallbackFn m_pCallback;
+    STDMETHODIMP (*SetCallback)(IGrabCallback *iface, CallbackFn pCallbackFn);
+} HWCGrabCallback;
+
+static inline HWCGrabCallback *impl_from_IGrabCallback(IGrabCallback *iface)
+{
+    return CONTAINING_RECORD(iface, HWCGrabCallback, IGrabCallback_iface);
+}
+
+static STDMETHODIMP HWCGrabCallback_QueryInterface(IGrabCallback *iface,
+                                                   REFIID riid, void **ppv)
+{
+    if (IsEqualIID(riid, &IID_IUnknown)) {
+        *ppv = (IUnknown *)iface;
+    } else if (IsEqualIID(riid, &IID_IGrabCallback)) {
+        *ppv = (IGrabCallback *)iface;
+    } else {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IGrabCallback_AddRef(iface);
+    return S_OK;
+}
+
+static STDMETHODIMP_(ULONG) HWCGrabCallback_AddRef(IGrabCallback *iface)
+{
+    HWCGrabCallback *This = impl_from_IGrabCallback(iface);
+
+    return InterlockedIncrement(&This->m_cRef);
+}
+
+static STDMETHODIMP_(ULONG) HWCGrabCallback_Release(IGrabCallback *iface)
+{
+    HWCGrabCallback *This = impl_from_IGrabCallback(iface);
+
+    if (InterlockedDecrement(&This->m_cRef) == 0) {
+        This->m_pCallback = NULL;
+        g_free((void *)This);
+        This = NULL;
+        return 0;
+    }
+
+    return This->m_cRef;
+}
+
+static STDMETHODIMP HWCGrabCallback_Grab(IGrabCallback *iface,
+                                         ULONG dwSize, BYTE *pBuffer)
+{
+    HWCGrabCallback *This = impl_from_IGrabCallback(iface);
+
+    if (This->m_pCallback) {
+        HRESULT hr = This->m_pCallback(dwSize, pBuffer);
+        if (FAILED(hr)) {
+            return E_FAIL;
+        } else {
+            return S_OK;
+        }
+    }
+
+    return E_FAIL;
+}
+
+static STDMETHODIMP HWCGrabCallback_SetCallback(IGrabCallback *iface,
+                                                CallbackFn pCallbackFn)
+{
+    HWCGrabCallback *This = impl_from_IGrabCallback(iface);
+
+    This->m_pCallback = pCallbackFn;
+    return S_OK;
+}
+
+static IGrabCallbackVtbl HWCGrabCallback_Vtbl = {
+        HWCGrabCallback_QueryInterface,
+        HWCGrabCallback_AddRef,
+        HWCGrabCallback_Release,
+        HWCGrabCallback_Grab
+};
+
+static STDMETHODIMP HWCGrabCallback_Construct(IGrabCallback **ppv)
+{
+    HWCGrabCallback *This =
+            (HWCGrabCallback *)g_malloc0(sizeof(HWCGrabCallback));
+
+    if (!This) {
+        ERR("failed to HWCGrabCallback_Construct, E_OUTOFMEMORY\n");
+        return E_OUTOFMEMORY;
+    }
+
+    This->IGrabCallback_iface.lpVtbl = &HWCGrabCallback_Vtbl;
+    This->m_cRef = 1;
+    This->m_pCallback = NULL;
+    This->SetCallback = HWCGrabCallback_SetCallback;
+    *ppv = &This->IGrabCallback_iface;
+    return S_OK;
+}
+
+/*
+ * HWCPin
+ */
+
+typedef struct HWCInPin {
+    IPin IPin_iface;
+    IMemInputPin IMemInputPin_iface;
+    IBaseFilter *m_pCFilter;
+    IPin *m_pConnectedPin;
+    IGrabCallback *m_pCallback;
+    IMemAllocator *m_pAllocator;
+    BOOL m_bReadOnly;
+    long m_cRef;
+    STDMETHODIMP (*SetGrabCallbackIF)(IPin *iface, IGrabCallback *pCaptureCB);
+} HWCInPin;
+
+static inline HWCInPin *impl_from_IPin(IPin *iface)
+{
+    return CONTAINING_RECORD(iface, HWCInPin, IPin_iface);
+}
+
+static inline HWCInPin *impl_from_IMemInputPin(IMemInputPin *iface)
+{
+    return CONTAINING_RECORD(iface, HWCInPin, IMemInputPin_iface);
+}
+
+static STDMETHODIMP HWCPin_QueryInterface(IPin *iface, REFIID riid, void **ppv)
+{
+    HWCInPin *This = impl_from_IPin(iface);
+
+    if (IsEqualIID(riid, &IID_IUnknown)) {
+        *ppv = (IUnknown *)(&This->IPin_iface);
+        IPin_AddRef((IPin *)*ppv);
+    } else if (IsEqualIID(riid, &IID_IPin)) {
+        *ppv = (IPin *)(&This->IPin_iface);
+        IPin_AddRef((IPin *)*ppv);
+    } else if (IsEqualIID(riid, &IID_IMemInputPin)) {
+        *ppv = (IMemInputPin *)(&This->IMemInputPin_iface);
+        IPin_AddRef((IMemInputPin *)*ppv);
+    } else {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    return S_OK;
+}
+
+static STDMETHODIMP_(ULONG) HWCPin_AddRef(IPin *iface)
+{
+    HWCInPin *This = impl_from_IPin(iface);
+
+    return InterlockedIncrement(&This->m_cRef);
+}
+
+static STDMETHODIMP_(ULONG) HWCPin_Release(IPin *iface)
+{
+    HWCInPin *This = impl_from_IPin(iface);
+
+    if (InterlockedDecrement(&This->m_cRef) == 0) {
+        if (This->m_pCallback) {
+            SAFE_RELEASE(This->m_pCallback);
+        }
+        if (This->m_pConnectedPin) {
+            SAFE_RELEASE(This->m_pConnectedPin);
+        }
+        if (This->m_pAllocator) {
+            IMemAllocator_Decommit(This->m_pAllocator);
+            SAFE_RELEASE(This->m_pAllocator);
+        }
+        g_free((void *)This);
+        This = NULL;
+        return 0;
+    }
+    return This->m_cRef;
+}
+
+static STDMETHODIMP HWCPin_Connect(IPin *iface,
+                                   IPin *pReceivePin,
+                                   const AM_MEDIA_TYPE *pmt)
+{
+    HWCInPin *This = impl_from_IPin(iface);
+
+    if (!pReceivePin) {
+        return E_POINTER;
+    }
+
+    if (This->m_pConnectedPin) {
+        return VFW_E_ALREADY_CONNECTED;
+    }
+
+    if (!pmt) {
+        return S_OK;
+    }
+    return S_FALSE;
+}
+
+static STDMETHODIMP HWCPin_ReceiveConnection(IPin *iface, IPin *pConnector,
+                                             const AM_MEDIA_TYPE *pmt)
+{
+    PIN_DIRECTION pd;
+    FILTER_STATE fs;
+    HWCInPin *This = impl_from_IPin(iface);
+
+    if (pConnector == NULL || pmt == NULL) {
+        return E_POINTER;
+    }
+
+    if (This->m_pConnectedPin) {
+        return VFW_E_ALREADY_CONNECTED;
+    }
+    IBaseFilter_GetState(This->m_pCFilter, 0, &fs);
+    if (fs != State_Stopped) {
+        return VFW_E_NOT_STOPPED;
+    }
+    IPin_QueryDirection(pConnector, &pd);
+    if (pd == PINDIR_INPUT) {
+        return VFW_E_INVALID_DIRECTION;
+    }
+
+    This->m_pConnectedPin = pConnector;
+    IPin_AddRef(This->m_pConnectedPin);
+    return S_OK;
+}
+
+static STDMETHODIMP HWCPin_Disconnect(IPin *iface)
+{
+    HWCInPin *This = impl_from_IPin(iface);
+
+    HRESULT hr;
+    FILTER_STATE fs;
+    IBaseFilter_GetState(This->m_pCFilter, 0, &fs);
+    if (fs != State_Stopped) {
+        return VFW_E_NOT_STOPPED;
+    }
+    if (This->m_pConnectedPin == NULL) {
+        hr = S_FALSE;
+    } else {
+        if (This->m_pAllocator) {
+            hr = IMemAllocator_Decommit(This->m_pAllocator);
+            if (FAILED(hr)) {
+                return hr;
+            }
+            SAFE_RELEASE(This->m_pAllocator);
+        }
+        SAFE_RELEASE(This->m_pConnectedPin);
+        hr = S_OK;
+    }
+    return hr;
+}
+
+static STDMETHODIMP HWCPin_ConnectedTo(IPin *iface, IPin **ppPin)
+{
+    HWCInPin *This = impl_from_IPin(iface);
+
+    if (ppPin == NULL) {
+        return E_POINTER;
+    }
+
+    if (This->m_pConnectedPin == NULL) {
+        *ppPin = NULL;
+        return VFW_E_NOT_CONNECTED;
+    } else {
+        *ppPin = This->m_pConnectedPin;
+        IPin_AddRef(This->m_pConnectedPin);
+    }
+    return S_OK;
+}
+
+static STDMETHODIMP HWCPin_ConnectionMediaType(IPin *iface, AM_MEDIA_TYPE *pmt)
+{
+    if (pmt == NULL) {
+        return E_POINTER;
+    }
+    return VFW_E_NOT_CONNECTED;
+}
+
+static STDMETHODIMP HWCPin_QueryPinInfo(IPin *iface, PIN_INFO *pInfo)
+{
+    HWCInPin *This = impl_from_IPin(iface);
+
+    if (pInfo == NULL) {
+        return E_POINTER;
+    }
+
+    pInfo->pFilter = This->m_pCFilter;
+    if (This->m_pCFilter) {
+        IBaseFilter_AddRef(This->m_pCFilter);
+    }
+    memcpy((void *)pInfo->achName, (void *)HWCPinName, sizeof(HWCPinName));
+    pInfo->dir = PINDIR_INPUT;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCPin_QueryDirection(IPin *iface, PIN_DIRECTION *pPinDir)
+{
+    if (pPinDir == NULL) {
+        return E_POINTER;
+    }
+    *pPinDir = PINDIR_INPUT;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCPin_QueryId(IPin *iface, LPWSTR *Id)
+{
+    PVOID pId;
+    if (Id == NULL) {
+        return E_POINTER;
+    }
+    pId = CoTaskMemAlloc(sizeof(HWCPinName));
+    memcpy((void *)pId, (void *)HWCPinName, sizeof(HWCPinName));
+    *Id = (LPWSTR)pId;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCPin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *pmt)
+{
+    if (pmt == NULL) {
+        return E_POINTER;
+    }
+    return S_OK;
+}
+
+static STDMETHODIMP HWCPin_EnumMediaTypes(IPin *iface,
+                                          IEnumMediaTypes **ppEnum)
+{
+    if (ppEnum == NULL) {
+            return E_POINTER;
+    }
+    return E_NOTIMPL;
+}
+
+static STDMETHODIMP HWCPin_QueryInternalConnections(IPin *iface,
+                                                    IPin **ppPin,
+                                                    ULONG *nPin)
+{
+    return E_NOTIMPL;
+}
+
+static STDMETHODIMP HWCPin_EndOfStream(IPin *iface)
+{
+    return S_OK;
+}
+
+static STDMETHODIMP HWCPin_BeginFlush(IPin *iface)
+{
+    return S_OK;
+}
+
+static STDMETHODIMP HWCPin_EndFlush(IPin *iface)
+{
+    return S_OK;
+}
+
+static STDMETHODIMP HWCPin_NewSegment(IPin *iface, REFERENCE_TIME tStart,
+                                      REFERENCE_TIME tStop, double dRate)
+{
+    return S_OK;
+}
+
+static STDMETHODIMP HWCMemInputPin_QueryInterface(IMemInputPin *iface,
+                                                  REFIID riid, void **ppv)
+{
+    HWCInPin *This = impl_from_IMemInputPin(iface);
+
+    if (IsEqualIID(riid, &IID_IUnknown)) {
+        *ppv = (IUnknown *)(&This->IMemInputPin_iface);
+        IPin_AddRef((IPin *)*ppv);
+    } else if (IsEqualIID(riid, &IID_IPin)) {
+        *ppv = (IPin *)(&This->IPin_iface);
+        IPin_AddRef((IPin *)*ppv);
+    } else if (IsEqualIID(riid, &IID_IMemInputPin)) {
+        *ppv = (IMemInputPin *)(&This->IMemInputPin_iface);
+        IPin_AddRef((IMemInputPin *)*ppv);
+    } else {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    return S_OK;
+}
+
+static STDMETHODIMP_(ULONG) HWCMemInputPin_AddRef(IMemInputPin *iface)
+{
+    HWCInPin *This = impl_from_IMemInputPin(iface);
+
+    return InterlockedIncrement(&This->m_cRef);
+}
+
+static STDMETHODIMP_(ULONG) HWCMemInputPin_Release(IMemInputPin *iface)
+{
+    HWCInPin *This = impl_from_IMemInputPin(iface);
+
+    if (InterlockedDecrement(&This->m_cRef) == 0) {
+        if (This->m_pCallback) {
+            SAFE_RELEASE(This->m_pCallback);
+        }
+        if (This->m_pConnectedPin) {
+            SAFE_RELEASE(This->m_pConnectedPin);
+        }
+        if (This->m_pAllocator) {
+            IMemAllocator_Decommit(This->m_pAllocator);
+            SAFE_RELEASE(This->m_pAllocator);
+        }
+        g_free((void *)This);
+        This = NULL;
+        return 0;
+    }
+    return This->m_cRef;
+}
+
+static STDMETHODIMP HWCMemInputPin_GetAllocator(IMemInputPin *iface,
+                                                IMemAllocator **ppAllocator)
+{
+    HWCInPin *This = impl_from_IMemInputPin(iface);
+
+    if (ppAllocator == NULL) {
+        return E_POINTER;
+    }
+
+    if (This->m_pAllocator == NULL) {
+        HRESULT hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL,
+                                        CLSCTX_INPROC_SERVER,
+                                        &IID_IMemAllocator,
+                                        (void **)&(This->m_pAllocator));
+        if (FAILED(hr)) {
+            ERR("Failed to CoCreateInstance for retrieving MemoryAllocator\n");
+            return hr;
+        }
+    }
+    ASSERT(This->m_pAllocator != NULL);
+    *ppAllocator = This->m_pAllocator;
+    IMemAllocator_AddRef(This->m_pAllocator);
+
+    return S_OK;
+}
+
+static STDMETHODIMP HWCMemInputPin_NotifyAllocator(IMemInputPin *iface,
+                                                   IMemAllocator *pAllocator,
+                                                   BOOL bReadOnly)
+{
+    HWCInPin *This = impl_from_IMemInputPin(iface);
+
+    if (pAllocator == NULL) {
+        return E_POINTER;
+    }
+
+    IMemAllocator *pOldAllocator = This->m_pAllocator;
+    IMemAllocator_AddRef(pAllocator);
+    This->m_pAllocator = pAllocator;
+
+    if (pOldAllocator != NULL) {
+        SAFE_RELEASE(pOldAllocator);
+    }
+
+    This->m_bReadOnly = bReadOnly;
+
+    return S_OK;
+}
+
+static STDMETHODIMP HWCMemInputPin_GetAllocatorRequirements(
+                                   IMemInputPin *iface,
+                                   ALLOCATOR_PROPERTIES *pProps)
+{
+    return E_NOTIMPL;
+}
+
+static STDMETHODIMP HWCMemInputPin_Receive(IMemInputPin *iface,
+                                           IMediaSample *pSample)
+{
+    HWCInPin *This = impl_from_IMemInputPin(iface);
+
+    if (pSample == NULL) {
+        ERR("pSample is NULL\n");
+        return E_POINTER;
+    }
+    if (This->m_pCallback != NULL) {
+        HRESULT hr;
+        BYTE *pBuffer = NULL;
+        DWORD dwSize = 0;
+        dwSize = IMediaSample_GetSize(pSample);
+        hr = IMediaSample_GetPointer(pSample, &pBuffer);
+        if (FAILED(hr)) {
+            ERR("Receive function : "
+                "failed to IMediaSample_GetPointer, 0x%ld\n", hr);
+            return hr;
+        }
+        hr = IGrabCallback_Grab(This->m_pCallback, dwSize, pBuffer);
+        if (FAILED(hr)) {
+            ERR("Receive function : failed to IGrabCallback_Grab, 0x%ld\n",
+                hr);
+            return hr;
+        }
+    }
+    return S_OK;
+}
+
+static STDMETHODIMP HWCMemInputPin_ReceiveMultiple(IMemInputPin *iface,
+                                                   IMediaSample **pSamples,
+                                                   long nSamples,
+                                                   long *nSamplesProcessed)
+{
+    HRESULT hr = S_OK;
+
+    if (pSamples == NULL) {
+        return E_POINTER;
+    }
+
+    *nSamplesProcessed = 0;
+
+    while (nSamples-- > 0) {
+        hr = IMemInputPin_Receive(iface, pSamples[*nSamplesProcessed]);
+        if (hr != S_OK) {
+            break;
+        }
+        (*nSamplesProcessed)++;
+    }
+    return hr;
+}
+
+static STDMETHODIMP HWCMemInputPin_ReceiveCanBlock(IMemInputPin *iface)
+{
+    return S_FALSE;
+}
+
+static STDMETHODIMP HWCPin_SetCallback(IPin *iface, IGrabCallback *pCaptureCB)
+{
+    HWCInPin *This = impl_from_IPin(iface);
+
+    if (pCaptureCB == NULL) {
+        SAFE_RELEASE(This->m_pCallback);
+    } else {
+        This->m_pCallback = pCaptureCB;
+        IGrabCallback_AddRef(This->m_pCallback);
+    }
+
+    return S_OK;
+}
+
+
+static IPinVtbl HWCPin_Vtbl = {
+    HWCPin_QueryInterface,
+    HWCPin_AddRef,
+    HWCPin_Release,
+    HWCPin_Connect,
+    HWCPin_ReceiveConnection,
+    HWCPin_Disconnect,
+    HWCPin_ConnectedTo,
+    HWCPin_ConnectionMediaType,
+    HWCPin_QueryPinInfo,
+    HWCPin_QueryDirection,
+    HWCPin_QueryId,
+    HWCPin_QueryAccept,
+    HWCPin_EnumMediaTypes,
+    HWCPin_QueryInternalConnections,
+    HWCPin_EndOfStream,
+    HWCPin_BeginFlush,
+    HWCPin_EndFlush,
+    HWCPin_NewSegment
+};
+
+static IMemInputPinVtbl HWCMemInputPin_Vtbl = {
+    HWCMemInputPin_QueryInterface,
+    HWCMemInputPin_AddRef,
+    HWCMemInputPin_Release,
+    HWCMemInputPin_GetAllocator,
+    HWCMemInputPin_NotifyAllocator,
+    HWCMemInputPin_GetAllocatorRequirements,
+    HWCMemInputPin_Receive,
+    HWCMemInputPin_ReceiveMultiple,
+    HWCMemInputPin_ReceiveCanBlock
+};
+
+static STDMETHODIMP HWCInPin_Construct(IBaseFilter *pFilter, IPin **ppv)
+{
+    HWCInPin *This = (HWCInPin *)g_malloc0(sizeof(HWCInPin));
+
+    if (!This) {
+        ERR("failed to HWCInPin_Construct, E_OUTOFMEMORY\n");
+        return E_OUTOFMEMORY;
+    }
+
+    This->IPin_iface.lpVtbl = &HWCPin_Vtbl;
+    This->IMemInputPin_iface.lpVtbl = &HWCMemInputPin_Vtbl;
+    This->m_bReadOnly = FALSE;
+    This->m_pCFilter = pFilter;
+    This->m_pConnectedPin = NULL;
+    This->m_pCallback = NULL;
+    This->m_pAllocator = NULL;
+    This->m_cRef = 1;
+    This->SetGrabCallbackIF = HWCPin_SetCallback;
+    *ppv = &This->IPin_iface;
+
+    return S_OK;
+}
+
+/*
+ * HWCEnumPins
+ */
+
+typedef struct HWCEnumPins {
+    IEnumPins IEnumPins_iface;
+    IBaseFilter *m_pFilter;
+    int m_nPos;
+    long m_cRef;
+} HWCEnumPins;
+
+static inline HWCEnumPins *impl_from_IEnumPins(IEnumPins *iface)
+{
+    return CONTAINING_RECORD(iface, HWCEnumPins, IEnumPins_iface);
+}
+
+static STDMETHODIMP HWCEnumPins_QueryInterface(IEnumPins *iface,
+                                               REFIID riid, void **ppv)
+{
+    if (ppv == NULL) {
+        return E_POINTER;
+    }
+
+    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IEnumPins)) {
+        *ppv = iface;
+    } else {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IEnumPins_AddRef(iface);
+    return S_OK;
+}
+
+static STDMETHODIMP_(ULONG) HWCEnumPins_AddRef(IEnumPins *iface)
+{
+    HWCEnumPins *This = impl_from_IEnumPins(iface);
+
+    return InterlockedIncrement(&This->m_cRef);
+}
+
+static STDMETHODIMP_(ULONG) HWCEnumPins_Release(IEnumPins *iface)
+{
+    HWCEnumPins *This = impl_from_IEnumPins(iface);
+
+    if (InterlockedDecrement(&This->m_cRef) == 0) {
+        if (This->m_pFilter) {
+            SAFE_RELEASE(This->m_pFilter);
+        }
+        This->m_nPos = 0;
+        g_free((void *)This);
+        This = NULL;
+        return 0;
+    }
+    return This->m_cRef;
+}
+
+static STDMETHODIMP HWCEnumPins_Next(IEnumPins *iface, ULONG cPins,
+                                     IPin **ppPins, ULONG *pcFetched)
+{
+    ULONG fetched;
+    HWCEnumPins *This = impl_from_IEnumPins(iface);
+
+    if (ppPins == NULL) {
+        return E_POINTER;
+    }
+
+    if (This->m_nPos < 1 && cPins > 0) {
+        IPin *pPin;
+        IBaseFilter_FindPin(This->m_pFilter, HWCPinName, &pPin);
+        *ppPins = pPin;
+        fetched = 1;
+        This->m_nPos++;
+    } else {
+        fetched = 0;
+    }
+
+    if (pcFetched != NULL) {
+        *pcFetched = fetched;
+    }
+
+    return (fetched == cPins) ? S_OK : S_FALSE;
+}
+
+static STDMETHODIMP HWCEnumPins_Skip(IEnumPins *iface, ULONG cPins)
+{
+    HWCEnumPins *This = impl_from_IEnumPins(iface);
+    This->m_nPos += cPins;
+    return (This->m_nPos >= 1) ? S_FALSE : S_OK;
+}
+
+static STDMETHODIMP HWCEnumPins_Reset(IEnumPins *iface)
+{
+    HWCEnumPins *This = impl_from_IEnumPins(iface);
+    This->m_nPos = 0;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCEnumPins_Construct(IBaseFilter *pFilter,
+                                          int nPos, IEnumPins **ppv);
+
+static STDMETHODIMP HWCEnumPins_Clone(IEnumPins *iface, IEnumPins **ppEnum)
+{
+    HWCEnumPins *This = impl_from_IEnumPins(iface);
+
+    if (ppEnum == NULL) {
+        return E_POINTER;
+    }
+
+    HWCEnumPins_Construct(This->m_pFilter, This->m_nPos, ppEnum);
+    if (*ppEnum == NULL) {
+        ERR("failed to HWCEnumPins_Construct in clone, E_OUTOFMEMORY\n");
+        return E_OUTOFMEMORY;
+    }
+
+    return S_OK;
+}
+
+static IEnumPinsVtbl HWCEnumPins_Vtbl = {
+    HWCEnumPins_QueryInterface,
+    HWCEnumPins_AddRef,
+    HWCEnumPins_Release,
+    HWCEnumPins_Next,
+    HWCEnumPins_Skip,
+    HWCEnumPins_Reset,
+    HWCEnumPins_Clone
+};
+
+
+static STDMETHODIMP HWCEnumPins_Construct(IBaseFilter *pFilter,
+                                          int nPos, IEnumPins **ppv)
+{
+    HWCEnumPins *This = (HWCEnumPins *)g_malloc0(sizeof(HWCEnumPins));
+
+    if (!This) {
+        ERR("failed to HWCEnumPins_Construct, E_OUTOFMEMORY\n");
+        return E_OUTOFMEMORY;
+    }
+
+    This->IEnumPins_iface.lpVtbl = &HWCEnumPins_Vtbl;
+    This->m_pFilter = pFilter;
+    if (This->m_pFilter) {
+        IBaseFilter_AddRef(This->m_pFilter);
+    }
+    This->m_cRef = 1;
+    This->m_nPos = nPos;
+    *ppv = &This->IEnumPins_iface;
+
+    return S_OK;
+}
+
+/*
+ * HWCFilter
+ */
+
+typedef struct HWCFilter {
+    IBaseFilter IBaseFilter_iface;
+    IPin *m_pPin;
+    IFilterGraph *m_pFilterGraph;
+    FILTER_STATE m_state;
+    long m_cRef;
+} HWCFilter;
+
+static inline HWCFilter *impl_from_IBaseFilter(IBaseFilter *iface)
+{
+    return CONTAINING_RECORD(iface, HWCFilter, IBaseFilter_iface);
+}
+
+static STDMETHODIMP HWCFilter_QueryInterface(IBaseFilter *iface,
+                                             REFIID riid, void **ppv)
+{
+    if (IsEqualIID(riid, &IID_IUnknown)) {
+        *ppv = (IUnknown *)iface;
+    } else if (IsEqualIID(riid, &IID_IPersist)) {
+        *ppv = (IPersist *)iface;
+    } else if (IsEqualIID(riid, &IID_IMediaFilter)) {
+        *ppv = (IMediaFilter *)iface;
+    } else if (IsEqualIID(riid, &IID_IBaseFilter)) {
+        *ppv = (IBaseFilter *)iface;
+    } else {
+        *ppv = NULL;
+        return E_NOINTERFACE;
+    }
+
+    IBaseFilter_AddRef(iface);
+    return S_OK;
+}
+
+static STDMETHODIMP_(ULONG) HWCFilter_AddRef(IBaseFilter *iface)
+{
+    HWCFilter *This = impl_from_IBaseFilter(iface);
+
+    return InterlockedIncrement(&This->m_cRef);
+}
+
+static STDMETHODIMP_(ULONG) HWCFilter_Release(IBaseFilter *iface)
+{
+    HWCFilter *This = impl_from_IBaseFilter(iface);
+
+    if (InterlockedDecrement(&This->m_cRef) == 0) {
+        if (This->m_pPin) {
+            SAFE_RELEASE(This->m_pPin);
+        }
+        g_free((void *)This);
+        This = NULL;
+        return 0;
+    }
+    return This->m_cRef;
+}
+
+static STDMETHODIMP HWCFilter_GetClassID(IBaseFilter *iface, CLSID *pClsID)
+{
+    if (pClsID == NULL) {
+        return E_POINTER;
+    }
+    return E_NOTIMPL;
+}
+
+static STDMETHODIMP HWCFilter_GetState(IBaseFilter *iface, DWORD dwMSecs,
+                                       FILTER_STATE *State)
+{
+    HWCFilter *This = impl_from_IBaseFilter(iface);
+    *State = This->m_state;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCFilter_SetSyncSource(IBaseFilter *iface,
+                                            IReferenceClock *pClock)
+{
+    return S_OK;
+}
+
+static STDMETHODIMP HWCFilter_GetSyncSource(IBaseFilter *iface,
+                                            IReferenceClock **pClock)
+{
+    *pClock = NULL;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCFilter_Stop(IBaseFilter *iface)
+{
+    HWCFilter *This = impl_from_IBaseFilter(iface);
+
+    IPin_EndFlush(This->m_pPin);
+    This->m_state = State_Stopped;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCFilter_Pause(IBaseFilter *iface)
+{
+    HWCFilter *This = impl_from_IBaseFilter(iface);
+    This->m_state = State_Paused;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCFilter_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
+{
+    HWCFilter *This = impl_from_IBaseFilter(iface);
+
+    if (This->m_state == State_Stopped) {
+        HRESULT hr;
+        hr = IBaseFilter_Pause(iface);
+        if (FAILED(hr)) {
+            ERR("HWCFilter_Run : Failed to IBaseFilter_Pause, ret=0xld%\n", hr);
+            return hr;
+        }
+    }
+
+    This->m_state = State_Running;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCFilter_EnumPins(IBaseFilter *iface, IEnumPins **ppEnum)
+{
+    if (ppEnum == NULL) {
+        return E_POINTER;
+    }
+
+    HWCEnumPins_Construct(iface, 0, ppEnum);
+    return *ppEnum == NULL ? E_OUTOFMEMORY : S_OK;
+}
+
+static STDMETHODIMP HWCFilter_FindPin(IBaseFilter *iface, LPCWSTR Id,
+                                      IPin **ppPin)
+{
+    HWCFilter *This = impl_from_IBaseFilter(iface);
+
+    if (ppPin == NULL) {
+        return E_POINTER;
+    }
+
+    if (memcmp((void *)Id, (void *)HWCPinName, sizeof(HWCPinName))) {
+        return VFW_E_NOT_FOUND;
+    }
+
+    if (!This->m_pPin) {
+        HWCInPin_Construct(iface, &This->m_pPin);
+    }
+    *ppPin = This->m_pPin;
+
+    IPin_AddRef(This->m_pPin);
+    return S_OK;
+}
+
+static STDMETHODIMP HWCFilter_QueryFilterInfo(IBaseFilter *iface,
+                                              FILTER_INFO *pInfo)
+{
+    HWCFilter *This = impl_from_IBaseFilter(iface);
+
+    if (pInfo == NULL) {
+        return E_POINTER;
+    }
+
+    memcpy((void *)pInfo->achName,
+           (void *)HWCFilterName,
+           sizeof(HWCFilterName));
+    pInfo->pGraph = This->m_pFilterGraph;
+    if (This->m_pFilterGraph) {
+        IFilterGraph_AddRef(This->m_pFilterGraph);
+    }
+    return S_OK;
+}
+
+static STDMETHODIMP HWCFilter_JoinFilterGraph(IBaseFilter *iface,
+                                              IFilterGraph *pGraph,
+                                              LPCWSTR pName)
+{
+    HWCFilter *This = impl_from_IBaseFilter(iface);
+
+    This->m_pFilterGraph = pGraph;
+    return S_OK;
+}
+
+static STDMETHODIMP HWCFilter_QueryVendorInfo(IBaseFilter *iface,
+                                              LPWSTR *pVendorInfo)
+{
+    return E_NOTIMPL;
+}
+
+static IBaseFilterVtbl HWCFilter_Vtbl = {
+    HWCFilter_QueryInterface,
+    HWCFilter_AddRef,
+    HWCFilter_Release,
+    HWCFilter_GetClassID,
+    HWCFilter_Stop,
+    HWCFilter_Pause,
+    HWCFilter_Run,
+    HWCFilter_GetState,
+    HWCFilter_SetSyncSource,
+    HWCFilter_GetSyncSource,
+    HWCFilter_EnumPins,
+    HWCFilter_FindPin,
+    HWCFilter_QueryFilterInfo,
+    HWCFilter_JoinFilterGraph,
+    HWCFilter_QueryVendorInfo
+};
+
+static STDMETHODIMP HWCFilter_Construct(IBaseFilter **ppv)
+{
+    HWCFilter *This = (HWCFilter *)g_malloc0(sizeof(HWCFilter));
+
+    if (!This) {
+        ERR("failed to HWCFilter_Construct, E_OUTOFMEMORY\n");
+        return E_OUTOFMEMORY;
+    }
+
+    This->IBaseFilter_iface.lpVtbl = &HWCFilter_Vtbl;
+    This->m_pFilterGraph = NULL;
+    This->m_state = State_Stopped;
+    This->m_cRef = 1;
+    HWCInPin_Construct(&This->IBaseFilter_iface, &This->m_pPin);
+    *ppv = &This->IBaseFilter_iface;
+
+    return S_OK;
+}
+
+/**********************************************************
+ *
+ * Virtual device implementations
+ *
+ **********************************************************/
+
+
+/*
+ * Declaration global variables for Win32 COM Interfaces
+ */
+IGraphBuilder *g_pGB ;
+ICaptureGraphBuilder2 *g_pCGB;
+IMediaControl *g_pMediaControl;
+
+IPin *g_pOutputPin;
+IPin *g_pInputPin;
+IBaseFilter *g_pDstFilter;
+IBaseFilter *g_pSrcFilter;
+
+IGrabCallback *g_pCallback;
+
+/* V4L2 defines copy from videodev2.h */
+#define V4L2_CTRL_FLAG_SLIDER       0x0020
+
+#define V4L2_CTRL_CLASS_USER        0x00980000
+#define V4L2_CID_BASE               (V4L2_CTRL_CLASS_USER | 0x900)
+#define V4L2_CID_BRIGHTNESS         (V4L2_CID_BASE+0)
+#define V4L2_CID_CONTRAST           (V4L2_CID_BASE+1)
+#define V4L2_CID_SATURATION         (V4L2_CID_BASE+2)
+#define V4L2_CID_SHARPNESS          (V4L2_CID_BASE+27)
+
+#define V4L2_PIX_FMT_YUYV    MAKEFOURCC('Y', 'U', 'Y', 'V') /* 16  YUV 4:2:2 */
+#define V4L2_PIX_FMT_YUV420  MAKEFOURCC('Y', 'U', '1', '2') /* 12  YUV 4:2:0 */
+#define V4L2_PIX_FMT_YVU420  MAKEFOURCC('Y', 'V', '1', '2') /* 12  YVU 4:2:0 */
+#define V4L2_PIX_FMT_RGB24   MAKEFOURCC('R', 'G', 'B', '3') /* 24  RGB-8-8-8 */
+
+typedef struct tagMaruCamConvertPixfmt {
+    uint32_t fmt;   /* fourcc */
+    uint32_t bpp;   /* bits per pixel, 0 for compressed formats */
+    uint32_t needs_conversion;
+} MaruCamConvertPixfmt;
+
+static MaruCamConvertPixfmt supported_dst_pixfmts[] = {
+        { V4L2_PIX_FMT_YUYV, 16, 0 },
+        { V4L2_PIX_FMT_YUV420, 12, 0 },
+        { V4L2_PIX_FMT_YVU420, 12, 0 },
+};
+
+typedef struct tagMaruCamConvertFrameInfo {
+    uint32_t width;
+    uint32_t height;
+} MaruCamConvertFrameInfo;
+
+static MaruCamConvertFrameInfo supported_dst_frames[] = {
+        { 640, 480 },
+        { 352, 288 },
+        { 320, 240 },
+        { 176, 144 },
+        { 160, 120 },
+};
+
+#define MARUCAM_CTRL_VALUE_MAX      20
+#define MARUCAM_CTRL_VALUE_MIN      1
+#define MARUCAM_CTRL_VALUE_MID      10
+#define MARUCAM_CTRL_VALUE_STEP     1
+
+struct marucam_qctrl {
+    uint32_t id;
+    uint32_t hit;
+    long min;
+    long max;
+    long step;
+    long init_val;
+};
+
+static struct marucam_qctrl qctrl_tbl[] = {
+    { V4L2_CID_BRIGHTNESS, 0, },
+    { V4L2_CID_CONTRAST, 0, },
+    { V4L2_CID_SATURATION, 0, },
+    { V4L2_CID_SHARPNESS, 0, },
+};
+
+static MaruCamState *g_state;
+
+static uint32_t ready_count;
+static uint32_t cur_fmt_idx;
+static uint32_t cur_frame_idx;
+static void *grab_buf;
+static uint32_t g_dwSrcFmt;
+
+
+/*
+ * Helper functions - converting image formats, converting values
+ */
+
+static uint32_t get_bytesperline(uint32_t pixfmt, uint32_t width)
+{
+    uint32_t bytesperline;
+
+    switch (pixfmt) {
+    case V4L2_PIX_FMT_YUV420:
+    case V4L2_PIX_FMT_YVU420:
+        bytesperline = (width * 12) >> 3;
+        break;
+    case V4L2_PIX_FMT_YUYV:
+    default:
+        bytesperline = width * 2;
+        break;
+    }
+
+    return bytesperline;
+}
+
+static uint32_t get_sizeimage(uint32_t pixfmt, uint32_t width, uint32_t height)
+{
+    return get_bytesperline(pixfmt, width) * height;
+}
+
+void yuyv_to_yuv420(const unsigned char *src, unsigned char *dest,
+        uint32_t width, uint32_t height, uint32_t yvu);
+void rgb24_to_yuv420(const unsigned char *src, unsigned char *dest,
+        uint32_t width, uint32_t height, uint32_t yvu);
+void rgb24_to_yuyv(unsigned char *src, unsigned char *dest,
+        uint32_t width, uint32_t height);
+void yuv420_to_yvu420(unsigned char *src, unsigned char *dest,
+        uint32_t width, uint32_t height);
+void yuv420_to_yuyv(unsigned char *src, unsigned char *dest,
+        uint32_t width, uint32_t height);
+
+static long value_convert_from_guest(long min, long max, long value)
+{
+    double rate = 0.0;
+    long dist = 0, ret = 0;
+
+    dist = max - min;
+
+    if (dist < MARUCAM_CTRL_VALUE_MAX) {
+        rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;
+        ret = min + (int32_t)(value / rate);
+    } else {
+        rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;
+        ret = min + (int32_t)(rate * value);
+    }
+    return ret;
+}
+
+static long value_convert_to_guest(long min, long max, long value)
+{
+    double rate  = 0.0;
+    long dist = 0, ret = 0;
+
+    dist = max - min;
+
+    if (dist < MARUCAM_CTRL_VALUE_MAX) {
+        rate = (double)MARUCAM_CTRL_VALUE_MAX / (double)dist;
+        ret = (int32_t)((double)(value - min) * rate);
+    } else {
+        rate = (double)dist / (double)MARUCAM_CTRL_VALUE_MAX;
+        ret = (int32_t)((double)(value - min) / rate);
+    }
+
+    return ret;
+}
+
+/*
+ * Callback function for grab frames
+ */
+static STDMETHODIMP marucam_device_callbackfn(ULONG dwSize, BYTE *pBuffer)
+{
+    void *tmp_buf;
+    uint32_t width, height, fmt, imgsize;
+
+    width = supported_dst_frames[cur_frame_idx].width;
+    height = supported_dst_frames[cur_frame_idx].height;
+    fmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
+    imgsize = get_sizeimage(fmt, width, height);
+
+    if (imgsize > (uint32_t)dwSize) {
+        ERR("Image size is mismatched\n");
+        return E_FAIL;
+    }
+
+    switch (g_dwSrcFmt) {
+    case V4L2_PIX_FMT_YUYV:
+        switch (fmt) {
+        case V4L2_PIX_FMT_YUV420:
+            yuyv_to_yuv420(pBuffer, grab_buf, width, height, 0);
+            break;
+        case V4L2_PIX_FMT_YVU420:
+            yuyv_to_yuv420(pBuffer, grab_buf, width, height, 1);
+            break;
+        case V4L2_PIX_FMT_YUYV:
+            memcpy(grab_buf, (void *)pBuffer, (size_t)dwSize);
+            break;
+        default:
+            ERR("Invalid pixel format\n");
+            return E_FAIL;
+        }
+        break;
+    case V4L2_PIX_FMT_RGB24:
+        switch (fmt) {
+        case V4L2_PIX_FMT_YUV420:
+            rgb24_to_yuv420(pBuffer, grab_buf, width, height, 0);
+            break;
+        case V4L2_PIX_FMT_YVU420:
+            rgb24_to_yuv420(pBuffer, grab_buf, width, height, 1);
+            break;
+        case V4L2_PIX_FMT_YUYV:
+            rgb24_to_yuyv(pBuffer, grab_buf, width, height);
+            break;
+        default:
+            ERR("Invalid pixel format\n");
+            return E_FAIL;
+        }
+        break;
+    case V4L2_PIX_FMT_YUV420:
+        switch (fmt) {
+        case V4L2_PIX_FMT_YUV420:
+            memcpy(grab_buf, (void *)pBuffer, (size_t)dwSize);
+            break;
+        case V4L2_PIX_FMT_YVU420:
+            yuv420_to_yvu420(pBuffer, grab_buf, width, height);
+            break;
+        case V4L2_PIX_FMT_YUYV:
+            yuv420_to_yuyv(pBuffer, grab_buf, width, height);
+            break;
+        default:
+            ERR("Invalid pixel format\n");
+            return E_FAIL;
+        }
+        break;
+    default:
+        ERR("Invalid pixel format\n");
+        return E_FAIL;
+    }
+
+    qemu_mutex_lock(&g_state->thread_mutex);
+    if (g_state->streamon) {
+        if (ready_count < MARUCAM_SKIPFRAMES) {
+            /* skip a frame cause first some frame are distorted */
+            ++ready_count;
+            TRACE("skip %d frame\n", ready_count);
+            qemu_mutex_unlock(&g_state->thread_mutex);
+            return S_OK;
+        }
+        if (g_state->req_frame == 0) {
+            TRACE("there is no request\n");
+            qemu_mutex_unlock(&g_state->thread_mutex);
+            return S_OK;
+        }
+        tmp_buf = g_state->vaddr + g_state->buf_size * (g_state->req_frame - 1);
+        memcpy(tmp_buf, grab_buf, g_state->buf_size);
+        g_state->req_frame = 0; /* clear request */
+        g_state->isr |= 0x01;   /* set a flag of rasing a interrupt */
+        qemu_bh_schedule(g_state->tx_bh);
+    }
+    qemu_mutex_unlock(&g_state->thread_mutex);
+    return S_OK;
+}
+
+/*
+ * Internal functions for manipulate interfaces
+ */
+
+static STDMETHODIMP_(void) CloseInterfaces(void)
+{
+    if (g_pMediaControl) {
+        g_pMediaControl->lpVtbl->Stop(g_pMediaControl);
+    }
+
+    if (g_pOutputPin) {
+        g_pOutputPin->lpVtbl->Disconnect(g_pOutputPin);
+    }
+
+    SAFE_RELEASE(g_pGB);
+    SAFE_RELEASE(g_pCGB);
+    SAFE_RELEASE(g_pMediaControl);
+    SAFE_RELEASE(g_pOutputPin);
+    SAFE_RELEASE(g_pInputPin);
+    SAFE_RELEASE(g_pDstFilter);
+    SAFE_RELEASE(g_pSrcFilter);
+    SAFE_RELEASE(g_pCallback);
+}
+
+static STDMETHODIMP_(void) DeleteMediaType(AM_MEDIA_TYPE *pmt)
+{
+    if (pmt == NULL) {
+        return;
+    }
+
+    if (pmt->cbFormat != 0) {
+        CoTaskMemFree((PVOID)pmt->pbFormat);
+        pmt->cbFormat = 0;
+        pmt->pbFormat = NULL;
+    }
+    if (pmt->pUnk != NULL) {
+        pmt->pUnk->lpVtbl->Release(pmt->pUnk);
+        pmt->pUnk = NULL;
+    }
+
+    CoTaskMemFree((PVOID)pmt);
+}
+
+static STDMETHODIMP GetPin(IBaseFilter *pFilter,
+                           PIN_DIRECTION PinDir, IPin **ppPin)
+{
+    HRESULT hr;
+    IEnumPins *pEnum = NULL;
+    IPin *pPin = NULL;
+
+    if (ppPin == NULL) {
+        return E_POINTER;
+    }
+
+    hr = pFilter->lpVtbl->EnumPins(pFilter, &pEnum);
+    if (FAILED(hr)) {
+        return hr;
+    }
+
+    while (pEnum->lpVtbl->Next(pEnum, 1, &pPin, 0) == S_OK) {
+        PIN_DIRECTION PinDirThis;
+        hr = pPin->lpVtbl->QueryDirection(pPin, &PinDirThis);
+        if (FAILED(hr)) {
+            SAFE_RELEASE(pPin);
+            SAFE_RELEASE(pEnum);
+            return hr;
+        }
+        if (PinDir == PinDirThis) {
+            *ppPin = pPin;
+            SAFE_RELEASE(pEnum);
+            return S_OK;
+        }
+        SAFE_RELEASE(pPin);
+    }
+
+    SAFE_RELEASE(pEnum);
+    return S_FALSE;
+}
+
+static STDMETHODIMP GraphBuilder_Init(void)
+{
+    HRESULT hr;
+
+    hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC,
+                          &IID_IGraphBuilder, (void **)&g_pGB);
+    if (FAILED(hr)) {
+        ERR("Failed to create instance of GraphBuilder, 0x%x\n", hr);
+        return hr;
+    }
+
+    hr = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC,
+                          &IID_ICaptureGraphBuilder2, (void **)&g_pCGB);
+    if (FAILED(hr)) {
+        ERR("Failed to create instance of CaptureGraphBuilder2, 0x%x\n", hr);
+        return hr;
+    }
+
+    hr = g_pCGB->lpVtbl->SetFiltergraph(g_pCGB, g_pGB);
+    if (FAILED(hr)) {
+        ERR("Failed to SetFiltergraph, 0x%x\n", hr);
+        return hr;
+    }
+
+    hr = g_pGB->lpVtbl->QueryInterface(g_pGB, &IID_IMediaControl,
+                                       (void **)&g_pMediaControl);
+    if (FAILED(hr)) {
+        ERR("Failed to QueryInterface for IMediaControl, 0x%x\n", hr);
+        return hr;
+    }
+
+    hr = HWCGrabCallback_Construct(&g_pCallback);
+    if (g_pCallback == NULL) {
+        hr = E_OUTOFMEMORY;
+    }
+
+    hr = ((HWCGrabCallback *)g_pCallback)->SetCallback(g_pCallback,
+                            (CallbackFn)marucam_device_callbackfn);
+
+    return hr;
+}
+
+static STDMETHODIMP BindSourceFilter(void)
+{
+    HRESULT hr;
+    ICreateDevEnum *pCreateDevEnum = NULL;
+    IEnumMoniker *pEnumMK = NULL;
+    IMoniker *pMoniKer;
+
+    hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
+                          &IID_ICreateDevEnum,
+                          (void **)&pCreateDevEnum);
+    if (FAILED(hr)) {
+        ERR("Failed to create instance of CreateDevEnum, 0x%x\n", hr);
+        return hr;
+    }
+
+    hr = pCreateDevEnum->lpVtbl->CreateClassEnumerator(pCreateDevEnum,
+                                      &CLSID_VideoInputDeviceCategory,
+                                      &pEnumMK, 0);
+    if (FAILED(hr)) {
+        ERR("Failed to get VideoInputDeviceCategory, 0x%x\n", hr);
+        SAFE_RELEASE(pCreateDevEnum);
+        return hr;
+    }
+
+    if (!pEnumMK) {
+        ERR("ClassEnumerator moniker is NULL\n");
+        SAFE_RELEASE(pCreateDevEnum);
+        return E_FAIL;
+    }
+    pEnumMK->lpVtbl->Reset(pEnumMK);
+
+    hr = pEnumMK->lpVtbl->Next(pEnumMK, 1, &pMoniKer, NULL);
+    if (hr == S_FALSE) {
+        hr = E_FAIL;
+    }
+    if (SUCCEEDED(hr)) {
+        IPropertyBag *pBag = NULL;
+        hr = pMoniKer->lpVtbl->BindToStorage(pMoniKer, 0, 0,
+                                             &IID_IPropertyBag,
+                                             (void **)&pBag);
+        if (SUCCEEDED(hr)) {
+            VARIANT var;
+            var.vt = VT_BSTR;
+            hr = pBag->lpVtbl->Read(pBag, L"FriendlyName", &var, NULL);
+            if (hr == NOERROR) {
+                hr = pMoniKer->lpVtbl->BindToObject(pMoniKer, NULL, NULL,
+                                                    &IID_IBaseFilter,
+                                                    (void **)&g_pSrcFilter);
+                if (FAILED(hr)) {
+                    ERR("Counldn't bind moniker to filter object!!\n");
+                } else {
+                    g_pSrcFilter->lpVtbl->AddRef(g_pSrcFilter);
+                }
+                SysFreeString(var.bstrVal);
+            }
+            SAFE_RELEASE(pBag);
+        }
+        SAFE_RELEASE(pMoniKer);
+    }
+
+    if (SUCCEEDED(hr)) {
+        hr = g_pGB->lpVtbl->AddFilter(g_pGB, g_pSrcFilter, L"Video Capture");
+        if (hr != S_OK && hr != S_FALSE) {
+            ERR("Counldn't add Video Capture filter to our graph!\n");
+            SAFE_RELEASE(g_pSrcFilter);
+        }
+    }
+    SAFE_RELEASE(pEnumMK);
+    SAFE_RELEASE(pCreateDevEnum);
+
+    return hr;
+}
+
+static STDMETHODIMP BindTargetFilter(void)
+{
+    HRESULT hr;
+    hr = HWCFilter_Construct(&g_pDstFilter);
+
+    if (SUCCEEDED(hr) && g_pDstFilter) {
+        hr = g_pGB->lpVtbl->AddFilter(g_pGB, g_pDstFilter, L"HWCFilter");
+        if (FAILED(hr)) {
+            ERR("Counldn't add HWCFilterr to our graph!\n");
+            SAFE_RELEASE(g_pDstFilter);
+        }
+    }
+    return hr;
+}
+
+static STDMETHODIMP ConnectFilters(void)
+{
+    HRESULT hr;
+
+    hr = GetPin(g_pSrcFilter, PINDIR_OUTPUT , &g_pOutputPin);
+    if (FAILED(hr)) {
+        ERR("Failed to get output pin. 0x%x\n", hr);
+        return hr;
+    }
+
+    hr = GetPin(g_pDstFilter, PINDIR_INPUT , &g_pInputPin);
+    if (FAILED(hr)) {
+        ERR("Failed to get input pin. 0x%x\n", hr);
+        return hr;
+    }
+
+    hr = g_pGB->lpVtbl->Connect(g_pGB, g_pOutputPin, g_pInputPin);
+    if (FAILED(hr)) {
+        ERR("Failed to connect pins. 0x%x\n", hr);
+    }
+    return hr;
+}
+
+static STDMETHODIMP DisconnectPins(void)
+{
+    HRESULT hr;
+
+    hr = g_pGB->lpVtbl->Disconnect(g_pGB, g_pOutputPin);
+    if (FAILED(hr)) {
+        ERR("Failed to disconnect output pin. 0x%x\n", hr);
+        return hr;
+    }
+
+    hr = g_pGB->lpVtbl->Disconnect(g_pGB, g_pInputPin);
+    if (FAILED(hr)) {
+        ERR("Failed to disconnect input pin. 0x%x\n", hr);
+    }
+
+    return hr;
+}
+
+static STDMETHODIMP RemoveFilters(void)
+{
+    HRESULT hr;
+
+    hr = g_pGB->lpVtbl->RemoveFilter(g_pGB, g_pSrcFilter);
+    if (FAILED(hr)) {
+        ERR("Failed to remove source filer. 0x%x\n", hr);
+        return hr;
+    }
+
+    hr = g_pGB->lpVtbl->RemoveFilter(g_pGB, g_pDstFilter);
+    if (FAILED(hr)) {
+        ERR("Failed to remove destination filer. 0x%x\n", hr);
+    }
+
+    return hr;
+}
+
+/* default fps is 15 */
+#define MARUCAM_DEFAULT_FRAMEINTERVAL    666666
+
+static STDMETHODIMP SetFormat(uint32_t dwWidth, uint32_t dwHeight,
+                              uint32_t dwDstFmt, uint32_t *dwSrcFmt)
+{
+    HRESULT hr;
+    IAMStreamConfig *pSConfig;
+    int iCount = 0, iSize = 0;
+    DWORD dwYUY2 = MAKEFOURCC('Y', 'U', 'Y', '2');
+    DWORD dwI420 = MAKEFOURCC('I', '4', '2', '0');
+
+    if (dwSrcFmt == NULL) {
+        ERR("invalid the source format pointer\n");
+        return E_FAIL;
+    }
+
+    hr = g_pCGB->lpVtbl->FindInterface(g_pCGB, &PIN_CATEGORY_CAPTURE, 0,
+                                       g_pSrcFilter, &IID_IAMStreamConfig,
+                                       (void **)&pSConfig);
+    if (FAILED(hr)) {
+        ERR("failed to FindInterface method\n");
+        return hr;
+    }
+
+    hr = pSConfig->lpVtbl->GetNumberOfCapabilities(pSConfig, &iCount, &iSize);
+    if (FAILED(hr)) {
+        ERR("failed to GetNumberOfCapabilities method\n");
+        SAFE_RELEASE(pSConfig);
+        return hr;
+    }
+
+    if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS)) {
+        int iFormat = 0;
+        for (iFormat = 0; iFormat < iCount; iFormat++) {
+            VIDEO_STREAM_CONFIG_CAPS scc;
+            AM_MEDIA_TYPE *pmtConfig;
+
+            hr = pSConfig->lpVtbl->GetStreamCaps(pSConfig, iFormat,
+                                                 &pmtConfig, (BYTE *)&scc);
+            if (hr == S_OK) {
+                if (IsEqualIID(&pmtConfig->formattype, &FORMAT_VideoInfo)) {
+                    VIDEOINFOHEADER *pvi =
+                                         (VIDEOINFOHEADER *)pmtConfig->pbFormat;
+                    if ((pvi->bmiHeader.biWidth == (LONG)dwWidth) &&
+                        (pvi->bmiHeader.biHeight == (LONG)dwHeight)) {
+                        if (pvi->bmiHeader.biCompression == dwYUY2) {
+                            *dwSrcFmt = V4L2_PIX_FMT_YUYV;
+                        } else if ((pvi->bmiHeader.biCompression == BI_RGB) &&
+                                (pvi->bmiHeader.biBitCount == 24)) {
+                            *dwSrcFmt = V4L2_PIX_FMT_RGB24;
+                        } else if (pvi->bmiHeader.biCompression == dwI420) {
+                            *dwSrcFmt = V4L2_PIX_FMT_YUV420;
+                        } else { /* not support format */
+                            DeleteMediaType(pmtConfig);
+                            continue;
+                        }
+                        /* use minimum FPS(maximum frameinterval)
+                           with non-VT system  */
+#ifdef CONFIG_HAX
+                        if (!hax_enabled()) {
+                            pvi->AvgTimePerFrame =
+                                    (REFERENCE_TIME)scc.MaxFrameInterval;
+                        } else {
+                            pvi->AvgTimePerFrame =
+                                (REFERENCE_TIME)MARUCAM_DEFAULT_FRAMEINTERVAL;
+                        }
+#else
+                        pvi->AvgTimePerFrame =
+                                (REFERENCE_TIME)scc.MaxFrameInterval;
+#endif
+                        hr = pSConfig->lpVtbl->SetFormat(pSConfig, pmtConfig);
+                        DeleteMediaType(pmtConfig);
+                        break;
+                    }
+                }
+                DeleteMediaType(pmtConfig);
+            }
+        }
+        if (iFormat >= iCount) {
+            ERR("Failed to Set format. "
+                "Maybe connected webcam does not support the (%ldx%ld) "
+                "resolution or image formats(YUY2, RGB24, I420).\n",
+                dwWidth, dwHeight);
+            hr = E_FAIL;
+        }
+    }
+    SAFE_RELEASE(pSConfig);
+    return hr;
+}
+
+static STDMETHODIMP QueryVideoProcAmp(long nProperty, long *pMin, long *pMax,
+                                      long *pStep, long *pDefault)
+{
+    HRESULT hr;
+    long Flags;
+    IAMVideoProcAmp *pProcAmp = NULL;
+
+    hr = g_pSrcFilter->lpVtbl->QueryInterface(g_pSrcFilter,
+                                              &IID_IAMVideoProcAmp,
+                                              (void **)&pProcAmp);
+    if (FAILED(hr)) {
+        return hr;
+    }
+
+    hr = pProcAmp->lpVtbl->GetRange(pProcAmp, nProperty, pMin, pMax,
+                                    pStep, pDefault, &Flags);
+
+    SAFE_RELEASE(pProcAmp);
+    return hr;
+}
+
+static STDMETHODIMP GetVideoProcAmp(long nProperty, long *pValue)
+{
+    HRESULT hr;
+    long Flags;
+    IAMVideoProcAmp *pProcAmp = NULL;
+
+    hr = g_pSrcFilter->lpVtbl->QueryInterface(g_pSrcFilter,
+                                              &IID_IAMVideoProcAmp,
+                                              (void **)&pProcAmp);
+    if (FAILED(hr)) {
+        return hr;
+    }
+
+    hr = pProcAmp->lpVtbl->Get(pProcAmp, nProperty, pValue, &Flags);
+    if (FAILED(hr)) {
+        ERR("Failed to get property for video\n");
+    }
+
+    SAFE_RELEASE(pProcAmp);
+    return hr;
+}
+
+static STDMETHODIMP SetVideoProcAmp(long nProperty, long value)
+{
+    HRESULT hr;
+
+    IAMVideoProcAmp *pProcAmp = NULL;
+    hr = g_pSrcFilter->lpVtbl->QueryInterface(g_pSrcFilter,
+                                              &IID_IAMVideoProcAmp,
+                                              (void **)&pProcAmp);
+    if (FAILED(hr)) {
+        return hr;
+    }
+
+    hr = pProcAmp->lpVtbl->Set(pProcAmp, nProperty, value,
+                               VideoProcAmp_Flags_Manual);
+    if (FAILED(hr)) {
+        ERR("Failed to set property for video\n");
+    }
+    SAFE_RELEASE(pProcAmp);
+    return hr;
+}
+
+static char *__wchar_to_char(const WCHAR *pwstr)
+{
+    char *pstr = NULL;
+    int len = 0;
+
+    len = wcslen(pwstr) + 1;
+    pstr = (char *)g_malloc0(sizeof(char) * len);
+    wcstombs(pstr, pwstr, len + 1);
+
+    return pstr;
+}
+
+int marucam_device_check(int log_flag)
+{
+    struct timeval t1, t2;
+    int ret = 0;
+    char *device_name = NULL;
+    HRESULT hr = E_FAIL;
+    ICreateDevEnum *pCreateDevEnum = NULL;
+    IGraphBuilder *pGB = NULL;
+    ICaptureGraphBuilder2 *pCGB = NULL;
+    IBaseFilter *pSrcFilter = NULL;
+    IEnumMoniker *pEnumMK = NULL;
+    IMoniker *pMoniKer = NULL;
+    IAMStreamConfig *pSConfig = NULL;
+    int iCount = 0, iSize = 0;
+
+    gettimeofday(&t1, NULL);
+    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+    if (FAILED(hr)) {
+        ERR("Failed to CoInitailizeEx\n");
+        gettimeofday(&t2, NULL);
+        ERR("Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    hr = CoCreateInstance(&CLSID_FilterGraph, NULL,
+                          CLSCTX_INPROC,
+                          &IID_IGraphBuilder,
+                          (void **)&pGB);
+    if (FAILED(hr)) {
+        ERR("Failed to create GraphBuilder, 0x%x\n", hr);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        ERR("Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    hr = CoCreateInstance(&CLSID_CaptureGraphBuilder2, NULL,
+                          CLSCTX_INPROC,
+                          &IID_ICaptureGraphBuilder2,
+                          (void **)&pCGB);
+    if (FAILED(hr)) {
+        ERR("Failed to create CaptureGraphBuilder2, 0x%x\n", hr);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        ERR("Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    hr = pCGB->lpVtbl->SetFiltergraph(pCGB, pGB);
+    if (FAILED(hr)) {
+        ERR("Failed to SetFiltergraph, 0x%x\n", hr);
+        SAFE_RELEASE(pCGB);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        ERR("Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL,
+                          CLSCTX_INPROC,
+                          &IID_ICreateDevEnum,
+                          (void **)&pCreateDevEnum);
+    if (FAILED(hr)) {
+        ERR("Failed to create instance of CLSID_SystemDeviceEnum\n");
+        SAFE_RELEASE(pCGB);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        ERR("Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    hr = pCreateDevEnum->lpVtbl->CreateClassEnumerator(pCreateDevEnum,
+                                  &CLSID_VideoInputDeviceCategory, &pEnumMK, 0);
+    if (FAILED(hr)) {
+        ERR("Failed to create class enumerator\n");
+        SAFE_RELEASE(pCreateDevEnum);
+        SAFE_RELEASE(pCGB);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        ERR("Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    if (!pEnumMK) {
+        ERR("Class enumerator is NULL!!\n");
+        SAFE_RELEASE(pCreateDevEnum);
+        SAFE_RELEASE(pCGB);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        ERR("Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+    pEnumMK->lpVtbl->Reset(pEnumMK);
+
+    hr = pEnumMK->lpVtbl->Next(pEnumMK, 1, &pMoniKer, NULL);
+    if (FAILED(hr) || (hr == S_FALSE)) {
+        ERR("Enum moniker returns a invalid value.\n");
+        SAFE_RELEASE(pEnumMK);
+        SAFE_RELEASE(pCreateDevEnum);
+        SAFE_RELEASE(pCGB);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        ERR("Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    IPropertyBag *pBag = NULL;
+    hr = pMoniKer->lpVtbl->BindToStorage(pMoniKer, 0, 0,
+                                         &IID_IPropertyBag,
+                                         (void **)&pBag);
+    if (FAILED(hr)) {
+        ERR("Failed to bind to storage.\n");
+        SAFE_RELEASE(pEnumMK);
+        SAFE_RELEASE(pCreateDevEnum);
+        SAFE_RELEASE(pCGB);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        ERR("Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    } else {
+        VARIANT var;
+        var.vt = VT_BSTR;
+        hr = pBag->lpVtbl->Read(pBag, L"FriendlyName", &var, NULL);
+        if (hr == S_OK) {
+            ret = 1;
+            if (!log_flag) {
+                SysFreeString(var.bstrVal);
+                SAFE_RELEASE(pBag);
+                SAFE_RELEASE(pMoniKer);
+                SAFE_RELEASE(pEnumMK);
+                SAFE_RELEASE(pCreateDevEnum);
+                SAFE_RELEASE(pCGB);
+                SAFE_RELEASE(pGB);
+                CoUninitialize();
+                gettimeofday(&t2, NULL);
+                ERR("Elapsed time : %lu.%06lu\n",
+                                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+                return ret;
+            }
+            device_name = __wchar_to_char(var.bstrVal);
+            INFO("Device name : %s\n", device_name);
+            g_free(device_name);
+            hr = pMoniKer->lpVtbl->BindToObject(pMoniKer, NULL, NULL,
+                                                &IID_IBaseFilter,
+                                                (void **)&pSrcFilter);
+            if (FAILED(hr)) {
+                ERR("Counldn't bind moniker to filter object!!\n");
+                SysFreeString(var.bstrVal);
+                SAFE_RELEASE(pBag);
+                SAFE_RELEASE(pMoniKer);
+                SAFE_RELEASE(pEnumMK);
+                SAFE_RELEASE(pCreateDevEnum);
+                SAFE_RELEASE(pCGB);
+                SAFE_RELEASE(pGB);
+                CoUninitialize();
+                gettimeofday(&t2, NULL);
+                ERR("Elapsed time : %lu.%06lu\n",
+                                t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+                return ret;
+            } else {
+                pSrcFilter->lpVtbl->AddRef(pSrcFilter);
+            }
+            SysFreeString(var.bstrVal);
+        }
+        SAFE_RELEASE(pBag);
+    }
+    SAFE_RELEASE(pMoniKer);
+
+    hr = pGB->lpVtbl->AddFilter(pGB, pSrcFilter, L"Video Capture");
+    if (hr != S_OK && hr != S_FALSE) {
+        ERR("Counldn't add Video Capture filter to our graph!\n");
+        SAFE_RELEASE(pSrcFilter);
+        SAFE_RELEASE(pEnumMK);
+        SAFE_RELEASE(pCreateDevEnum);
+        SAFE_RELEASE(pCGB);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        ERR("Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    hr = pCGB->lpVtbl->FindInterface(pCGB, &PIN_CATEGORY_CAPTURE, 0,
+                                       pSrcFilter, &IID_IAMStreamConfig,
+                                       (void **)&pSConfig);
+    if (FAILED(hr)) {
+        ERR("Failed to FindInterface method\n");
+        SAFE_RELEASE(pSrcFilter);
+        SAFE_RELEASE(pEnumMK);
+        SAFE_RELEASE(pCreateDevEnum);
+        SAFE_RELEASE(pCGB);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        ERR("Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    hr = pSConfig->lpVtbl->GetNumberOfCapabilities(pSConfig, &iCount, &iSize);
+    if (FAILED(hr)) {
+        ERR("Failed to GetNumberOfCapabilities method\n");
+        SAFE_RELEASE(pSConfig);
+        SAFE_RELEASE(pSrcFilter);
+        SAFE_RELEASE(pEnumMK);
+        SAFE_RELEASE(pCreateDevEnum);
+        SAFE_RELEASE(pCGB);
+        SAFE_RELEASE(pGB);
+        CoUninitialize();
+        gettimeofday(&t2, NULL);
+        ERR("Elapsed time : %lu.%06lu\n",
+                        t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+        return ret;
+    }
+
+    if (iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS)) {
+        int iFormat = 0;
+        for (iFormat = 0; iFormat < iCount; iFormat++) {
+            VIDEO_STREAM_CONFIG_CAPS scc;
+            AM_MEDIA_TYPE *pmtConfig;
+
+            hr = pSConfig->lpVtbl->GetStreamCaps(pSConfig, iFormat, &pmtConfig,
+                                                 (BYTE *)&scc);
+            if (hr == S_OK) {
+                if (IsEqualIID(&pmtConfig->formattype, &FORMAT_VideoInfo)) {
+                    VIDEOINFOHEADER *pvi =
+                                         (VIDEOINFOHEADER *)pmtConfig->pbFormat;
+                    if (pvi->bmiHeader.biCompression == BI_RGB) {
+                        INFO("RGB BitCount: %d, Frame size: %ux%u\n",
+                                pvi->bmiHeader.biBitCount,
+                                pvi->bmiHeader.biWidth,
+                                pvi->bmiHeader.biHeight);
+                    } else {
+                        INFO("PixelFormat: %c%c%c%c, Frame size: %ux%u\n",
+                            (char)(pvi->bmiHeader.biCompression),
+                            (char)(pvi->bmiHeader.biCompression >> 8),
+                            (char)(pvi->bmiHeader.biCompression >> 16),
+                            (char)(pvi->bmiHeader.biCompression >> 24),
+                            pvi->bmiHeader.biWidth,
+                            pvi->bmiHeader.biHeight);
+                    }
+                }
+                DeleteMediaType(pmtConfig);
+            }
+        }
+    }
+
+    hr = pGB->lpVtbl->RemoveFilter(pGB, pSrcFilter);
+    if (FAILED(hr)) {
+        ERR("Failed to remove source filer. 0x%x\n", hr);
+    }
+
+    SAFE_RELEASE(pSConfig);
+    SAFE_RELEASE(pSrcFilter);
+    SAFE_RELEASE(pCGB);
+    SAFE_RELEASE(pGB);
+    SAFE_RELEASE(pEnumMK);
+    SAFE_RELEASE(pCreateDevEnum);
+    CoUninitialize();
+    gettimeofday(&t2, NULL);
+    ERR("Elapsed time : %lu.%06lu\n",
+                    t2.tv_sec-t1.tv_sec, t2.tv_usec-t1.tv_usec);
+
+    return ret;
+}
+
+/* MARUCAM_CMD_INIT */
+void marucam_device_init(MaruCamState *state)
+{
+    g_state = state;
+}
+
+void marucam_device_exit(MaruCamState *state)
+{
+}
+
+/* MARUCAM_CMD_OPEN */
+void marucam_device_open(MaruCamState *state)
+{
+    HRESULT hr;
+    uint32_t dwHeight, dwWidth, dwDstFmt;
+    MaruCamParam *param = state->param;
+    param->top = 0;
+
+    hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
+    if (FAILED(hr)) {
+        ERR("CoInitailizeEx\n");
+        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
+        param->errCode = EINVAL;
+        return;
+    }
+
+    hr = GraphBuilder_Init();
+    if (FAILED(hr)) {
+        ERR("GraphBuilder_Init\n");
+        DisconnectPins();
+        RemoveFilters();
+        CloseInterfaces();
+        CoUninitialize();
+        param->errCode = EINVAL;
+        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
+        return;
+    }
+
+    hr = BindSourceFilter();
+    if (FAILED(hr)) {
+        ERR("BindSourceFilter\n");
+        DisconnectPins();
+        RemoveFilters();
+        CloseInterfaces();
+        CoUninitialize();
+        param->errCode = EINVAL;
+        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
+        return;
+    }
+
+    hr = BindTargetFilter();
+    if (FAILED(hr)) {
+        ERR("BindTargetFilter\n");
+        DisconnectPins();
+        RemoveFilters();
+        CloseInterfaces();
+        CoUninitialize();
+        param->errCode = EINVAL;
+        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
+        return;
+    }
+
+    hr = ConnectFilters();
+    if (FAILED(hr)) {
+        ERR("ConnectFilters\n");
+        DisconnectPins();
+        RemoveFilters();
+        CloseInterfaces();
+        CoUninitialize();
+        param->errCode = EINVAL;
+        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
+        return;
+    }
+
+    cur_frame_idx = 0;
+    cur_fmt_idx = 0;
+
+    dwHeight = supported_dst_frames[cur_frame_idx].height;
+    dwWidth = supported_dst_frames[cur_frame_idx].width;
+    dwDstFmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
+    hr = SetFormat(dwWidth, dwHeight, dwDstFmt, &g_dwSrcFmt);
+    if (hr != S_OK) {
+        ERR("failed to Set default values\n");
+        DisconnectPins();
+        RemoveFilters();
+        CloseInterfaces();
+        CoUninitialize();
+        param->errCode = EINVAL;
+        ERR("camera device open failed!!!, [HRESULT : 0x%x]\n", hr);
+        return;
+    }
+
+    INFO("Opened\n");
+    return;
+}
+
+/* MARUCAM_CMD_CLOSE */
+void marucam_device_close(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+    int ret = 0;
+    param->top = 0;
+
+    qemu_mutex_lock(&state->thread_mutex);
+    ret = state->streamon;
+    qemu_mutex_unlock(&state->thread_mutex);
+    if (ret) {
+        marucam_device_stop_preview(state);
+    }
+
+    if (g_pGB) {
+        DisconnectPins();
+        RemoveFilters();
+    }
+    CloseInterfaces();
+    CoUninitialize();
+    INFO("Closed\n");
+}
+
+/* MARUCAM_CMD_START_PREVIEW */
+void marucam_device_start_preview(MaruCamState *state)
+{
+    HRESULT hr;
+    uint32_t pixfmt, width, height;
+    MaruCamParam *param = state->param;
+    param->top = 0;
+
+    ready_count = 0;
+    width = supported_dst_frames[cur_frame_idx].width;
+    height = supported_dst_frames[cur_frame_idx].height;
+    pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
+    state->buf_size = get_sizeimage(pixfmt, width, height);
+
+    INFO("Pixfmt(%c%c%c%c), W:H(%d:%d), buf size(%u)\n",
+         (char)(pixfmt), (char)(pixfmt >> 8),
+         (char)(pixfmt >> 16), (char)(pixfmt >> 24),
+         width, height, state->buf_size);
+    INFO("Starting preview\n");
+
+    assert(g_pCallback != NULL);
+    hr = ((HWCInPin *)g_pInputPin)->SetGrabCallbackIF(g_pInputPin,
+                                                       g_pCallback);
+    if (FAILED(hr)) {
+        ERR("Failed to set IGrabCallback interface.\n");
+        param->errCode = EINVAL;
+        return;
+    }
+
+    if (grab_buf) {
+        g_free(grab_buf);
+        grab_buf = NULL;
+    }
+    grab_buf = (void *)g_malloc0(state->buf_size);
+    if (grab_buf == NULL) {
+        param->errCode = ENOMEM;
+        return;
+    }
+
+    hr = g_pMediaControl->lpVtbl->Run(g_pMediaControl);
+    if (FAILED(hr)) {
+        ERR("Failed to run media control. hr=0x%x\n", hr);
+        param->errCode = EINVAL;
+        return;
+    }
+
+    qemu_mutex_lock(&state->thread_mutex);
+    state->streamon = 1;
+    qemu_mutex_unlock(&state->thread_mutex);
+
+    INFO("Streaming on ......\n");
+}
+
+/* MARUCAM_CMD_STOP_PREVIEW */
+void marucam_device_stop_preview(MaruCamState *state)
+{
+    HRESULT hr;
+    MaruCamParam *param = state->param;
+    param->top = 0;
+
+    INFO("...... Streaming off\n");
+    qemu_mutex_lock(&state->thread_mutex);
+    state->streamon = 0;
+    qemu_mutex_unlock(&state->thread_mutex);
+
+    hr = ((HWCInPin *)g_pInputPin)->SetGrabCallbackIF(g_pInputPin, NULL);
+    if (FAILED(hr)) {
+        ERR("Failed to set IGrabCallback interface.\n");
+        param->errCode = EINVAL;
+        return;
+    }
+
+    hr = g_pMediaControl->lpVtbl->Stop(g_pMediaControl);
+    if (FAILED(hr)) {
+        ERR("Failed to stop media control.\n");
+        param->errCode = EINVAL;
+        return;
+    }
+
+    if (grab_buf) {
+        g_free(grab_buf);
+        grab_buf = NULL;
+    }
+    state->buf_size = 0;
+
+    INFO("Stopping preview\n");
+}
+
+/* MARUCAM_CMD_S_PARAM */
+void marucam_device_s_param(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+
+    /* We use default FPS of the webcam */
+    param->top = 0;
+}
+
+/* MARUCAM_CMD_G_PARAM */
+void marucam_device_g_param(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+
+    /* We use default FPS of the webcam
+     * return a fixed value on guest ini file (1/30).
+     */
+    param->top = 0;
+    param->stack[0] = 0x1000; /* V4L2_CAP_TIMEPERFRAME */
+    param->stack[1] = 1; /* numerator */
+    param->stack[2] = 30; /* denominator */
+}
+
+/* MARUCAM_CMD_S_FMT */
+void marucam_device_s_fmt(MaruCamState *state)
+{
+    uint32_t width, height, pixfmt, pidx, fidx;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    width = param->stack[0];
+    height = param->stack[1];
+    pixfmt = param->stack[2];
+
+    for (fidx = 0; fidx < ARRAY_SIZE(supported_dst_frames); fidx++) {
+        if ((supported_dst_frames[fidx].width == width) &&
+                (supported_dst_frames[fidx].height == height)) {
+            break;
+        }
+    }
+    if (fidx == ARRAY_SIZE(supported_dst_frames)) {
+        param->errCode = EINVAL;
+        return;
+    }
+    for (pidx = 0; pidx < ARRAY_SIZE(supported_dst_pixfmts); pidx++) {
+        if (supported_dst_pixfmts[pidx].fmt == pixfmt) {
+            break;
+        }
+    }
+    if (pidx == ARRAY_SIZE(supported_dst_pixfmts)) {
+        param->errCode = EINVAL;
+        return;
+    }
+
+    if ((supported_dst_frames[cur_frame_idx].width != width) &&
+            (supported_dst_frames[cur_frame_idx].height != height)) {
+        HRESULT hr = SetFormat(width, height, pixfmt, &g_dwSrcFmt);
+        if (FAILED(hr)) {
+            param->errCode = EINVAL;
+            return;
+        }
+    }
+
+    cur_frame_idx = fidx;
+    cur_fmt_idx = pidx;
+
+    pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
+    width = supported_dst_frames[cur_frame_idx].width;
+    height = supported_dst_frames[cur_frame_idx].height;
+
+    param->stack[0] = width;
+    param->stack[1] = height;
+    param->stack[2] = 1; /* V4L2_FIELD_NONE */
+    param->stack[3] = pixfmt;
+    param->stack[4] = get_bytesperline(pixfmt, width);
+    param->stack[5] = get_sizeimage(pixfmt, width, height);
+    param->stack[6] = 0;
+    param->stack[7] = 0;
+
+    TRACE("Set format...\n");
+}
+
+/* MARUCAM_CMD_G_FMT */
+void marucam_device_g_fmt(MaruCamState *state)
+{
+    uint32_t width, height, pixfmt;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt;
+    width = supported_dst_frames[cur_frame_idx].width;
+    height = supported_dst_frames[cur_frame_idx].height;
+
+    param->stack[0] = width;
+    param->stack[1] = height;
+    param->stack[2] = 1; /* V4L2_FIELD_NONE */
+    param->stack[3] = pixfmt;
+    param->stack[4] = get_bytesperline(pixfmt, width);
+    param->stack[5] = get_sizeimage(pixfmt, width, height);
+    param->stack[6] = 0;
+    param->stack[7] = 0;
+
+    TRACE("Get format...\n");
+}
+
+void marucam_device_try_fmt(MaruCamState *state)
+{
+    uint32_t width, height, pixfmt, i;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    width = param->stack[0];
+    height = param->stack[1];
+    pixfmt = param->stack[2];
+
+    for (i = 0; i < ARRAY_SIZE(supported_dst_frames); i++) {
+        if ((supported_dst_frames[i].width == width) &&
+                (supported_dst_frames[i].height == height)) {
+            break;
+        }
+    }
+    if (i == ARRAY_SIZE(supported_dst_frames)) {
+        param->errCode = EINVAL;
+        return;
+    }
+    for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) {
+        if (supported_dst_pixfmts[i].fmt == pixfmt) {
+            break;
+        }
+    }
+    if (i == ARRAY_SIZE(supported_dst_pixfmts)) {
+        param->errCode = EINVAL;
+        return;
+    }
+
+    param->stack[0] = width;
+    param->stack[1] = height;
+    param->stack[2] = 1; /* V4L2_FIELD_NONE */
+    param->stack[3] = pixfmt;
+    param->stack[4] = get_bytesperline(pixfmt, width);
+    param->stack[5] = get_sizeimage(pixfmt, width, height);
+    param->stack[6] = 0;
+    param->stack[7] = 0;
+}
+
+void marucam_device_enum_fmt(MaruCamState *state)
+{
+    uint32_t index;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    index = param->stack[0];
+
+    if (index >= ARRAY_SIZE(supported_dst_pixfmts)) {
+        param->errCode = EINVAL;
+        return;
+    }
+    param->stack[1] = 0; /* flags = NONE */
+    param->stack[2] = supported_dst_pixfmts[index].fmt; /* pixelformat */
+    /* set description */
+    switch (supported_dst_pixfmts[index].fmt) {
+    case V4L2_PIX_FMT_YUYV:
+        memcpy(&param->stack[3], "YUYV", 32);
+        break;
+    case V4L2_PIX_FMT_YUV420:
+        memcpy(&param->stack[3], "YU12", 32);
+        break;
+    case V4L2_PIX_FMT_YVU420:
+        memcpy(&param->stack[3], "YV12", 32);
+        break;
+    default:
+        ERR("Invalid pixel format\n");
+        param->errCode = EINVAL;
+        break;
+    }
+}
+
+void marucam_device_qctrl(MaruCamState *state)
+{
+    HRESULT hr;
+    uint32_t id, i;
+    long property, min, max, step, def_val, set_val;
+    char name[32] = {0,};
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    id = param->stack[0];
+
+    switch (id) {
+    case V4L2_CID_BRIGHTNESS:
+        TRACE("V4L2_CID_BRIGHTNESS\n");
+        property = VideoProcAmp_Brightness;
+        memcpy((void *)name, (void *)"brightness", 32);
+        i = 0;
+        break;
+    case V4L2_CID_CONTRAST:
+        TRACE("V4L2_CID_CONTRAST\n");
+        property = VideoProcAmp_Contrast;
+        memcpy((void *)name, (void *)"contrast", 32);
+        i = 1;
+        break;
+    case V4L2_CID_SATURATION:
+        TRACE("V4L2_CID_SATURATION\n");
+        property = VideoProcAmp_Saturation;
+        memcpy((void *)name, (void *)"saturation", 32);
+        i = 2;
+        break;
+    case V4L2_CID_SHARPNESS:
+        TRACE("V4L2_CID_SHARPNESS\n");
+        property = VideoProcAmp_Sharpness;
+        memcpy((void *)name, (void *)"sharpness", 32);
+        i = 3;
+        break;
+    default:
+        ERR("Invalid control ID\n");
+        param->errCode = EINVAL;
+        return;
+    }
+    hr = QueryVideoProcAmp(property, &min, &max, &step, &def_val);
+    if (FAILED(hr)) {
+        param->errCode = EINVAL;
+        ERR("failed to query video controls [HRESULT : 0x%x]\n", hr);
+        return;
+    } else {
+        qctrl_tbl[i].hit = 1;
+        qctrl_tbl[i].min = min;
+        qctrl_tbl[i].max = max;
+        qctrl_tbl[i].step = step;
+        qctrl_tbl[i].init_val = def_val;
+
+        if ((qctrl_tbl[i].min + qctrl_tbl[i].max) == 0) {
+            set_val = 0;
+        } else {
+            set_val = (qctrl_tbl[i].min + qctrl_tbl[i].max) / 2;
+        }
+        hr = SetVideoProcAmp(property, set_val);
+        if (FAILED(hr)) {
+            param->errCode = EINVAL;
+            ERR("failed to set video control value, [HRESULT : 0x%x]\n", hr);
+            return;
+        }
+    }
+
+    param->stack[0] = id;
+    param->stack[1] = MARUCAM_CTRL_VALUE_MIN;  /* minimum */
+    param->stack[2] = MARUCAM_CTRL_VALUE_MAX;  /* maximum */
+    param->stack[3] = MARUCAM_CTRL_VALUE_STEP; /*  step   */
+    param->stack[4] = MARUCAM_CTRL_VALUE_MID;  /* default_value */
+    param->stack[5] = V4L2_CTRL_FLAG_SLIDER;
+    /* name field setting */
+    memcpy(&param->stack[6], (void *)name, sizeof(name)/sizeof(name[0]));
+}
+
+void marucam_device_s_ctrl(MaruCamState *state)
+{
+    HRESULT hr;
+    uint32_t i;
+    long property, set_val;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+
+    switch (param->stack[0]) {
+    case V4L2_CID_BRIGHTNESS:
+        i = 0;
+        property = VideoProcAmp_Brightness;
+        break;
+    case V4L2_CID_CONTRAST:
+        i = 1;
+        property = VideoProcAmp_Contrast;
+        break;
+    case V4L2_CID_SATURATION:
+        i = 2;
+        property = VideoProcAmp_Saturation;
+        break;
+    case V4L2_CID_SHARPNESS:
+        i = 3;
+        property = VideoProcAmp_Sharpness;
+        break;
+    default:
+        param->errCode = EINVAL;
+        return;
+    }
+    set_val = value_convert_from_guest(qctrl_tbl[i].min,
+            qctrl_tbl[i].max, (long)param->stack[1]);
+    hr = SetVideoProcAmp(property, set_val);
+    if (FAILED(hr)) {
+        param->errCode = EINVAL;
+        ERR("failed to set video control value, [HRESULT : 0x%x]\n", hr);
+        return;
+    }
+}
+
+void marucam_device_g_ctrl(MaruCamState *state)
+{
+    HRESULT hr;
+    uint32_t i;
+    long property, get_val;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    switch (param->stack[0]) {
+    case V4L2_CID_BRIGHTNESS:
+        i = 0;
+        property = VideoProcAmp_Brightness;
+        break;
+    case V4L2_CID_CONTRAST:
+        i = 1;
+        property = VideoProcAmp_Contrast;
+        break;
+    case V4L2_CID_SATURATION:
+        i = 2;
+        property = VideoProcAmp_Saturation;
+        break;
+    case V4L2_CID_SHARPNESS:
+        i = 3;
+        property = VideoProcAmp_Sharpness;
+        break;
+    default:
+        param->errCode = EINVAL;
+        return;
+    }
+
+    hr = GetVideoProcAmp(property, &get_val);
+    if (FAILED(hr)) {
+        param->errCode = EINVAL;
+        ERR("failed to get video control value!!!, [HRESULT : 0x%x]\n", hr);
+        return;
+    }
+    param->stack[0] = (uint32_t)value_convert_to_guest(qctrl_tbl[i].min,
+                qctrl_tbl[i].max, get_val);
+}
+
+void marucam_device_enum_fsizes(MaruCamState *state)
+{
+    uint32_t index, pixfmt, i;
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+    index = param->stack[0];
+    pixfmt = param->stack[1];
+
+    if (index >= ARRAY_SIZE(supported_dst_frames)) {
+        param->errCode = EINVAL;
+        return;
+    }
+    for (i = 0; i < ARRAY_SIZE(supported_dst_pixfmts); i++) {
+        if (supported_dst_pixfmts[i].fmt == pixfmt) {
+            break;
+        }
+    }
+
+    if (i == ARRAY_SIZE(supported_dst_pixfmts)) {
+        param->errCode = EINVAL;
+        return;
+    }
+
+    param->stack[0] = supported_dst_frames[index].width;
+    param->stack[1] = supported_dst_frames[index].height;
+}
+
+void marucam_device_enum_fintv(MaruCamState *state)
+{
+    MaruCamParam *param = state->param;
+
+    param->top = 0;
+
+    /* switch by index(param->stack[0]) */
+    switch (param->stack[0]) {
+    case 0:
+        param->stack[1] = 30; /* denominator */
+        break;
+    default:
+        param->errCode = EINVAL;
+        return;
+    }
+    param->stack[0] = 1; /* numerator */
+}
+
+void yuyv_to_yuv420(const unsigned char *src, unsigned char *dest,
+        uint32_t width, uint32_t height, uint32_t yvu)
+{
+    uint32_t i, j;
+    const unsigned char *src1;
+    unsigned char *udest, *vdest;
+
+    /* copy the Y values */
+    src1 = src;
+    for (i = 0; i < height; i++) {
+        for (j = 0; j < width; j += 2) {
+            *dest++ = src1[0];
+            *dest++ = src1[2];
+            src1 += 4;
+        }
+    }
+
+    /* copy the U and V values */
+    src++;              /* point to V */
+    src1 = src + width * 2;     /* next line */
+    if (yvu) {
+        vdest = dest;
+        udest = dest + width * height / 4;
+    } else {
+        udest = dest;
+        vdest = dest + width * height / 4;
+    }
+    for (i = 0; i < height; i += 2) {
+        for (j = 0; j < width; j += 2) {
+            *udest++ = ((int) src[0] + src1[0]) / 2;    /* U */
+            *vdest++ = ((int) src[2] + src1[2]) / 2;    /* V */
+            src += 4;
+            src1 += 4;
+        }
+        src = src1;
+        src1 += width * 2;
+    }
+}
+
+#define RGB2Y(r, g, b, y)   \
+    (y) = ((8453 * (r) + 16594 * (g) + 3223 * (b) + 524288) >> 15)
+
+#define RGB2UV(r, g, b, u, v)   \
+    do {    \
+        (u) = ((-4878 * (r) - 9578 * (g) + 14456 * (b) + 4210688) >> 15);   \
+        (v) = ((14456 * (r) - 12105 * (g) - 2351 * (b) + 4210688) >> 15);   \
+    } while (0)
+
+#define CLIP(color) \
+    (unsigned char)(((color) > 0xFF) ? 0xff : (((color) < 0) ? 0 : (color)))
+
+void rgb24_to_yuv420(const unsigned char *src, unsigned char *dest,
+                     uint32_t width, uint32_t height, uint32_t yvu)
+{
+    uint32_t x, y;
+    uint32_t halfWidth;
+    uint8_t *yplane, *uplane, *vplane;
+    uint8_t *yline, *uline, *vline;
+    const uint8_t *rgbIndex;
+
+    halfWidth = width >> 1;
+    yplane = dest;
+
+    if (yvu) {
+        vplane = dest + width * height;
+        uplane = vplane + ((width * height) >> 2);
+    } else {
+        uplane = dest + width * height;
+        vplane = uplane + ((width * height) >> 2);
+    }
+
+    for (y = 0; y < height; y++) {
+        yline = yplane + (y * width);
+        uline = uplane + ((y >> 1) * halfWidth);
+        vline = vplane + ((y >> 1) * halfWidth);
+
+        rgbIndex = src + (width * (height - 1 - y) * 3);
+        for (x = 0; x < (int)width; x+=2) {
+            RGB2Y(rgbIndex[2], rgbIndex[1], rgbIndex[0], *yline++);
+            rgbIndex += 3;
+            RGB2Y(rgbIndex[2], rgbIndex[1], rgbIndex[0], *yline++);
+            RGB2UV(rgbIndex[2], rgbIndex[1], rgbIndex[0], *uline++, *vline++);
+            rgbIndex += 3;
+        }
+    }
+}
+
+void rgb24_to_yuyv(unsigned char *src, unsigned char *dest,
+                   uint32_t width, uint32_t height)
+{
+    uint32_t i, j;
+    uint8_t *ptr;
+
+    for (i = 0; i < height; i++) {
+        ptr = src + (width * (height - 1 - i) * 3);
+        for (j = 0; j < width; j += 2) {
+            /* y */
+            *dest++ = CLIP(0.299 * (ptr[2] - 128) +
+                           0.587 * (ptr[1] - 128) +
+                           0.114 * (ptr[0] - 128) + 128);
+            /* u */
+            *dest++ = CLIP(((-0.147 * (ptr[2] - 128) -
+                           0.289 * (ptr[1] - 128) +
+                           0.436 * (ptr[0] - 128) + 128) +
+                           (-0.147 * (ptr[5] - 128) -
+                           0.289 * (ptr[4] - 128) +
+                           0.436 * (ptr[3] - 128) + 128)) / 2);
+            /* y1 */
+            *dest++ = CLIP(0.299 * (ptr[5] - 128) +
+                           0.587 * (ptr[4] - 128) +
+                           0.114 * (ptr[3] - 128) + 128);
+            /* v */
+            *dest++ = CLIP(((0.615 * (ptr[2] - 128) -
+                           0.515 * (ptr[1] - 128) -
+                           0.100 * (ptr[0] - 128) + 128) +
+                           (0.615 * (ptr[5] - 128) -
+                           0.515 * (ptr[4] - 128) -
+                           0.100 * (ptr[3] - 128) + 128)) / 2);
+            ptr += 6;
+        }
+    }
+}
+
+void yuv420_to_yvu420(unsigned char *src, unsigned char *dest,
+                      uint32_t width, uint32_t height)
+{
+    unsigned char *psrc_y, *pdst_y;
+    unsigned char *psrc_u, *pdst_u;
+    unsigned char *psrc_v, *pdst_v;
+
+    psrc_y = src;
+    psrc_u = psrc_y + (width * height);
+    psrc_v = psrc_u + (width * height / 4);
+
+    pdst_y = dest;
+    pdst_v = pdst_y + (width * height);
+    pdst_u = pdst_v + (width * height / 4);
+
+    memcpy(pdst_y, psrc_y, width * height);
+    memcpy(pdst_v, psrc_v, width * height / 4);
+    memcpy(pdst_u, psrc_u, width * height / 4);
+}
+
+void yuv420_to_yuyv(unsigned char *src, unsigned char *dest,
+                    uint32_t width, uint32_t height)
+{
+    unsigned char *py;
+    unsigned char *pu;
+    unsigned char *pv;
+
+    uint32_t linesize = width * 2;
+    uint32_t uvlinesize = width / 2;
+    uint32_t offset = 0;
+    uint32_t offset1 = 0;
+    uint32_t offsety = 0;
+    uint32_t offsety1 = 0;
+    uint32_t offsetuv = 0;
+    uint32_t h = 0;
+    uint32_t w = 0;
+    uint32_t wy = 0;
+    uint32_t huv = 0;
+    uint32_t wuv = 0;
+
+    py = src;
+    pu = py + (width * height);
+    pv = pu + (width * height / 4);
+
+    for (h = 0; h < height; h += 2) {
+        wy = 0;
+        wuv = 0;
+        offset = h * linesize;
+        offset1 = (h + 1) * linesize;
+        offsety = h * width;
+        offsety1 = (h + 1) * width;
+        offsetuv = huv * uvlinesize;
+
+        for (w = 0; w < linesize; w += 4) {
+            /* y00 */
+            dest[w + offset] = py[wy + offsety];
+            /* u0 */
+            dest[(w + 1) + offset] = pu[wuv + offsetuv];
+            /* y01 */
+            dest[(w + 2) + offset] = py[(wy + 1) + offsety];
+            /* v0 */
+            dest[(w + 3) + offset] = pv[wuv + offsetuv];
+
+            /* y10 */
+            dest[w + offset1] = py[wy + offsety1];
+            /* u0 */
+            dest[(w + 1) + offset1] = pu[wuv + offsetuv];
+            /* y11 */
+            dest[(w + 2) + offset1] = py[(wy + 1) + offsety1];
+            /* v0 */
+            dest[(w + 3) + offset1] = pv[wuv + offsetuv];
+
+            wuv++;
+            wy += 2;
+        }
+        huv++;
+    }
+}
diff --git a/tizen/src/hw/pci/maru_codec.c b/tizen/src/hw/pci/maru_codec.c
new file mode 100644 (file)
index 0000000..2c9b2db
--- /dev/null
@@ -0,0 +1,1690 @@
+/*
+ * Virtual Codec device
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Kitae Kim <kt920.kim@samsung.com>
+ *  SeokYeon Hwang <syeon.hwang@samsung.com>
+ *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ *  DongKyun Yun
+ *
+ * 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 "maru_codec.h"
+#include "qemu-common.h"
+
+#define MARU_CODEC_DEV_NAME     "codec"
+#define MARU_CODEC_VERSION      14
+
+/*  Needs 16M to support 1920x1080 video resolution.
+ *  Output size for encoding has to be greater than (width * height * 6)
+ */
+#define MARU_CODEC_MEM_SIZE     (2 * 16 * 1024 * 1024)
+#define MARU_CODEC_REG_SIZE     (256)
+#define MARU_CODEC_IRQ 0x7f
+
+#define GEN_MASK(x) ((1<<(x))-1)
+#define ROUND_UP_X(v, x) (((v) + GEN_MASK(x)) & ~GEN_MASK(x))
+#define ROUND_UP_2(x) ROUND_UP_X(x, 1)
+#define ROUND_UP_4(x) ROUND_UP_X(x, 2)
+#define ROUND_UP_8(x) ROUND_UP_X(x, 3)
+#define DIV_ROUND_UP_X(v, x) (((v) + GEN_MASK(x)) >> (x))
+
+typedef struct PixFmtInfo {
+    uint8_t x_chroma_shift;
+    uint8_t y_chroma_shift;
+} PixFmtInfo;
+
+static PixFmtInfo pix_fmt_info[PIX_FMT_NB];
+
+/* define debug channel */
+MULTI_DEBUG_CHANNEL(qemu, marucodec);
+
+void codec_thread_init(SVCodecState *s)
+{
+    int index = 0;
+    QemuThread *pthread = NULL;
+    TRACE("Enter, %s\n", __func__);
+
+    pthread = g_malloc0(sizeof(QemuThread) * CODEC_MAX_THREAD);
+    if (!pthread) {
+        ERR("Failed to allocate wrk_thread memory.\n");
+        return;
+    }
+    qemu_cond_init(&s->codec_thread.cond);
+    qemu_mutex_init(&s->codec_thread.mutex);
+
+    qemu_mutex_lock(&s->thread_mutex);
+    s->isrunning = 1;
+    qemu_mutex_unlock(&s->thread_mutex);
+
+    for (; index < CODEC_MAX_THREAD; index++) {
+        qemu_thread_create(&pthread[index], codec_worker_thread, (void *)s,
+            QEMU_THREAD_JOINABLE);
+    }
+
+    s->codec_thread.wrk_thread = pthread;
+    TRACE("Leave, %s\n", __func__);
+}
+
+void codec_thread_exit(SVCodecState *s)
+{
+    TRACE("Enter, %s\n", __func__);
+    int index;
+
+    /* stop to run dedicated threads. */
+    s->isrunning = 0;
+
+    for (index = 0; index < CODEC_MAX_THREAD; index++) {
+        qemu_thread_join(&s->codec_thread.wrk_thread[index]);
+    }
+
+    TRACE("destroy mutex and conditional.\n");
+    qemu_mutex_destroy(&s->codec_thread.mutex);
+    qemu_cond_destroy(&s->codec_thread.cond);
+
+    TRACE("Leave, %s\n", __func__);
+}
+
+void wake_codec_worker_thread(SVCodecState *s)
+{
+    TRACE("Enter, %s\n", __func__);
+
+    qemu_cond_signal(&s->codec_thread.cond);
+    TRACE("sent a conditional signal to a worker thread.\n");
+
+    TRACE("Leave, %s\n", __func__);
+}
+
+void *codec_worker_thread(void *opaque)
+{
+    SVCodecState *s = (SVCodecState *)opaque;
+    QemuThread thread;
+    AVCodecContext *avctx;
+
+    TRACE("Enter, %s\n", __func__);
+    qemu_mutex_lock(&s->thread_mutex);
+
+    while (s->isrunning) {
+        TRACE("wait for conditional signal.\n");
+        qemu_cond_wait(&s->codec_thread.cond, &s->thread_mutex);
+
+        qemu_thread_get_self(&thread);
+#ifdef CONFIG_LINUX
+        TRACE("wake up a worker thread. :%x\n", thread.thread);
+#endif
+        avctx = s->codec_ctx[s->codec_param.ctx_index].avctx;
+        if (avctx) {
+            if (avctx->codec->decode) {
+                decode_codec(s);
+            } else {
+                encode_codec(s);
+            }
+        } else {
+            ERR("there is a synchrous problem "
+                "between each context.\n");
+            continue;
+        }
+
+        s->codec_thread.state = MARU_CODEC_IRQ;
+        qemu_bh_schedule(s->tx_bh);
+    }
+    qemu_mutex_unlock(&s->thread_mutex);
+    TRACE("Leave, %s\n", __func__);
+
+    return NULL;
+}
+
+int decode_codec(SVCodecState *s)
+{
+    AVCodecContext *avctx;
+    uint32_t len = 0, ctx_index;
+
+    TRACE("Enter, %s\n", __func__);
+
+    qemu_mutex_lock(&s->codec_thread.mutex);
+    ctx_index = s->codec_param.ctx_index;
+    qemu_mutex_unlock(&s->codec_thread.mutex);
+
+    avctx = s->codec_ctx[ctx_index].avctx;
+    if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
+        len = qemu_avcodec_decode_video(s, ctx_index);
+    } else {
+        len = qemu_avcodec_decode_audio(s, ctx_index);
+    }
+
+    TRACE("Leave, %s\n", __func__);
+    return len;
+}
+
+int encode_codec(SVCodecState *s)
+{
+    AVCodecContext *avctx;
+    uint32_t len = 0, ctx_index;
+
+    TRACE("Enter, %s\n", __func__);
+
+    qemu_mutex_unlock(&s->thread_mutex);
+
+    ctx_index = s->codec_param.ctx_index;
+    avctx = s->codec_ctx[ctx_index].avctx;
+    if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
+        len = qemu_avcodec_encode_video(s, ctx_index);
+    } else {
+        len = qemu_avcodec_encode_audio(s, ctx_index);
+    }
+
+    qemu_mutex_lock(&s->thread_mutex);
+
+    TRACE("Leave, %s\n", __func__);
+    return len;
+}
+
+static int qemu_serialize_rational(const AVRational *elem, uint8_t *buff)
+{
+    int size = 0;
+
+    memcpy(buff + size, &elem->num, sizeof(elem->num));
+    size += sizeof(elem->num);
+    memcpy(buff + size, &elem->den, sizeof(elem->den));
+    size += sizeof(elem->den);
+
+    return size;
+}
+
+static int qemu_deserialize_rational(const uint8_t *buff, AVRational *elem)
+{
+    int size = 0;
+
+    memset(elem, 0, sizeof(*elem));
+
+    memcpy(&elem->num, buff + size, sizeof(elem->num));
+    size += sizeof(elem->num);
+    memcpy(&elem->den, buff + size, sizeof(elem->den));
+    size += sizeof(elem->den);
+
+    return size;
+}
+
+static int qemu_serialize_frame(const AVFrame *elem, uint8_t *buff)
+{
+    int size = 0;
+
+    memcpy(buff + size, &elem->key_frame, sizeof(elem->key_frame));
+    size += sizeof(elem->key_frame);
+    memcpy(buff + size, &elem->pict_type, sizeof(elem->pict_type));
+    size += sizeof(elem->pict_type);
+    memcpy(buff + size, &elem->pts, sizeof(elem->pts));
+    size += sizeof(elem->pts);
+    memcpy(buff + size, &elem->coded_picture_number,
+            sizeof(elem->coded_picture_number));
+    size += sizeof(elem->coded_picture_number);
+    memcpy(buff + size, &elem->display_picture_number,
+            sizeof(elem->display_picture_number));
+    size += sizeof(elem->display_picture_number);
+    memcpy(buff + size, &elem->quality, sizeof(elem->quality));
+    size += sizeof(elem->quality);
+    memcpy(buff + size, &elem->age, sizeof(elem->age));
+    size += sizeof(elem->age);
+    memcpy(buff + size, &elem->reference, sizeof(elem->reference));
+    size += sizeof(elem->reference);
+    memcpy(buff + size, &elem->reordered_opaque,
+            sizeof(elem->reordered_opaque));
+    size += sizeof(elem->reordered_opaque);
+    memcpy(buff + size, &elem->repeat_pict, sizeof(elem->repeat_pict));
+    size += sizeof(elem->repeat_pict);
+    memcpy(buff + size, &elem->interlaced_frame,
+            sizeof(elem->interlaced_frame));
+    size += sizeof(elem->interlaced_frame);
+
+    return size;
+}
+
+static int qemu_deserialize_frame(const uint8_t *buff, AVFrame *elem)
+{
+    int size = 0;
+
+    memset(elem, 0, sizeof(*elem));
+
+    memcpy(&elem->linesize, buff + size, sizeof(elem->linesize));
+    size += sizeof(elem->linesize);
+    memcpy(&elem->key_frame, buff + size, sizeof(elem->key_frame));
+    size += sizeof(elem->key_frame);
+    memcpy(&elem->pict_type, buff + size, sizeof(elem->pict_type));
+    size += sizeof(elem->pict_type);
+    memcpy(&elem->pts, buff + size, sizeof(elem->pts));
+    size += sizeof(elem->pts);
+    memcpy(&elem->coded_picture_number, buff + size,
+            sizeof(elem->coded_picture_number));
+    size += sizeof(elem->coded_picture_number);
+    memcpy(&elem->display_picture_number, buff + size,
+            sizeof(elem->display_picture_number));
+    size += sizeof(elem->display_picture_number);
+    memcpy(&elem->quality, buff + size, sizeof(elem->quality));
+    size += sizeof(elem->quality);
+    memcpy(&elem->age, buff + size, sizeof(elem->age));
+    size += sizeof(elem->age);
+    memcpy(&elem->reference, buff + size, sizeof(elem->reference));
+    size += sizeof(elem->reference);
+    memcpy(&elem->qstride, buff + size, sizeof(elem->qstride));
+    size += sizeof(elem->qstride);
+    memcpy(&elem->motion_subsample_log2, buff + size,
+            sizeof(elem->motion_subsample_log2));
+    size += sizeof(elem->motion_subsample_log2);
+    memcpy(&elem->error, buff + size, sizeof(elem->error));
+    size += sizeof(elem->error);
+    memcpy(&elem->type, buff + size, sizeof(elem->type));
+    size += sizeof(elem->type);
+    memcpy(&elem->repeat_pict, buff + size, sizeof(elem->repeat_pict));
+    size += sizeof(elem->repeat_pict);
+    memcpy(&elem->qscale_type, buff + size, sizeof(elem->qscale_type));
+    size += sizeof(elem->qscale_type);
+    memcpy(&elem->interlaced_frame, buff + size,
+            sizeof(elem->interlaced_frame));
+    size += sizeof(elem->interlaced_frame);
+    memcpy(&elem->top_field_first, buff + size, sizeof(elem->top_field_first));
+    size += sizeof(elem->top_field_first);
+    memcpy(&elem->palette_has_changed, buff + size,
+            sizeof(elem->palette_has_changed));
+    size += sizeof(elem->palette_has_changed);
+    memcpy(&elem->buffer_hints, buff + size, sizeof(elem->buffer_hints));
+    size += sizeof(elem->buffer_hints);
+    memcpy(&elem->reordered_opaque, buff + size,
+            sizeof(elem->reordered_opaque));
+    size += sizeof(elem->reordered_opaque);
+
+    return size;
+}
+
+void qemu_parser_init(SVCodecState *s, int ctx_index)
+{
+    TRACE("[%s] Enter\n", __func__);
+
+    s->codec_ctx[ctx_index].parser_buf = NULL;
+    s->codec_ctx[ctx_index].parser_use = false;
+
+    TRACE("[%s] Leave\n", __func__);
+}
+
+void qemu_reset_codec_info(SVCodecState *s, uint32_t value)
+{
+    int ctx_idx;
+
+    TRACE("[%s] Enter\n", __func__);
+    qemu_mutex_lock(&s->thread_mutex);
+
+    for (ctx_idx = 0; ctx_idx < CODEC_CONTEXT_MAX; ctx_idx++) {
+        if (s->codec_ctx[ctx_idx].file_index == value) {
+            TRACE("reset %d context\n", ctx_idx);
+            qemu_mutex_unlock(&s->thread_mutex);
+            qemu_av_free(s, ctx_idx);
+            qemu_mutex_lock(&s->thread_mutex);
+            s->codec_ctx[ctx_idx].avctx_use = false;
+            break;
+        }
+    }
+    qemu_parser_init(s, ctx_idx);
+
+    qemu_mutex_unlock(&s->thread_mutex);
+    TRACE("[%s] Leave\n", __func__);
+}
+
+/* void av_register_all() */
+void qemu_av_register_all(void)
+{
+    av_register_all();
+    TRACE("av_register_all\n");
+}
+
+/* int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic) */
+int qemu_avcodec_get_buffer(AVCodecContext *context, AVFrame *picture)
+{
+    int ret;
+    TRACE("avcodec_default_get_buffer\n");
+
+    picture->reordered_opaque = context->reordered_opaque;
+    picture->opaque = NULL;
+
+    ret = avcodec_default_get_buffer(context, picture);
+
+    return ret;
+}
+
+/* void avcodec_default_release_buffer(AVCodecContext *ctx, AVFrame *frame) */
+void qemu_avcodec_release_buffer(AVCodecContext *context, AVFrame *picture)
+{
+    TRACE("avcodec_default_release_buffer\n");
+    avcodec_default_release_buffer(context, picture);
+}
+
+static void qemu_init_pix_fmt_info(void)
+{
+    /* YUV formats */
+    pix_fmt_info[PIX_FMT_YUV420P].x_chroma_shift = 1;
+    pix_fmt_info[PIX_FMT_YUV420P].y_chroma_shift = 1;
+
+    pix_fmt_info[PIX_FMT_YUV422P].x_chroma_shift = 1;
+    pix_fmt_info[PIX_FMT_YUV422P].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_YUV444P].x_chroma_shift = 1;
+    pix_fmt_info[PIX_FMT_YUV444P].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_YUYV422].x_chroma_shift = 1;
+    pix_fmt_info[PIX_FMT_YUYV422].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_YUV410P].x_chroma_shift = 2;
+    pix_fmt_info[PIX_FMT_YUV410P].y_chroma_shift = 2;
+
+    pix_fmt_info[PIX_FMT_YUV411P].x_chroma_shift = 2;
+    pix_fmt_info[PIX_FMT_YUV411P].y_chroma_shift = 0;
+
+    /* JPEG YUV */
+    pix_fmt_info[PIX_FMT_YUVJ420P].x_chroma_shift = 1;
+    pix_fmt_info[PIX_FMT_YUVJ420P].y_chroma_shift = 1;
+
+    pix_fmt_info[PIX_FMT_YUVJ422P].x_chroma_shift = 1;
+    pix_fmt_info[PIX_FMT_YUVJ422P].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_YUVJ444P].x_chroma_shift = 0;
+    pix_fmt_info[PIX_FMT_YUVJ444P].y_chroma_shift = 0;
+
+    /* RGB formats */
+    pix_fmt_info[PIX_FMT_RGB24].x_chroma_shift = 0;
+    pix_fmt_info[PIX_FMT_RGB24].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_BGR24].x_chroma_shift = 0;
+    pix_fmt_info[PIX_FMT_BGR24].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_RGB32].x_chroma_shift = 0;
+    pix_fmt_info[PIX_FMT_RGB32].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_RGB565].x_chroma_shift = 0;
+    pix_fmt_info[PIX_FMT_RGB565].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_RGB555].x_chroma_shift = 0;
+    pix_fmt_info[PIX_FMT_RGB555].y_chroma_shift = 0;
+
+    pix_fmt_info[PIX_FMT_YUVA420P].x_chroma_shift = 1,
+    pix_fmt_info[PIX_FMT_YUVA420P].y_chroma_shift = 1;
+}
+
+static uint8_t *qemu_malloc_avpicture (int picture_size)
+{
+    uint8_t *ptr = NULL;
+
+    ptr = av_mallocz(picture_size);
+    if (!ptr) {
+        ERR("failed to allocate memory.\n");
+        return NULL;
+    }
+
+    return ptr;
+}
+
+static int qemu_avpicture_fill(AVPicture *picture, uint8_t *ptr,
+                                int pix_fmt, int width,
+                                int height, bool encode)
+{
+    int size, w2, h2, size2;
+    int stride, stride2;
+    int fsize;
+    PixFmtInfo *pinfo;
+
+    pinfo = &pix_fmt_info[pix_fmt];
+
+    switch (pix_fmt) {
+    case PIX_FMT_YUV420P:
+    case PIX_FMT_YUV422P:
+    case PIX_FMT_YUV444P:
+    case PIX_FMT_YUV410P:
+    case PIX_FMT_YUV411P:
+    case PIX_FMT_YUVJ420P:
+    case PIX_FMT_YUVJ422P:
+    case PIX_FMT_YUVJ444P:
+        stride = ROUND_UP_4(width);
+        h2 = ROUND_UP_X(height, pinfo->y_chroma_shift);
+        size = stride * h2;
+        w2 = DIV_ROUND_UP_X(width, pinfo->x_chroma_shift);
+        stride2 = ROUND_UP_4(w2);
+        h2 = DIV_ROUND_UP_X(height, pinfo->y_chroma_shift);
+        size2 = stride2 * h2;
+        fsize = size + 2 * size2;
+        TRACE("stride: %d, stride2: %d, size: %d, size2: %d, fsize: %d\n",
+            stride, stride2, size, size2, fsize);
+        if (!encode && !ptr) {
+            ptr = qemu_malloc_avpicture(fsize);
+        }
+        picture->data[0] = ptr;
+        picture->data[1] = picture->data[0] + size;
+        picture->data[2] = picture->data[1] + size2;
+        picture->data[3] = NULL;
+        picture->linesize[0] = stride;
+        picture->linesize[1] = stride2;
+        picture->linesize[2] = stride2;
+        picture->linesize[3] = 0;
+        TRACE("planes %d %d %d\n", 0, size, size + size2);
+        TRACE("strides %d %d %d\n", stride, stride2, stride2);
+        break;
+    case PIX_FMT_YUVA420P:
+        stride = ROUND_UP_4 (width);
+        h2 = ROUND_UP_X (height, pinfo->y_chroma_shift);
+        size = stride * h2;
+        w2 = DIV_ROUND_UP_X (width, pinfo->x_chroma_shift);
+        stride2 = ROUND_UP_4 (w2);
+        h2 = DIV_ROUND_UP_X (height, pinfo->y_chroma_shift);
+        size2 = stride2 * h2;
+        fsize = 2 * size + 2 * size2;
+        TRACE("stride %d, stride2 %d, size %d, size2 %d, fsize %d\n",
+            stride, stride2, size, size2, fsize);
+        if (!encode && !ptr) {
+            ptr = qemu_malloc_avpicture(fsize);
+        }
+        picture->data[0] = ptr;
+        picture->data[1] = picture->data[0] + size;
+        picture->data[2] = picture->data[1] + size2;
+        picture->data[3] = picture->data[2] + size2;
+        picture->linesize[0] = stride;
+        picture->linesize[1] = stride2;
+        picture->linesize[2] = stride2;
+        picture->linesize[3] = stride;
+        TRACE("planes %d %d %d %d\n", 0, size, size + size2, size + 2 * size2);
+        TRACE("strides %d %d %d %d\n", stride, stride2, stride2, stride);
+        break;
+    case PIX_FMT_RGB24:
+    case PIX_FMT_BGR24:
+        stride = ROUND_UP_4 (width * 3);
+        fsize = stride * height;
+        TRACE("stride: %d, fsize: %d\n", stride, fsize);
+        if (!encode && !ptr) {
+            ptr = qemu_malloc_avpicture(fsize);
+        }
+        picture->data[0] = ptr;
+        picture->data[1] = NULL;
+        picture->data[2] = NULL;
+        picture->data[3] = NULL;
+        picture->linesize[0] = stride;
+        picture->linesize[1] = 0;
+        picture->linesize[2] = 0;
+        picture->linesize[3] = 0;
+        break;
+    case PIX_FMT_RGB32:
+        stride = width * 4;
+        fsize = stride * height;
+        TRACE("stride: %d, fsize: %d\n", stride, fsize);
+        if (!encode && !ptr) {
+            ptr = qemu_malloc_avpicture(fsize);
+        }
+        picture->data[0] = ptr;
+        picture->data[1] = NULL;
+        picture->data[2] = NULL;
+        picture->data[3] = NULL;
+        picture->linesize[0] = stride;
+        picture->linesize[1] = 0;
+        picture->linesize[2] = 0;
+        picture->linesize[3] = 0;
+        break;
+    case PIX_FMT_RGB555:
+    case PIX_FMT_RGB565:
+    case PIX_FMT_YUYV422:
+    case PIX_FMT_UYVY422:
+        stride = ROUND_UP_4 (width * 2);
+        fsize = stride * height;
+        TRACE("stride: %d, fsize: %d\n", stride, fsize);
+        if (!encode && !ptr) {
+            ptr = qemu_malloc_avpicture(fsize);
+        }
+        picture->data[0] = ptr;
+        picture->data[1] = NULL;
+        picture->data[2] = NULL;
+        picture->data[3] = NULL;
+        picture->linesize[0] = stride;
+        picture->linesize[1] = 0;
+        picture->linesize[2] = 0;
+        picture->linesize[3] = 0;
+        break;
+    case PIX_FMT_UYYVYY411:
+        /* FIXME, probably not the right stride */
+        stride = ROUND_UP_4 (width);
+        size = stride * height;
+        fsize = size + size / 2;
+        TRACE("stride %d, size %d, fsize %d\n", stride, size, fsize);
+        if (!encode && !ptr) {
+            ptr = qemu_malloc_avpicture(fsize);
+        }
+        picture->data[0] = ptr;
+        picture->data[1] = NULL;
+        picture->data[2] = NULL;
+        picture->data[3] = NULL;
+        picture->linesize[0] = width + width / 2;
+        picture->linesize[1] = 0;
+        picture->linesize[2] = 0;
+        picture->linesize[3] = 0;
+        break;
+    case PIX_FMT_GRAY8:
+        stride = ROUND_UP_4 (width);
+        fsize = stride * height;
+        TRACE("stride %d, fsize %d\n", stride, fsize);
+        if (!encode && !ptr) {
+            ptr = qemu_malloc_avpicture(fsize);
+        }
+        picture->data[0] = ptr;
+        picture->data[1] = NULL;
+        picture->data[2] = NULL;
+        picture->data[3] = NULL;
+        picture->linesize[0] = stride;
+        picture->linesize[1] = 0;
+        picture->linesize[2] = 0;
+        picture->linesize[3] = 0;
+        break;
+    case PIX_FMT_MONOWHITE:
+    case PIX_FMT_MONOBLACK:
+        stride = ROUND_UP_4 ((width + 7) >> 3);
+        fsize = stride * height;
+        TRACE("stride %d, fsize %d\n", stride, fsize);
+        if (!encode && !ptr) {
+            ptr = qemu_malloc_avpicture(fsize);
+        }
+        picture->data[0] = ptr;
+        picture->data[1] = NULL;
+        picture->data[2] = NULL;
+        picture->data[3] = NULL;
+        picture->linesize[0] = stride;
+        picture->linesize[1] = 0;
+        picture->linesize[2] = 0;
+        picture->linesize[3] = 0;
+        break;
+    case PIX_FMT_PAL8:
+        /* already forced to be with stride, so same result as other function */
+        stride = ROUND_UP_4 (width);
+        size = stride * height;
+        fsize = size + 256 * 4;
+        TRACE("stride %d, size %d, fsize %d\n", stride, size, fsize);
+        if (!encode && !ptr) {
+            ptr = qemu_malloc_avpicture(fsize);
+        }
+        picture->data[0] = ptr;
+        picture->data[1] = ptr + size;    /* palette is stored here as 256 32 bit words */
+        picture->data[2] = NULL;
+        picture->data[3] = NULL;
+        picture->linesize[0] = stride;
+        picture->linesize[1] = 4;
+        picture->linesize[2] = 0;
+        picture->linesize[3] = 0;
+        break;
+    default:
+        picture->data[0] = NULL;
+        picture->data[1] = NULL;
+        picture->data[2] = NULL;
+        picture->data[3] = NULL;
+        fsize = -1;
+        ERR("pixel format: %d was wrong.\n", pix_fmt);
+        break;
+    }
+
+    return fsize;
+}
+
+/* int avcodec_open(AVCodecContext *avctx, AVCodec *codec) */
+int qemu_avcodec_open(SVCodecState *s)
+{
+    AVCodecContext *avctx;
+    AVCodec *codec;
+    enum CodecID codec_id;
+    off_t offset;
+    int ret = -1;
+    int bEncode = 0;
+    int size = 0;
+    int ctx_index = 0;
+
+    av_register_all();
+    TRACE("av_register_all\n");
+
+    ctx_index = qemu_avcodec_alloc_context(s);
+    if (ctx_index < 0) {
+        return ret;
+    }
+
+    qemu_mutex_lock(&s->thread_mutex);
+    offset = s->codec_param.mmap_offset;
+    qemu_mutex_unlock(&s->thread_mutex);
+
+    avctx = s->codec_ctx[ctx_index].avctx;
+    if (!avctx) {
+        ERR("[%s] %d of AVCodecContext is NULL!\n", __func__, ctx_index);
+        qemu_mutex_unlock(&s->thread_mutex);
+        return ret;
+    }
+
+    TRACE("[%s] Context Index:%d, offset:%d\n", __func__, ctx_index, offset);
+    memcpy(&avctx->bit_rate, (uint8_t *)s->vaddr + offset, sizeof(int));
+    size = sizeof(int);
+    memcpy(&avctx->bit_rate_tolerance,
+            (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    memcpy(&avctx->flags, (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    size += qemu_deserialize_rational((uint8_t *)s->vaddr + offset + size,
+                                        &avctx->time_base);
+    memcpy(&avctx->width, (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    memcpy(&avctx->height, (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    memcpy(&avctx->gop_size, (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    memcpy(&avctx->pix_fmt, (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    memcpy(&avctx->sample_rate,
+            (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    memcpy(&avctx->channels, (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    memcpy(&avctx->codec_tag, (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    memcpy(&avctx->block_align,
+            (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    memcpy(&avctx->rc_strategy,
+            (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    memcpy(&avctx->strict_std_compliance,
+            (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    memcpy(&avctx->rc_qsquish,
+            (uint8_t *)s->vaddr + offset + size, sizeof(float));
+    size += sizeof(float);
+    size += qemu_deserialize_rational((uint8_t *)s->vaddr + offset + size,
+            &avctx->sample_aspect_ratio);
+    memcpy(&avctx->qmin, (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    memcpy(&avctx->qmax, (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    memcpy(&avctx->pre_me, (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    memcpy(&avctx->trellis, (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    memcpy(&avctx->extradata_size,
+            (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    memcpy(&codec_id, (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    memcpy(&bEncode, (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    TRACE("Context Index:%d, width:%d, height:%d\n",
+            ctx_index, avctx->width, avctx->height);
+
+    if (avctx->extradata_size > 0) {
+        avctx->extradata = (uint8_t *)av_mallocz(avctx->extradata_size +
+                             ROUND_UP_X(FF_INPUT_BUFFER_PADDING_SIZE, 4));
+        memcpy(avctx->extradata,
+                (uint8_t *)s->vaddr + offset + size, avctx->extradata_size);
+        size += avctx->extradata_size;
+    } else {
+        TRACE("[%s] allocate dummy extradata\n", __func__);
+        avctx->extradata =
+                av_mallocz(ROUND_UP_X(FF_INPUT_BUFFER_PADDING_SIZE, 4));
+    }
+
+    if (bEncode) {
+        TRACE("[%s] find encoder :%d\n", __func__, codec_id);
+        codec = avcodec_find_encoder(codec_id);
+    } else {
+        TRACE("[%s] find decoder :%d\n", __func__, codec_id);
+        codec = avcodec_find_decoder(codec_id);
+    }
+
+    if (!codec) {
+        ERR("[%s] failed to find codec of %d\n", __func__, codec_id);
+    }
+
+    if (codec->type == AVMEDIA_TYPE_AUDIO) {
+        s->codec_ctx[ctx_index].mem_index = s->codec_param.mem_index;
+        TRACE("set mem_index: %d into ctx_index: %d.\n",
+            s->codec_ctx[ctx_index].mem_index, ctx_index);
+    }
+
+#if 0
+    avctx->get_buffer = qemu_avcodec_get_buffer;
+    avctx->release_buffer = qemu_avcodec_release_buffer;
+#endif
+
+    ret = avcodec_open(avctx, codec);
+    if (ret != 0) {
+        ERR("[%s] avcodec_open failure, %d\n", __func__, ret);
+    }
+
+    memcpy((uint8_t *)s->vaddr + offset, &ctx_index, sizeof(int));
+    size = sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->pix_fmt, sizeof(int));
+    size += sizeof(int);
+    size += qemu_serialize_rational(&avctx->time_base,
+            (uint8_t *)s->vaddr + offset + size);
+    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->channels, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size,
+            &avctx->sample_fmt, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size,
+            &avctx->codec_type, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->codec_id, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size,
+            &avctx->coded_width, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size,
+            &avctx->coded_height, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size,
+            &avctx->ticks_per_frame, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size,
+            &avctx->chroma_sample_location, sizeof(int));
+    size += sizeof(int);
+#if 0
+    memcpy((uint8_t *)s->vaddr + offset + size,
+            avctx->priv_data, codec->priv_data_size);
+    size += codec->priv_data_size;
+#endif
+    memcpy((uint8_t *)s->vaddr + offset + size, &ret, sizeof(int));
+    size += sizeof(int);
+
+    TRACE("Leave, %s\n", __func__);
+    return ret;
+}
+
+/* int avcodec_close(AVCodecContext *avctx) */
+int qemu_avcodec_close(SVCodecState *s, int ctx_index)
+{
+    AVCodecContext *avctx;
+    off_t offset;
+    int ret = -1;
+
+    TRACE("Enter, %s\n", __func__);
+    qemu_mutex_lock(&s->thread_mutex);
+
+    offset = s->codec_param.mmap_offset;
+
+    avctx = s->codec_ctx[ctx_index].avctx;
+    if (!avctx) {
+        ERR("[%s] %d of AVCodecContext is NULL\n", __func__, ctx_index);
+        memcpy((uint8_t *)s->vaddr + offset, &ret, sizeof(int));
+        qemu_mutex_unlock(&s->thread_mutex);
+        return ret;
+    }
+
+    ret = avcodec_close(avctx);
+    TRACE("after avcodec_close. ret:%d\n", ret);
+
+    memcpy((uint8_t *)s->vaddr + offset, &ret, sizeof(int));
+
+    qemu_mutex_unlock(&s->thread_mutex);
+
+    TRACE("[%s] Leave\n", __func__);
+    return ret;
+}
+
+/* AVCodecContext* avcodec_alloc_context (void) */
+int qemu_avcodec_alloc_context(SVCodecState *s)
+{
+    int index;
+
+    TRACE("[%s] Enter\n", __func__);
+
+    for (index = 0; index < CODEC_CONTEXT_MAX; index++) {
+        if (s->codec_ctx[index].avctx_use == false) {
+            TRACE("Succeeded to get %d of context.\n", index);
+            s->codec_ctx[index].avctx_use = true;
+            break;
+        }
+        TRACE("Failed to get context.\n");
+    }
+
+    if (index == CODEC_CONTEXT_MAX) {
+        ERR("Failed to get available codec context.");
+        ERR(" Try to run codec again.\n");
+        return -1;
+    }
+
+    TRACE("allocate %d of context and frame.\n", index);
+    s->codec_ctx[index].avctx = avcodec_alloc_context();
+    s->codec_ctx[index].frame = avcodec_alloc_frame();
+
+    s->codec_ctx[index].file_index = s->codec_param.file_index;
+    qemu_parser_init(s, index);
+    qemu_init_pix_fmt_info();
+
+    TRACE("[%s] Leave\n", __func__);
+
+    return index;
+}
+
+/* void av_free(void *ptr) */
+void qemu_av_free(SVCodecState *s, int ctx_index)
+{
+    AVCodecContext *avctx;
+    AVFrame *avframe;
+
+    TRACE("enter %s\n", __func__);
+    qemu_mutex_lock(&s->thread_mutex);
+
+    avctx = s->codec_ctx[ctx_index].avctx;
+    avframe = s->codec_ctx[ctx_index].frame;
+
+    if (avctx && avctx->palctrl) {
+        av_free(avctx->palctrl);
+        avctx->palctrl = NULL;
+    }
+
+    if (avctx && avctx->extradata) {
+        TRACE("free extradata\n");
+        av_free(avctx->extradata);
+        avctx->extradata = NULL;
+    }
+
+    if (avctx && avctx->codec_type == AVMEDIA_TYPE_AUDIO) {
+        int audio_idx = s->codec_ctx[ctx_index].mem_index;
+        TRACE("reset audio mem_idex: %d\n", __LINE__, audio_idx);
+        s->audio_codec_offset[audio_idx] = 0;
+    }
+
+    if (avctx) {
+        TRACE("free codec context of %d.\n", ctx_index);
+        av_free(avctx);
+        s->codec_ctx[ctx_index].avctx = NULL;
+    }
+
+    if (avframe) {
+        TRACE("free codec frame of %d.\n", ctx_index);
+        av_free(avframe);
+        s->codec_ctx[ctx_index].frame = NULL;
+    }
+
+    qemu_mutex_unlock(&s->thread_mutex);
+    TRACE("leave %s\n", __func__);
+}
+
+/* void avcodec_flush_buffers(AVCodecContext *avctx) */
+void qemu_avcodec_flush_buffers(SVCodecState *s, int ctx_index)
+{
+    AVCodecContext *avctx;
+
+    TRACE("Enter\n");
+    qemu_mutex_lock(&s->thread_mutex);
+
+    avctx = s->codec_ctx[ctx_index].avctx;
+    if (avctx) {
+        avcodec_flush_buffers(avctx);
+    } else {
+        ERR("[%s] %d of AVCodecContext is NULL\n", __func__, ctx_index);
+    }
+
+    qemu_mutex_unlock(&s->thread_mutex);
+    TRACE("[%s] Leave\n", __func__);
+}
+
+/* int avcodec_decode_video(AVCodecContext *avctx, AVFrame *picture,
+ *                          int *got_picture_ptr, const uint8_t *buf,
+ *                          int buf_size)
+ */
+int qemu_avcodec_decode_video(SVCodecState *s, int ctx_index)
+{
+    AVCodecContext *avctx;
+    AVFrame *picture;
+    AVPacket avpkt;
+    int got_picture_ptr;
+    uint8_t *buf;
+    uint8_t *parser_buf;
+    bool parser_use;
+    int buf_size;
+    int size = 0;
+    int ret = -1;
+    off_t offset;
+
+    TRACE("Enter, %s\n", __func__);
+    qemu_mutex_lock(&s->codec_thread.mutex);
+
+    TRACE("[%s] Video Context Index : %d\n", __func__, ctx_index);
+
+    avctx = s->codec_ctx[ctx_index].avctx;
+    picture = s->codec_ctx[ctx_index].frame;
+    if (!avctx || !picture) {
+        ERR("[%s] %d of Context or Frame is NULL!\n", __func__, ctx_index);
+        qemu_mutex_unlock(&s->codec_thread.mutex);
+        return ret;
+    }
+
+    offset = s->codec_param.mmap_offset;
+
+    parser_buf = s->codec_ctx[ctx_index].parser_buf;
+    parser_use = s->codec_ctx[ctx_index].parser_use;
+    TRACE("[%s] Parser Buffer : %p, Parser:%d\n", __func__,
+            parser_buf, parser_use);
+
+    memcpy(&avctx->reordered_opaque,
+            (uint8_t *)s->vaddr + offset, sizeof(int64_t));
+    size = sizeof(int64_t);
+    memcpy(&avctx->skip_frame,
+            (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+    memcpy(&buf_size, (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+
+    picture->reordered_opaque = avctx->reordered_opaque;
+
+    if (parser_buf && parser_use) {
+        buf = parser_buf;
+    } else if (buf_size > 0) {
+        TRACE("[%s] not use parser, codec_id:%x\n", __func__, avctx->codec_id);
+        buf = (uint8_t *)s->vaddr + offset + size;
+        size += buf_size;
+    } else {
+        TRACE("There is no input buffer\n");
+        buf = NULL;
+    }
+
+    memset(&avpkt, 0, sizeof(AVPacket));
+    avpkt.data = buf;
+    avpkt.size = buf_size;
+    TRACE("packet buf:%p, size:%d\n", buf, buf_size);
+
+    ret = avcodec_decode_video2(avctx, picture, &got_picture_ptr, &avpkt);
+
+    TRACE("[%s] after decoding video, ret:%d\n", __func__, ret);
+    if (ret < 0) {
+        ERR("[%s] failed to decode video!!, ret:%d\n", __func__, ret);
+    } else {
+        if (ret == 0) {
+            TRACE("[%s] no frame. packet size:%d\n", __func__, avpkt.size);
+        }
+        TRACE("decoded frame number:%d\n", avctx->frame_number);
+    }
+
+    memcpy((uint8_t *)s->vaddr + offset, &avctx->pix_fmt, sizeof(int));
+    size = sizeof(int);
+    size += qemu_serialize_rational(&avctx->time_base,
+                                    (uint8_t *)s->vaddr + offset + size);
+    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->width, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->height, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size,
+            &avctx->has_b_frames, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size,
+            &avctx->frame_number, sizeof(int));
+    size += sizeof(int);
+    size += qemu_serialize_rational(&avctx->sample_aspect_ratio,
+                                    (uint8_t *)s->vaddr + offset + size);
+    memcpy((uint8_t *)s->vaddr + offset + size,
+            &avctx->internal_buffer_count, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->profile, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->level, sizeof(int));
+    size += sizeof(int);
+    size += qemu_serialize_frame(picture, (uint8_t *)s->vaddr + offset + size);
+
+    memcpy((uint8_t *)s->vaddr + offset + size, &got_picture_ptr, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size, &ret, sizeof(int));
+    size += sizeof(int);
+
+#if 0
+    memcpy((uint8_t *)s->vaddr + offset + size, dst.data[0], numbytes);
+    av_free(buffer);
+
+    if (parser_buf && parser_use) {
+        TRACE("[%s] Free input buffer after decoding video\n", __func__);
+        TRACE("[%s] input buffer : %p, %p\n",
+            __func__, avpkt.data, parser_buf);
+        av_free(avpkt.data);
+        s->codec_ctx[ctx_index].parser_buf = NULL;
+    }
+#endif
+
+    qemu_mutex_unlock(&s->codec_thread.mutex);
+    TRACE("Leave, %s\n", __func__);
+
+    return ret;
+}
+
+/* int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf,
+ *                          int buf_size, const AVFrame *pict)
+ */
+int qemu_avcodec_encode_video(SVCodecState *s, int ctx_index)
+{
+    AVCodecContext *avctx = NULL;
+    AVFrame *pict = NULL;
+    uint8_t *inputBuf = NULL;
+    int outbufSize = 0;
+    int bPict = -1;
+    int size = 0;
+    int ret = -1;
+    off_t offset;
+
+    TRACE("Enter, %s\n", __func__);
+    qemu_mutex_lock(&s->codec_thread.mutex);
+
+    avctx = s->codec_ctx[ctx_index].avctx;
+    pict = s->codec_ctx[ctx_index].frame;
+    if (!avctx || !pict) {
+        ERR("[%s] %d of Context or Frame is NULL\n", __func__, ctx_index);
+        qemu_mutex_unlock(&s->thread_mutex);
+        return ret;
+    }
+
+    offset = s->codec_param.mmap_offset;
+
+    size = sizeof(int);
+    memcpy(&bPict, (uint8_t *)s->vaddr + offset, size);
+    TRACE("[%s] avframe is :%d\n", __func__, bPict);
+
+    if (bPict == 0) {
+        memcpy(&outbufSize, (uint8_t *)s->vaddr + offset + size, size);
+        size += sizeof(int);
+        size +=
+            qemu_deserialize_frame((uint8_t *)s->vaddr + offset + size, pict);
+
+        inputBuf = (uint8_t *)s->vaddr + offset + size;
+        if (!inputBuf) {
+            ERR("[%s] failed to get input buffer\n", __func__);
+            return ret;
+        }
+
+        ret = qemu_avpicture_fill((AVPicture *)pict, inputBuf, avctx->pix_fmt,
+                            avctx->width, avctx->height, true);
+
+        if (ret < 0) {
+            ERR("after avpicture_fill, ret:%d\n", ret);
+        }
+        TRACE("before encode video, ticks_per_frame:%d, pts:%lld\n",
+               avctx->ticks_per_frame, pict->pts);
+    } else {
+        TRACE("flush encoded buffers\n");
+        pict = NULL;
+    }
+
+    ret = avcodec_encode_video(avctx, (uint8_t *)s->vaddr + offset,
+                                outbufSize, pict);
+    TRACE("encode video, ret:%d, pts:%lld, outbuf size:%d\n",
+            ret, pict->pts, outbufSize);
+
+    if (ret < 0) {
+        ERR("failed to encode video.\n");
+    }
+
+    memcpy((uint8_t *)s->vaddr + offset + outbufSize, &ret, sizeof(int));
+
+    qemu_mutex_unlock(&s->codec_thread.mutex);
+    TRACE("Leave, %s\n", __func__);
+
+    return ret;
+}
+
+/*
+ *  int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
+ *                            int *frame_size_ptr, AVPacket *avpkt)
+ */
+int qemu_avcodec_decode_audio(SVCodecState *s, int ctx_index)
+{
+    AVCodecContext *avctx;
+    AVPacket avpkt;
+    int16_t *samples;
+    int frame_size_ptr;
+    uint8_t *buf;
+    uint8_t *parser_buf;
+    bool parser_use;
+    int buf_size, outbuf_size;
+    int size;
+    int ret = -1;
+    off_t offset;
+
+    TRACE("Enter, %s\n", __func__);
+
+    TRACE("Audio Context Index : %d\n", ctx_index);
+    avctx = s->codec_ctx[ctx_index].avctx;
+    if (!avctx) {
+        ERR("[%s] %d of Context is NULL!\n", __func__, ctx_index);
+        qemu_mutex_unlock(&s->codec_thread.mutex);
+        return ret;
+    }
+
+    if (!avctx->codec) {
+        ERR("[%s] %d of Codec is NULL\n", __func__, ctx_index);
+        qemu_mutex_unlock(&s->codec_thread.mutex);
+        return ret;
+    }
+
+    offset = s->codec_param.mmap_offset;
+
+    parser_buf = s->codec_ctx[ctx_index].parser_buf;
+    parser_use = s->codec_ctx[ctx_index].parser_use;
+
+    memcpy(&buf_size, (uint8_t *)s->vaddr + offset, sizeof(int));
+    size = sizeof(int);
+    if (parser_buf && parser_use) {
+        TRACE("[%s] use parser, buf:%p codec_id:%x\n",
+                __func__, parser_buf, avctx->codec_id);
+        buf = parser_buf;
+    } else if (buf_size > 0) {
+        TRACE("[%s] not use parser, codec_id:%x\n", __func__, avctx->codec_id);
+        buf = (uint8_t *)s->vaddr + offset + size;
+        size += buf_size;
+    } else {
+        TRACE("no input buffer\n");
+        buf = NULL;
+    }
+
+    av_init_packet(&avpkt);
+    avpkt.data = buf;
+    avpkt.size = buf_size;
+
+    frame_size_ptr = AVCODEC_MAX_AUDIO_FRAME_SIZE;
+    outbuf_size = frame_size_ptr;
+    samples = av_malloc(frame_size_ptr);
+
+    ret = avcodec_decode_audio3(avctx, samples, &frame_size_ptr, &avpkt);
+    TRACE("after decoding audio!, ret:%d\n", ret);
+
+    memcpy((uint8_t *)s->vaddr + offset, &avctx->bit_rate, sizeof(int));
+    size = sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size,
+            &avctx->sample_rate, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->channels, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size,
+        &avctx->channel_layout, sizeof(int64_t));
+    size += sizeof(int64_t);
+    memcpy((uint8_t *)s->vaddr + offset + size, &avctx->sub_id, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size,
+            &avctx->frame_size, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size,
+            &avctx->frame_number, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size, samples, outbuf_size);
+    size += outbuf_size;
+    memcpy((uint8_t *)s->vaddr + offset + size, &frame_size_ptr, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size, &ret, sizeof(int));
+    size += sizeof(int);
+
+    TRACE("before free input buffer and output buffer!\n");
+    if (samples) {
+        TRACE("release allocated audio buffer.\n");
+        av_free(samples);
+        samples = NULL;
+    }
+
+    if (parser_buf && parser_use) {
+        TRACE("[%s] free parser buf\n", __func__);
+        av_free(avpkt.data);
+        s->codec_ctx[ctx_index].parser_buf = NULL;
+    }
+
+    TRACE("[%s] Leave\n", __func__);
+
+    return ret;
+}
+
+int qemu_avcodec_encode_audio(SVCodecState *s, int ctx_index)
+{
+    WARN("[%s] Does not support audio encoder using FFmpeg\n", __func__);
+    return 0;
+}
+
+/* void av_picture_copy(AVPicture *dst, const AVPicture *src,
+ *                      enum PixelFormat pix_fmt, int width, int height)
+ */
+void qemu_av_picture_copy(SVCodecState *s, int ctx_index)
+{
+    AVCodecContext *avctx = NULL;
+    AVPicture dst;
+    AVPicture *src = NULL;
+    int numBytes = 0;
+    uint8_t *buffer = NULL;
+    off_t offset = 0;
+
+    TRACE("Enter :%s\n", __func__);
+    qemu_mutex_lock(&s->thread_mutex);
+
+    avctx = s->codec_ctx[ctx_index].avctx;
+    src = (AVPicture *)s->codec_ctx[ctx_index].frame;
+    if (!avctx && !src) {
+        ERR("[%s] %d of context or frame is NULL\n", __func__, ctx_index);
+        qemu_mutex_unlock(&s->thread_mutex);
+        return;
+    }
+
+    offset = s->codec_param.mmap_offset;
+
+    numBytes = qemu_avpicture_fill(&dst, NULL, avctx->pix_fmt,
+                                  avctx->width, avctx->height, false);
+    TRACE("after avpicture_fill: %d\n", numBytes);
+    if (numBytes < 0) {
+        ERR("picture size:%d is wrong.\n", numBytes);
+        qemu_mutex_unlock(&s->thread_mutex);
+        return;
+    }
+
+    av_picture_copy(&dst, src, avctx->pix_fmt, avctx->width, avctx->height);
+    buffer = dst.data[0];
+    memcpy((uint8_t *)s->vaddr + offset, buffer, numBytes);
+    TRACE("after copy image buffer from host to guest.\n");
+
+    if (buffer) {
+        TRACE("release allocated video frame.\n");
+        av_free(buffer);
+    }
+
+    qemu_mutex_unlock(&s->thread_mutex);
+    TRACE("Leave :%s\n", __func__);
+}
+
+/* AVCodecParserContext *av_parser_init(int codec_id) */
+void qemu_av_parser_init(SVCodecState *s, int ctx_index)
+{
+    AVCodecParserContext *parser_ctx = NULL;
+    AVCodecContext *avctx;
+
+    TRACE("Enter :%s\n", __func__);
+    qemu_mutex_lock(&s->thread_mutex);
+
+    avctx = s->codec_ctx[ctx_index].avctx;
+    if (!avctx) {
+        ERR("[%s] %d of AVCodecContext is NULL!!\n", __func__, ctx_index);
+        qemu_mutex_unlock(&s->thread_mutex);
+        return;
+    }
+
+    TRACE("before av_parser_init, codec_type:%d codec_id:%x\n",
+            avctx->codec_type, avctx->codec_id);
+
+    parser_ctx = av_parser_init(avctx->codec_id);
+    if (parser_ctx) {
+        TRACE("[%s] using parser\n", __func__);
+        s->codec_ctx[ctx_index].parser_use = true;
+    } else {
+        TRACE("[%s] no parser\n", __func__);
+        s->codec_ctx[ctx_index].parser_use = false;
+    }
+    s->codec_ctx[ctx_index].parser_ctx = parser_ctx;
+
+    qemu_mutex_unlock(&s->thread_mutex);
+    TRACE("[%s] Leave\n", __func__);
+}
+
+/* int av_parser_parse(AVCodecParserContext *s, AVCodecContext *avctx,
+ *                     uint8_t **poutbuf, int *poutbuf_size,
+ *                     const uint8_t *buf, int buf_size,
+ *                     int64_t pts, int64_t dts)
+ */
+int qemu_av_parser_parse(SVCodecState *s, int ctx_index)
+{
+    AVCodecParserContext *parser_ctx = NULL;
+    AVCodecContext *avctx = NULL;
+    uint8_t *poutbuf;
+    int poutbuf_size = 0;
+    uint8_t *inbuf = NULL;
+    int inbuf_size;
+    int64_t pts;
+    int64_t dts;
+    int64_t pos;
+    int size, ret = -1;
+    off_t offset;
+
+    TRACE("Enter %s\n", __func__);
+    qemu_mutex_lock(&s->thread_mutex);
+
+    parser_ctx = s->codec_ctx[ctx_index].parser_ctx;
+    avctx = s->codec_ctx[ctx_index].avctx;
+    if (!avctx) {
+        ERR("[%s] %d of AVCodecContext is NULL\n", __func__, ctx_index);
+        qemu_mutex_unlock(&s->thread_mutex);
+        return ret;
+    }
+
+    if (!parser_ctx) {
+        ERR("[%s] %d of AVCodecParserContext is NULL\n", __func__, ctx_index);
+        qemu_mutex_unlock(&s->thread_mutex);
+        return ret;
+    }
+
+    offset = s->codec_param.mmap_offset;
+
+    memcpy(&parser_ctx->pts,
+        (uint8_t *)s->vaddr + offset, sizeof(int64_t));
+    size = sizeof(int64_t);
+    memcpy(&parser_ctx->dts,
+        (uint8_t *)s->vaddr + offset + size, sizeof(int64_t));
+    size += sizeof(int64_t);
+    memcpy(&parser_ctx->pos,
+        (uint8_t *)s->vaddr + offset + size, sizeof(int64_t));
+    size += sizeof(int64_t);
+    memcpy(&pts, (uint8_t *)s->vaddr + offset + size, sizeof(int64_t));
+    size += sizeof(int64_t);
+    memcpy(&dts, (uint8_t *)s->vaddr + offset + size, sizeof(int64_t));
+    size += sizeof(int64_t);
+    memcpy(&pos, (uint8_t *)s->vaddr + offset + size, sizeof(int64_t));
+    size += sizeof(int64_t);
+    memcpy(&inbuf_size, (uint8_t *)s->vaddr + offset + size, sizeof(int));
+    size += sizeof(int);
+
+    if (inbuf_size > 0) {
+        inbuf = av_mallocz(inbuf_size);
+        memcpy(inbuf, (uint8_t *)s->vaddr + offset + size, inbuf_size);
+    } else {
+        inbuf = NULL;
+        INFO("input buffer size for parser is zero.\n");
+    }
+
+    TRACE("[%s] inbuf:%p inbuf_size :%d\n", __func__, inbuf, inbuf_size);
+    ret = av_parser_parse2(parser_ctx, avctx, &poutbuf, &poutbuf_size,
+                           inbuf, inbuf_size, pts, dts, pos);
+    TRACE("after parsing, outbuf size :%d, ret:%d\n", poutbuf_size, ret);
+
+    if (poutbuf) {
+        s->codec_ctx[ctx_index].parser_buf = poutbuf;
+    }
+
+    TRACE("[%s] inbuf : %p, outbuf : %p\n", __func__, inbuf, poutbuf);
+    memcpy((uint8_t *)s->vaddr + offset, &parser_ctx->pts, sizeof(int64_t));
+    size = sizeof(int64_t);
+    memcpy((uint8_t *)s->vaddr + offset + size, &poutbuf_size, sizeof(int));
+    size += sizeof(int);
+    memcpy((uint8_t *)s->vaddr + offset + size, &ret, sizeof(int));
+    size += sizeof(int);
+    if (poutbuf && poutbuf_size > 0) {
+        memcpy((uint8_t *)s->vaddr + offset + size, poutbuf, poutbuf_size);
+    } else {
+        av_free(inbuf);
+    }
+
+#if 0
+    if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
+        TRACE("[%s] free parser inbuf\n", __func__);
+        av_free(inbuf);
+    }
+#endif
+
+    qemu_mutex_unlock(&s->thread_mutex);
+    TRACE("Leave, %s\n", __func__);
+
+    return ret;
+}
+
+/* void av_parser_close(AVCodecParserContext *s) */
+void qemu_av_parser_close(SVCodecState *s, int ctx_index)
+{
+    AVCodecParserContext *parser_ctx;
+
+    TRACE("Enter, %s\n", __func__);
+    qemu_mutex_lock(&s->thread_mutex);
+
+    parser_ctx = s->codec_ctx[ctx_index].parser_ctx;
+    if (!parser_ctx) {
+        ERR("AVCodecParserContext is NULL\n");
+        qemu_mutex_unlock(&s->thread_mutex);
+        return;
+    }
+    av_parser_close(parser_ctx);
+
+    qemu_mutex_unlock(&s->thread_mutex);
+    TRACE("Leave, %s\n", __func__);
+}
+
+int codec_operate(uint32_t api_index, uint32_t ctx_index, SVCodecState *s)
+{
+    int ret = -1;
+
+    TRACE("[%s] context : %d\n", __func__, ctx_index);
+    switch (api_index) {
+    /* FFMPEG API */
+    case EMUL_AV_REGISTER_ALL:
+        qemu_av_register_all();
+        break;
+    case EMUL_AVCODEC_OPEN:
+        ret = qemu_avcodec_open(s);
+        break;
+    case EMUL_AVCODEC_CLOSE:
+        ret = qemu_avcodec_close(s, ctx_index);
+        qemu_av_free(s, ctx_index);
+        break;
+    case EMUL_AVCODEC_FLUSH_BUFFERS:
+        qemu_avcodec_flush_buffers(s, ctx_index);
+        break;
+    case EMUL_AVCODEC_DECODE_VIDEO:
+    case EMUL_AVCODEC_ENCODE_VIDEO:
+    case EMUL_AVCODEC_DECODE_AUDIO:
+    case EMUL_AVCODEC_ENCODE_AUDIO:
+        wake_codec_worker_thread(s);
+        break;
+    case EMUL_AV_PICTURE_COPY:
+        qemu_av_picture_copy(s, ctx_index);
+        break;
+    case EMUL_AV_PARSER_INIT:
+        qemu_av_parser_init(s, ctx_index);
+        break;
+    case EMUL_AV_PARSER_PARSE:
+        ret = qemu_av_parser_parse(s, ctx_index);
+        break;
+    case EMUL_AV_PARSER_CLOSE:
+        qemu_av_parser_close(s, ctx_index);
+        break;
+    default:
+        WARN("api index %d does not exist!.\n", api_index);
+    }
+    return ret;
+}
+
+static uint32_t qemu_get_mmap_offset(SVCodecState *s)
+{
+    int index = 0;
+
+    for (; index < AUDIO_CODEC_MEM_OFFSET_MAX; index++)  {
+        if (s->audio_codec_offset[index] == 0) {
+            s->audio_codec_offset[index] = 1;
+            break;
+        }
+    }
+    TRACE("return mmap offset: %d\n", index);
+
+    return index;
+}
+
+/*
+ *  Codec Device APIs
+ */
+uint64_t codec_read(void *opaque, hwaddr addr, unsigned size)
+{
+    SVCodecState *s = (SVCodecState *)opaque;
+    uint64_t ret = 0;
+
+    switch (addr) {
+    case CODEC_CMD_GET_THREAD_STATE:
+        qemu_mutex_lock(&s->thread_mutex);
+        ret = s->codec_thread.state;
+        s->codec_thread.state = 0;
+        qemu_mutex_unlock(&s->thread_mutex);
+        TRACE("ret: %d, thread state: %d\n", ret, s->codec_thread.state);
+        qemu_irq_lower(s->dev.irq[0]);
+        break;
+    case CODEC_CMD_GET_VERSION:
+        ret = MARU_CODEC_VERSION;
+        TRACE("codec version: %d\n", ret);
+        break;
+    case CODEC_CMD_GET_DEVICE_MEM:
+        qemu_mutex_lock(&s->thread_mutex);
+        ret = s->device_mem_avail;
+        if (s->device_mem_avail != 1) {
+            s->device_mem_avail = 1;
+        }
+        qemu_mutex_unlock(&s->thread_mutex);
+        break;
+    case CODEC_CMD_GET_MMAP_OFFSET:
+        ret = qemu_get_mmap_offset(s);
+        TRACE("mem index: %d\n", ret);
+        break;
+    default:
+        ERR("no avaiable command for read. %d\n", addr);
+    }
+
+    return ret;
+}
+
+void codec_write(void *opaque, hwaddr addr,
+                uint64_t value, unsigned size)
+{
+    SVCodecState *s = (SVCodecState *)opaque;
+
+    switch (addr) {
+    case CODEC_CMD_API_INDEX:
+        codec_operate(value, s->codec_param.ctx_index, s);
+        break;
+    case CODEC_CMD_CONTEXT_INDEX:
+        s->codec_param.ctx_index = value;
+        TRACE("Context Index: %d\n", s->codec_param.ctx_index);
+        break;
+    case CODEC_CMD_FILE_INDEX:
+        s->codec_param.file_index = value;
+        break;
+    case CODEC_CMD_DEVICE_MEM_OFFSET:
+        s->codec_param.mmap_offset = value;
+        TRACE("MMAP Offset: %d\n", s->codec_param.mmap_offset);
+        break;
+    case CODEC_CMD_RESET_CODEC_INFO:
+        qemu_reset_codec_info(s, value);
+        break;
+    case CODEC_CMD_SET_DEVICE_MEM:
+        qemu_mutex_lock(&s->thread_mutex);
+        s->device_mem_avail = value;
+        qemu_mutex_unlock(&s->thread_mutex);
+        break;
+    case CODEC_CMD_SET_MMAP_OFFSET:
+        s->codec_param.mem_index = value;
+        break;
+    default:
+        ERR("no avaiable command for write. %d\n", addr);
+    }
+}
+
+static const MemoryRegionOps codec_mmio_ops = {
+    .read = codec_read,
+    .write = codec_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static void codec_tx_bh(void *opaque)
+{
+    SVCodecState *s = (SVCodecState *)opaque;
+
+    int ctx_index;
+    AVCodecContext *ctx;
+
+    ctx_index = s->codec_param.ctx_index;
+    ctx = s->codec_ctx[ctx_index].avctx;
+
+    TRACE("Enter, %s\n", __func__);
+
+    /* raise irq as soon as a worker thread had finished a job*/
+    if (s->codec_thread.state) {
+        TRACE("raise codec irq. state:%d, codec:%d\n",
+              s->codec_thread.state, ctx->codec_type);
+        qemu_irq_raise(s->dev.irq[0]);
+    }
+
+    TRACE("Leave, %s\n", __func__);
+}
+
+static int codec_initfn(PCIDevice *dev)
+{
+    SVCodecState *s = DO_UPCAST(SVCodecState, dev, dev);
+    uint8_t *pci_conf = s->dev.config;
+
+    INFO("[%s] device init\n", __func__);
+
+    memset(&s->codec_param, 0, sizeof(SVCodecParam));
+
+    qemu_mutex_init(&s->thread_mutex);
+    codec_thread_init(s);
+    s->tx_bh = qemu_bh_new(codec_tx_bh, s);
+
+    pci_config_set_interrupt_pin(pci_conf, 1);
+
+    memory_region_init_ram(&s->vram, OBJECT(s), "codec.ram", MARU_CODEC_MEM_SIZE);
+    s->vaddr = memory_region_get_ram_ptr(&s->vram);
+
+    memory_region_init_io(&s->mmio, OBJECT(s), &codec_mmio_ops, s,
+                        "codec-mmio", MARU_CODEC_REG_SIZE);
+
+    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
+    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);
+
+    return 0;
+}
+
+static void codec_exitfn(PCIDevice *dev)
+{
+    SVCodecState *s = DO_UPCAST(SVCodecState, dev, dev);
+    INFO("[%s] device exit\n", __func__);
+
+    qemu_bh_delete(s->tx_bh);
+
+    memory_region_destroy(&s->vram);
+    memory_region_destroy(&s->mmio);
+}
+
+int codec_init(PCIBus *bus)
+{
+    INFO("[%s] device create\n", __func__);
+    pci_create_simple(bus, -1, MARU_CODEC_DEV_NAME);
+    return 0;
+}
+
+static void codec_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = codec_initfn;
+    k->exit = codec_exitfn;
+    k->vendor_id = PCI_VENDOR_ID_TIZEN;
+    k->device_id = PCI_DEVICE_ID_VIRTUAL_CODEC;
+    k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
+    dc->desc = "Virtual Codec device for Tizen emulator";
+}
+
+static TypeInfo codec_info = {
+    .name          = MARU_CODEC_DEV_NAME,
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(SVCodecState),
+    .class_init    = codec_class_init,
+};
+
+static void codec_register_types(void)
+{
+    type_register_static(&codec_info);
+}
+
+type_init(codec_register_types)
diff --git a/tizen/src/hw/pci/maru_codec.h b/tizen/src/hw/pci/maru_codec.h
new file mode 100644 (file)
index 0000000..999d232
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * Virtual Codec device
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Kitae Kim <kt920.kim@samsung.com>
+ *  SeokYeon Hwang <syeon.hwang@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 <stdio.h>
+#include <sys/types.h>
+#include "hw/hw.h"
+#include "sysemu/kvm.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_ids.h"
+#include "qemu/thread.h"
+#include "debug_ch.h"
+#include "maru_device_ids.h"
+
+#include <libavformat/avformat.h>
+
+#define CODEC_CONTEXT_MAX                      1024
+#define VIDEO_CODEC_MEM_OFFSET_MAX     16
+#define AUDIO_CODEC_MEM_OFFSET_MAX     64
+
+#define CODEC_MAX_THREAD       10
+
+/*
+ *  Codec Device Structures
+ */
+typedef struct _SVCodecParam {
+    uint32_t        api_index;
+    uint32_t        ctx_index;
+    uint32_t        file_index;
+    uint32_t        mem_index;
+    uint32_t        mmap_offset;
+} SVCodecParam;
+
+typedef struct _SVCodecContext {
+    AVCodecContext          *avctx;
+    AVFrame                 *frame;
+    AVCodecParserContext    *parser_ctx;
+    uint8_t                 *parser_buf;
+    uint8_t                 parser_use;
+    uint8_t                 avctx_use;
+    uint32_t                file_index;
+       uint32_t                                mem_index;
+} SVCodecContext;
+
+typedef struct _SVCodecThreadPool {
+       QemuThread                      *wrk_thread;
+       QemuMutex                       mutex;
+       QemuCond                        cond;
+       uint32_t                        state;
+       uint8_t                         isrunning;
+} SVCodecThreadPool;
+
+typedef struct _SVCodecState {
+    PCIDevice           dev;
+
+    uint8_t             *vaddr;
+    MemoryRegion        vram;
+    MemoryRegion        mmio;
+
+    QEMUBH              *tx_bh;
+    QemuMutex           thread_mutex;
+
+    SVCodecContext      codec_ctx[CODEC_CONTEXT_MAX];
+    SVCodecParam        codec_param;
+       SVCodecThreadPool       codec_thread;
+       uint8_t                         audio_codec_offset[AUDIO_CODEC_MEM_OFFSET_MAX];
+       uint8_t                         device_mem_avail;
+       uint8_t                         isrunning;
+} SVCodecState;
+
+enum codec_io_cmd {
+    CODEC_CMD_API_INDEX         = 0x00,
+    CODEC_CMD_CONTEXT_INDEX     = 0x04,
+       CODEC_CMD_FILE_INDEX            = 0x08,
+    CODEC_CMD_DEVICE_MEM_OFFSET        = 0x0c,
+    CODEC_CMD_GET_THREAD_STATE = 0x10,
+    CODEC_CMD_GET_VERSION       = 0x14,
+    CODEC_CMD_GET_DEVICE_MEM    = 0x18,
+    CODEC_CMD_SET_DEVICE_MEM   = 0x1C,
+    CODEC_CMD_GET_MMAP_OFFSET  = 0x20,
+    CODEC_CMD_SET_MMAP_OFFSET  = 0x24,
+    CODEC_CMD_RESET_CODEC_INFO  = 0x28,
+};
+
+enum {
+    EMUL_AV_REGISTER_ALL = 1,
+    EMUL_AVCODEC_OPEN,
+    EMUL_AVCODEC_CLOSE,
+    EMUL_AVCODEC_FLUSH_BUFFERS,
+    EMUL_AVCODEC_DECODE_VIDEO,
+    EMUL_AVCODEC_ENCODE_VIDEO,
+    EMUL_AVCODEC_DECODE_AUDIO,
+    EMUL_AVCODEC_ENCODE_AUDIO,
+    EMUL_AV_PICTURE_COPY,
+    EMUL_AV_PARSER_INIT,
+    EMUL_AV_PARSER_PARSE,
+    EMUL_AV_PARSER_CLOSE,
+};
+
+
+/*
+ *  Codec Thread Functions
+ */
+void codec_thread_init(SVCodecState *s);
+void codec_thread_exit(SVCodecState *s);
+void *codec_worker_thread(void *opaque);
+void wake_codec_worker_thread(SVCodecState *s);
+int decode_codec(SVCodecState *s);
+int encode_codec(SVCodecState *s);
+
+/*
+ *  Codec Device Functions
+ */
+int codec_init(PCIBus *bus);
+uint64_t codec_read(void *opaque, hwaddr addr,
+                    unsigned size);
+void codec_write(void *opaque, hwaddr addr,
+                uint64_t value, unsigned size);
+int codec_operate(uint32_t api_index, uint32_t ctx_index,
+                SVCodecState *state);
+
+/*
+ *  Codec Helper Functions
+ */
+void qemu_parser_init(SVCodecState *s, int ctx_index);
+void qemu_codec_close(SVCodecState *s, uint32_t value);
+void qemu_get_codec_ver(SVCodecState *s);
+void qemu_reset_codec_info(SVCodecState *s, uint32_t value);
+
+/*
+ *  FFMPEG Functions
+ */
+void qemu_av_register_all(void);
+int qemu_avcodec_open(SVCodecState *s);
+int qemu_avcodec_close(SVCodecState *s, int ctx_index);
+int qemu_avcodec_alloc_context(SVCodecState *s);
+void qemu_avcodec_flush_buffers(SVCodecState *s, int ctx_index);
+int qemu_avcodec_decode_video(SVCodecState *s, int ctx_index);
+int qemu_avcodec_encode_video(SVCodecState *s, int ctx_index);
+int qemu_avcodec_decode_audio(SVCodecState *s, int ctx_index);
+int qemu_avcodec_encode_audio(SVCodecState *s, int ctx_index);
+void qemu_av_picture_copy(SVCodecState *s, int ctx_index);
+void qemu_av_parser_init(SVCodecState *s, int ctx_index);
+int qemu_av_parser_parse(SVCodecState *s, int ctx_index);
+void qemu_av_parser_close(SVCodecState *s, int ctx_index);
+int qemu_avcodec_get_buffer(AVCodecContext *context, AVFrame *picture);
+void qemu_avcodec_release_buffer(AVCodecContext *context, AVFrame *picture);
+void qemu_av_free(SVCodecState *s, int ctx_index);
diff --git a/tizen/src/hw/usb/Makefile.objs b/tizen/src/hw/usb/Makefile.objs
new file mode 100644 (file)
index 0000000..ab68d31
--- /dev/null
@@ -0,0 +1 @@
+obj-y += maru_usb_touchscreen.o
diff --git a/tizen/src/hw/usb/maru_usb_touchscreen.c b/tizen/src/hw/usb/maru_usb_touchscreen.c
new file mode 100644 (file)
index 0000000..3f1b7e8
--- /dev/null
@@ -0,0 +1,322 @@
+/*
+ * Maru USB Touchscreen Device
+ * Based on hw/usb-wacom.c:
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  GiWoong Kim <giwoong.kim@samsung.com>
+ *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ *  HyunJun Son
+ *
+ * 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 "maru_usb_touchscreen.h"
+#include "debug_ch.h"
+
+MULTI_DEBUG_CHANNEL(qemu, usb_touchscreen);
+
+
+#define MAX_TOUCH_EVENT_CNT 128
+
+//lock for between communication thread and main thread
+static pthread_mutex_t event_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static QTAILQ_HEAD(, TouchEventEntry) events_queue =
+    QTAILQ_HEAD_INITIALIZER(events_queue);
+
+static unsigned int event_cnt = 0;
+static unsigned int _processed_buf_cnt = 0;
+static TouchEventEntry _event_buf[MAX_TOUCH_EVENT_CNT];
+
+/**
+ * @brief : qemu touch(host mouse) event handler
+ * @param opaque : state of device
+ * @param x : X-axis value
+ * @param y : Y-axis value
+ * @param z : event id for multiple touch
+ */
+static void usb_touchscreen_event(void *opaque, int x, int y, int z, int buttons_state)
+{
+    TouchEventEntry *te;
+    USBTouchscreenState *s = opaque;
+
+    pthread_mutex_lock(&event_mutex);
+    if (event_cnt >= MAX_TOUCH_EVENT_CNT) {
+        pthread_mutex_unlock(&event_mutex);
+        INFO("full touch event queue, lose event\n", event_cnt);
+        return;
+    }
+
+    //using prepared memory
+    te = &(_event_buf[_processed_buf_cnt % MAX_TOUCH_EVENT_CNT]);
+    _processed_buf_cnt++;
+
+    /* mouse event is copied into the queue */
+    te->index = ++event_cnt;
+    te->queue_packet.x = x;
+    te->queue_packet.y = y;
+    te->queue_packet.z = z;
+    te->queue_packet.state = buttons_state;
+
+    QTAILQ_INSERT_TAIL(&events_queue, te, node);
+    s->changed = 1;
+    pthread_mutex_unlock(&event_mutex);
+
+    TRACE("touch event (%d) : x=%d, y=%d, z=%d, state=%d\n", te->index, x, y, z, buttons_state);
+}
+
+/**
+ * @brief : fill the usb packet
+ * @param s : state of device
+ * @param buf : usb packet
+ * @param len : size of packet
+ */
+static int usb_touchscreen_poll(USBTouchscreenState *s, uint8_t *buf, int len)
+{
+    USBEmulTouchscreenPacket *packet = (USBEmulTouchscreenPacket *)buf;
+
+    if (s->mouse_grabbed == 0) {
+        s->eh_entry = qemu_add_mouse_event_handler(usb_touchscreen_event, s, 1, "QEMU USB touchscreen");
+        qemu_activate_mouse_event_handler(s->eh_entry);
+        s->mouse_grabbed = 1;
+    }
+
+    if (len < EMUL_TOUCHSCREEN_PACKET_LEN) {
+        return 0;
+    }
+
+    packet->x = s->dx & 0xffff;
+    packet->y = s->dy & 0xffff;
+    packet->z = s->dz & 0xffff;
+
+    if (s->buttons_state == 0) {
+        packet->state = 0;
+    } else {
+        packet->state = 1;
+    }
+
+    return EMUL_TOUCHSCREEN_PACKET_LEN;
+}
+
+static void usb_touchscreen_handle_reset(USBDevice *dev)
+{
+    USBTouchscreenState *s = (USBTouchscreenState *) dev;
+
+    pthread_mutex_lock(&event_mutex);
+
+    s->dx = 0;
+    s->dy = 0;
+    s->dz = 0;
+    s->buttons_state = 0;
+
+    event_cnt = 0;
+    _processed_buf_cnt = 0;
+
+    pthread_mutex_unlock(&event_mutex);
+}
+
+static void usb_touchscreen_handle_control(USBDevice *dev, USBPacket *p,
+    int request, int value, int index, int length, uint8_t *data)
+{
+    usb_desc_handle_control(dev, p, request, value, index, length, data);
+}
+
+/**
+ * @brief : call by uhci frame timer
+ * @param dev : state of device
+ * @param p : usb packet
+ */
+static void usb_touchscreen_handle_data(USBDevice *dev, USBPacket *p)
+{
+    USBTouchscreenState *s = (USBTouchscreenState *) dev;
+    uint8_t buf[p->iov.size];
+    int len = 0;
+
+    switch (p->pid) {
+    case USB_TOKEN_IN:
+        if (p->ep->nr == 1) {
+            pthread_mutex_lock(&event_mutex);
+
+            if (s->changed == 0) {
+                pthread_mutex_unlock(&event_mutex);
+                TRACE("USB_RET_NAK\n");
+            }
+
+            if (event_cnt != 0) {
+                if (!QTAILQ_EMPTY(&events_queue)) {
+                    TouchEventEntry *te = QTAILQ_FIRST(&events_queue);
+
+                    s->dx = te->queue_packet.x;
+                    s->dy = te->queue_packet.y;
+                    s->dz = te->queue_packet.z;
+                    s->buttons_state = te->queue_packet.state;
+
+                    QTAILQ_REMOVE(&events_queue, te, node);
+                    event_cnt--;
+                    TRACE("processed touch event (%d) : x=%d, y=%d, z=%d, state=%d\n",
+                        te->index, s->dx, s->dy, s->dz, s->buttons_state);
+
+                    if (QTAILQ_EMPTY(&events_queue)) {
+                        s->changed = 0;
+                        TRACE("processed all touch events (%d)\n", event_cnt);
+                    }
+                }
+            } else {
+                s->changed = 0;
+            }
+
+            pthread_mutex_unlock(&event_mutex);
+
+            memset(buf, 0, sizeof(buf));
+            len = usb_touchscreen_poll(s, buf, p->iov.size); //write event to packet
+            usb_packet_copy(p, buf, len);
+            break;
+        }
+        /* Fall through */
+    case USB_TOKEN_OUT:
+    default:
+        TRACE("USB_RET_STALL\n");
+        break;
+    }
+}
+
+static void usb_touchscreen_handle_destroy(USBDevice *dev)
+{
+    USBTouchscreenState *s = (USBTouchscreenState *) dev;
+
+    if (s->mouse_grabbed == 1) {
+        qemu_remove_mouse_event_handler(s->eh_entry);
+        s->mouse_grabbed = 0;
+    }
+}
+
+/**
+ * @brief : initialize a touchscreen device
+ * @param opaque : state of device
+ */
+static int usb_touchscreen_initfn(USBDevice *dev)
+{
+    USBTouchscreenState *s = DO_UPCAST(USBTouchscreenState, dev, dev);
+    usb_desc_init(dev);
+
+    pthread_mutex_lock(&event_mutex);
+    s->changed = 1;
+    pthread_mutex_unlock(&event_mutex);
+
+    return 0;
+}
+
+/**
+ * @brief : remove mouse handlers before loading
+ * @param opaque : state of device
+ */
+static int touchscreen_pre_load(void *opaque)
+{
+    USBTouchscreenState *s = (USBTouchscreenState *)opaque;
+
+    if (s->eh_entry) {
+        qemu_remove_mouse_event_handler(s->eh_entry);
+    }
+
+    return 0;
+}
+
+static int touchscreen_post_load(void *opaque, int version_id)
+{
+    USBTouchscreenState *s = (USBTouchscreenState *)opaque;
+
+    pthread_mutex_lock(&event_mutex);
+    s->changed = 1;
+    pthread_mutex_unlock(&event_mutex);
+
+    if (s->mouse_grabbed == 1) {
+        s->eh_entry = qemu_add_mouse_event_handler(usb_touchscreen_event, s, 1, "QEMU USB touchscreen");
+        qemu_activate_mouse_event_handler(s->eh_entry);
+    }
+
+    return 0;
+}
+
+static VMStateDescription vmsd_usbdevice = {
+    .name = "maru-touchscreen-usbdevice",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields = (VMStateField []) {
+        VMSTATE_UINT8(addr, USBDevice),
+        VMSTATE_INT32(state, USBDevice),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static VMStateDescription vmsd = {
+    .name = "maru-touchscreen",
+    .version_id = 2,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .pre_load = touchscreen_pre_load,
+    .post_load = touchscreen_post_load,
+    .fields = (VMStateField []) {
+        VMSTATE_STRUCT(dev, USBTouchscreenState, 1, vmsd_usbdevice, USBDevice),
+        VMSTATE_INT32(dx, USBTouchscreenState),
+        VMSTATE_INT32(dy, USBTouchscreenState),
+        VMSTATE_INT32(dz, USBTouchscreenState),
+        VMSTATE_INT32(buttons_state, USBTouchscreenState),
+        VMSTATE_INT8(mouse_grabbed, USBTouchscreenState),
+        VMSTATE_INT8(changed, USBTouchscreenState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void usb_touchscreen_class_initfn(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    USBDeviceClass *uc = USB_DEVICE_CLASS(klass);
+
+    uc->handle_reset   = usb_touchscreen_handle_reset;
+    uc->handle_control = usb_touchscreen_handle_control;
+    uc->handle_data    = usb_touchscreen_handle_data;
+    uc->handle_destroy = usb_touchscreen_handle_destroy;
+    uc->init           = usb_touchscreen_initfn;
+    uc->product_desc   = "Maru USB Touchscreen";
+    uc->usb_desc       = &desc_touchscreen;
+    dc->vmsd           = &vmsd;
+    dc->desc           = "Maru USB Touchscreen";
+}
+
+static TypeInfo touchscreen_info = {
+    .name          = "usb-maru-touchscreen",
+    .parent        = TYPE_USB_DEVICE,
+    .instance_size = sizeof(USBTouchscreenState),
+    .class_init    = usb_touchscreen_class_initfn,
+};
+
+/**
+ * @brief : register a touchscreen device
+ */
+static void usb_touchscreen_register_types(void)
+{
+    type_register_static(&touchscreen_info);
+    usb_legacy_register("usb-maru-touchscreen", "maru-touchscreen", NULL);
+}
+
+type_init(usb_touchscreen_register_types)
diff --git a/tizen/src/hw/usb/maru_usb_touchscreen.h b/tizen/src/hw/usb/maru_usb_touchscreen.h
new file mode 100644 (file)
index 0000000..d285cfc
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Maru USB Touchscreen Device
+ * Based on hw/usb-wacom.c:
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  GiWoong Kim <giwoong.kim@samsung.com>
+ *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ *  HyunJun Son
+ *
+ * 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_TOUCH_H_
+#define MARU_TOUCH_H_
+
+#include <pthread.h>
+#include "hw/hw.h"
+#include "ui/console.h"
+#include "hw/usb.h"
+#include "hw/usb/desc.h"
+
+
+typedef struct USBTouchscreenState {
+    USBDevice dev;
+    QEMUPutMouseEntry *eh_entry;
+
+    int32_t dx, dy, dz, buttons_state;
+    int8_t mouse_grabbed;
+    int8_t changed;
+} USBTouchscreenState;
+
+/* This structure must match the kernel definitions */
+typedef struct USBEmulTouchscreenPacket {
+    uint16_t x, y, z;
+    uint8_t state;
+} USBEmulTouchscreenPacket;
+
+
+#define EMUL_TOUCHSCREEN_PACKET_LEN 7
+#define TOUCHSCREEN_RESOLUTION_X 5040
+#define TOUCHSCREEN_RESOLUTION_Y 3780
+
+enum {
+    STR_MANUFACTURER = 1,
+    STR_PRODUCT,
+    STR_SERIALNUMBER,
+};
+
+static const USBDescStrings desc_strings = {
+    [STR_MANUFACTURER]     = "QEMU " QEMU_VERSION,
+    [STR_PRODUCT]          = "Maru USB Touchscreen",
+    [STR_SERIALNUMBER]     = "1",
+};
+
+static const USBDescIface desc_iface_touchscreen = {
+    .bInterfaceNumber              = 0,
+    .bNumEndpoints                 = 1,
+    .bInterfaceClass               = USB_CLASS_HID,
+    .bInterfaceSubClass            = 0x01, /* boot */
+    .bInterfaceProtocol            = 0x02,
+    .ndesc                         = 1,
+    .descs = (USBDescOther[]) {
+        {
+            /* HID descriptor */
+            .data = (uint8_t[]) {
+                0x09,          /*  u8  bLength */
+                0x21,          /*  u8  bDescriptorType */
+                0x01, 0x10,    /*  u16 HID_class */
+                0x00,          /*  u8  country_code */
+                0x01,          /*  u8  num_descriptors */
+                0x22,          /*  u8  type: Report */
+                0x6e, 0,       /*  u16 len */
+            },
+        },
+    },
+    .eps = (USBDescEndpoint[]) {
+        {
+            .bEndpointAddress      = USB_DIR_IN | 0x01,
+            .bmAttributes          = USB_ENDPOINT_XFER_INT,
+            .wMaxPacketSize        = 8,
+            .bInterval             = 0x0a,
+        },
+    },
+};
+
+static const USBDescDevice desc_device_touchscreen = {
+    .bcdUSB                        = 0x0110,
+    .bMaxPacketSize0               = EMUL_TOUCHSCREEN_PACKET_LEN + 1,
+    .bNumConfigurations            = 1,
+    .confs = (USBDescConfig[]) {
+        {
+            .bNumInterfaces        = 1,
+            .bConfigurationValue   = 1,
+            .bmAttributes          = 0x80,
+            .bMaxPower             = 40,
+            .nif = 1,
+            .ifs = &desc_iface_touchscreen,
+        },
+    },
+};
+
+static const USBDesc desc_touchscreen = {
+    .id = {
+        .idVendor          = 0x056a,
+        .idProduct         = 0x0000,
+        .bcdDevice         = 0x0010,
+        .iManufacturer     = STR_MANUFACTURER,
+        .iProduct          = STR_PRODUCT,
+        .iSerialNumber     = STR_SERIALNUMBER,
+    },
+    .full = &desc_device_touchscreen,
+    .str = desc_strings,
+};
+
+typedef struct TouchEventEntry {
+    USBEmulTouchscreenPacket queue_packet;
+    int index;
+
+    /* used internally by qemu for handling mice */
+    QTAILQ_ENTRY(TouchEventEntry) node;
+} TouchEventEntry;
+
+#endif /* MARU_TOUCH_H_ */
diff --git a/tizen/src/hw/virtio/Makefile.objs b/tizen/src/hw/virtio/Makefile.objs
new file mode 100644 (file)
index 0000000..dd29fc4
--- /dev/null
@@ -0,0 +1,11 @@
+obj-y += maru_virtio_pci.o
+obj-y += maru_virtio_touchscreen.o
+obj-y += maru_virtio_esm.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
+obj-y += maru_virtio_vmodem.o
diff --git a/tizen/src/hw/virtio/maru_virtio_esm.c b/tizen/src/hw/virtio/maru_virtio_esm.c
new file mode 100644 (file)
index 0000000..455c33b
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * Virtio EmulatorStatusMedium Device
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  SeokYeon Hwang <syeon.hwang@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 "hw/maru_device_ids.h"
+#include "maru_virtio_esm.h"
+#include "skin/maruskin_server.h"
+#include "emul_state.h"
+#include "debug_ch.h"
+
+MULTI_DEBUG_CHANNEL(qemu, virtio-esm);
+
+
+#define SYSTEM_MODE_LAYER 1
+#define USER_MODE_LAYER 0
+static uint8_t boot_complete;
+
+struct progress_info {
+    char mode;
+    uint16_t percentage;
+};
+
+static VirtQueueElement elem;
+struct progress_info progress;
+
+static void virtio_esm_handle(VirtIODevice *vdev, VirtQueue *vq)
+{
+    VirtIOESM *vesm = VIRTIO_ESM(vdev);
+    int index = 0;
+
+    TRACE("virtqueue handler.\n");
+    if (virtio_queue_empty(vesm->vq)) {
+        INFO("virtqueue is empty.\n");
+        return;
+    }
+
+    // Get a queue buffer.
+    index = virtqueue_pop(vq, &elem);
+    TRACE("virtqueue pop. index: %d\n", index);
+
+    TRACE("virtio element out number : %d\n", elem.out_num);
+    if (elem.out_num != 1) {
+        ERR("virtio element out number is wierd.\n");
+    }
+    else {
+        TRACE("caramis elem.out_sg[0].iov_len : %x\n", elem.out_sg[0].iov_len);
+        TRACE("caramis elem.out_sg[0].iov_base : %x\n", elem.out_sg[0].iov_base);
+        if (elem.out_sg[0].iov_len != 4) {
+            ERR("out lenth is wierd.\n");
+        }
+        else {
+            progress = *((struct progress_info*)elem.out_sg[0].iov_base);
+            TRACE("Boot up progress is [%u] percent done at %s.\n",
+                progress.percentage,
+                progress.mode == 's' || progress.mode == 'S' ? "system mode" : "user mode");
+
+            /* notify to skin */
+            if (progress.mode == 's' || progress.mode == 'S') {
+                if (progress.percentage >= 100) {
+                    boot_complete |= (1 << SYSTEM_MODE_LAYER);
+                }
+
+                notify_booting_progress(SYSTEM_MODE_LAYER, progress.percentage);
+            } else {
+                if (progress.percentage >= 100) {
+                    boot_complete |= (1 << USER_MODE_LAYER);
+                }
+
+                notify_booting_progress(USER_MODE_LAYER, progress.percentage);
+            }
+
+            /* booting complete check */
+            if ((boot_complete & (1 << SYSTEM_MODE_LAYER)) &&
+                (boot_complete & (1 << USER_MODE_LAYER))) {
+                set_emulator_condition(BOOT_COMPLETED);
+            }
+        }
+    }
+
+    // There is no data to copy into guest.
+    virtqueue_push(vesm->vq, &elem, 0);
+    virtio_notify(&vesm->vdev, vesm->vq);
+}
+
+static uint32_t virtio_esm_get_features(VirtIODevice *vdev, uint32_t feature)
+{
+    TRACE("virtio_esm_get_features.\n");
+    return feature;
+}
+
+static void virtio_esm_reset(VirtIODevice* vdev)
+{
+    TRACE("virtio_esm_reset.\n");
+
+    progress.mode = '\0';
+    progress.percentage = 0;
+}
+
+
+static void virtio_esm_device_realize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    VirtIOESM *vesm = VIRTIO_ESM(dev);
+
+    INFO("initialize virtio-esm device\n");
+    virtio_init(vdev, "virtio-esm", VIRTIO_ID_ESM, 0);
+
+    vesm->vq = virtio_add_queue(vdev, 1, virtio_esm_handle);
+
+    virtio_esm_reset(vdev);
+}
+
+static void virtio_esm_device_unrealize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+
+    INFO("destroy device\n");
+    virtio_cleanup(vdev);
+}
+
+static void virtio_esm_class_init(ObjectClass *klass, void *data)
+{
+    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+    vdc->realize = virtio_esm_device_realize;
+    vdc->unrealize = virtio_esm_device_unrealize;
+    vdc->get_features = virtio_esm_get_features;
+    // This device is no need to reset.
+    //vdc->reset = virtio_esm_reset;
+}
+
+static const TypeInfo virtio_device_info = {
+    .name = TYPE_VIRTIO_ESM,
+    .parent = TYPE_VIRTIO_DEVICE,
+    .instance_size = sizeof(VirtIOESM),
+    .class_init = virtio_esm_class_init,
+};
+
+static void virtio_register_types(void)
+{
+    type_register_static(&virtio_device_info);
+}
+
+type_init(virtio_register_types)
diff --git a/tizen/src/hw/virtio/maru_virtio_esm.h b/tizen/src/hw/virtio/maru_virtio_esm.h
new file mode 100644 (file)
index 0000000..934dfe9
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ * Virtio EmulatorStatusMedium Device
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  SeokYeon Hwang <syeon.hwang@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_VIRTIO_ESM_H_
+#define MARU_VIRTIO_ESM_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "hw/virtio/virtio.h"
+
+#define TYPE_VIRTIO_ESM "virtio-esm-device"
+#define VIRTIO_ESM(obj) \
+        OBJECT_CHECK(VirtIOESM, (obj), TYPE_VIRTIO_ESM)
+
+typedef struct VirtIOEmulatorStatusMedium {
+    VirtIODevice    vdev;
+    VirtQueue       *vq;
+    DeviceState     *qdev;
+} VirtIOESM;
+
+VirtIODevice *virtio_esm_init(DeviceState *dev);
+
+void virtio_esm_exit(VirtIODevice *vdev);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MARU_VIRTIO_ESM_H_ */
diff --git a/tizen/src/hw/virtio/maru_virtio_evdi.c b/tizen/src/hw/virtio/maru_virtio_evdi.c
new file mode 100644 (file)
index 0000000..d3ff432
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * Virtio EmulatorVirtualDeviceInterface Device
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  DaiYoung Kim <daiyoung777.kim.hwang@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 "hw/maru_device_ids.h"
+#include "maru_virtio_evdi.h"
+#include "debug_ch.h"
+#include "ecs/ecs.h"
+
+MULTI_DEBUG_CHANNEL(qemu, virtio-evdi);
+
+#define EVDI_DEVICE_NAME "virtio-evdi"
+
+enum {
+    IOTYPE_INPUT = 0,
+    IOTYPE_OUTPUT = 1
+};
+
+
+#ifndef min
+#define min(a,b) ((a)<(b)?(a):(b))
+#endif
+
+
+VirtIOEVDI* vio_evdi;
+
+//
+
+typedef struct MsgInfo
+{
+    msg_info info;
+    QTAILQ_ENTRY(MsgInfo) next;
+}MsgInfo;
+
+static QTAILQ_HEAD(MsgInfoRecvHead , MsgInfo) evdi_recv_msg_queue =
+    QTAILQ_HEAD_INITIALIZER(evdi_recv_msg_queue);
+
+//
+
+typedef struct EvdiBuf {
+    VirtQueueElement elem;
+
+    QTAILQ_ENTRY(EvdiBuf) next;
+} EvdiBuf;
+
+static QTAILQ_HEAD(EvdiMsgHead , EvdiBuf) evdi_in_queue =
+    QTAILQ_HEAD_INITIALIZER(evdi_in_queue);
+
+
+static pthread_mutex_t recv_buf_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+bool send_to_evdi(const uint32_t route, char* data, const uint32_t len)
+{
+    int size;
+    int left = len;
+    int count = 0;
+    char* readptr = data;
+
+    if(vio_evdi == NULL) {
+        ERR("EVDI is not initialized\n");
+        return false;
+    }
+
+    if (unlikely(!virtio_queue_ready(vio_evdi->rvq))) {
+        ERR("virtio queue is not ready\n");
+        return false;
+    }
+
+    while (left > 0)
+    {
+        MsgInfo* _msg = (MsgInfo*) malloc(sizeof(MsgInfo));
+        if (!_msg)
+            return false;
+
+        memset(&_msg->info, 0, sizeof(msg_info));
+
+        size = min(left, __MAX_BUF_SIZE);
+        memcpy(_msg->info.buf, readptr, size);
+        readptr += size;
+        _msg->info.use = size;
+        _msg->info.index = count;
+
+        pthread_mutex_lock(&recv_buf_mutex);
+
+        QTAILQ_INSERT_TAIL(&evdi_recv_msg_queue, _msg, next);
+
+        pthread_mutex_unlock(&recv_buf_mutex);
+
+        left -= size;
+        count ++;
+    }
+
+    qemu_bh_schedule(vio_evdi->bh);
+
+    return true;
+}
+
+
+static void flush_evdi_recv_queue(void)
+{
+    int index;
+
+    if (unlikely(!virtio_queue_ready(vio_evdi->rvq))) {
+        INFO("virtio queue is not ready\n");
+        return;
+    }
+
+    if (unlikely(virtio_queue_empty(vio_evdi->rvq))) {
+        TRACE("virtqueue is empty\n");
+        return;
+    }
+
+
+    pthread_mutex_lock(&recv_buf_mutex);
+
+    while (!QTAILQ_EMPTY(&evdi_recv_msg_queue))
+    {
+         MsgInfo* msginfo = QTAILQ_FIRST(&evdi_recv_msg_queue);
+         if (!msginfo)
+             break;
+
+         VirtQueueElement elem;
+         index = virtqueue_pop(vio_evdi->rvq, &elem);
+         if (index == 0)
+         {
+             //ERR("unexpected empty queue");
+             break;
+         }
+
+         //INFO(">> virtqueue_pop. index: %d, out_num : %d, in_num : %d\n", index, elem.out_num, elem.in_num);
+
+         memset(elem.in_sg[0].iov_base, 0, elem.in_sg[0].iov_len);
+         memcpy(elem.in_sg[0].iov_base, &msginfo->info, sizeof(struct msg_info));
+
+         //INFO(">> send to guest count = %d, use = %d, msg = %s, iov_len = %d \n",
+                // ++g_cnt, msginfo->info.use, msginfo->info.buf, elem.in_sg[0].iov_len);
+
+         virtqueue_push(vio_evdi->rvq, &elem, sizeof(msg_info));
+         virtio_notify(&vio_evdi->vdev, vio_evdi->rvq);
+
+         QTAILQ_REMOVE(&evdi_recv_msg_queue, msginfo, next);
+         if (msginfo)
+             free(msginfo);
+    }
+
+    pthread_mutex_unlock(&recv_buf_mutex);
+
+}
+
+
+static void virtio_evdi_recv(VirtIODevice *vdev, VirtQueue *vq)
+{
+    flush_evdi_recv_queue();
+}
+
+static void virtio_evdi_send(VirtIODevice *vdev, VirtQueue *vq)
+{
+    VirtIOEVDI *vevdi = (VirtIOEVDI *)vdev;
+    int index = 0;
+    struct msg_info _msg;
+
+    if (virtio_queue_empty(vevdi->svq)) {
+        INFO("<< virtqueue is empty.\n");
+        return;
+    }
+
+    VirtQueueElement elem;
+
+    while ((index = virtqueue_pop(vq, &elem))) {
+
+        //INFO("<< virtqueue pop. index: %d, out_num : %d, in_num : %d\n", index,  elem.out_num, elem.in_num);
+
+        //INFO("<< use=%d, iov_len = %d\n", _msg.use, elem.out_sg[0].iov_len);
+
+        memset(&_msg, 0x00, sizeof(_msg));
+        memcpy(&_msg, elem.out_sg[0].iov_base, elem.out_sg[0].iov_len);
+
+        //INFO("<< recv from guest len = %d, msg = %s \n", _msg.use, _msg.buf);
+
+        send_injector_ntf(_msg.buf, _msg.use);
+    }
+
+    virtqueue_push(vq, &elem, sizeof(VirtIOEVDI));
+    virtio_notify(&vio_evdi->vdev, vq);
+}
+
+static uint32_t virtio_evdi_get_features(VirtIODevice *vdev,
+                                            uint32_t request_feature)
+{
+    TRACE("virtio_evdi_get_features.\n");
+    return 0;
+}
+
+static void maru_evdi_bh(void *opaque)
+{
+    flush_evdi_recv_queue();
+}
+
+static void virtio_evdi_realize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    vio_evdi = VIRTIO_EVDI(dev);
+    if (vio_evdi == NULL) {
+        ERR("failed to initialize evdi device\n");
+        return;
+    }
+
+    INFO("initialize evdi device\n");
+
+    virtio_init(vdev, TYPE_VIRTIO_EVDI, VIRTIO_ID_EVDI, 0); //EVDI_DEVICE_NAME
+
+    vio_evdi->rvq = virtio_add_queue(&vio_evdi->vdev, 256, virtio_evdi_recv);
+    vio_evdi->svq = virtio_add_queue(&vio_evdi->vdev, 256, virtio_evdi_send);
+
+    vio_evdi->bh = qemu_bh_new(maru_evdi_bh, vio_evdi);
+
+}
+
+static void virtio_evdi_unrealize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+
+    INFO("destroy evdi device\n");
+
+    if (vio_evdi->bh) {
+            qemu_bh_delete(vio_evdi->bh);
+        }
+
+    virtio_cleanup(vdev);
+}
+
+static void virtio_evdi_reset(VirtIODevice *vdev)
+{
+    TRACE("virtio_evdi_reset.\n");
+}
+
+
+static void virtio_evdi_class_init(ObjectClass *klass, void *data)
+{
+    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+    vdc->realize = virtio_evdi_realize;
+    vdc->unrealize = virtio_evdi_unrealize;
+    vdc->get_features = virtio_evdi_get_features;
+    vdc->reset = virtio_evdi_reset;
+}
+
+
+
+static const TypeInfo virtio_device_info = {
+    .name = TYPE_VIRTIO_EVDI,
+    .parent = TYPE_VIRTIO_DEVICE,
+    .instance_size = sizeof(VirtIOEVDI),
+    .class_init = virtio_evdi_class_init,
+};
+
+static void virtio_register_types(void)
+{
+    type_register_static(&virtio_device_info);
+}
+
+type_init(virtio_register_types)
diff --git a/tizen/src/hw/virtio/maru_virtio_evdi.h b/tizen/src/hw/virtio/maru_virtio_evdi.h
new file mode 100644 (file)
index 0000000..a8c5fa0
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * maru_virtio_evdi.h
+ *
+ *  Created on: 2013. 3. 30.
+ *      Author: dykim
+ */
+
+#ifndef MARU_VIRTIO_EVDI_H_
+#define MARU_VIRTIO_EVDI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "hw/virtio/virtio.h"
+
+/* device protocol */
+
+#define __MAX_BUF_SIZE 1024
+
+enum
+{
+       route_qemu = 0,
+       route_control_server = 1,
+       route_monitor = 2,
+       route_ij = 3
+};
+
+typedef unsigned int CSCliSN;
+
+typedef struct msg_info {
+       char buf[__MAX_BUF_SIZE];
+
+       uint32_t route;
+       uint32_t use;
+       uint16_t count;
+       uint16_t index;
+
+       CSCliSN cclisn;
+}msg_info;
+
+/* device protocol */
+
+typedef struct VirtIOEVDI{
+    VirtIODevice    vdev;
+    VirtQueue       *rvq;
+    VirtQueue          *svq;
+    DeviceState     *qdev;
+
+    QEMUBH *bh;
+} VirtIOEVDI;
+
+
+
+#define TYPE_VIRTIO_EVDI "virtio-evdi-device"
+#define VIRTIO_EVDI(obj) \
+        OBJECT_CHECK(VirtIOEVDI, (obj), TYPE_VIRTIO_EVDI)
+
+//VirtIODevice *virtio_evdi_init(DeviceState *dev);
+
+//void virtio_evdi_exit(VirtIODevice *vdev);
+bool send_to_evdi(const uint32_t route, char* data, const uint32_t len);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MARU_VIRTIO_EVDI_H_ */
diff --git a/tizen/src/hw/virtio/maru_virtio_hwkey.c b/tizen/src/hw/virtio/maru_virtio_hwkey.c
new file mode 100644 (file)
index 0000000..8d010bc
--- /dev/null
@@ -0,0 +1,267 @@
+/*
+ * 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);
+
+        printf("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 uint32_t virtio_hwkey_get_features(
+    VirtIODevice *vdev, uint32_t request_features)
+{
+    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_HWKEY(dev);
+
+    if (vdev == NULL) {
+        ERR("failed to initialize the hwkey device\n");
+        return;
+    }
+
+    virtio_init(vdev, TYPE_VIRTIO_HWKEY, VIRTIO_ID_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_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)
+
diff --git a/tizen/src/hw/virtio/maru_virtio_hwkey.h b/tizen/src/hw/virtio/maru_virtio_hwkey.h
new file mode 100644 (file)
index 0000000..9e48da8
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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_HWKEY "virtio-hwkey-device"
+#define VIRTIO_HWKEY(obj) \
+        OBJECT_CHECK(VirtIOHWKey, (obj), TYPE_VIRTIO_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_ */
diff --git a/tizen/src/hw/virtio/maru_virtio_jack.c b/tizen/src/hw/virtio/maru_virtio_jack.c
new file mode 100644 (file)
index 0000000..f1f1fdb
--- /dev/null
@@ -0,0 +1,328 @@
+/*
+ * Virtio Jack Device
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Jinhyung Choi <jinhyung2.choi@samsung.com>
+ *  Daiyoung Kim <daiyoung777.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 "hw/pci/pci.h"
+
+#include "hw/maru_device_ids.h"
+#include "debug_ch.h"
+
+#include "maru_virtio_jack.h"
+
+MULTI_DEBUG_CHANNEL(qemu, virtio-jack);
+
+#define JACK_DEVICE_NAME  "jack"
+#define _MAX_BUF          1024
+#define __MAX_BUF_JACK    32
+
+static int charger_online = 0;
+static int earjack_online = 0;
+static int earkey_online = 0;
+static int hdmi_online = 0;
+static int usb_online = 0;
+
+VirtIOJACK* vjack;
+static int jack_capability = 0;
+
+typedef struct msg_info {
+    char buf[_MAX_BUF];
+
+    uint16_t type;
+    uint16_t req;
+} msg_info;
+
+enum request_cmd {
+    request_get = 0,
+    request_set,
+    request_answer
+};
+
+void set_jack_charger(int online){
+    charger_online = online;
+}
+
+int get_jack_charger(void) {
+    return charger_online;
+}
+
+void set_jack_usb(int online){
+    usb_online = online;
+}
+
+int get_jack_usb(void) {
+    return usb_online;
+}
+
+static void set_jack_data (enum jack_types type, char* data, int len)
+{
+    if (len < 0 || len > __MAX_BUF_JACK) {
+        ERR("jack data size is wrong.\n");
+        return;
+    }
+
+    if (data == NULL) {
+        ERR("jack data is NULL.\n");
+        return;
+    }
+
+    switch (type) {
+        case jack_type_charger:
+            sscanf(data, "%d", &charger_online);
+            break;
+        case jack_type_earjack:
+            sscanf(data, "%d", &earjack_online);
+            break;
+        case jack_type_earkey:
+            sscanf(data, "%d", &earkey_online);
+            break;
+        case jack_type_hdmi:
+            sscanf(data, "%d", &hdmi_online);
+            break;
+        case jack_type_usb:
+            sscanf(data, "%d", &usb_online);
+            break;
+        default:
+            return;
+    }
+}
+
+static void get_jack_data(enum jack_types type, char* msg_info)
+{
+    if (msg_info == NULL) {
+        return;
+    }
+
+    switch (type) {
+        case jack_type_list:
+            sprintf(msg_info, "%d", jack_capability);
+            break;
+        case jack_type_charger:
+            sprintf(msg_info, "%d", charger_online);
+            break;
+        case jack_type_earjack:
+            sprintf(msg_info, "%d", earjack_online);
+            break;
+        case jack_type_earkey:
+            sprintf(msg_info, "%d", earkey_online);
+            break;
+        case jack_type_hdmi:
+            sprintf(msg_info, "%d", hdmi_online);
+            break;
+        case jack_type_usb:
+            sprintf(msg_info, "%d", usb_online);
+            break;
+        default:
+            return;
+    }
+}
+
+static void answer_jack_data_request(int type, char* data, VirtQueueElement *elem)
+{
+    msg_info* msginfo = (msg_info*) malloc(sizeof(msg_info));
+    if (!msginfo) {
+        ERR("msginfo is NULL!\n");
+        return;
+    }
+
+    msginfo->req = request_answer;
+    msginfo->type = type;
+    get_jack_data(type, msginfo->buf);
+
+    TRACE("sending message: %s, type: %d, req: %d\n", msginfo->buf, msginfo->type, msginfo->req);
+
+    memset(elem->in_sg[0].iov_base, 0, elem->in_sg[0].iov_len);
+    memcpy(elem->in_sg[0].iov_base, msginfo, sizeof(struct msg_info));
+
+    if (msginfo)
+        free(msginfo);
+}
+
+static void handle_msg(struct msg_info *msg, VirtQueueElement *elem)
+{
+    unsigned int len = 0;
+
+    if (msg == NULL) {
+        ERR("msg info structure is NULL.\n");
+        return;
+    }
+
+    if (msg->req == request_set) {
+        set_jack_data (msg->type, msg->buf, strlen(msg->buf));
+    } else if (msg->req == request_get) {
+        answer_jack_data_request(msg->type, msg->buf, elem);
+        len = sizeof(msg_info);
+    }
+
+    virtqueue_push(vjack->vq, elem, len);
+    virtio_notify(&vjack->vdev, vjack->vq);
+}
+
+static void virtio_jack_vq(VirtIODevice *vdev, VirtQueue *vq)
+{
+    VirtIOJACK *vjack = (VirtIOJACK*)vdev;
+    struct msg_info msg;
+    VirtQueueElement elem;
+    int index = 0;
+
+    if (vjack->vq == NULL) {
+        ERR("virt queue is not ready.\n");
+        return;
+    }
+
+    if (!virtio_queue_ready(vjack->vq)) {
+        ERR("virtqueue is not ready.");
+        return;
+    }
+
+    if (virtio_queue_empty(vjack->vq)) {
+        ERR("<< virtqueue is empty.\n");
+        return;
+    }
+
+    while ((index = virtqueue_pop(vq, &elem))) {
+        memset(&msg, 0x00, sizeof(msg));
+        memcpy(&msg, elem.out_sg[0].iov_base, elem.out_sg[0].iov_len);
+
+        TRACE("handling msg from driver: %s, len: %d, type: %d, req: %d, index: %d\n", msg.buf, strlen(msg.buf), msg.type, msg.req, index);
+
+        handle_msg(&msg, &elem);
+    }
+}
+
+static int set_capability(char* jack)
+{
+    if (!strncmp(jack, JACK_NAME_CHARGER, 7)) {
+        return jack_cap_charger;
+    } else if (!strncmp(jack, JACK_NAME_EARJACK, 7)) {
+        return jack_cap_earjack;
+    } else if (!strncmp(jack, JACK_NAME_EARKEY, 6)) {
+        return jack_cap_earkey;
+    } else if (!strncmp(jack, JACK_NAME_HDMI, 4)) {
+        return jack_cap_hdmi;
+    } else if (!strncmp(jack, JACK_NAME_USB, 3)) {
+        return jack_cap_usb;
+    }
+
+    return 0;
+}
+
+static void parse_jack_capability(char* lists)
+{
+    char token[] = JACK_CAP_TOKEN;
+    char* data = NULL;
+
+    if (lists == NULL)
+        return;
+
+    data = strtok(lists, token);
+    if (data != NULL) {
+        jack_capability |= set_capability(data);
+        while ((data = strtok(NULL, token)) != NULL) {
+            jack_capability |= set_capability(data);
+        }
+    }
+
+    INFO("jack device capabilty enabled with %02x\n", jack_capability);
+}
+
+static void virtio_jack_realize(DeviceState *dev, Error **errp)
+{
+    INFO("initialize virtio-jack device\n");
+
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    vjack = VIRTIO_JACK(vdev);
+
+    virtio_init(vdev, JACK_DEVICE_NAME, VIRTIO_ID_JACK, 0);
+
+    if (vjack == NULL) {
+        ERR("failed to initialize jack device\n");
+        return;
+    }
+
+    vjack->vq = virtio_add_queue(&vjack->vdev, 64, virtio_jack_vq);
+
+    INFO("initialized jack type: %s\n", vjack->jacks);
+
+    if (vjack->jacks) {
+        parse_jack_capability(vjack->jacks);
+    }
+}
+
+static void virtio_jack_unrealize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    INFO("destroy jack device\n");
+
+    virtio_cleanup(vdev);
+}
+
+
+static void virtio_jack_reset(VirtIODevice *vdev)
+{
+    TRACE("virtio_jack_reset.\n");
+}
+
+static uint32_t virtio_jack_get_features(VirtIODevice *vdev,
+                                            uint32_t request_feature)
+{
+    TRACE("virtio_jack_get_features.\n");
+    return 0;
+}
+
+static Property virtio_jack_properties[] = {
+    DEFINE_PROP_STRING(ATTRIBUTE_NAME_JACKS, VirtIOJACK, jacks),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_jack_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+    dc->props = virtio_jack_properties;
+    vdc->realize = virtio_jack_realize;
+    vdc->unrealize = virtio_jack_unrealize;
+    vdc->get_features = virtio_jack_get_features;
+    vdc->reset = virtio_jack_reset;
+}
+
+static const TypeInfo virtio_device_info = {
+    .name = TYPE_VIRTIO_JACK,
+    .parent = TYPE_VIRTIO_DEVICE,
+    .instance_size = sizeof(VirtIOJACK),
+    .class_init = virtio_jack_class_init,
+};
+
+static void virtio_register_types(void)
+{
+    type_register_static(&virtio_device_info);
+}
+
+type_init(virtio_register_types)
+
diff --git a/tizen/src/hw/virtio/maru_virtio_jack.h b/tizen/src/hw/virtio/maru_virtio_jack.h
new file mode 100644 (file)
index 0000000..615db82
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * Virtio Jack Device
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Jinhyung choi   <jinhyung2.choi@samsung.com>
+ *  Daiyoung Kim    <daiyoung777.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_VIRTIO_JACK_H_
+#define MARU_VIRTIO_JACK_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "hw/virtio/virtio.h"
+
+#define TYPE_VIRTIO_JACK "virtio-jack-device"
+#define VIRTIO_JACK(obj) \
+        OBJECT_CHECK(VirtIOJACK, (obj), TYPE_VIRTIO_JACK)
+
+enum jack_types {
+    jack_type_list = 0,
+    jack_type_charger,
+    jack_type_earjack,
+    jack_type_earkey,
+    jack_type_hdmi,
+    jack_type_usb,
+    jack_type_max
+};
+
+enum jack_capabilities {
+    jack_cap_charger = 0x01,
+    jack_cap_earjack = 0x02,
+    jack_cap_earkey  = 0x04,
+    jack_cap_hdmi    = 0x08,
+    jack_cap_usb     = 0x10
+};
+
+typedef struct VirtIOJACK {
+    VirtIODevice    vdev;
+    VirtQueue       *vq;
+    DeviceState     *qdev;
+
+    char            *jacks;
+} VirtIOJACK;
+
+#define ATTRIBUTE_NAME_JACKS "jacks"
+
+#define JACK_NAME_CHARGER "charger"
+#define JACK_NAME_EARJACK "earjack"
+#define JACK_NAME_EARKEY "earkey"
+#define JACK_NAME_HDMI "hdmi"
+#define JACK_NAME_USB "usb"
+
+#define JACK_CAP_TOKEN "&"
+
+void set_jack_charger(int online);
+int get_jack_charger(void);
+
+void set_jack_usb(int online);
+int get_jack_usb(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tizen/src/hw/virtio/maru_virtio_keyboard.c b/tizen/src/hw/virtio/maru_virtio_keyboard.c
new file mode 100644 (file)
index 0000000..7132d51
--- /dev/null
@@ -0,0 +1,300 @@
+/*
+ * Virtio Keyboard Device
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Kitae Kim <kt920.kim@samsung.com>
+ *  GiWoong Kim <giwoong.kim@samsung.com>
+ *  SeokYeon Hwang <syeon.hwang@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 "hw/maru_device_ids.h"
+#include "maru_virtio_keyboard.h"
+#include "debug_ch.h"
+
+
+MULTI_DEBUG_CHANNEL(qemu, virtio-kbd);
+
+VirtIOKeyboard *vkbd;
+VirtQueueElement elem;
+
+static void virtio_keyboard_handle(VirtIODevice *vdev, VirtQueue *vq)
+{
+    VirtIOKeyboard *vkbd = (VirtIOKeyboard *)vdev;
+    int index = 0;
+
+    if (virtio_queue_empty(vkbd->vq)) {
+        INFO("virtqueue is empty.\n");
+        return;
+    }
+
+    /* Get a queue buffer which is written by guest side. */
+    do {
+        index = virtqueue_pop(vq, &elem);
+        TRACE("virtqueue pop.\n");
+    } while (index < VIRTIO_KBD_QUEUE_SIZE);
+}
+
+void virtio_keyboard_notify(void *opaque)
+{
+    VirtIOKeyboard *vkbd = (VirtIOKeyboard *)opaque;
+    EmulKbdEvent *kbdevt;
+    int written_cnt = 0;
+
+    if (!vkbd) {
+        ERR("VirtIOKeyboard is NULL.\n");
+        return;
+    }
+
+    TRACE("[Enter] virtqueue notifier.\n");
+
+    if (!virtio_queue_ready(vkbd->vq)) {
+        INFO("virtqueue is not ready.\n");
+        return;
+    }
+
+    if (vkbd->kbdqueue.rptr == VIRTIO_KBD_QUEUE_SIZE) {
+        vkbd->kbdqueue.rptr = 0;
+    }
+
+    qemu_mutex_lock(&vkbd->event_mutex);
+    written_cnt = vkbd->kbdqueue.wptr;
+
+    while ((written_cnt--)) {
+        kbdevt = &vkbd->kbdqueue.kbdevent[vkbd->kbdqueue.rptr];
+
+        if (((EmulKbdEvent*)(elem.in_sg[vkbd->kbdqueue.rptr].iov_base))->code != 0) {
+            TRACE("FIXME: virtio queue is full.\n");
+        }
+
+        /* Copy keyboard data into guest side. */
+        TRACE("copy: keycode %d, type %d, elem_index %d\n",
+            kbdevt->code, kbdevt->type, vkbd->kbdqueue.rptr);
+        memcpy(elem.in_sg[vkbd->kbdqueue.rptr].iov_base, kbdevt, sizeof(EmulKbdEvent));
+        memset(kbdevt, 0x00, sizeof(EmulKbdEvent));
+
+        if (vkbd->kbdqueue.wptr > 0) {
+            vkbd->kbdqueue.wptr--;
+            TRACE("written_cnt: %d, wptr: %d, qemu_index: %d\n",
+                written_cnt, vkbd->kbdqueue.wptr, vkbd->kbdqueue.rptr);
+        }
+
+        vkbd->kbdqueue.rptr++;
+        if (vkbd->kbdqueue.rptr == VIRTIO_KBD_QUEUE_SIZE) {
+            vkbd->kbdqueue.rptr = 0;
+        }
+    }
+    qemu_mutex_unlock(&vkbd->event_mutex);
+
+    virtqueue_push(vkbd->vq, &elem, sizeof(EmulKbdEvent));
+    virtio_notify(&vkbd->vdev, vkbd->vq);
+
+    TRACE("[Leave] virtqueue notifier.\n");
+}
+
+void virtio_keyboard_event(int keycode)
+{
+    EmulKbdEvent kbdevt = {0};
+    int *index = NULL;
+
+    if (!vkbd) {
+        ERR("VirtIOKeyboard is NULL.\n");
+        return;
+    }
+
+    if (!virtio_queue_ready(vkbd->vq)) {
+        INFO("virtqueue is not ready.\n");
+        return;
+    }
+
+    index = &(vkbd->kbdqueue.index);
+    TRACE("[Enter] input_event handler. cnt %d\n", vkbd->kbdqueue.wptr);
+
+    if (*index < 0) {
+        ERR("keyboard queue is overflow.\n");
+        return;
+    }
+
+    if (*index == VIRTIO_KBD_QUEUE_SIZE) {
+        *index = 0;
+    }
+
+    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);
+    memcpy(&vkbd->kbdqueue.kbdevent[(*index)++], &kbdevt, sizeof(kbdevt));
+    TRACE("event: keycode %d, type %d, index %d.\n",
+        kbdevt.code, kbdevt.type, ((*index) - 1));
+
+    vkbd->kbdqueue.wptr++;
+    qemu_mutex_unlock(&vkbd->event_mutex);
+
+    TRACE("[Leave] input_event handler. cnt:%d\n", vkbd->kbdqueue.wptr);
+
+    qemu_bh_schedule(vkbd->bh);
+}
+
+static uint32_t virtio_keyboard_get_features(VirtIODevice *vdev,
+                                            uint32_t request_feature)
+{
+    TRACE("virtio_keyboard_get_features.\n");
+    return 0;
+}
+
+static void virtio_keyboard_bh(void *opaque)
+{
+    virtio_keyboard_notify(opaque);
+}
+
+static void virtio_keyboard_device_realize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    vkbd = VIRTIO_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_KEYBOARD, VIRTIO_ID_KEYBOARD, 0);
+
+    memset(&vkbd->kbdqueue, 0x00, sizeof(vkbd->kbdqueue));
+    vkbd->extension_key = 0;
+    qemu_mutex_init(&vkbd->event_mutex);
+
+    vkbd->vq = virtio_add_queue(vdev, 128, virtio_keyboard_handle);
+    vkbd->qdev = dev;
+
+    /* bottom half */
+    vkbd->bh = qemu_bh_new(virtio_keyboard_bh, vkbd);
+}
+
+static void virtio_keyboard_device_unrealize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    VirtIOKeyboard *vkbd = (VirtIOKeyboard *)vdev;
+
+    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)
+{
+    vkbd = VIRTIO_KEYBOARD(vdev);
+
+    INFO("reset keyboard device\n");
+    vkbd->kbdqueue.rptr = 0;
+    vkbd->kbdqueue.index = 0;
+}
+
+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_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)
+
diff --git a/tizen/src/hw/virtio/maru_virtio_keyboard.h b/tizen/src/hw/virtio/maru_virtio_keyboard.h
new file mode 100644 (file)
index 0000000..f3296bc
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Virtio Keyboard Device
+ *
+ * Copyright (c) 2011 - 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Kitae Kim <kt920.kim@samsung.com>
+ *  GiWoong Kim <giwoong.kim@samsung.com>
+ *  SeokYeon Hwang <syeon.hwang@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 VIRTIO_KEYBOARD_H_
+#define VIRTIO_KEYBOARD_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "qemu/thread.h"
+#include "hw/virtio/virtio.h"
+
+#define TYPE_VIRTIO_KEYBOARD "virtio-keyboard-device"
+#define VIRTIO_KEYBOARD(obj) \
+        OBJECT_CHECK(VirtIOKeyboard, (obj), TYPE_VIRTIO_KEYBOARD)
+#define VIRTIO_KBD_QUEUE_SIZE  100
+
+typedef struct EmulKbdEvent {
+    uint16_t code;
+    uint16_t type;
+} EmulKbdEvent;
+
+typedef struct VirtIOKbdQueue {
+    EmulKbdEvent kbdevent[VIRTIO_KBD_QUEUE_SIZE];
+    int index;
+    int rptr, wptr;
+} VirtIOKbdQueue;
+
+typedef struct VirtIOKeyboard {
+    VirtIODevice    vdev;
+    VirtQueue       *vq;
+    DeviceState     *qdev;
+    uint16_t        extension_key;
+
+    VirtIOKbdQueue  kbdqueue;
+    QemuMutex       event_mutex;
+    QEMUBH          *bh;
+} VirtIOKeyboard;
+
+VirtIODevice *virtio_keyboard_init(DeviceState *dev);
+void virtio_keyboard_exit(VirtIODevice *vdev);
+
+void virtio_keyboard_event(int keycode);
+void virtio_keyboard_notify(void *opaque);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* VIRTIO_KEYBOARD_H_ */
diff --git a/tizen/src/hw/virtio/maru_virtio_nfc.c b/tizen/src/hw/virtio/maru_virtio_nfc.c
new file mode 100644 (file)
index 0000000..ce632e6
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * Virtio NFC Device
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Munkyu Im <munkyu.im@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 "hw/maru_device_ids.h"
+#include "maru_virtio_nfc.h"
+#include "debug_ch.h"
+#include "ecs/ecs.h"
+
+MULTI_DEBUG_CHANNEL(qemu, virtio-nfc);
+
+#define NFC_DEVICE_NAME "virtio-nfc"
+
+enum {
+    IOTYPE_INPUT = 0,
+    IOTYPE_OUTPUT = 1
+};
+
+
+#ifndef min
+#define min(a,b) ((a)<(b)?(a):(b))
+#endif
+
+VirtIONFC* vio_nfc;
+
+typedef struct MsgInfo
+{
+    nfc_msg_info info;
+    QTAILQ_ENTRY(MsgInfo) next;
+}MsgInfo;
+
+static QTAILQ_HEAD(MsgInfoRecvHead , MsgInfo) nfc_recv_msg_queue =
+QTAILQ_HEAD_INITIALIZER(nfc_recv_msg_queue);
+
+typedef struct NFCBuf {
+    VirtQueueElement elem;
+    QTAILQ_ENTRY(NFCBuf) next;
+} NFCBuf;
+
+static pthread_mutex_t recv_buf_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+bool send_to_nfc(unsigned char id, unsigned char type, const char* data, const uint32_t len)
+{
+    if(vio_nfc == NULL) {
+        ERR("NFC is not initialized\n");
+        return false;
+    }
+
+    if (unlikely(!virtio_queue_ready(vio_nfc->rvq))) {
+        ERR("virtio queue is not ready\n");
+        return false;
+    }
+
+    MsgInfo* _msg = (MsgInfo*) malloc(sizeof(MsgInfo));
+    if (!_msg) {
+        return false;
+    }
+
+    if(len > NFC_MAX_BUF_SIZE) {
+        ERR("the length of data is longer than max buffer size");
+        free(_msg);
+        return false;
+    }
+
+    memset(&_msg->info, 0, sizeof(nfc_msg_info));
+
+    memcpy(_msg->info.buf, data, len);
+    _msg->info.use = len;
+    _msg->info.client_id = id;
+    _msg->info.client_type = type;
+
+    pthread_mutex_lock(&recv_buf_mutex);
+
+    QTAILQ_INSERT_TAIL(&nfc_recv_msg_queue, _msg, next);
+
+    pthread_mutex_unlock(&recv_buf_mutex);
+
+    qemu_bh_schedule(vio_nfc->bh);
+
+    return true;
+}
+
+static void flush_nfc_recv_queue(void)
+{
+    int index;
+
+    if (unlikely(!virtio_queue_ready(vio_nfc->rvq))) {
+        INFO("virtio queue is not ready\n");
+        return;
+    }
+
+    if (unlikely(virtio_queue_empty(vio_nfc->rvq))) {
+        TRACE("virtqueue is empty\n");
+        return;
+    }
+
+
+    pthread_mutex_lock(&recv_buf_mutex);
+
+    while (!QTAILQ_EMPTY(&nfc_recv_msg_queue))
+    {
+        MsgInfo* msginfo = QTAILQ_FIRST(&nfc_recv_msg_queue);
+        if (!msginfo) {
+            break;
+        }
+
+        VirtQueueElement elem;
+        index = virtqueue_pop(vio_nfc->rvq, &elem);
+        if (index == 0)
+        {
+            //ERR("unexpected empty queue");
+            break;
+        }
+
+        INFO(">> virtqueue_pop. index: %d, out_num : %d, in_num : %d\n", index, elem.out_num, elem.in_num);
+
+        memcpy(elem.in_sg[0].iov_base, &msginfo->info, sizeof(struct nfc_msg_info));
+
+        INFO(">> send to guest use = %d, msg = %s, iov_len = %d \n",
+                msginfo->info.use, msginfo->info.buf, elem.in_sg[0].iov_len);
+
+        virtqueue_push(vio_nfc->rvq, &elem, sizeof(nfc_msg_info));
+        virtio_notify(&vio_nfc->vdev, vio_nfc->rvq);
+
+        QTAILQ_REMOVE(&nfc_recv_msg_queue, msginfo, next);
+        if (msginfo)
+            free(msginfo);
+    }
+
+    pthread_mutex_unlock(&recv_buf_mutex);
+
+}
+
+
+static void virtio_nfc_recv(VirtIODevice *vdev, VirtQueue *vq)
+{
+    flush_nfc_recv_queue();
+}
+
+static void virtio_nfc_send(VirtIODevice *vdev, VirtQueue *vq)
+{
+    VirtIONFC *vnfc = (VirtIONFC *)vdev;
+    int index = 0;
+    struct nfc_msg_info _msg;
+
+    if (virtio_queue_empty(vnfc->svq)) {
+        INFO("<< virtqueue is empty.\n");
+        return;
+    }
+
+    VirtQueueElement elem;
+
+    while ((index = virtqueue_pop(vq, &elem))) {
+
+        INFO("<< virtqueue pop. index: %d, out_num : %d, in_num : %d\n", index,  elem.out_num, elem.in_num);
+
+        INFO("<< iov_len = %d\n", elem.out_sg[0].iov_len);
+
+        memset(&_msg, 0x00, sizeof(_msg));
+        memcpy(&_msg, elem.out_sg[0].iov_base, elem.out_sg[0].iov_len);
+
+        INFO("<< recv from guest len = %d, msg = %s \n", _msg.use, _msg.buf);
+        send_nfc_ntf(&_msg);
+
+    }
+
+    virtqueue_push(vq, &elem, sizeof(VirtIONFC));
+    virtio_notify(&vio_nfc->vdev, vq);
+}
+
+static uint32_t virtio_nfc_get_features(VirtIODevice *vdev,
+        uint32_t request_feature)
+{
+    TRACE("virtio_nfc_get_features.\n");
+    return 0;
+}
+
+static void maru_nfc_bh(void *opaque)
+{
+    flush_nfc_recv_queue();
+}
+
+static void virtio_nfc_realize(DeviceState* dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    vio_nfc = VIRTIO_NFC(vdev);
+    if (vio_nfc == NULL) {
+        ERR("failed to initialize nfc device\n");
+        return;
+    }
+
+    INFO("initialize nfc device\n");
+
+    virtio_init(vdev, NFC_DEVICE_NAME, VIRTIO_ID_NFC, 0);
+
+    vio_nfc->rvq = virtio_add_queue(&vio_nfc->vdev, 256, virtio_nfc_recv);
+    vio_nfc->svq = virtio_add_queue(&vio_nfc->vdev, 256, virtio_nfc_send);
+
+    vio_nfc->bh = qemu_bh_new(maru_nfc_bh, vio_nfc);
+}
+
+static void virtio_nfc_unrealize(DeviceState* dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+
+    INFO("destroy nfc device\n");
+
+    if (vio_nfc->bh) {
+        qemu_bh_delete(vio_nfc->bh);
+    }
+
+    virtio_cleanup(vdev);
+}
+
+static void virtio_nfc_reset(VirtIODevice *vdev)
+{
+    TRACE("virtio_sensor_reset.\n");
+}
+
+
+static void virtio_nfc_class_init(ObjectClass *klass, void *data)
+{
+    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+    vdc->realize = virtio_nfc_realize;
+    vdc->unrealize = virtio_nfc_unrealize;
+    vdc->get_features = virtio_nfc_get_features;
+    vdc->reset = virtio_nfc_reset;
+}
+
+static const TypeInfo virtio_device_info = {
+    .name = TYPE_VIRTIO_NFC,
+    .parent = TYPE_VIRTIO_DEVICE,
+    .instance_size = sizeof(VirtIONFC),
+    .class_init = virtio_nfc_class_init,
+};
+
+static void virtio_register_types(void)
+{
+    type_register_static(&virtio_device_info);
+}
+
+type_init(virtio_register_types)
+
diff --git a/tizen/src/hw/virtio/maru_virtio_nfc.h b/tizen/src/hw/virtio/maru_virtio_nfc.h
new file mode 100644 (file)
index 0000000..17c539a
--- /dev/null
@@ -0,0 +1,72 @@
+/*\r
+ * Virtio NFC Device\r
+ *\r
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Contact:\r
+ *  Munkyu Im <munkyu.im@samsung.com>\r
+ *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r
+ *\r
+ * Contributors:\r
+ * - S-Core Co., Ltd\r
+ *\r
+ */\r
+\r
+#ifndef MARU_VIRTIO_NFC_H_\r
+#define MARU_VIRTIO_NFC_H_\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#include "hw/virtio/virtio.h"\r
+\r
+enum request_cmd_nfc {\r
+       request_nfc_get = 0,\r
+       request_nfc_set,\r
+       request_nfc_answer\r
+};\r
+\r
+\r
+/* device protocol */\r
+\r
+#define __MAX_BUF_SIZE 1024\r
+\r
+\r
+typedef struct VirtIONFC{\r
+    VirtIODevice    vdev;\r
+    VirtQueue       *rvq;\r
+    VirtQueue          *svq;\r
+    DeviceState     *qdev;\r
+\r
+    QEMUBH *bh;\r
+} VirtIONFC;\r
+\r
+\r
+#define TYPE_VIRTIO_NFC "virtio-nfc-device"\r
+#define VIRTIO_NFC(obj) \\r
+        OBJECT_CHECK(VirtIONFC, (obj), TYPE_VIRTIO_NFC)\r
+\r
+\r
+bool send_to_nfc(unsigned char id, unsigned char type, const char* data, const uint32_t len);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+\r
+#endif /* MARU_VIRTIO_NFC_H_ */\r
diff --git a/tizen/src/hw/virtio/maru_virtio_pci.c b/tizen/src/hw/virtio/maru_virtio_pci.c
new file mode 100644 (file)
index 0000000..b8c71bf
--- /dev/null
@@ -0,0 +1,625 @@
+/*
+ * Maru virtio pci
+ *
+ * Copyright (C) 2014 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
+ *
+ * refer to hw/virtio/virtio-pci.c
+ */
+
+#include "hw/virtio/virtio-pci.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_sensor.h"
+#include "maru_virtio_jack.h"
+#include "maru_virtio_power.h"
+#include "maru_virtio_nfc.h"
+#include "maru_virtio_vmodem.h"
+
+typedef struct VirtIOTouchscreenPCI VirtIOTouchscreenPCI;
+typedef struct VirtIOEVDIPCI VirtIOEVDIPCI;
+typedef struct VirtIOESMPCI VirtIOESMPCI;
+typedef struct VirtIOHWKeyPCI VirtIOHWKeyPCI;
+typedef struct VirtIOKeyboardPCI VirtIOKeyboardPCI;
+typedef struct VirtIOSENSORPCI VirtIOSENSORPCI;
+typedef struct VirtIONFCPCI VirtIONFCPCI;
+typedef struct VirtIOPOWERPCI VirtIOPOWERPCI;
+typedef struct VirtIOJACKPCI VirtIOJACKPCI;
+typedef struct VirtIOVModemPCI VirtIOVModemPCI;
+
+/*
+ * virtio-touchscreen-pci: This extends VirtioPCIProxy.
+ */
+#define TYPE_VIRTIO_TOUCHSCREEN_PCI "virtio-touchscreen-pci"
+#define VIRTIO_TOUCHSCREEN_PCI(obj) \
+        OBJECT_CHECK(VirtIOTouchscreenPCI, (obj), TYPE_VIRTIO_TOUCHSCREEN_PCI)
+
+struct VirtIOTouchscreenPCI {
+    VirtIOPCIProxy parent_obj;
+    VirtIOTouchscreen vdev;
+};
+
+/*
+ * virtio-keyboard-pci: This extends VirtioPCIProxy.
+ */
+#define TYPE_VIRTIO_KEYBOARD_PCI "virtio-keyboard-pci"
+#define VIRTIO_KEYBOARD_PCI(obj) \
+        OBJECT_CHECK(VirtIOKeyboardPCI, (obj), TYPE_VIRTIO_KEYBOARD_PCI)
+
+struct VirtIOKeyboardPCI {
+    VirtIOPCIProxy parent_obj;
+    VirtIOKeyboard vdev;
+};
+
+/*
+ * virtio-evdi-pci: This extends VirtioPCIProxy.
+ */
+#define TYPE_VIRTIO_EVDI_PCI "virtio-evdi-pci"
+#define VIRTIO_EVDI_PCI(obj) \
+        OBJECT_CHECK(VirtIOEVDIPCI, (obj), TYPE_VIRTIO_EVDI_PCI)
+
+struct VirtIOEVDIPCI {
+    VirtIOPCIProxy parent_obj;
+    VirtIOEVDI vdev;
+};
+
+/*
+ * virtio-esm-pci: This extends VirtioPCIProxy.
+ */
+#define TYPE_VIRTIO_ESM_PCI "virtio-esm-pci"
+#define VIRTIO_ESM_PCI(obj) \
+        OBJECT_CHECK(VirtIOESMPCI, (obj), TYPE_VIRTIO_ESM_PCI)
+struct VirtIOESMPCI {
+    VirtIOPCIProxy parent_obj;
+    VirtIOESM vdev;
+};
+
+/*
+ * virtio-hwkey-pci: This extends VirtioPCIProxy.
+ */
+#define TYPE_VIRTIO_HWKEY_PCI "virtio-hwkey-pci"
+#define VIRTIO_HWKEY_PCI(obj) \
+        OBJECT_CHECK(VirtIOHWKeyPCI, (obj), TYPE_VIRTIO_HWKEY_PCI)
+struct VirtIOHWKeyPCI {
+    VirtIOPCIProxy parent_obj;
+    VirtIOHWKey vdev;
+};
+
+/*
+ * virtio-sensor-pci: This extends VirtioPCIProxy.
+ */
+#define TYPE_VIRTIO_SENSOR_PCI "virtio-sensor-pci"
+#define VIRTIO_SENSOR_PCI(obj) \
+        OBJECT_CHECK(VirtIOSENSORPCI, (obj), TYPE_VIRTIO_SENSOR_PCI)
+
+struct VirtIOSENSORPCI {
+    VirtIOPCIProxy parent_obj;
+    VirtIOSENSOR vdev;
+};
+
+/*
+ * virtio-nfc-pci: This extends VirtioPCIProxy.
+ */
+#define TYPE_VIRTIO_NFC_PCI "virtio-nfc-pci"
+#define VIRTIO_NFC_PCI(obj) \
+        OBJECT_CHECK(VirtIONFCPCI, (obj), TYPE_VIRTIO_NFC_PCI)
+
+struct VirtIONFCPCI {
+    VirtIOPCIProxy parent_obj;
+    VirtIONFC vdev;
+};
+
+/*
+ * virtio-jack-pci: This extends VirtioPCIProxy.
+ */
+#define TYPE_VIRTIO_JACK_PCI "virtio-jack-pci"
+#define VIRTIO_JACK_PCI(obj) \
+        OBJECT_CHECK(VirtIOJACKPCI, (obj), TYPE_VIRTIO_JACK_PCI)
+
+struct VirtIOJACKPCI {
+    VirtIOPCIProxy parent_obj;
+    VirtIOJACK vdev;
+};
+
+/*
+ * virtio-power-pci: This extends VirtioPCIProxy.
+ */
+#define TYPE_VIRTIO_POWER_PCI "virtio-power-pci"
+#define VIRTIO_POWER_PCI(obj) \
+        OBJECT_CHECK(VirtIOPOWERPCI, (obj), TYPE_VIRTIO_POWER_PCI)
+
+struct VirtIOPOWERPCI {
+    VirtIOPCIProxy parent_obj;
+    VirtIOPOWER vdev;
+};
+
+/*
+ * virtio-vmodem-pci: This extends VirtioPCIProxy.
+ */
+#define TYPE_VIRTIO_VMODEM_PCI "virtio-vmodem-pci"
+#define VIRTIO_VMODEM_PCI(obj) \
+        OBJECT_CHECK(VirtIOVModemPCI, (obj), TYPE_VIRTIO_VMODEM_PCI)
+struct VirtIOVModemPCI {
+    VirtIOPCIProxy parent_obj;
+    VirtIOVModem vdev;
+};
+
+
+/* virtio-touchscreen-pci */
+
+static Property virtio_touchscreen_pci_properties[] = {
+    DEFINE_PROP_UINT32(TOUCHSCREEN_OPTION_NAME,
+        VirtIOTouchscreenPCI,vdev.max_finger, DEFAULT_MAX_FINGER),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static int virtio_touchscreen_pci_init(VirtIOPCIProxy *vpci_dev)
+{
+    VirtIOTouchscreenPCI *dev = VIRTIO_TOUCHSCREEN_PCI(vpci_dev);
+    DeviceState *vdev = DEVICE(&dev->vdev);
+
+    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+    if (qdev_init(vdev) < 0) {
+        return -1;
+    }
+    return 0;
+}
+
+static void virtio_touchscreen_pci_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+
+    dc->props = virtio_touchscreen_pci_properties;
+    k->init = virtio_touchscreen_pci_init;
+    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_TOUCHSCREEN;
+    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
+    pcidev_k->class_id = PCI_CLASS_OTHERS;
+}
+
+static void virtio_touchscreen_pci_instance_init(Object *obj)
+{
+    VirtIOTouchscreenPCI *dev = VIRTIO_TOUCHSCREEN_PCI(obj);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_TOUCHSCREEN);
+    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
+
+    dev->vdev.max_finger = DEFAULT_MAX_FINGER;
+}
+
+static TypeInfo virtio_touchscreen_pci_info = {
+    .name          = TYPE_VIRTIO_TOUCHSCREEN_PCI,
+    .parent        = TYPE_VIRTIO_PCI,
+    .instance_size = sizeof(VirtIOTouchscreenPCI),
+    .instance_init = virtio_touchscreen_pci_instance_init,
+    .class_init    = virtio_touchscreen_pci_class_init,
+};
+
+/* virtio-keyboard-pci */
+
+static int virtio_keyboard_pci_init(VirtIOPCIProxy *vpci_dev)
+{
+    VirtIOKeyboardPCI *dev = VIRTIO_KEYBOARD_PCI(vpci_dev);
+    DeviceState *vdev = DEVICE(&dev->vdev);
+
+    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+    if (qdev_init(vdev) < 0) {
+        return -1;
+    }
+    return 0;
+}
+
+static void virtio_keyboard_pci_class_init(ObjectClass *klass, void *data)
+{
+    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_keyboard_pci_init;
+    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_KEYBOARD;
+    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
+    pcidev_k->class_id = PCI_CLASS_OTHERS;
+}
+
+static void virtio_keyboard_pci_instance_init(Object *obj)
+{
+    VirtIOKeyboardPCI *dev = VIRTIO_KEYBOARD_PCI(obj);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_KEYBOARD);
+    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
+}
+
+static TypeInfo virtio_keyboard_pci_info = {
+    .name          = TYPE_VIRTIO_KEYBOARD_PCI,
+    .parent        = TYPE_VIRTIO_PCI,
+    .instance_size = sizeof(VirtIOKeyboardPCI),
+    .instance_init = virtio_keyboard_pci_instance_init,
+    .class_init    = virtio_keyboard_pci_class_init,
+};
+
+/* virtio-esm-pci */
+
+static int virtio_esm_pci_init(VirtIOPCIProxy *vpci_dev)
+{
+    VirtIOESMPCI *dev = VIRTIO_ESM_PCI(vpci_dev);
+    DeviceState *vdev = DEVICE(&dev->vdev);
+
+    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+    if (qdev_init(vdev) < 0) {
+        return -1;
+    }
+    return 0;
+}
+
+static void virtio_esm_pci_class_init(ObjectClass *klass, void *data)
+{
+    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_esm_pci_init;
+    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_ESM;
+    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
+    pcidev_k->class_id = PCI_CLASS_OTHERS;
+}
+
+static void virtio_esm_pci_instance_init(Object *obj)
+{
+    VirtIOESMPCI *dev = VIRTIO_ESM_PCI(obj);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_ESM);
+    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
+}
+
+static TypeInfo virtio_esm_pci_info = {
+    .name          = TYPE_VIRTIO_ESM_PCI,
+    .parent        = TYPE_VIRTIO_PCI,
+    .instance_size = sizeof(VirtIOESMPCI),
+    .instance_init = virtio_esm_pci_instance_init,
+    .class_init    = virtio_esm_pci_class_init,
+};
+
+/* virtio-hwkey-pci */
+
+static int virtio_hwkey_pci_init(VirtIOPCIProxy *vpci_dev)
+{
+    VirtIOHWKeyPCI *dev = VIRTIO_HWKEY_PCI(vpci_dev);
+    DeviceState *vdev = DEVICE(&dev->vdev);
+
+    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+    if (qdev_init(vdev) < 0) {
+        return -1;
+    }
+    return 0;
+}
+
+static void virtio_hwkey_pci_class_init(ObjectClass *klass, void *data)
+{
+//    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_hwkey_pci_init;
+    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_HWKEY;
+    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
+    pcidev_k->class_id = PCI_CLASS_OTHERS;
+}
+
+static void virtio_hwkey_pci_instance_init(Object *obj)
+{
+    VirtIOHWKeyPCI *dev = VIRTIO_HWKEY_PCI(obj);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_HWKEY);
+    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
+}
+
+static TypeInfo virtio_hwkey_pci_info = {
+    .name          = TYPE_VIRTIO_HWKEY_PCI,
+    .parent        = TYPE_VIRTIO_PCI,
+    .instance_size = sizeof(VirtIOHWKeyPCI),
+    .instance_init = virtio_hwkey_pci_instance_init,
+    .class_init    = virtio_hwkey_pci_class_init,
+};
+
+/* virtio-evdi-pci */
+
+static int virtio_evdi_pci_init(VirtIOPCIProxy *vpci_dev)
+{
+    VirtIOEVDIPCI *dev = VIRTIO_EVDI_PCI(vpci_dev);
+    DeviceState *vdev = DEVICE(&dev->vdev);
+
+    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+    if (qdev_init(vdev) < 0) {
+        return -1;
+    }
+    return 0;
+}
+
+static void virtio_evdi_pci_class_init(ObjectClass *klass, void *data)
+{
+//    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_evdi_pci_init;
+    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_EVDI;
+    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
+    pcidev_k->class_id = PCI_CLASS_OTHERS;
+}
+
+static void virtio_evdi_pci_instance_init(Object *obj)
+{
+    VirtIOEVDIPCI *dev = VIRTIO_EVDI_PCI(obj);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_EVDI);
+    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
+}
+
+static TypeInfo virtio_evdi_pci_info = {
+    .name          = TYPE_VIRTIO_EVDI_PCI,
+    .parent        = TYPE_VIRTIO_PCI,
+    .instance_size = sizeof(VirtIOEVDIPCI),
+    .instance_init = virtio_evdi_pci_instance_init,
+    .class_init    = virtio_evdi_pci_class_init,
+};
+
+/* virtio-sensor-pci */
+
+static int virtio_sensor_pci_init(VirtIOPCIProxy *vpci_dev)
+{
+    VirtIOSENSORPCI *dev = VIRTIO_SENSOR_PCI(vpci_dev);
+    DeviceState *vdev = DEVICE(&dev->vdev);
+
+    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+    if (qdev_init(vdev) < 0) {
+        return -1;
+    }
+    return 0;
+}
+
+static Property virtio_sensor_pci_properties[] = {
+    DEFINE_PROP_STRING(ATTRIBUTE_NAME_SENSORS, VirtIOSENSORPCI, vdev.sensors),
+    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_sensor_pci_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_sensor_pci_init;
+    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_SENSOR;
+    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
+    pcidev_k->class_id = PCI_CLASS_OTHERS;
+    dc->props = virtio_sensor_pci_properties;
+}
+
+static void virtio_sensor_pci_instance_init(Object *obj)
+{
+    VirtIOSENSORPCI *dev = VIRTIO_SENSOR_PCI(obj);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_SENSOR);
+    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
+}
+
+static TypeInfo virtio_sensor_pci_info = {
+    .name          = TYPE_VIRTIO_SENSOR_PCI,
+    .parent        = TYPE_VIRTIO_PCI,
+    .instance_size = sizeof(VirtIOSENSORPCI),
+    .instance_init = virtio_sensor_pci_instance_init,
+    .class_init    = virtio_sensor_pci_class_init,
+};
+
+/* virtio NFC */
+
+static int virtio_nfc_pci_init(VirtIOPCIProxy *vpci_dev)
+{
+    VirtIONFCPCI *dev = VIRTIO_NFC_PCI(vpci_dev);
+    DeviceState *vdev = DEVICE(&dev->vdev);
+
+    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+    if (qdev_init(vdev) < 0) {
+        return -1;
+    }
+    return 0;
+}
+
+static void virtio_nfc_pci_class_init(ObjectClass *klass, void *data)
+{
+    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_nfc_pci_init;
+    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_NFC;
+    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
+    pcidev_k->class_id = PCI_CLASS_OTHERS;
+}
+
+static void virtio_nfc_pci_instance_init(Object *obj)
+{
+    VirtIONFCPCI *dev = VIRTIO_NFC_PCI(obj);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_NFC);
+    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
+}
+
+static TypeInfo virtio_nfc_pci_info = {
+    .name          = TYPE_VIRTIO_NFC_PCI,
+    .parent        = TYPE_VIRTIO_PCI,
+    .instance_size = sizeof(VirtIONFCPCI),
+    .instance_init = virtio_nfc_pci_instance_init,
+    .class_init    = virtio_nfc_pci_class_init,
+};
+
+/* virtio-jack-pci */
+
+static int virtio_jack_pci_init(VirtIOPCIProxy *vpci_dev)
+{
+    VirtIOJACKPCI *dev = VIRTIO_JACK_PCI(vpci_dev);
+    DeviceState *vdev = DEVICE(&dev->vdev);
+
+    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+    if (qdev_init(vdev) < 0) {
+        return -1;
+    }
+    return 0;
+}
+
+static Property virtio_jack_pci_properties[] = {
+    DEFINE_PROP_STRING(ATTRIBUTE_NAME_JACKS, VirtIOJACKPCI, vdev.jacks),
+    DEFINE_VIRTIO_COMMON_FEATURES(VirtIOPCIProxy, host_features),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_jack_pci_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_jack_pci_init;
+    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_JACK;
+    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
+    pcidev_k->class_id = PCI_CLASS_OTHERS;
+    dc->props = virtio_jack_pci_properties;
+}
+
+static void virtio_jack_pci_instance_init(Object *obj)
+{
+    VirtIOJACKPCI *dev = VIRTIO_JACK_PCI(obj);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_JACK);
+    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
+}
+
+static TypeInfo virtio_jack_pci_info = {
+    .name          = TYPE_VIRTIO_JACK_PCI,
+    .parent        = TYPE_VIRTIO_PCI,
+    .instance_size = sizeof(VirtIOJACKPCI),
+    .instance_init = virtio_jack_pci_instance_init,
+    .class_init    = virtio_jack_pci_class_init,
+};
+
+/* virtio-power-pci */
+
+static int virtio_power_pci_init(VirtIOPCIProxy *vpci_dev)
+{
+    VirtIOPOWERPCI *dev = VIRTIO_POWER_PCI(vpci_dev);
+    DeviceState *vdev = DEVICE(&dev->vdev);
+
+    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+    if (qdev_init(vdev) < 0) {
+        return -1;
+    }
+    return 0;
+}
+
+static void virtio_power_pci_class_init(ObjectClass *klass, void *data)
+{
+    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_power_pci_init;
+    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_POWER;
+    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
+    pcidev_k->class_id = PCI_CLASS_OTHERS;
+}
+
+static void virtio_power_pci_instance_init(Object *obj)
+{
+    VirtIOPOWERPCI *dev = VIRTIO_POWER_PCI(obj);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_POWER);
+    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
+}
+
+static TypeInfo virtio_power_pci_info = {
+    .name          = TYPE_VIRTIO_POWER_PCI,
+    .parent        = TYPE_VIRTIO_PCI,
+    .instance_size = sizeof(VirtIOPOWERPCI),
+    .instance_init = virtio_power_pci_instance_init,
+    .class_init    = virtio_power_pci_class_init,
+};
+
+/* virtio-vmodem-pci */
+
+static int virtio_vmodem_pci_init(VirtIOPCIProxy *vpci_dev)
+{
+    VirtIOVModemPCI *dev = VIRTIO_VMODEM_PCI(vpci_dev);
+    DeviceState *vdev = DEVICE(&dev->vdev);
+
+    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+    if (qdev_init(vdev) < 0) {
+        return -1;
+    }
+    return 0;
+}
+
+static void virtio_vmodem_pci_class_init(ObjectClass *klass, void *data)
+{
+    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+
+    k->init = virtio_vmodem_pci_init;
+    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_VMODEM;
+    pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
+    pcidev_k->class_id = PCI_CLASS_OTHERS;
+}
+
+static void virtio_vmodem_pci_instance_init(Object *obj)
+{
+    VirtIOVModemPCI *dev = VIRTIO_VMODEM_PCI(obj);
+    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_VMODEM);
+    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);
+}
+
+static TypeInfo virtio_vmodem_pci_info = {
+    .name          = TYPE_VIRTIO_VMODEM_PCI,
+    .parent        = TYPE_VIRTIO_PCI,
+    .instance_size = sizeof(VirtIOVModemPCI),
+    .instance_init = virtio_vmodem_pci_instance_init,
+    .class_init    = virtio_vmodem_pci_class_init,
+};
+
+static void maru_virtio_pci_register_types(void)
+{
+    type_register_static(&virtio_evdi_pci_info);
+    type_register_static(&virtio_esm_pci_info);
+    type_register_static(&virtio_hwkey_pci_info);
+    type_register_static(&virtio_keyboard_pci_info);
+    type_register_static(&virtio_touchscreen_pci_info);
+    type_register_static(&virtio_sensor_pci_info);
+    type_register_static(&virtio_nfc_pci_info);
+    type_register_static(&virtio_jack_pci_info);
+    type_register_static(&virtio_power_pci_info);
+    type_register_static(&virtio_vmodem_pci_info);
+}
+
+type_init(maru_virtio_pci_register_types)
diff --git a/tizen/src/hw/virtio/maru_virtio_power.c b/tizen/src/hw/virtio/maru_virtio_power.c
new file mode 100644 (file)
index 0000000..c275fdd
--- /dev/null
@@ -0,0 +1,269 @@
+/*
+ * Virtio Power Device
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Jinhyung Choi <jinhyung2.choi@samsung.com>
+ *  Daiyoung Kim <daiyoung777.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 "hw/pci/pci.h"
+
+#include "hw/maru_device_ids.h"
+#include "debug_ch.h"
+
+#include "maru_virtio_power.h"
+
+MULTI_DEBUG_CHANNEL(qemu, virtio-power);
+
+#define POWER_DEVICE_NAME  "power_supply"
+#define _MAX_BUF           1024
+#define __MAX_BUF_POWER    32
+
+static int capacity = 50;
+static int charge_full = 0;
+static int charge_now = 0;
+
+VirtIOPOWER* vpower;
+
+typedef struct msg_info {
+    char buf[_MAX_BUF];
+
+    uint16_t type;
+    uint16_t req;
+} msg_info;
+
+enum request_cmd {
+    request_get = 0,
+    request_set,
+    request_answer
+};
+
+static void set_power_data (enum power_types type, char* data, int len)
+{
+    if (len < 0 || len > __MAX_BUF_POWER) {
+        ERR("power data size is wrong.\n");
+        return;
+    }
+
+    if (data == NULL) {
+        ERR("power data is NULL.\n");
+        return;
+    }
+
+    switch (type) {
+        case power_type_capacity:
+            sscanf(data, "%d", &capacity);
+            break;
+        case power_type_charge_full:
+            sscanf(data, "%d", &charge_full);
+            break;
+        case power_type_charge_now:
+            sscanf(data, "%d", &charge_now);
+            break;
+        default:
+            return;
+    }
+}
+
+static void get_power_data(enum power_types type, char* msg_info)
+{
+    if (msg_info == NULL) {
+        return;
+    }
+
+    switch (type) {
+        case power_type_capacity:
+            sprintf(msg_info, "%d", capacity);
+            break;
+        case power_type_charge_full:
+            sprintf(msg_info, "%d", charge_full);
+            break;
+        case power_type_charge_now:
+            sprintf(msg_info, "%d", charge_now);
+            break;
+        default:
+            return;
+    }
+}
+
+void set_power_capacity(int level) {
+    capacity = level;
+}
+
+int get_power_capacity(void) {
+    return capacity;
+}
+
+void set_power_charge_full(int full){
+    charge_full = full;
+}
+
+int get_power_charge_full(void){
+    return charge_full;
+}
+
+void set_power_charge_now(int now){
+    charge_now = now;
+}
+
+int get_power_charge_now(void){
+    return charge_now;
+}
+
+static void answer_power_data_request(int type, char* data, VirtQueueElement *elem)
+{
+    msg_info* msginfo = (msg_info*) malloc(sizeof(msg_info));
+    if (!msginfo) {
+        ERR("msginfo is NULL!\n");
+        return;
+    }
+
+    msginfo->req = request_answer;
+    msginfo->type = type;
+    get_power_data(type, msginfo->buf);
+
+    TRACE("sending message: %s, type: %d, req: %d\n", msginfo->buf, msginfo->type, msginfo->req);
+
+    memset(elem->in_sg[0].iov_base, 0, elem->in_sg[0].iov_len);
+    memcpy(elem->in_sg[0].iov_base, msginfo, sizeof(struct msg_info));
+
+    if (msginfo)
+        free(msginfo);
+}
+
+static void handle_msg(struct msg_info *msg, VirtQueueElement *elem)
+{
+    unsigned int len = 0;
+
+    if (msg == NULL) {
+        ERR("msg info structure is NULL.\n");
+        return;
+    }
+
+    if (msg->req == request_set) {
+        set_power_data (msg->type, msg->buf, strlen(msg->buf));
+    } else if (msg->req == request_get) {
+        answer_power_data_request(msg->type, msg->buf, elem);
+        len = sizeof(msg_info);
+    }
+
+    virtqueue_push(vpower->vq, elem, len);
+    virtio_notify(&vpower->vdev, vpower->vq);
+}
+
+static void virtio_power_vq(VirtIODevice *vdev, VirtQueue *vq)
+{
+    VirtIOPOWER *vpower = (VirtIOPOWER*)vdev;
+    struct msg_info msg;
+    VirtQueueElement elem;
+    int index = 0;
+
+    if (vpower->vq == NULL) {
+        ERR("virt queue is not ready.\n");
+        return;
+    }
+
+    if (!virtio_queue_ready(vpower->vq)) {
+        ERR("virtqueue is not ready.");
+        return;
+    }
+
+    if (virtio_queue_empty(vpower->vq)) {
+        ERR("<< virtqueue is empty.\n");
+        return;
+    }
+
+    while ((index = virtqueue_pop(vq, &elem))) {
+        memset(&msg, 0x00, sizeof(msg));
+        memcpy(&msg, elem.out_sg[0].iov_base, elem.out_sg[0].iov_len);
+
+        TRACE("handling msg from driver: %s, len: %d, type: %d, req: %d, index: %d\n", msg.buf, strlen(msg.buf), msg.type, msg.req, index);
+
+        handle_msg(&msg, &elem);
+    }
+}
+
+static void virtio_power_realize(DeviceState *dev, Error **errp)
+{
+    INFO("initialize virtio-power device\n");
+
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    vpower = VIRTIO_POWER(vdev);
+
+    virtio_init(vdev, POWER_DEVICE_NAME, VIRTIO_ID_POWER, 0);
+
+    if (vpower == NULL) {
+        ERR("failed to initialize power device\n");
+        return;
+    }
+
+    vpower->vq = virtio_add_queue(&vpower->vdev, 64, virtio_power_vq);
+}
+
+static void virtio_power_unrealize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    INFO("destroy power device\n");
+
+    virtio_cleanup(vdev);
+}
+
+
+static void virtio_power_reset(VirtIODevice *vdev)
+{
+    TRACE("virtio_power_reset.\n");
+}
+
+static uint32_t virtio_power_get_features(VirtIODevice *vdev,
+                                            uint32_t request_feature)
+{
+    TRACE("virtio_power_get_features.\n");
+    return 0;
+}
+
+static void virtio_power_class_init(ObjectClass *klass, void *data)
+{
+    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+    vdc->realize = virtio_power_realize;
+    vdc->unrealize = virtio_power_unrealize;
+    vdc->get_features = virtio_power_get_features;
+    vdc->reset = virtio_power_reset;
+}
+
+static const TypeInfo virtio_device_info = {
+    .name = TYPE_VIRTIO_POWER,
+    .parent = TYPE_VIRTIO_DEVICE,
+    .instance_size = sizeof(VirtIOPOWER),
+    .class_init = virtio_power_class_init,
+};
+
+static void virtio_register_types(void)
+{
+    type_register_static(&virtio_device_info);
+}
+
+type_init(virtio_register_types)
+
diff --git a/tizen/src/hw/virtio/maru_virtio_power.h b/tizen/src/hw/virtio/maru_virtio_power.h
new file mode 100644 (file)
index 0000000..0a76fec
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Virtio Power Device
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Jinhyung choi   <jinhyung2.choi@samsung.com>
+ *  Daiyoung Kim    <daiyoung777.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_VIRTIO_POWER_H_
+#define MARU_VIRTIO_POWER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "hw/virtio/virtio.h"
+
+#define TYPE_VIRTIO_POWER "virtio-power-device"
+#define VIRTIO_POWER(obj) \
+        OBJECT_CHECK(VirtIOPOWER, (obj), TYPE_VIRTIO_POWER)
+
+enum power_types {
+    power_type_capacity = 0,
+    power_type_charge_full,
+    power_type_charge_now,
+    power_type_max
+};
+
+typedef struct VirtIOPOWER {
+    VirtIODevice    vdev;
+    VirtQueue       *vq;
+    DeviceState     *qdev;
+
+    QEMUBH          *bh;
+} VirtIOPOWER;
+
+void set_power_capacity(int capacity);
+int get_power_capacity(void);
+void set_power_charge_full(int full);
+int get_power_charge_full(void);
+void set_power_charge_now(int now);
+int get_power_charge_now(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tizen/src/hw/virtio/maru_virtio_sensor.c b/tizen/src/hw/virtio/maru_virtio_sensor.c
new file mode 100644 (file)
index 0000000..95516dd
--- /dev/null
@@ -0,0 +1,597 @@
+/*
+ * Virtio Sensor Device
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Jinhyung Choi <jinhyung2.choi@samsung.com>
+ *  Daiyoung Kim <daiyoung777.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 "hw/pci/pci.h"
+
+#include "hw/maru_device_ids.h"
+#include "maru_virtio_sensor.h"
+#include "debug_ch.h"
+#include "ecs/ecs.h"
+
+MULTI_DEBUG_CHANNEL(qemu, virtio-sensor);
+
+#define SENSOR_DEVICE_NAME  "sensor"
+#define _MAX_BUF            1024
+#define __MAX_BUF_SENSOR    32
+
+static QemuMutex accel_mutex;
+static QemuMutex geo_mutex;
+static QemuMutex gyro_mutex;
+static QemuMutex light_mutex;
+static QemuMutex proxi_mutex;
+
+static char accel_xyz [__MAX_BUF_SENSOR] = {'0',',','9','8','0','6','6','5',',','0'};
+static int accel_enable = 0;
+static int accel_delay = 200000000;
+
+static char geo_raw [__MAX_BUF_SENSOR] = {'0',' ','-','9','0',' ','0',' ','3'};
+static char geo_tesla [__MAX_BUF_SENSOR] = {'1',' ','0',' ','-','1','0'};
+static int geo_enable = 0;
+static int geo_delay = 200000000;
+
+static int gyro_x_raw = 0;
+static int gyro_y_raw = 0;
+static int gyro_z_raw = 0;
+static int gyro_enable = 0;
+static int gyro_delay = 200000000;
+
+static int light_adc = 65535;
+static int light_level = 10;
+static int light_enable = 0;
+static int light_delay = 200000000;
+
+static int proxi_vo = 8;
+static int proxi_enable = 0;
+static int proxi_delay = 200000000;
+
+VirtIOSENSOR* vsensor;
+static int sensor_capability = 0;
+
+typedef struct msg_info {
+    char buf[_MAX_BUF];
+
+    uint16_t type;
+    uint16_t req;
+} msg_info;
+
+static type_action get_action(enum sensor_types type)
+{
+    type_action action = 0;
+
+    switch (type) {
+    case sensor_type_accel:
+        action = ACTION_ACCEL;
+        break;
+    case sensor_type_gyro:
+        action = ACTION_GYRO;
+        break;
+    case sensor_type_mag:
+        action = ACTION_MAG;
+        break;
+    case sensor_type_light:
+        action = ACTION_LIGHT;
+        break;
+    case sensor_type_proxi:
+        action = ACTION_PROXI;
+        break;
+    default:
+        break;
+    }
+
+    return action;
+}
+
+static void send_sensor_to_ecs(const char* data, enum sensor_types type)
+{
+    type_length length = 0;
+    type_group group = GROUP_STATUS;
+    type_action action = 0;
+    int buf_len = strlen(data);
+    int message_len =  buf_len + 14;
+
+    char* ecs_message = (char*) malloc(message_len + 1);
+    if (!ecs_message)
+        return;
+
+    memset(ecs_message, 0, message_len + 1);
+
+    length = (unsigned short) buf_len;
+    action = get_action(type);
+
+    memcpy(ecs_message, MESSAGE_TYPE_SENSOR, 6);
+    memcpy(ecs_message + 10, &length, sizeof(unsigned short));
+    memcpy(ecs_message + 12, &group, sizeof(unsigned char));
+    memcpy(ecs_message + 13, &action, sizeof(unsigned char));
+    memcpy(ecs_message + 14, data, buf_len);
+
+    TRACE("ntf_to_injector- len: %d, group: %d, action: %d, data: %s\n", length, group, action, data);
+
+    send_device_ntf(ecs_message, message_len);
+
+    if (ecs_message)
+        free(ecs_message);
+}
+
+static void __set_sensor_data (enum sensor_types type, char* data, int len)
+{
+    if (len < 0 || len > __MAX_BUF_SENSOR) {
+        ERR("sensor data size is wrong.\n");
+        return;
+    }
+
+    if (data == NULL) {
+        ERR("sensor data is NULL.\n");
+        return;
+    }
+
+    TRACE("set_sensor_data with type '%d' with data '%s'", type, data);
+
+    switch (type) {
+        case sensor_type_accel:
+            qemu_mutex_lock(&accel_mutex);
+            strcpy(accel_xyz, data);
+            qemu_mutex_unlock(&accel_mutex);
+            break;
+        case sensor_type_accel_enable:
+            qemu_mutex_lock(&accel_mutex);
+            sscanf(data, "%d", &accel_enable);
+            qemu_mutex_unlock(&accel_mutex);
+            break;
+        case sensor_type_accel_delay:
+            qemu_mutex_lock(&accel_mutex);
+            sscanf(data, "%d", &accel_delay);
+            qemu_mutex_unlock(&accel_mutex);
+            break;
+        case sensor_type_gyro_enable:
+            qemu_mutex_lock(&gyro_mutex);
+            sscanf(data, "%d", &gyro_enable);
+            qemu_mutex_unlock(&gyro_mutex);
+            break;
+        case sensor_type_gyro_delay:
+            qemu_mutex_lock(&gyro_mutex);
+            sscanf(data, "%d", &gyro_delay);
+            qemu_mutex_unlock(&gyro_mutex);
+            break;
+        case sensor_type_gyro_x:
+            qemu_mutex_lock(&gyro_mutex);
+            sscanf(data, "%d", &gyro_x_raw);
+            qemu_mutex_unlock(&gyro_mutex);
+            break;
+        case sensor_type_gyro_y:
+            qemu_mutex_lock(&gyro_mutex);
+            sscanf(data, "%d", &gyro_y_raw);
+            qemu_mutex_unlock(&gyro_mutex);
+            break;
+        case sensor_type_gyro_z:
+            qemu_mutex_lock(&gyro_mutex);
+            sscanf(data, "%d", &gyro_z_raw);
+            qemu_mutex_unlock(&gyro_mutex);
+            break;
+        case sensor_type_gyro:
+            qemu_mutex_lock(&gyro_mutex);
+            sscanf(data, "%d %d %d", &gyro_x_raw, &gyro_y_raw, &gyro_z_raw);
+            qemu_mutex_unlock(&gyro_mutex);
+            break;
+        case sensor_type_light_adc:
+            qemu_mutex_lock(&light_mutex);
+            sscanf(data, "%d", &light_adc);
+            light_level = (light_adc / 6554) % 10 + 1;
+            qemu_mutex_unlock(&light_mutex);
+            break;
+        case sensor_type_light_level:
+            qemu_mutex_lock(&light_mutex);
+            sscanf(data, "%d", &light_level);
+            qemu_mutex_unlock(&light_mutex);
+            break;
+        case sensor_type_light_enable:
+            qemu_mutex_lock(&light_mutex);
+            sscanf(data, "%d", &light_enable);
+            qemu_mutex_unlock(&light_mutex);
+            break;
+        case sensor_type_light_delay:
+            qemu_mutex_lock(&light_mutex);
+            sscanf(data, "%d", &light_delay);
+            qemu_mutex_unlock(&light_mutex);
+            break;
+        case sensor_type_proxi:
+            qemu_mutex_lock(&proxi_mutex);
+            sscanf(data, "%d", &proxi_vo);
+            qemu_mutex_unlock(&proxi_mutex);
+            break;
+        case sensor_type_proxi_enable:
+            qemu_mutex_lock(&proxi_mutex);
+            sscanf(data, "%d", &proxi_enable);
+            qemu_mutex_unlock(&proxi_mutex);
+            break;
+        case sensor_type_proxi_delay:
+            qemu_mutex_lock(&proxi_mutex);
+            sscanf(data, "%d", &proxi_delay);
+            qemu_mutex_unlock(&proxi_mutex);
+            break;
+        case sensor_type_mag:
+            qemu_mutex_lock(&geo_mutex);
+            strcpy(geo_tesla, data);
+            qemu_mutex_unlock(&geo_mutex);
+            break;
+        case sensor_type_tilt:
+            qemu_mutex_lock(&geo_mutex);
+            strcpy(geo_raw, data);
+            qemu_mutex_unlock(&geo_mutex);
+            break;
+        case sensor_type_geo_enable:
+            qemu_mutex_lock(&geo_mutex);
+            sscanf(data, "%d", &geo_enable);
+            qemu_mutex_unlock(&geo_mutex);
+            break;
+        case sensor_type_geo_delay:
+            qemu_mutex_lock(&geo_mutex);
+            sscanf(data, "%d", &geo_delay);
+            qemu_mutex_unlock(&geo_mutex);
+            break;
+        default:
+            return;
+    }
+}
+
+static void __get_sensor_data(enum sensor_types type, char* msg_info)
+{
+    if (msg_info == NULL) {
+        return;
+    }
+
+    switch (type) {
+        case sensor_type_list:
+            sprintf(msg_info, "%d", sensor_capability);
+            break;
+        case sensor_type_accel:
+            qemu_mutex_lock(&accel_mutex);
+            strcpy(msg_info, accel_xyz);
+            qemu_mutex_unlock(&accel_mutex);
+            break;
+        case sensor_type_accel_enable:
+            qemu_mutex_lock(&accel_mutex);
+            sprintf(msg_info, "%d", accel_enable);
+            qemu_mutex_unlock(&accel_mutex);
+            break;
+        case sensor_type_accel_delay:
+            qemu_mutex_lock(&accel_mutex);
+            sprintf(msg_info, "%d", accel_delay);
+            qemu_mutex_unlock(&accel_mutex);
+            break;
+        case sensor_type_mag:
+            qemu_mutex_lock(&geo_mutex);
+            strcpy(msg_info, geo_tesla);
+            qemu_mutex_unlock(&geo_mutex);
+            break;
+        case sensor_type_tilt:
+            qemu_mutex_lock(&geo_mutex);
+            strcpy(msg_info, geo_raw);
+            qemu_mutex_unlock(&geo_mutex);
+            break;
+        case sensor_type_geo_enable:
+            qemu_mutex_lock(&geo_mutex);
+            sprintf(msg_info, "%d", geo_enable);
+            qemu_mutex_unlock(&geo_mutex);
+            break;
+        case sensor_type_geo_delay:
+            qemu_mutex_lock(&geo_mutex);
+            sprintf(msg_info, "%d", geo_delay);
+            qemu_mutex_unlock(&geo_mutex);
+            break;
+        case sensor_type_gyro:
+            qemu_mutex_lock(&gyro_mutex);
+            sprintf(msg_info, "%d,%d,%d", gyro_x_raw, gyro_y_raw, gyro_z_raw);
+            qemu_mutex_unlock(&gyro_mutex);
+            break;
+        case sensor_type_gyro_enable:
+            qemu_mutex_lock(&gyro_mutex);
+            sprintf(msg_info, "%d", gyro_enable);
+            qemu_mutex_unlock(&gyro_mutex);
+            break;
+        case sensor_type_gyro_delay:
+            qemu_mutex_lock(&gyro_mutex);
+            sprintf(msg_info, "%d", gyro_delay);
+            qemu_mutex_unlock(&gyro_mutex);
+            break;
+        case sensor_type_gyro_x:
+            qemu_mutex_lock(&gyro_mutex);
+            sprintf(msg_info, "%d", gyro_x_raw);
+            qemu_mutex_unlock(&gyro_mutex);
+            break;
+        case sensor_type_gyro_y:
+            qemu_mutex_lock(&gyro_mutex);
+            sprintf(msg_info, "%d", gyro_y_raw);
+            qemu_mutex_unlock(&gyro_mutex);
+            break;
+        case sensor_type_gyro_z:
+            qemu_mutex_lock(&gyro_mutex);
+            sprintf(msg_info, "%d", gyro_z_raw);
+            qemu_mutex_unlock(&gyro_mutex);
+            break;
+        case sensor_type_light:
+        case sensor_type_light_adc:
+            qemu_mutex_lock(&light_mutex);
+            sprintf(msg_info, "%d", light_adc);
+            qemu_mutex_unlock(&light_mutex);
+            break;
+        case sensor_type_light_level:
+            qemu_mutex_lock(&light_mutex);
+            sprintf(msg_info, "%d", light_level);
+            qemu_mutex_unlock(&light_mutex);
+            break;
+        case sensor_type_light_enable:
+            qemu_mutex_lock(&light_mutex);
+            sprintf(msg_info, "%d", light_enable);
+            qemu_mutex_unlock(&light_mutex);
+            break;
+        case sensor_type_light_delay:
+            qemu_mutex_lock(&light_mutex);
+            sprintf(msg_info, "%d", light_delay);
+            qemu_mutex_unlock(&light_mutex);
+            break;
+        case sensor_type_proxi:
+            qemu_mutex_lock(&proxi_mutex);
+            sprintf(msg_info, "%d", proxi_vo);
+            qemu_mutex_unlock(&proxi_mutex);
+            break;
+        case sensor_type_proxi_enable:
+            qemu_mutex_lock(&proxi_mutex);
+            sprintf(msg_info, "%d", proxi_enable);
+            qemu_mutex_unlock(&proxi_mutex);
+            break;
+        case sensor_type_proxi_delay:
+            qemu_mutex_lock(&proxi_mutex);
+            sprintf(msg_info, "%d", proxi_delay);
+            qemu_mutex_unlock(&proxi_mutex);
+            break;
+        default:
+            return;
+    }
+}
+
+void req_sensor_data (enum sensor_types type, enum request_cmd req, char* data, int len)
+{
+    char msg_info [__MAX_BUF_SENSOR];
+    memset(msg_info, 0, __MAX_BUF_SENSOR);
+
+    if (type >= sensor_type_max || (req != request_get && req != request_set)) {
+        ERR("unavailable sensor type request.\n");
+        return;
+    }
+
+    if (req == request_set) {
+        __set_sensor_data (type, data, len);
+    } else if (req == request_get) {
+        __get_sensor_data(type, msg_info);
+        send_sensor_to_ecs(msg_info, type);
+    }
+}
+
+static void answer_sensor_data_request(int type, char* data, VirtQueueElement *elem)
+{
+    msg_info* msginfo = (msg_info*) malloc(sizeof(msg_info));
+    if (!msginfo) {
+        ERR("msginfo is NULL!\n");
+        return;
+    }
+
+    msginfo->req = request_answer;
+    msginfo->type = type;
+    __get_sensor_data(type, msginfo->buf);
+
+    TRACE("sending message: %s, type: %d, req: %d\n", msginfo->buf, msginfo->type, msginfo->req);
+
+    memset(elem->in_sg[0].iov_base, 0, elem->in_sg[0].iov_len);
+    memcpy(elem->in_sg[0].iov_base, msginfo, sizeof(struct msg_info));
+
+    if (msginfo)
+        free(msginfo);
+}
+
+static void handle_msg(struct msg_info *msg, VirtQueueElement *elem)
+{
+    unsigned int len = 0;
+
+    if (msg == NULL) {
+        ERR("msg info structure is NULL.\n");
+        return;
+    }
+
+    if (msg->req == request_set) {
+        __set_sensor_data (msg->type, msg->buf, strlen(msg->buf));
+    } else if (msg->req == request_get) {
+        answer_sensor_data_request(msg->type, msg->buf, elem);
+        len = sizeof(msg_info);
+    }
+
+    virtqueue_push(vsensor->vq, elem, len);
+    virtio_notify(&vsensor->vdev, vsensor->vq);
+}
+
+static void virtio_sensor_vq(VirtIODevice *vdev, VirtQueue *vq)
+{
+    VirtIOSENSOR *vsensor = (VirtIOSENSOR*)vdev;
+    struct msg_info msg;
+    VirtQueueElement elem;
+    int index = 0;
+
+    if (vsensor->vq == NULL) {
+        ERR("virt queue is not ready.\n");
+        return;
+    }
+
+    if (!virtio_queue_ready(vsensor->vq)) {
+        ERR("virtqueue is not ready.");
+        return;
+    }
+
+    if (virtio_queue_empty(vsensor->vq)) {
+        ERR("<< virtqueue is empty.\n");
+        return;
+    }
+
+    while ((index = virtqueue_pop(vq, &elem))) {
+        memset(&msg, 0x00, sizeof(msg));
+        memcpy(&msg, elem.out_sg[0].iov_base, elem.out_sg[0].iov_len);
+
+        TRACE("handling msg from driver: %s, len: %d, type: %d, req: %d, index: %d\n", msg.buf, strlen(msg.buf), msg.type, msg.req, index);
+
+        handle_msg(&msg, &elem);
+    }
+}
+
+static int set_capability(char* sensor)
+{
+    if (!strncmp(sensor, SENSOR_NAME_ACCEL, 5)) {
+        return sensor_cap_accel;
+    } else if (!strncmp(sensor, SENSOR_NAME_GEO, 3)) {
+        return sensor_cap_geo;
+    } else if (!strncmp(sensor, SENSOR_NAME_GYRO, 4)) {
+        return sensor_cap_gyro;
+    } else if (!strncmp(sensor, SENSOR_NAME_LIGHT, 5)) {
+        return sensor_cap_light;
+    } else if (!strncmp(sensor, SENSOR_NAME_PROXI, 5)) {
+        return sensor_cap_proxi;
+    } else if (!strncmp(sensor, SENSOR_NAME_HAPTIC, 6)) {
+        return sensor_cap_haptic;
+    } else {
+        ERR("unknown sensor request: %s", sensor);
+    }
+
+    return 0;
+}
+
+static void parse_sensor_capability(char* lists)
+{
+    char token[] = SENSOR_CAP_TOKEN;
+    char* data = NULL;
+
+    if (lists == NULL)
+        return;
+
+    data = strtok(lists, token);
+    if (data != NULL) {
+        sensor_capability |= set_capability(data);
+        while ((data = strtok(NULL, token)) != NULL) {
+            sensor_capability |= set_capability(data);
+        }
+    }
+
+    INFO("sensor device capabilty enabled with %02x\n", sensor_capability);
+}
+
+static void virtio_sensor_realize(DeviceState *dev, Error **errp)
+{
+    INFO("initialize virtio-sensor device\n");
+
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    vsensor = VIRTIO_SENSOR(vdev);
+
+    virtio_init(vdev, SENSOR_DEVICE_NAME, VIRTIO_ID_SENSOR, 0);
+
+    if (vsensor == NULL) {
+        ERR("failed to initialize sensor device\n");
+        error_set(errp, QERR_DEVICE_INIT_FAILED, SENSOR_DEVICE_NAME);
+        return;
+    }
+
+    qemu_mutex_init(&accel_mutex);
+    qemu_mutex_init(&gyro_mutex);
+    qemu_mutex_init(&geo_mutex);
+    qemu_mutex_init(&light_mutex);
+    qemu_mutex_init(&proxi_mutex);
+
+    vsensor->vq = virtio_add_queue(&vsensor->vdev, 64, virtio_sensor_vq);
+
+    INFO("initialized sensor type: %s\n", vsensor->sensors);
+
+    if (vsensor->sensors) {
+        parse_sensor_capability(vsensor->sensors);
+    }
+}
+
+static void virtio_sensor_unrealize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    INFO("destroy sensor device\n");
+
+    qemu_mutex_destroy(&accel_mutex);
+    qemu_mutex_destroy(&gyro_mutex);
+    qemu_mutex_destroy(&geo_mutex);
+    qemu_mutex_destroy(&light_mutex);
+    qemu_mutex_destroy(&proxi_mutex);
+
+    virtio_cleanup(vdev);
+}
+
+
+static void virtio_sensor_reset(VirtIODevice *vdev)
+{
+    TRACE("virtio_sensor_reset.\n");
+}
+
+static uint32_t virtio_sensor_get_features(VirtIODevice *vdev,
+                                            uint32_t request_feature)
+{
+    TRACE("virtio_sensor_get_features.\n");
+    return 0;
+}
+
+static Property virtio_sensor_properties[] = {
+    DEFINE_PROP_STRING(ATTRIBUTE_NAME_SENSORS, VirtIOSENSOR, sensors),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_sensor_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    dc->props = virtio_sensor_properties;
+    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+    vdc->unrealize= virtio_sensor_unrealize;
+    vdc->realize = virtio_sensor_realize;
+    vdc->get_features = virtio_sensor_get_features;
+    vdc->reset = virtio_sensor_reset;
+}
+
+static const TypeInfo virtio_device_info = {
+    .name = TYPE_VIRTIO_SENSOR,
+    .parent = TYPE_VIRTIO_DEVICE,
+    .instance_size = sizeof(VirtIOSENSOR),
+    .class_init = virtio_sensor_class_init,
+};
+
+static void virtio_register_types(void)
+{
+    type_register_static(&virtio_device_info);
+}
+
+type_init(virtio_register_types)
+
diff --git a/tizen/src/hw/virtio/maru_virtio_sensor.h b/tizen/src/hw/virtio/maru_virtio_sensor.h
new file mode 100644 (file)
index 0000000..382c0c4
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Virtio Sensor Device
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Jinhyung choi   <jinhyung2.choi@samsung.com>
+ *  Daiyoung Kim    <daiyoung777.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_VIRTIO_SENSOR_H_
+#define MARU_VIRTIO_SENSOR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "hw/virtio/virtio.h"
+
+enum request_cmd {
+    request_get = 0,
+    request_set,
+    request_answer
+};
+
+enum sensor_types {
+    sensor_type_list = 0,
+    sensor_type_accel,
+    sensor_type_accel_enable,
+    sensor_type_accel_delay,
+    sensor_type_geo,
+    sensor_type_geo_enable,
+    sensor_type_geo_delay,
+    sensor_type_gyro,
+    sensor_type_gyro_enable,
+    sensor_type_gyro_delay,
+    sensor_type_gyro_x,
+    sensor_type_gyro_y,
+    sensor_type_gyro_z,
+    sensor_type_light,
+    sensor_type_light_enable,
+    sensor_type_light_delay,
+    sensor_type_light_adc,
+    sensor_type_light_level,
+    sensor_type_proxi,
+    sensor_type_proxi_enable,
+    sensor_type_proxi_delay,
+    sensor_type_mag,
+    sensor_type_tilt,
+    sensor_type_max
+};
+
+enum sensor_capabilities {
+    sensor_cap_accel  = 0x01,
+    sensor_cap_geo    = 0x02,
+    sensor_cap_gyro   = 0x04,
+    sensor_cap_light  = 0x08,
+    sensor_cap_proxi  = 0x10,
+    sensor_cap_haptic = 0x20
+};
+
+#define MESSAGE_TYPE_SENSOR "sensor"
+
+#define GROUP_STATUS        15
+
+#define ACTION_ACCEL        110
+#define ACTION_GYRO         111
+#define ACTION_MAG          112
+#define ACTION_LIGHT        113
+#define ACTION_PROXI        114
+
+#define ATTRIBUTE_NAME_SENSORS "sensors"
+
+#define SENSOR_NAME_ACCEL  "accel"
+#define SENSOR_NAME_GYRO   "gyro"
+#define SENSOR_NAME_GEO    "geo"
+#define SENSOR_NAME_LIGHT  "light"
+#define SENSOR_NAME_PROXI  "proxi"
+#define SENSOR_NAME_HAPTIC "haptic"
+
+#define SENSOR_CAP_TOKEN "&"
+
+#define TYPE_VIRTIO_SENSOR "virtio-sensor-device"
+#define VIRTIO_SENSOR(obj) \
+        OBJECT_CHECK(VirtIOSENSOR, (obj), TYPE_VIRTIO_SENSOR)
+
+typedef struct VirtIOSENSOR {
+    VirtIODevice    vdev;
+    VirtQueue       *vq;
+    DeviceState     *qdev;
+
+    char            *sensors;
+} VirtIOSENSOR;
+
+void req_sensor_data(enum sensor_types type, enum request_cmd req, char* data, int len);
+
+#define get_sensor_accel()  \
+    req_sensor_data(sensor_type_accel, request_get, NULL, 0);
+
+#define get_sensor_gyro()   \
+    req_sensor_data(sensor_type_gyro, request_get, NULL, 0);
+
+#define get_sensor_mag()    \
+    req_sensor_data(sensor_type_mag, request_get, NULL, 0);
+
+#define get_sensor_light()  \
+    req_sensor_data(sensor_type_light_adc, request_get, NULL, 0);
+
+#define get_sensor_proxi()  \
+    req_sensor_data(sensor_type_proxi, request_get, NULL, 0);
+
+#define set_sensor_accel(data, len) \
+    req_sensor_data(sensor_type_accel, request_set, data, len);
+
+#define set_sensor_proxi(data, len) \
+    req_sensor_data(sensor_type_proxi, request_set, data, len);
+
+#define set_sensor_light(data, len) \
+    req_sensor_data(sensor_type_light_adc, request_set, data, len);
+
+#define set_sensor_gyro(data, len)  \
+    req_sensor_data(sensor_type_gyro, request_set, data, len);
+
+#define set_sensor_tilt(data, len)  \
+    req_sensor_data(sensor_type_tilt, request_set, data, len);
+
+#define set_sensor_mag(data, len)   \
+    req_sensor_data(sensor_type_mag, request_set, data, len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/tizen/src/hw/virtio/maru_virtio_touchscreen.c b/tizen/src/hw/virtio/maru_virtio_touchscreen.c
new file mode 100644 (file)
index 0000000..4e60b8b
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ * Maru Virtio Touchscreen Device
+ *
+ * Copyright (c) 2011 - 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 "maru_virtio_touchscreen.h"
+#include "hw/maru_device_ids.h"
+#include "emul_state.h"
+#include "debug_ch.h"
+
+MULTI_DEBUG_CHANNEL(qemu, touchscreen);
+
+
+#define DEVICE_NAME "virtio-touchscreen"
+
+/*
+ * touch event queue
+ */
+typedef struct TouchEventEntry {
+    unsigned int index;
+    EmulTouchEvent touch;
+
+    QTAILQ_ENTRY(TouchEventEntry) node;
+} TouchEventEntry;
+
+/* the maximum number of touch event that can be put into a queue */
+#define MAX_TOUCH_EVENT_CNT 256
+
+static TouchEventEntry _events_buf[MAX_TOUCH_EVENT_CNT];
+static QTAILQ_HEAD(, TouchEventEntry) 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 ElementEntry _elem_buf[10];
+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 */
+
+
+VirtIOTouchscreen *ts;
+
+/* lock for between communication thread and IO thread */
+static pthread_mutex_t event_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t elem_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+
+void virtio_touchscreen_event(int x, int y, int z, int buttons_state)
+{
+    TouchEventEntry *entry = NULL;
+
+    if (unlikely(!virtio_queue_ready(ts->vq))) {
+        ERR("virtio queue is not ready\n");
+        return;
+    }
+
+    if (unlikely(event_queue_cnt >= MAX_TOUCH_EVENT_CNT)) {
+        INFO("full touch event queue, lose event\n", event_queue_cnt);
+
+        qemu_bh_schedule(ts->bh);
+        return;
+    }
+
+    entry = &(_events_buf[event_ringbuf_cnt % MAX_TOUCH_EVENT_CNT]);
+    event_ringbuf_cnt++;
+
+    /* mouse event is copied into the queue */
+    entry->touch.x = x;
+    entry->touch.y = y;
+    entry->touch.z = z;
+    entry->touch.state = buttons_state;
+
+    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_touchscreen_notify */
+    qemu_bh_schedule(ts->bh);
+
+    TRACE("touch event (%d) : x=%d, y=%d, z=%d, state=%d\n",
+        entry->index, entry->touch.x, entry->touch.y,
+        entry->touch.z, entry->touch.state);
+}
+
+static void maru_virtio_touchscreen_handle(VirtIODevice *vdev, VirtQueue *vq)
+{
+#if 0 /* not used yet */
+    if (ts->eh_entry == NULL) {
+        void *vbuf = NULL;
+        VirtQueueElement elem;
+        int max_trkid = 0;
+
+        virtqueue_pop(ts->vq, &elem);
+        vbuf = elem.in_sg[0].iov_base;
+        memcpy(&max_trkid, vbuf, sizeof(max_trkid));
+
+        if (max_trkid > 0) {
+            INFO("virtio touchscreen's maximum of tracking id = %d\n", max_trkid);
+
+            /* register a event handler */
+            ts->eh_entry = qemu_add_mouse_event_handler(
+                virtio_touchscreen_event, ts, 1, "QEMU Virtio Touchscreen");
+            qemu_activate_mouse_event_handler(ts->eh_entry);
+
+            //TODO:
+            virtqueue_push(ts->vq, &elem, 0);
+            virtio_notify(&(ts->vdev), ts->vq);
+        } else {
+            INFO("virtio touchscreen is not added to qemu mouse event handler\n");
+        }
+    }
+#endif
+
+    int virt_sg_index = 0;
+    ElementEntry *elem_entry = NULL;
+
+    TRACE("maru_virtio_touchscreen_handle\n");
+
+    if (unlikely(virtio_queue_empty(ts->vq))) {
+        TRACE("virtqueue is empty\n");
+        return;
+    }
+
+    while (true) {
+        elem_entry = &(_elem_buf[elem_ringbuf_cnt % 10]);
+        elem_ringbuf_cnt++;
+
+        virt_sg_index = virtqueue_pop(ts->vq, &elem_entry->elem);
+        if (virt_sg_index == 0) {
+            elem_ringbuf_cnt--;
+            break;
+        } else if (virt_sg_index < 0) {
+            ERR("virtqueue is broken\n");
+            elem_ringbuf_cnt--;
+            return;
+        }
+
+        pthread_mutex_lock(&elem_mutex);
+
+        elem_entry->el_index = ++elem_queue_cnt;
+        elem_entry->sg_index = (unsigned int)virt_sg_index;
+
+        /* save VirtQueueElement */
+        QTAILQ_INSERT_TAIL(&elem_queue, elem_entry, node);
+
+        if (ts->waitBuf == true) {
+            ts->waitBuf = false;
+
+            /* call maru_virtio_touchscreen_notify */
+            qemu_bh_schedule(ts->bh);
+        }
+
+        pthread_mutex_unlock(&elem_mutex);
+    }
+}
+
+void maru_virtio_touchscreen_notify(void)
+{
+    ElementEntry *elem_entry = NULL;
+    unsigned int ii = 0;
+
+    TRACE("maru_virtio_touchscreen_notify\n");
+
+    if (unlikely(!virtio_queue_ready(ts->vq))) {
+        ERR("virtio queue is not ready\n");
+        return;
+    }
+
+    while (true) {
+        if (event_queue_cnt == 0) {
+            TRACE("no event\n");
+            break;
+        } else if (elem_queue_cnt == 0) {
+            TRACE("no buffer\n");
+
+            pthread_mutex_lock(&elem_mutex);
+            /* maybe next time */
+            ts->waitBuf = true;
+            pthread_mutex_unlock(&elem_mutex);
+            break;
+        }
+
+        elem_entry = QTAILQ_FIRST(&elem_queue);
+
+        if (elem_entry->sg_index > 0) {
+            TouchEventEntry *event_entry = NULL;
+            VirtQueueElement *element = NULL;
+            void *vbuf = NULL;
+
+            element = &elem_entry->elem;
+            vbuf = element->in_sg[elem_entry->sg_index - 1].iov_base;
+
+            /* get touch event from host queue */
+            event_entry = QTAILQ_FIRST(&events_queue);
+
+            TRACE("touch(%d) : x=%d, y=%d, z=%d, state=%d | \
+                event_queue_cnt=%d, elem.index=%d, elem.in_num=%d, sg_index=%d\n",
+                event_entry->index, event_entry->touch.x, event_entry->touch.y,
+                event_entry->touch.z, event_entry->touch.state,
+                event_queue_cnt, element->index, element->in_num,
+                elem_entry->sg_index);
+
+            /* copy event into virtio buffer */
+            memcpy(vbuf, &(event_entry->touch), sizeof(event_entry->touch));
+
+            pthread_mutex_lock(&event_mutex);
+
+            /* remove host event */
+            QTAILQ_REMOVE(&events_queue, event_entry, node);
+            event_queue_cnt--;
+
+            pthread_mutex_unlock(&event_mutex);
+
+            /* put buffer into virtio queue */
+            virtqueue_fill(ts->vq, element, sizeof(EmulTouchEvent), ii++);
+        }
+
+        pthread_mutex_lock(&elem_mutex);
+
+        QTAILQ_REMOVE(&elem_queue, elem_entry, node);
+        elem_queue_cnt--;
+
+        pthread_mutex_unlock(&elem_mutex);
+    }
+
+    if (ii != 0) {
+        /* signal other side */
+        virtqueue_flush(ts->vq, ii);
+        /* notify to guest */
+        virtio_notify(&(ts->vdev), ts->vq);
+    }
+}
+
+static void virtio_touchscreen_get_config(
+    VirtIODevice *vdev, uint8_t *config_data)
+{
+    int max_trkid = 10;
+    INFO("virtio_touchscreen_get_config\n");
+
+    max_trkid = get_emul_max_touch_point();
+    memcpy(config_data, &max_trkid, 4);
+}
+
+static void virtio_touchscreen_set_config(
+    VirtIODevice *vdev, const uint8_t *config_data)
+{
+    /* do nothing */
+}
+
+static uint32_t virtio_touchscreen_get_features(
+    VirtIODevice *vdev, uint32_t request_features)
+{
+    /* do nothing */
+
+    return request_features;
+}
+
+static void maru_touchscreen_bh(void *opaque)
+{
+    //TouchscreenState *ts = (TouchscreenState *)opaque;
+
+    maru_virtio_touchscreen_notify();
+}
+
+static void virtio_touchscreen_device_realize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    ts = VIRTIO_TOUCHSCREEN(dev);
+
+    INFO("initialize touchscreen device : %d\n", ts->max_finger);
+
+    virtio_init(vdev, DEVICE_NAME, VIRTIO_ID_TOUCHSCREEN, 4);
+    /*if (ts == NULL) {
+        ERR("failed to initialize the touchscreen device\n");
+        return NULL;
+    }*/
+
+    // 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);
+}
+
+static void virtio_touchscreen_device_unrealize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+
+    INFO("exit the touchscreen device\n");
+
+    if (ts->bh) {
+        qemu_bh_delete(ts->bh);
+    }
+
+    virtio_cleanup(vdev);
+
+    pthread_mutex_destroy(&event_mutex);
+    pthread_mutex_destroy(&elem_mutex);
+}
+
+static Property virtio_touchscreen_properties[] = {
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_touchscreen_device_reset(VirtIODevice *vdev)
+{
+    TouchEventEntry *event_entry = NULL;
+    ElementEntry *elem_entry = NULL;
+
+    INFO("reset the touchscreen device\n");
+
+    /* reset the counters */
+    event_ringbuf_cnt = 0;
+    elem_ringbuf_cnt = 0;
+
+    /* reset queue */
+    pthread_mutex_lock(&event_mutex);
+    while (event_queue_cnt > 0) {
+        event_entry = QTAILQ_FIRST(&events_queue);
+        QTAILQ_REMOVE(&events_queue, event_entry, node);
+
+        event_queue_cnt--;
+    }
+    pthread_mutex_unlock(&event_mutex);
+
+    pthread_mutex_lock(&elem_mutex);
+    while (elem_queue_cnt > 0) {
+        elem_entry = QTAILQ_FIRST(&elem_queue);
+        QTAILQ_REMOVE(&elem_queue, elem_entry, node);
+
+        elem_queue_cnt--;
+    }
+
+    ts->waitBuf = false;
+    pthread_mutex_unlock(&elem_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_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)
diff --git a/tizen/src/hw/virtio/maru_virtio_touchscreen.h b/tizen/src/hw/virtio/maru_virtio_touchscreen.h
new file mode 100644 (file)
index 0000000..042c577
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Maru Virtio Touchscreen Device
+ *
+ * Copyright (c) 2011 - 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_TOUCHSCREEN_H_
+#define MARU_TOUCHSCREEN_H_
+
+#include "hw/virtio/virtio.h"
+
+#define TYPE_VIRTIO_TOUCHSCREEN "virtio-touchscreen-device"
+#define VIRTIO_TOUCHSCREEN(obj) \
+        OBJECT_CHECK(VirtIOTouchscreen, (obj), TYPE_VIRTIO_TOUCHSCREEN)
+
+#define TOUCHSCREEN_OPTION_NAME "max_point"
+#define DEFAULT_MAX_FINGER (1)
+
+typedef struct VirtIOTouchscreen {
+    VirtIODevice vdev;
+    /* simply a queue into which buffers are posted
+    by the guest for consumption by the host */
+    VirtQueue *vq;
+    bool waitBuf;
+
+    QEMUBH *bh;
+    DeviceState *qdev;
+
+    unsigned int max_finger;
+} VirtIOTouchscreen;
+
+/* This structure must match the kernel definitions */
+typedef struct EmulTouchEvent {
+    uint16_t x, y, z;
+    uint8_t state;
+} EmulTouchEvent;
+
+void virtio_touchscreen_event(int x, int y, int z, int buttons_state);
+void maru_virtio_touchscreen_notify(void);
+
+#endif /* MARU_TOUCHSCREEN_H_ */
diff --git a/tizen/src/hw/virtio/maru_virtio_vmodem.c b/tizen/src/hw/virtio/maru_virtio_vmodem.c
new file mode 100644 (file)
index 0000000..93974fd
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ * Virtio Virtual Modem Device
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Sooyoung Ha <yoosah.ha@samsung.com>
+ *  SeokYeon Hwang <syeon.hwang@samsung.com>
+ *  Sangho Park <sangho1206.park@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 "hw/maru_device_ids.h"
+#include "maru_virtio_vmodem.h"
+#include "maru_virtio_evdi.h"
+#include "debug_ch.h"
+#include "ecs/ecs.h"
+
+MULTI_DEBUG_CHANNEL(qemu, virtio-vmodem);
+
+#define VMODEM_DEVICE_NAME "virtio-vmodem"
+
+enum {
+    IOTYPE_INPUT = 0,
+    IOTYPE_OUTPUT = 1
+};
+
+#ifndef min
+#define min(a,b) ((a)<(b)?(a):(b))
+#endif
+
+VirtIOVModem *vio_vmodem;
+
+typedef struct MsgInfo
+{
+    msg_info info;
+    QTAILQ_ENTRY(MsgInfo) next;
+}MsgInfo;
+
+static QTAILQ_HEAD(MsgInfoRecvHead , MsgInfo) vmodem_recv_msg_queue =
+    QTAILQ_HEAD_INITIALIZER(vmodem_recv_msg_queue);
+
+typedef struct EvdiBuf {
+    VirtQueueElement elem;
+
+    QTAILQ_ENTRY(EvdiBuf) next;
+} EvdiBuf;
+
+static QTAILQ_HEAD(EvdiMsgHead , EvdiBuf) vmodem_in_queue =
+    QTAILQ_HEAD_INITIALIZER(vmodem_in_queue);
+
+bool send_to_vmodem(const uint32_t route, char *data, const uint32_t len)
+{
+    int size;
+    int left = len;
+    int count = 0;
+    char *readptr = data;
+
+    while (left > 0) {
+        MsgInfo *_msg = (MsgInfo*) malloc(sizeof(MsgInfo));
+        if (!_msg) {
+            ERR("malloc failed\n");
+            return false;
+        }
+
+        memset(&_msg->info, 0, sizeof(msg_info));
+
+        size = min(left, __MAX_BUF_SIZE);
+        memcpy(_msg->info.buf, readptr, size);
+        readptr += size;
+        _msg->info.use = size;
+        _msg->info.index = count;
+
+        qemu_mutex_lock(&vio_vmodem->mutex);
+
+        QTAILQ_INSERT_TAIL(&vmodem_recv_msg_queue, _msg, next);
+
+        qemu_mutex_unlock(&vio_vmodem->mutex);
+
+        left -= size;
+        count ++;
+    }
+
+    qemu_bh_schedule(vio_vmodem->bh);
+
+    return true;
+}
+
+static void flush_vmodem_recv_queue(void)
+{
+    int index;
+
+    if (unlikely(!virtio_queue_ready(vio_vmodem->rvq))) {
+        ERR("virtio queue is not ready\n");
+        return;
+    }
+
+    if (unlikely(virtio_queue_empty(vio_vmodem->rvq))) {
+        ERR("virtqueue is empty\n");
+        return;
+    }
+
+    qemu_mutex_lock(&vio_vmodem->mutex);
+
+    while (!QTAILQ_EMPTY(&vmodem_recv_msg_queue))
+    {
+        MsgInfo *msginfo = QTAILQ_FIRST(&vmodem_recv_msg_queue);
+        if (!msginfo)
+            break;
+
+        VirtQueueElement elem;
+        index = virtqueue_pop(vio_vmodem->rvq, &elem);
+        if (index == 0) {
+            break;
+        }
+
+        memset(elem.in_sg[0].iov_base, 0, elem.in_sg[0].iov_len);
+        memcpy(elem.in_sg[0].iov_base, &msginfo->info, sizeof(struct msg_info));
+
+        virtqueue_push(vio_vmodem->rvq, &elem, sizeof(msg_info));
+        virtio_notify(&vio_vmodem->vdev, vio_vmodem->rvq);
+
+        QTAILQ_REMOVE(&vmodem_recv_msg_queue, msginfo, next);
+        if (msginfo)
+            free(msginfo);
+    }
+    qemu_mutex_unlock(&vio_vmodem->mutex);
+}
+
+
+static void virtio_vmodem_recv(VirtIODevice *vdev, VirtQueue *vq)
+{
+    flush_vmodem_recv_queue();
+}
+
+static void virtio_vmodem_send(VirtIODevice *vdev, VirtQueue *vq)
+{
+    VirtIOVModem *vvmodem = (VirtIOVModem *)vdev;
+    int index = 0;
+    struct msg_info _msg;
+
+    if (virtio_queue_empty(vvmodem->svq)) {
+        ERR("virtqueue is empty.\n");
+        return;
+    }
+
+    VirtQueueElement elem;
+
+    while ((index = virtqueue_pop(vq, &elem))) {
+        memset(&_msg, 0x00, sizeof(_msg));
+        memcpy(&_msg, elem.out_sg[0].iov_base, elem.out_sg[0].iov_len);
+
+        TRACE("vmodem send to ecp.\n");
+        send_injector_ntf(_msg.buf, _msg.use);
+    }
+
+    virtqueue_push(vq, &elem, sizeof(VirtIOVModem));
+    virtio_notify(&vio_vmodem->vdev, vq);
+}
+
+static uint32_t virtio_vmodem_get_features(VirtIODevice *vdev,
+                                            uint32_t request_feature)
+{
+    TRACE("virtio_vmodem_get_features.\n");
+    return 0;
+}
+
+static void maru_vmodem_bh(void *opaque)
+{
+    flush_vmodem_recv_queue();
+}
+
+static void virtio_vmodem_realize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+
+    vio_vmodem = VIRTIO_VMODEM(vdev);
+
+    if (vio_vmodem == NULL) {
+        ERR("failed to initialize vmodem device\n");
+        return;
+    }
+
+    virtio_init(vdev, TYPE_VIRTIO_VMODEM, VIRTIO_ID_VMODEM, 0); //VMODEM_DEVICE_NAME
+    qemu_mutex_init(&vio_vmodem->mutex);
+
+    vio_vmodem->rvq = virtio_add_queue(&vio_vmodem->vdev, 256, virtio_vmodem_recv);
+    vio_vmodem->svq = virtio_add_queue(&vio_vmodem->vdev, 256, virtio_vmodem_send);
+    vio_vmodem->qdev = dev;
+
+    vio_vmodem->bh = qemu_bh_new(maru_vmodem_bh, vio_vmodem);
+
+    INFO("finish the vmodem device initialization.\n");
+}
+
+static void virtio_vmodem_unrealize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+
+    INFO("destroy vmodem device\n");
+
+    if (vio_vmodem->bh) {
+        qemu_bh_delete(vio_vmodem->bh);
+    }
+
+    qemu_mutex_destroy(&vio_vmodem->mutex);
+    virtio_cleanup(vdev);
+}
+
+static void virtio_vmodem_reset(VirtIODevice *vdev)
+{
+    INFO("virtio_vmodem_reset.\n");
+}
+
+
+static void virtio_vmodem_class_init(ObjectClass *klass, void *data)
+{
+    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+    vdc->realize = virtio_vmodem_realize;
+    vdc->unrealize = virtio_vmodem_unrealize;
+    vdc->get_features = virtio_vmodem_get_features;
+    vdc->reset = virtio_vmodem_reset;
+}
+
+
+
+static const TypeInfo virtio_device_info = {
+    .name = TYPE_VIRTIO_VMODEM,
+    .parent = TYPE_VIRTIO_DEVICE,
+    .instance_size = sizeof(VirtIOVModem),
+    .class_init = virtio_vmodem_class_init,
+};
+
+static void virtio_register_types(void)
+{
+    type_register_static(&virtio_device_info);
+}
+
+type_init(virtio_register_types)
diff --git a/tizen/src/hw/virtio/maru_virtio_vmodem.h b/tizen/src/hw/virtio/maru_virtio_vmodem.h
new file mode 100644 (file)
index 0000000..6248296
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Virtio Virtual Modem Device
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Sooyoung Ha <yoosah.ha@samsung.com>
+ *  SeokYeon Hwang <syeon.hwang@samsung.com>
+ *  Sangho Park <sangho1206.park@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_VIRTIO_VMODEM_H_
+#define MARU_VIRTIO_VMODEM_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "hw/virtio/virtio.h"
+
+typedef struct VirtIOVirtualModem{
+    VirtIODevice    vdev;
+    VirtQueue       *rvq;
+    VirtQueue       *svq;
+    DeviceState     *qdev;
+
+    QemuMutex mutex;
+    QEMUBH *bh;
+} VirtIOVModem;
+
+#define TYPE_VIRTIO_VMODEM "virtio-vmodem-device"
+#define VIRTIO_VMODEM(obj) \
+        OBJECT_CHECK(VirtIOVModem, (obj), TYPE_VIRTIO_VMODEM)
+
+bool send_to_vmodem(const uint32_t route, char *data, const uint32_t len);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* MARU_VIRTIO_VMODEM_H_ */
diff --git a/tizen/src/sdb_noti_server.c b/tizen/src/sdb_noti_server.c
deleted file mode 100644 (file)
index 252b770..0000000
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Emulator SDB Notification Server
- *
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Jinhyung choi   <jinhyung2.choi@samsung.com>
- *  MunKyu Im       <munkyu.im@samsung.com>
- *  Sangho Park     <sangho1206.park@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 "qemu/sockets.h"
-
-#include "hw/maru_virtio_hwkey.h"
-#include "hw/maru_pm.h"
-#include "skin/maruskin_server.h"
-#include "ecs/ecs.h"
-
-#include "emulator.h"
-#include "debug_ch.h"
-#include "sdb_noti_server.h"
-
-MULTI_DEBUG_CHANNEL(qemu, sdb_noti);
-
-#define RECV_BUF_SIZE 32
-
-typedef struct SDB_Noti_Server {
-    int server_fd;
-    GIOChannel *server_chan;
-    guint server_tag;
-} SDB_Noti_Server;
-
-typedef struct SDB_Client {
-    int port;
-    struct sockaddr_in addr;
-    char serial[RECV_BUF_SIZE];
-
-    QTAILQ_ENTRY(SDB_Client) next;
-} SDB_Client;
-
-static QTAILQ_HEAD(SDB_ClientHead, SDB_Client)
-clients = QTAILQ_HEAD_INITIALIZER(clients);
-
-static SDB_Noti_Server *current_server;
-static QemuMutex mutex_clients;
-
-static void remove_sdb_client(SDB_Client* client)
-{
-    if (client == NULL) {
-        return;
-    }
-
-    qemu_mutex_lock(&mutex_clients);
-
-    QTAILQ_REMOVE(&clients, client, next);
-
-    qemu_mutex_unlock(&mutex_clients);
-
-    g_free(client);
-}
-
-static void send_to_sdb_client(SDB_Client* client, int state)
-{
-    struct sockaddr_in sock_addr;
-    int s, slen = sizeof(sock_addr);
-    int serial_len = 0;
-    char buf [32];
-
-    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1){
-          INFO("socket creation error! %d\n", errno);
-          return;
-    }
-
-    memset(&sock_addr, 0, sizeof(sock_addr));
-
-    sock_addr.sin_family = AF_INET;
-    sock_addr.sin_port = htons(client->port);
-    sock_addr.sin_addr = (client->addr).sin_addr;
-
-    if (connect(s, (struct sockaddr*)&sock_addr, slen) == -1) {
-        INFO("connect error! remove this client.\n");
-        remove_sdb_client(client);
-        close(s);
-        return;
-    }
-
-    memset(buf, 0, sizeof(buf));
-
-    serial_len = strlen(client->serial);
-
-    // send message "[4 digit message length]host:sync:emulator-26101:[0|1]"
-    sprintf(buf, "%04xhost:sync:%s:%01d", (serial_len + 12), client->serial, state);
-
-    INFO("send %s to client %s\n", buf, inet_ntoa(client->addr.sin_addr));
-
-    if (send(s, buf, sizeof(buf), 0) == -1)
-    {
-        INFO("send error! remove this client.\n");
-        remove_sdb_client(client);
-    }
-
-    close(s);
-}
-
-void notify_all_sdb_clients(int state)
-{
-    qemu_mutex_lock(&mutex_clients);
-    SDB_Client *client, *next;
-
-    QTAILQ_FOREACH_SAFE(client, &clients, next, next)
-    {
-        send_to_sdb_client(client, state);
-    }
-    qemu_mutex_unlock(&mutex_clients);
-
-}
-
-static void add_sdb_client(struct sockaddr_in* addr, int port, const char* serial)
-{
-    SDB_Client *cli = NULL;
-    SDB_Client *client = NULL, *next;
-
-    if (addr == NULL) {
-        INFO("SDB_Client client's address is EMPTY.\n");
-        return;
-    } else if (serial == NULL || strlen(serial) <= 0) {
-        INFO("SDB_Client client's serial is EMPTY.\n");
-        return;
-    } else if (strlen(serial) > RECV_BUF_SIZE) {
-        INFO("SDB_Client client's serial is too long. %s\n", serial);
-        return;
-    }
-
-    qemu_mutex_lock(&mutex_clients);
-    QTAILQ_FOREACH_SAFE(cli, &clients, next, next)
-    {
-        if (!strcmp(serial, cli->serial) && !strcmp(inet_ntoa(addr->sin_addr), inet_ntoa((cli->addr).sin_addr))) {
-            INFO("Client cannot be duplicated.\n");
-            qemu_mutex_unlock(&mutex_clients);
-            return;
-        }
-    }
-    qemu_mutex_unlock(&mutex_clients);
-
-    client = g_malloc0(sizeof(SDB_Client));
-    if (NULL == client) {
-        INFO("SDB_Client allocation failed.\n");
-        return;
-    }
-
-    memcpy(&client->addr, addr, sizeof(struct sockaddr_in));
-    client->port = port;
-    strcpy(client->serial, serial);
-
-    qemu_mutex_lock(&mutex_clients);
-
-    QTAILQ_INSERT_TAIL(&clients, client, next);
-
-    qemu_mutex_unlock(&mutex_clients);
-
-    INFO("Added new sdb client. ip: %s, port: %d, serial: %s\n", inet_ntoa((client->addr).sin_addr), client->port, client->serial);
-
-    send_to_sdb_client(client, runstate_check(RUN_STATE_SUSPENDED));
-}
-
-static int parse_val(char* buff, unsigned char data, char* parsbuf)
-{
-    int count = 0;
-
-    while (1) {
-        if (count > 12) {
-            return -1;
-        }
-
-        if (buff[count] == data) {
-            count++;
-            strncpy(parsbuf, buff, count);
-            return count;
-        }
-
-        count++;
-    }
-
-    return 0;
-}
-
-#define SDB_SERVER_PORT 26097
-static void register_sdb_server(char* readbuf, struct sockaddr_in* client_addr)
-{
-    int port = 0;
-    char token[] = "\n";
-    char* ret = NULL;
-    char* serial = NULL;
-
-    ret = strtok(readbuf, token);
-    if (ret == NULL) {
-        INFO("command is not found.");
-        return;
-    }
-
-    serial = strtok(NULL, token);
-    if (serial == NULL) {
-        INFO("serial is not found.");
-        return;
-    }
-
-    port = SDB_SERVER_PORT;
-
-    add_sdb_client(client_addr, port, serial);
-}
-
-#define PRESS     1
-#define RELEASE   2
-#define POWER_KEY 116
-static void wakeup_guest(void)
-{
-    // FIXME: Temporarily working model.
-    // It must be fixed as the way it works.
-    maru_hwkey_event(PRESS, POWER_KEY);
-    maru_hwkey_event(RELEASE, POWER_KEY);
-}
-
-static void suspend_lock_state(int state)
-{
-    ecs_suspend_lock_state(state);
-}
-
-static void command_handler(char* readbuf, struct sockaddr_in* client_addr)
-{
-    char command[RECV_BUF_SIZE];
-    memset(command, '\0', sizeof(command));
-
-    parse_val(readbuf, 0x0a, command);
-
-    TRACE("----------------------------------------\n");
-    TRACE("command:%s\n", command);
-    if (strcmp(command, "2\n" ) == 0) {
-        notify_sdb_daemon_start();
-    } else if (strcmp(command, "5\n") == 0) {
-        register_sdb_server(readbuf, client_addr);
-    } else if (strcmp(command, "6\n") == 0) {
-        wakeup_guest();
-    } else if (strcmp(command, "7\n") == 0) {
-        suspend_lock_state(SUSPEND_LOCK);
-    } else if (strcmp(command, "8\n") == 0) {
-        suspend_lock_state(SUSPEND_UNLOCK);
-    } else {
-        INFO("!!! unknown command : %s\n", command);
-    }
-    TRACE("========================================\n");
-}
-
-static void close_clients(void)
-{
-    qemu_mutex_lock(&mutex_clients);
-    SDB_Client * client, *next;
-
-    QTAILQ_FOREACH_SAFE(client, &clients, next, next)
-    {
-        QTAILQ_REMOVE(&clients, client, next);
-
-        if (NULL != client)
-        {
-            g_free(client);
-        }
-    }
-
-    qemu_mutex_unlock(&mutex_clients);
-}
-
-static void close_server(void)
-{
-    if (current_server == NULL) {
-        return;
-    }
-
-    close_clients();
-
-    if (current_server->server_fd > 0) {
-        if (current_server->server_tag) {
-            g_source_remove(current_server->server_tag);
-            current_server->server_tag = 0;
-        }
-        if (current_server->server_chan) {
-            g_io_channel_unref(current_server->server_chan);
-        }
-        closesocket(current_server->server_fd);
-    }
-
-    g_free(current_server);
-
-    qemu_mutex_destroy(&mutex_clients);
-}
-
-static gboolean sdb_noti_read(GIOChannel *channel, GIOCondition cond, void *opaque)
-{
-    int recv_cnt = 0;
-    struct sockaddr_in client_addr;
-    socklen_t client_len;
-    char readbuf[RECV_BUF_SIZE + 1];
-    SDB_Noti_Server *server = opaque;
-
-    memset(&readbuf, 0, sizeof(readbuf));
-
-    recv_cnt = recvfrom(server->server_fd, readbuf, RECV_BUF_SIZE, 0,
-                        (struct sockaddr*) &client_addr, &client_len);
-
-    if (recv_cnt > 0) {
-        command_handler((char*)readbuf, &client_addr);
-    } else if (recv_cnt == 0) {
-        INFO("noti server recvfrom returned 0.\n");
-    } else {
-#ifdef _WIN32
-        errno = WSAGetLastError();
-#endif
-        TRACE("recvfrom error case (it can be from non-blocking socket): %d", errno);
-    }
-
-    return TRUE;
-}
-
-static int create_UDP_server(SDB_Noti_Server *server, int port)
-{
-    struct sockaddr_in server_addr;
-    int opt = 1;
-
-    if ((server->server_fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
-        INFO("create listen socket error:%d\n", errno);
-        return -1;
-    }
-
-    memset(&server_addr, '\0', sizeof(server_addr));
-    server_addr.sin_family = PF_INET;
-    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
-    server_addr.sin_port = htons(port);
-
-    qemu_set_nonblock(server->server_fd);
-
-    if (qemu_setsockopt(server->server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) {
-        INFO("setsockopt SO_REUSEADDR is failed.: %d\n", errno);
-        return -1;
-    }
-
-    if (bind(server->server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {
-        INFO("sdb noti server bind error: %d", errno);
-        return -1;
-    }
-
-    return 0;
-}
-
-static GIOChannel *io_channel_from_socket(int fd)
-{
-    GIOChannel *chan;
-
-    if (fd == -1) {
-        return NULL;
-    }
-
-#ifdef _WIN32
-    chan = g_io_channel_win32_new_socket(fd);
-#else
-    chan = g_io_channel_unix_new(fd);
-#endif
-
-    g_io_channel_set_encoding(chan, NULL, NULL);
-    g_io_channel_set_buffered(chan, FALSE);
-
-    return chan;
-}
-
-static void sdb_noti_server_notify_exit(Notifier *notifier, void *data)
-{
-    INFO("shutdown sdb notification server.\n");
-    close_server();
-}
-
-static Notifier sdb_noti_server_exit = { .notify = sdb_noti_server_notify_exit };
-
-void start_sdb_noti_server(int server_port)
-{
-    SDB_Noti_Server *server;
-    int ret;
-
-    INFO("start sdb noti server thread.\n");
-
-    server = g_malloc0(sizeof(SDB_Noti_Server));
-    if (server == NULL) {
-        INFO("SDB Notification server allocation is failed.\n");
-        return;
-    }
-
-    ret = create_UDP_server(server, server_port);
-    if (ret < 0) {
-        INFO("failed to create UDP server\n");
-        close_server();
-        return;
-    }
-
-    server->server_chan = io_channel_from_socket(server->server_fd);
-    server->server_tag = g_io_add_watch(server->server_chan, G_IO_IN, sdb_noti_read, server);
-
-    current_server = server;
-
-    qemu_mutex_init(&mutex_clients);
-
-    INFO("success to bind port[127.0.0.1:%d/udp] for sdb noti server in host \n", server_port);
-
-    emulator_add_exit_notifier(&sdb_noti_server_exit);
-}
-
diff --git a/tizen/src/sdb_noti_server.h b/tizen/src/sdb_noti_server.h
deleted file mode 100644 (file)
index 9aaf7b3..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Emulator SDB Notification Server
- *
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- * Contact:
- *  Jinhyung choi   <jinhyung2.choi@samsung.com>
- *  MunKyu Im       <munkyu.im@samsung.com>
- *  Sangho Park     <sangho1206.park@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 SDB_NOTI_SERVER_H_
-#define SDB_NOTI_SERVER_H_
-
-void start_sdb_noti_server(int server_port);
-
-#define STATE_RUNNING 0
-#define STATE_SUSPEND 1
-void notify_all_sdb_clients(int state);
-
-#endif
index e21dfd30bf7e4dc3981f3aad37a9967ecfa4cc19..96f9719107c228ee602f681a05689b001f5d9aa6 100644 (file)
@@ -31,7 +31,7 @@
 #ifndef MARUSKIN_KEYMAP_H_
 #define MARUSKIN_KEYMAP_H_
 
-#include "hw/maru_virtio_keyboard.h"
+#include "hw/virtio/maru_virtio_keyboard.h"
 
 /* keep it consistent with emulator-skin(swt) virtual keycode */
 #define JAVA_KEYCODE_BIT (1 << 24)
index 8d4bbfa97478258568efcbffbf0eaf5e4808e51e..7bad11b4cc13d751b9b8a8e12872188f570aa9ea 100644 (file)
@@ -37,9 +37,9 @@
 
 #include "maru_common.h"
 #include "maruskin_operation.h"
-#include "hw/maru_brightness.h"
-#include "hw/maru_virtio_hwkey.h"
-#include "hw/maru_virtio_touchscreen.h"
+#include "hw/pci/maru_brightness.h"
+#include "hw/virtio/maru_virtio_hwkey.h"
+#include "hw/virtio/maru_virtio_touchscreen.h"
 #include "display/maru_display.h"
 #include "emulator.h"
 #include "debug_ch.h"
index 1102f2ea239eac51a9c3a86b9d3606a01c3f6bfe..2234ec0adeff3a31e3dd60b1d6618ded4289783d 100644 (file)
@@ -8,6 +8,9 @@ obj-$(CONFIG_DARWIN) += osutil-darwin.o
 #sdb
 obj-y += sdb.o
 
+# sdb noti server
+obj-y += sdb_noti_server.o
+
 # check gl
 obj-y += check_gl_core.o
 obj-$(CONFIG_LINUX) += check_gl_glx.o
diff --git a/tizen/src/util/sdb_noti_server.c b/tizen/src/util/sdb_noti_server.c
new file mode 100644 (file)
index 0000000..3d22b4b
--- /dev/null
@@ -0,0 +1,430 @@
+/*
+ * Emulator SDB Notification Server
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Jinhyung choi   <jinhyung2.choi@samsung.com>
+ *  MunKyu Im       <munkyu.im@samsung.com>
+ *  Sangho Park     <sangho1206.park@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 "qemu/sockets.h"
+
+#include "hw/maru_pm.h"
+#include "hw/virtio/maru_virtio_hwkey.h"
+#include "skin/maruskin_server.h"
+#include "ecs/ecs.h"
+
+#include "emulator.h"
+#include "debug_ch.h"
+#include "sdb_noti_server.h"
+
+MULTI_DEBUG_CHANNEL(qemu, sdb_noti);
+
+#define RECV_BUF_SIZE 32
+
+typedef struct SDB_Noti_Server {
+    int server_fd;
+    GIOChannel *server_chan;
+    guint server_tag;
+} SDB_Noti_Server;
+
+typedef struct SDB_Client {
+    int port;
+    struct sockaddr_in addr;
+    char serial[RECV_BUF_SIZE];
+
+    QTAILQ_ENTRY(SDB_Client) next;
+} SDB_Client;
+
+static QTAILQ_HEAD(SDB_ClientHead, SDB_Client)
+clients = QTAILQ_HEAD_INITIALIZER(clients);
+
+static SDB_Noti_Server *current_server;
+static QemuMutex mutex_clients;
+
+static void remove_sdb_client(SDB_Client* client)
+{
+    if (client == NULL) {
+        return;
+    }
+
+    qemu_mutex_lock(&mutex_clients);
+
+    QTAILQ_REMOVE(&clients, client, next);
+
+    qemu_mutex_unlock(&mutex_clients);
+
+    g_free(client);
+}
+
+static void send_to_sdb_client(SDB_Client* client, int state)
+{
+    struct sockaddr_in sock_addr;
+    int s, slen = sizeof(sock_addr);
+    int serial_len = 0;
+    char buf [32];
+
+    if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1){
+          INFO("socket creation error! %d\n", errno);
+          return;
+    }
+
+    memset(&sock_addr, 0, sizeof(sock_addr));
+
+    sock_addr.sin_family = AF_INET;
+    sock_addr.sin_port = htons(client->port);
+    sock_addr.sin_addr = (client->addr).sin_addr;
+
+    if (connect(s, (struct sockaddr*)&sock_addr, slen) == -1) {
+        INFO("connect error! remove this client.\n");
+        remove_sdb_client(client);
+        close(s);
+        return;
+    }
+
+    memset(buf, 0, sizeof(buf));
+
+    serial_len = strlen(client->serial);
+
+    // send message "[4 digit message length]host:sync:emulator-26101:[0|1]"
+    sprintf(buf, "%04xhost:sync:%s:%01d", (serial_len + 12), client->serial, state);
+
+    INFO("send %s to client %s\n", buf, inet_ntoa(client->addr.sin_addr));
+
+    if (send(s, buf, sizeof(buf), 0) == -1)
+    {
+        INFO("send error! remove this client.\n");
+        remove_sdb_client(client);
+    }
+
+    close(s);
+}
+
+void notify_all_sdb_clients(int state)
+{
+    qemu_mutex_lock(&mutex_clients);
+    SDB_Client *client, *next;
+
+    QTAILQ_FOREACH_SAFE(client, &clients, next, next)
+    {
+        send_to_sdb_client(client, state);
+    }
+    qemu_mutex_unlock(&mutex_clients);
+
+}
+
+static void add_sdb_client(struct sockaddr_in* addr, int port, const char* serial)
+{
+    SDB_Client *cli = NULL;
+    SDB_Client *client = NULL, *next;
+
+    if (addr == NULL) {
+        INFO("SDB_Client client's address is EMPTY.\n");
+        return;
+    } else if (serial == NULL || strlen(serial) <= 0) {
+        INFO("SDB_Client client's serial is EMPTY.\n");
+        return;
+    } else if (strlen(serial) > RECV_BUF_SIZE) {
+        INFO("SDB_Client client's serial is too long. %s\n", serial);
+        return;
+    }
+
+    qemu_mutex_lock(&mutex_clients);
+    QTAILQ_FOREACH_SAFE(cli, &clients, next, next)
+    {
+        if (!strcmp(serial, cli->serial) && !strcmp(inet_ntoa(addr->sin_addr), inet_ntoa((cli->addr).sin_addr))) {
+            INFO("Client cannot be duplicated.\n");
+            qemu_mutex_unlock(&mutex_clients);
+            return;
+        }
+    }
+    qemu_mutex_unlock(&mutex_clients);
+
+    client = g_malloc0(sizeof(SDB_Client));
+    if (NULL == client) {
+        INFO("SDB_Client allocation failed.\n");
+        return;
+    }
+
+    memcpy(&client->addr, addr, sizeof(struct sockaddr_in));
+    client->port = port;
+    strcpy(client->serial, serial);
+
+    qemu_mutex_lock(&mutex_clients);
+
+    QTAILQ_INSERT_TAIL(&clients, client, next);
+
+    qemu_mutex_unlock(&mutex_clients);
+
+    INFO("Added new sdb client. ip: %s, port: %d, serial: %s\n", inet_ntoa((client->addr).sin_addr), client->port, client->serial);
+
+    send_to_sdb_client(client, runstate_check(RUN_STATE_SUSPENDED));
+}
+
+static int parse_val(char* buff, unsigned char data, char* parsbuf)
+{
+    int count = 0;
+
+    while (1) {
+        if (count > 12) {
+            return -1;
+        }
+
+        if (buff[count] == data) {
+            count++;
+            strncpy(parsbuf, buff, count);
+            return count;
+        }
+
+        count++;
+    }
+
+    return 0;
+}
+
+#define SDB_SERVER_PORT 26097
+static void register_sdb_server(char* readbuf, struct sockaddr_in* client_addr)
+{
+    int port = 0;
+    char token[] = "\n";
+    char* ret = NULL;
+    char* serial = NULL;
+
+    ret = strtok(readbuf, token);
+    if (ret == NULL) {
+        INFO("command is not found.");
+        return;
+    }
+
+    serial = strtok(NULL, token);
+    if (serial == NULL) {
+        INFO("serial is not found.");
+        return;
+    }
+
+    port = SDB_SERVER_PORT;
+
+    add_sdb_client(client_addr, port, serial);
+}
+
+#define PRESS     1
+#define RELEASE   2
+#define POWER_KEY 116
+static void wakeup_guest(void)
+{
+    // FIXME: Temporarily working model.
+    // It must be fixed as the way it works.
+    maru_hwkey_event(PRESS, POWER_KEY);
+    maru_hwkey_event(RELEASE, POWER_KEY);
+}
+
+static void suspend_lock_state(int state)
+{
+    ecs_suspend_lock_state(state);
+}
+
+static void command_handler(char* readbuf, struct sockaddr_in* client_addr)
+{
+    char command[RECV_BUF_SIZE];
+    memset(command, '\0', sizeof(command));
+
+    parse_val(readbuf, 0x0a, command);
+
+    TRACE("----------------------------------------\n");
+    TRACE("command:%s\n", command);
+    if (strcmp(command, "2\n" ) == 0) {
+        notify_sdb_daemon_start();
+    } else if (strcmp(command, "5\n") == 0) {
+        register_sdb_server(readbuf, client_addr);
+    } else if (strcmp(command, "6\n") == 0) {
+        wakeup_guest();
+    } else if (strcmp(command, "7\n") == 0) {
+        suspend_lock_state(SUSPEND_LOCK);
+    } else if (strcmp(command, "8\n") == 0) {
+        suspend_lock_state(SUSPEND_UNLOCK);
+    } else {
+        INFO("!!! unknown command : %s\n", command);
+    }
+    TRACE("========================================\n");
+}
+
+static void close_clients(void)
+{
+    qemu_mutex_lock(&mutex_clients);
+    SDB_Client * client, *next;
+
+    QTAILQ_FOREACH_SAFE(client, &clients, next, next)
+    {
+        QTAILQ_REMOVE(&clients, client, next);
+
+        if (NULL != client)
+        {
+            g_free(client);
+        }
+    }
+
+    qemu_mutex_unlock(&mutex_clients);
+}
+
+static void close_server(void)
+{
+    if (current_server == NULL) {
+        return;
+    }
+
+    close_clients();
+
+    if (current_server->server_fd > 0) {
+        if (current_server->server_tag) {
+            g_source_remove(current_server->server_tag);
+            current_server->server_tag = 0;
+        }
+        if (current_server->server_chan) {
+            g_io_channel_unref(current_server->server_chan);
+        }
+        closesocket(current_server->server_fd);
+    }
+
+    g_free(current_server);
+
+    qemu_mutex_destroy(&mutex_clients);
+}
+
+static gboolean sdb_noti_read(GIOChannel *channel, GIOCondition cond, void *opaque)
+{
+    int recv_cnt = 0;
+    struct sockaddr_in client_addr;
+    socklen_t client_len;
+    char readbuf[RECV_BUF_SIZE + 1];
+    SDB_Noti_Server *server = opaque;
+
+    memset(&readbuf, 0, sizeof(readbuf));
+
+    recv_cnt = recvfrom(server->server_fd, readbuf, RECV_BUF_SIZE, 0,
+                        (struct sockaddr*) &client_addr, &client_len);
+
+    if (recv_cnt > 0) {
+        command_handler((char*)readbuf, &client_addr);
+    } else if (recv_cnt == 0) {
+        INFO("noti server recvfrom returned 0.\n");
+    } else {
+#ifdef _WIN32
+        errno = WSAGetLastError();
+#endif
+        TRACE("recvfrom error case (it can be from non-blocking socket): %d", errno);
+    }
+
+    return TRUE;
+}
+
+static int create_UDP_server(SDB_Noti_Server *server, int port)
+{
+    struct sockaddr_in server_addr;
+    int opt = 1;
+
+    if ((server->server_fd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
+        INFO("create listen socket error:%d\n", errno);
+        return -1;
+    }
+
+    memset(&server_addr, '\0', sizeof(server_addr));
+    server_addr.sin_family = PF_INET;
+    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
+    server_addr.sin_port = htons(port);
+
+    qemu_set_nonblock(server->server_fd);
+
+    if (qemu_setsockopt(server->server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) {
+        INFO("setsockopt SO_REUSEADDR is failed.: %d\n", errno);
+        return -1;
+    }
+
+    if (bind(server->server_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) {
+        INFO("sdb noti server bind error: %d", errno);
+        return -1;
+    }
+
+    return 0;
+}
+
+static GIOChannel *io_channel_from_socket(int fd)
+{
+    GIOChannel *chan;
+
+    if (fd == -1) {
+        return NULL;
+    }
+
+#ifdef _WIN32
+    chan = g_io_channel_win32_new_socket(fd);
+#else
+    chan = g_io_channel_unix_new(fd);
+#endif
+
+    g_io_channel_set_encoding(chan, NULL, NULL);
+    g_io_channel_set_buffered(chan, FALSE);
+
+    return chan;
+}
+
+static void sdb_noti_server_notify_exit(Notifier *notifier, void *data)
+{
+    INFO("shutdown sdb notification server.\n");
+    close_server();
+}
+
+static Notifier sdb_noti_server_exit = { .notify = sdb_noti_server_notify_exit };
+
+void start_sdb_noti_server(int server_port)
+{
+    SDB_Noti_Server *server;
+    int ret;
+
+    INFO("start sdb noti server thread.\n");
+
+    server = g_malloc0(sizeof(SDB_Noti_Server));
+    if (server == NULL) {
+        INFO("SDB Notification server allocation is failed.\n");
+        return;
+    }
+
+    ret = create_UDP_server(server, server_port);
+    if (ret < 0) {
+        INFO("failed to create UDP server\n");
+        close_server();
+        return;
+    }
+
+    server->server_chan = io_channel_from_socket(server->server_fd);
+    server->server_tag = g_io_add_watch(server->server_chan, G_IO_IN, sdb_noti_read, server);
+
+    current_server = server;
+
+    qemu_mutex_init(&mutex_clients);
+
+    INFO("success to bind port[127.0.0.1:%d/udp] for sdb noti server in host \n", server_port);
+
+    emulator_add_exit_notifier(&sdb_noti_server_exit);
+}
+
diff --git a/tizen/src/util/sdb_noti_server.h b/tizen/src/util/sdb_noti_server.h
new file mode 100644 (file)
index 0000000..9aaf7b3
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Emulator SDB Notification Server
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ *  Jinhyung choi   <jinhyung2.choi@samsung.com>
+ *  MunKyu Im       <munkyu.im@samsung.com>
+ *  Sangho Park     <sangho1206.park@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 SDB_NOTI_SERVER_H_
+#define SDB_NOTI_SERVER_H_
+
+void start_sdb_noti_server(int server_port);
+
+#define STATE_RUNNING 0
+#define STATE_SUSPEND 1
+void notify_all_sdb_clients(int state);
+
+#endif