sensor: add pedometer sensor device driver
authorSooyoung Ha <yoosah.ha@samsung.com>
Wed, 20 Jul 2016 06:13:03 +0000 (15:13 +0900)
committerJinhyung Choi <jinh0.choi@samsung.com>
Thu, 1 Dec 2016 09:04:50 +0000 (18:04 +0900)
Change-Id: I284ce56f2f8ea9aa8909e6a3c1be044518f115b9
Signed-off-by: Sooyoung Ha <yoosah.ha@samsung.com>
(cherry picked from commit 66ee7c4ee8cdc7afcb629ea3840eafddf5091a33)

drivers/maru/sensors/Makefile
drivers/maru/sensors/maru_pedo.c [new file with mode: 0644]
drivers/maru/sensors/maru_virtio_sensor.c
drivers/maru/sensors/maru_virtio_sensor.h

index de588ff..2f5cabe 100644 (file)
@@ -1,12 +1,13 @@
 ccflags-y += -Werror
 obj-$(CONFIG_MARU_VIRTIO_SENSOR) += maru_virtio_sensor.o       \
-                                                                       maru_accel.o                    \
-                                                                       maru_geo.o                              \
-                                                                       maru_gyro.o                             \
-                                                                       maru_light.o                    \
-                                                                       maru_proxi.o                    \
-                                                                       maru_rotation_vector.o  \
-                                                                       maru_haptic.o                   \
-                                                                       maru_pressure.o                 \
-                                                                       maru_uv.o                               \
-                                                                       maru_hrm.o
+                                       maru_accel.o            \
+                                       maru_geo.o              \
+                                       maru_gyro.o             \
+                                       maru_light.o            \
+                                       maru_proxi.o            \
+                                       maru_rotation_vector.o  \
+                                       maru_haptic.o           \
+                                       maru_pressure.o         \
+                                       maru_uv.o               \
+                                       maru_hrm.o              \
+                                       maru_pedo.o
diff --git a/drivers/maru/sensors/maru_pedo.c b/drivers/maru/sensors/maru_pedo.c
new file mode 100644 (file)
index 0000000..ec5efcf
--- /dev/null
@@ -0,0 +1,499 @@
+/*
+ * Maru Virtio Pedometer Sensor Device Driver
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ *  Sooyoung Ha <yoosah.ha@samsung.com>
+ *  Jinhyung Choi <jinh0.choi@samsung.com>
+ *  SeokYeon Hwang <syeon.hwang@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 <linux/cdev.h>
+#include <linux/uaccess.h>
+
+#include "maru_virtio_sensor.h"
+
+struct maru_pedo_data {
+       struct input_dev *input_data;
+       struct delayed_work work;
+
+       struct virtio_sensor *vs;
+
+       atomic_t pedo;
+       atomic_t enable;
+       atomic_t poll_delay;
+};
+
+static struct class *pedo_class;
+dev_t pedo_devno;
+int pedo_major = 0;
+struct maru_pedo_data *gdata = NULL;
+
+#define PEDO_MSG_LENGTH 18
+#define PEDO_CMD_LENGTH 5
+#define SHUB_LIB_PEDOMETER 3
+#define SHUB_INST_LIB_ADD ((char)-79)
+#define SHUB_INST_LIB_REMOVE ((char)-78)
+
+static char STOP_MSG[] = { 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static char WALK_SLOW_MSG[] = { 1, 1, 3, 1, 0, 0, 0, 1, 0, 56, 30, 3, 3, 15, 0, 0, 0, 0};
+static char WALK_MSG[] = { 1, 1, 3, 1, 0, 0, 0, 1, 0, 80, 60, 3, 3, 20, 0, 0, 0, 0};
+static char RUN_SLOW_MSG[] = { 1, 1, 3, 0, 1, 0, 0, 1, 0, 110, 120, 4, 8, 30, 0, 0, 0, 0};
+static char RUN_MSG[] = { 1, 1, 3, 0, 1, 0, 0, 1, 0, 120, 0xA0, 4, 8, 37, 0, 0, 0, 0};
+
+static char PEDO_ENABLE_CMD[] = {SHUB_INST_LIB_ADD, SHUB_LIB_PEDOMETER, 0, 0, 0};
+static char PEDO_DISABLE_CMD[] = {SHUB_INST_LIB_REMOVE, SHUB_LIB_PEDOMETER, 0, 0};
+
+static void maru_pedo_input_work_func(struct work_struct *work)
+{
+       int pedo = 0;
+       int poll_time = 0;
+       int enable = -1;
+       int ret = 0;
+       char sensor_data[__MAX_BUF_SENSOR];
+       struct maru_pedo_data *data = container_of((struct delayed_work *)work,
+                       struct maru_pedo_data, work);
+
+       LOG(1, "maru_pedo_input_work_func starts");
+
+       memset(sensor_data, 0, __MAX_BUF_SENSOR);
+
+       poll_time = atomic_read(&data->poll_delay);
+       enable = atomic_read(&data->enable);
+
+       if (enable) {
+               mutex_lock(&data->vs->vqlock);
+               ret = get_sensor_data(sensor_type_pedo, sensor_data);
+               mutex_unlock(&data->vs->vqlock);
+               if (!ret) {
+                       sscanf(sensor_data, "%d", &pedo);
+                       atomic_set(&data->pedo, pedo);
+                       LOG(1, "pedo_set %d", pedo);
+
+                       input_report_rel(data->input_data, REL_RX, 3);
+                       input_sync(data->input_data);
+               }
+       }
+
+       enable = atomic_read(&data->enable);
+
+       if (enable) {
+               if (poll_time > 0) {
+                       schedule_delayed_work(&data->work, nsecs_to_jiffies(poll_time));
+               } else {
+                       schedule_delayed_work(&data->work, 0);
+               }
+       }
+}
+
+static ssize_t maru_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       char sensor_data[__MAX_BUF_SENSOR];
+       int ret;
+       struct input_dev *input_data = to_input_dev(dev);
+       struct maru_pedo_data *data = input_get_drvdata(input_data);
+
+       memset(sensor_data, 0, __MAX_BUF_SENSOR);
+       mutex_lock(&data->vs->vqlock);
+       ret = get_sensor_data(sensor_type_pedo_enable, sensor_data);
+       mutex_unlock(&data->vs->vqlock);
+       if (ret)
+               return sprintf(buf, "%d", -1);
+
+       return sprintf(buf, "%s", sensor_data);
+}
+
+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_pedo_data *data = input_get_drvdata(input_data);
+       int value = simple_strtoul(buf, NULL, 10);
+
+       if (value != 0 && value != 1)
+               return count;
+
+       mutex_lock(&data->vs->vqlock);
+       set_sensor_data(sensor_type_pedo_enable, buf);
+       mutex_unlock(&data->vs->vqlock);
+
+       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)
+{
+       char sensor_data[__MAX_BUF_SENSOR];
+       int ret;
+       struct input_dev *input_data = to_input_dev(dev);
+       struct maru_pedo_data *data = input_get_drvdata(input_data);
+
+       memset(sensor_data, 0, __MAX_BUF_SENSOR);
+       mutex_lock(&data->vs->vqlock);
+       ret = get_sensor_data(sensor_type_pedo_delay, sensor_data);
+       mutex_unlock(&data->vs->vqlock);
+       if (ret)
+               return sprintf(buf, "%d", -1);
+
+       return sprintf(buf, "%s", sensor_data);
+}
+
+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_pedo_data *data = input_get_drvdata(input_data);
+       int value = simple_strtoul(buf, NULL, 10);
+
+       if (value < __MIN_DELAY_SENSOR)
+               return count;
+
+       mutex_lock(&data->vs->vqlock);
+       set_sensor_data(sensor_type_pedo_delay, buf);
+       mutex_unlock(&data->vs->vqlock);
+       atomic_set(&data->poll_delay, value);
+
+       return strnlen(buf, __MAX_BUF_SENSOR);
+}
+
+static struct device_attribute attr_pedo[] = {
+       MARU_ATTR_RW(enable),
+       MARU_ATTR_RW(poll_delay),
+};
+
+static struct attribute *maru_pedo_attribute[] = {
+       &attr_pedo[0].attr,
+       &attr_pedo[1].attr,
+       NULL
+};
+
+static struct attribute_group maru_pedo_attribute_group = {
+       .attrs = maru_pedo_attribute
+};
+
+static void pedo_clear(struct maru_pedo_data *data)
+{
+       if (data == NULL)
+               return;
+
+       if (data->input_data) {
+               sysfs_remove_group(&data->input_data->dev.kobj,
+                       &maru_pedo_attribute_group);
+               input_free_device(data->input_data);
+       }
+
+       kfree(data);
+       data = NULL;
+}
+
+static int set_initial_value(struct maru_pedo_data *data)
+{
+       int delay = 0;
+       int ret = 0;
+       int enable = 0;
+       char sensor_data[__MAX_BUF_SENSOR];
+
+       memset(sensor_data, 0, __MAX_BUF_SENSOR);
+
+       mutex_lock(&data->vs->vqlock);
+       ret = get_sensor_data(sensor_type_pedo_delay, sensor_data);
+       mutex_unlock(&data->vs->vqlock);
+       if (ret) {
+               ERR("failed to get initial delay time");
+               return ret;
+       }
+
+       delay = sensor_atoi(sensor_data);
+
+       mutex_lock(&data->vs->vqlock);
+       ret = get_sensor_data(sensor_type_pedo_enable, sensor_data);
+       mutex_unlock(&data->vs->vqlock);
+       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_pedo_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");
+               pedo_clear(data);
+               return -ENOMEM;
+       }
+
+       input_data->name = SENSOR_PEDO_INPUT_NAME;
+       input_data->id.bustype = BUS_I2C;
+
+       set_bit(EV_REL, input_data->evbit);
+       set_bit(EV_SYN, input_data->evbit);
+       input_set_capability(input_data, EV_REL, REL_RX);
+
+       data->input_data = input_data;
+
+       ret = input_register_device(input_data);
+       if (ret) {
+               ERR("failed to register input data");
+               pedo_clear(data);
+               return ret;
+       }
+
+       input_set_drvdata(input_data, data);
+
+       ret = sysfs_create_group(&input_data->dev.kobj,
+                       &maru_pedo_attribute_group);
+       if (ret) {
+               pedo_clear(data);
+               ERR("failed initialing devices");
+               return ret;
+       }
+
+       return ret;
+}
+
+static int pedo_open(struct inode *inode, struct file *filp)
+{
+       filp->private_data = inode->i_cdev;
+       LOG(1, "pedometer is opened");
+       return 0;
+}
+
+static int pedo_close(struct inode *inode, struct file *filp)
+{
+       LOG(1, "pedometer is closed");
+       return 0;
+}
+
+static ssize_t pedo_read(struct file *filp, char __user *ubuf, size_t len,
+               loff_t *f_pos)
+{
+       unsigned long ret = 0;
+       int pedo = 0;
+       LOG(1, "try to read pedometer node");
+
+       pedo = atomic_read(&gdata->pedo);
+       LOG(1, "selected pedometer state is %d", pedo);
+
+       switch (pedo) {
+       case 1:
+               ret = copy_to_user(ubuf, STOP_MSG, PEDO_MSG_LENGTH);
+               break;
+       case 2:
+               ret = copy_to_user(ubuf, WALK_SLOW_MSG, PEDO_MSG_LENGTH);
+               break;
+       case 3:
+               ret = copy_to_user(ubuf, WALK_MSG, PEDO_MSG_LENGTH);
+               break;
+       case 4:
+               ret = copy_to_user(ubuf, RUN_SLOW_MSG, PEDO_MSG_LENGTH);
+               break;
+       case 5:
+               ret = copy_to_user(ubuf, RUN_MSG, PEDO_MSG_LENGTH);
+               break;
+       default:
+               ERR("invalid case pedometer state %d!!", pedo);
+               return -EFAULT;
+       }
+       if (ret) {
+               ERR("pedometer copy_to_user failed, errno: %lu", ret);
+               return -EFAULT;
+       } else {
+               LOG(1, "pedometer copy_to_user success.");
+               return PEDO_MSG_LENGTH;
+       }
+}
+
+static ssize_t pedo_write(struct file *filp, const char __user *ubuf, size_t len,
+               loff_t *f_pos)
+{
+       unsigned long ret = 0;
+       char cmd[PEDO_CMD_LENGTH] = {'\0', };
+       char buf[2] = {'\0', };
+       int value = -1;
+
+       LOG(1, "try to write pedometer node %zi", len);
+
+       ret = copy_from_user(cmd, ubuf, len);
+       if (ret) {
+               ERR("pedometer copy_to_user failed, errno: %lu", ret);
+               return -EFAULT;
+       }
+
+       if (!memcmp(cmd, PEDO_ENABLE_CMD, 2)) {
+               LOG(1, "enable pedometer");
+               value = 1;
+       } else if (!memcmp(cmd, PEDO_DISABLE_CMD, 2)) {
+               LOG(1, "disable pedometer");
+               value = 0;
+       } else {
+               ERR("invalid command %s", cmd);
+               return -EFAULT;
+       }
+       sprintf(buf, "%d", value);
+       mutex_lock(&gdata->vs->vqlock);
+       set_sensor_data(sensor_type_pedo_enable, buf);
+       mutex_unlock(&gdata->vs->vqlock);
+
+       if (value) {
+               if (atomic_read(&gdata->enable) != 1) {
+                       atomic_set(&gdata->enable, 1);
+                       schedule_delayed_work(&gdata->work, 0);
+
+               }
+       } else {
+               if (atomic_read(&gdata->enable) != 0) {
+                       atomic_set(&gdata->enable, 0);
+                       cancel_delayed_work(&gdata->work);
+               }
+       }
+       return 1;
+}
+
+struct file_operations pedo_fops = {
+       .owner =        THIS_MODULE,
+       .read =         pedo_read,
+       .write =        pedo_write,
+       .open =         pedo_open,
+       .release =      pedo_close,
+};
+
+static char *pedo_devnode(struct device *dev, umode_t *mode)
+{
+       return kasprintf(GFP_KERNEL, "%s", dev_name(dev));
+}
+
+int maru_pedo_init(struct virtio_sensor *vs)
+{
+       int ret = 0;
+       int err = 0;
+       dev_t dev = 0;
+       struct cdev *cdev = NULL;
+
+       INFO("maru_pedo device init starts.");
+
+       cdev = kzalloc(sizeof(struct cdev), GFP_KERNEL);
+       if (cdev == NULL) {
+               ERR("failed to create pedo cdev.");
+               return -ENOMEM;
+       }
+
+       gdata = kzalloc(sizeof(struct maru_pedo_data), GFP_KERNEL);
+       if (gdata == NULL) {
+               ERR("failed to create pedo data.");
+               return -ENOMEM;
+       }
+
+       vs->pedo_handle = gdata;
+       gdata->vs = vs;
+
+       INIT_DELAYED_WORK(&gdata->work, maru_pedo_input_work_func);
+       ret = alloc_chrdev_region(&dev, 0, 1, DRIVER_PEDO_NAME);
+       if (ret < 0) {
+               ERR("Unable to get pedo region, error %d", ret);
+               return -1;
+       }
+
+       pedo_major = MAJOR(dev);
+       LOG(1, "pedo device major num = %d\n", pedo_major);
+       pedo_devno = dev;
+
+       pedo_class = class_create(THIS_MODULE, DRIVER_PEDO_NAME);
+
+       if (IS_ERR(pedo_class)) {
+               ERR("Unable to create pedo_class, error %d", ret);
+               unregister_chrdev_region(dev, 1);
+               return PTR_ERR(pedo_class);
+       }
+       pedo_class->devnode = pedo_devnode;
+
+       cdev_init(cdev, &pedo_fops);
+       cdev->owner = THIS_MODULE;
+       err = cdev_add(cdev, MKDEV(pedo_major, 0), 1);
+       if (err) {
+               ERR("unable to add cdev with error %d for pedo device\n", err);
+       }
+
+       if (IS_ERR(device_create(pedo_class, NULL, MKDEV(pedo_major, 0), NULL,
+               kasprintf(GFP_KERNEL, "%s", DRIVER_PEDO_NAME)))) {
+               ERR("failed to create pedo device");
+               pedo_clear(gdata);
+               return -1;
+       }
+
+       ret = create_input_device(gdata);
+       if (ret) {
+               ERR("failed to create input device");
+               return ret;
+       }
+
+       ret = set_initial_value(gdata);
+       if (ret) {
+               ERR("failed to set initial value");
+               return ret;
+       }
+
+       INFO("maru_pedo device init ends.");
+
+       return ret;
+}
+
+int maru_pedo_exit(struct virtio_sensor *vs)
+{
+       struct maru_pedo_data *data = NULL;
+
+       data = (struct maru_pedo_data *)vs->pedo_handle;
+       pedo_clear(data);
+       INFO("maru_pedo device exit ends.");
+       return 0;
+}
index 3b7b060..33d6157 100644 (file)
@@ -342,6 +342,14 @@ static void device_init(struct virtio_sensor *vs)
                        ERR("failed to init hrm with error %d", ret);
                }
        }
+
+       if (vs->sensor_capability & sensor_cap_pedo) {
+               ret = maru_pedo_init(vs);
+               if (ret) {
+                       vs->sensor_fail_init |= sensor_cap_pedo;
+                       ERR("failed to init pedo with error %d", ret);
+               }
+       }
 }
 
 static void device_exit(struct virtio_sensor *vs)
@@ -395,6 +403,11 @@ static void device_exit(struct virtio_sensor *vs)
                        !(vs->sensor_fail_init & sensor_cap_hrm)) {
                maru_hrm_exit(vs);
        }
+
+       if (vs->sensor_capability & sensor_cap_pedo &&
+                       !(vs->sensor_fail_init & sensor_cap_pedo)) {
+               maru_pedo_exit(vs);
+       }
 }
 
 static void cleanup(struct virtio_device* dev) {
index 580b6e0..1a44b75 100644 (file)
@@ -44,43 +44,46 @@ enum request_cmd {
 };
 
 enum sensor_types {
-    sensor_type_list = 0,
-    sensor_type_accel,
-    sensor_type_accel_enable,
-    sensor_type_accel_delay,
+       sensor_type_list = 0,
+       sensor_type_accel,
+       sensor_type_accel_enable,
+       sensor_type_accel_delay,
        sensor_type_geo,
-    sensor_type_geo_enable,                            // 5
-    sensor_type_geo_delay,
+       sensor_type_geo_enable,                 // 5
+       sensor_type_geo_delay,
        sensor_type_gyro,
-    sensor_type_gyro_enable,
-    sensor_type_gyro_delay,
-       sensor_type_gyro_x,                                     // 10
+       sensor_type_gyro_enable,
+       sensor_type_gyro_delay,
+       sensor_type_gyro_x,                     // 10
        sensor_type_gyro_y,
        sensor_type_gyro_z,
        sensor_type_light,
        sensor_type_light_enable,
-       sensor_type_light_delay,                        // 15
+       sensor_type_light_delay,                // 15
        sensor_type_light_adc,
        sensor_type_light_level,
        sensor_type_proxi,
        sensor_type_proxi_enable,
-       sensor_type_proxi_delay,                        // 20
+       sensor_type_proxi_delay,                // 20
        sensor_type_rotation_vector,
        sensor_type_rotation_vector_enable,
        sensor_type_rotation_vector_delay,
        sensor_type_mag,
-       sensor_type_tilt,                                       // 25
-    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_tilt,                       // 25
+       sensor_type_pressure,
+       sensor_type_pressure_enable,
+       sensor_type_pressure_delay,
+       sensor_type_uv,
+       sensor_type_uv_enable,                  // 30
+       sensor_type_uv_delay,
+       sensor_type_hrm,
+       sensor_type_hrm_heart,
+       sensor_type_hrm_rri,
+       sensor_type_hrm_enable,                 // 35
+       sensor_type_hrm_delay,
+       sensor_type_pedo,
+       sensor_type_pedo_enable,
+       sensor_type_pedo_delay,
        sensor_type_max
 };
 
@@ -90,11 +93,12 @@ enum sensor_capabilities {
        sensor_cap_gyro                         = 0x0004,
        sensor_cap_light                        = 0x0008,
        sensor_cap_proxi                        = 0x0010,
-       sensor_cap_rotation_vector      = 0x0020,
+       sensor_cap_rotation_vector              = 0x0020,
        sensor_cap_haptic                       = 0x0040,
        sensor_cap_pressure                     = 0x0080,
        sensor_cap_uv                           = 0x0100,
-       sensor_cap_hrm                          = 0x0200
+       sensor_cap_hrm                          = 0x0200,
+       sensor_cap_pedo                         = 0x0400
 };
 
 #define __MAX_BUF_SIZE                 1024
@@ -145,6 +149,7 @@ struct virtio_sensor {
        void* pressure_handle;
        void* uv_handle;
        void* hrm_handle;
+       void* pedo_handle;
 };
 
 #define MARU_DEVICE_ATTR(_name)        \
@@ -152,13 +157,13 @@ struct virtio_sensor {
 
 #define MARU_ATTR_RONLY(_name) { \
        .attr   = { .name = __stringify(_name), .mode = 0444 }, \
-       .show   = maru_##_name##_show,                                  \
+       .show   = maru_##_name##_show,                          \
 }
 
 #define MARU_ATTR_RW(_name) { \
        .attr = {.name = __stringify(_name), .mode = 0644 },    \
-       .show   = maru_##_name##_show,                                  \
-       .store  = maru_##_name##_store,                                 \
+       .show   = maru_##_name##_show,                          \
+       .store  = maru_##_name##_store,                         \
 }
 
 int sensor_atoi(const char *value);
@@ -174,26 +179,26 @@ int l_register_sensor_device(struct device *dev, struct virtio_sensor *vs,
 void set_sensor_data(int type, const char* buf);
 int get_sensor_data(int type, char* data);
 
-#define SENSOR_CLASS_NAME                      "sensors"
+#define SENSOR_CLASS_NAME              "sensors"
 #define MARU_SENSOR_DEVICE_VENDOR      "Tizen_SDK"
 
-#define DRIVER_ACCEL_NAME                      "accel"
+#define DRIVER_ACCEL_NAME              "accel"
 #define SENSOR_ACCEL_INPUT_NAME                "accelerometer_sensor"
 #define MARU_ACCEL_DEVICE_NAME         "maru_sensor_accel_1"
 
-#define DRIVER_GEO_NAME                                "geo"
+#define DRIVER_GEO_NAME                        "geo"
 #define SENSOR_GEO_INPUT_NAME          "geomagnetic_sensor"
 #define MARU_GEO_DEVICE_NAME           "maru_sensor_geo_1"
 
-#define DRIVER_GYRO_NAME                       "gyro"
+#define DRIVER_GYRO_NAME               "gyro"
 #define SENSOR_GYRO_INPUT_NAME         "gyro_sensor"
 #define MARU_GYRO_DEVICE_NAME          "maru_sensor_gyro_1"
 
-#define DRIVER_LIGHT_NAME                      "light"
+#define DRIVER_LIGHT_NAME              "light"
 #define SENSOR_LIGHT_INPUT_NAME                "light_sensor"
 #define MARU_LIGHT_DEVICE_NAME         "maru_sensor_light_1"
 
-#define DRIVER_PROXI_NAME                      "proxi"
+#define DRIVER_PROXI_NAME              "proxi"
 #define SENSOR_PROXI_INPUT_NAME                "proximity_sensor"
 #define MARU_PROXI_DEVICE_NAME         "maru_sensor_proxi_1"
 
@@ -207,14 +212,18 @@ int get_sensor_data(int type, char* data);
 #define SENSOR_PRESSURE_INPUT_NAME     "pressure_sensor"
 #define MARU_PRESSURE_DEVICE_NAME      "maru_sensor_pressure_1"
 
-#define DRIVER_UV_NAME                         "ultraviolet"
+#define DRIVER_UV_NAME                 "ultraviolet"
 #define SENSOR_UV_INPUT_NAME           "uv_sensor"
-#define MARU_UV_DEVICE_NAME                    "maru_sensor_uv_1"
+#define MARU_UV_DEVICE_NAME            "maru_sensor_uv_1"
 
-#define DRIVER_HRM_NAME                                "hrm"
+#define DRIVER_HRM_NAME                        "hrm"
 #define SENSOR_HRM_INPUT_NAME          "hrm_lib_sensor"
 #define MARU_HRM_DEVICE_NAME           "maru_sensor_hrm_1"
 
+#define DRIVER_PEDO_NAME               "ssp_sensorhub"
+#define SENSOR_PEDO_INPUT_NAME         "ssp_context"
+#define MARU_PEDO_DEVICE_NAME          "maru_sensor_pedo_1"
+
 // It locates /sys/module/maru_virtio_sensor/parameters/sensor_driver_debug
 extern int sensor_driver_debug;
 
@@ -291,4 +300,10 @@ int maru_uv_exit(struct virtio_sensor *vs);
 int maru_hrm_init(struct virtio_sensor *vs);
 int maru_hrm_exit(struct virtio_sensor *vs);
 
+/*
+ * Pedometer device
+ */
+int maru_pedo_init(struct virtio_sensor *vs);
+int maru_pedo_exit(struct virtio_sensor *vs);
+
 #endif