Devices: data is moved into qemu from kernel 42/17242/2
authorJinhyung Choi <jinhyung2.choi@samsung.com>
Thu, 6 Mar 2014 05:24:49 +0000 (14:24 +0900)
committerJinhyung Choi <jinhyung2.choi@samsung.com>
Thu, 6 Mar 2014 05:34:13 +0000 (14:34 +0900)
- virtio devices: Jacks, battery, and sensor

Change-Id: I846717a99cfdac02b3d57336d385fb2c03ed08f3
Signed-off-by: Jinhyung Choi <jinhyung2.choi@samsung.com>
18 files changed:
hw/virtio/virtio-pci.c
hw/virtio/virtio-pci.h
package/changelog
package/pkginfo.manifest
tizen/src/Makefile.tizen
tizen/src/ecs/ecs.c
tizen/src/ecs/ecs.h
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/hw/maru_device_ids.h
tizen/src/hw/maru_virtio_jack.c [new file with mode: 0644]
tizen/src/hw/maru_virtio_jack.h [new file with mode: 0644]
tizen/src/hw/maru_virtio_power.c [new file with mode: 0644]
tizen/src/hw/maru_virtio_power.h [new file with mode: 0644]
tizen/src/hw/maru_virtio_sensor.c
tizen/src/hw/maru_virtio_sensor.h

index cf6ac0b..5920cd0 100644 (file)
@@ -1837,6 +1837,88 @@ static TypeInfo virtio_nfc_pci_info = {
     .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 void virtio_jack_pci_class_init(ObjectClass *klass, void *data)
+{
+    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;
+}
+
+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,
+};
+
 
 #endif
 
@@ -1905,6 +1987,8 @@ static void virtio_pci_register_types(void)
     type_register_static(&virtio_gl_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);
 #endif
 }
 
index e9a6d79..8912d96 100644 (file)
@@ -44,6 +44,8 @@
 #include "../tizen/src/hw/maru_virtio_touchscreen.h"
 #include "../tizen/src/hw/virtio-gl.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"
 #endif
 
@@ -65,6 +67,8 @@ typedef struct VirtIOHWKeyPCI VirtIOHWKeyPCI;
 typedef struct VirtIOKeyboardPCI VirtIOKeyboardPCI;
 typedef struct VirtIOSENSORPCI VirtIOSENSORPCI;
 typedef struct VirtIONFCPCI VirtIONFCPCI;
+typedef struct VirtIOPOWERPCI VirtIOPOWERPCI;
+typedef struct VirtIOJACKPCI VirtIOJACKPCI;
 #endif
 
 /* virtio-pci-bus */
@@ -323,6 +327,30 @@ struct VirtIONFCPCI {
     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;
+};
+
 #endif
 
 /* Virtio ABI version, if we increment this, we break the guest driver. */
index 6307b96..bd49bc0 100644 (file)
@@ -1,3 +1,6 @@
+* 1.7.24
+- Moved device data into qemu from driver
+== Jinhyung Choi <jinhyung2.choi@samsung.com> 2014-03-06
 * 1.7.23
 - modified SDK version loading
 == GiWoong Kim <giwoong.kim@samsung.com> 2014-03-04
index 129d805..88f614f 100644 (file)
@@ -1,4 +1,4 @@
-Version: 1.7.23
+Version: 1.7.24
 Maintainer: Yeong-Kyoon Lee<yeongkyoon.lee@samsung.com>
 Source: emulator
 
index 5fb4d98..9b126cf 100644 (file)
@@ -123,6 +123,8 @@ obj-y += maru_virtio_hwkey.o
 obj-y += maru_virtio_evdi.o
 obj-y += maru_virtio_sensor.o
 obj-y += maru_virtio_nfc.o
+obj-y += maru_virtio_jack.o
+obj-y += maru_virtio_power.o
 obj-y += maru_virtio_esm.o
 obj-y += maru_brill_codec.o
 
index b722193..e721511 100644 (file)
@@ -141,42 +141,16 @@ static inline void start_logging(void) {
 
     stdout[0] = flog[0];
     stderr[0] = flog[0];
-
-    g_free(path);
 #else
-    log_fd = open("/dev/null", O_RDONLY);
-    if(log_fd < 0) {
-        fprintf(stderr, "failed to open() /dev/null\n");
-        return;
-    }
-    if(dup2(log_fd, 0) < 0) {
-        fprintf(stderr, "failed to dup2(log_fd, 0)\n");
-        return;
-    }
-
     log_fd = creat(path, 0640);
     if (log_fd < 0) {
         log_fd = open("/dev/null", O_WRONLY);
-        if(log_fd < 0) {
-            fprintf(stderr, "failed to open(/dev/null, O_WRONLY)\n");
-            g_free(path);
-            return;
-        }
     }
-
-    if(dup2(log_fd, 1) < 0) {
-        fprintf(stderr, "failed to dup2(log_fd, 1)\n");
-        g_free(path);
-        return;
-    }
-
-    if(dup2(log_fd, 2) < 0) {
-        fprintf(stderr, "failed to dup2(log_fd, 2)\n");
-        g_free(path);
+    if (log_fd < 0) {
         return;
     }
-
-    g_free(path);
+    dup2(log_fd, 1);
+    dup2(log_fd, 2);
 #endif
 }
 
@@ -383,6 +357,11 @@ static void ecs_read(ECS_Client *cli) {
     int read = 0;
     int to_read_bytes = 0;
 
+    if (cli == NULL)
+    {
+        LOG("client is null.");
+        return;
+    }
 #ifndef __WIN32
     if (ioctl(cli->client_fd, FIONREAD, &to_read_bytes) < 0)
     {
@@ -396,11 +375,11 @@ static void ecs_read(ECS_Client *cli) {
         LOG("ioctl failed");
          return;
     }
-     to_read_bytes = (int)to_read_bytes_long;
+    to_read_bytes = (int)to_read_bytes_long;
 #endif
 
     if (to_read_bytes == 0) {
-        LOG("ioctl FIONREAD: 0");
+        LOG("ioctl FIONREAD: 0\n");
         goto fail;
     }
 
index b31fbf7..ef2809b 100644 (file)
 #define LOG(fmt, arg...)
 #endif
 
-#ifndef _WIN32
-#define LOG_HOME                "HOME"
-#define LOG_PATH                "/tizen-sdk-data/emulator/vms/ecs.log"
-#else
-#define LOG_HOME                "LOCALAPPDATA"
-#define LOG_PATH                "\\tizen-sdk-data\\emulator\\vms\\ecs.log"
-#endif
-
 #define ECS_OPTS_NAME           "ecs"
 #define HOST_LISTEN_ADDR        "127.0.0.1"
 #define HOST_LISTEN_PORT        0
 #define COMMAND_TYPE_MONITOR    "monitor"
 #define COMMAND_TYPE_DEVICE     "device"
 
-//
 #define COMMAND_TYPE_TETHERING  "tethering"
 
-#define ECS_MSG_STARTINFO_REQ   "startinfo_req"
-#define ECS_MSG_STARTINFO_ANS   "startinfo_ans"
-
 #define MSG_TYPE_SENSOR         "sensor"
+#define MSG_TYPE_SENSOR_LEN     10
 #define MSG_TYPE_NFC            "nfc"
 #define MSG_TYPE_SIMUL_NFC      "simul_nfc"
 
 #define MSG_GROUP_STATUS        15
 
-#define MSG_ACTION_ACCEL        110
-#define MSG_ACTION_GYRO         111
-#define MSG_ACTION_MAG          112
-#define MSG_ACTION_LIGHT        113
-#define MSG_ACTION_PROXI        114
+enum message_action {
+    MSG_ACT_BATTERY_LEVEL = 100,
+    MSG_ACT_BATTERY_CHARGER = 101,
+    MSG_ACT_USB = 102,
+    MSG_ACT_EARJACK = 103,
+    MSG_ACT_RSSI = 104,
+    MSG_ACT_ACCEL = 110,
+    MSG_ACT_GYRO = 111,
+    MSG_ACT_MAG = 112,
+    MSG_ACT_LIGHT = 113,
+    MSG_ACT_PROXI = 114,
+    MSG_ACT_MOTION = 115
+};
 
 #define TIMER_ALIVE_S           60
 #define TYPE_DATA_SELF          "self"
 
-enum sensor_level {
+enum injector_level {
     level_accel = 1,
     level_proxi = 2,
     level_light = 3,
     level_gyro = 4,
     level_geo = 5,
+    level_battery = 8,
     level_tilt = 12,
     level_magnetic = 13
 };
 
+#define MAX_CATEGORY_LEN        10
 typedef unsigned short  type_length;
 typedef unsigned char   type_group;
 typedef unsigned char   type_action;
@@ -119,7 +118,7 @@ typedef struct sbuf
 {
     int _netlen;
     int _use;
-    char _buf[4096];
+    char _buf[OUT_BUF_SIZE];
 }sbuf;
 
 struct Monitor {
@@ -229,10 +228,9 @@ void send_host_keyboard_ntf(int on);
 /* request */
 int accel_min_max(double value);
 void req_set_sensor_accel(int x, int y, int z);
-void set_sensor_data(int length, const char* data);
+void set_injector_data(const char* data);
 
 /* Monitor */
-void handle_ecs_command(JSONMessageParser *parser, QList *tokens, void *opaque);
 void handle_qmp_command(JSONMessageParser *parser, QList *tokens, void *opaque);
 
 static QemuOptsList qemu_ecs_opts = {
index a7880e2..1979453 100644 (file)
@@ -569,7 +569,7 @@ out:
     QDECREF(input);
     QDECREF(args);
 }
-
+#if 0
 static int check_key(QObject *input_obj, const char *key) {
     const QDictEntry *ent;
     QDict *input_dict;
@@ -591,7 +591,7 @@ static int check_key(QObject *input_obj, const char *key) {
 
     return 0;
 }
-#if 0
+
 static QObject* get_data_object(QObject *input_obj) {
     const QDictEntry *ent;
     QDict *input_dict;
@@ -614,7 +614,7 @@ static QObject* get_data_object(QObject *input_obj) {
 
     return NULL;
 }
-#endif
+
 static int ijcount = 0;
 
 static bool injector_command_proc(ECS_Client *clii, QObject *obj) {
@@ -775,7 +775,7 @@ void handle_ecs_command(JSONMessageParser *parser, QList *tokens,
         LOG("handler not found");
     }
 }
-
+#endif
 bool msgproc_monitor_req(ECS_Client *ccli, ECS__MonitorReq* msg)
 {
     LOG(">> monitor req: data = %s", msg->command);
index 2e1fe9c..8a39b64 100644 (file)
@@ -62,6 +62,8 @@
 
 #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 "skin/maruskin_operation.h"
 #include "skin/maruskin_server.h"
@@ -145,6 +147,39 @@ static bool send_to_single_client(ECS__Master* master, ECS_Client *ccli)
     return true;
 }
 #endif
+
+static void send_status_injector_ntf(const char* cmd, int cmdlen, int act, char* on)
+{
+    int msglen = 0, datalen = 0;
+    type_length length  = 0;
+    type_group group = GROUP_STATUS;
+    type_action action = act;
+
+    if (cmd == NULL || on == NULL || cmdlen > 10)
+        return;
+
+    datalen = strlen(on);
+    length  = (unsigned short)datalen;
+
+    msglen = datalen + 15;
+    char* status_msg = (char*) malloc(msglen);
+    if(!status_msg)
+        return;
+
+    memset(status_msg, 0, msglen);
+
+    memcpy(status_msg, cmd, cmdlen);
+    memcpy(status_msg + 10, &length, sizeof(unsigned short));
+    memcpy(status_msg + 12, &group, sizeof(unsigned char));
+    memcpy(status_msg + 13, &action, sizeof(unsigned char));
+    memcpy(status_msg + 14, on, datalen);
+
+    send_injector_ntf(status_msg, msglen);
+
+    if (status_msg)
+        free(status_msg);
+}
+
 static void msgproc_injector_ans(ECS_Client* ccli, const char* category, bool succeed)
 {
     if (ccli == NULL) {
@@ -173,7 +208,10 @@ static void msgproc_injector_ans(ECS_Client* ccli, const char* category, bool su
 bool msgproc_injector_req(ECS_Client* ccli, ECS__InjectorReq* msg)
 {
     char cmd[10];
+    char data[10];
     bool ret = false;
+    int sndlen = 0;
+    char* sndbuf;
     memset(cmd, 0, 10);
     strcpy(cmd, msg->category);
     type_length length = (type_length) msg->length;
@@ -191,9 +229,29 @@ bool msgproc_injector_req(ECS_Client* ccli, ECS__InjectorReq* msg)
     LOG(">> header = cmd = %s, length = %d, action=%d, group=%d", cmd, length,
             action, group);
 
+    if (!strncmp(cmd, MSG_TYPE_SENSOR, 6)) {
+        if (group == MSG_GROUP_STATUS) {
+            memset(data, 0, 10);
+            if (action == MSG_ACT_BATTERY_LEVEL) {
+                sprintf(data, "%d", get_power_capacity());
+            } else if (action == MSG_ACT_BATTERY_CHARGER){
+                sprintf(data, "%d", get_jack_charger());
+            } else {
+                goto injector_send;
+            }
+            LOG("status : %s", data);
+            send_status_injector_ntf(MSG_TYPE_SENSOR, MSG_TYPE_SENSOR_LEN, action, data);
+            goto injector_req_success;
+        } else {
+            if (msg->data.data && datalen > 0){
+                set_injector_data((char*)msg->data.data);
+            }
+        }
+    }
 
-    int sndlen = datalen + 14;
-    char* sndbuf = (char*) g_malloc(sndlen + 1);
+injector_send:
+    sndlen = datalen + 14;
+    sndbuf = (char*) g_malloc(sndlen + 1);
     if (!sndbuf) {
         goto injector_req_fail;
     }
@@ -224,6 +282,7 @@ bool msgproc_injector_req(ECS_Client* ccli, ECS__InjectorReq* msg)
     if (!ret)
         goto injector_req_fail;
 
+injector_req_success:
     msgproc_injector_ans(ccli, cmd, ret);
     return true;
 
@@ -334,20 +393,20 @@ bool msgproc_device_req(ECS_Client* ccli, ECS__DeviceReq* msg)
 
     if (!strncmp(cmd, MSG_TYPE_SENSOR, 6)) {
         if (group == MSG_GROUP_STATUS) {
-            if (action == MSG_ACTION_ACCEL) {
+            if (action == MSG_ACT_ACCEL) {
                 get_sensor_accel();
-            } else if (action == MSG_ACTION_GYRO) {
+            } else if (action == MSG_ACT_GYRO) {
                 get_sensor_gyro();
-            } else if (action == MSG_ACTION_MAG) {
+            } else if (action == MSG_ACT_MAG) {
                 get_sensor_mag();
-            } else if (action == MSG_ACTION_LIGHT) {
+            } else if (action == MSG_ACT_LIGHT) {
                 get_sensor_light();
-            } else if (action == MSG_ACTION_PROXI) {
+            } else if (action == MSG_ACT_PROXI) {
                 get_sensor_proxi();
             }
         } else {
             if (data != NULL) {
-                set_sensor_data(length, data);
+                set_injector_data(data);
             }
         }
     } else if (!strncmp(cmd, "Network", 7)) {
index ccb04c3..e524c31 100644 (file)
@@ -37,6 +37,8 @@
 
 #include "ecs.h"
 #include "hw/maru_virtio_sensor.h"
+#include "hw/maru_virtio_power.h"
+#include "hw/maru_virtio_jack.h"
 
 #define TEMP_BUF_SIZE   255
 #define MAX_VAL_LENGTH  40
@@ -293,7 +295,40 @@ static void _req_set_sensor_mag(int len, const char* data)
     set_sensor_mag(tmp, strlen(tmp));
 }
 
-void set_sensor_data(int length, const char* data)
+static void set_battery_data(int len, const char* data) {
+    char tmp[TEMP_BUF_SIZE];
+    int id = 0, status = 0, level = 0;
+
+    // remove item size
+    len += get_parse_val(data + len, tmp);
+
+    // id
+    len += get_parse_val(data + len, tmp);
+    id = atoi(tmp);
+
+    // status
+    len += get_parse_val(data + len, tmp);
+    status = atoi(tmp);
+
+    if (id == 1) {
+        set_power_capacity(status);
+        if (status == 100) {
+            set_power_charge_full(1);
+        } else {
+            set_power_charge_full(0);
+        }
+    } else if (id == 2) {
+        level = get_power_capacity();
+        set_jack_charger(status);
+        if (level != 100 && status == 1) {
+            set_power_charge_now(1);
+        } else {
+            set_power_charge_now(0);
+        }
+    }
+}
+
+void set_injector_data(const char* data)
 {
     char tmpbuf[TEMP_BUF_SIZE];
     int len = get_parse_val(data, tmpbuf);
@@ -314,6 +349,9 @@ void set_sensor_data(int length, const char* data)
         case level_geo:
             _req_set_sensor_geo(len, data);
             break;
+        case level_battery:
+            set_battery_data(len, data);
+            break;
         case level_tilt:
             _req_set_sensor_tilt(len, data);
             break;
index f5c64af..9315da8 100644 (file)
@@ -5,7 +5,7 @@
  *
  * Contact:
  *  KiTae Kim       <kt920.kim@samsung.com>
- *  JiHey Kim       <jihye1128.kim@samsung.com>
+ *  JiHye Kim       <jihye1128.kim@samsung.com>
  *  YeongKyoon Lee  <yeongkyoon.lee@samsung.com>
  *
  * This program is free software; you can redistribute it and/or
@@ -222,7 +222,7 @@ static bool send_tethering_ntf(const char *data)
 
 void send_tethering_sensor_data(const char *data, int len)
 {
-    set_sensor_data(len, data);
+    set_injector_data(data);
 }
 
 void send_tethering_touch_data(int x, int y, int index, int status)
index 0b1623a..7672b33 100644 (file)
 #define PCI_DEVICE_ID_VIRTIO_KEYBOARD    0x1020
 #define PCI_DEVICE_ID_VIRTIO_ESM         0x1024
 #define PCI_DEVICE_ID_VIRTIO_HWKEY       0x1028
-#define PCI_DEVICE_ID_VIRTIO_EVDI        0x1032
-#define PCI_DEVICE_ID_VIRTIO_GL          0x1036
-#define PCI_DEVICE_ID_VIRTIO_SENSOR      0x103A
-#define PCI_DEVICE_ID_VIRTIO_NFC         0x103E
+#define PCI_DEVICE_ID_VIRTIO_EVDI        0x102C
+#define PCI_DEVICE_ID_VIRTIO_GL          0x1030
+#define PCI_DEVICE_ID_VIRTIO_SENSOR      0x1034
+#define PCI_DEVICE_ID_VIRTIO_POWER       0x1035
+#define PCI_DEVICE_ID_VIRTIO_JACK        0x1036
+#define PCI_DEVICE_ID_VIRTIO_NFC         0x1038
 #define PCI_DEVICE_ID_VIRTUAL_BRILL_CODEC  0x1040
 
 /* Virtio */
@@ -95,5 +97,7 @@
 #define VIRTIO_ID_GL                   36
 #define VIRTIO_ID_SENSOR        37
 #define VIRTIO_ID_NFC           38
+#define VIRTIO_ID_JACK          39
+#define VIRTIO_ID_POWER         40
 
 #endif /* MARU_DEVICE_IDS_H_ */
diff --git a/tizen/src/hw/maru_virtio_jack.c b/tizen/src/hw/maru_virtio_jack.c
new file mode 100644 (file)
index 0000000..0747487
--- /dev/null
@@ -0,0 +1,279 @@
+/*
+ * 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;
+
+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_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);
+
+    INFO("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) {
+        INFO("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);
+
+        INFO("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 virtio_jack_init(VirtIODevice *vdev)
+{
+    INFO("initialize virtio-jack device\n");
+
+    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 -1;
+    }
+
+    vjack->vq = virtio_add_queue(&vjack->vdev, 64, virtio_jack_vq);
+
+    return 0;
+}
+
+static int virtio_jack_exit(DeviceState *dev)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    INFO("destroy jack device\n");
+
+    virtio_cleanup(vdev);
+
+    return 0;
+}
+
+
+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 void virtio_jack_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+    dc->exit = virtio_jack_exit;
+    vdc->init = virtio_jack_init;
+    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
new file mode 100644 (file)
index 0000000..4b85232
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * 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_charger = 0,
+    jack_type_earjack,
+    jack_type_earkey,
+    jack_type_hdmi,
+    jack_type_usb,
+    jack_type_max
+};
+
+typedef struct VirtIOJACK {
+    VirtIODevice    vdev;
+    VirtQueue       *vq;
+    DeviceState     *qdev;
+
+    QEMUBH          *bh;
+} VirtIOJACK;
+
+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_power.c b/tizen/src/hw/maru_virtio_power.c
new file mode 100644 (file)
index 0000000..400db63
--- /dev/null
@@ -0,0 +1,273 @@
+/*
+ * 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);
+
+    INFO("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) {
+        INFO("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);
+
+        INFO("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 virtio_power_init(VirtIODevice *vdev)
+{
+    INFO("initialize virtio-power device\n");
+
+    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 -1;
+    }
+
+    vpower->vq = virtio_add_queue(&vpower->vdev, 64, virtio_power_vq);
+
+    return 0;
+}
+
+static int virtio_power_exit(DeviceState *dev)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    INFO("destroy power device\n");
+
+    virtio_cleanup(vdev);
+
+    return 0;
+}
+
+
+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)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+    dc->exit = virtio_power_exit;
+    vdc->init = virtio_power_init;
+    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
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
index 4558225..a0475eb 100644 (file)
 MULTI_DEBUG_CHANNEL(qemu, virtio-sensor);
 
 #define SENSOR_DEVICE_NAME  "sensor"
-#define _MAX_BUF                    1024
+#define _MAX_BUF            1024
+#define __MAX_BUF_SENSOR    32
 
+static char accel_xyz [__MAX_BUF_SENSOR] = {'0',',','9','8','0','6','6','5',',','0'};
+
+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 gyro_x_raw = 0;
+static int gyro_y_raw = 0;
+static int gyro_z_raw = 0;
+
+static int light_adc = 65535;
+static int light_level = 10;
+
+static int proxi_vo = 8;
 
 VirtIOSENSOR* vsensor;
 
@@ -49,106 +63,8 @@ typedef struct msg_info {
 
     uint16_t type;
     uint16_t req;
-
-    QTAILQ_ENTRY(msg_info) next;
 } msg_info;
 
-
-static QTAILQ_HEAD(msgInfoRecvHead , msg_info) sensor_msg_queue =
-    QTAILQ_HEAD_INITIALIZER(sensor_msg_queue);
-
-static pthread_mutex_t buf_mutex = PTHREAD_MUTEX_INITIALIZER;
-
-static void add_msg_queue(msg_info* msg)
-{
-    pthread_mutex_lock(&buf_mutex);
-    QTAILQ_INSERT_TAIL(&sensor_msg_queue, msg, next);
-    pthread_mutex_unlock(&buf_mutex);
-
-    qemu_bh_schedule(vsensor->bh);
-}
-
-void req_sensor_data (enum sensor_types type, enum request_cmd req, char* data, int len)
-{
-    if (type >= sensor_type_max || (req != request_get && req != request_set)) {
-        ERR("unavailable sensor type request.\n");
-    }
-
-    msg_info* msg = (msg_info*) malloc(sizeof(msg_info));
-    if (!msg) {
-        ERR("The allocation of msg_info is failed.\n");
-        return;
-    }
-
-    memset(msg, 0, sizeof(msg_info));
-
-    if (req == request_set) {
-        if (len > _MAX_BUF) {
-            ERR("The data is too big to send.\n");
-                       free(msg);
-            return;
-        }
-        memcpy(msg->buf, data, len);
-    }
-
-    msg->type = type;
-    msg->req = req;
-
-    add_msg_queue(msg);
-}
-
-static void flush_sensor_recv_queue(void)
-{
-    int index;
-
-    if (unlikely(!virtio_queue_ready(vsensor->rvq))) {
-        INFO("virtio queue is not ready\n");
-        return;
-    }
-
-    if (unlikely(virtio_queue_empty(vsensor->rvq))) {
-        INFO("virtqueue is empty\n");
-        return;
-    }
-
-    pthread_mutex_lock(&buf_mutex);
-    while (!QTAILQ_EMPTY(&sensor_msg_queue))
-    {
-        msg_info* msginfo = QTAILQ_FIRST(&sensor_msg_queue);
-        if (!msginfo) {
-            ERR("msginfo is NULL!\n");
-            break;
-        }
-
-        INFO("sending message: %s, type: %d, req: %d\n", msginfo->buf, msginfo->type, msginfo->req);
-
-        VirtQueueElement elem;
-        index = virtqueue_pop(vsensor->rvq, &elem);
-        if (index == 0)
-            break;
-
-        memcpy(elem.in_sg[0].iov_base, msginfo, sizeof(struct msg_info));
-
-        virtqueue_push(vsensor->rvq, &elem, sizeof(msg_info));
-        virtio_notify(&vsensor->vdev, vsensor->rvq);
-
-        QTAILQ_REMOVE(&sensor_msg_queue, msginfo, next);
-        if (msginfo)
-            free(msginfo);
-    }
-    pthread_mutex_unlock(&buf_mutex);
-}
-
-static void virtio_sensor_recv(VirtIODevice *vdev, VirtQueue *vq)
-{
-    flush_sensor_recv_queue();
-}
-
-static void maru_sensor_bh(void *opaque)
-{
-    flush_sensor_recv_queue();
-}
-
 static type_action get_action(enum sensor_types type)
 {
     type_action action = 0;
@@ -176,13 +92,12 @@ static type_action get_action(enum sensor_types type)
     return action;
 }
 
-static void send_to_ecs(struct msg_info* msg)
+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(msg->buf);
+    int buf_len = strlen(data);
     int message_len =  buf_len + 14;
 
     char* ecs_message = (char*) malloc(message_len + 1);
@@ -192,15 +107,15 @@ static void send_to_ecs(struct msg_info* msg)
     memset(ecs_message, 0, message_len + 1);
 
     length = (unsigned short) buf_len;
-    action = get_action(msg->type);
+    action = get_action(type);
 
     memcpy(ecs_message, MESSAGE_TYPE_SENSOR, 10);
     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, msg->buf, buf_len);
+    memcpy(ecs_message + 14, data, buf_len);
 
-    INFO("ntf_to_injector- len: %d, group: %d, action: %d, data: %s\n", length, group, action, msg->buf);
+    INFO("ntf_to_injector- len: %d, group: %d, action: %d, data: %s\n", length, group, action, data);
 
     send_device_ntf(ecs_message, message_len);
 
@@ -208,32 +123,186 @@ static void send_to_ecs(struct msg_info* msg)
         free(ecs_message);
 }
 
-static void virtio_sensor_send(VirtIODevice *vdev, VirtQueue *vq)
+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;
+    }
+
+    switch (type) {
+        case sensor_type_accel:
+            strcpy(accel_xyz, data);
+            break;
+        case sensor_type_gyro_x:
+            sscanf(data, "%d", &gyro_x_raw);
+            break;
+        case sensor_type_gyro_y:
+            sscanf(data, "%d", &gyro_y_raw);
+            break;
+        case sensor_type_gyro_z:
+            sscanf(data, "%d", &gyro_z_raw);
+            break;
+        case sensor_type_light_adc:
+            sscanf(data, "%d", &light_adc);
+            light_level = (light_adc / 6554) % 10 + 1;
+            break;
+        case sensor_type_light_level:
+            sscanf(data, "%d", &light_level);
+            break;
+        case sensor_type_proxi:
+            sscanf(data, "%d", &proxi_vo);
+            break;
+        case sensor_type_mag:
+            strcpy(geo_tesla, data);
+            break;
+        case sensor_type_tilt:
+            strcpy(geo_raw, data);
+            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_accel:
+            strcpy(msg_info, accel_xyz);
+            break;
+        case sensor_type_mag:
+            strcpy(msg_info, geo_tesla);
+            break;
+        case sensor_type_tilt:
+            strcpy(msg_info, geo_raw);
+            break;
+        case sensor_type_gyro:
+            sprintf(msg_info, "%d, %d, %d", gyro_x_raw, gyro_y_raw, gyro_z_raw);
+            break;
+        case sensor_type_gyro_x:
+            sprintf(msg_info, "%d", gyro_x_raw);
+            break;
+        case sensor_type_gyro_y:
+            sprintf(msg_info, "%d", gyro_y_raw);
+            break;
+        case sensor_type_gyro_z:
+            sprintf(msg_info, "%d", gyro_z_raw);
+            break;
+        case sensor_type_light:
+        case sensor_type_light_adc:
+            sprintf(msg_info, "%d", light_adc);
+            break;
+        case sensor_type_light_level:
+            sprintf(msg_info, "%d", light_level);
+            break;
+        case sensor_type_proxi:
+            sprintf(msg_info, "%d", proxi_vo);
+            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);
+
+    INFO("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) {
+        INFO("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 (virtio_queue_empty(vsensor->svq)) {
-        INFO("<< virtqueue is empty.\n");
+    if (vsensor->vq == NULL) {
+        ERR("virt queue is not ready.\n");
         return;
     }
 
-    while ((index = virtqueue_pop(vq, &elem))) {
+    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);
 
-        INFO("send to ecs: %s, len: %d, type: %d, req: %d\n", msg.buf, strlen(msg.buf), msg.type, msg.req);
-        send_to_ecs(&msg);
-    }
+        INFO("handling msg from driver: %s, len: %d, type: %d, req: %d, index: %d\n", msg.buf, strlen(msg.buf), msg.type, msg.req, index);
 
-    virtqueue_push(vq, &elem, sizeof(VirtIOSENSOR));
-    virtio_notify(&vsensor->vdev, vq);
+        handle_msg(&msg, &elem);
+    }
 }
 
-
 static int virtio_sensor_init(VirtIODevice *vdev)
 {
     INFO("initialize virtio-sensor device\n");
@@ -247,10 +316,7 @@ static int virtio_sensor_init(VirtIODevice *vdev)
         return -1;
     }
 
-    vsensor->rvq = virtio_add_queue(&vsensor->vdev, 64, virtio_sensor_recv);
-    vsensor->svq = virtio_add_queue(&vsensor->vdev, 64, virtio_sensor_send);
-
-    vsensor->bh = qemu_bh_new(maru_sensor_bh, vsensor);
+    vsensor->vq = virtio_add_queue(&vsensor->vdev, 64, virtio_sensor_vq);
 
     return 0;
 }
@@ -260,9 +326,6 @@ static int virtio_sensor_exit(DeviceState *dev)
     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
     INFO("destroy sensor device\n");
 
-    if (vsensor->bh)
-        qemu_bh_delete(vsensor->bh);
-
     virtio_cleanup(vdev);
 
     return 0;
@@ -281,7 +344,6 @@ static uint32_t virtio_sensor_get_features(VirtIODevice *vdev,
     return 0;
 }
 
-
 static void virtio_sensor_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -292,8 +354,6 @@ static void virtio_sensor_class_init(ObjectClass *klass, void *data)
     vdc->reset = virtio_sensor_reset;
 }
 
-
-
 static const TypeInfo virtio_device_info = {
     .name = TYPE_VIRTIO_SENSOR,
     .parent = TYPE_VIRTIO_DEVICE,
index 9ba1d56..31093a5 100644 (file)
@@ -4,9 +4,9 @@
  * 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>
+ *  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
@@ -37,31 +37,36 @@ extern "C" {
 #include "hw/virtio/virtio.h"
 
 enum request_cmd {
-       request_get = 0,
-       request_set,
-       request_answer
+    request_get = 0,
+    request_set,
+    request_answer
 };
 
 enum sensor_types {
-       sensor_type_accel = 0,
-       sensor_type_geo,
-       sensor_type_gyro,
-       sensor_type_light,
-       sensor_type_proxi,
-       sensor_type_mag,
-       sensor_type_tilt,
-       sensor_type_max
+    sensor_type_accel = 0,
+    sensor_type_geo,
+    sensor_type_gyro,
+    sensor_type_gyro_x,
+    sensor_type_gyro_y,
+    sensor_type_gyro_z,
+    sensor_type_light,
+    sensor_type_light_adc,
+    sensor_type_light_level,
+    sensor_type_proxi,
+    sensor_type_mag,
+    sensor_type_tilt,
+    sensor_type_max
 };
 
-#define MESSAGE_TYPE_SENSOR    "sensor"
+#define MESSAGE_TYPE_SENSOR "sensor"
 
-#define GROUP_STATUS           15
+#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 ACTION_ACCEL        110
+#define ACTION_GYRO         111
+#define ACTION_MAG          112
+#define ACTION_LIGHT        113
+#define ACTION_PROXI        114
 
 #define TYPE_VIRTIO_SENSOR "virtio-sensor-device"
 #define VIRTIO_SENSOR(obj) \
@@ -69,47 +74,44 @@ enum sensor_types {
 
 typedef struct VirtIOSENSOR {
     VirtIODevice    vdev;
-    VirtQueue       *rvq;
-    VirtQueue       *svq;
+    VirtQueue       *vq;
     DeviceState     *qdev;
-
-       QEMUBH                  *bh;
 } 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_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_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_mag()    \
+    req_sensor_data(sensor_type_mag, request_get, NULL, 0);
 
-#define get_sensor_light()     \
-       req_sensor_data(sensor_type_light, request_get, NULL, 0);
+#define get_sensor_light()  \
+    req_sensor_data(sensor_type_light, request_get, NULL, 0);
 
-#define get_sensor_proxi()     \
-       req_sensor_data(sensor_type_proxi, 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_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_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, request_set, data, len);
+#define set_sensor_light(data, len) \
+    req_sensor_data(sensor_type_light, request_set, data, len);
 
-#define set_sensor_gyro(data, len)     \
-       req_sensor_data(sensor_type_gyro, 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_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);
+#define set_sensor_mag(data, len)   \
+    req_sensor_data(sensor_type_mag, request_set, data, len);
 
 #ifdef __cplusplus
 }