blob: 8aa7f723f22d2c8bdae9d73006f2acc6334f4cac [file] [log] [blame]
Anirudh Ghayalfcfbea62011-07-27 11:04:58 +05301/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/kernel.h>
16#include <linux/errno.h>
17#include <linux/interrupt.h>
18#include <linux/platform_device.h>
19#include <linux/slab.h>
20#include <linux/mfd/pm8xxx/core.h>
21#include <linux/mfd/pm8xxx/vibrator.h>
22
23#include "../staging/android/timed_output.h"
24
25#define VIB_DRV 0x4A
26
27#define VIB_DRV_SEL_MASK 0xf8
28#define VIB_DRV_SEL_SHIFT 0x03
29#define VIB_DRV_EN_MANUAL_MASK 0xfc
30
31#define VIB_MAX_LEVEL_mV 3100
32#define VIB_MIN_LEVEL_mV 1200
33
34struct pm8xxx_vib {
35 struct hrtimer vib_timer;
36 struct timed_output_dev timed_dev;
37 spinlock_t lock;
38 struct work_struct work;
39 struct device *dev;
40 const struct pm8xxx_vibrator_platform_data *pdata;
41 int state;
42 int level;
43 u8 reg_vib_drv;
44};
45
46/* REVISIT: just for debugging, will be removed in final working version */
47static void __dump_vib_regs(struct pm8xxx_vib *vib, char *msg)
48{
49 u8 temp;
50
51 dev_dbg(vib->dev, "%s\n", msg);
52
53 pm8xxx_readb(vib->dev->parent, VIB_DRV, &temp);
54 dev_dbg(vib->dev, "VIB_DRV - %X\n", temp);
55}
56
57static int pm8xxx_vib_read_u8(struct pm8xxx_vib *vib,
58 u8 *data, u16 reg)
59{
60 int rc;
61
62 rc = pm8xxx_readb(vib->dev->parent, reg, data);
63 if (rc < 0)
64 dev_warn(vib->dev, "Error reading pm8xxx: %X - ret %X\n",
65 reg, rc);
66
67 return rc;
68}
69
70static int pm8xxx_vib_write_u8(struct pm8xxx_vib *vib,
71 u8 data, u16 reg)
72{
73 int rc;
74
75 rc = pm8xxx_writeb(vib->dev->parent, reg, data);
76 if (rc < 0)
77 dev_warn(vib->dev, "Error writing pm8xxx: %X - ret %X\n",
78 reg, rc);
79 return rc;
80}
81
82static int pm8xxx_vib_set(struct pm8xxx_vib *vib, int on)
83{
84 int rc;
85 u8 val;
86
87 if (on) {
88 val = vib->reg_vib_drv;
89 val |= ((vib->level << VIB_DRV_SEL_SHIFT) & VIB_DRV_SEL_MASK);
90 rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
91 if (rc < 0)
92 return rc;
93 vib->reg_vib_drv = val;
94 } else {
95 val = vib->reg_vib_drv;
96 val &= ~VIB_DRV_SEL_MASK;
97 rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
98 if (rc < 0)
99 return rc;
100 vib->reg_vib_drv = val;
101 }
102 __dump_vib_regs(vib, "vib_set_end");
103
104 return rc;
105}
106
107static void pm8xxx_vib_enable(struct timed_output_dev *dev, int value)
108{
109 struct pm8xxx_vib *vib = container_of(dev, struct pm8xxx_vib,
110 timed_dev);
111 unsigned long flags;
112
113 spin_lock_irqsave(&vib->lock, flags);
114
115retry:
116 if (hrtimer_try_to_cancel(&vib->vib_timer) < 0) {
117 spin_unlock_irqrestore(&vib->lock, flags);
118 cpu_relax();
119 goto retry;
120 }
121
122 if (value == 0)
123 vib->state = 0;
124 else {
125 value = (value > vib->pdata->max_timeout_ms ?
126 vib->pdata->max_timeout_ms : value);
127 vib->state = 1;
128 hrtimer_start(&vib->vib_timer,
129 ktime_set(value / 1000, (value % 1000) * 1000000),
130 HRTIMER_MODE_REL);
131 }
132 spin_unlock_irqrestore(&vib->lock, flags);
133 schedule_work(&vib->work);
134}
135
136static void pm8xxx_vib_update(struct work_struct *work)
137{
138 struct pm8xxx_vib *vib = container_of(work, struct pm8xxx_vib,
139 work);
140
141 pm8xxx_vib_set(vib, vib->state);
142}
143
144static int pm8xxx_vib_get_time(struct timed_output_dev *dev)
145{
146 struct pm8xxx_vib *vib = container_of(dev, struct pm8xxx_vib,
147 timed_dev);
148
149 if (hrtimer_active(&vib->vib_timer)) {
150 ktime_t r = hrtimer_get_remaining(&vib->vib_timer);
151 return (int)ktime_to_us(r);
152 } else
153 return 0;
154}
155
156static enum hrtimer_restart pm8xxx_vib_timer_func(struct hrtimer *timer)
157{
158 struct pm8xxx_vib *vib = container_of(timer, struct pm8xxx_vib,
159 vib_timer);
160
161 vib->state = 0;
162 schedule_work(&vib->work);
163
164 return HRTIMER_NORESTART;
165}
166
167#ifdef CONFIG_PM
168static int pm8xxx_vib_suspend(struct device *dev)
169{
170 struct pm8xxx_vib *vib = dev_get_drvdata(dev);
171
172 hrtimer_cancel(&vib->vib_timer);
173 cancel_work_sync(&vib->work);
174 /* turn-off vibrator */
175 pm8xxx_vib_set(vib, 0);
176
177 return 0;
178}
179
180static const struct dev_pm_ops pm8xxx_vib_pm_ops = {
181 .suspend = pm8xxx_vib_suspend,
182};
183#endif
184
185static int __devinit pm8xxx_vib_probe(struct platform_device *pdev)
186
187{
188 const struct pm8xxx_vibrator_platform_data *pdata =
189 pdev->dev.platform_data;
190 struct pm8xxx_vib *vib;
191 u8 val;
192 int rc;
193
194 if (!pdata)
195 return -EINVAL;
196
197 if (pdata->level_mV < VIB_MIN_LEVEL_mV ||
198 pdata->level_mV > VIB_MAX_LEVEL_mV)
199 return -EINVAL;
200
201 vib = kzalloc(sizeof(*vib), GFP_KERNEL);
202 if (!vib)
203 return -ENOMEM;
204
205 vib->pdata = pdata;
206 vib->level = pdata->level_mV / 100;
207 vib->dev = &pdev->dev;
208
209 spin_lock_init(&vib->lock);
210 INIT_WORK(&vib->work, pm8xxx_vib_update);
211
212 hrtimer_init(&vib->vib_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
213 vib->vib_timer.function = pm8xxx_vib_timer_func;
214
215 vib->timed_dev.name = "vibrator";
216 vib->timed_dev.get_time = pm8xxx_vib_get_time;
217 vib->timed_dev.enable = pm8xxx_vib_enable;
218
219 __dump_vib_regs(vib, "boot_vib_default");
220
221 /*
222 * Configure the vibrator, it operates in manual mode
223 * for timed_output framework.
224 */
225 rc = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
226 if (rc < 0)
227 goto err_read_vib;
228 val &= ~VIB_DRV_EN_MANUAL_MASK;
229 rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
230 if (rc < 0)
231 goto err_read_vib;
232
233 vib->reg_vib_drv = val;
234
235 rc = timed_output_dev_register(&vib->timed_dev);
236 if (rc < 0)
237 goto err_read_vib;
238
239 pm8xxx_vib_enable(&vib->timed_dev, pdata->initial_vibrate_ms);
240
241 platform_set_drvdata(pdev, vib);
242
243 return 0;
244
245err_read_vib:
246 kfree(vib);
247 return rc;
248}
249
250static int __devexit pm8xxx_vib_remove(struct platform_device *pdev)
251{
252 struct pm8xxx_vib *vib = platform_get_drvdata(pdev);
253
254 cancel_work_sync(&vib->work);
255 hrtimer_cancel(&vib->vib_timer);
256 timed_output_dev_unregister(&vib->timed_dev);
257 platform_set_drvdata(pdev, NULL);
258 kfree(vib);
259
260 return 0;
261}
262
263static struct platform_driver pm8xxx_vib_driver = {
264 .probe = pm8xxx_vib_probe,
265 .remove = __devexit_p(pm8xxx_vib_remove),
266 .driver = {
267 .name = PM8XXX_VIBRATOR_DEV_NAME,
268 .owner = THIS_MODULE,
269#ifdef CONFIG_PM
270 .pm = &pm8xxx_vib_pm_ops,
271#endif
272 },
273};
274
275static int __init pm8xxx_vib_init(void)
276{
277 return platform_driver_register(&pm8xxx_vib_driver);
278}
279module_init(pm8xxx_vib_init);
280
281static void __exit pm8xxx_vib_exit(void)
282{
283 platform_driver_unregister(&pm8xxx_vib_driver);
284}
285module_exit(pm8xxx_vib_exit);
286
287MODULE_ALIAS("platform:" PM8XXX_VIBRATOR_DEV_NAME);
288MODULE_DESCRIPTION("pm8xxx vibrator driver");
289MODULE_LICENSE("GPL v2");