From: Sooyoung Ha Date: Wed, 20 Jul 2016 06:13:03 +0000 (+0900) Subject: sensor: add pedometer sensor device driver X-Git-Tag: Tizen_Studio_1.3_Release_p3.0~3^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d594f86f2c6ac417fdaf733ac9a014f25a0a6af1;p=sdk%2Femulator%2Femulator-kernel.git sensor: add pedometer sensor device driver Change-Id: I284ce56f2f8ea9aa8909e6a3c1be044518f115b9 Signed-off-by: Sooyoung Ha (cherry picked from commit 66ee7c4ee8cdc7afcb629ea3840eafddf5091a33) --- diff --git a/drivers/maru/sensors/Makefile b/drivers/maru/sensors/Makefile index de588ff..2f5cabe 100644 --- a/drivers/maru/sensors/Makefile +++ b/drivers/maru/sensors/Makefile @@ -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 index 0000000..ec5efcf --- /dev/null +++ b/drivers/maru/sensors/maru_pedo.c @@ -0,0 +1,499 @@ +/* + * Maru Virtio Pedometer Sensor Device Driver + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: + * Sooyoung Ha + * Jinhyung Choi + * SeokYeon Hwang + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributors: + * - S-Core Co., Ltd + * + */ + +#include +#include +#include +#include + +#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; +} diff --git a/drivers/maru/sensors/maru_virtio_sensor.c b/drivers/maru/sensors/maru_virtio_sensor.c index 3b7b060..33d6157 100644 --- a/drivers/maru/sensors/maru_virtio_sensor.c +++ b/drivers/maru/sensors/maru_virtio_sensor.c @@ -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) { diff --git a/drivers/maru/sensors/maru_virtio_sensor.h b/drivers/maru/sensors/maru_virtio_sensor.h index 580b6e0..1a44b75 100644 --- a/drivers/maru/sensors/maru_virtio_sensor.h +++ b/drivers/maru/sensors/maru_virtio_sensor.h @@ -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