blob: cd9b171c0d378985141b66209ea9bfdb6681940c [file] [log] [blame]
Devin Kim55468852012-06-19 12:01:32 -07001/*
2 * android vibrator driver
3 *
4 * Copyright (C) 2009-2012 LGE, Inc.
5 *
6 * Author: Jinkyu Choi <jinkyu@lge.com>
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,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/platform_device.h>
28#include <linux/gpio.h>
29#include <linux/delay.h>
30#include <linux/timer.h>
31#include <linux/err.h>
32#include <linux/android_vibrator.h>
33#include "../staging/android/timed_output.h"
34
35#define ANDROID_VIBRATOR_USE_WORKQUEUE
36
37#ifdef ANDROID_VIBRATOR_USE_WORKQUEUE
38static struct workqueue_struct *vibrator_workqueue;
39#endif
40
41struct timed_vibrator_data {
42 struct timed_output_dev dev;
43 struct hrtimer timer;
44 spinlock_t lock;
45 atomic_t vib_status; /* on/off */
46
47 int max_timeout;
Devin Kim795a9a62012-08-28 10:08:46 -070048 atomic_t gain; /* default max gain */
49 atomic_t pwm;
50 atomic_t ms_time; /* vibrator duration */
51 struct android_vibrator_platform_data *pdata;
Devin Kim55468852012-06-19 12:01:32 -070052 struct work_struct work_vibrator_off;
53 struct work_struct work_vibrator_on;
54};
55
56static int android_vibrator_force_set(struct timed_vibrator_data *vib,
Devin Kim795a9a62012-08-28 10:08:46 -070057 int intensity, int pwm)
Devin Kim55468852012-06-19 12:01:32 -070058{
59 /* Check the Force value with Max and Min force value */
Devin Kim795a9a62012-08-28 10:08:46 -070060 int vib_duration_ms = 0;
61 pr_debug("%s: intensity : %d\n", __func__, intensity);
Devin Kim55468852012-06-19 12:01:32 -070062
Devin Kim795a9a62012-08-28 10:08:46 -070063 if (intensity > 127)
64 intensity = 127;
65 if (intensity < -127)
66 intensity = -127;
Devin Kim55468852012-06-19 12:01:32 -070067
68 /* TODO: control the gain of vibrator */
Devin Kim795a9a62012-08-28 10:08:46 -070069 if (intensity == 0) {
70 vib->pdata->ic_enable_set(0);
71 vib->pdata->pwm_set(0, 0, pwm);
Devin Kim55468852012-06-19 12:01:32 -070072 /* should be checked for vibrator response time */
Devin Kim795a9a62012-08-28 10:08:46 -070073 vib->pdata->power_set(0);
Devin Kim55468852012-06-19 12:01:32 -070074
75 atomic_set(&vib->vib_status, false);
76 } else {
77 cancel_work_sync(&vib->work_vibrator_off);
78 hrtimer_cancel(&vib->timer);
Devin Kim795a9a62012-08-28 10:08:46 -070079 vib_duration_ms = atomic_read(&vib->ms_time);
Devin Kim55468852012-06-19 12:01:32 -070080 /* should be checked for vibrator response time */
Devin Kim795a9a62012-08-28 10:08:46 -070081 vib->pdata->power_set(1);
82 vib->pdata->pwm_set(1, intensity, pwm);
83 vib->pdata->ic_enable_set(1);
Devin Kim55468852012-06-19 12:01:32 -070084
85 atomic_set(&vib->vib_status, true);
86 hrtimer_start(&vib->timer,
Devin Kim795a9a62012-08-28 10:08:46 -070087 ns_to_ktime((u64)vib_duration_ms * NSEC_PER_MSEC),
Devin Kim55468852012-06-19 12:01:32 -070088 HRTIMER_MODE_REL);
89 }
90 return 0;
91}
92
93static void android_vibrator_on(struct work_struct *work)
94{
95 struct timed_vibrator_data *vib =
96 container_of(work, struct timed_vibrator_data,
97 work_vibrator_on);
Devin Kim795a9a62012-08-28 10:08:46 -070098 int gain = atomic_read(&vib->gain);
99 int pwm = atomic_read(&vib->pwm);
Devin Kim55468852012-06-19 12:01:32 -0700100 /* suspend /resume logging test */
Devin Kim795a9a62012-08-28 10:08:46 -0700101 pr_debug("%s: gain = %d pwm = %d\n", __func__,
102 gain, pwm);
Devin Kim55468852012-06-19 12:01:32 -0700103
Devin Kim795a9a62012-08-28 10:08:46 -0700104 android_vibrator_force_set(vib, gain, pwm);
Devin Kim55468852012-06-19 12:01:32 -0700105}
106
107static void android_vibrator_off(struct work_struct *work)
108{
109 struct timed_vibrator_data *vib =
110 container_of(work, struct timed_vibrator_data,
111 work_vibrator_off);
112
Devin Kim795a9a62012-08-28 10:08:46 -0700113 pr_debug("%s\n", __func__);
114 android_vibrator_force_set(vib, 0, vib->pdata->vibe_n_value);
Devin Kim55468852012-06-19 12:01:32 -0700115}
116
117static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)
118{
119 struct timed_vibrator_data *vib =
120 container_of(timer, struct timed_vibrator_data, timer);
121#ifdef ANDROID_VIBRATOR_USE_WORKQUEUE
122 queue_work(vibrator_workqueue,&vib->work_vibrator_off);
123#endif
124 return HRTIMER_NORESTART;
125}
126
127static int vibrator_get_time(struct timed_output_dev *dev)
128{
129 struct timed_vibrator_data *vib =
130 container_of(dev, struct timed_vibrator_data, dev);
131
132 if (hrtimer_active(&vib->timer)) {
133 ktime_t r = hrtimer_get_remaining(&vib->timer);
134 return ktime_to_ms(r);
135 }
136
137 return 0;
138}
139
Devin Kim795a9a62012-08-28 10:08:46 -0700140static void vibrator_enable(struct timed_output_dev *dev, int ms_time)
Devin Kim55468852012-06-19 12:01:32 -0700141{
142 struct timed_vibrator_data *vib =
143 container_of(dev, struct timed_vibrator_data, dev);
144 unsigned long flags;
145
Devin Kim795a9a62012-08-28 10:08:46 -0700146 pr_debug("%s: ms_time %d \n", __func__, ms_time);
Devin Kim55468852012-06-19 12:01:32 -0700147 spin_lock_irqsave(&vib->lock, flags);
148
Devin Kim795a9a62012-08-28 10:08:46 -0700149 if (ms_time > 0) {
150 if (ms_time > vib->max_timeout)
151 ms_time = vib->max_timeout;
Devin Kim55468852012-06-19 12:01:32 -0700152
Devin Kim795a9a62012-08-28 10:08:46 -0700153 atomic_set(&vib->ms_time, ms_time);
Devin Kim55468852012-06-19 12:01:32 -0700154
155#ifdef ANDROID_VIBRATOR_USE_WORKQUEUE
156 queue_work(vibrator_workqueue,&vib->work_vibrator_on);
157#endif
158 } else {
159#ifdef ANDROID_VIBRATOR_USE_WORKQUEUE
160 queue_work(vibrator_workqueue,&vib->work_vibrator_off);
161#endif
162 }
163 spin_unlock_irqrestore(&vib->lock, flags);
Devin Kim55468852012-06-19 12:01:32 -0700164}
165
166static ssize_t vibrator_amp_show(struct device *dev,
167 struct device_attribute *attr, char *buf)
168{
169 struct timed_output_dev *dev_ =
170 (struct timed_output_dev *)dev_get_drvdata(dev);
171 struct timed_vibrator_data *vib =
172 container_of(dev_, struct timed_vibrator_data, dev);
Devin Kim795a9a62012-08-28 10:08:46 -0700173 int gain = atomic_read(&(vib->gain));
Devin Kim55468852012-06-19 12:01:32 -0700174
175 return sprintf(buf, "%d\n", gain);
176}
177
178static ssize_t vibrator_amp_store(struct device *dev,
179 struct device_attribute *attr, const char *buf, size_t size)
180{
181 struct timed_output_dev *dev_ =
182 (struct timed_output_dev *)dev_get_drvdata(dev);
183 struct timed_vibrator_data *vib =
184 container_of(dev_, struct timed_vibrator_data, dev);
185
186 int gain;
187 sscanf(buf, "%d", &gain);
Devin Kim795a9a62012-08-28 10:08:46 -0700188 atomic_set(&vib->gain, gain);
Devin Kim55468852012-06-19 12:01:32 -0700189
190 return size;
191}
192
193static ssize_t vibrator_pwm_show(struct device *dev,
194 struct device_attribute *attr, char *buf)
195{
196 struct timed_output_dev *dev_ =
197 (struct timed_output_dev *)dev_get_drvdata(dev);
198 struct timed_vibrator_data *vib =
199 container_of(dev_, struct timed_vibrator_data, dev);
Devin Kim795a9a62012-08-28 10:08:46 -0700200 int gain = atomic_read(&(vib->pwm));
Devin Kim55468852012-06-19 12:01:32 -0700201
202 gain = 4800/gain;
203
204 return sprintf(buf, "%d\n", gain);
205}
206
Devin Kim795a9a62012-08-28 10:08:46 -0700207
Devin Kim55468852012-06-19 12:01:32 -0700208static ssize_t vibrator_pwm_store(struct device *dev,
209 struct device_attribute *attr, const char *buf, size_t size)
210{
211 struct timed_output_dev *dev_ =
212 (struct timed_output_dev *)dev_get_drvdata(dev);
213 struct timed_vibrator_data *vib =
214 container_of(dev_, struct timed_vibrator_data, dev);
215
216 int gain;
217 sscanf(buf, "%d", &gain);
218
219 gain = 4800/gain;
220
Devin Kim795a9a62012-08-28 10:08:46 -0700221 atomic_set(&vib->pwm, gain);
Devin Kim55468852012-06-19 12:01:32 -0700222
223 return size;
224}
225
Devin Kim795a9a62012-08-28 10:08:46 -0700226static struct device_attribute android_vibrator_device_attrs[] = {
Devin Kim55468852012-06-19 12:01:32 -0700227 __ATTR(amp, S_IRUGO | S_IWUSR, vibrator_amp_show, vibrator_amp_store),
228 __ATTR(pwm, S_IRUGO | S_IWUSR, vibrator_pwm_show, vibrator_pwm_store),
229};
230
231struct timed_vibrator_data android_vibrator_data = {
232 .dev.name = "vibrator",
233 .dev.enable = vibrator_enable,
234 .dev.get_time = vibrator_get_time,
235 .max_timeout = 30000, /* max time for vibrator enable 30 sec. */
Devin Kim795a9a62012-08-28 10:08:46 -0700236 .pdata = NULL,
Devin Kim55468852012-06-19 12:01:32 -0700237};
238
239static int android_vibrator_probe(struct platform_device *pdev)
240{
241
242 int i, ret = 0;
Devin Kim795a9a62012-08-28 10:08:46 -0700243 struct timed_vibrator_data *vib = &android_vibrator_data;
244 vib->pdata = pdev->dev.platform_data;
Devin Kim55468852012-06-19 12:01:32 -0700245
Devin Kim795a9a62012-08-28 10:08:46 -0700246 if (!vib->pdata) {
247 pr_err("%s: no platform data\n", __func__);
Devin Kim55468852012-06-19 12:01:32 -0700248 return -ENODEV;
249 }
250
Devin Kim795a9a62012-08-28 10:08:46 -0700251 if (vib->pdata->vibrator_init) {
252 ret = vib->pdata->vibrator_init();
253 if (ret < 0) {
254 pr_err("%s: failed to vibrator init\n", __func__);
255 return ret;
256 }
257 }
258
259 platform_set_drvdata(pdev, &android_vibrator_data);
260
261 atomic_set(&vib->gain, vib->pdata->amp); /* max value is 128 */
262 atomic_set(&vib->pwm, vib->pdata->vibe_n_value);
Devin Kim55468852012-06-19 12:01:32 -0700263 atomic_set(&vib->vib_status, false);
Devin Kim795a9a62012-08-28 10:08:46 -0700264 pr_info("android_vibrator: default amplitude %d \n",
265 vib->pdata->amp);
Devin Kim55468852012-06-19 12:01:32 -0700266
267 INIT_WORK(&vib->work_vibrator_off, android_vibrator_off);
268 INIT_WORK(&vib->work_vibrator_on, android_vibrator_on);
269 hrtimer_init(&vib->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
270 vib->timer.function = vibrator_timer_func;
271 spin_lock_init(&vib->lock);
272
273 ret = timed_output_dev_register(&vib->dev);
274 if (ret < 0) {
Devin Kim795a9a62012-08-28 10:08:46 -0700275 pr_err("%s: failed to register timed output device\n",
276 __func__);
277 return ret;
Devin Kim55468852012-06-19 12:01:32 -0700278 }
Devin Kim795a9a62012-08-28 10:08:46 -0700279
280 for (i = 0; i < ARRAY_SIZE(android_vibrator_device_attrs); i++) {
281 ret = device_create_file(vib->dev.dev,
282 &android_vibrator_device_attrs[i]);
Devin Kim55468852012-06-19 12:01:32 -0700283 if (ret < 0) {
Devin Kim795a9a62012-08-28 10:08:46 -0700284 pr_err("%s: failed to create sysfs\n", __func__);
285 goto err_sysfs;
Devin Kim55468852012-06-19 12:01:32 -0700286 }
287 }
288
Devin Kim795a9a62012-08-28 10:08:46 -0700289 pr_info("android vibrator probed\n");
Devin Kim55468852012-06-19 12:01:32 -0700290
291 return 0;
Devin Kim795a9a62012-08-28 10:08:46 -0700292
293err_sysfs:
294 for (; i >= 0; i--) {
295 device_remove_file(vib->dev.dev,
296 &android_vibrator_device_attrs[i]);
297 }
298
299 timed_output_dev_unregister(&vib->dev);
300 return ret;
Devin Kim55468852012-06-19 12:01:32 -0700301}
302
303static int android_vibrator_remove(struct platform_device *pdev)
304{
305 struct timed_vibrator_data *vib =
306 (struct timed_vibrator_data *)platform_get_drvdata(pdev);
Devin Kim795a9a62012-08-28 10:08:46 -0700307 int i;
Devin Kim55468852012-06-19 12:01:32 -0700308
309#ifdef ANDROID_VIBRATOR_USE_WORKQUEUE
310 queue_work(vibrator_workqueue, &vib->work_vibrator_off);
311#endif
Devin Kim795a9a62012-08-28 10:08:46 -0700312 for (i = ARRAY_SIZE(android_vibrator_device_attrs); i >= 0; i--) {
313 device_remove_file(vib->dev.dev,
314 &android_vibrator_device_attrs[i]);
315 }
Devin Kim55468852012-06-19 12:01:32 -0700316
317 timed_output_dev_unregister(&vib->dev);
318
319 return 0;
320}
321
Devin Kim55468852012-06-19 12:01:32 -0700322static struct platform_driver android_vibrator_driver = {
323 .probe = android_vibrator_probe,
324 .remove = android_vibrator_remove,
Devin Kim55468852012-06-19 12:01:32 -0700325 .driver = {
326 .name = "android-vibrator",
327 },
328};
329
330static int __init android_vibrator_init(void)
331{
Devin Kim55468852012-06-19 12:01:32 -0700332#ifdef ANDROID_VIBRATOR_USE_WORKQUEUE
333 vibrator_workqueue = create_workqueue("vibrator");
334
Devin Kim795a9a62012-08-28 10:08:46 -0700335 if (!vibrator_workqueue) {
336 pr_err("%s: out of memory\n", __func__);
Devin Kim55468852012-06-19 12:01:32 -0700337 return -ENOMEM;
Devin Kim795a9a62012-08-28 10:08:46 -0700338 }
Devin Kim55468852012-06-19 12:01:32 -0700339#endif
340 return platform_driver_register(&android_vibrator_driver);
Devin Kim55468852012-06-19 12:01:32 -0700341}
342
343static void __exit android_vibrator_exit(void)
344{
Devin Kim55468852012-06-19 12:01:32 -0700345#ifdef ANDROID_VIBRATOR_USE_WORKQUEUE
346 if (vibrator_workqueue)
347 destroy_workqueue(vibrator_workqueue);
348
349 vibrator_workqueue = NULL;
350#endif
351 platform_driver_unregister(&android_vibrator_driver);
Devin Kim55468852012-06-19 12:01:32 -0700352}
353
354late_initcall_sync(android_vibrator_init); /* to let init lately */
355module_exit(android_vibrator_exit);
356
357MODULE_AUTHOR("LG Electronics Inc.");
358MODULE_DESCRIPTION("Android Vibrator Driver");
359MODULE_LICENSE("GPL");