blob: 647799f15a3b3b19ea746cb6581ec02eb3992866 [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>
Duy Truonge833aca2013-02-12 13:35:08 -08006 * Copyright (c) 2010-2012, The Linux Foundation. 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;
Mohan Pallakaca6a02c2012-12-05 16:50:48 +053045 struct mutex lock;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070046 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);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700219
Mohan Pallakaca6a02c2012-12-05 16:50:48 +0530220 mutex_lock(&haptic->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700221 hrtimer_cancel(&haptic->timer);
222 if (value == 0)
223 haptic->enable = 0;
224 else {
225 value = (value > haptic->pdata->max_timeout ?
226 haptic->pdata->max_timeout : value);
227 haptic->enable = 1;
228 hrtimer_start(&haptic->timer,
229 ktime_set(value / 1000, (value % 1000) * 1000000),
230 HRTIMER_MODE_REL);
231 }
Mohan Pallakaca6a02c2012-12-05 16:50:48 +0530232 mutex_unlock(&haptic->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700233 schedule_work(&haptic->work);
234}
235
236static int isa1200_chip_get_time(struct timed_output_dev *dev)
237{
238 struct isa1200_chip *haptic = container_of(dev, struct isa1200_chip,
239 dev);
240
241 if (hrtimer_active(&haptic->timer)) {
242 ktime_t r = hrtimer_get_remaining(&haptic->timer);
243 struct timeval t = ktime_to_timeval(r);
244 return t.tv_sec * 1000 + t.tv_usec / 1000;
245 } else
246 return 0;
247}
248
249static enum hrtimer_restart isa1200_vib_timer_func(struct hrtimer *timer)
250{
251 struct isa1200_chip *haptic = container_of(timer, struct isa1200_chip,
252 timer);
253 haptic->enable = 0;
254 schedule_work(&haptic->work);
255
256 return HRTIMER_NORESTART;
257}
258
259static void dump_isa1200_reg(char *str, struct i2c_client *client)
260{
261 pr_debug("%s reg0x%x=0x%x, reg0x%x=0x%x, reg0x%x=0x%x\n", str,
262 ISA1200_HCTRL0, isa1200_read_reg(client, ISA1200_HCTRL0),
263 ISA1200_HCTRL1, isa1200_read_reg(client, ISA1200_HCTRL1),
264 ISA1200_HCTRL5, isa1200_read_reg(client, ISA1200_HCTRL5));
265}
266
267static int isa1200_setup(struct i2c_client *client)
268{
269 struct isa1200_chip *haptic = i2c_get_clientdata(client);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530270 int temp, rc;
271 u8 value;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700272
273 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530274 if (haptic->is_len_gpio_valid == true)
275 gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
276
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700277 udelay(250);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530278
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700279 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 1);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530280 if (haptic->is_len_gpio_valid == true)
281 gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 1);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700282
283 value = (haptic->pdata->smart_en << 3) |
284 (haptic->pdata->is_erm << 5) |
285 (haptic->pdata->ext_clk_en << 7);
286
287 rc = isa1200_write_reg(client, ISA1200_HCTRL1, value);
288 if (rc < 0) {
289 pr_err("%s: i2c write failure\n", __func__);
Mohan Pallakaacdca0f2011-11-21 13:08:00 +0530290 goto reset_gpios;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700291 }
292
293 if (haptic->pdata->mode_ctrl == PWM_GEN_MODE) {
294 temp = haptic->pdata->pwm_fd.pwm_div;
295 if (temp < 128 || temp > 1024 || temp % 128) {
296 pr_err("%s: Invalid divider\n", __func__);
297 goto reset_hctrl1;
298 }
299 value = ((temp >> 7) - 1);
300 } else if (haptic->pdata->mode_ctrl == PWM_INPUT_MODE) {
301 temp = haptic->pdata->pwm_fd.pwm_freq;
302 if (temp < 22400 || temp > 172600 || temp % 22400) {
303 pr_err("%s: Invalid frequency\n", __func__);
304 goto reset_hctrl1;
305 }
306 value = ((temp / 22400) - 1);
307 haptic->period_ns = NSEC_PER_SEC / temp;
308 }
309
310 value |= (haptic->pdata->mode_ctrl << 3) |
311 (haptic->pdata->overdrive_high << 5) |
312 (haptic->pdata->overdrive_en << 5) |
313 (haptic->pdata->chip_en << 7);
314
315 rc = isa1200_write_reg(client, ISA1200_HCTRL0, value);
316 if (rc < 0) {
317 pr_err("%s: i2c write failure\n", __func__);
318 goto reset_hctrl1;
319 }
320
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530321 /* if hen and len are seperate then pull down hen
322 * otherwise set power down bit */
323 if (haptic->is_len_gpio_valid == true)
324 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
325 else {
326 rc = isa1200_write_reg(client, ISA1200_HCTRL0,
327 value & ISA1200_POWER_DOWN_MASK);
328 if (rc < 0) {
329 pr_err("%s: i2c write failure\n", __func__);
330 goto reset_hctrl1;
331 }
332 }
333
334 haptic->hctrl0_val = value;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700335 dump_isa1200_reg("new:", client);
336 return 0;
337
338reset_hctrl1:
339 i2c_smbus_write_byte_data(client, ISA1200_HCTRL1,
340 ISA1200_HCTRL1_RESET);
Mohan Pallakaacdca0f2011-11-21 13:08:00 +0530341reset_gpios:
342 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
343 if (haptic->is_len_gpio_valid == true)
344 gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700345 return rc;
346}
347
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530348static int isa1200_reg_power(struct isa1200_chip *haptic, bool on)
349{
350 const struct isa1200_regulator *reg_info =
351 haptic->pdata->regulator_info;
352 u8 i, num_reg = haptic->pdata->num_regulators;
353 int rc;
354
355 for (i = 0; i < num_reg; i++) {
356 rc = regulator_set_optimum_mode(haptic->regs[i],
357 on ? reg_info[i].load_uA : 0);
358 if (rc < 0) {
359 pr_err("%s: regulator_set_optimum_mode failed(%d)\n",
360 __func__, rc);
361 goto regs_fail;
362 }
363
364 rc = on ? regulator_enable(haptic->regs[i]) :
365 regulator_disable(haptic->regs[i]);
366 if (rc < 0) {
367 pr_err("%s: regulator %sable fail %d\n", __func__,
368 on ? "en" : "dis", rc);
369 regulator_set_optimum_mode(haptic->regs[i],
370 !on ? reg_info[i].load_uA : 0);
371 goto regs_fail;
372 }
373 }
374
375 return 0;
376
377regs_fail:
378 while (i--) {
379 regulator_set_optimum_mode(haptic->regs[i],
380 !on ? reg_info[i].load_uA : 0);
381 !on ? regulator_enable(haptic->regs[i]) :
382 regulator_disable(haptic->regs[i]);
383 }
384 return rc;
385}
386
387static int isa1200_reg_setup(struct isa1200_chip *haptic, bool on)
388{
389 const struct isa1200_regulator *reg_info =
390 haptic->pdata->regulator_info;
391 u8 i, num_reg = haptic->pdata->num_regulators;
392 int rc = 0;
393
394 /* put regulators */
395 if (on == false) {
396 i = num_reg;
397 goto put_regs;
398 }
399
400 haptic->regs = kzalloc(num_reg * sizeof(struct regulator *),
401 GFP_KERNEL);
402 if (!haptic->regs) {
403 pr_err("unable to allocate memory\n");
404 return -ENOMEM;
405 }
406
407 for (i = 0; i < num_reg; i++) {
408 haptic->regs[i] = regulator_get(&haptic->client->dev,
409 reg_info[i].name);
410 if (IS_ERR(haptic->regs[i])) {
411 rc = PTR_ERR(haptic->regs[i]);
412 pr_err("%s:regulator get failed(%d)\n", __func__, rc);
413 goto put_regs;
414 }
415
416 if (regulator_count_voltages(haptic->regs[i]) > 0) {
417 rc = regulator_set_voltage(haptic->regs[i],
418 reg_info[i].min_uV, reg_info[i].max_uV);
419 if (rc) {
420 pr_err("%s: regulator_set_voltage failed(%d)\n",
421 __func__, rc);
422 regulator_put(haptic->regs[i]);
423 goto put_regs;
424 }
425 }
426 }
427
428 return rc;
429
430put_regs:
431 while (i--) {
432 if (regulator_count_voltages(haptic->regs[i]) > 0)
433 regulator_set_voltage(haptic->regs[i], 0,
434 reg_info[i].max_uV);
435 regulator_put(haptic->regs[i]);
436 }
437 kfree(haptic->regs);
438 return rc;
439}
440
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700441static int __devinit isa1200_probe(struct i2c_client *client,
442 const struct i2c_device_id *id)
443{
444 struct isa1200_chip *haptic;
445 struct isa1200_platform_data *pdata;
446 int ret;
447
448 if (!i2c_check_functionality(client->adapter,
449 I2C_FUNC_SMBUS_BYTE_DATA)) {
450 dev_err(&client->dev, "%s: no support for i2c read/write"
451 "byte data\n", __func__);
452 return -EIO;
453 }
454
455 pdata = client->dev.platform_data;
456 if (!pdata) {
457 dev_err(&client->dev, "%s: no platform data\n", __func__);
458 return -EINVAL;
459 }
460
461 if (pdata->dev_setup) {
462 ret = pdata->dev_setup(true);
463 if (ret < 0) {
464 dev_err(&client->dev, "dev setup failed\n");
465 return -EINVAL;
466 }
467 }
468
469 haptic = kzalloc(sizeof(struct isa1200_chip), GFP_KERNEL);
470 if (!haptic) {
471 ret = -ENOMEM;
472 goto mem_alloc_fail;
473 }
474 haptic->client = client;
475 haptic->enable = 0;
476 haptic->pdata = pdata;
477
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530478 if (pdata->regulator_info) {
479 ret = isa1200_reg_setup(haptic, true);
480 if (ret) {
481 dev_err(&client->dev, "%s: regulator setup failed\n",
482 __func__);
483 goto reg_setup_fail;
484 }
485
486 ret = isa1200_reg_power(haptic, true);
487 if (ret) {
488 dev_err(&client->dev, "%s: regulator power failed\n",
489 __func__);
490 goto reg_pwr_fail;
491 }
492 }
493
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700494 if (pdata->power_on) {
495 ret = pdata->power_on(1);
496 if (ret) {
497 dev_err(&client->dev, "%s: power-up failed\n",
498 __func__);
499 goto pwr_up_fail;
500 }
501 }
502
Mohan Pallakaca6a02c2012-12-05 16:50:48 +0530503 mutex_init(&haptic->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700504 INIT_WORK(&haptic->work, isa1200_chip_work);
Mohan Pallakaace9fa92012-05-11 13:05:40 +0530505 haptic->clk_on = false;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700506
507 hrtimer_init(&haptic->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
508 haptic->timer.function = isa1200_vib_timer_func;
509
510 /*register with timed output class*/
511 haptic->dev.name = pdata->name;
512 haptic->dev.get_time = isa1200_chip_get_time;
513 haptic->dev.enable = isa1200_chip_enable;
514 ret = timed_output_dev_register(&haptic->dev);
515 if (ret < 0)
516 goto timed_reg_fail;
517
518 i2c_set_clientdata(client, haptic);
519
520 ret = gpio_is_valid(pdata->hap_en_gpio);
521 if (ret) {
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530522 ret = gpio_request(pdata->hap_en_gpio, "haptic_en_gpio");
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700523 if (ret) {
524 dev_err(&client->dev, "%s: gpio %d request failed\n",
525 __func__, pdata->hap_en_gpio);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530526 goto hen_gpio_fail;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700527 }
528 } else {
529 dev_err(&client->dev, "%s: Invalid gpio %d\n", __func__,
530 pdata->hap_en_gpio);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530531 goto hen_gpio_fail;
532 }
533
534 haptic->is_len_gpio_valid = true;
535 ret = gpio_is_valid(haptic->pdata->hap_len_gpio);
536 if (ret) {
537 ret = gpio_request(pdata->hap_len_gpio,
538 "haptic_ldo_gpio");
539 if (ret) {
540 dev_err(&client->dev,
541 "%s: gpio %d request failed\n",
542 __func__, pdata->hap_len_gpio);
543 goto len_gpio_fail;
544 }
545 } else {
546 dev_err(&client->dev, "%s: gpio is not used/Invalid %d\n",
547 __func__, pdata->hap_len_gpio);
548 haptic->is_len_gpio_valid = false;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700549 }
550
551 ret = isa1200_setup(client);
552 if (ret) {
553 dev_err(&client->dev, "%s: setup fail %d\n", __func__, ret);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530554 goto setup_fail;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700555 }
556
557 if (haptic->pdata->mode_ctrl == PWM_INPUT_MODE) {
558 haptic->pwm = pwm_request(pdata->pwm_ch_id, id->name);
559 if (IS_ERR(haptic->pwm)) {
560 dev_err(&client->dev, "%s: pwm request failed\n",
561 __func__);
562 ret = PTR_ERR(haptic->pwm);
563 goto reset_hctrl0;
564 }
Mohan Pallaka32f20a72012-06-14 14:41:11 +0530565 } else if (haptic->pdata->need_pwm_clk) {
566 haptic->pwm_clk = clk_get(&client->dev, "pwm_clk");
567 if (IS_ERR(haptic->pwm_clk)) {
568 dev_err(&client->dev, "pwm_clk get failed\n");
569 ret = PTR_ERR(haptic->pwm_clk);
570 goto reset_hctrl0;
571 }
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700572 }
573
574 printk(KERN_INFO "%s: %s registered\n", __func__, id->name);
575 return 0;
576
577reset_hctrl0:
Mohan Pallakaacdca0f2011-11-21 13:08:00 +0530578 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
579 if (haptic->is_len_gpio_valid == true)
580 gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
581 i2c_smbus_write_byte_data(client, ISA1200_HCTRL1,
582 ISA1200_HCTRL1_RESET);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700583 i2c_smbus_write_byte_data(client, ISA1200_HCTRL0,
584 ISA1200_HCTRL0_RESET);
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530585setup_fail:
586 if (haptic->is_len_gpio_valid == true)
587 gpio_free(pdata->hap_len_gpio);
588len_gpio_fail:
589 gpio_free(pdata->hap_en_gpio);
590hen_gpio_fail:
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700591 timed_output_dev_unregister(&haptic->dev);
592timed_reg_fail:
Mohan Pallakaca6a02c2012-12-05 16:50:48 +0530593 mutex_destroy(&haptic->lock);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700594 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
Mohan Pallakaca6a02c2012-12-05 16:50:48 +0530640 /* destroy mutex */
641 mutex_destroy(&haptic->lock);
642
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700643 /* power-off the chip */
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530644 if (haptic->pdata->regulator_info) {
645 isa1200_reg_power(haptic, false);
646 isa1200_reg_setup(haptic, false);
647 }
648
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700649 if (haptic->pdata->power_on)
650 haptic->pdata->power_on(0);
651
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530652 if (haptic->pdata->dev_setup)
653 haptic->pdata->dev_setup(false);
654
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700655 kfree(haptic);
656 return 0;
657}
658
659#ifdef CONFIG_PM
660static int isa1200_suspend(struct i2c_client *client, pm_message_t mesg)
661{
662 struct isa1200_chip *haptic = i2c_get_clientdata(client);
663 int ret;
664
665 hrtimer_cancel(&haptic->timer);
666 cancel_work_sync(&haptic->work);
667 /* turn-off current vibration */
668 isa1200_vib_set(haptic, 0);
669
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530670 gpio_set_value_cansleep(haptic->pdata->hap_en_gpio, 0);
671 if (haptic->is_len_gpio_valid == true)
672 gpio_set_value_cansleep(haptic->pdata->hap_len_gpio, 0);
673
674 if (haptic->pdata->regulator_info)
675 isa1200_reg_power(haptic, false);
676
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700677 if (haptic->pdata->power_on) {
678 ret = haptic->pdata->power_on(0);
679 if (ret) {
680 dev_err(&client->dev, "power-down failed\n");
681 return ret;
682 }
683 }
684
685 return 0;
686}
687
688static int isa1200_resume(struct i2c_client *client)
689{
690 struct isa1200_chip *haptic = i2c_get_clientdata(client);
691 int ret;
692
Mohan Pallaka73787fa2011-09-09 15:14:20 +0530693 if (haptic->pdata->regulator_info)
694 isa1200_reg_power(haptic, true);
695
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700696 if (haptic->pdata->power_on) {
697 ret = haptic->pdata->power_on(1);
698 if (ret) {
699 dev_err(&client->dev, "power-up failed\n");
700 return ret;
701 }
702 }
703
704 isa1200_setup(client);
705 return 0;
706}
707#else
708#define isa1200_suspend NULL
709#define isa1200_resume NULL
710#endif
711
712static const struct i2c_device_id isa1200_id[] = {
713 { "isa1200_1", 0 },
714 { },
715};
716MODULE_DEVICE_TABLE(i2c, isa1200_id);
717
718static struct i2c_driver isa1200_driver = {
719 .driver = {
720 .name = "isa1200",
721 },
722 .probe = isa1200_probe,
723 .remove = __devexit_p(isa1200_remove),
724 .suspend = isa1200_suspend,
725 .resume = isa1200_resume,
726 .id_table = isa1200_id,
727};
728
729static int __init isa1200_init(void)
730{
731 return i2c_add_driver(&isa1200_driver);
732}
733
734static void __exit isa1200_exit(void)
735{
736 i2c_del_driver(&isa1200_driver);
737}
738
739module_init(isa1200_init);
740module_exit(isa1200_exit);
741
742MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
743MODULE_DESCRIPTION("ISA1200 Haptic Motor driver");
744MODULE_LICENSE("GPL");