blob: 555dfdd2d09237693c57e7a168f404c9c66747b4 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/*
2 * isa1200.c - Haptic Motor
3 *
4 * Copyright (C) 2009 Samsung Electronics
5 * Kyungmin Park <kyungmin.park@samsung.com>
Mohan Pallakaace9fa92012-05-11 13:05:40 +05306 * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/i2c.h>
16#include <linux/gpio.h>
17#include <linux/delay.h>
18#include <linux/err.h>
19#include <linux/pwm.h>
20#include <linux/workqueue.h>
21#include <linux/slab.h>
Mohan Pallaka73787fa2011-09-09 15:14:20 +053022#include <linux/regulator/consumer.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070023#include <linux/i2c/isa1200.h>
24#include "../staging/android/timed_output.h"
25
26#define ISA1200_HCTRL0 0x30
27#define ISA1200_HCTRL1 0x31
28#define ISA1200_HCTRL5 0x35
29
30#define ISA1200_HCTRL0_RESET 0x01
31#define ISA1200_HCTRL1_RESET 0x4B
32
33#define ISA1200_HCTRL5_VIB_STRT 0xD5
34#define ISA1200_HCTRL5_VIB_STOP 0x6B
Mohan Pallakaace9fa92012-05-11 13:05:40 +053035#define ISA1200_POWER_DOWN_MASK 0x7F
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070036
37struct isa1200_chip {
38 struct i2c_client *client;
39 struct isa1200_platform_data *pdata;
40 struct pwm_device *pwm;
41 struct hrtimer timer;
42 struct timed_output_dev dev;
43 struct work_struct work;
44 spinlock_t lock;
45 unsigned int enable;
46 unsigned int period_ns;
Mohan Pallaka73787fa2011-09-09 15:14:20 +053047 bool is_len_gpio_valid;
48 struct regulator **regs;
Mohan Pallakaace9fa92012-05-11 13:05:40 +053049 bool clk_on;
50 u8 hctrl0_val;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070051};
52
53static int isa1200_read_reg(struct i2c_client *client, int reg)
54{
55 int ret;
56
57 ret = i2c_smbus_read_byte_data(client, reg);
58 if (ret < 0)
59 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
60
61 return ret;
62}
63
64static int isa1200_write_reg(struct i2c_client *client, int reg, u8 value)
65{
66 int ret;
67
68 ret = i2c_smbus_write_byte_data(client, reg, value);
69 if (ret < 0)
70 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
71
72 return ret;
73}
74
75static void isa1200_vib_set(struct isa1200_chip *haptic, int enable)
76{
77 int rc = 0;
78
79 if (enable) {
Mohan Pallakaace9fa92012-05-11 13:05:40 +053080 /* if hen and len are seperate then enable hen
81 * otherwise set normal mode bit */
82 if (haptic->is_len_gpio_valid == true)
83 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 1);
84 else {
85 rc = isa1200_write_reg(haptic->client, ISA1200_HCTRL0,
86 haptic->hctrl0_val | ~ISA1200_POWER_DOWN_MASK);
87 if (rc < 0) {
88 pr_err("%s: i2c write failure\n", __func__);
89 return;
90 }
91 }
92
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070093 if (haptic->pdata->mode_ctrl == PWM_INPUT_MODE) {
94 int period_us = haptic->period_ns / 1000;
Mohan Pallakaace9fa92012-05-11 13:05:40 +053095
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070096 rc = pwm_config(haptic->pwm,
97 (period_us * haptic->pdata->duty) / 100,
98 period_us);
Mohan Pallakaace9fa92012-05-11 13:05:40 +053099 if (rc < 0) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700100 pr_err("%s: pwm_config fail\n", __func__);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530101 goto chip_dwn;
102 }
103
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700104 rc = pwm_enable(haptic->pwm);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530105 if (rc < 0) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700106 pr_err("%s: pwm_enable fail\n", __func__);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530107 goto chip_dwn;
108 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700109 } else if (haptic->pdata->mode_ctrl == PWM_GEN_MODE) {
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530110 /* vote for clock */
111 if (haptic->pdata->clk_enable && !haptic->clk_on) {
112 rc = haptic->pdata->clk_enable(true);
113 if (rc < 0) {
114 pr_err("%s: clk enable failed\n",
115 __func__);
116 goto chip_dwn;
117 }
118 haptic->clk_on = true;
119 }
120
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700121 rc = isa1200_write_reg(haptic->client,
122 ISA1200_HCTRL5,
123 ISA1200_HCTRL5_VIB_STRT);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530124 if (rc < 0) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700125 pr_err("%s: start vibartion fail\n", __func__);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530126 goto dis_clk;
127 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700128 }
129 } else {
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530130 /* if hen and len are seperate then pull down hen
131 * otherwise set power down bit */
132 if (haptic->is_len_gpio_valid == true)
133 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
134 else {
135 rc = isa1200_write_reg(haptic->client, ISA1200_HCTRL0,
136 haptic->hctrl0_val & ISA1200_POWER_DOWN_MASK);
137 if (rc < 0) {
138 pr_err("%s: i2c write failure\n", __func__);
139 return;
140 }
141 }
142
143 if (haptic->pdata->mode_ctrl == PWM_INPUT_MODE) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700144 pwm_disable(haptic->pwm);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530145 } else if (haptic->pdata->mode_ctrl == PWM_GEN_MODE) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700146 rc = isa1200_write_reg(haptic->client,
147 ISA1200_HCTRL5,
148 ISA1200_HCTRL5_VIB_STOP);
149 if (rc < 0)
150 pr_err("%s: stop vibartion fail\n", __func__);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530151
152 /* de-vote clock */
153 if (haptic->pdata->clk_enable && haptic->clk_on) {
154 rc = haptic->pdata->clk_enable(false);
155 if (rc < 0) {
156 pr_err("%s: clk disable failed\n",
157 __func__);
158 return;
159 }
160 haptic->clk_on = false;
161 }
162 }
163 }
164
165 return;
166
167dis_clk:
168 if (haptic->pdata->clk_enable && haptic->clk_on) {
169 rc = haptic->pdata->clk_enable(false);
170 if (rc < 0) {
171 pr_err("%s: clk disable failed\n", __func__);
172 return;
173 }
174 haptic->clk_on = false;
175 }
176chip_dwn:
177 if (haptic->is_len_gpio_valid == true)
178 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
179 else {
180 rc = isa1200_write_reg(haptic->client, ISA1200_HCTRL0,
181 haptic->hctrl0_val & ISA1200_POWER_DOWN_MASK);
182 if (rc < 0) {
183 pr_err("%s: i2c write failure\n", __func__);
184 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700185 }
186 }
187}
188
189static void isa1200_chip_work(struct work_struct *work)
190{
191 struct isa1200_chip *haptic;
192
193 haptic = container_of(work, struct isa1200_chip, work);
194 isa1200_vib_set(haptic, haptic->enable);
195}
196
197static void isa1200_chip_enable(struct timed_output_dev *dev, int value)
198{
199 struct isa1200_chip *haptic = container_of(dev, struct isa1200_chip,
200 dev);
201 unsigned long flags;
202
203 spin_lock_irqsave(&haptic->lock, flags);
204 hrtimer_cancel(&haptic->timer);
205 if (value == 0)
206 haptic->enable = 0;
207 else {
208 value = (value > haptic->pdata->max_timeout ?
209 haptic->pdata->max_timeout : value);
210 haptic->enable = 1;
211 hrtimer_start(&haptic->timer,
212 ktime_set(value / 1000, (value % 1000) * 1000000),
213 HRTIMER_MODE_REL);
214 }
215 spin_unlock_irqrestore(&haptic->lock, flags);
216 schedule_work(&haptic->work);
217}
218
219static int isa1200_chip_get_time(struct timed_output_dev *dev)
220{
221 struct isa1200_chip *haptic = container_of(dev, struct isa1200_chip,
222 dev);
223
224 if (hrtimer_active(&haptic->timer)) {
225 ktime_t r = hrtimer_get_remaining(&haptic->timer);
226 struct timeval t = ktime_to_timeval(r);
227 return t.tv_sec * 1000 + t.tv_usec / 1000;
228 } else
229 return 0;
230}
231
232static enum hrtimer_restart isa1200_vib_timer_func(struct hrtimer *timer)
233{
234 struct isa1200_chip *haptic = container_of(timer, struct isa1200_chip,
235 timer);
236 haptic->enable = 0;
237 schedule_work(&haptic->work);
238
239 return HRTIMER_NORESTART;
240}
241
242static void dump_isa1200_reg(char *str, struct i2c_client *client)
243{
244 pr_debug("%s reg0x%x=0x%x, reg0x%x=0x%x, reg0x%x=0x%x\n", str,
245 ISA1200_HCTRL0, isa1200_read_reg(client, ISA1200_HCTRL0),
246 ISA1200_HCTRL1, isa1200_read_reg(client, ISA1200_HCTRL1),
247 ISA1200_HCTRL5, isa1200_read_reg(client, ISA1200_HCTRL5));
248}
249
250static int isa1200_setup(struct i2c_client *client)
251{
252 struct isa1200_chip *haptic = i2c_get_clientdata(client);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530253 int temp, rc;
254 u8 value;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700255
256 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530257 if (haptic->is_len_gpio_valid == true)
258 gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
259
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700260 udelay(250);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530261
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700262 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 1);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530263 if (haptic->is_len_gpio_valid == true)
264 gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700265
266 value = (haptic->pdata->smart_en << 3) |
267 (haptic->pdata->is_erm << 5) |
268 (haptic->pdata->ext_clk_en << 7);
269
270 rc = isa1200_write_reg(client, ISA1200_HCTRL1, value);
271 if (rc < 0) {
272 pr_err("%s: i2c write failure\n", __func__);
Mohan Pallakaacdca0f2011-11-21 13:08:00 +0530273 goto reset_gpios;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700274 }
275
276 if (haptic->pdata->mode_ctrl == PWM_GEN_MODE) {
277 temp = haptic->pdata->pwm_fd.pwm_div;
278 if (temp < 128 || temp > 1024 || temp % 128) {
279 pr_err("%s: Invalid divider\n", __func__);
280 goto reset_hctrl1;
281 }
282 value = ((temp >> 7) - 1);
283 } else if (haptic->pdata->mode_ctrl == PWM_INPUT_MODE) {
284 temp = haptic->pdata->pwm_fd.pwm_freq;
285 if (temp < 22400 || temp > 172600 || temp % 22400) {
286 pr_err("%s: Invalid frequency\n", __func__);
287 goto reset_hctrl1;
288 }
289 value = ((temp / 22400) - 1);
290 haptic->period_ns = NSEC_PER_SEC / temp;
291 }
292
293 value |= (haptic->pdata->mode_ctrl << 3) |
294 (haptic->pdata->overdrive_high << 5) |
295 (haptic->pdata->overdrive_en << 5) |
296 (haptic->pdata->chip_en << 7);
297
298 rc = isa1200_write_reg(client, ISA1200_HCTRL0, value);
299 if (rc < 0) {
300 pr_err("%s: i2c write failure\n", __func__);
301 goto reset_hctrl1;
302 }
303
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530304 /* if hen and len are seperate then pull down hen
305 * otherwise set power down bit */
306 if (haptic->is_len_gpio_valid == true)
307 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
308 else {
309 rc = isa1200_write_reg(client, ISA1200_HCTRL0,
310 value & ISA1200_POWER_DOWN_MASK);
311 if (rc < 0) {
312 pr_err("%s: i2c write failure\n", __func__);
313 goto reset_hctrl1;
314 }
315 }
316
317 haptic->hctrl0_val = value;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700318 dump_isa1200_reg("new:", client);
319 return 0;
320
321reset_hctrl1:
322 i2c_smbus_write_byte_data(client, ISA1200_HCTRL1,
323 ISA1200_HCTRL1_RESET);
Mohan Pallakaacdca0f2011-11-21 13:08:00 +0530324reset_gpios:
325 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
326 if (haptic->is_len_gpio_valid == true)
327 gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700328 return rc;
329}
330
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530331static int isa1200_reg_power(struct isa1200_chip *haptic, bool on)
332{
333 const struct isa1200_regulator *reg_info =
334 haptic->pdata->regulator_info;
335 u8 i, num_reg = haptic->pdata->num_regulators;
336 int rc;
337
338 for (i = 0; i < num_reg; i++) {
339 rc = regulator_set_optimum_mode(haptic->regs[i],
340 on ? reg_info[i].load_uA : 0);
341 if (rc < 0) {
342 pr_err("%s: regulator_set_optimum_mode failed(%d)\n",
343 __func__, rc);
344 goto regs_fail;
345 }
346
347 rc = on ? regulator_enable(haptic->regs[i]) :
348 regulator_disable(haptic->regs[i]);
349 if (rc < 0) {
350 pr_err("%s: regulator %sable fail %d\n", __func__,
351 on ? "en" : "dis", rc);
352 regulator_set_optimum_mode(haptic->regs[i],
353 !on ? reg_info[i].load_uA : 0);
354 goto regs_fail;
355 }
356 }
357
358 return 0;
359
360regs_fail:
361 while (i--) {
362 regulator_set_optimum_mode(haptic->regs[i],
363 !on ? reg_info[i].load_uA : 0);
364 !on ? regulator_enable(haptic->regs[i]) :
365 regulator_disable(haptic->regs[i]);
366 }
367 return rc;
368}
369
370static int isa1200_reg_setup(struct isa1200_chip *haptic, bool on)
371{
372 const struct isa1200_regulator *reg_info =
373 haptic->pdata->regulator_info;
374 u8 i, num_reg = haptic->pdata->num_regulators;
375 int rc = 0;
376
377 /* put regulators */
378 if (on == false) {
379 i = num_reg;
380 goto put_regs;
381 }
382
383 haptic->regs = kzalloc(num_reg * sizeof(struct regulator *),
384 GFP_KERNEL);
385 if (!haptic->regs) {
386 pr_err("unable to allocate memory\n");
387 return -ENOMEM;
388 }
389
390 for (i = 0; i < num_reg; i++) {
391 haptic->regs[i] = regulator_get(&haptic->client->dev,
392 reg_info[i].name);
393 if (IS_ERR(haptic->regs[i])) {
394 rc = PTR_ERR(haptic->regs[i]);
395 pr_err("%s:regulator get failed(%d)\n", __func__, rc);
396 goto put_regs;
397 }
398
399 if (regulator_count_voltages(haptic->regs[i]) > 0) {
400 rc = regulator_set_voltage(haptic->regs[i],
401 reg_info[i].min_uV, reg_info[i].max_uV);
402 if (rc) {
403 pr_err("%s: regulator_set_voltage failed(%d)\n",
404 __func__, rc);
405 regulator_put(haptic->regs[i]);
406 goto put_regs;
407 }
408 }
409 }
410
411 return rc;
412
413put_regs:
414 while (i--) {
415 if (regulator_count_voltages(haptic->regs[i]) > 0)
416 regulator_set_voltage(haptic->regs[i], 0,
417 reg_info[i].max_uV);
418 regulator_put(haptic->regs[i]);
419 }
420 kfree(haptic->regs);
421 return rc;
422}
423
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700424static int __devinit isa1200_probe(struct i2c_client *client,
425 const struct i2c_device_id *id)
426{
427 struct isa1200_chip *haptic;
428 struct isa1200_platform_data *pdata;
429 int ret;
430
431 if (!i2c_check_functionality(client->adapter,
432 I2C_FUNC_SMBUS_BYTE_DATA)) {
433 dev_err(&client->dev, "%s: no support for i2c read/write"
434 "byte data\n", __func__);
435 return -EIO;
436 }
437
438 pdata = client->dev.platform_data;
439 if (!pdata) {
440 dev_err(&client->dev, "%s: no platform data\n", __func__);
441 return -EINVAL;
442 }
443
444 if (pdata->dev_setup) {
445 ret = pdata->dev_setup(true);
446 if (ret < 0) {
447 dev_err(&client->dev, "dev setup failed\n");
448 return -EINVAL;
449 }
450 }
451
452 haptic = kzalloc(sizeof(struct isa1200_chip), GFP_KERNEL);
453 if (!haptic) {
454 ret = -ENOMEM;
455 goto mem_alloc_fail;
456 }
457 haptic->client = client;
458 haptic->enable = 0;
459 haptic->pdata = pdata;
460
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530461 if (pdata->regulator_info) {
462 ret = isa1200_reg_setup(haptic, true);
463 if (ret) {
464 dev_err(&client->dev, "%s: regulator setup failed\n",
465 __func__);
466 goto reg_setup_fail;
467 }
468
469 ret = isa1200_reg_power(haptic, true);
470 if (ret) {
471 dev_err(&client->dev, "%s: regulator power failed\n",
472 __func__);
473 goto reg_pwr_fail;
474 }
475 }
476
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700477 if (pdata->power_on) {
478 ret = pdata->power_on(1);
479 if (ret) {
480 dev_err(&client->dev, "%s: power-up failed\n",
481 __func__);
482 goto pwr_up_fail;
483 }
484 }
485
486 spin_lock_init(&haptic->lock);
487 INIT_WORK(&haptic->work, isa1200_chip_work);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530488 haptic->clk_on = false;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700489
490 hrtimer_init(&haptic->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
491 haptic->timer.function = isa1200_vib_timer_func;
492
493 /*register with timed output class*/
494 haptic->dev.name = pdata->name;
495 haptic->dev.get_time = isa1200_chip_get_time;
496 haptic->dev.enable = isa1200_chip_enable;
497 ret = timed_output_dev_register(&haptic->dev);
498 if (ret < 0)
499 goto timed_reg_fail;
500
501 i2c_set_clientdata(client, haptic);
502
503 ret = gpio_is_valid(pdata->hap_en_gpio);
504 if (ret) {
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530505 ret = gpio_request(pdata->hap_en_gpio, "haptic_en_gpio");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700506 if (ret) {
507 dev_err(&client->dev, "%s: gpio %d request failed\n",
508 __func__, pdata->hap_en_gpio);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530509 goto hen_gpio_fail;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700510 }
511 } else {
512 dev_err(&client->dev, "%s: Invalid gpio %d\n", __func__,
513 pdata->hap_en_gpio);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530514 goto hen_gpio_fail;
515 }
516
517 haptic->is_len_gpio_valid = true;
518 ret = gpio_is_valid(haptic->pdata->hap_len_gpio);
519 if (ret) {
520 ret = gpio_request(pdata->hap_len_gpio,
521 "haptic_ldo_gpio");
522 if (ret) {
523 dev_err(&client->dev,
524 "%s: gpio %d request failed\n",
525 __func__, pdata->hap_len_gpio);
526 goto len_gpio_fail;
527 }
528 } else {
529 dev_err(&client->dev, "%s: gpio is not used/Invalid %d\n",
530 __func__, pdata->hap_len_gpio);
531 haptic->is_len_gpio_valid = false;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700532 }
533
534 ret = isa1200_setup(client);
535 if (ret) {
536 dev_err(&client->dev, "%s: setup fail %d\n", __func__, ret);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530537 goto setup_fail;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700538 }
539
540 if (haptic->pdata->mode_ctrl == PWM_INPUT_MODE) {
541 haptic->pwm = pwm_request(pdata->pwm_ch_id, id->name);
542 if (IS_ERR(haptic->pwm)) {
543 dev_err(&client->dev, "%s: pwm request failed\n",
544 __func__);
545 ret = PTR_ERR(haptic->pwm);
546 goto reset_hctrl0;
547 }
548 }
549
550 printk(KERN_INFO "%s: %s registered\n", __func__, id->name);
551 return 0;
552
553reset_hctrl0:
Mohan Pallakaacdca0f2011-11-21 13:08:00 +0530554 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
555 if (haptic->is_len_gpio_valid == true)
556 gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
557 i2c_smbus_write_byte_data(client, ISA1200_HCTRL1,
558 ISA1200_HCTRL1_RESET);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700559 i2c_smbus_write_byte_data(client, ISA1200_HCTRL0,
560 ISA1200_HCTRL0_RESET);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530561setup_fail:
562 if (haptic->is_len_gpio_valid == true)
563 gpio_free(pdata->hap_len_gpio);
564len_gpio_fail:
565 gpio_free(pdata->hap_en_gpio);
566hen_gpio_fail:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700567 timed_output_dev_unregister(&haptic->dev);
568timed_reg_fail:
569 if (pdata->power_on)
570 pdata->power_on(0);
571pwr_up_fail:
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530572 if (pdata->regulator_info)
573 isa1200_reg_power(haptic, false);
574reg_pwr_fail:
575 if (pdata->regulator_info)
576 isa1200_reg_setup(haptic, false);
577reg_setup_fail:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700578 kfree(haptic);
579mem_alloc_fail:
580 if (pdata->dev_setup)
581 pdata->dev_setup(false);
582 return ret;
583}
584
585static int __devexit isa1200_remove(struct i2c_client *client)
586{
587 struct isa1200_chip *haptic = i2c_get_clientdata(client);
588
589 hrtimer_cancel(&haptic->timer);
590 cancel_work_sync(&haptic->work);
591
592 /* turn-off current vibration */
593 isa1200_vib_set(haptic, 0);
594
595 if (haptic->pdata->mode_ctrl == PWM_INPUT_MODE)
596 pwm_free(haptic->pwm);
597
598 timed_output_dev_unregister(&haptic->dev);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530599
Mohan Pallakaacdca0f2011-11-21 13:08:00 +0530600 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
601 if (haptic->is_len_gpio_valid == true)
602 gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
603
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700604 gpio_free(haptic->pdata->hap_en_gpio);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530605 if (haptic->is_len_gpio_valid == true)
606 gpio_free(haptic->pdata->hap_len_gpio);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700607
608 /* reset hardware registers */
609 i2c_smbus_write_byte_data(client, ISA1200_HCTRL0,
610 ISA1200_HCTRL0_RESET);
611 i2c_smbus_write_byte_data(client, ISA1200_HCTRL1,
612 ISA1200_HCTRL1_RESET);
613
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700614
615 /* power-off the chip */
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530616 if (haptic->pdata->regulator_info) {
617 isa1200_reg_power(haptic, false);
618 isa1200_reg_setup(haptic, false);
619 }
620
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700621 if (haptic->pdata->power_on)
622 haptic->pdata->power_on(0);
623
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530624 if (haptic->pdata->dev_setup)
625 haptic->pdata->dev_setup(false);
626
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700627 kfree(haptic);
628 return 0;
629}
630
631#ifdef CONFIG_PM
632static int isa1200_suspend(struct i2c_client *client, pm_message_t mesg)
633{
634 struct isa1200_chip *haptic = i2c_get_clientdata(client);
635 int ret;
636
637 hrtimer_cancel(&haptic->timer);
638 cancel_work_sync(&haptic->work);
639 /* turn-off current vibration */
640 isa1200_vib_set(haptic, 0);
641
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530642 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
643 if (haptic->is_len_gpio_valid == true)
644 gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
645
646 if (haptic->pdata->regulator_info)
647 isa1200_reg_power(haptic, false);
648
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700649 if (haptic->pdata->power_on) {
650 ret = haptic->pdata->power_on(0);
651 if (ret) {
652 dev_err(&client->dev, "power-down failed\n");
653 return ret;
654 }
655 }
656
657 return 0;
658}
659
660static int isa1200_resume(struct i2c_client *client)
661{
662 struct isa1200_chip *haptic = i2c_get_clientdata(client);
663 int ret;
664
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530665 if (haptic->pdata->regulator_info)
666 isa1200_reg_power(haptic, true);
667
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700668 if (haptic->pdata->power_on) {
669 ret = haptic->pdata->power_on(1);
670 if (ret) {
671 dev_err(&client->dev, "power-up failed\n");
672 return ret;
673 }
674 }
675
676 isa1200_setup(client);
677 return 0;
678}
679#else
680#define isa1200_suspend NULL
681#define isa1200_resume NULL
682#endif
683
684static const struct i2c_device_id isa1200_id[] = {
685 { "isa1200_1", 0 },
686 { },
687};
688MODULE_DEVICE_TABLE(i2c, isa1200_id);
689
690static struct i2c_driver isa1200_driver = {
691 .driver = {
692 .name = "isa1200",
693 },
694 .probe = isa1200_probe,
695 .remove = __devexit_p(isa1200_remove),
696 .suspend = isa1200_suspend,
697 .resume = isa1200_resume,
698 .id_table = isa1200_id,
699};
700
701static int __init isa1200_init(void)
702{
703 return i2c_add_driver(&isa1200_driver);
704}
705
706static void __exit isa1200_exit(void)
707{
708 i2c_del_driver(&isa1200_driver);
709}
710
711module_init(isa1200_init);
712module_exit(isa1200_exit);
713
714MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
715MODULE_DESCRIPTION("ISA1200 Haptic Motor driver");
716MODULE_LICENSE("GPL");