Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pm8xxx-vibrator.c
Go to the documentation of this file.
1 /* 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/platform_device.h>
18 #include <linux/input.h>
19 #include <linux/slab.h>
20 #include <linux/mfd/pm8xxx/core.h>
21 
22 #define VIB_DRV 0x4A
23 
24 #define VIB_DRV_SEL_MASK 0xf8
25 #define VIB_DRV_SEL_SHIFT 0x03
26 #define VIB_DRV_EN_MANUAL_MASK 0xfc
27 
28 #define VIB_MAX_LEVEL_mV (3100)
29 #define VIB_MIN_LEVEL_mV (1200)
30 #define VIB_MAX_LEVELS (VIB_MAX_LEVEL_mV - VIB_MIN_LEVEL_mV)
31 
32 #define MAX_FF_SPEED 0xff
33 
44 struct pm8xxx_vib {
45  struct input_dev *vib_input_dev;
46  struct work_struct work;
47  struct device *dev;
48  int speed;
49  int level;
50  bool active;
52 };
53 
60 static int pm8xxx_vib_read_u8(struct pm8xxx_vib *vib,
61  u8 *data, u16 reg)
62 {
63  int rc;
64 
65  rc = pm8xxx_readb(vib->dev->parent, reg, data);
66  if (rc < 0)
67  dev_warn(vib->dev, "Error reading pm8xxx reg 0x%x(0x%x)\n",
68  reg, rc);
69  return rc;
70 }
71 
78 static int pm8xxx_vib_write_u8(struct pm8xxx_vib *vib,
79  u8 data, u16 reg)
80 {
81  int rc;
82 
83  rc = pm8xxx_writeb(vib->dev->parent, reg, data);
84  if (rc < 0)
85  dev_warn(vib->dev, "Error writing pm8xxx reg 0x%x(0x%x)\n",
86  reg, rc);
87  return rc;
88 }
89 
95 static int pm8xxx_vib_set(struct pm8xxx_vib *vib, bool on)
96 {
97  int rc;
98  u8 val = vib->reg_vib_drv;
99 
100  if (on)
101  val |= ((vib->level << VIB_DRV_SEL_SHIFT) & VIB_DRV_SEL_MASK);
102  else
103  val &= ~VIB_DRV_SEL_MASK;
104 
105  rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
106  if (rc < 0)
107  return rc;
108 
109  vib->reg_vib_drv = val;
110  return 0;
111 }
112 
117 static void pm8xxx_work_handler(struct work_struct *work)
118 {
119  struct pm8xxx_vib *vib = container_of(work, struct pm8xxx_vib, work);
120  int rc;
121  u8 val;
122 
123  rc = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
124  if (rc < 0)
125  return;
126 
127  /*
128  * pmic vibrator supports voltage ranges from 1.2 to 3.1V, so
129  * scale the level to fit into these ranges.
130  */
131  if (vib->speed) {
132  vib->active = true;
133  vib->level = ((VIB_MAX_LEVELS * vib->speed) / MAX_FF_SPEED) +
135  vib->level /= 100;
136  } else {
137  vib->active = false;
138  vib->level = VIB_MIN_LEVEL_mV / 100;
139  }
140 
141  pm8xxx_vib_set(vib, vib->active);
142 }
143 
150 static void pm8xxx_vib_close(struct input_dev *dev)
151 {
152  struct pm8xxx_vib *vib = input_get_drvdata(dev);
153 
154  cancel_work_sync(&vib->work);
155  if (vib->active)
156  pm8xxx_vib_set(vib, false);
157 }
158 
167 static int pm8xxx_vib_play_effect(struct input_dev *dev, void *data,
168  struct ff_effect *effect)
169 {
170  struct pm8xxx_vib *vib = input_get_drvdata(dev);
171 
172  vib->speed = effect->u.rumble.strong_magnitude >> 8;
173  if (!vib->speed)
174  vib->speed = effect->u.rumble.weak_magnitude >> 9;
175 
176  schedule_work(&vib->work);
177 
178  return 0;
179 }
180 
181 static int __devinit pm8xxx_vib_probe(struct platform_device *pdev)
182 
183 {
184  struct pm8xxx_vib *vib;
185  struct input_dev *input_dev;
186  int error;
187  u8 val;
188 
189  vib = kzalloc(sizeof(*vib), GFP_KERNEL);
190  input_dev = input_allocate_device();
191  if (!vib || !input_dev) {
192  dev_err(&pdev->dev, "couldn't allocate memory\n");
193  error = -ENOMEM;
194  goto err_free_mem;
195  }
196 
197  INIT_WORK(&vib->work, pm8xxx_work_handler);
198  vib->dev = &pdev->dev;
199  vib->vib_input_dev = input_dev;
200 
201  /* operate in manual mode */
202  error = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
203  if (error < 0)
204  goto err_free_mem;
205  val &= ~VIB_DRV_EN_MANUAL_MASK;
206  error = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
207  if (error < 0)
208  goto err_free_mem;
209 
210  vib->reg_vib_drv = val;
211 
212  input_dev->name = "pm8xxx_vib_ffmemless";
213  input_dev->id.version = 1;
214  input_dev->dev.parent = &pdev->dev;
215  input_dev->close = pm8xxx_vib_close;
216  input_set_drvdata(input_dev, vib);
217  input_set_capability(vib->vib_input_dev, EV_FF, FF_RUMBLE);
218 
219  error = input_ff_create_memless(input_dev, NULL,
220  pm8xxx_vib_play_effect);
221  if (error) {
222  dev_err(&pdev->dev,
223  "couldn't register vibrator as FF device\n");
224  goto err_free_mem;
225  }
226 
227  error = input_register_device(input_dev);
228  if (error) {
229  dev_err(&pdev->dev, "couldn't register input device\n");
230  goto err_destroy_memless;
231  }
232 
233  platform_set_drvdata(pdev, vib);
234  return 0;
235 
236 err_destroy_memless:
237  input_ff_destroy(input_dev);
238 err_free_mem:
239  input_free_device(input_dev);
240  kfree(vib);
241 
242  return error;
243 }
244 
245 static int __devexit pm8xxx_vib_remove(struct platform_device *pdev)
246 {
247  struct pm8xxx_vib *vib = platform_get_drvdata(pdev);
248 
249  input_unregister_device(vib->vib_input_dev);
250  kfree(vib);
251 
252  platform_set_drvdata(pdev, NULL);
253 
254  return 0;
255 }
256 
257 #ifdef CONFIG_PM_SLEEP
258 static int pm8xxx_vib_suspend(struct device *dev)
259 {
260  struct pm8xxx_vib *vib = dev_get_drvdata(dev);
261 
262  /* Turn off the vibrator */
263  pm8xxx_vib_set(vib, false);
264 
265  return 0;
266 }
267 #endif
268 
269 static SIMPLE_DEV_PM_OPS(pm8xxx_vib_pm_ops, pm8xxx_vib_suspend, NULL);
270 
271 static struct platform_driver pm8xxx_vib_driver = {
272  .probe = pm8xxx_vib_probe,
273  .remove = __devexit_p(pm8xxx_vib_remove),
274  .driver = {
275  .name = "pm8xxx-vib",
276  .owner = THIS_MODULE,
277  .pm = &pm8xxx_vib_pm_ops,
278  },
279 };
280 module_platform_driver(pm8xxx_vib_driver);
281 
282 MODULE_ALIAS("platform:pm8xxx_vib");
283 MODULE_DESCRIPTION("PMIC8xxx vibrator driver based on ff-memless framework");
284 MODULE_LICENSE("GPL v2");
285 MODULE_AUTHOR("Amy Maloche <[email protected]>");