sensor: added pressure, ultraviolet, and hrm sensor 45/28745/4 tizen_linux_3.12
authorJinhyung Choi <jinhyung2.choi@samsung.com>
Wed, 15 Oct 2014 09:57:10 +0000 (18:57 +0900)
committerJinhyung Choi <jinhyung2.choi@samsung.com>
Thu, 23 Oct 2014 06:23:45 +0000 (15:23 +0900)
- modified and converted the value (sync with sensor fw)

Change-Id: I087418ae5c756042489d558d32b92baef6492e6a
Signed-off-by: Jinhyung Choi <jinhyung2.choi@samsung.com>
drivers/maru/sensors/Makefile
drivers/maru/sensors/maru_accel.c
drivers/maru/sensors/maru_geo.c
drivers/maru/sensors/maru_gyro.c
drivers/maru/sensors/maru_hrm.c [new file with mode: 0644]
drivers/maru/sensors/maru_light.c
drivers/maru/sensors/maru_pressure.c [new file with mode: 0644]
drivers/maru/sensors/maru_proxi.c
drivers/maru/sensors/maru_uv.c [new file with mode: 0644]
drivers/maru/sensors/maru_virtio_sensor.c
drivers/maru/sensors/maru_virtio_sensor.h

index 92d79d5addce513d4f553d884d757196e77922a7..5a9914616e081a52f5e7bbb6e6215f9187eed683 100644 (file)
@@ -5,4 +5,7 @@ obj-$(CONFIG_MARU_VIRTIO_SENSOR) += maru_virtio_sensor.o        \
                                                                        maru_light.o                    \
                                                                        maru_proxi.o                    \
                                                                        maru_rotation_vector.o  \
-                                                                       maru_haptic.o
+                                                                       maru_haptic.o                   \
+                                                                       maru_pressure.o                 \
+                                                                       maru_uv.o                               \
+                                                                       maru_hrm.o
index 679ffa36f88b4e85eee90d8c62961831ae9c6833..3bba6bb05a88b79fed6d70b05ddc3190e7396728 100644 (file)
@@ -29,6 +29,7 @@
 
 #include <linux/kernel.h>
 #include <linux/slab.h>
+#include <linux/limits.h>
 
 #include "maru_virtio_sensor.h"
 
@@ -49,12 +50,23 @@ static struct device *accel_sensor_device;
 static struct device *l_accel_sensor_device;
 #endif
 
+#define GRAVITY_CHANGE_UNIT            15322
+static short sensor_convert_data(int number)
+{
+       int temp;
+       temp = number / 64;
+       temp = temp * (SHRT_MAX / 2);
+       temp = temp / GRAVITY_CHANGE_UNIT;
+       return (short)temp;
+}
+
 static void maru_accel_input_work_func(struct work_struct *work) {
 
        int poll_time = 200000000;
        int enable = 0;
        int ret = 0;
        int accel_x, accel_y, accel_z;
+       short raw_x, raw_y, raw_z;
        char sensor_data[__MAX_BUF_SENSOR];
        struct maru_accel_data *data = container_of((struct delayed_work *)work,
                        struct maru_accel_data, work);
@@ -74,11 +86,27 @@ static void maru_accel_input_work_func(struct work_struct *work) {
                mutex_unlock(&data->data_mutex);
                if (!ret) {
                        sscanf(sensor_data, "%d,%d,%d", &accel_x, &accel_y, &accel_z);
-                       LOG(1, "accel_set %d, %d, %d", accel_x, accel_y, accel_z);
-
-                       input_report_rel(data->input_data, REL_RX, accel_x);
-                       input_report_rel(data->input_data, REL_RY, accel_y);
-                       input_report_rel(data->input_data, REL_RZ, accel_z);
+                       LOG(1, "accel_set act %d, %d, %d", accel_x, accel_y, accel_z);
+                       raw_x = sensor_convert_data(accel_x);
+                       raw_y = sensor_convert_data(accel_y);
+                       raw_z = sensor_convert_data(accel_z);
+                       LOG(1, "accel_set raw %d, %d, %d", raw_x, raw_y, raw_z);
+
+                       if (raw_x == 0) {
+                               raw_x = 1;
+                       }
+
+                       if (raw_y == 0) {
+                               raw_y = 1;
+                       }
+
+                       if (raw_z == 0) {
+                               raw_z = 1;
+                       }
+
+                       input_report_rel(data->input_data, REL_X, raw_x);
+                       input_report_rel(data->input_data, REL_Y, raw_y);
+                       input_report_rel(data->input_data, REL_Z, raw_z);
                        input_sync(data->input_data);
                }
        }
@@ -236,10 +264,9 @@ static int set_initial_value(struct maru_accel_data *data)
 {
        int delay = 0;
        int ret = 0;
-       int enable = 0;
        char sensor_data [__MAX_BUF_SENSOR];
 
-       memset(sensor_data, 0, __MAX_BUF_SENSOR);
+       memset(sensor_data, 0, sizeof(sensor_data));
 
        ret = get_sensor_data(sensor_type_accel_delay, sensor_data);
        if (ret) {
@@ -248,15 +275,6 @@ static int set_initial_value(struct maru_accel_data *data)
        }
 
        delay = sensor_atoi(sensor_data);
-
-       ret = get_sensor_data(sensor_type_accel_enable, sensor_data);
-       if (ret) {
-               ERR("failed to get initial enable");
-               return ret;
-       }
-
-       enable = sensor_atoi(sensor_data);
-
        if (delay < 0) {
                ERR("weird value is set initial delay");
                return ret;
@@ -264,10 +282,11 @@ static int set_initial_value(struct maru_accel_data *data)
 
        atomic_set(&data->poll_delay, delay);
 
-       if (enable) {
-               atomic_set(&data->enable, 1);
-               schedule_delayed_work(&data->work, 0);
-       }
+       memset(sensor_data, 0, sizeof(sensor_data));
+       sensor_data[0] = '0';
+
+       set_sensor_data(sensor_type_accel_enable, sensor_data);
+       atomic_set(&data->enable, 0);
 
        return ret;
 }
@@ -289,9 +308,9 @@ static int create_input_device(struct maru_accel_data *data)
 
        set_bit(EV_REL, input_data->evbit);
        set_bit(EV_SYN, input_data->evbit);
-       input_set_capability(input_data, EV_REL, REL_RX);
-       input_set_capability(input_data, EV_REL, REL_RY);
-       input_set_capability(input_data, EV_REL, REL_RZ);
+       input_set_capability(input_data, EV_REL, REL_X);
+       input_set_capability(input_data, EV_REL, REL_Y);
+       input_set_capability(input_data, EV_REL, REL_Z);
 
        data->input_data = input_data;
 
index b5422e8909a8a558555517796fa42728277fbb12..3d5ac703e217f17c8e59e9116cc3a9f28da348f2 100644 (file)
@@ -49,12 +49,18 @@ static struct device *geo_sensor_device;
 static struct device *l_geo_sensor_device;
 #endif
 
+static short sensor_convert_data(int number)
+{
+       return (short) ((number * 5) / 3); // divided by 0.6
+}
+
 static void maru_geo_input_work_func(struct work_struct *work) {
 
        int poll_time = 200000000;
        int enable = 0;
        int ret = 0;
-       int geo_x, geo_y, geo_z, hdst;
+       int geo_x, geo_y, geo_z, hdst = 4;
+       short raw_x, raw_y, raw_z;
        char sensor_data[__MAX_BUF_SENSOR];
        struct maru_geo_data *data = container_of((struct delayed_work *)work,
                        struct maru_geo_data, work);
@@ -70,15 +76,31 @@ static void maru_geo_input_work_func(struct work_struct *work) {
 
        if (enable) {
                mutex_lock(&data->data_mutex);
-               ret = get_sensor_data(sensor_type_tilt, sensor_data);
+               ret = get_sensor_data(sensor_type_mag, sensor_data);
                mutex_unlock(&data->data_mutex);
                if (!ret) {
-                       sscanf(sensor_data, "%d %d %d %d", &geo_x, &geo_y, &geo_z, &hdst);
-                       LOG(1, "geo_set %d, %d, %d, %d", geo_x, geo_y, geo_z, hdst);
-
-                       input_report_rel(data->input_data, REL_RX, geo_x);
-                       input_report_rel(data->input_data, REL_RY, geo_y);
-                       input_report_rel(data->input_data, REL_RZ, geo_z);
+                       sscanf(sensor_data, "%d %d %d", &geo_x, &geo_y, &geo_z);
+                       LOG(1, "geo_set act %d, %d, %d", geo_x, geo_y, geo_z);
+                       raw_x = sensor_convert_data(geo_x);
+                       raw_y = sensor_convert_data(geo_y);
+                       raw_z = sensor_convert_data(geo_z);
+                       LOG(1, "geo_set raw %d, %d, %d, %d", raw_x, raw_y, raw_z, hdst);
+
+                       if (raw_x == 0) {
+                               raw_x = 1;
+                       }
+
+                       if (raw_y == 0) {
+                               raw_y = 1;
+                       }
+
+                       if (raw_z == 0) {
+                               raw_z = 1;
+                       }
+
+                       input_report_rel(data->input_data, REL_RX, raw_x);
+                       input_report_rel(data->input_data, REL_RY, raw_y);
+                       input_report_rel(data->input_data, REL_RZ, raw_z);
                        input_report_rel(data->input_data, REL_HWHEEL, hdst);
                        input_sync(data->input_data);
                }
@@ -250,7 +272,6 @@ static int set_initial_value(struct maru_geo_data *data)
 {
        int delay = 0;
        int ret = 0;
-       int enable = 0;
        char sensor_data [__MAX_BUF_SENSOR];
 
        memset(sensor_data, 0, __MAX_BUF_SENSOR);
@@ -262,15 +283,6 @@ static int set_initial_value(struct maru_geo_data *data)
        }
 
        delay = sensor_atoi(sensor_data);
-
-       ret = get_sensor_data(sensor_type_geo_enable, sensor_data);
-       if (ret) {
-               ERR("failed to get initial enable");
-               return ret;
-       }
-
-       enable = sensor_atoi(sensor_data);
-
        if (delay < 0) {
                ERR("weird value is set initial delay");
                return ret;
@@ -278,10 +290,10 @@ static int set_initial_value(struct maru_geo_data *data)
 
        atomic_set(&data->poll_delay, delay);
 
-       if (enable) {
-               atomic_set(&data->enable, 1);
-               schedule_delayed_work(&data->work, 0);
-       }
+       memset(sensor_data, 0, sizeof(sensor_data));
+       sensor_data[0] = '0';
+       set_sensor_data(sensor_type_geo_enable, sensor_data);
+       atomic_set(&data->enable, 0);
 
        return ret;
 }
index c54268580e194f71b5727a2265f972eb203d70f7..d43258b676fa8dcf91a1f9a6699c81da8a99fb70 100644 (file)
@@ -49,6 +49,10 @@ static struct device *gyro_sensor_device;
 static struct device *l_gyro_sensor_device;
 #endif
 
+static int gyro_adjust_x = 1;
+static int gyro_adjust_y = 1;
+static int gyro_adjust_z = 1;
+
 static void maru_gyro_input_work_func(struct work_struct *work) {
 
        int poll_time = 200000000;
@@ -74,7 +78,22 @@ static void maru_gyro_input_work_func(struct work_struct *work) {
                mutex_unlock(&data->data_mutex);
                if (!ret) {
                        sscanf(sensor_data, "%d,%d,%d", &gyro_x, &gyro_y, &gyro_z);
-                       LOG(1, "gyro_set %d, %d, %d", gyro_x, gyro_y, gyro_z);
+                       LOG(1, "gyro_set act %d, %d, %d", gyro_x, gyro_y, gyro_z);
+
+                       if (gyro_x == 0) {
+                               gyro_x = gyro_adjust_x;
+                               gyro_adjust_x *= -1;
+                       }
+
+                       if (gyro_y == 0) {
+                               gyro_y = gyro_adjust_y;
+                               gyro_adjust_y *= -1;
+                       }
+
+                       if (gyro_z == 0) {
+                               gyro_z = gyro_adjust_z;
+                               gyro_adjust_z *= -1;
+                       }
 
                        input_report_rel(data->input_data, REL_RX, gyro_x);
                        input_report_rel(data->input_data, REL_RY, gyro_y);
@@ -262,10 +281,9 @@ static int set_initial_value(struct maru_gyro_data *data)
 {
        int delay = 0;
        int ret = 0;
-       int enable = 0;
        char sensor_data [__MAX_BUF_SENSOR];
 
-       memset(sensor_data, 0, __MAX_BUF_SENSOR);
+       memset(sensor_data, 0, sizeof(sensor_data));
 
        ret = get_sensor_data(sensor_type_gyro_delay, sensor_data);
        if (ret) {
@@ -274,15 +292,6 @@ static int set_initial_value(struct maru_gyro_data *data)
        }
 
        delay = sensor_atoi(sensor_data);
-
-       ret = get_sensor_data(sensor_type_gyro_enable, sensor_data);
-       if (ret) {
-               ERR("failed to get initial enable");
-               return ret;
-       }
-
-       enable = sensor_atoi(sensor_data);
-
        if (delay < 0) {
                ERR("weird value is set initial delay");
                return ret;
@@ -290,10 +299,11 @@ static int set_initial_value(struct maru_gyro_data *data)
 
        atomic_set(&data->poll_delay, delay);
 
-       if (enable) {
-               atomic_set(&data->enable, 1);
-               schedule_delayed_work(&data->work, 0);
-       }
+       memset(sensor_data, 0, sizeof(sensor_data));
+       sensor_data[0] = '0';
+
+       set_sensor_data(sensor_type_gyro_enable, sensor_data);
+       atomic_set(&data->enable, 0);
 
        return ret;
 }
diff --git a/drivers/maru/sensors/maru_hrm.c b/drivers/maru/sensors/maru_hrm.c
new file mode 100644 (file)
index 0000000..431b4c0
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ * Maru Virtio HRM(HeartBeat Rate Monitor) Sensor Device Driver
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *  Jinhyung Choi <jinhyung2.choi@samsung.com>
+ *  Sangho Park <sangho1206.park@samsung.com>
+ *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include "maru_virtio_sensor.h"
+
+struct maru_hrm_data {
+       struct input_dev *input_data;
+       struct delayed_work work;
+       struct mutex data_mutex;
+
+       struct virtio_sensor* vs;
+
+       atomic_t enable;
+       atomic_t poll_delay;
+};
+
+static struct device *hrm_sensor_device;
+
+static void maru_hrm_input_work_func(struct work_struct *work) {
+
+       int poll_time = 200000000;
+       int enable = 0;
+       int ret = 0;
+       int hrm = 0, rri = 0;
+       char sensor_data[__MAX_BUF_SENSOR];
+       struct maru_hrm_data *data = container_of((struct delayed_work *)work,
+                       struct maru_hrm_data, work);
+
+       LOG(1, "maru_hrm_input_work_func starts");
+
+       memset(sensor_data, 0, __MAX_BUF_SENSOR);
+       poll_time = atomic_read(&data->poll_delay);
+
+       mutex_lock(&data->data_mutex);
+       enable = atomic_read(&data->enable);
+       mutex_unlock(&data->data_mutex);
+
+       if (enable) {
+               mutex_lock(&data->data_mutex);
+               ret = get_sensor_data(sensor_type_hrm, sensor_data);
+               mutex_unlock(&data->data_mutex);
+               if (!ret) {
+                       sscanf(sensor_data, "%d, %d", &hrm, &rri);
+                       LOG(1, "hrm_set %d %d", hrm, rri);
+
+                       input_report_rel(data->input_data, REL_X, hrm + 1);
+                       input_report_rel(data->input_data, REL_Y, rri + 1);
+                       input_report_rel(data->input_data, REL_Z, 1);
+                       input_sync(data->input_data);
+               }
+       }
+
+       mutex_lock(&data->data_mutex);
+       enable = atomic_read(&data->enable);
+       mutex_unlock(&data->data_mutex);
+
+       LOG(1, "enable: %d, poll_time: %d", enable, poll_time);
+       if (enable) {
+               if (poll_time > 0) {
+                       schedule_delayed_work(&data->work, nsecs_to_jiffies(poll_time));
+               } else {
+                       schedule_delayed_work(&data->work, 0);
+               }
+       }
+
+       LOG(1, "maru_hrm_input_work_func ends");
+
+}
+
+static ssize_t maru_name_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%s", MARU_HRM_DEVICE_NAME);
+}
+
+static ssize_t maru_vendor_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%s", MARU_SENSOR_DEVICE_VENDOR);
+}
+
+static ssize_t maru_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       return get_data_for_show(sensor_type_hrm_enable, buf);
+}
+
+static ssize_t maru_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct input_dev *input_data = to_input_dev(dev);
+       struct maru_hrm_data *data = input_get_drvdata(input_data);
+       int value = simple_strtoul(buf, NULL, 10);
+
+       if (value != 0 && value != 1)
+               return count;
+
+       set_sensor_data(sensor_type_hrm_enable, buf);
+
+       if (value) {
+               if (atomic_read(&data->enable) != 1) {
+                       atomic_set(&data->enable, 1);
+                       schedule_delayed_work(&data->work, 0);
+
+               }
+       } else {
+               if (atomic_read(&data->enable) != 0) {
+                       atomic_set(&data->enable, 0);
+                       cancel_delayed_work(&data->work);
+               }
+       }
+
+       return strnlen(buf, __MAX_BUF_SENSOR);
+}
+
+static ssize_t maru_poll_delay_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       return get_data_for_show(sensor_type_hrm_delay, buf);
+}
+
+static ssize_t maru_poll_delay_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct input_dev *input_data = to_input_dev(dev);
+       struct maru_hrm_data *data = input_get_drvdata(input_data);
+       int value = simple_strtoul(buf, NULL, 10);
+
+       set_sensor_data(sensor_type_hrm_delay, buf);
+       atomic_set(&data->poll_delay, value);
+
+       return strnlen(buf, __MAX_BUF_SENSOR);
+}
+
+static struct device_attribute dev_attr_sensor_name =
+               __ATTR(name, S_IRUGO, maru_name_show, NULL);
+
+static struct device_attribute dev_attr_sensor_vendor =
+               __ATTR(vendor, S_IRUGO, maru_vendor_show, NULL);
+
+static struct device_attribute *hrm_sensor_attrs [] = {
+       &dev_attr_sensor_name,
+       &dev_attr_sensor_vendor,
+       NULL,
+};
+
+static struct device_attribute attr_hrm [] =
+{
+       MARU_ATTR_RW(enable),
+       MARU_ATTR_RW(poll_delay),
+};
+
+static struct attribute *maru_hrm_attribute[] = {
+       &attr_hrm[0].attr,
+       &attr_hrm[1].attr,
+       NULL
+};
+
+static struct attribute_group maru_hrm_attribute_group = {
+       .attrs = maru_hrm_attribute
+};
+
+static void hrm_clear(struct maru_hrm_data *data) {
+       if (data == NULL)
+               return;
+
+       if (data->input_data) {
+               sysfs_remove_group(&data->input_data->dev.kobj,
+                       &maru_hrm_attribute_group);
+               input_free_device(data->input_data);
+       }
+
+       kfree(data);
+       data = NULL;
+}
+
+static int set_initial_value(struct maru_hrm_data *data)
+{
+       int delay = 0;
+       int ret = 0;
+       int enable = 0;
+       char sensor_data [__MAX_BUF_SENSOR];
+
+       memset(sensor_data, 0, __MAX_BUF_SENSOR);
+
+       ret = get_sensor_data(sensor_type_hrm_delay, sensor_data);
+       if (ret) {
+               ERR("failed to get initial delay time");
+               return ret;
+       }
+
+       delay = sensor_atoi(sensor_data);
+
+       ret = get_sensor_data(sensor_type_hrm_enable, sensor_data);
+       if (ret) {
+               ERR("failed to get initial enable");
+               return ret;
+       }
+
+       enable = sensor_atoi(sensor_data);
+
+       if (delay < 0) {
+               ERR("weird value is set initial delay");
+               return ret;
+       }
+
+       atomic_set(&data->poll_delay, delay);
+
+       if (enable) {
+               atomic_set(&data->enable, 1);
+               schedule_delayed_work(&data->work, 0);
+       }
+
+       return ret;
+}
+
+static int create_input_device(struct maru_hrm_data *data)
+{
+       int ret = 0;
+       struct input_dev *input_data = NULL;
+
+       input_data = input_allocate_device();
+       if (input_data == NULL) {
+               ERR("failed initialing input handler");
+               hrm_clear(data);
+               return -ENOMEM;
+       }
+
+       input_data->name = SENSOR_HRM_INPUT_NAME;
+       input_data->id.bustype = BUS_I2C;
+
+       set_bit(EV_REL, input_data->evbit);
+       input_set_capability(input_data, EV_REL, REL_X);
+       input_set_capability(input_data, EV_REL, REL_Y);
+       input_set_capability(input_data, EV_REL, REL_Z);
+
+       data->input_data = input_data;
+
+       ret = input_register_device(input_data);
+       if (ret) {
+               ERR("failed to register input data");
+               hrm_clear(data);
+               return ret;
+       }
+
+       input_set_drvdata(input_data, data);
+
+       ret = sysfs_create_group(&input_data->dev.kobj,
+                       &maru_hrm_attribute_group);
+       if (ret) {
+               hrm_clear(data);
+               ERR("failed initialing devices");
+               return ret;
+       }
+
+       return ret;
+}
+
+int maru_hrm_init(struct virtio_sensor *vs) {
+       int ret = 0;
+       struct maru_hrm_data *data = NULL;
+
+       INFO("maru_hrm device init starts.");
+
+       data = kmalloc(sizeof(struct maru_hrm_data), GFP_KERNEL);
+       if (data == NULL) {
+               ERR("failed to create hrm data.");
+               return -ENOMEM;
+       }
+
+       vs->hrm_handle = data;
+       data->vs = vs;
+
+       mutex_init(&data->data_mutex);
+
+       INIT_DELAYED_WORK(&data->work, maru_hrm_input_work_func);
+
+       // create name & vendor
+       ret = register_sensor_device(hrm_sensor_device, vs,
+                       hrm_sensor_attrs, DRIVER_HRM_NAME);
+       if (ret) {
+               ERR("failed to register hrm device");
+               hrm_clear(data);
+               return -1;
+       }
+
+       // create input
+       ret = create_input_device(data);
+       if (ret) {
+               ERR("failed to create input device");
+               return ret;
+       }
+
+       // set initial delay & enable
+       ret = set_initial_value(data);
+       if (ret) {
+               ERR("failed to set initial value");
+               return ret;
+       }
+
+       INFO("maru_hrm device init ends.");
+
+       return ret;
+}
+
+int maru_hrm_exit(struct virtio_sensor *vs) {
+       struct maru_hrm_data *data = NULL;
+
+       data = (struct maru_hrm_data *)vs->hrm_handle;
+       hrm_clear(data);
+       INFO("maru_hrm device exit ends.");
+       return 0;
+}
index ae77bc95eb45434b48f8f7b4f4ef414448b2d676..ecb6f98266ec577a360e72860b6caf9bcaa0a4cc 100644 (file)
@@ -76,11 +76,11 @@ static void maru_light_input_work_func(struct work_struct *work) {
                        sscanf(sensor_data, "%d", &light);
                        LOG(1, "light_set %d", light);
 
-                       input_report_rel(data->input_data, REL_RX, light);      // LUX
-                       input_report_rel(data->input_data, REL_HWHEEL, 0);      // red
-                       input_report_rel(data->input_data, REL_DIAL, 0);        // green
-                       input_report_rel(data->input_data, REL_WHEEL, 0);       // blue
-                       input_report_rel(data->input_data, REL_MISC, 0);        // white
+                       input_report_rel(data->input_data, REL_RX, (light + 1));        // LUX
+                       input_report_rel(data->input_data, REL_HWHEEL, 0);                      // red
+                       input_report_rel(data->input_data, REL_DIAL, 0);                        // green
+                       input_report_rel(data->input_data, REL_WHEEL, 0);                       // blue
+                       input_report_rel(data->input_data, REL_MISC, 0);                        // white
                        input_sync(data->input_data);
                }
        }
diff --git a/drivers/maru/sensors/maru_pressure.c b/drivers/maru/sensors/maru_pressure.c
new file mode 100644 (file)
index 0000000..1b84f57
--- /dev/null
@@ -0,0 +1,361 @@
+/*
+ * Maru Virtio Pressure Sensor Device Driver
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *  Jinhyung Choi <jinhyung2.choi@samsung.com>
+ *  Sangho Park <sangho1206.park@samsung.com>
+ *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include "maru_virtio_sensor.h"
+
+struct maru_pressure_data {
+       struct input_dev *input_data;
+       struct delayed_work work;
+       struct mutex data_mutex;
+
+       struct virtio_sensor* vs;
+
+       atomic_t enable;
+       atomic_t poll_delay;
+};
+
+static struct device *pressure_sensor_device;
+
+#define PRESSURE_ADJUST                193
+static int pressure_convert_data(int number)
+{
+       return number * 10000 / PRESSURE_ADJUST;
+}
+
+#define TEMP_ADJUST            2
+static short temp_convert_data(int number)
+{
+       int temp;
+       temp = number * TEMP_ADJUST;
+       return (short)temp;
+}
+
+static void maru_pressure_input_work_func(struct work_struct *work) {
+
+       int poll_time = 200000000;
+       int enable = 0;
+       int ret = 0;
+       int pressure = 0;
+       int temperature = 0;
+       int raw_pressure;
+       short raw_temp;
+       char sensor_data[__MAX_BUF_SENSOR];
+       struct maru_pressure_data *data = container_of((struct delayed_work *)work,
+                       struct maru_pressure_data, work);
+
+       LOG(1, "maru_pressure_input_work_func starts");
+
+       memset(sensor_data, 0, sizeof(sensor_data));
+       poll_time = atomic_read(&data->poll_delay);
+
+       mutex_lock(&data->data_mutex);
+       enable = atomic_read(&data->enable);
+       mutex_unlock(&data->data_mutex);
+
+       if (enable) {
+               mutex_lock(&data->data_mutex);
+               ret = get_sensor_data(sensor_type_pressure, sensor_data);
+               mutex_unlock(&data->data_mutex);
+               if (!ret) {
+                       sscanf(sensor_data, "%d, %d", &pressure, &temperature);
+                       LOG(1, "pressure_set %d, %d", pressure, temperature);
+
+                       raw_pressure = pressure_convert_data(pressure);
+                       if (temperature == 0) {
+                               temperature = 1;
+                       }
+                       raw_temp = temp_convert_data(temperature);
+
+                       LOG(1, "pressure raw pressure %d, temp %d.\n", raw_pressure, raw_temp);
+
+                       input_report_rel(data->input_data, REL_HWHEEL, raw_pressure);
+                       input_report_rel(data->input_data, REL_DIAL, 101325);
+                       input_report_rel(data->input_data, REL_WHEEL, raw_temp);
+                       input_sync(data->input_data);
+               }
+       }
+
+       mutex_lock(&data->data_mutex);
+       enable = atomic_read(&data->enable);
+       mutex_unlock(&data->data_mutex);
+
+       LOG(1, "enable: %d, poll_time: %d", enable, poll_time);
+       if (enable) {
+               if (poll_time > 0) {
+                       schedule_delayed_work(&data->work, nsecs_to_jiffies(poll_time));
+               } else {
+                       schedule_delayed_work(&data->work, 0);
+               }
+       }
+
+       LOG(1, "maru_pressure_input_work_func ends");
+
+}
+
+static ssize_t maru_name_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%s", MARU_PRESSURE_DEVICE_NAME);
+}
+
+static ssize_t maru_vendor_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%s", MARU_SENSOR_DEVICE_VENDOR);
+}
+
+static ssize_t maru_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       return get_data_for_show(sensor_type_pressure_enable, buf);
+}
+
+static ssize_t maru_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct input_dev *input_data = to_input_dev(dev);
+       struct maru_pressure_data *data = input_get_drvdata(input_data);
+       int value = simple_strtoul(buf, NULL, 10);
+
+       if (value != 0 && value != 1)
+               return count;
+
+       set_sensor_data(sensor_type_pressure_enable, buf);
+
+       if (value) {
+               if (atomic_read(&data->enable) != 1) {
+                       atomic_set(&data->enable, 1);
+                       schedule_delayed_work(&data->work, 0);
+
+               }
+       } else {
+               if (atomic_read(&data->enable) != 0) {
+                       atomic_set(&data->enable, 0);
+                       cancel_delayed_work(&data->work);
+               }
+       }
+
+       return strnlen(buf, __MAX_BUF_SENSOR);
+}
+
+static ssize_t maru_poll_delay_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       return get_data_for_show(sensor_type_pressure_delay, buf);
+}
+
+static ssize_t maru_poll_delay_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct input_dev *input_data = to_input_dev(dev);
+       struct maru_pressure_data *data = input_get_drvdata(input_data);
+       int value = simple_strtoul(buf, NULL, 10);
+
+       set_sensor_data(sensor_type_pressure_delay, buf);
+       atomic_set(&data->poll_delay, value);
+
+       return strnlen(buf, __MAX_BUF_SENSOR);
+}
+
+static struct device_attribute dev_attr_sensor_name =
+               __ATTR(name, S_IRUGO, maru_name_show, NULL);
+
+static struct device_attribute dev_attr_sensor_vendor =
+               __ATTR(vendor, S_IRUGO, maru_vendor_show, NULL);
+
+static struct device_attribute *pressure_sensor_attrs [] = {
+       &dev_attr_sensor_name,
+       &dev_attr_sensor_vendor,
+       NULL,
+};
+
+static struct device_attribute attr_pressure [] =
+{
+       MARU_ATTR_RW(enable),
+       MARU_ATTR_RW(poll_delay),
+};
+
+static struct attribute *maru_pressure_attribute[] = {
+       &attr_pressure[0].attr,
+       &attr_pressure[1].attr,
+       NULL
+};
+
+static struct attribute_group maru_pressure_attribute_group = {
+       .attrs = maru_pressure_attribute
+};
+
+static void pressure_clear(struct maru_pressure_data *data) {
+       if (data == NULL)
+               return;
+
+       if (data->input_data) {
+               sysfs_remove_group(&data->input_data->dev.kobj,
+                       &maru_pressure_attribute_group);
+               input_free_device(data->input_data);
+       }
+
+       kfree(data);
+       data = NULL;
+}
+
+static int set_initial_value(struct maru_pressure_data *data)
+{
+       int delay = 0;
+       int ret = 0;
+       int enable = 0;
+       char sensor_data [__MAX_BUF_SENSOR];
+
+       memset(sensor_data, 0, sizeof(sensor_data));
+
+       ret = get_sensor_data(sensor_type_pressure_delay, sensor_data);
+       if (ret) {
+               ERR("failed to get initial delay time");
+               return ret;
+       }
+
+       delay = sensor_atoi(sensor_data);
+
+       ret = get_sensor_data(sensor_type_pressure_enable, sensor_data);
+       if (ret) {
+               ERR("failed to get initial enable");
+               return ret;
+       }
+
+       enable = sensor_atoi(sensor_data);
+
+       if (delay < 0) {
+               ERR("weird value is set initial delay");
+               return ret;
+       }
+
+       atomic_set(&data->poll_delay, delay);
+
+       if (enable) {
+               atomic_set(&data->enable, 1);
+               schedule_delayed_work(&data->work, 0);
+       }
+
+       return ret;
+}
+
+static int create_input_device(struct maru_pressure_data *data)
+{
+       int ret = 0;
+       struct input_dev *input_data = NULL;
+
+       input_data = input_allocate_device();
+       if (input_data == NULL) {
+               ERR("failed initialing input handler");
+               pressure_clear(data);
+               return -ENOMEM;
+       }
+
+       input_data->name = SENSOR_PRESSURE_INPUT_NAME;
+       input_data->id.bustype = BUS_I2C;
+
+       set_bit(EV_REL, input_data->evbit);
+       input_set_capability(input_data, EV_REL, REL_HWHEEL);
+       input_set_capability(input_data, EV_REL, REL_DIAL);
+       input_set_capability(input_data, EV_REL, REL_WHEEL);
+
+       data->input_data = input_data;
+
+       ret = input_register_device(input_data);
+       if (ret) {
+               ERR("failed to register input data");
+               pressure_clear(data);
+               return ret;
+       }
+
+       input_set_drvdata(input_data, data);
+
+       ret = sysfs_create_group(&input_data->dev.kobj,
+                       &maru_pressure_attribute_group);
+       if (ret) {
+               pressure_clear(data);
+               ERR("failed initialing devices");
+               return ret;
+       }
+
+       return ret;
+}
+
+int maru_pressure_init(struct virtio_sensor *vs) {
+       int ret = 0;
+       struct maru_pressure_data *data = NULL;
+
+       INFO("maru_pressure device init starts.");
+
+       data = kmalloc(sizeof(struct maru_pressure_data), GFP_KERNEL);
+       if (data == NULL) {
+               ERR("failed to create pressure data.");
+               return -ENOMEM;
+       }
+
+       vs->pressure_handle = data;
+       data->vs = vs;
+
+       mutex_init(&data->data_mutex);
+
+       INIT_DELAYED_WORK(&data->work, maru_pressure_input_work_func);
+
+       // create name & vendor
+       ret = register_sensor_device(pressure_sensor_device, vs,
+                       pressure_sensor_attrs, DRIVER_PRESSURE_NAME);
+       if (ret) {
+               ERR("failed to register pressure device");
+               pressure_clear(data);
+               return -1;
+       }
+
+       // create input
+       ret = create_input_device(data);
+       if (ret) {
+               ERR("failed to create input device");
+               return ret;
+       }
+
+       // set initial delay & enable
+       ret = set_initial_value(data);
+       if (ret) {
+               ERR("failed to set initial value");
+               return ret;
+       }
+
+       INFO("maru_pressure device init ends.");
+
+       return ret;
+}
+
+int maru_pressure_exit(struct virtio_sensor *vs) {
+       struct maru_pressure_data *data = NULL;
+
+       data = (struct maru_pressure_data *)vs->pressure_handle;
+       pressure_clear(data);
+       INFO("maru_pressure device exit ends.");
+       return 0;
+}
index 94bbae3d83b08e02153ea4a14a59dfa860a8fc9c..1c9d13d33b195a99c458a7956109dbdb3266eee5 100644 (file)
@@ -74,11 +74,14 @@ static void maru_proxi_input_work_func(struct work_struct *work) {
                mutex_unlock(&data->data_mutex);
                if (!ret) {
                        sscanf(sensor_data, "%d", &proxi);
-                       if (proxi)
+                       if (!proxi)
                                proxi = 1;
+                       else
+                               proxi = 0;
+
                        LOG(1, "proxi_set %d", proxi);
 
-                       input_report_rel(data->input_data, ABS_DISTANCE, proxi);
+                       input_report_abs(data->input_data, ABS_DISTANCE, proxi);
                        input_sync(data->input_data);
                }
        }
@@ -298,10 +301,12 @@ static int create_input_device(struct maru_proxi_data *data)
        }
 
        input_data->name = SENSOR_PROXI_INPUT_NAME;
-       input_data->id.bustype = BUS_I2C;
+
+       input_set_drvdata(input_data, data);
 
        set_bit(EV_ABS, input_data->evbit);
        input_set_capability(input_data, EV_ABS, ABS_DISTANCE);
+       input_set_abs_params(input_data, ABS_DISTANCE, 0, 1, 0, 0);
 
        data->input_data = input_data;
 
@@ -312,8 +317,6 @@ static int create_input_device(struct maru_proxi_data *data)
                return ret;
        }
 
-       input_set_drvdata(input_data, data);
-
        ret = sysfs_create_group(&input_data->dev.kobj,
                        &maru_proxi_attribute_group);
        if (ret) {
diff --git a/drivers/maru/sensors/maru_uv.c b/drivers/maru/sensors/maru_uv.c
new file mode 100644 (file)
index 0000000..2c6037d
--- /dev/null
@@ -0,0 +1,332 @@
+/*
+ * Maru Virtio UltraViolet Sensor Device Driver
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *  Jinhyung Choi <jinhyung2.choi@samsung.com>
+ *  Sangho Park <sangho1206.park@samsung.com>
+ *  YeongKyoon Lee <yeongkyoon.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+
+#include "maru_virtio_sensor.h"
+
+struct maru_uv_data {
+       struct input_dev *input_data;
+       struct delayed_work work;
+       struct mutex data_mutex;
+
+       struct virtio_sensor* vs;
+
+       atomic_t enable;
+       atomic_t poll_delay;
+};
+
+static struct device *uv_sensor_device;
+
+static void maru_uv_input_work_func(struct work_struct *work) {
+
+       int poll_time = 200000000;
+       int enable = 0;
+       int ret = 0;
+       int uv = 0;
+       char sensor_data[__MAX_BUF_SENSOR];
+       struct maru_uv_data *data = container_of((struct delayed_work *)work,
+                       struct maru_uv_data, work);
+
+       LOG(1, "maru_uv_input_work_func starts");
+
+       memset(sensor_data, 0, __MAX_BUF_SENSOR);
+       poll_time = atomic_read(&data->poll_delay);
+
+       mutex_lock(&data->data_mutex);
+       enable = atomic_read(&data->enable);
+       mutex_unlock(&data->data_mutex);
+
+       if (enable) {
+               mutex_lock(&data->data_mutex);
+               ret = get_sensor_data(sensor_type_uv, sensor_data);
+               mutex_unlock(&data->data_mutex);
+               if (!ret) {
+                       sscanf(sensor_data, "%d", &uv);
+                       LOG(1, "uv_set %d", uv);
+
+                       input_report_rel(data->input_data, REL_MISC, (uv + 1));
+                       input_sync(data->input_data);
+               }
+       }
+
+       mutex_lock(&data->data_mutex);
+       enable = atomic_read(&data->enable);
+       mutex_unlock(&data->data_mutex);
+
+       LOG(1, "enable: %d, poll_time: %d", enable, poll_time);
+       if (enable) {
+               if (poll_time > 0) {
+                       schedule_delayed_work(&data->work, nsecs_to_jiffies(poll_time));
+               } else {
+                       schedule_delayed_work(&data->work, 0);
+               }
+       }
+
+       LOG(1, "maru_uv_input_work_func ends");
+
+}
+
+static ssize_t maru_name_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%s", MARU_UV_DEVICE_NAME);
+}
+
+static ssize_t maru_vendor_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%s", MARU_SENSOR_DEVICE_VENDOR);
+}
+
+static ssize_t maru_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       return get_data_for_show(sensor_type_uv_enable, buf);
+}
+
+static ssize_t maru_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct input_dev *input_data = to_input_dev(dev);
+       struct maru_uv_data *data = input_get_drvdata(input_data);
+       int value = simple_strtoul(buf, NULL, 10);
+
+       if (value != 0 && value != 1)
+               return count;
+
+       set_sensor_data(sensor_type_uv_enable, buf);
+
+       if (value) {
+               if (atomic_read(&data->enable) != 1) {
+                       atomic_set(&data->enable, 1);
+                       schedule_delayed_work(&data->work, 0);
+
+               }
+       } else {
+               if (atomic_read(&data->enable) != 0) {
+                       atomic_set(&data->enable, 0);
+                       cancel_delayed_work(&data->work);
+               }
+       }
+
+       return strnlen(buf, __MAX_BUF_SENSOR);
+}
+
+static ssize_t maru_poll_delay_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       return get_data_for_show(sensor_type_uv_delay, buf);
+}
+
+static ssize_t maru_poll_delay_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+       struct input_dev *input_data = to_input_dev(dev);
+       struct maru_uv_data *data = input_get_drvdata(input_data);
+       int value = simple_strtoul(buf, NULL, 10);
+
+       set_sensor_data(sensor_type_uv_delay, buf);
+       atomic_set(&data->poll_delay, value);
+
+       return strnlen(buf, __MAX_BUF_SENSOR);
+}
+
+static struct device_attribute dev_attr_sensor_name =
+               __ATTR(name, S_IRUGO, maru_name_show, NULL);
+
+static struct device_attribute dev_attr_sensor_vendor =
+               __ATTR(vendor, S_IRUGO, maru_vendor_show, NULL);
+
+static struct device_attribute *uv_sensor_attrs [] = {
+       &dev_attr_sensor_name,
+       &dev_attr_sensor_vendor,
+       NULL,
+};
+
+static struct device_attribute attr_uv [] =
+{
+       MARU_ATTR_RW(enable),
+       MARU_ATTR_RW(poll_delay),
+};
+
+static struct attribute *maru_uv_attribute[] = {
+       &attr_uv[0].attr,
+       &attr_uv[1].attr,
+       NULL
+};
+
+static struct attribute_group maru_uv_attribute_group = {
+       .attrs = maru_uv_attribute
+};
+
+static void uv_clear(struct maru_uv_data *data) {
+       if (data == NULL)
+               return;
+
+       if (data->input_data) {
+               sysfs_remove_group(&data->input_data->dev.kobj,
+                       &maru_uv_attribute_group);
+               input_free_device(data->input_data);
+       }
+
+       kfree(data);
+       data = NULL;
+}
+
+static int set_initial_value(struct maru_uv_data *data)
+{
+       int delay = 0;
+       int ret = 0;
+       int enable = 0;
+       char sensor_data [__MAX_BUF_SENSOR];
+
+       memset(sensor_data, 0, __MAX_BUF_SENSOR);
+
+       ret = get_sensor_data(sensor_type_uv_delay, sensor_data);
+       if (ret) {
+               ERR("failed to get initial delay time");
+               return ret;
+       }
+
+       delay = sensor_atoi(sensor_data);
+
+       ret = get_sensor_data(sensor_type_uv_enable, sensor_data);
+       if (ret) {
+               ERR("failed to get initial enable");
+               return ret;
+       }
+
+       enable = sensor_atoi(sensor_data);
+
+       if (delay < 0) {
+               ERR("weird value is set initial delay");
+               return ret;
+       }
+
+       atomic_set(&data->poll_delay, delay);
+
+       if (enable) {
+               atomic_set(&data->enable, 1);
+               schedule_delayed_work(&data->work, 0);
+       }
+
+       return ret;
+}
+
+static int create_input_device(struct maru_uv_data *data)
+{
+       int ret = 0;
+       struct input_dev *input_data = NULL;
+
+       input_data = input_allocate_device();
+       if (input_data == NULL) {
+               ERR("failed initialing input handler");
+               uv_clear(data);
+               return -ENOMEM;
+       }
+
+       input_data->name = SENSOR_UV_INPUT_NAME;
+       input_data->id.bustype = BUS_I2C;
+
+       set_bit(EV_REL, input_data->evbit);
+       input_set_capability(input_data, EV_REL, REL_MISC);
+
+       data->input_data = input_data;
+
+       ret = input_register_device(input_data);
+       if (ret) {
+               ERR("failed to register input data");
+               uv_clear(data);
+               return ret;
+       }
+
+       input_set_drvdata(input_data, data);
+
+       ret = sysfs_create_group(&input_data->dev.kobj,
+                       &maru_uv_attribute_group);
+       if (ret) {
+               uv_clear(data);
+               ERR("failed initialing devices");
+               return ret;
+       }
+
+       return ret;
+}
+
+int maru_uv_init(struct virtio_sensor *vs) {
+       int ret = 0;
+       struct maru_uv_data *data = NULL;
+
+       INFO("maru_uv device init starts.");
+
+       data = kmalloc(sizeof(struct maru_uv_data), GFP_KERNEL);
+       if (data == NULL) {
+               ERR("failed to create uv data.");
+               return -ENOMEM;
+       }
+
+       vs->uv_handle = data;
+       data->vs = vs;
+
+       mutex_init(&data->data_mutex);
+
+       INIT_DELAYED_WORK(&data->work, maru_uv_input_work_func);
+
+       // create name & vendor
+       ret = register_sensor_device(uv_sensor_device, vs,
+                       uv_sensor_attrs, DRIVER_UV_NAME);
+       if (ret) {
+               ERR("failed to register uv device");
+               uv_clear(data);
+               return -1;
+       }
+
+       // create input
+       ret = create_input_device(data);
+       if (ret) {
+               ERR("failed to create input device");
+               return ret;
+       }
+
+       // set initial delay & enable
+       ret = set_initial_value(data);
+       if (ret) {
+               ERR("failed to set initial value");
+               return ret;
+       }
+
+       INFO("maru_uv device init ends.");
+
+       return ret;
+}
+
+int maru_uv_exit(struct virtio_sensor *vs) {
+       struct maru_uv_data *data = NULL;
+
+       data = (struct maru_uv_data *)vs->uv_handle;
+       uv_clear(data);
+       INFO("maru_uv device exit ends.");
+       return 0;
+}
index 63c71dfc6b880d2fbd87e091674126488c394402..d47bf58bd5ee3948d2a070ecdefb72a62697768b 100644 (file)
@@ -316,6 +316,30 @@ static void device_init(struct virtio_sensor *vs)
                        ERR("failed to init haptic with error %d", ret);
                }
        }
+
+       if (vs->sensor_capability & sensor_cap_pressure) {
+               ret = maru_pressure_init(vs);
+               if (ret) {
+                       vs->sensor_fail_init |= sensor_cap_pressure;
+                       ERR("failed to init pressure with error %d", ret);
+               }
+       }
+
+       if (vs->sensor_capability & sensor_cap_uv) {
+               ret = maru_uv_init(vs);
+               if (ret) {
+                       vs->sensor_fail_init |= sensor_cap_uv;
+                       ERR("failed to init uv with error %d", ret);
+               }
+       }
+
+       if (vs->sensor_capability & sensor_cap_hrm) {
+               ret = maru_hrm_init(vs);
+               if (ret) {
+                       vs->sensor_fail_init |= sensor_cap_hrm;
+                       ERR("failed to init hrm with error %d", ret);
+               }
+       }
 }
 
 static void device_exit(struct virtio_sensor *vs)
@@ -354,6 +378,21 @@ static void device_exit(struct virtio_sensor *vs)
                        !(vs->sensor_fail_init & sensor_cap_haptic)) {
                maru_haptic_exit(vs);
        }
+
+       if (vs->sensor_capability & sensor_cap_pressure &&
+                       !(vs->sensor_fail_init & sensor_cap_pressure)) {
+               maru_pressure_exit(vs);
+       }
+
+       if (vs->sensor_capability & sensor_cap_uv &&
+                       !(vs->sensor_fail_init & sensor_cap_uv)) {
+               maru_uv_exit(vs);
+       }
+
+       if (vs->sensor_capability & sensor_cap_hrm &&
+                       !(vs->sensor_fail_init & sensor_cap_hrm)) {
+               maru_hrm_exit(vs);
+       }
 }
 
 static void cleanup(struct virtio_device* dev) {
index 12c75eb42a604949a3457df27105baff303238c4..06533bcba68bbbeb1459f503128675fe472dcb80 100644 (file)
@@ -69,17 +69,31 @@ enum sensor_types {
        sensor_type_rotation_vector_delay,
        sensor_type_mag,
        sensor_type_tilt,
+    sensor_type_pressure,
+    sensor_type_pressure_enable,
+    sensor_type_pressure_delay,
+    sensor_type_uv,
+    sensor_type_uv_enable,
+    sensor_type_uv_delay,
+    sensor_type_hrm,
+    sensor_type_hrm_heart,
+    sensor_type_hrm_rri,
+    sensor_type_hrm_enable,
+    sensor_type_hrm_delay,
        sensor_type_max
 };
 
 enum sensor_capabilities {
-       sensor_cap_accel                        = 0x01,
-       sensor_cap_geo                          = 0x02,
-       sensor_cap_gyro                         = 0x04,
-       sensor_cap_light                        = 0x08,
-       sensor_cap_proxi                        = 0x10,
-       sensor_cap_rotation_vector      = 0x20,
-       sensor_cap_haptic                       = 0x40
+       sensor_cap_accel                        = 0x0001,
+       sensor_cap_geo                          = 0x0002,
+       sensor_cap_gyro                         = 0x0004,
+       sensor_cap_light                        = 0x0008,
+       sensor_cap_proxi                        = 0x0010,
+       sensor_cap_rotation_vector      = 0x0020,
+       sensor_cap_haptic                       = 0x0040,
+       sensor_cap_pressure                     = 0x0080,
+       sensor_cap_uv                           = 0x0100,
+       sensor_cap_hrm                          = 0x0200
 };
 
 #define __MAX_BUF_SIZE                 1024
@@ -122,6 +136,9 @@ struct virtio_sensor {
        void* proxi_handle;
        void* rotation_vector_handle;
        void* haptic_handle;
+       void* pressure_handle;
+       void* uv_handle;
+       void* hrm_handle;
 };
 
 #define MARU_DEVICE_ATTR(_name)        \
@@ -181,6 +198,18 @@ int get_sensor_data(int type, char* data);
 
 #define SENSOR_HAPTIC_INPUT_NAME       "haptic_sensor"
 
+#define DRIVER_PRESSURE_NAME           "pressure"
+#define SENSOR_PRESSURE_INPUT_NAME     "pressure_sensor"
+#define MARU_PRESSURE_DEVICE_NAME      "maru_sensor_pressure_1"
+
+#define DRIVER_UV_NAME                         "ultraviolet"
+#define SENSOR_UV_INPUT_NAME           "uv_sensor"
+#define MARU_UV_DEVICE_NAME                    "maru_sensor_uv_1"
+
+#define DRIVER_HRM_NAME                                "hrm"
+#define SENSOR_HRM_INPUT_NAME          "hrm_lib_sensor"
+#define MARU_HRM_DEVICE_NAME           "maru_sensor_hrm_1"
+
 // It locates /sys/module/maru_virtio_sensor/parameters/sensor_driver_debug
 extern int sensor_driver_debug;
 
@@ -239,4 +268,22 @@ int maru_rotation_vector_exit(struct virtio_sensor *vs);
 int maru_haptic_init(struct virtio_sensor *vs);
 int maru_haptic_exit(struct virtio_sensor *vs);
 
+/*
+ * Pressure device
+ */
+int maru_pressure_init(struct virtio_sensor *vs);
+int maru_pressure_exit(struct virtio_sensor *vs);
+
+/*
+ * UV(UltraViolet) device
+ */
+int maru_uv_init(struct virtio_sensor *vs);
+int maru_uv_exit(struct virtio_sensor *vs);
+
+/*
+ * HRM(Heart Beat Rate) device
+ */
+int maru_hrm_init(struct virtio_sensor *vs);
+int maru_hrm_exit(struct virtio_sensor *vs);
+
 #endif