aboutsummaryrefslogtreecommitdiff
path: root/drivers/misc/mediatek/vibrator/thunderquake_engine.c
blob: 41241703dd5a4b15ae63636e7d3a037d11538336 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/*
 * Copyright © 2014, Varun Chitre "varun.chitre15" <varun.chitre15@gmail.com>
 *
 * Vibration Intensity Controller for MTK Vibrator
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * 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.
 *
 * Please preserve this licence and driver name if you implement this
 * anywhere else.
 *
 */

#include <linux/module.h>
#include <linux/kobject.h>
#include <linux/sysfs.h>
#include <linux/kernel.h>
#include <linux/kallsyms.h>

#include <cust_vibrator.h>
#include <vibrator_hal.h>
#include <mach/upmu_hw.h>

#define MAX_VIBR 7
#define MIN_VIBR 0

#define ENGINE_VERSION  1
#define ENGINE_VERSION_SUB 0

extern void pmic_set_register_value(PMU_FLAGS_LIST_ENUM flagname, kal_uint32 val);

static ssize_t vibr_vtg_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
	struct vibrator_hw *hw = mt_get_cust_vibrator_hw();

	return sprintf(buf, "%d\n", hw->vib_vol);
}

static ssize_t vibr_vtg_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
	unsigned int val;
    struct vibrator_hw *hw = mt_get_cust_vibrator_hw();
	sscanf(buf, "%u", &val);
	if (val >= MIN_VIBR && val <= MAX_VIBR) {
       pmic_set_register_value(PMIC_RG_VIBR_VOSEL, val);
       hw->vib_vol = val;
    }
	return count;
}

static ssize_t thunderquake_version_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
	return sprintf(buf, "version: %u.%u\n", ENGINE_VERSION, ENGINE_VERSION_SUB);
}

static struct kobj_attribute thunderquake_version_attribute =
	__ATTR(engine_version,
		0444,
		thunderquake_version_show, NULL);

static struct kobj_attribute thunderquake_level_attribute =
	__ATTR(level,
		0666,
		vibr_vtg_show, vibr_vtg_store);

static struct attribute *thunderquake_engine_attrs[] = {
		&thunderquake_level_attribute.attr,
		&thunderquake_version_attribute.attr,
		NULL,
	};

static struct attribute_group vibr_level_control_attr_group = {
		.attrs = thunderquake_engine_attrs,
	};

static struct kobject *vibr_level_control_kobj;

static int vibr_level_control_init(void)
{
	int sysfs_result;
	printk(KERN_DEBUG "[%s]\n", __func__);

	vibr_level_control_kobj =
		kobject_create_and_add("thunderquake_engine", kernel_kobj);

	if (!vibr_level_control_kobj) {
		pr_err("%s Interface create failed!\n",
			__func__);
		return -ENOMEM;
    }

	sysfs_result = sysfs_create_group(vibr_level_control_kobj,
			&vibr_level_control_attr_group);

	if (sysfs_result) {
		pr_info("%s sysfs create failed!\n", __func__);
		kobject_put(vibr_level_control_kobj);
	}
	return sysfs_result;
}

static void vibr_level_control_exit(void)
{
	if (vibr_level_control_kobj != NULL)
		kobject_put(vibr_level_control_kobj);
}

module_init(vibr_level_control_init);
module_exit(vibr_level_control_exit);
MODULE_LICENSE("GPL and additional rights");
MODULE_AUTHOR("Varun Chitre <varun.chitre15@gmail.com>");
MODULE_DESCRIPTION("ThundQuake Engine - Driver to control Mediatek Vibrator Intensity");