blob: 6c3e7875fb2a4a60d9c62e6a8525c503f7845015 [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>
Mohan Pallaka32f20a72012-06-14 14:41:11 +053023#include <linux/clk.h>
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070024#include <linux/i2c/isa1200.h>
25#include "../staging/android/timed_output.h"
26
27#define ISA1200_HCTRL0 0x30
28#define ISA1200_HCTRL1 0x31
29#define ISA1200_HCTRL5 0x35
30
31#define ISA1200_HCTRL0_RESET 0x01
32#define ISA1200_HCTRL1_RESET 0x4B
33
34#define ISA1200_HCTRL5_VIB_STRT 0xD5
35#define ISA1200_HCTRL5_VIB_STOP 0x6B
Mohan Pallakaace9fa92012-05-11 13:05:40 +053036#define ISA1200_POWER_DOWN_MASK 0x7F
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070037
38struct isa1200_chip {
39 struct i2c_client *client;
40 struct isa1200_platform_data *pdata;
41 struct pwm_device *pwm;
42 struct hrtimer timer;
43 struct timed_output_dev dev;
44 struct work_struct work;
45 spinlock_t lock;
46 unsigned int enable;
47 unsigned int period_ns;
Mohan Pallaka73787fa2011-09-09 15:14:20 +053048 bool is_len_gpio_valid;
49 struct regulator **regs;
Mohan Pallakaace9fa92012-05-11 13:05:40 +053050 bool clk_on;
51 u8 hctrl0_val;
Mohan Pallaka32f20a72012-06-14 14:41:11 +053052 struct clk *pwm_clk;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070053};
54
55static int isa1200_read_reg(struct i2c_client *client, int reg)
56{
57 int ret;
58
59 ret = i2c_smbus_read_byte_data(client, reg);
60 if (ret < 0)
61 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
62
63 return ret;
64}
65
66static int isa1200_write_reg(struct i2c_client *client, int reg, u8 value)
67{
68 int ret;
69
70 ret = i2c_smbus_write_byte_data(client, reg, value);
71 if (ret < 0)
72 dev_err(&client->dev, "%s: err %d\n", __func__, ret);
73
74 return ret;
75}
76
77static void isa1200_vib_set(struct isa1200_chip *haptic, int enable)
78{
79 int rc = 0;
80
81 if (enable) {
Mohan Pallakaace9fa92012-05-11 13:05:40 +053082 /* if hen and len are seperate then enable hen
83 * otherwise set normal mode bit */
84 if (haptic->is_len_gpio_valid == true)
85 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 1);
86 else {
87 rc = isa1200_write_reg(haptic->client, ISA1200_HCTRL0,
88 haptic->hctrl0_val | ~ISA1200_POWER_DOWN_MASK);
89 if (rc < 0) {
90 pr_err("%s: i2c write failure\n", __func__);
91 return;
92 }
93 }
94
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070095 if (haptic->pdata->mode_ctrl == PWM_INPUT_MODE) {
96 int period_us = haptic->period_ns / 1000;
Mohan Pallakaace9fa92012-05-11 13:05:40 +053097
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070098 rc = pwm_config(haptic->pwm,
99 (period_us * haptic->pdata->duty) / 100,
100 period_us);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530101 if (rc < 0) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700102 pr_err("%s: pwm_config fail\n", __func__);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530103 goto chip_dwn;
104 }
105
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700106 rc = pwm_enable(haptic->pwm);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530107 if (rc < 0) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700108 pr_err("%s: pwm_enable fail\n", __func__);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530109 goto chip_dwn;
110 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700111 } else if (haptic->pdata->mode_ctrl == PWM_GEN_MODE) {
Mohan Pallaka32f20a72012-06-14 14:41:11 +0530112 /* check for board specific clk callback */
113 if (haptic->pdata->clk_enable) {
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530114 rc = haptic->pdata->clk_enable(true);
115 if (rc < 0) {
Mohan Pallaka32f20a72012-06-14 14:41:11 +0530116 pr_err("%s: clk enable cb failed\n",
117 __func__);
118 goto chip_dwn;
119 }
120 }
121
122 /* vote for clock */
123 if (haptic->pdata->need_pwm_clk && !haptic->clk_on) {
124 rc = clk_enable(haptic->pwm_clk);
125 if (rc < 0) {
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530126 pr_err("%s: clk enable failed\n",
127 __func__);
Mohan Pallaka32f20a72012-06-14 14:41:11 +0530128 goto dis_clk_cb;
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530129 }
130 haptic->clk_on = true;
131 }
132
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700133 rc = isa1200_write_reg(haptic->client,
134 ISA1200_HCTRL5,
135 ISA1200_HCTRL5_VIB_STRT);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530136 if (rc < 0) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700137 pr_err("%s: start vibartion fail\n", __func__);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530138 goto dis_clk;
139 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700140 }
141 } else {
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530142 /* if hen and len are seperate then pull down hen
143 * otherwise set power down bit */
144 if (haptic->is_len_gpio_valid == true)
145 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
146 else {
147 rc = isa1200_write_reg(haptic->client, ISA1200_HCTRL0,
148 haptic->hctrl0_val & ISA1200_POWER_DOWN_MASK);
149 if (rc < 0) {
150 pr_err("%s: i2c write failure\n", __func__);
151 return;
152 }
153 }
154
155 if (haptic->pdata->mode_ctrl == PWM_INPUT_MODE) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700156 pwm_disable(haptic->pwm);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530157 } else if (haptic->pdata->mode_ctrl == PWM_GEN_MODE) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700158 rc = isa1200_write_reg(haptic->client,
159 ISA1200_HCTRL5,
160 ISA1200_HCTRL5_VIB_STOP);
161 if (rc < 0)
162 pr_err("%s: stop vibartion fail\n", __func__);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530163
164 /* de-vote clock */
Mohan Pallaka32f20a72012-06-14 14:41:11 +0530165 if (haptic->pdata->need_pwm_clk && haptic->clk_on) {
166 clk_disable(haptic->pwm_clk);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530167 haptic->clk_on = false;
168 }
Mohan Pallaka32f20a72012-06-14 14:41:11 +0530169 /* check for board specific clk callback */
170 if (haptic->pdata->clk_enable) {
171 rc = haptic->pdata->clk_enable(false);
172 if (rc < 0)
173 pr_err("%s: clk disable cb failed\n",
174 __func__);
175 }
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530176 }
177 }
178
179 return;
180
181dis_clk:
Mohan Pallaka32f20a72012-06-14 14:41:11 +0530182 if (haptic->pdata->need_pwm_clk && haptic->clk_on) {
183 clk_disable(haptic->pwm_clk);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530184 haptic->clk_on = false;
185 }
Mohan Pallaka32f20a72012-06-14 14:41:11 +0530186
187dis_clk_cb:
188 if (haptic->pdata->clk_enable) {
189 rc = haptic->pdata->clk_enable(false);
190 if (rc < 0)
191 pr_err("%s: clk disable cb failed\n", __func__);
192 }
193
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530194chip_dwn:
195 if (haptic->is_len_gpio_valid == true)
196 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
197 else {
198 rc = isa1200_write_reg(haptic->client, ISA1200_HCTRL0,
199 haptic->hctrl0_val & ISA1200_POWER_DOWN_MASK);
200 if (rc < 0) {
201 pr_err("%s: i2c write failure\n", __func__);
202 return;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700203 }
204 }
205}
206
207static void isa1200_chip_work(struct work_struct *work)
208{
209 struct isa1200_chip *haptic;
210
211 haptic = container_of(work, struct isa1200_chip, work);
212 isa1200_vib_set(haptic, haptic->enable);
213}
214
215static void isa1200_chip_enable(struct timed_output_dev *dev, int value)
216{
217 struct isa1200_chip *haptic = container_of(dev, struct isa1200_chip,
218 dev);
219 unsigned long flags;
220
221 spin_lock_irqsave(&haptic->lock, flags);
222 hrtimer_cancel(&haptic->timer);
223 if (value == 0)
224 haptic->enable = 0;
225 else {
226 value = (value > haptic->pdata->max_timeout ?
227 haptic->pdata->max_timeout : value);
228 haptic->enable = 1;
229 hrtimer_start(&haptic->timer,
230 ktime_set(value / 1000, (value % 1000) * 1000000),
231 HRTIMER_MODE_REL);
232 }
233 spin_unlock_irqrestore(&haptic->lock, flags);
234 schedule_work(&haptic->work);
235}
236
237static int isa1200_chip_get_time(struct timed_output_dev *dev)
238{
239 struct isa1200_chip *haptic = container_of(dev, struct isa1200_chip,
240 dev);
241
242 if (hrtimer_active(&haptic->timer)) {
243 ktime_t r = hrtimer_get_remaining(&haptic->timer);
244 struct timeval t = ktime_to_timeval(r);
245 return t.tv_sec * 1000 + t.tv_usec / 1000;
246 } else
247 return 0;
248}
249
250static enum hrtimer_restart isa1200_vib_timer_func(struct hrtimer *timer)
251{
252 struct isa1200_chip *haptic = container_of(timer, struct isa1200_chip,
253 timer);
254 haptic->enable = 0;
255 schedule_work(&haptic->work);
256
257 return HRTIMER_NORESTART;
258}
259
260static void dump_isa1200_reg(char *str, struct i2c_client *client)
261{
262 pr_debug("%s reg0x%x=0x%x, reg0x%x=0x%x, reg0x%x=0x%x\n", str,
263 ISA1200_HCTRL0, isa1200_read_reg(client, ISA1200_HCTRL0),
264 ISA1200_HCTRL1, isa1200_read_reg(client, ISA1200_HCTRL1),
265 ISA1200_HCTRL5, isa1200_read_reg(client, ISA1200_HCTRL5));
266}
267
268static int isa1200_setup(struct i2c_client *client)
269{
270 struct isa1200_chip *haptic = i2c_get_clientdata(client);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530271 int temp, rc;
272 u8 value;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700273
274 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530275 if (haptic->is_len_gpio_valid == true)
276 gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
277
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700278 udelay(250);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530279
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700280 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 1);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530281 if (haptic->is_len_gpio_valid == true)
282 gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700283
284 value = (haptic->pdata->smart_en << 3) |
285 (haptic->pdata->is_erm << 5) |
286 (haptic->pdata->ext_clk_en << 7);
287
288 rc = isa1200_write_reg(client, ISA1200_HCTRL1, value);
289 if (rc < 0) {
290 pr_err("%s: i2c write failure\n", __func__);
Mohan Pallakaacdca0f2011-11-21 13:08:00 +0530291 goto reset_gpios;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700292 }
293
294 if (haptic->pdata->mode_ctrl == PWM_GEN_MODE) {
295 temp = haptic->pdata->pwm_fd.pwm_div;
296 if (temp < 128 || temp > 1024 || temp % 128) {
297 pr_err("%s: Invalid divider\n", __func__);
298 goto reset_hctrl1;
299 }
300 value = ((temp >> 7) - 1);
301 } else if (haptic->pdata->mode_ctrl == PWM_INPUT_MODE) {
302 temp = haptic->pdata->pwm_fd.pwm_freq;
303 if (temp < 22400 || temp > 172600 || temp % 22400) {
304 pr_err("%s: Invalid frequency\n", __func__);
305 goto reset_hctrl1;
306 }
307 value = ((temp / 22400) - 1);
308 haptic->period_ns = NSEC_PER_SEC / temp;
309 }
310
311 value |= (haptic->pdata->mode_ctrl << 3) |
312 (haptic->pdata->overdrive_high << 5) |
313 (haptic->pdata->overdrive_en << 5) |
314 (haptic->pdata->chip_en << 7);
315
316 rc = isa1200_write_reg(client, ISA1200_HCTRL0, value);
317 if (rc < 0) {
318 pr_err("%s: i2c write failure\n", __func__);
319 goto reset_hctrl1;
320 }
321
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530322 /* if hen and len are seperate then pull down hen
323 * otherwise set power down bit */
324 if (haptic->is_len_gpio_valid == true)
325 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
326 else {
327 rc = isa1200_write_reg(client, ISA1200_HCTRL0,
328 value & ISA1200_POWER_DOWN_MASK);
329 if (rc < 0) {
330 pr_err("%s: i2c write failure\n", __func__);
331 goto reset_hctrl1;
332 }
333 }
334
335 haptic->hctrl0_val = value;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700336 dump_isa1200_reg("new:", client);
337 return 0;
338
339reset_hctrl1:
340 i2c_smbus_write_byte_data(client, ISA1200_HCTRL1,
341 ISA1200_HCTRL1_RESET);
Mohan Pallakaacdca0f2011-11-21 13:08:00 +0530342reset_gpios:
343 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
344 if (haptic->is_len_gpio_valid == true)
345 gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700346 return rc;
347}
348
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530349static int isa1200_reg_power(struct isa1200_chip *haptic, bool on)
350{
351 const struct isa1200_regulator *reg_info =
352 haptic->pdata->regulator_info;
353 u8 i, num_reg = haptic->pdata->num_regulators;
354 int rc;
355
356 for (i = 0; i < num_reg; i++) {
357 rc = regulator_set_optimum_mode(haptic->regs[i],
358 on ? reg_info[i].load_uA : 0);
359 if (rc < 0) {
360 pr_err("%s: regulator_set_optimum_mode failed(%d)\n",
361 __func__, rc);
362 goto regs_fail;
363 }
364
365 rc = on ? regulator_enable(haptic->regs[i]) :
366 regulator_disable(haptic->regs[i]);
367 if (rc < 0) {
368 pr_err("%s: regulator %sable fail %d\n", __func__,
369 on ? "en" : "dis", rc);
370 regulator_set_optimum_mode(haptic->regs[i],
371 !on ? reg_info[i].load_uA : 0);
372 goto regs_fail;
373 }
374 }
375
376 return 0;
377
378regs_fail:
379 while (i--) {
380 regulator_set_optimum_mode(haptic->regs[i],
381 !on ? reg_info[i].load_uA : 0);
382 !on ? regulator_enable(haptic->regs[i]) :
383 regulator_disable(haptic->regs[i]);
384 }
385 return rc;
386}
387
388static int isa1200_reg_setup(struct isa1200_chip *haptic, bool on)
389{
390 const struct isa1200_regulator *reg_info =
391 haptic->pdata->regulator_info;
392 u8 i, num_reg = haptic->pdata->num_regulators;
393 int rc = 0;
394
395 /* put regulators */
396 if (on == false) {
397 i = num_reg;
398 goto put_regs;
399 }
400
401 haptic->regs = kzalloc(num_reg * sizeof(struct regulator *),
402 GFP_KERNEL);
403 if (!haptic->regs) {
404 pr_err("unable to allocate memory\n");
405 return -ENOMEM;
406 }
407
408 for (i = 0; i < num_reg; i++) {
409 haptic->regs[i] = regulator_get(&haptic->client->dev,
410 reg_info[i].name);
411 if (IS_ERR(haptic->regs[i])) {
412 rc = PTR_ERR(haptic->regs[i]);
413 pr_err("%s:regulator get failed(%d)\n", __func__, rc);
414 goto put_regs;
415 }
416
417 if (regulator_count_voltages(haptic->regs[i]) > 0) {
418 rc = regulator_set_voltage(haptic->regs[i],
419 reg_info[i].min_uV, reg_info[i].max_uV);
420 if (rc) {
421 pr_err("%s: regulator_set_voltage failed(%d)\n",
422 __func__, rc);
423 regulator_put(haptic->regs[i]);
424 goto put_regs;
425 }
426 }
427 }
428
429 return rc;
430
431put_regs:
432 while (i--) {
433 if (regulator_count_voltages(haptic->regs[i]) > 0)
434 regulator_set_voltage(haptic->regs[i], 0,
435 reg_info[i].max_uV);
436 regulator_put(haptic->regs[i]);
437 }
438 kfree(haptic->regs);
439 return rc;
440}
441
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700442static int __devinit isa1200_probe(struct i2c_client *client,
443 const struct i2c_device_id *id)
444{
445 struct isa1200_chip *haptic;
446 struct isa1200_platform_data *pdata;
447 int ret;
448
449 if (!i2c_check_functionality(client->adapter,
450 I2C_FUNC_SMBUS_BYTE_DATA)) {
451 dev_err(&client->dev, "%s: no support for i2c read/write"
452 "byte data\n", __func__);
453 return -EIO;
454 }
455
456 pdata = client->dev.platform_data;
457 if (!pdata) {
458 dev_err(&client->dev, "%s: no platform data\n", __func__);
459 return -EINVAL;
460 }
461
462 if (pdata->dev_setup) {
463 ret = pdata->dev_setup(true);
464 if (ret < 0) {
465 dev_err(&client->dev, "dev setup failed\n");
466 return -EINVAL;
467 }
468 }
469
470 haptic = kzalloc(sizeof(struct isa1200_chip), GFP_KERNEL);
471 if (!haptic) {
472 ret = -ENOMEM;
473 goto mem_alloc_fail;
474 }
475 haptic->client = client;
476 haptic->enable = 0;
477 haptic->pdata = pdata;
478
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530479 if (pdata->regulator_info) {
480 ret = isa1200_reg_setup(haptic, true);
481 if (ret) {
482 dev_err(&client->dev, "%s: regulator setup failed\n",
483 __func__);
484 goto reg_setup_fail;
485 }
486
487 ret = isa1200_reg_power(haptic, true);
488 if (ret) {
489 dev_err(&client->dev, "%s: regulator power failed\n",
490 __func__);
491 goto reg_pwr_fail;
492 }
493 }
494
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700495 if (pdata->power_on) {
496 ret = pdata->power_on(1);
497 if (ret) {
498 dev_err(&client->dev, "%s: power-up failed\n",
499 __func__);
500 goto pwr_up_fail;
501 }
502 }
503
504 spin_lock_init(&haptic->lock);
505 INIT_WORK(&haptic->work, isa1200_chip_work);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530506 haptic->clk_on = false;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700507
508 hrtimer_init(&haptic->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
509 haptic->timer.function = isa1200_vib_timer_func;
510
511 /*register with timed output class*/
512 haptic->dev.name = pdata->name;
513 haptic->dev.get_time = isa1200_chip_get_time;
514 haptic->dev.enable = isa1200_chip_enable;
515 ret = timed_output_dev_register(&haptic->dev);
516 if (ret < 0)
517 goto timed_reg_fail;
518
519 i2c_set_clientdata(client, haptic);
520
521 ret = gpio_is_valid(pdata->hap_en_gpio);
522 if (ret) {
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530523 ret = gpio_request(pdata->hap_en_gpio, "haptic_en_gpio");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700524 if (ret) {
525 dev_err(&client->dev, "%s: gpio %d request failed\n",
526 __func__, pdata->hap_en_gpio);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530527 goto hen_gpio_fail;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700528 }
529 } else {
530 dev_err(&client->dev, "%s: Invalid gpio %d\n", __func__,
531 pdata->hap_en_gpio);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530532 goto hen_gpio_fail;
533 }
534
535 haptic->is_len_gpio_valid = true;
536 ret = gpio_is_valid(haptic->pdata->hap_len_gpio);
537 if (ret) {
538 ret = gpio_request(pdata->hap_len_gpio,
539 "haptic_ldo_gpio");
540 if (ret) {
541 dev_err(&client->dev,
542 "%s: gpio %d request failed\n",
543 __func__, pdata->hap_len_gpio);
544 goto len_gpio_fail;
545 }
546 } else {
547 dev_err(&client->dev, "%s: gpio is not used/Invalid %d\n",
548 __func__, pdata->hap_len_gpio);
549 haptic->is_len_gpio_valid = false;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700550 }
551
552 ret = isa1200_setup(client);
553 if (ret) {
554 dev_err(&client->dev, "%s: setup fail %d\n", __func__, ret);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530555 goto setup_fail;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700556 }
557
558 if (haptic->pdata->mode_ctrl == PWM_INPUT_MODE) {
559 haptic->pwm = pwm_request(pdata->pwm_ch_id, id->name);
560 if (IS_ERR(haptic->pwm)) {
561 dev_err(&client->dev, "%s: pwm request failed\n",
562 __func__);
563 ret = PTR_ERR(haptic->pwm);
564 goto reset_hctrl0;
565 }
Mohan Pallaka32f20a72012-06-14 14:41:11 +0530566 } else if (haptic->pdata->need_pwm_clk) {
567 haptic->pwm_clk = clk_get(&client->dev, "pwm_clk");
568 if (IS_ERR(haptic->pwm_clk)) {
569 dev_err(&client->dev, "pwm_clk get failed\n");
570 ret = PTR_ERR(haptic->pwm_clk);
571 goto reset_hctrl0;
572 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700573 }
574
575 printk(KERN_INFO "%s: %s registered\n", __func__, id->name);
576 return 0;
577
578reset_hctrl0:
Mohan Pallakaacdca0f2011-11-21 13:08:00 +0530579 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
580 if (haptic->is_len_gpio_valid == true)
581 gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
582 i2c_smbus_write_byte_data(client, ISA1200_HCTRL1,
583 ISA1200_HCTRL1_RESET);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700584 i2c_smbus_write_byte_data(client, ISA1200_HCTRL0,
585 ISA1200_HCTRL0_RESET);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530586setup_fail:
587 if (haptic->is_len_gpio_valid == true)
588 gpio_free(pdata->hap_len_gpio);
589len_gpio_fail:
590 gpio_free(pdata->hap_en_gpio);
591hen_gpio_fail:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700592 timed_output_dev_unregister(&haptic->dev);
593timed_reg_fail:
594 if (pdata->power_on)
595 pdata->power_on(0);
596pwr_up_fail:
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530597 if (pdata->regulator_info)
598 isa1200_reg_power(haptic, false);
599reg_pwr_fail:
600 if (pdata->regulator_info)
601 isa1200_reg_setup(haptic, false);
602reg_setup_fail:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700603 kfree(haptic);
604mem_alloc_fail:
605 if (pdata->dev_setup)
606 pdata->dev_setup(false);
607 return ret;
608}
609
610static int __devexit isa1200_remove(struct i2c_client *client)
611{
612 struct isa1200_chip *haptic = i2c_get_clientdata(client);
613
614 hrtimer_cancel(&haptic->timer);
615 cancel_work_sync(&haptic->work);
616
617 /* turn-off current vibration */
618 isa1200_vib_set(haptic, 0);
619
620 if (haptic->pdata->mode_ctrl == PWM_INPUT_MODE)
621 pwm_free(haptic->pwm);
622
623 timed_output_dev_unregister(&haptic->dev);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530624
Mohan Pallakaacdca0f2011-11-21 13:08:00 +0530625 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
626 if (haptic->is_len_gpio_valid == true)
627 gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
628
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700629 gpio_free(haptic->pdata->hap_en_gpio);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530630 if (haptic->is_len_gpio_valid == true)
631 gpio_free(haptic->pdata->hap_len_gpio);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700632
633 /* reset hardware registers */
634 i2c_smbus_write_byte_data(client, ISA1200_HCTRL0,
635 ISA1200_HCTRL0_RESET);
636 i2c_smbus_write_byte_data(client, ISA1200_HCTRL1,
637 ISA1200_HCTRL1_RESET);
638
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700639
640 /* power-off the chip */
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530641 if (haptic->pdata->regulator_info) {
642 isa1200_reg_power(haptic, false);
643 isa1200_reg_setup(haptic, false);
644 }
645
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700646 if (haptic->pdata->power_on)
647 haptic->pdata->power_on(0);
648
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530649 if (haptic->pdata->dev_setup)
650 haptic->pdata->dev_setup(false);
651
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700652 kfree(haptic);
653 return 0;
654}
655
656#ifdef CONFIG_PM
657static int isa1200_suspend(struct i2c_client *client, pm_message_t mesg)
658{
659 struct isa1200_chip *haptic = i2c_get_clientdata(client);
660 int ret;
661
662 hrtimer_cancel(&haptic->timer);
663 cancel_work_sync(&haptic->work);
664 /* turn-off current vibration */
665 isa1200_vib_set(haptic, 0);
666
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530667 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
668 if (haptic->is_len_gpio_valid == true)
669 gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
670
671 if (haptic->pdata->regulator_info)
672 isa1200_reg_power(haptic, false);
673
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700674 if (haptic->pdata->power_on) {
675 ret = haptic->pdata->power_on(0);
676 if (ret) {
677 dev_err(&client->dev, "power-down failed\n");
678 return ret;
679 }
680 }
681
682 return 0;
683}
684
685static int isa1200_resume(struct i2c_client *client)
686{
687 struct isa1200_chip *haptic = i2c_get_clientdata(client);
688 int ret;
689
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530690 if (haptic->pdata->regulator_info)
691 isa1200_reg_power(haptic, true);
692
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700693 if (haptic->pdata->power_on) {
694 ret = haptic->pdata->power_on(1);
695 if (ret) {
696 dev_err(&client->dev, "power-up failed\n");
697 return ret;
698 }
699 }
700
701 isa1200_setup(client);
702 return 0;
703}
704#else
705#define isa1200_suspend NULL
706#define isa1200_resume NULL
707#endif
708
709static const struct i2c_device_id isa1200_id[] = {
710 { "isa1200_1", 0 },
711 { },
712};
713MODULE_DEVICE_TABLE(i2c, isa1200_id);
714
715static struct i2c_driver isa1200_driver = {
716 .driver = {
717 .name = "isa1200",
718 },
719 .probe = isa1200_probe,
720 .remove = __devexit_p(isa1200_remove),
721 .suspend = isa1200_suspend,
722 .resume = isa1200_resume,
723 .id_table = isa1200_id,
724};
725
726static int __init isa1200_init(void)
727{
728 return i2c_add_driver(&isa1200_driver);
729}
730
731static void __exit isa1200_exit(void)
732{
733 i2c_del_driver(&isa1200_driver);
734}
735
736module_init(isa1200_init);
737module_exit(isa1200_exit);
738
739MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
740MODULE_DESCRIPTION("ISA1200 Haptic Motor driver");
741MODULE_LICENSE("GPL");