blob: c39ec93c0c58075bf6d5ca58f29dc0e9807291ef [file] [log] [blame]
Michael Hennerich88751dd2009-09-17 22:39:38 -07001/*
2 * File: drivers/input/keyboard/adp5588_keys.c
Michael Hennerich5a9003d2010-01-19 00:28:44 -08003 * Description: keypad driver for ADP5588 and ADP5587
4 * I2C QWERTY Keypad and IO Expander
Michael Hennerich88751dd2009-09-17 22:39:38 -07005 * Bugs: Enter bugs at http://blackfin.uclinux.org/
6 *
7 * Copyright (C) 2008-2009 Analog Devices Inc.
8 * Licensed under the GPL-2 or later.
9 */
10
11#include <linux/module.h>
12#include <linux/version.h>
13#include <linux/init.h>
14#include <linux/interrupt.h>
15#include <linux/irq.h>
16#include <linux/workqueue.h>
17#include <linux/errno.h>
18#include <linux/pm.h>
19#include <linux/platform_device.h>
20#include <linux/input.h>
21#include <linux/i2c.h>
Xiaolong Chenba9f5072010-07-26 01:01:11 -070022#include <linux/gpio.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090023#include <linux/slab.h>
Michael Hennerich88751dd2009-09-17 22:39:38 -070024
25#include <linux/i2c/adp5588.h>
26
27 /* Configuration Register1 */
28#define AUTO_INC (1 << 7)
29#define GPIEM_CFG (1 << 6)
30#define OVR_FLOW_M (1 << 5)
31#define INT_CFG (1 << 4)
32#define OVR_FLOW_IEN (1 << 3)
33#define K_LCK_IM (1 << 2)
34#define GPI_IEN (1 << 1)
35#define KE_IEN (1 << 0)
36
37/* Interrupt Status Register */
38#define CMP2_INT (1 << 5)
39#define CMP1_INT (1 << 4)
40#define OVR_FLOW_INT (1 << 3)
41#define K_LCK_INT (1 << 2)
42#define GPI_INT (1 << 1)
43#define KE_INT (1 << 0)
44
45/* Key Lock and Event Counter Register */
46#define K_LCK_EN (1 << 6)
47#define LCK21 0x30
48#define KEC 0xF
49
50/* Key Event Register xy */
51#define KEY_EV_PRESSED (1 << 7)
52#define KEY_EV_MASK (0x7F)
53
54#define KP_SEL(x) (0xFFFF >> (16 - x)) /* 2^x-1 */
55
56#define KEYP_MAX_EVENT 10
57
Xiaolong Chenba9f5072010-07-26 01:01:11 -070058#define MAXGPIO 18
59#define ADP_BANK(offs) ((offs) >> 3)
60#define ADP_BIT(offs) (1u << ((offs) & 0x7))
61
Michael Hennerich88751dd2009-09-17 22:39:38 -070062/*
63 * Early pre 4.0 Silicon required to delay readout by at least 25ms,
64 * since the Event Counter Register updated 25ms after the interrupt
65 * asserted.
66 */
67#define WA_DELAYED_READOUT_REVID(rev) ((rev) < 4)
68
69struct adp5588_kpad {
70 struct i2c_client *client;
71 struct input_dev *input;
72 struct delayed_work work;
73 unsigned long delay;
74 unsigned short keycode[ADP5588_KEYMAPSIZE];
Xiaolong CHEN69a4af62010-06-24 19:10:40 -070075 const struct adp5588_gpi_map *gpimap;
76 unsigned short gpimapsize;
Xiaolong Chenba9f5072010-07-26 01:01:11 -070077#ifdef CONFIG_GPIOLIB
78 unsigned char gpiomap[MAXGPIO];
79 bool export_gpio;
80 struct gpio_chip gc;
81 struct mutex gpio_lock; /* Protect cached dir, dat_out */
82 u8 dat_out[3];
83 u8 dir[3];
84#endif
Michael Hennerich88751dd2009-09-17 22:39:38 -070085};
86
87static int adp5588_read(struct i2c_client *client, u8 reg)
88{
89 int ret = i2c_smbus_read_byte_data(client, reg);
90
91 if (ret < 0)
92 dev_err(&client->dev, "Read Error\n");
93
94 return ret;
95}
96
97static int adp5588_write(struct i2c_client *client, u8 reg, u8 val)
98{
99 return i2c_smbus_write_byte_data(client, reg, val);
100}
101
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700102#ifdef CONFIG_GPIOLIB
103static int adp5588_gpio_get_value(struct gpio_chip *chip, unsigned off)
104{
105 struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
106 unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
107 unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
108
109 return !!(adp5588_read(kpad->client, GPIO_DAT_STAT1 + bank) & bit);
110}
111
112static void adp5588_gpio_set_value(struct gpio_chip *chip,
113 unsigned off, int val)
114{
115 struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
116 unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
117 unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
118
119 mutex_lock(&kpad->gpio_lock);
120
121 if (val)
122 kpad->dat_out[bank] |= bit;
123 else
124 kpad->dat_out[bank] &= ~bit;
125
126 adp5588_write(kpad->client, GPIO_DAT_OUT1 + bank,
127 kpad->dat_out[bank]);
128
129 mutex_unlock(&kpad->gpio_lock);
130}
131
132static int adp5588_gpio_direction_input(struct gpio_chip *chip, unsigned off)
133{
134 struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
135 unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
136 unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
137 int ret;
138
139 mutex_lock(&kpad->gpio_lock);
140
141 kpad->dir[bank] &= ~bit;
142 ret = adp5588_write(kpad->client, GPIO_DIR1 + bank, kpad->dir[bank]);
143
144 mutex_unlock(&kpad->gpio_lock);
145
146 return ret;
147}
148
149static int adp5588_gpio_direction_output(struct gpio_chip *chip,
150 unsigned off, int val)
151{
152 struct adp5588_kpad *kpad = container_of(chip, struct adp5588_kpad, gc);
153 unsigned int bank = ADP_BANK(kpad->gpiomap[off]);
154 unsigned int bit = ADP_BIT(kpad->gpiomap[off]);
155 int ret;
156
157 mutex_lock(&kpad->gpio_lock);
158
159 kpad->dir[bank] |= bit;
160
161 if (val)
162 kpad->dat_out[bank] |= bit;
163 else
164 kpad->dat_out[bank] &= ~bit;
165
166 ret = adp5588_write(kpad->client, GPIO_DAT_OUT1 + bank,
167 kpad->dat_out[bank]);
168 ret |= adp5588_write(kpad->client, GPIO_DIR1 + bank,
169 kpad->dir[bank]);
170
171 mutex_unlock(&kpad->gpio_lock);
172
173 return ret;
174}
175
176static int __devinit adp5588_gpio_add(struct device *dev)
177{
178 struct adp5588_kpad *kpad = dev_get_drvdata(dev);
179 const struct adp5588_kpad_platform_data *pdata = dev->platform_data;
180 const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data;
181 int i, error;
182
183 if (gpio_data) {
184 int j = 0;
185 bool pin_used[MAXGPIO];
186
187 for (i = 0; i < pdata->rows; i++)
188 pin_used[i] = true;
189
190 for (i = 0; i < pdata->cols; i++)
191 pin_used[i + GPI_PIN_COL_BASE - GPI_PIN_BASE] = true;
192
193 for (i = 0; i < kpad->gpimapsize; i++)
194 pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true;
195
196 for (i = 0; i < MAXGPIO; i++) {
197 if (!pin_used[i])
198 kpad->gpiomap[j++] = i;
199 }
200 kpad->gc.ngpio = j;
201
202 if (kpad->gc.ngpio)
203 kpad->export_gpio = true;
204 }
205
206 if (!kpad->export_gpio) {
207 dev_info(dev, "No unused gpios left to export\n");
208 return 0;
209 }
210
211 kpad->gc.direction_input = adp5588_gpio_direction_input;
212 kpad->gc.direction_output = adp5588_gpio_direction_output;
213 kpad->gc.get = adp5588_gpio_get_value;
214 kpad->gc.set = adp5588_gpio_set_value;
215 kpad->gc.can_sleep = 1;
216
217 kpad->gc.base = gpio_data->gpio_start;
218 kpad->gc.label = kpad->client->name;
219 kpad->gc.owner = THIS_MODULE;
220
221 mutex_init(&kpad->gpio_lock);
222
223 error = gpiochip_add(&kpad->gc);
224 if (error) {
225 dev_err(dev, "gpiochip_add failed, err: %d\n", error);
226 return error;
227 }
228
229 for (i = 0; i <= ADP_BANK(MAXGPIO); i++) {
230 kpad->dat_out[i] = adp5588_read(kpad->client,
231 GPIO_DAT_OUT1 + i);
232 kpad->dir[i] = adp5588_read(kpad->client, GPIO_DIR1 + i);
233 }
234
235 if (gpio_data->setup) {
236 error = gpio_data->setup(kpad->client,
237 kpad->gc.base, kpad->gc.ngpio,
238 gpio_data->context);
239 if (error)
240 dev_warn(dev, "setup failed, %d\n", error);
241 }
242
243 return 0;
244}
245
246static void __devexit adp5588_gpio_remove(struct device *dev)
247{
248 struct adp5588_kpad *kpad = dev_get_drvdata(dev);
249 const struct adp5588_kpad_platform_data *pdata = dev->platform_data;
250 const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data;
251 int error;
252
253 if (!kpad->export_gpio)
254 return;
255
256 if (gpio_data->teardown) {
257 error = gpio_data->teardown(kpad->client,
258 kpad->gc.base, kpad->gc.ngpio,
259 gpio_data->context);
260 if (error)
261 dev_warn(dev, "teardown failed %d\n", error);
262 }
263
264 error = gpiochip_remove(&kpad->gc);
265 if (error)
266 dev_warn(dev, "gpiochip_remove failed %d\n", error);
267}
268#else
269static inline int adp5588_gpio_add(struct device *dev)
270{
271 return 0;
272}
273
274static inline void adp5588_gpio_remove(struct device *dev)
275{
276}
277#endif
278
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700279static void adp5588_report_events(struct adp5588_kpad *kpad, int ev_cnt)
280{
281 int i, j;
282
283 for (i = 0; i < ev_cnt; i++) {
284 int key = adp5588_read(kpad->client, Key_EVENTA + i);
285 int key_val = key & KEY_EV_MASK;
286
287 if (key_val >= GPI_PIN_BASE && key_val <= GPI_PIN_END) {
288 for (j = 0; j < kpad->gpimapsize; j++) {
289 if (key_val == kpad->gpimap[j].pin) {
290 input_report_switch(kpad->input,
291 kpad->gpimap[j].sw_evt,
292 key & KEY_EV_PRESSED);
293 break;
294 }
295 }
296 } else {
297 input_report_key(kpad->input,
298 kpad->keycode[key_val - 1],
299 key & KEY_EV_PRESSED);
300 }
301 }
302}
303
Michael Hennerich88751dd2009-09-17 22:39:38 -0700304static void adp5588_work(struct work_struct *work)
305{
306 struct adp5588_kpad *kpad = container_of(work,
307 struct adp5588_kpad, work.work);
308 struct i2c_client *client = kpad->client;
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700309 int status, ev_cnt;
Michael Hennerich88751dd2009-09-17 22:39:38 -0700310
311 status = adp5588_read(client, INT_STAT);
312
313 if (status & OVR_FLOW_INT) /* Unlikely and should never happen */
314 dev_err(&client->dev, "Event Overflow Error\n");
315
316 if (status & KE_INT) {
317 ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & KEC;
318 if (ev_cnt) {
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700319 adp5588_report_events(kpad, ev_cnt);
Michael Hennerich88751dd2009-09-17 22:39:38 -0700320 input_sync(kpad->input);
321 }
322 }
323 adp5588_write(client, INT_STAT, status); /* Status is W1C */
324}
325
326static irqreturn_t adp5588_irq(int irq, void *handle)
327{
328 struct adp5588_kpad *kpad = handle;
329
330 /*
331 * use keventd context to read the event fifo registers
332 * Schedule readout at least 25ms after notification for
333 * REVID < 4
334 */
335
336 schedule_delayed_work(&kpad->work, kpad->delay);
337
338 return IRQ_HANDLED;
339}
340
341static int __devinit adp5588_setup(struct i2c_client *client)
342{
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700343 const struct adp5588_kpad_platform_data *pdata = client->dev.platform_data;
344 const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data;
Michael Hennerich88751dd2009-09-17 22:39:38 -0700345 int i, ret;
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700346 unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0;
Michael Hennerich88751dd2009-09-17 22:39:38 -0700347
348 ret = adp5588_write(client, KP_GPIO1, KP_SEL(pdata->rows));
349 ret |= adp5588_write(client, KP_GPIO2, KP_SEL(pdata->cols) & 0xFF);
350 ret |= adp5588_write(client, KP_GPIO3, KP_SEL(pdata->cols) >> 8);
351
352 if (pdata->en_keylock) {
353 ret |= adp5588_write(client, UNLOCK1, pdata->unlock_key1);
354 ret |= adp5588_write(client, UNLOCK2, pdata->unlock_key2);
355 ret |= adp5588_write(client, KEY_LCK_EC_STAT, K_LCK_EN);
356 }
357
358 for (i = 0; i < KEYP_MAX_EVENT; i++)
359 ret |= adp5588_read(client, Key_EVENTA);
360
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700361 for (i = 0; i < pdata->gpimapsize; i++) {
362 unsigned short pin = pdata->gpimap[i].pin;
363
364 if (pin <= GPI_PIN_ROW_END) {
365 evt_mode1 |= (1 << (pin - GPI_PIN_ROW_BASE));
366 } else {
367 evt_mode2 |= ((1 << (pin - GPI_PIN_COL_BASE)) & 0xFF);
368 evt_mode3 |= ((1 << (pin - GPI_PIN_COL_BASE)) >> 8);
369 }
370 }
371
372 if (pdata->gpimapsize) {
373 ret |= adp5588_write(client, GPI_EM1, evt_mode1);
374 ret |= adp5588_write(client, GPI_EM2, evt_mode2);
375 ret |= adp5588_write(client, GPI_EM3, evt_mode3);
376 }
377
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700378 if (gpio_data) {
379 for (i = 0; i <= ADP_BANK(MAXGPIO); i++) {
380 int pull_mask = gpio_data->pullup_dis_mask;
381
382 ret |= adp5588_write(client, GPIO_PULL1 + i,
383 (pull_mask >> (8 * i)) & 0xFF);
384 }
385 }
386
Michael Hennerich88751dd2009-09-17 22:39:38 -0700387 ret |= adp5588_write(client, INT_STAT, CMP2_INT | CMP1_INT |
388 OVR_FLOW_INT | K_LCK_INT |
389 GPI_INT | KE_INT); /* Status is W1C */
390
391 ret |= adp5588_write(client, CFG, INT_CFG | OVR_FLOW_IEN | KE_IEN);
392
393 if (ret < 0) {
394 dev_err(&client->dev, "Write Error\n");
395 return ret;
396 }
397
398 return 0;
399}
400
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700401static void __devinit adp5588_report_switch_state(struct adp5588_kpad *kpad)
402{
403 int gpi_stat1 = adp5588_read(kpad->client, GPIO_DAT_STAT1);
404 int gpi_stat2 = adp5588_read(kpad->client, GPIO_DAT_STAT2);
405 int gpi_stat3 = adp5588_read(kpad->client, GPIO_DAT_STAT3);
406 int gpi_stat_tmp, pin_loc;
407 int i;
408
409 for (i = 0; i < kpad->gpimapsize; i++) {
410 unsigned short pin = kpad->gpimap[i].pin;
411
412 if (pin <= GPI_PIN_ROW_END) {
413 gpi_stat_tmp = gpi_stat1;
414 pin_loc = pin - GPI_PIN_ROW_BASE;
415 } else if ((pin - GPI_PIN_COL_BASE) < 8) {
416 gpi_stat_tmp = gpi_stat2;
417 pin_loc = pin - GPI_PIN_COL_BASE;
418 } else {
419 gpi_stat_tmp = gpi_stat3;
420 pin_loc = pin - GPI_PIN_COL_BASE - 8;
421 }
422
423 if (gpi_stat_tmp < 0) {
424 dev_err(&kpad->client->dev,
425 "Can't read GPIO_DAT_STAT switch %d default to OFF\n",
426 pin);
427 gpi_stat_tmp = 0;
428 }
429
430 input_report_switch(kpad->input,
431 kpad->gpimap[i].sw_evt,
432 !(gpi_stat_tmp & (1 << pin_loc)));
433 }
434
435 input_sync(kpad->input);
436}
437
438
Michael Hennerich88751dd2009-09-17 22:39:38 -0700439static int __devinit adp5588_probe(struct i2c_client *client,
440 const struct i2c_device_id *id)
441{
442 struct adp5588_kpad *kpad;
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700443 const struct adp5588_kpad_platform_data *pdata = client->dev.platform_data;
Michael Hennerich88751dd2009-09-17 22:39:38 -0700444 struct input_dev *input;
445 unsigned int revid;
446 int ret, i;
447 int error;
448
449 if (!i2c_check_functionality(client->adapter,
450 I2C_FUNC_SMBUS_BYTE_DATA)) {
451 dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
452 return -EIO;
453 }
454
455 if (!pdata) {
456 dev_err(&client->dev, "no platform data?\n");
457 return -EINVAL;
458 }
459
460 if (!pdata->rows || !pdata->cols || !pdata->keymap) {
461 dev_err(&client->dev, "no rows, cols or keymap from pdata\n");
462 return -EINVAL;
463 }
464
465 if (pdata->keymapsize != ADP5588_KEYMAPSIZE) {
466 dev_err(&client->dev, "invalid keymapsize\n");
467 return -EINVAL;
468 }
469
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700470 if (!pdata->gpimap && pdata->gpimapsize) {
471 dev_err(&client->dev, "invalid gpimap from pdata\n");
472 return -EINVAL;
473 }
474
475 if (pdata->gpimapsize > ADP5588_GPIMAPSIZE_MAX) {
476 dev_err(&client->dev, "invalid gpimapsize\n");
477 return -EINVAL;
478 }
479
480 for (i = 0; i < pdata->gpimapsize; i++) {
481 unsigned short pin = pdata->gpimap[i].pin;
482
483 if (pin < GPI_PIN_BASE || pin > GPI_PIN_END) {
484 dev_err(&client->dev, "invalid gpi pin data\n");
485 return -EINVAL;
486 }
487
488 if (pin <= GPI_PIN_ROW_END) {
489 if (pin - GPI_PIN_ROW_BASE + 1 <= pdata->rows) {
490 dev_err(&client->dev, "invalid gpi row data\n");
491 return -EINVAL;
492 }
493 } else {
494 if (pin - GPI_PIN_COL_BASE + 1 <= pdata->cols) {
495 dev_err(&client->dev, "invalid gpi col data\n");
496 return -EINVAL;
497 }
498 }
499 }
500
Michael Hennerich88751dd2009-09-17 22:39:38 -0700501 if (!client->irq) {
502 dev_err(&client->dev, "no IRQ?\n");
503 return -EINVAL;
504 }
505
506 kpad = kzalloc(sizeof(*kpad), GFP_KERNEL);
507 input = input_allocate_device();
508 if (!kpad || !input) {
509 error = -ENOMEM;
510 goto err_free_mem;
511 }
512
513 kpad->client = client;
514 kpad->input = input;
515 INIT_DELAYED_WORK(&kpad->work, adp5588_work);
516
517 ret = adp5588_read(client, DEV_ID);
518 if (ret < 0) {
519 error = ret;
520 goto err_free_mem;
521 }
522
523 revid = (u8) ret & ADP5588_DEVICE_ID_MASK;
524 if (WA_DELAYED_READOUT_REVID(revid))
525 kpad->delay = msecs_to_jiffies(30);
526
527 input->name = client->name;
528 input->phys = "adp5588-keys/input0";
529 input->dev.parent = &client->dev;
530
531 input_set_drvdata(input, kpad);
532
533 input->id.bustype = BUS_I2C;
534 input->id.vendor = 0x0001;
535 input->id.product = 0x0001;
536 input->id.version = revid;
537
538 input->keycodesize = sizeof(kpad->keycode[0]);
539 input->keycodemax = pdata->keymapsize;
540 input->keycode = kpad->keycode;
541
542 memcpy(kpad->keycode, pdata->keymap,
543 pdata->keymapsize * input->keycodesize);
544
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700545 kpad->gpimap = pdata->gpimap;
546 kpad->gpimapsize = pdata->gpimapsize;
547
Michael Hennerich88751dd2009-09-17 22:39:38 -0700548 /* setup input device */
549 __set_bit(EV_KEY, input->evbit);
550
551 if (pdata->repeat)
552 __set_bit(EV_REP, input->evbit);
553
554 for (i = 0; i < input->keycodemax; i++)
555 __set_bit(kpad->keycode[i] & KEY_MAX, input->keybit);
556 __clear_bit(KEY_RESERVED, input->keybit);
557
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700558 if (kpad->gpimapsize)
559 __set_bit(EV_SW, input->evbit);
560 for (i = 0; i < kpad->gpimapsize; i++)
561 __set_bit(kpad->gpimap[i].sw_evt, input->swbit);
562
Michael Hennerich88751dd2009-09-17 22:39:38 -0700563 error = input_register_device(input);
564 if (error) {
565 dev_err(&client->dev, "unable to register input device\n");
566 goto err_free_mem;
567 }
568
569 error = request_irq(client->irq, adp5588_irq,
570 IRQF_TRIGGER_FALLING | IRQF_DISABLED,
571 client->dev.driver->name, kpad);
572 if (error) {
573 dev_err(&client->dev, "irq %d busy?\n", client->irq);
574 goto err_unreg_dev;
575 }
576
577 error = adp5588_setup(client);
578 if (error)
579 goto err_free_irq;
580
Xiaolong CHEN69a4af62010-06-24 19:10:40 -0700581 if (kpad->gpimapsize)
582 adp5588_report_switch_state(kpad);
583
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700584 error = adp5588_gpio_add(&client->dev);
585 if (error)
586 goto err_free_irq;
587
Michael Hennerich88751dd2009-09-17 22:39:38 -0700588 device_init_wakeup(&client->dev, 1);
589 i2c_set_clientdata(client, kpad);
590
591 dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq);
592 return 0;
593
594 err_free_irq:
595 free_irq(client->irq, kpad);
596 err_unreg_dev:
597 input_unregister_device(input);
598 input = NULL;
599 err_free_mem:
600 input_free_device(input);
601 kfree(kpad);
602
603 return error;
604}
605
606static int __devexit adp5588_remove(struct i2c_client *client)
607{
608 struct adp5588_kpad *kpad = i2c_get_clientdata(client);
609
610 adp5588_write(client, CFG, 0);
611 free_irq(client->irq, kpad);
612 cancel_delayed_work_sync(&kpad->work);
613 input_unregister_device(kpad->input);
Xiaolong Chenba9f5072010-07-26 01:01:11 -0700614 adp5588_gpio_remove(&client->dev);
Michael Hennerich88751dd2009-09-17 22:39:38 -0700615 kfree(kpad);
616
617 return 0;
618}
619
620#ifdef CONFIG_PM
621static int adp5588_suspend(struct device *dev)
622{
623 struct adp5588_kpad *kpad = dev_get_drvdata(dev);
624 struct i2c_client *client = kpad->client;
625
626 disable_irq(client->irq);
627 cancel_delayed_work_sync(&kpad->work);
628
629 if (device_may_wakeup(&client->dev))
630 enable_irq_wake(client->irq);
631
632 return 0;
633}
634
635static int adp5588_resume(struct device *dev)
636{
637 struct adp5588_kpad *kpad = dev_get_drvdata(dev);
638 struct i2c_client *client = kpad->client;
639
640 if (device_may_wakeup(&client->dev))
641 disable_irq_wake(client->irq);
642
643 enable_irq(client->irq);
644
645 return 0;
646}
647
Alexey Dobriyan47145212009-12-14 18:00:08 -0800648static const struct dev_pm_ops adp5588_dev_pm_ops = {
Michael Hennerich88751dd2009-09-17 22:39:38 -0700649 .suspend = adp5588_suspend,
650 .resume = adp5588_resume,
651};
652#endif
653
654static const struct i2c_device_id adp5588_id[] = {
655 { KBUILD_MODNAME, 0 },
Michael Hennerich5a9003d2010-01-19 00:28:44 -0800656 { "adp5587-keys", 0 },
Michael Hennerich88751dd2009-09-17 22:39:38 -0700657 { }
658};
659MODULE_DEVICE_TABLE(i2c, adp5588_id);
660
661static struct i2c_driver adp5588_driver = {
662 .driver = {
663 .name = KBUILD_MODNAME,
664#ifdef CONFIG_PM
665 .pm = &adp5588_dev_pm_ops,
666#endif
667 },
668 .probe = adp5588_probe,
669 .remove = __devexit_p(adp5588_remove),
670 .id_table = adp5588_id,
671};
672
673static int __init adp5588_init(void)
674{
675 return i2c_add_driver(&adp5588_driver);
676}
677module_init(adp5588_init);
678
679static void __exit adp5588_exit(void)
680{
681 i2c_del_driver(&adp5588_driver);
682}
683module_exit(adp5588_exit);
684
685MODULE_LICENSE("GPL");
686MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
Michael Hennerich5a9003d2010-01-19 00:28:44 -0800687MODULE_DESCRIPTION("ADP5588/87 Keypad driver");
Michael Hennerich88751dd2009-09-17 22:39:38 -0700688MODULE_ALIAS("platform:adp5588-keys");