aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/sensorhub/stm/sensors_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/sensorhub/stm/sensors_core.c')
-rwxr-xr-xdrivers/sensorhub/stm/sensors_core.c173
1 files changed, 173 insertions, 0 deletions
diff --git a/drivers/sensorhub/stm/sensors_core.c b/drivers/sensorhub/stm/sensors_core.c
new file mode 100755
index 00000000000..2e64ee34325
--- /dev/null
+++ b/drivers/sensorhub/stm/sensors_core.c
@@ -0,0 +1,173 @@
+/*
+ * Universal sensors core class
+ *
+ * Author : Ryunkyun Park <ryun.park@samsung.com>
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/err.h>
+
+struct class *sensors_class;
+EXPORT_SYMBOL_GPL(sensors_class);
+struct class *sensors_event_class;
+EXPORT_SYMBOL_GPL(sensors_event_class);
+static atomic_t sensor_count;
+static struct device *symlink_dev;
+
+/*
+ * Create sysfs interface
+ */
+static void set_sensor_attr(struct device *dev,
+ struct device_attribute *attributes[])
+{
+ int i;
+
+ for (i = 0; attributes[i] != NULL; i++)
+ if ((device_create_file(dev, attributes[i])) < 0)
+ pr_err("[SENSOR CORE] fail device_create_file"\
+ "(dev, attributes[%d])\n", i);
+}
+
+int sensors_create_symlink(struct kobject *target,
+ const char *name)
+{
+ int err = 0;
+
+ if (symlink_dev == NULL) {
+ pr_err("%s, symlink_dev is NULL!!!\n", __func__);
+ return err ;
+ }
+
+ err = sysfs_create_link(&symlink_dev->kobj, target, name);
+
+ if (err < 0) {
+ pr_err("%s, %s failed!(%d)\n", __func__, name, err);
+ return err;
+ }
+
+ return err;
+}
+EXPORT_SYMBOL_GPL(sensors_create_symlink);
+
+void sensors_remove_symlink(struct kobject *target,
+ const char *name)
+{
+
+ if (symlink_dev == NULL) {
+ pr_err("%s, symlink_dev is NULL!!!\n", __func__);
+ return;
+ }
+
+ sysfs_delete_link(&symlink_dev->kobj, target, name);
+}
+EXPORT_SYMBOL_GPL(sensors_remove_symlink);
+
+
+int sensors_register(struct device *dev, void *drvdata,
+ struct device_attribute *attributes[], char *name)
+{
+ int ret = 0;
+
+ if (!sensors_class) {
+ sensors_class = class_create(THIS_MODULE, "sensors");
+ if (IS_ERR(sensors_class))
+ return PTR_ERR(sensors_class);
+ }
+
+ dev = device_create(sensors_class, NULL, 0, drvdata, "%s", name);
+
+ if (IS_ERR(dev)) {
+ ret = PTR_ERR(dev);
+ pr_err("[SENSORS CORE] device_create failed!"\
+ "[%d]\n", ret);
+ return ret;
+ }
+
+ set_sensor_attr(dev, attributes);
+ atomic_inc(&sensor_count);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(sensors_register);
+
+void sensors_unregister(struct device *dev,
+ struct device_attribute *attributes[])
+{
+ int i;
+
+ for (i = 0; attributes[i] != NULL; i++)
+ device_remove_file(dev, attributes[i]);
+}
+EXPORT_SYMBOL_GPL(sensors_unregister);
+
+void destroy_sensor_class(void)
+{
+ if (sensors_class) {
+ class_destroy(sensors_class);
+ sensors_class = NULL;
+ }
+
+ if (sensors_event_class) {
+ device_destroy(sensors_event_class, symlink_dev->devt);
+ class_destroy(sensors_event_class);
+ symlink_dev = NULL;
+ sensors_event_class = NULL;
+ }
+}
+EXPORT_SYMBOL_GPL(destroy_sensor_class);
+
+static int __init sensors_class_init(void)
+{
+ pr_info("[SENSORS CORE] sensors_class_init\n");
+ sensors_class = class_create(THIS_MODULE, "sensors");
+
+ if (IS_ERR(sensors_class)) {
+ pr_err("%s, create sensors_class is failed.(err=%ld)\n",
+ __func__, IS_ERR(sensors_class));
+ return PTR_ERR(sensors_class);
+ }
+
+ /* For symbolic link */
+ sensors_event_class = class_create(THIS_MODULE, "sensor_event");
+ if (IS_ERR(sensors_event_class)) {
+ pr_err("%s, create sensors_class is failed.(err=%ld)\n",
+ __func__, IS_ERR(sensors_event_class));
+ return PTR_ERR(sensors_event_class);
+ }
+
+ symlink_dev = device_create(sensors_event_class, NULL, 0, NULL,
+ "%s", "symlink");
+
+ if (IS_ERR(symlink_dev)) {
+ pr_err("[SENSORS CORE] symlink_dev create failed!"\
+ "[%ld]\n", IS_ERR(symlink_dev));
+ return PTR_ERR(symlink_dev);
+ }
+
+ atomic_set(&sensor_count, 0);
+ sensors_class->dev_uevent = NULL;
+ pr_info("[SENSORS CORE] sensors_class_init succcess\n");
+
+ return 0;
+}
+
+static void __exit sensors_class_exit(void)
+{
+ if (sensors_class || sensors_event_class) {
+ class_destroy(sensors_class);
+ sensors_class = NULL;
+ class_destroy(sensors_event_class);
+ sensors_event_class = NULL;
+ }
+}
+
+subsys_initcall(sensors_class_init);
+module_exit(sensors_class_exit);
+
+MODULE_DESCRIPTION("Universal sensors core class");
+MODULE_AUTHOR("Ryunkyun Park <ryun.park@samsung.com>");
+MODULE_LICENSE("GPL");