sensor: haptic device is added. 15/23215/1
authorJinhyung Choi <jinhyung2.choi@samsung.com>
Wed, 18 Jun 2014 08:05:19 +0000 (17:05 +0900)
committerJinhyung Choi <jinhyung2.choi@samsung.com>
Fri, 20 Jun 2014 05:21:22 +0000 (14:21 +0900)
Change-Id: Ib91965250546c302afab31969a8ff3ccc3fab4c6
Signed-off-by: Jinhyung Choi <jinhyung2.choi@samsung.com>
drivers/maru/sensors/Makefile
drivers/maru/sensors/maru_haptic.c [new file with mode: 0644]
drivers/maru/sensors/maru_virtio_sensor.c
drivers/maru/sensors/maru_virtio_sensor.h

index 57259aa78063a2cdf0c360433d12b47f4d2ac6d4..ce63afa5a5bd94118c0a86c4a10d7ba2b968008f 100644 (file)
@@ -3,4 +3,5 @@ obj-$(CONFIG_MARU_VIRTIO_SENSOR) += maru_virtio_sensor.o        \
                                                                        maru_geo.o                              \
                                                                        maru_gyro.o                             \
                                                                        maru_light.o                    \
-                                                                       maru_proxi.o
+                                                                       maru_proxi.o                    \
+                                                                       maru_haptic.o
diff --git a/drivers/maru/sensors/maru_haptic.c b/drivers/maru/sensors/maru_haptic.c
new file mode 100644 (file)
index 0000000..d10338e
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Maru Virtio Haptic 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_haptic_data {
+       struct input_dev *input_data;
+
+       struct virtio_sensor* vs;
+};
+
+static void haptic_clear(struct maru_haptic_data *data) {
+       if (data == NULL)
+               return;
+
+       if (data->input_data) {
+               input_ff_destroy(data->input_data);
+               input_free_device(data->input_data);
+       }
+
+       kfree(data);
+       data = NULL;
+}
+
+static int maru_upload_effect(struct input_dev *dev, struct ff_effect *effect, struct ff_effect *old)
+{
+       LOG(KERN_INFO, "called maru_upload_effect. No work to do.");
+       return 0;
+}
+
+static int maru_erase_effect(struct input_dev *dev, int effect_id)
+{
+       LOG(KERN_INFO, "called maru_erase_effect. No work to do.");
+       return 0;
+}
+
+static void maru_set_gain(struct input_dev *dev, u16 gain)
+{
+}
+
+static void maru_set_autocenter(struct input_dev *dev, u16 magnitude)
+{
+}
+
+static int maru_playback(struct input_dev *dev, int effect_id, int value)
+{
+       LOG(KERN_INFO, "called maru_playback. No work to do.");
+       return 0;
+}
+
+static int create_input_device(struct maru_haptic_data *data)
+{
+       int ret = 0;
+       struct ff_device *ff;
+       struct input_dev *input_data = NULL;
+
+       input_data = input_allocate_device();
+       if (input_data == NULL) {
+               LOG(KERN_ERR, "failed initialing input handler");
+               haptic_clear(data);
+               return -ENOMEM;
+       }
+
+       input_data->name = SENSOR_HAPTIC_INPUT_NAME;
+       input_data->id.bustype = BUS_I2C;
+
+       set_bit(EV_FF, input_data->evbit);
+       input_set_capability(input_data, EV_FF, FF_PERIODIC);
+
+       data->input_data = input_data;
+
+       input_set_drvdata(input_data, data);
+
+       ret = input_ff_create(input_data, 16);
+       if (ret)
+               return ret;
+
+       set_bit(FF_SQUARE, input_data->ffbit);
+       ff = input_data->ff;
+       ff->upload = maru_upload_effect;
+       ff->erase = maru_erase_effect;
+       ff->set_gain = maru_set_gain;
+       ff->set_autocenter = maru_set_autocenter;
+       ff->playback = maru_playback;
+
+       ret = input_register_device(input_data);
+       if (ret) {
+               LOG(KERN_ERR, "failed to register input data");
+               haptic_clear(data);
+               return ret;
+       }
+
+
+       return ret;
+}
+
+int maru_haptic_init(struct virtio_sensor *vs) {
+       int ret = 0;
+       struct maru_haptic_data *data = NULL;
+
+       LOG(KERN_INFO, "maru_haptic device init starts.");
+
+       data = kmalloc(sizeof(struct maru_haptic_data), GFP_KERNEL);
+       if (data == NULL) {
+               LOG(KERN_ERR, "failed to create haptic data.");
+               return -ENOMEM;
+       }
+
+       data->vs = vs;
+       vs->haptic_handle = data;
+
+       // create input
+       ret = create_input_device(data);
+       if (ret) {
+               LOG(KERN_ERR, "failed to create input device");
+               return ret;
+       }
+
+       LOG(KERN_INFO, "maru_haptic device init ends.");
+
+       return ret;
+}
+
+int maru_haptic_exit(struct virtio_sensor *vs) {
+       struct maru_haptic_data *data = NULL;
+
+       data = (struct maru_haptic_data *)vs->haptic_handle;
+       haptic_clear(data);
+
+       return 0;
+}
index c17de0ac5851c6ec9a3a67b8ac1800e5e9487b13..3d8ee025beb3d304d901b8d401d29ac087c852c1 100644 (file)
@@ -287,6 +287,12 @@ static int device_init(struct virtio_sensor *vs)
                        return ret;
        }
 
+       if (vs->sensor_capability & sensor_cap_haptic) {
+               ret = maru_haptic_init(vs);
+               if (ret)
+                       return ret;
+       }
+
        return ret;
 }
 
@@ -311,6 +317,10 @@ static void device_exit(struct virtio_sensor *vs)
        if (vs->sensor_capability & sensor_cap_proxi) {
                maru_proxi_exit(vs);
        }
+
+       if (vs->sensor_capability & sensor_cap_haptic) {
+               maru_haptic_exit(vs);
+       }
 }
 
 static void cleanup(struct virtio_device* dev) {
index f0c5b8dd94322dde4d672fc30249b3172ac33dd2..3480741f939a74d468459e4ba131c23f87fb489b 100644 (file)
@@ -70,11 +70,12 @@ enum sensor_types {
 };
 
 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_accel        = 0x01,
+       sensor_cap_geo          = 0x02,
+       sensor_cap_gyro         = 0x04,
+       sensor_cap_light        = 0x08,
+       sensor_cap_proxi        = 0x10,
+       sensor_cap_haptic       = 0x20
 };
 
 #define __MAX_BUF_SIZE                 1024
@@ -114,6 +115,7 @@ struct virtio_sensor {
        void* gyro_handle;
        void* light_handle;
        void* proxi_handle;
+       void* haptic_handle;
 };
 
 #define MARU_DEVICE_ATTR(_name)        \
@@ -167,6 +169,8 @@ int get_sensor_data(int type, char* data);
 #define SENSOR_PROXI_INPUT_NAME                "proximity_sensor"
 #define MARU_PROXI_DEVICE_NAME         "EMULATOR_PROXI"
 
+#define SENSOR_HAPTIC_INPUT_NAME       "haptic_sensor"
+
 #define LOG(log_level, fmt, ...) \
        printk(log_level "%s: " fmt "\n", SENSOR_CLASS_NAME, ##__VA_ARGS__)
 
@@ -200,4 +204,10 @@ int maru_light_exit(struct virtio_sensor *vs);
 int maru_proxi_init(struct virtio_sensor *vs);
 int maru_proxi_exit(struct virtio_sensor *vs);
 
+/*
+ * Haptic device
+ */
+int maru_haptic_init(struct virtio_sensor *vs);
+int maru_haptic_exit(struct virtio_sensor *vs);
+
 #endif