misc: Removed warnings from MAX1749 driver
[linux-2.6.git] / drivers / misc / max1749.c
1 /*
2  * drivers/misc/max1749.c
3  *
4  * Driver for MAX1749, vibrator motor driver.
5  *
6  * Copyright (c) 2011-2013 NVIDIA Corporation, All Rights Reserved.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  * more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21  */
22
23 #include <linux/module.h>
24 #include <linux/regulator/consumer.h>
25 #include <linux/kernel.h>
26 #include <linux/platform_device.h>
27 #include <linux/err.h>
28 #include <linux/hrtimer.h>
29 #include <linux/delay.h>
30 #include <linux/workqueue.h>
31
32 #include <linux/slab.h>
33
34 #include "../staging/android/timed_output.h"
35
36 struct vibrator_data {
37         struct timed_output_dev dev;
38         struct hrtimer timer;
39         struct regulator *regulator;
40         struct work_struct work;
41         bool vibrator_on;
42 };
43
44 static struct vibrator_data *data;
45
46
47 static void vibrator_start(void)
48 {
49         if (!data->vibrator_on) {
50                 regulator_enable(data->regulator);
51                 data->vibrator_on = true;
52         }
53 }
54
55 static void vibrator_stop(void)
56 {
57         int ret;
58         if (data->vibrator_on) {
59                 ret = regulator_is_enabled(data->regulator);
60                 if (ret > 0) {
61                         regulator_disable(data->regulator);
62                         data->vibrator_on = false;
63                 }
64         }
65 }
66
67 static void vibrator_work_func(struct work_struct *work)
68 {
69         vibrator_stop();
70 }
71
72 static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)
73 {
74         schedule_work(&data->work);
75         return HRTIMER_NORESTART;
76 }
77
78 /*
79  * Timeout value can be changed from sysfs entry
80  * created by timed_output_dev.
81  * echo 100 > /sys/class/timed_output/vibrator/enable
82  */
83 static void vibrator_enable(struct timed_output_dev *dev, int value)
84 {
85         hrtimer_cancel(&data->timer);
86         if (value > 0) {
87                 vibrator_start();
88                 hrtimer_start(&data->timer,
89                           ktime_set(value / 1000, (value % 1000) * 1000000),
90                           HRTIMER_MODE_REL);
91         } else
92                 vibrator_stop();
93         return;
94 }
95
96 static int vibrator_get_time(struct timed_output_dev *dev)
97 {
98         if (hrtimer_active(&data->timer)) {
99                 ktime_t r = hrtimer_get_remaining(&data->timer);
100                 struct timeval t = ktime_to_timeval(r);
101                 return t.tv_sec * 1000 + t.tv_usec / 1000;
102         } else
103                 return 0;
104 }
105
106 static struct timed_output_dev vibrator_dev = {
107         .name           = "vibrator",
108         .get_time       = vibrator_get_time,
109         .enable         = vibrator_enable,
110 };
111
112 static int vibrator_probe(struct platform_device *pdev)
113 {
114         int ret;
115         data = kzalloc(sizeof(struct vibrator_data), GFP_KERNEL);
116         if (!data)
117                 return -ENOMEM;
118
119         data->regulator = regulator_get(NULL, "vdd_vbrtr");
120         if (IS_ERR_OR_NULL(data->regulator)) {
121                 pr_err("vibrator_init:Couldn't get regulator vdd_vbrtr\n");
122                 data->regulator = NULL;
123                 ret = PTR_ERR(data->regulator);
124                 goto err;
125         }
126         hrtimer_init(&data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
127         /* Intialize the work queue */
128         INIT_WORK(&data->work, vibrator_work_func);
129         data->timer.function = vibrator_timer_func;
130         data->dev = vibrator_dev;
131         data->vibrator_on = false;
132
133         ret = timed_output_dev_register(&data->dev);
134         if (ret)
135                 goto err2;
136
137         return 0;
138
139 err2:
140         regulator_put(data->regulator);
141 err:
142         kfree(data);
143         return ret;
144 }
145
146 static int vibrator_remove(struct platform_device *pdev)
147 {
148         timed_output_dev_unregister(&data->dev);
149         regulator_put(data->regulator);
150         kfree(data);
151
152         return 0;
153 }
154
155 static struct platform_driver vibrator_driver = {
156         .probe = vibrator_probe,
157         .remove = vibrator_remove,
158         .driver = {
159                 .name = "tegra-vibrator",
160                 .owner = THIS_MODULE,
161         },
162 };
163
164 static int __init vibrator_init(void)
165 {
166         return platform_driver_register(&vibrator_driver);
167 }
168
169 static void __exit vibrator_exit(void)
170 {
171         platform_driver_unregister(&vibrator_driver);
172 }
173
174 MODULE_DESCRIPTION("timed output vibrator device");
175 MODULE_AUTHOR("GPL");
176
177 module_init(vibrator_init);
178 module_exit(vibrator_exit);