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");
|