blob: 13932f781aa5f2717deb25f2ff42fb4db955fe0f [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>
Devin Kima66ff762012-09-13 14:44:22 -070033#include <linux/mutex.h>
Devin Kim55468852012-06-19 12:01:32 -070034#include "../staging/android/timed_output.h"
35
36#define ANDROID_VIBRATOR_USE_WORKQUEUE
37
38#ifdef ANDROID_VIBRATOR_USE_WORKQUEUE
39static struct workqueue_struct *vibrator_workqueue;
40#endif
41
42struct timed_vibrator_data {
43 struct timed_output_dev dev;
44 struct hrtimer timer;
45 spinlock_t lock;
Devin Kim55468852012-06-19 12:01:32 -070046 int max_timeout;
Devin Kima66ff762012-09-13 14:44:22 -070047 atomic_t vib_status; /* 1:on,0:off */
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
Devin Kima66ff762012-09-13 14:44:22 -070056#ifdef ANDROID_VIBRATOR_USE_WORKQUEUE
Devin Kimb017c812012-09-17 09:50:23 -070057static inline void vibrator_work_on(struct work_struct *work)
58{
59 queue_work(vibrator_workqueue, work);
60}
61
62static inline void vibrator_work_off(struct work_struct *work)
Devin Kima66ff762012-09-13 14:44:22 -070063{
64 if (!work_pending(work))
65 queue_work(vibrator_workqueue, work);
66}
Devin Kima66ff762012-09-13 14:44:22 -070067#else
Devin Kimb017c812012-09-17 09:50:23 -070068static inline void vibrator_work_on(struct work_struct *work)
69{
70 schedule_work(work);
71}
72
73static inline void vibrator_work_off(struct work_struct *work)
Devin Kima66ff762012-09-13 14:44:22 -070074{
75 if (!work_pending(work))
76 schedule_work(work);
77}
78#endif
79
Devin Kim55468852012-06-19 12:01:32 -070080static int android_vibrator_force_set(struct timed_vibrator_data *vib,
Devin Kim795a9a62012-08-28 10:08:46 -070081 int intensity, int pwm)
Devin Kim55468852012-06-19 12:01:32 -070082{
Devin Kim7eb84ca2012-09-14 16:16:13 -070083 struct android_vibrator_platform_data *pdata = vib->pdata;
Devin Kim795a9a62012-08-28 10:08:46 -070084 int vib_duration_ms = 0;
Devin Kim7eb84ca2012-09-14 16:16:13 -070085
Devin Kim795a9a62012-08-28 10:08:46 -070086 pr_debug("%s: intensity : %d\n", __func__, intensity);
Devin Kim55468852012-06-19 12:01:32 -070087
Devin Kim7eb84ca2012-09-14 16:16:13 -070088 if (pdata->vibe_warmup_delay > 0) {
89 if (atomic_read(&vib->vib_status))
90 msleep(pdata->vibe_warmup_delay);
91 }
92
Devin Kim55468852012-06-19 12:01:32 -070093 /* TODO: control the gain of vibrator */
Devin Kim795a9a62012-08-28 10:08:46 -070094 if (intensity == 0) {
Devin Kim7eb84ca2012-09-14 16:16:13 -070095 pdata->ic_enable_set(0);
96 pdata->pwm_set(0, 0, pwm);
Devin Kim55468852012-06-19 12:01:32 -070097 /* should be checked for vibrator response time */
Devin Kim7eb84ca2012-09-14 16:16:13 -070098 pdata->power_set(0);
Devin Kima66ff762012-09-13 14:44:22 -070099 atomic_set(&vib->vib_status, 0);
Devin Kim55468852012-06-19 12:01:32 -0700100 } else {
Devin Kima66ff762012-09-13 14:44:22 -0700101 if (work_pending(&vib->work_vibrator_off))
102 cancel_work_sync(&vib->work_vibrator_off);
Devin Kim55468852012-06-19 12:01:32 -0700103 hrtimer_cancel(&vib->timer);
Devin Kima66ff762012-09-13 14:44:22 -0700104
Devin Kim795a9a62012-08-28 10:08:46 -0700105 vib_duration_ms = atomic_read(&vib->ms_time);
Devin Kim55468852012-06-19 12:01:32 -0700106 /* should be checked for vibrator response time */
Devin Kim7eb84ca2012-09-14 16:16:13 -0700107 pdata->power_set(1);
108 pdata->pwm_set(1, intensity, pwm);
109 pdata->ic_enable_set(1);
Devin Kima66ff762012-09-13 14:44:22 -0700110 atomic_set(&vib->vib_status, 1);
Devin Kim55468852012-06-19 12:01:32 -0700111
Devin Kim55468852012-06-19 12:01:32 -0700112 hrtimer_start(&vib->timer,
Devin Kim795a9a62012-08-28 10:08:46 -0700113 ns_to_ktime((u64)vib_duration_ms * NSEC_PER_MSEC),
Devin Kim55468852012-06-19 12:01:32 -0700114 HRTIMER_MODE_REL);
115 }
Devin Kima66ff762012-09-13 14:44:22 -0700116
Devin Kim55468852012-06-19 12:01:32 -0700117 return 0;
118}
119
120static void android_vibrator_on(struct work_struct *work)
121{
122 struct timed_vibrator_data *vib =
123 container_of(work, struct timed_vibrator_data,
124 work_vibrator_on);
Devin Kim795a9a62012-08-28 10:08:46 -0700125 int gain = atomic_read(&vib->gain);
126 int pwm = atomic_read(&vib->pwm);
Devin Kim55468852012-06-19 12:01:32 -0700127 /* suspend /resume logging test */
Devin Kim795a9a62012-08-28 10:08:46 -0700128 pr_debug("%s: gain = %d pwm = %d\n", __func__,
129 gain, pwm);
Devin Kim55468852012-06-19 12:01:32 -0700130
Devin Kim795a9a62012-08-28 10:08:46 -0700131 android_vibrator_force_set(vib, gain, pwm);
Devin Kim55468852012-06-19 12:01:32 -0700132}
133
134static void android_vibrator_off(struct work_struct *work)
135{
136 struct timed_vibrator_data *vib =
137 container_of(work, struct timed_vibrator_data,
138 work_vibrator_off);
139
Devin Kim795a9a62012-08-28 10:08:46 -0700140 pr_debug("%s\n", __func__);
141 android_vibrator_force_set(vib, 0, vib->pdata->vibe_n_value);
Devin Kim55468852012-06-19 12:01:32 -0700142}
143
144static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)
145{
146 struct timed_vibrator_data *vib =
147 container_of(timer, struct timed_vibrator_data, timer);
Devin Kimb017c812012-09-17 09:50:23 -0700148 vibrator_work_off(&vib->work_vibrator_off);
Devin Kim55468852012-06-19 12:01:32 -0700149 return HRTIMER_NORESTART;
150}
151
152static int vibrator_get_time(struct timed_output_dev *dev)
153{
154 struct timed_vibrator_data *vib =
155 container_of(dev, struct timed_vibrator_data, dev);
156
157 if (hrtimer_active(&vib->timer)) {
158 ktime_t r = hrtimer_get_remaining(&vib->timer);
159 return ktime_to_ms(r);
160 }
161
162 return 0;
163}
164
Devin Kim795a9a62012-08-28 10:08:46 -0700165static void vibrator_enable(struct timed_output_dev *dev, int ms_time)
Devin Kim55468852012-06-19 12:01:32 -0700166{
167 struct timed_vibrator_data *vib =
168 container_of(dev, struct timed_vibrator_data, dev);
169 unsigned long flags;
170
Devin Kim795a9a62012-08-28 10:08:46 -0700171 pr_debug("%s: ms_time %d \n", __func__, ms_time);
Devin Kim55468852012-06-19 12:01:32 -0700172 spin_lock_irqsave(&vib->lock, flags);
173
Devin Kim795a9a62012-08-28 10:08:46 -0700174 if (ms_time > 0) {
175 if (ms_time > vib->max_timeout)
176 ms_time = vib->max_timeout;
Devin Kim55468852012-06-19 12:01:32 -0700177
Devin Kim795a9a62012-08-28 10:08:46 -0700178 atomic_set(&vib->ms_time, ms_time);
Devin Kim55468852012-06-19 12:01:32 -0700179
Devin Kimb017c812012-09-17 09:50:23 -0700180 vibrator_work_on(&vib->work_vibrator_on);
Devin Kim55468852012-06-19 12:01:32 -0700181 } else {
Devin Kimb017c812012-09-17 09:50:23 -0700182 vibrator_work_off(&vib->work_vibrator_off);
Devin Kim55468852012-06-19 12:01:32 -0700183 }
184 spin_unlock_irqrestore(&vib->lock, flags);
Devin Kim55468852012-06-19 12:01:32 -0700185}
186
187static ssize_t vibrator_amp_show(struct device *dev,
188 struct device_attribute *attr, char *buf)
189{
190 struct timed_output_dev *dev_ =
191 (struct timed_output_dev *)dev_get_drvdata(dev);
192 struct timed_vibrator_data *vib =
193 container_of(dev_, struct timed_vibrator_data, dev);
Devin Kim795a9a62012-08-28 10:08:46 -0700194 int gain = atomic_read(&(vib->gain));
Devin Kim55468852012-06-19 12:01:32 -0700195
196 return sprintf(buf, "%d\n", gain);
197}
198
199static ssize_t vibrator_amp_store(struct device *dev,
200 struct device_attribute *attr, const char *buf, size_t size)
201{
202 struct timed_output_dev *dev_ =
203 (struct timed_output_dev *)dev_get_drvdata(dev);
204 struct timed_vibrator_data *vib =
205 container_of(dev_, struct timed_vibrator_data, dev);
206
207 int gain;
208 sscanf(buf, "%d", &gain);
Devin Kimbfae2082012-09-18 16:48:15 -0700209 if (gain > 100)
210 gain = 100;
211 else if (gain < -100)
212 gain = -100;
Devin Kim795a9a62012-08-28 10:08:46 -0700213 atomic_set(&vib->gain, gain);
Devin Kim55468852012-06-19 12:01:32 -0700214
215 return size;
216}
217
218static ssize_t vibrator_pwm_show(struct device *dev,
219 struct device_attribute *attr, char *buf)
220{
221 struct timed_output_dev *dev_ =
222 (struct timed_output_dev *)dev_get_drvdata(dev);
223 struct timed_vibrator_data *vib =
224 container_of(dev_, struct timed_vibrator_data, dev);
Devin Kim795a9a62012-08-28 10:08:46 -0700225 int gain = atomic_read(&(vib->pwm));
Devin Kim55468852012-06-19 12:01:32 -0700226
227 gain = 4800/gain;
228
229 return sprintf(buf, "%d\n", gain);
230}
231
Devin Kim795a9a62012-08-28 10:08:46 -0700232
Devin Kim55468852012-06-19 12:01:32 -0700233static ssize_t vibrator_pwm_store(struct device *dev,
234 struct device_attribute *attr, const char *buf, size_t size)
235{
236 struct timed_output_dev *dev_ =
237 (struct timed_output_dev *)dev_get_drvdata(dev);
238 struct timed_vibrator_data *vib =
239 container_of(dev_, struct timed_vibrator_data, dev);
240
241 int gain;
242 sscanf(buf, "%d", &gain);
243
244 gain = 4800/gain;
245
Devin Kim795a9a62012-08-28 10:08:46 -0700246 atomic_set(&vib->pwm, gain);
Devin Kim55468852012-06-19 12:01:32 -0700247
248 return size;
249}
250
Devin Kim795a9a62012-08-28 10:08:46 -0700251static struct device_attribute android_vibrator_device_attrs[] = {
Devin Kim55468852012-06-19 12:01:32 -0700252 __ATTR(amp, S_IRUGO | S_IWUSR, vibrator_amp_show, vibrator_amp_store),
253 __ATTR(pwm, S_IRUGO | S_IWUSR, vibrator_pwm_show, vibrator_pwm_store),
254};
255
256struct timed_vibrator_data android_vibrator_data = {
257 .dev.name = "vibrator",
258 .dev.enable = vibrator_enable,
259 .dev.get_time = vibrator_get_time,
260 .max_timeout = 30000, /* max time for vibrator enable 30 sec. */
Devin Kim55468852012-06-19 12:01:32 -0700261};
262
263static int android_vibrator_probe(struct platform_device *pdev)
264{
265
266 int i, ret = 0;
Devin Kim795a9a62012-08-28 10:08:46 -0700267 struct timed_vibrator_data *vib = &android_vibrator_data;
268 vib->pdata = pdev->dev.platform_data;
Devin Kim55468852012-06-19 12:01:32 -0700269
Devin Kim795a9a62012-08-28 10:08:46 -0700270 if (!vib->pdata) {
271 pr_err("%s: no platform data\n", __func__);
Devin Kim55468852012-06-19 12:01:32 -0700272 return -ENODEV;
273 }
274
Devin Kim795a9a62012-08-28 10:08:46 -0700275 if (vib->pdata->vibrator_init) {
276 ret = vib->pdata->vibrator_init();
277 if (ret < 0) {
278 pr_err("%s: failed to vibrator init\n", __func__);
279 return ret;
280 }
281 }
282
283 platform_set_drvdata(pdev, &android_vibrator_data);
284
Devin Kimbfae2082012-09-18 16:48:15 -0700285 if (vib->pdata->amp > 100)
286 vib->pdata->amp = 100;
287 else if (vib->pdata->amp < -100)
288 vib->pdata->amp = -100;
289 atomic_set(&vib->gain, vib->pdata->amp); /* max value is 100 */
Devin Kim795a9a62012-08-28 10:08:46 -0700290 atomic_set(&vib->pwm, vib->pdata->vibe_n_value);
Devin Kima66ff762012-09-13 14:44:22 -0700291 atomic_set(&vib->vib_status, 0);
Devin Kim795a9a62012-08-28 10:08:46 -0700292 pr_info("android_vibrator: default amplitude %d \n",
293 vib->pdata->amp);
Devin Kim55468852012-06-19 12:01:32 -0700294
295 INIT_WORK(&vib->work_vibrator_off, android_vibrator_off);
296 INIT_WORK(&vib->work_vibrator_on, android_vibrator_on);
297 hrtimer_init(&vib->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
298 vib->timer.function = vibrator_timer_func;
299 spin_lock_init(&vib->lock);
300
301 ret = timed_output_dev_register(&vib->dev);
302 if (ret < 0) {
Devin Kim795a9a62012-08-28 10:08:46 -0700303 pr_err("%s: failed to register timed output device\n",
304 __func__);
305 return ret;
Devin Kim55468852012-06-19 12:01:32 -0700306 }
Devin Kim795a9a62012-08-28 10:08:46 -0700307
308 for (i = 0; i < ARRAY_SIZE(android_vibrator_device_attrs); i++) {
309 ret = device_create_file(vib->dev.dev,
310 &android_vibrator_device_attrs[i]);
Devin Kim55468852012-06-19 12:01:32 -0700311 if (ret < 0) {
Devin Kim795a9a62012-08-28 10:08:46 -0700312 pr_err("%s: failed to create sysfs\n", __func__);
313 goto err_sysfs;
Devin Kim55468852012-06-19 12:01:32 -0700314 }
315 }
316
Devin Kim795a9a62012-08-28 10:08:46 -0700317 pr_info("android vibrator probed\n");
Devin Kim55468852012-06-19 12:01:32 -0700318
319 return 0;
Devin Kim795a9a62012-08-28 10:08:46 -0700320
321err_sysfs:
322 for (; i >= 0; i--) {
323 device_remove_file(vib->dev.dev,
324 &android_vibrator_device_attrs[i]);
325 }
326
327 timed_output_dev_unregister(&vib->dev);
328 return ret;
Devin Kim55468852012-06-19 12:01:32 -0700329}
330
331static int android_vibrator_remove(struct platform_device *pdev)
332{
333 struct timed_vibrator_data *vib =
334 (struct timed_vibrator_data *)platform_get_drvdata(pdev);
Devin Kim795a9a62012-08-28 10:08:46 -0700335 int i;
Devin Kim55468852012-06-19 12:01:32 -0700336
Devin Kimb017c812012-09-17 09:50:23 -0700337 vibrator_work_off(&vib->work_vibrator_off);
Devin Kim795a9a62012-08-28 10:08:46 -0700338 for (i = ARRAY_SIZE(android_vibrator_device_attrs); i >= 0; i--) {
339 device_remove_file(vib->dev.dev,
340 &android_vibrator_device_attrs[i]);
341 }
Devin Kim55468852012-06-19 12:01:32 -0700342
343 timed_output_dev_unregister(&vib->dev);
344
345 return 0;
346}
347
Devin Kim55468852012-06-19 12:01:32 -0700348static struct platform_driver android_vibrator_driver = {
349 .probe = android_vibrator_probe,
350 .remove = android_vibrator_remove,
Devin Kim55468852012-06-19 12:01:32 -0700351 .driver = {
352 .name = "android-vibrator",
353 },
354};
355
356static int __init android_vibrator_init(void)
357{
Devin Kim55468852012-06-19 12:01:32 -0700358#ifdef ANDROID_VIBRATOR_USE_WORKQUEUE
359 vibrator_workqueue = create_workqueue("vibrator");
Devin Kim795a9a62012-08-28 10:08:46 -0700360 if (!vibrator_workqueue) {
361 pr_err("%s: out of memory\n", __func__);
Devin Kim55468852012-06-19 12:01:32 -0700362 return -ENOMEM;
Devin Kim795a9a62012-08-28 10:08:46 -0700363 }
Devin Kim55468852012-06-19 12:01:32 -0700364#endif
365 return platform_driver_register(&android_vibrator_driver);
Devin Kim55468852012-06-19 12:01:32 -0700366}
367
368static void __exit android_vibrator_exit(void)
369{
Devin Kim55468852012-06-19 12:01:32 -0700370#ifdef ANDROID_VIBRATOR_USE_WORKQUEUE
371 if (vibrator_workqueue)
372 destroy_workqueue(vibrator_workqueue);
Devin Kim55468852012-06-19 12:01:32 -0700373 vibrator_workqueue = NULL;
374#endif
375 platform_driver_unregister(&android_vibrator_driver);
Devin Kim55468852012-06-19 12:01:32 -0700376}
377
378late_initcall_sync(android_vibrator_init); /* to let init lately */
379module_exit(android_vibrator_exit);
380
381MODULE_AUTHOR("LG Electronics Inc.");
382MODULE_DESCRIPTION("Android Vibrator Driver");
383MODULE_LICENSE("GPL");