Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
max8997_haptic.c
Go to the documentation of this file.
1 /*
2  * MAX8997-haptic controller driver
3  *
4  * Copyright (C) 2012 Samsung Electronics
5  * Donggeun Kim <[email protected]>
6  *
7  * This program is not provided / owned by Maxim Integrated Products.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  *
23  */
24 
25 #include <linux/module.h>
26 #include <linux/init.h>
27 #include <linux/slab.h>
28 #include <linux/platform_device.h>
29 #include <linux/err.h>
30 #include <linux/pwm.h>
31 #include <linux/input.h>
33 #include <linux/mfd/max8997.h>
35 
36 /* Haptic configuration 2 register */
37 #define MAX8997_MOTOR_TYPE_SHIFT 7
38 #define MAX8997_ENABLE_SHIFT 6
39 #define MAX8997_MODE_SHIFT 5
40 
41 /* Haptic driver configuration register */
42 #define MAX8997_CYCLE_SHIFT 6
43 #define MAX8997_SIG_PERIOD_SHIFT 4
44 #define MAX8997_SIG_DUTY_SHIFT 2
45 #define MAX8997_PWM_DUTY_SHIFT 0
46 
48  struct device *dev;
49  struct i2c_client *client;
52 
53  struct work_struct work;
54  struct mutex mutex;
55 
56  bool enabled;
57  unsigned int level;
58 
59  struct pwm_device *pwm;
60  unsigned int pwm_period;
62 
65 
66  unsigned int internal_mode_pattern;
67  unsigned int pattern_cycle;
68  unsigned int pattern_signal_period;
69 };
70 
71 static int max8997_haptic_set_duty_cycle(struct max8997_haptic *chip)
72 {
73  int ret = 0;
74 
75  if (chip->mode == MAX8997_EXTERNAL_MODE) {
76  unsigned int duty = chip->pwm_period * chip->level / 100;
77  ret = pwm_config(chip->pwm, duty, chip->pwm_period);
78  } else {
79  int i;
80  u8 duty_index = 0;
81 
82  for (i = 0; i <= 64; i++) {
83  if (chip->level <= i * 100 / 64) {
84  duty_index = i;
85  break;
86  }
87  }
88  switch (chip->internal_mode_pattern) {
89  case 0:
91  MAX8997_HAPTIC_REG_SIGPWMDC1, duty_index);
92  break;
93  case 1:
95  MAX8997_HAPTIC_REG_SIGPWMDC2, duty_index);
96  break;
97  case 2:
99  MAX8997_HAPTIC_REG_SIGPWMDC3, duty_index);
100  break;
101  case 3:
103  MAX8997_HAPTIC_REG_SIGPWMDC4, duty_index);
104  break;
105  default:
106  break;
107  }
108  }
109  return ret;
110 }
111 
112 static void max8997_haptic_configure(struct max8997_haptic *chip)
113 {
114  u8 value;
115 
116  value = chip->type << MAX8997_MOTOR_TYPE_SHIFT |
117  chip->enabled << MAX8997_ENABLE_SHIFT |
118  chip->mode << MAX8997_MODE_SHIFT | chip->pwm_divisor;
120 
121  if (chip->mode == MAX8997_INTERNAL_MODE && chip->enabled) {
122  value = chip->internal_mode_pattern << MAX8997_CYCLE_SHIFT |
128 
129  switch (chip->internal_mode_pattern) {
130  case 0:
131  value = chip->pattern_cycle << 4;
134  value = chip->pattern_signal_period;
137  break;
138 
139  case 1:
140  value = chip->pattern_cycle;
143  value = chip->pattern_signal_period;
146  break;
147 
148  case 2:
149  value = chip->pattern_cycle << 4;
152  value = chip->pattern_signal_period;
155  break;
156 
157  case 3:
158  value = chip->pattern_cycle;
161  value = chip->pattern_signal_period;
164  break;
165 
166  default:
167  break;
168  }
169  }
170 }
171 
172 static void max8997_haptic_enable(struct max8997_haptic *chip)
173 {
174  int error;
175 
176  mutex_lock(&chip->mutex);
177 
178  error = max8997_haptic_set_duty_cycle(chip);
179  if (error) {
180  dev_err(chip->dev, "set_pwm_cycle failed, error: %d\n", error);
181  goto out;
182  }
183 
184  if (!chip->enabled) {
185  chip->enabled = true;
187  max8997_haptic_configure(chip);
188  if (chip->mode == MAX8997_EXTERNAL_MODE)
189  pwm_enable(chip->pwm);
190  }
191 
192 out:
193  mutex_unlock(&chip->mutex);
194 }
195 
196 static void max8997_haptic_disable(struct max8997_haptic *chip)
197 {
198  mutex_lock(&chip->mutex);
199 
200  if (chip->enabled) {
201  chip->enabled = false;
202  max8997_haptic_configure(chip);
203  if (chip->mode == MAX8997_EXTERNAL_MODE)
204  pwm_disable(chip->pwm);
206  }
207 
208  mutex_unlock(&chip->mutex);
209 }
210 
211 static void max8997_haptic_play_effect_work(struct work_struct *work)
212 {
213  struct max8997_haptic *chip =
214  container_of(work, struct max8997_haptic, work);
215 
216  if (chip->level)
217  max8997_haptic_enable(chip);
218  else
219  max8997_haptic_disable(chip);
220 }
221 
222 static int max8997_haptic_play_effect(struct input_dev *dev, void *data,
223  struct ff_effect *effect)
224 {
225  struct max8997_haptic *chip = input_get_drvdata(dev);
226 
227  chip->level = effect->u.rumble.strong_magnitude;
228  if (!chip->level)
229  chip->level = effect->u.rumble.weak_magnitude;
230 
231  schedule_work(&chip->work);
232 
233  return 0;
234 }
235 
236 static void max8997_haptic_close(struct input_dev *dev)
237 {
238  struct max8997_haptic *chip = input_get_drvdata(dev);
239 
240  cancel_work_sync(&chip->work);
241  max8997_haptic_disable(chip);
242 }
243 
244 static int __devinit max8997_haptic_probe(struct platform_device *pdev)
245 {
246  struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
247  const struct max8997_platform_data *pdata =
248  dev_get_platdata(iodev->dev);
249  const struct max8997_haptic_platform_data *haptic_pdata =
250  pdata->haptic_pdata;
251  struct max8997_haptic *chip;
252  struct input_dev *input_dev;
253  int error;
254 
255  if (!haptic_pdata) {
256  dev_err(&pdev->dev, "no haptic platform data\n");
257  return -EINVAL;
258  }
259 
260  chip = kzalloc(sizeof(struct max8997_haptic), GFP_KERNEL);
261  input_dev = input_allocate_device();
262  if (!chip || !input_dev) {
263  dev_err(&pdev->dev, "unable to allocate memory\n");
264  error = -ENOMEM;
265  goto err_free_mem;
266  }
267 
268  INIT_WORK(&chip->work, max8997_haptic_play_effect_work);
269  mutex_init(&chip->mutex);
270 
271  chip->client = iodev->haptic;
272  chip->dev = &pdev->dev;
273  chip->input_dev = input_dev;
274  chip->pwm_period = haptic_pdata->pwm_period;
275  chip->type = haptic_pdata->type;
276  chip->mode = haptic_pdata->mode;
277  chip->pwm_divisor = haptic_pdata->pwm_divisor;
278 
279  switch (chip->mode) {
281  chip->internal_mode_pattern =
282  haptic_pdata->internal_mode_pattern;
283  chip->pattern_cycle = haptic_pdata->pattern_cycle;
284  chip->pattern_signal_period =
285  haptic_pdata->pattern_signal_period;
286  break;
287 
289  chip->pwm = pwm_request(haptic_pdata->pwm_channel_id,
290  "max8997-haptic");
291  if (IS_ERR(chip->pwm)) {
292  error = PTR_ERR(chip->pwm);
293  dev_err(&pdev->dev,
294  "unable to request PWM for haptic, error: %d\n",
295  error);
296  goto err_free_mem;
297  }
298  break;
299 
300  default:
301  dev_err(&pdev->dev,
302  "Invalid chip mode specified (%d)\n", chip->mode);
303  error = -EINVAL;
304  goto err_free_mem;
305  }
306 
307  chip->regulator = regulator_get(&pdev->dev, "inmotor");
308  if (IS_ERR(chip->regulator)) {
309  error = PTR_ERR(chip->regulator);
310  dev_err(&pdev->dev,
311  "unable to get regulator, error: %d\n",
312  error);
313  goto err_free_pwm;
314  }
315 
316  input_dev->name = "max8997-haptic";
317  input_dev->id.version = 1;
318  input_dev->dev.parent = &pdev->dev;
319  input_dev->close = max8997_haptic_close;
320  input_set_drvdata(input_dev, chip);
321  input_set_capability(input_dev, EV_FF, FF_RUMBLE);
322 
323  error = input_ff_create_memless(input_dev, NULL,
324  max8997_haptic_play_effect);
325  if (error) {
326  dev_err(&pdev->dev,
327  "unable to create FF device, error: %d\n",
328  error);
329  goto err_put_regulator;
330  }
331 
332  error = input_register_device(input_dev);
333  if (error) {
334  dev_err(&pdev->dev,
335  "unable to register input device, error: %d\n",
336  error);
337  goto err_destroy_ff;
338  }
339 
340  platform_set_drvdata(pdev, chip);
341  return 0;
342 
343 err_destroy_ff:
344  input_ff_destroy(input_dev);
345 err_put_regulator:
346  regulator_put(chip->regulator);
347 err_free_pwm:
348  if (chip->mode == MAX8997_EXTERNAL_MODE)
349  pwm_free(chip->pwm);
350 err_free_mem:
351  input_free_device(input_dev);
352  kfree(chip);
353 
354  return error;
355 }
356 
357 static int __devexit max8997_haptic_remove(struct platform_device *pdev)
358 {
359  struct max8997_haptic *chip = platform_get_drvdata(pdev);
360 
361  input_unregister_device(chip->input_dev);
362  regulator_put(chip->regulator);
363 
364  if (chip->mode == MAX8997_EXTERNAL_MODE)
365  pwm_free(chip->pwm);
366 
367  kfree(chip);
368 
369  return 0;
370 }
371 
372 #ifdef CONFIG_PM_SLEEP
373 static int max8997_haptic_suspend(struct device *dev)
374 {
375  struct platform_device *pdev = to_platform_device(dev);
376  struct max8997_haptic *chip = platform_get_drvdata(pdev);
377 
378  max8997_haptic_disable(chip);
379 
380  return 0;
381 }
382 #endif
383 
384 static SIMPLE_DEV_PM_OPS(max8997_haptic_pm_ops, max8997_haptic_suspend, NULL);
385 
386 static const struct platform_device_id max8997_haptic_id[] = {
387  { "max8997-haptic", 0 },
388  { },
389 };
390 MODULE_DEVICE_TABLE(i2c, max8997_haptic_id);
391 
392 static struct platform_driver max8997_haptic_driver = {
393  .driver = {
394  .name = "max8997-haptic",
395  .owner = THIS_MODULE,
396  .pm = &max8997_haptic_pm_ops,
397  },
398  .probe = max8997_haptic_probe,
399  .remove = __devexit_p(max8997_haptic_remove),
400  .id_table = max8997_haptic_id,
401 };
402 module_platform_driver(max8997_haptic_driver);
403 
404 MODULE_ALIAS("platform:max8997-haptic");
405 MODULE_AUTHOR("Donggeun Kim <[email protected]>");
406 MODULE_DESCRIPTION("max8997_haptic driver");
407 MODULE_LICENSE("GPL");