-/*\r
- * Common implementation of MARU Virtual Camera device by PCI bus.\r
- *\r
- * Copyright (c) 2011 - 2012 Samsung Electronics Co., Ltd All Rights Reserved\r
- *\r
- * Contact:\r
- * JinHyung Jo <jinhyung.jo@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
-\r
-#include <stdarg.h>\r
-#include <stdlib.h>\r
-#include <stdio.h>\r
-#include <string.h>\r
-#include <inttypes.h>\r
-#include <signal.h>\r
-\r
-#include "qemu-common.h"\r
-#include "cpu-common.h"\r
-\r
-#include "pci.h"\r
-#include "pci_ids.h"\r
-#include "maru_device_ids.h"\r
-\r
-#include "maru_camera_common.h"\r
-#include "tizen/src/debug_ch.h"\r
-\r
-MULTI_DEBUG_CHANNEL(tizen, camera_pci);\r
-\r
-#define MARU_PCI_CAMERA_DEVICE_NAME "maru_camera_pci"\r
-\r
-#define MARUCAM_MEM_SIZE (4 * 1024 * 1024) /* 4MB */\r
-#define MARUCAM_REG_SIZE (256) /* 64 * 4Byte */\r
-\r
-/*\r
- * I/O functions\r
- */\r
-static inline uint32_t\r
-marucam_mmio_read(void *opaque, target_phys_addr_t offset)\r
-{\r
- uint32_t ret = 0;\r
- MaruCamState *state = (MaruCamState*)opaque;\r
-\r
- switch (offset & 0xFF) {\r
- case MARUCAM_CMD_ISR:\r
- qemu_mutex_lock(&state->thread_mutex);\r
- ret = state->isr;\r
- if (ret != 0) {\r
- qemu_irq_lower(state->dev.irq[2]);\r
- state->isr = 0;\r
- }\r
- qemu_mutex_unlock(&state->thread_mutex);\r
- break;\r
- case MARUCAM_CMD_G_DATA:\r
- ret = state->param->stack[state->param->top++];\r
- break;\r
- case MARUCAM_CMD_OPEN:\r
- case MARUCAM_CMD_CLOSE:\r
- case MARUCAM_CMD_START_PREVIEW:\r
- case MARUCAM_CMD_STOP_PREVIEW:\r
- case MARUCAM_CMD_S_PARAM:\r
- case MARUCAM_CMD_G_PARAM:\r
- case MARUCAM_CMD_ENUM_FMT:\r
- case MARUCAM_CMD_TRY_FMT:\r
- case MARUCAM_CMD_S_FMT:\r
- case MARUCAM_CMD_G_FMT:\r
- case MARUCAM_CMD_QCTRL:\r
- case MARUCAM_CMD_S_CTRL:\r
- case MARUCAM_CMD_G_CTRL:\r
- case MARUCAM_CMD_ENUM_FSIZES:\r
- case MARUCAM_CMD_ENUM_FINTV:\r
- ret = state->param->errCode;\r
- state->param->errCode = 0;\r
- break;\r
- default:\r
- ERR("Not supported command: 0x%x\n", offset);\r
- ret = EINVAL;\r
- break;\r
- }\r
- return ret;\r
-}\r
-\r
-static inline void\r
-marucam_mmio_write(void *opaque, target_phys_addr_t offset, uint32_t value)\r
-{\r
- MaruCamState *state = (MaruCamState*)opaque;\r
- \r
- switch(offset & 0xFF) {\r
- case MARUCAM_CMD_OPEN:\r
- marucam_device_open(state);\r
- break;\r
- case MARUCAM_CMD_CLOSE:\r
- marucam_device_close(state);\r
- break;\r
- case MARUCAM_CMD_START_PREVIEW:\r
- marucam_device_start_preview(state);\r
- break;\r
- case MARUCAM_CMD_STOP_PREVIEW:\r
- marucam_device_stop_preview(state);\r
- memset(state->vaddr, 0, MARUCAM_MEM_SIZE);\r
- break;\r
- case MARUCAM_CMD_S_PARAM:\r
- marucam_device_s_param(state);\r
- break;\r
- case MARUCAM_CMD_G_PARAM:\r
- marucam_device_g_param(state);\r
- break;\r
- case MARUCAM_CMD_ENUM_FMT:\r
- marucam_device_enum_fmt(state);\r
- break;\r
- case MARUCAM_CMD_TRY_FMT:\r
- marucam_device_try_fmt(state);\r
- break;\r
- case MARUCAM_CMD_S_FMT:\r
- marucam_device_s_fmt(state);\r
- break;\r
- case MARUCAM_CMD_G_FMT:\r
- marucam_device_g_fmt(state);\r
- break;\r
- case MARUCAM_CMD_QCTRL:\r
- marucam_device_qctrl(state);\r
- break;\r
- case MARUCAM_CMD_S_CTRL:\r
- marucam_device_s_ctrl(state);\r
- break;\r
- case MARUCAM_CMD_G_CTRL:\r
- marucam_device_g_ctrl(state);\r
- break;\r
- case MARUCAM_CMD_ENUM_FSIZES:\r
- marucam_device_enum_fsizes(state);\r
- break;\r
- case MARUCAM_CMD_ENUM_FINTV:\r
- marucam_device_enum_fintv(state);\r
- break;\r
- case MARUCAM_CMD_S_DATA:\r
- state->param->stack[state->param->top++] = value;\r
- break;\r
- case MARUCAM_CMD_DATACLR:\r
- memset(state->param, 0, sizeof(MaruCamParam));\r
- break;\r
- case MARUCAM_CMD_REQFRAME:\r
- qemu_mutex_lock(&state->thread_mutex);\r
- state->req_frame = value + 1;\r
- qemu_mutex_unlock(&state->thread_mutex);\r
- break;\r
- default:\r
- ERR("Not supported command: 0x%x\n", offset);\r
- break;\r
- }\r
-}\r
-\r
-static const MemoryRegionOps maru_camera_mmio_ops = {\r
- .old_mmio = {\r
- .read = {\r
- marucam_mmio_read,\r
- marucam_mmio_read,\r
- marucam_mmio_read,\r
- },\r
- .write = {\r
- marucam_mmio_write,\r
- marucam_mmio_write,\r
- marucam_mmio_write,\r
- },\r
- },\r
- .endianness = DEVICE_LITTLE_ENDIAN,\r
-};\r
-\r
-/*\r
- * QEMU bottom half funtion\r
- */\r
-static void marucam_tx_bh(void *opaque)\r
-{\r
- MaruCamState *state = (MaruCamState *)opaque;\r
-\r
- qemu_mutex_lock(&state->thread_mutex);\r
- if (state->isr) {\r
- qemu_irq_raise(state->dev.irq[2]);\r
- }\r
- qemu_mutex_unlock(&state->thread_mutex);\r
-}\r
-\r
-/*\r
- * Initialization function\r
- */\r
-static int marucam_initfn(PCIDevice *dev)\r
-{\r
- MaruCamState *s = DO_UPCAST(MaruCamState, dev, dev);\r
- uint8_t *pci_conf = s->dev.config;\r
-\r
- pci_config_set_interrupt_pin(pci_conf, 0x03);\r
-\r
- memory_region_init_ram(&s->vram, "marucamera.ram", MARUCAM_MEM_SIZE);\r
- s->vaddr = memory_region_get_ram_ptr(&s->vram);\r
- memset(s->vaddr, 0, MARUCAM_MEM_SIZE);\r
-\r
- memory_region_init_io (&s->mmio, &maru_camera_mmio_ops, s,\r
- "maru-camera-mmio", MARUCAM_REG_SIZE);\r
- pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);\r
- pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);\r
-\r
- /* for worker thread */\r
- s->param = (MaruCamParam*)g_malloc0(sizeof(MaruCamParam));\r
- qemu_cond_init(&s->thread_cond);\r
- qemu_mutex_init(&s->thread_mutex);\r
-\r
- marucam_device_init(s);\r
-\r
- s->tx_bh = qemu_bh_new(marucam_tx_bh, s);\r
- INFO("[%s] camera device was initialized.\n", __func__);\r
-\r
- return 0;\r
-}\r
-\r
-/*\r
- * Termination function\r
- */\r
-static void marucam_exitfn(PCIDevice *pci_dev)\r
-{\r
- MaruCamState *s =\r
- OBJECT_CHECK(MaruCamState, pci_dev, MARU_PCI_CAMERA_DEVICE_NAME);\r
-\r
- marucam_device_exit(s);\r
- g_free(s->param);\r
- qemu_cond_destroy(&s->thread_cond);\r
- qemu_mutex_destroy(&s->thread_mutex);\r
-\r
- memory_region_destroy(&s->vram);\r
- memory_region_destroy(&s->mmio);\r
-\r
-\r
- INFO("[%s] camera device was released.\n", __func__);\r
-}\r
-\r
-int maru_camera_pci_init(PCIBus *bus)\r
-{\r
- INFO("[%s] camera device was initialized.\n", __func__);\r
- pci_create_simple(bus, -1, MARU_PCI_CAMERA_DEVICE_NAME);\r
- return 0;\r
-}\r
-\r
-static void maru_camera_pci_class_init(ObjectClass *klass, void *data)\r
-{\r
- DeviceClass *dc = DEVICE_CLASS(klass);\r
- PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);\r
-\r
- k->no_hotplug = 1;\r
- k->init = marucam_initfn;\r
- k->exit = marucam_exitfn;\r
- k->vendor_id = PCI_VENDOR_ID_TIZEN;\r
- k->device_id = PCI_DEVICE_ID_VIRTUAL_CAMERA;\r
- k->class_id = PCI_CLASS_OTHERS;\r
- dc->desc = "MARU Virtual Camera device for Tizen emulator";\r
-}\r
-\r
-static TypeInfo maru_camera_info = {\r
- .name = MARU_PCI_CAMERA_DEVICE_NAME,\r
- .parent = TYPE_PCI_DEVICE,\r
- .instance_size = sizeof(MaruCamState),\r
- .class_init = maru_camera_pci_class_init,\r
-};\r
-\r
-static void maru_camera_pci_register_types(void)\r
-{\r
- type_register_static(&maru_camera_info);\r
-}\r
-\r
-type_init(maru_camera_pci_register_types)\r
+/*
+ * 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 "cpu-common.h"
+
+#include "pci.h"
+#include "pci_ids.h"
+#include "maru_device_ids.h"
+
+#include "maru_camera_common.h"
+#include "tizen/src/debug_ch.h"
+
+MULTI_DEBUG_CHANNEL(tizen, camera_pci);
+
+#define MARU_PCI_CAMERA_DEVICE_NAME "maru_camera_pci"
+
+#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, target_phys_addr_t 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) {
+ qemu_irq_lower(state->dev.irq[2]);
+ 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, target_phys_addr_t 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) {
+ qemu_irq_raise(state->dev.irq[2]);
+ }
+ 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;
+
+ pci_config_set_interrupt_pin(pci_conf, 0x03);
+
+ memory_region_init_ram(&s->vram, "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,
+ &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);
+ INFO("[%s] camera device was initialized.\n", __func__);
+
+ return 0;
+}
+
+/*
+ * Termination function
+ */
+static void marucam_exitfn(PCIDevice *pci_dev)
+{
+ MaruCamState *s =
+ OBJECT_CHECK(MaruCamState, pci_dev, MARU_PCI_CAMERA_DEVICE_NAME);
+
+ 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("[%s] camera device was released.\n", __func__);
+}
+
+int maru_camera_pci_init(PCIBus *bus)
+{
+ INFO("[%s] camera device was initialized.\n", __func__);
+ 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->no_hotplug = 1;
+ 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->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)