blob: 0b423c2d3d93c750c4c81e7c43cca298baa1c446 [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
57static inline void vibrator_work(struct work_struct *work)
58{
59 if (!work_pending(work))
60 queue_work(vibrator_workqueue, work);
61}
62
63#else
64static inline void vibrator_work(struct work_struct *work)
65{
66 if (!work_pending(work))
67 schedule_work(work);
68}
69#endif
70
71static DEFINE_MUTEX(vib_lock);
72
Devin Kim55468852012-06-19 12:01:32 -070073static int android_vibrator_force_set(struct timed_vibrator_data *vib,
Devin Kim795a9a62012-08-28 10:08:46 -070074 int intensity, int pwm)
Devin Kim55468852012-06-19 12:01:32 -070075{
Devin Kim7eb84ca2012-09-14 16:16:13 -070076 struct android_vibrator_platform_data *pdata = vib->pdata;
Devin Kim795a9a62012-08-28 10:08:46 -070077 int vib_duration_ms = 0;
Devin Kim7eb84ca2012-09-14 16:16:13 -070078
Devin Kim795a9a62012-08-28 10:08:46 -070079 pr_debug("%s: intensity : %d\n", __func__, intensity);
Devin Kim55468852012-06-19 12:01:32 -070080
Devin Kim7eb84ca2012-09-14 16:16:13 -070081 /* Check the Force value with Max and Min force value */
Devin Kim795a9a62012-08-28 10:08:46 -070082 if (intensity > 127)
83 intensity = 127;
84 if (intensity < -127)
85 intensity = -127;
Devin Kim55468852012-06-19 12:01:32 -070086
Devin Kima66ff762012-09-13 14:44:22 -070087 mutex_lock(&vib_lock);
88
Devin Kim7eb84ca2012-09-14 16:16:13 -070089 if (pdata->vibe_warmup_delay > 0) {
90 if (atomic_read(&vib->vib_status))
91 msleep(pdata->vibe_warmup_delay);
92 }
93
Devin Kim55468852012-06-19 12:01:32 -070094 /* TODO: control the gain of vibrator */
Devin Kim795a9a62012-08-28 10:08:46 -070095 if (intensity == 0) {
Devin Kim7eb84ca2012-09-14 16:16:13 -070096 pdata->ic_enable_set(0);
97 pdata->pwm_set(0, 0, pwm);
Devin Kim55468852012-06-19 12:01:32 -070098 /* should be checked for vibrator response time */
Devin Kim7eb84ca2012-09-14 16:16:13 -070099 pdata->power_set(0);
Devin Kima66ff762012-09-13 14:44:22 -0700100 atomic_set(&vib->vib_status, 0);
Devin Kim55468852012-06-19 12:01:32 -0700101 } else {
Devin Kima66ff762012-09-13 14:44:22 -0700102 if (work_pending(&vib->work_vibrator_off))
103 cancel_work_sync(&vib->work_vibrator_off);
Devin Kim55468852012-06-19 12:01:32 -0700104 hrtimer_cancel(&vib->timer);
Devin Kima66ff762012-09-13 14:44:22 -0700105
Devin Kim795a9a62012-08-28 10:08:46 -0700106 vib_duration_ms = atomic_read(&vib->ms_time);
Devin Kim55468852012-06-19 12:01:32 -0700107 /* should be checked for vibrator response time */
Devin Kim7eb84ca2012-09-14 16:16:13 -0700108 pdata->power_set(1);
109 pdata->pwm_set(1, intensity, pwm);
110 pdata->ic_enable_set(1);
Devin Kima66ff762012-09-13 14:44:22 -0700111 atomic_set(&vib->vib_status, 1);
Devin Kim55468852012-06-19 12:01:32 -0700112
Devin Kim55468852012-06-19 12:01:32 -0700113 hrtimer_start(&vib->timer,
Devin Kim795a9a62012-08-28 10:08:46 -0700114 ns_to_ktime((u64)vib_duration_ms * NSEC_PER_MSEC),
Devin Kim55468852012-06-19 12:01:32 -0700115 HRTIMER_MODE_REL);
116 }
Devin Kima66ff762012-09-13 14:44:22 -0700117
118 mutex_unlock(&vib_lock);
119
Devin Kim55468852012-06-19 12:01:32 -0700120 return 0;
121}
122
123static void android_vibrator_on(struct work_struct *work)
124{
125 struct timed_vibrator_data *vib =
126 container_of(work, struct timed_vibrator_data,
127 work_vibrator_on);
Devin Kim795a9a62012-08-28 10:08:46 -0700128 int gain = atomic_read(&vib->gain);
129 int pwm = atomic_read(&vib->pwm);
Devin Kim55468852012-06-19 12:01:32 -0700130 /* suspend /resume logging test */
Devin Kim795a9a62012-08-28 10:08:46 -0700131 pr_debug("%s: gain = %d pwm = %d\n", __func__,
132 gain, pwm);
Devin Kim55468852012-06-19 12:01:32 -0700133
Devin Kim795a9a62012-08-28 10:08:46 -0700134 android_vibrator_force_set(vib, gain, pwm);
Devin Kim55468852012-06-19 12:01:32 -0700135}
136
137static void android_vibrator_off(struct work_struct *work)
138{
139 struct timed_vibrator_data *vib =
140 container_of(work, struct timed_vibrator_data,
141 work_vibrator_off);
142
Devin Kim795a9a62012-08-28 10:08:46 -0700143 pr_debug("%s\n", __func__);
144 android_vibrator_force_set(vib, 0, vib->pdata->vibe_n_value);
Devin Kim55468852012-06-19 12:01:32 -0700145}
146
147static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)
148{
149 struct timed_vibrator_data *vib =
150 container_of(timer, struct timed_vibrator_data, timer);
Devin Kima66ff762012-09-13 14:44:22 -0700151 vibrator_work(&vib->work_vibrator_off);
Devin Kim55468852012-06-19 12:01:32 -0700152 return HRTIMER_NORESTART;
153}
154
155static int vibrator_get_time(struct timed_output_dev *dev)
156{
157 struct timed_vibrator_data *vib =
158 container_of(dev, struct timed_vibrator_data, dev);
159
160 if (hrtimer_active(&vib->timer)) {
161 ktime_t r = hrtimer_get_remaining(&vib->timer);
162 return ktime_to_ms(r);
163 }
164
165 return 0;
166}
167
Devin Kim795a9a62012-08-28 10:08:46 -0700168static void vibrator_enable(struct timed_output_dev *dev, int ms_time)
Devin Kim55468852012-06-19 12:01:32 -0700169{
170 struct timed_vibrator_data *vib =
171 container_of(dev, struct timed_vibrator_data, dev);
172 unsigned long flags;
173
Devin Kim795a9a62012-08-28 10:08:46 -0700174 pr_debug("%s: ms_time %d \n", __func__, ms_time);
Devin Kim55468852012-06-19 12:01:32 -0700175 spin_lock_irqsave(&vib->lock, flags);
176
Devin Kim795a9a62012-08-28 10:08:46 -0700177 if (ms_time > 0) {
178 if (ms_time > vib->max_timeout)
179 ms_time = vib->max_timeout;
Devin Kim55468852012-06-19 12:01:32 -0700180
Devin Kim795a9a62012-08-28 10:08:46 -0700181 atomic_set(&vib->ms_time, ms_time);
Devin Kim55468852012-06-19 12:01:32 -0700182
Devin Kima66ff762012-09-13 14:44:22 -0700183 vibrator_work(&vib->work_vibrator_on);
Devin Kim55468852012-06-19 12:01:32 -0700184 } else {
Devin Kima66ff762012-09-13 14:44:22 -0700185 vibrator_work(&vib->work_vibrator_off);
Devin Kim55468852012-06-19 12:01:32 -0700186 }
187 spin_unlock_irqrestore(&vib->lock, flags);
Devin Kim55468852012-06-19 12:01:32 -0700188}
189
190static ssize_t vibrator_amp_show(struct device *dev,
191 struct device_attribute *attr, char *buf)
192{
193 struct timed_output_dev *dev_ =
194 (struct timed_output_dev *)dev_get_drvdata(dev);
195 struct timed_vibrator_data *vib =
196 container_of(dev_, struct timed_vibrator_data, dev);
Devin Kim795a9a62012-08-28 10:08:46 -0700197 int gain = atomic_read(&(vib->gain));
Devin Kim55468852012-06-19 12:01:32 -0700198
199 return sprintf(buf, "%d\n", gain);
200}
201
202static ssize_t vibrator_amp_store(struct device *dev,
203 struct device_attribute *attr, const char *buf, size_t size)
204{
205 struct timed_output_dev *dev_ =
206 (struct timed_output_dev *)dev_get_drvdata(dev);
207 struct timed_vibrator_data *vib =
208 container_of(dev_, struct timed_vibrator_data, dev);
209
210 int gain;
211 sscanf(buf, "%d", &gain);
Devin Kim795a9a62012-08-28 10:08:46 -0700212 atomic_set(&vib->gain, gain);
Devin Kim55468852012-06-19 12:01:32 -0700213
214 return size;
215}
216
217static ssize_t vibrator_pwm_show(struct device *dev,
218 struct device_attribute *attr, char *buf)
219{
220 struct timed_output_dev *dev_ =
221 (struct timed_output_dev *)dev_get_drvdata(dev);
222 struct timed_vibrator_data *vib =
223 container_of(dev_, struct timed_vibrator_data, dev);
Devin Kim795a9a62012-08-28 10:08:46 -0700224 int gain = atomic_read(&(vib->pwm));
Devin Kim55468852012-06-19 12:01:32 -0700225
226 gain = 4800/gain;
227
228 return sprintf(buf, "%d\n", gain);
229}
230
Devin Kim795a9a62012-08-28 10:08:46 -0700231
Devin Kim55468852012-06-19 12:01:32 -0700232static ssize_t vibrator_pwm_store(struct device *dev,
233 struct device_attribute *attr, const char *buf, size_t size)
234{
235 struct timed_output_dev *dev_ =
236 (struct timed_output_dev *)dev_get_drvdata(dev);
237 struct timed_vibrator_data *vib =
238 container_of(dev_, struct timed_vibrator_data, dev);
239
240 int gain;
241 sscanf(buf, "%d", &gain);
242
243 gain = 4800/gain;
244
Devin Kim795a9a62012-08-28 10:08:46 -0700245 atomic_set(&vib->pwm, gain);
Devin Kim55468852012-06-19 12:01:32 -0700246
247 return size;
248}
249
Devin Kim795a9a62012-08-28 10:08:46 -0700250static struct device_attribute android_vibrator_device_attrs[] = {
Devin Kim55468852012-06-19 12:01:32 -0700251 __ATTR(amp, S_IRUGO | S_IWUSR, vibrator_amp_show, vibrator_amp_store),
252 __ATTR(pwm, S_IRUGO | S_IWUSR, vibrator_pwm_show, vibrator_pwm_store),
253};
254
255struct timed_vibrator_data android_vibrator_data = {
256 .dev.name = "vibrator",
257 .dev.enable = vibrator_enable,
258 .dev.get_time = vibrator_get_time,
259 .max_timeout = 30000, /* max time for vibrator enable 30 sec. */
Devin Kim55468852012-06-19 12:01:32 -0700260};
261
262static int android_vibrator_probe(struct platform_device *pdev)
263{
264
265 int i, ret = 0;
Devin Kim795a9a62012-08-28 10:08:46 -0700266 struct timed_vibrator_data *vib = &android_vibrator_data;
267 vib->pdata = pdev->dev.platform_data;
Devin Kim55468852012-06-19 12:01:32 -0700268
Devin Kim795a9a62012-08-28 10:08:46 -0700269 if (!vib->pdata) {
270 pr_err("%s: no platform data\n", __func__);
Devin Kim55468852012-06-19 12:01:32 -0700271 return -ENODEV;
272 }
273
Devin Kim795a9a62012-08-28 10:08:46 -0700274 if (vib->pdata->vibrator_init) {
275 ret = vib->pdata->vibrator_init();
276 if (ret < 0) {
277 pr_err("%s: failed to vibrator init\n", __func__);
278 return ret;
279 }
280 }
281
282 platform_set_drvdata(pdev, &android_vibrator_data);
283
284 atomic_set(&vib->gain, vib->pdata->amp); /* max value is 128 */
285 atomic_set(&vib->pwm, vib->pdata->vibe_n_value);
Devin Kima66ff762012-09-13 14:44:22 -0700286 atomic_set(&vib->vib_status, 0);
Devin Kim795a9a62012-08-28 10:08:46 -0700287 pr_info("android_vibrator: default amplitude %d \n",
288 vib->pdata->amp);
Devin Kim55468852012-06-19 12:01:32 -0700289
290 INIT_WORK(&vib->work_vibrator_off, android_vibrator_off);
291 INIT_WORK(&vib->work_vibrator_on, android_vibrator_on);
292 hrtimer_init(&vib->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
293 vib->timer.function = vibrator_timer_func;
294 spin_lock_init(&vib->lock);
295
296 ret = timed_output_dev_register(&vib->dev);
297 if (ret < 0) {
Devin Kim795a9a62012-08-28 10:08:46 -0700298 pr_err("%s: failed to register timed output device\n",
299 __func__);
300 return ret;
Devin Kim55468852012-06-19 12:01:32 -0700301 }
Devin Kim795a9a62012-08-28 10:08:46 -0700302
303 for (i = 0; i < ARRAY_SIZE(android_vibrator_device_attrs); i++) {
304 ret = device_create_file(vib->dev.dev,
305 &android_vibrator_device_attrs[i]);
Devin Kim55468852012-06-19 12:01:32 -0700306 if (ret < 0) {
Devin Kim795a9a62012-08-28 10:08:46 -0700307 pr_err("%s: failed to create sysfs\n", __func__);
308 goto err_sysfs;
Devin Kim55468852012-06-19 12:01:32 -0700309 }
310 }
311
Devin Kim795a9a62012-08-28 10:08:46 -0700312 pr_info("android vibrator probed\n");
Devin Kim55468852012-06-19 12:01:32 -0700313
314 return 0;
Devin Kim795a9a62012-08-28 10:08:46 -0700315
316err_sysfs:
317 for (; i >= 0; i--) {
318 device_remove_file(vib->dev.dev,
319 &android_vibrator_device_attrs[i]);
320 }
321
322 timed_output_dev_unregister(&vib->dev);
323 return ret;
Devin Kim55468852012-06-19 12:01:32 -0700324}
325
326static int android_vibrator_remove(struct platform_device *pdev)
327{
328 struct timed_vibrator_data *vib =
329 (struct timed_vibrator_data *)platform_get_drvdata(pdev);
Devin Kim795a9a62012-08-28 10:08:46 -0700330 int i;
Devin Kim55468852012-06-19 12:01:32 -0700331
Devin Kima66ff762012-09-13 14:44:22 -0700332 vibrator_work(&vib->work_vibrator_off);
Devin Kim795a9a62012-08-28 10:08:46 -0700333 for (i = ARRAY_SIZE(android_vibrator_device_attrs); i >= 0; i--) {
334 device_remove_file(vib->dev.dev,
335 &android_vibrator_device_attrs[i]);
336 }
Devin Kim55468852012-06-19 12:01:32 -0700337
338 timed_output_dev_unregister(&vib->dev);
339
340 return 0;
341}
342
Devin Kim55468852012-06-19 12:01:32 -0700343static struct platform_driver android_vibrator_driver = {
344 .probe = android_vibrator_probe,
345 .remove = android_vibrator_remove,
Devin Kim55468852012-06-19 12:01:32 -0700346 .driver = {
347 .name = "android-vibrator",
348 },
349};
350
351static int __init android_vibrator_init(void)
352{
Devin Kim55468852012-06-19 12:01:32 -0700353#ifdef ANDROID_VIBRATOR_USE_WORKQUEUE
354 vibrator_workqueue = create_workqueue("vibrator");
Devin Kim795a9a62012-08-28 10:08:46 -0700355 if (!vibrator_workqueue) {
356 pr_err("%s: out of memory\n", __func__);
Devin Kim55468852012-06-19 12:01:32 -0700357 return -ENOMEM;
Devin Kim795a9a62012-08-28 10:08:46 -0700358 }
Devin Kim55468852012-06-19 12:01:32 -0700359#endif
360 return platform_driver_register(&android_vibrator_driver);
Devin Kim55468852012-06-19 12:01:32 -0700361}
362
363static void __exit android_vibrator_exit(void)
364{
Devin Kim55468852012-06-19 12:01:32 -0700365#ifdef ANDROID_VIBRATOR_USE_WORKQUEUE
366 if (vibrator_workqueue)
367 destroy_workqueue(vibrator_workqueue);
Devin Kim55468852012-06-19 12:01:32 -0700368 vibrator_workqueue = NULL;
369#endif
370 platform_driver_unregister(&android_vibrator_driver);
Devin Kim55468852012-06-19 12:01:32 -0700371}
372
373late_initcall_sync(android_vibrator_init); /* to let init lately */
374module_exit(android_vibrator_exit);
375
376MODULE_AUTHOR("LG Electronics Inc.");
377MODULE_DESCRIPTION("Android Vibrator Driver");
378MODULE_LICENSE("GPL");