From: Jinhyung Choi Date: Thu, 6 Mar 2014 05:24:49 +0000 (+0900) Subject: Devices: data is moved into qemu from kernel X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.1~480 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=158b013175a26bf1dce48e642c736e17f8ebc5a4;p=sdk%2Femulator%2Fqemu.git Devices: data is moved into qemu from kernel - virtio devices: Jacks, battery, and sensor Change-Id: I846717a99cfdac02b3d57336d385fb2c03ed08f3 Signed-off-by: Jinhyung Choi --- diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index cf6ac0b8e0..5920cd0112 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -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 } diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h index e9a6d7943a..8912d96957 100644 --- a/hw/virtio/virtio-pci.h +++ b/hw/virtio/virtio-pci.h @@ -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. */ diff --git a/package/changelog b/package/changelog index 6307b9636d..bd49bc0e1c 100644 --- a/package/changelog +++ b/package/changelog @@ -1,3 +1,6 @@ +* 1.7.24 +- Moved device data into qemu from driver +== Jinhyung Choi 2014-03-06 * 1.7.23 - modified SDK version loading == GiWoong Kim 2014-03-04 diff --git a/package/pkginfo.manifest b/package/pkginfo.manifest index 129d805977..88f614f792 100644 --- a/package/pkginfo.manifest +++ b/package/pkginfo.manifest @@ -1,4 +1,4 @@ -Version: 1.7.23 +Version: 1.7.24 Maintainer: Yeong-Kyoon Lee Source: emulator diff --git a/tizen/src/Makefile.tizen b/tizen/src/Makefile.tizen index 5fb4d983fa..9b126cfabb 100644 --- a/tizen/src/Makefile.tizen +++ b/tizen/src/Makefile.tizen @@ -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 diff --git a/tizen/src/ecs/ecs.c b/tizen/src/ecs/ecs.c index b722193c28..e721511a28 100644 --- a/tizen/src/ecs/ecs.c +++ b/tizen/src/ecs/ecs.c @@ -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; } diff --git a/tizen/src/ecs/ecs.h b/tizen/src/ecs/ecs.h index b31fbf701c..ef2809b708 100644 --- a/tizen/src/ecs/ecs.h +++ b/tizen/src/ecs/ecs.h @@ -55,14 +55,6 @@ #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 @@ -77,37 +69,44 @@ #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 = { diff --git a/tizen/src/ecs/ecs_mon.c b/tizen/src/ecs/ecs_mon.c index a7880e2ed0..19794536d2 100644 --- a/tizen/src/ecs/ecs_mon.c +++ b/tizen/src/ecs/ecs_mon.c @@ -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); diff --git a/tizen/src/ecs/ecs_msg.c b/tizen/src/ecs/ecs_msg.c index 2e1fe9ccd4..8a39b64490 100644 --- a/tizen/src/ecs/ecs_msg.c +++ b/tizen/src/ecs/ecs_msg.c @@ -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)) { diff --git a/tizen/src/ecs/ecs_sensor.c b/tizen/src/ecs/ecs_sensor.c index ccb04c3feb..e524c31115 100644 --- a/tizen/src/ecs/ecs_sensor.c +++ b/tizen/src/ecs/ecs_sensor.c @@ -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; diff --git a/tizen/src/ecs/ecs_tethering.c b/tizen/src/ecs/ecs_tethering.c index f5c64afb83..9315da89a3 100644 --- a/tizen/src/ecs/ecs_tethering.c +++ b/tizen/src/ecs/ecs_tethering.c @@ -5,7 +5,7 @@ * * Contact: * KiTae Kim - * JiHey Kim + * JiHye Kim * YeongKyoon Lee * * 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) diff --git a/tizen/src/hw/maru_device_ids.h b/tizen/src/hw/maru_device_ids.h index 0b1623ae73..7672b33ce5 100644 --- a/tizen/src/hw/maru_device_ids.h +++ b/tizen/src/hw/maru_device_ids.h @@ -53,10 +53,12 @@ #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 index 0000000000..0747487976 --- /dev/null +++ b/tizen/src/hw/maru_virtio_jack.c @@ -0,0 +1,279 @@ +/* + * Virtio Jack Device + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: + * Jinhyung Choi + * Daiyoung Kim + * YeongKyoon Lee + * + * 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 + +#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 index 0000000000..4b85232cca --- /dev/null +++ b/tizen/src/hw/maru_virtio_jack.h @@ -0,0 +1,70 @@ +/* + * Virtio Jack Device + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: + * Jinhyung choi + * Daiyoung Kim + * YeongKyoon Lee + * + * 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 index 0000000000..400db63202 --- /dev/null +++ b/tizen/src/hw/maru_virtio_power.c @@ -0,0 +1,273 @@ +/* + * Virtio Power Device + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: + * Jinhyung Choi + * Daiyoung Kim + * YeongKyoon Lee + * + * 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 + +#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 index 0000000000..0a76fec557 --- /dev/null +++ b/tizen/src/hw/maru_virtio_power.h @@ -0,0 +1,69 @@ +/* + * Virtio Power Device + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: + * Jinhyung choi + * Daiyoung Kim + * YeongKyoon Lee + * + * 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 index 4558225315..a0475ebcff 100644 --- a/tizen/src/hw/maru_virtio_sensor.c +++ b/tizen/src/hw/maru_virtio_sensor.c @@ -39,8 +39,22 @@ 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, diff --git a/tizen/src/hw/maru_virtio_sensor.h b/tizen/src/hw/maru_virtio_sensor.h index 9ba1d56e48..31093a5477 100644 --- a/tizen/src/hw/maru_virtio_sensor.h +++ b/tizen/src/hw/maru_virtio_sensor.h @@ -4,9 +4,9 @@ * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: - * Jinhyung choi - * Daiyoung Kim - * YeongKyoon Lee + * Jinhyung choi + * Daiyoung Kim + * YeongKyoon Lee * * 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 }