.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
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
}
#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
typedef struct VirtIOKeyboardPCI VirtIOKeyboardPCI;
typedef struct VirtIOSENSORPCI VirtIOSENSORPCI;
typedef struct VirtIONFCPCI VirtIONFCPCI;
+typedef struct VirtIOPOWERPCI VirtIOPOWERPCI;
+typedef struct VirtIOJACKPCI VirtIOJACKPCI;
#endif
/* virtio-pci-bus */
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. */
+* 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
-Version: 1.7.23
+Version: 1.7.24
Maintainer: Yeong-Kyoon Lee<yeongkyoon.lee@samsung.com>
Source: emulator
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
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
}
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)
{
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;
}
#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;
{
int _netlen;
int _use;
- char _buf[4096];
+ char _buf[OUT_BUF_SIZE];
}sbuf;
struct Monitor {
/* 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 = {
QDECREF(input);
QDECREF(args);
}
-
+#if 0
static int check_key(QObject *input_obj, const char *key) {
const QDictEntry *ent;
QDict *input_dict;
return 0;
}
-#if 0
+
static QObject* get_data_object(QObject *input_obj) {
const QDictEntry *ent;
QDict *input_dict;
return NULL;
}
-#endif
+
static int ijcount = 0;
static bool injector_command_proc(ECS_Client *clii, QObject *obj) {
LOG("handler not found");
}
}
-
+#endif
bool msgproc_monitor_req(ECS_Client *ccli, ECS__MonitorReq* msg)
{
LOG(">> monitor req: data = %s", msg->command);
#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"
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) {
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;
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;
}
if (!ret)
goto injector_req_fail;
+injector_req_success:
msgproc_injector_ans(ccli, cmd, ret);
return true;
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)) {
#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
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);
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;
*
* 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
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)
#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 */
#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_ */
--- /dev/null
+/*
+ * 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)
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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)
+
--- /dev/null
+/*
+ * 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
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;
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;
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);
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);
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");
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;
}
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
INFO("destroy sensor device\n");
- if (vsensor->bh)
- qemu_bh_delete(vsensor->bh);
-
virtio_cleanup(vdev);
return 0;
return 0;
}
-
static void virtio_sensor_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
vdc->reset = virtio_sensor_reset;
}
-
-
static const TypeInfo virtio_device_info = {
.name = TYPE_VIRTIO_SENSOR,
.parent = TYPE_VIRTIO_DEVICE,
* Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact:
- * Jinhyung choi <jinhyung2.choi@samsung.com>
- * Daiyoung Kim <daiyoung777.kim@samsung.com>
- * YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ * 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
#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) \
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
}