• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/drivers/input/keyboard/
1/*
2 * File: drivers/input/keyboard/adp5588_keys.c
3 * Description:  keypad driver for ADP5588 and ADP5587
4 *		 I2C QWERTY Keypad and IO Expander
5 * 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>
22#include <linux/gpio.h>
23#include <linux/slab.h>
24
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
58#define MAXGPIO			18
59#define ADP_BANK(offs)		((offs) >> 3)
60#define ADP_BIT(offs)		(1u << ((offs) & 0x7))
61
62/*
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];
75	const struct adp5588_gpi_map *gpimap;
76	unsigned short gpimapsize;
77#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
85};
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
102#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_build_gpiomap(struct adp5588_kpad *kpad,
177				const struct adp5588_kpad_platform_data *pdata)
178{
179	bool pin_used[MAXGPIO];
180	int n_unused = 0;
181	int i;
182
183	memset(pin_used, 0, sizeof(pin_used));
184
185	for (i = 0; i < pdata->rows; i++)
186		pin_used[i] = true;
187
188	for (i = 0; i < pdata->cols; i++)
189		pin_used[i + GPI_PIN_COL_BASE - GPI_PIN_BASE] = true;
190
191	for (i = 0; i < kpad->gpimapsize; i++)
192		pin_used[kpad->gpimap[i].pin - GPI_PIN_BASE] = true;
193
194	for (i = 0; i < MAXGPIO; i++)
195		if (!pin_used[i])
196			kpad->gpiomap[n_unused++] = i;
197
198	return n_unused;
199}
200
201static int __devinit adp5588_gpio_add(struct adp5588_kpad *kpad)
202{
203	struct device *dev = &kpad->client->dev;
204	const struct adp5588_kpad_platform_data *pdata = dev->platform_data;
205	const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data;
206	int i, error;
207
208	if (!gpio_data)
209		return 0;
210
211	kpad->gc.ngpio = adp5588_build_gpiomap(kpad, pdata);
212	if (kpad->gc.ngpio == 0) {
213		dev_info(dev, "No unused gpios left to export\n");
214		return 0;
215	}
216
217	kpad->export_gpio = true;
218
219	kpad->gc.direction_input = adp5588_gpio_direction_input;
220	kpad->gc.direction_output = adp5588_gpio_direction_output;
221	kpad->gc.get = adp5588_gpio_get_value;
222	kpad->gc.set = adp5588_gpio_set_value;
223	kpad->gc.can_sleep = 1;
224
225	kpad->gc.base = gpio_data->gpio_start;
226	kpad->gc.label = kpad->client->name;
227	kpad->gc.owner = THIS_MODULE;
228
229	mutex_init(&kpad->gpio_lock);
230
231	error = gpiochip_add(&kpad->gc);
232	if (error) {
233		dev_err(dev, "gpiochip_add failed, err: %d\n", error);
234		return error;
235	}
236
237	for (i = 0; i <= ADP_BANK(MAXGPIO); i++) {
238		kpad->dat_out[i] = adp5588_read(kpad->client,
239						GPIO_DAT_OUT1 + i);
240		kpad->dir[i] = adp5588_read(kpad->client, GPIO_DIR1 + i);
241	}
242
243	if (gpio_data->setup) {
244		error = gpio_data->setup(kpad->client,
245					 kpad->gc.base, kpad->gc.ngpio,
246					 gpio_data->context);
247		if (error)
248			dev_warn(dev, "setup failed, %d\n", error);
249	}
250
251	return 0;
252}
253
254static void __devexit adp5588_gpio_remove(struct adp5588_kpad *kpad)
255{
256	struct device *dev = &kpad->client->dev;
257	const struct adp5588_kpad_platform_data *pdata = dev->platform_data;
258	const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data;
259	int error;
260
261	if (!kpad->export_gpio)
262		return;
263
264	if (gpio_data->teardown) {
265		error = gpio_data->teardown(kpad->client,
266					    kpad->gc.base, kpad->gc.ngpio,
267					    gpio_data->context);
268		if (error)
269			dev_warn(dev, "teardown failed %d\n", error);
270	}
271
272	error = gpiochip_remove(&kpad->gc);
273	if (error)
274		dev_warn(dev, "gpiochip_remove failed %d\n", error);
275}
276#else
277static inline int adp5588_gpio_add(struct adp5588_kpad *kpad)
278{
279	return 0;
280}
281
282static inline void adp5588_gpio_remove(struct adp5588_kpad *kpad)
283{
284}
285#endif
286
287static void adp5588_report_events(struct adp5588_kpad *kpad, int ev_cnt)
288{
289	int i, j;
290
291	for (i = 0; i < ev_cnt; i++) {
292		int key = adp5588_read(kpad->client, Key_EVENTA + i);
293		int key_val = key & KEY_EV_MASK;
294
295		if (key_val >= GPI_PIN_BASE && key_val <= GPI_PIN_END) {
296			for (j = 0; j < kpad->gpimapsize; j++) {
297				if (key_val == kpad->gpimap[j].pin) {
298					input_report_switch(kpad->input,
299							kpad->gpimap[j].sw_evt,
300							key & KEY_EV_PRESSED);
301					break;
302				}
303			}
304		} else {
305			input_report_key(kpad->input,
306					 kpad->keycode[key_val - 1],
307					 key & KEY_EV_PRESSED);
308		}
309	}
310}
311
312static void adp5588_work(struct work_struct *work)
313{
314	struct adp5588_kpad *kpad = container_of(work,
315						struct adp5588_kpad, work.work);
316	struct i2c_client *client = kpad->client;
317	int status, ev_cnt;
318
319	status = adp5588_read(client, INT_STAT);
320
321	if (status & OVR_FLOW_INT)	/* Unlikely and should never happen */
322		dev_err(&client->dev, "Event Overflow Error\n");
323
324	if (status & KE_INT) {
325		ev_cnt = adp5588_read(client, KEY_LCK_EC_STAT) & KEC;
326		if (ev_cnt) {
327			adp5588_report_events(kpad, ev_cnt);
328			input_sync(kpad->input);
329		}
330	}
331	adp5588_write(client, INT_STAT, status); /* Status is W1C */
332}
333
334static irqreturn_t adp5588_irq(int irq, void *handle)
335{
336	struct adp5588_kpad *kpad = handle;
337
338	/*
339	 * use keventd context to read the event fifo registers
340	 * Schedule readout at least 25ms after notification for
341	 * REVID < 4
342	 */
343
344	schedule_delayed_work(&kpad->work, kpad->delay);
345
346	return IRQ_HANDLED;
347}
348
349static int __devinit adp5588_setup(struct i2c_client *client)
350{
351	const struct adp5588_kpad_platform_data *pdata = client->dev.platform_data;
352	const struct adp5588_gpio_platform_data *gpio_data = pdata->gpio_data;
353	int i, ret;
354	unsigned char evt_mode1 = 0, evt_mode2 = 0, evt_mode3 = 0;
355
356	ret = adp5588_write(client, KP_GPIO1, KP_SEL(pdata->rows));
357	ret |= adp5588_write(client, KP_GPIO2, KP_SEL(pdata->cols) & 0xFF);
358	ret |= adp5588_write(client, KP_GPIO3, KP_SEL(pdata->cols) >> 8);
359
360	if (pdata->en_keylock) {
361		ret |= adp5588_write(client, UNLOCK1, pdata->unlock_key1);
362		ret |= adp5588_write(client, UNLOCK2, pdata->unlock_key2);
363		ret |= adp5588_write(client, KEY_LCK_EC_STAT, K_LCK_EN);
364	}
365
366	for (i = 0; i < KEYP_MAX_EVENT; i++)
367		ret |= adp5588_read(client, Key_EVENTA);
368
369	for (i = 0; i < pdata->gpimapsize; i++) {
370		unsigned short pin = pdata->gpimap[i].pin;
371
372		if (pin <= GPI_PIN_ROW_END) {
373			evt_mode1 |= (1 << (pin - GPI_PIN_ROW_BASE));
374		} else {
375			evt_mode2 |= ((1 << (pin - GPI_PIN_COL_BASE)) & 0xFF);
376			evt_mode3 |= ((1 << (pin - GPI_PIN_COL_BASE)) >> 8);
377		}
378	}
379
380	if (pdata->gpimapsize) {
381		ret |= adp5588_write(client, GPI_EM1, evt_mode1);
382		ret |= adp5588_write(client, GPI_EM2, evt_mode2);
383		ret |= adp5588_write(client, GPI_EM3, evt_mode3);
384	}
385
386	if (gpio_data) {
387		for (i = 0; i <= ADP_BANK(MAXGPIO); i++) {
388			int pull_mask = gpio_data->pullup_dis_mask;
389
390			ret |= adp5588_write(client, GPIO_PULL1 + i,
391				(pull_mask >> (8 * i)) & 0xFF);
392		}
393	}
394
395	ret |= adp5588_write(client, INT_STAT, CMP2_INT | CMP1_INT |
396					OVR_FLOW_INT | K_LCK_INT |
397					GPI_INT | KE_INT); /* Status is W1C */
398
399	ret |= adp5588_write(client, CFG, INT_CFG | OVR_FLOW_IEN | KE_IEN);
400
401	if (ret < 0) {
402		dev_err(&client->dev, "Write Error\n");
403		return ret;
404	}
405
406	return 0;
407}
408
409static void __devinit adp5588_report_switch_state(struct adp5588_kpad *kpad)
410{
411	int gpi_stat1 = adp5588_read(kpad->client, GPIO_DAT_STAT1);
412	int gpi_stat2 = adp5588_read(kpad->client, GPIO_DAT_STAT2);
413	int gpi_stat3 = adp5588_read(kpad->client, GPIO_DAT_STAT3);
414	int gpi_stat_tmp, pin_loc;
415	int i;
416
417	for (i = 0; i < kpad->gpimapsize; i++) {
418		unsigned short pin = kpad->gpimap[i].pin;
419
420		if (pin <= GPI_PIN_ROW_END) {
421			gpi_stat_tmp = gpi_stat1;
422			pin_loc = pin - GPI_PIN_ROW_BASE;
423		} else if ((pin - GPI_PIN_COL_BASE) < 8) {
424			gpi_stat_tmp = gpi_stat2;
425			pin_loc = pin - GPI_PIN_COL_BASE;
426		} else {
427			gpi_stat_tmp = gpi_stat3;
428			pin_loc = pin - GPI_PIN_COL_BASE - 8;
429		}
430
431		if (gpi_stat_tmp < 0) {
432			dev_err(&kpad->client->dev,
433				"Can't read GPIO_DAT_STAT switch %d default to OFF\n",
434				pin);
435			gpi_stat_tmp = 0;
436		}
437
438		input_report_switch(kpad->input,
439				    kpad->gpimap[i].sw_evt,
440				    !(gpi_stat_tmp & (1 << pin_loc)));
441	}
442
443	input_sync(kpad->input);
444}
445
446
447static int __devinit adp5588_probe(struct i2c_client *client,
448					const struct i2c_device_id *id)
449{
450	struct adp5588_kpad *kpad;
451	const struct adp5588_kpad_platform_data *pdata = client->dev.platform_data;
452	struct input_dev *input;
453	unsigned int revid;
454	int ret, i;
455	int error;
456
457	if (!i2c_check_functionality(client->adapter,
458					I2C_FUNC_SMBUS_BYTE_DATA)) {
459		dev_err(&client->dev, "SMBUS Byte Data not Supported\n");
460		return -EIO;
461	}
462
463	if (!pdata) {
464		dev_err(&client->dev, "no platform data?\n");
465		return -EINVAL;
466	}
467
468	if (!pdata->rows || !pdata->cols || !pdata->keymap) {
469		dev_err(&client->dev, "no rows, cols or keymap from pdata\n");
470		return -EINVAL;
471	}
472
473	if (pdata->keymapsize != ADP5588_KEYMAPSIZE) {
474		dev_err(&client->dev, "invalid keymapsize\n");
475		return -EINVAL;
476	}
477
478	if (!pdata->gpimap && pdata->gpimapsize) {
479		dev_err(&client->dev, "invalid gpimap from pdata\n");
480		return -EINVAL;
481	}
482
483	if (pdata->gpimapsize > ADP5588_GPIMAPSIZE_MAX) {
484		dev_err(&client->dev, "invalid gpimapsize\n");
485		return -EINVAL;
486	}
487
488	for (i = 0; i < pdata->gpimapsize; i++) {
489		unsigned short pin = pdata->gpimap[i].pin;
490
491		if (pin < GPI_PIN_BASE || pin > GPI_PIN_END) {
492			dev_err(&client->dev, "invalid gpi pin data\n");
493			return -EINVAL;
494		}
495
496		if (pin <= GPI_PIN_ROW_END) {
497			if (pin - GPI_PIN_ROW_BASE + 1 <= pdata->rows) {
498				dev_err(&client->dev, "invalid gpi row data\n");
499				return -EINVAL;
500			}
501		} else {
502			if (pin - GPI_PIN_COL_BASE + 1 <= pdata->cols) {
503				dev_err(&client->dev, "invalid gpi col data\n");
504				return -EINVAL;
505			}
506		}
507	}
508
509	if (!client->irq) {
510		dev_err(&client->dev, "no IRQ?\n");
511		return -EINVAL;
512	}
513
514	kpad = kzalloc(sizeof(*kpad), GFP_KERNEL);
515	input = input_allocate_device();
516	if (!kpad || !input) {
517		error = -ENOMEM;
518		goto err_free_mem;
519	}
520
521	kpad->client = client;
522	kpad->input = input;
523	INIT_DELAYED_WORK(&kpad->work, adp5588_work);
524
525	ret = adp5588_read(client, DEV_ID);
526	if (ret < 0) {
527		error = ret;
528		goto err_free_mem;
529	}
530
531	revid = (u8) ret & ADP5588_DEVICE_ID_MASK;
532	if (WA_DELAYED_READOUT_REVID(revid))
533		kpad->delay = msecs_to_jiffies(30);
534
535	input->name = client->name;
536	input->phys = "adp5588-keys/input0";
537	input->dev.parent = &client->dev;
538
539	input_set_drvdata(input, kpad);
540
541	input->id.bustype = BUS_I2C;
542	input->id.vendor = 0x0001;
543	input->id.product = 0x0001;
544	input->id.version = revid;
545
546	input->keycodesize = sizeof(kpad->keycode[0]);
547	input->keycodemax = pdata->keymapsize;
548	input->keycode = kpad->keycode;
549
550	memcpy(kpad->keycode, pdata->keymap,
551		pdata->keymapsize * input->keycodesize);
552
553	kpad->gpimap = pdata->gpimap;
554	kpad->gpimapsize = pdata->gpimapsize;
555
556	/* setup input device */
557	__set_bit(EV_KEY, input->evbit);
558
559	if (pdata->repeat)
560		__set_bit(EV_REP, input->evbit);
561
562	for (i = 0; i < input->keycodemax; i++)
563		__set_bit(kpad->keycode[i] & KEY_MAX, input->keybit);
564	__clear_bit(KEY_RESERVED, input->keybit);
565
566	if (kpad->gpimapsize)
567		__set_bit(EV_SW, input->evbit);
568	for (i = 0; i < kpad->gpimapsize; i++)
569		__set_bit(kpad->gpimap[i].sw_evt, input->swbit);
570
571	error = input_register_device(input);
572	if (error) {
573		dev_err(&client->dev, "unable to register input device\n");
574		goto err_free_mem;
575	}
576
577	error = request_irq(client->irq, adp5588_irq,
578			    IRQF_TRIGGER_FALLING | IRQF_DISABLED,
579			    client->dev.driver->name, kpad);
580	if (error) {
581		dev_err(&client->dev, "irq %d busy?\n", client->irq);
582		goto err_unreg_dev;
583	}
584
585	error = adp5588_setup(client);
586	if (error)
587		goto err_free_irq;
588
589	if (kpad->gpimapsize)
590		adp5588_report_switch_state(kpad);
591
592	error = adp5588_gpio_add(kpad);
593	if (error)
594		goto err_free_irq;
595
596	device_init_wakeup(&client->dev, 1);
597	i2c_set_clientdata(client, kpad);
598
599	dev_info(&client->dev, "Rev.%d keypad, irq %d\n", revid, client->irq);
600	return 0;
601
602 err_free_irq:
603	free_irq(client->irq, kpad);
604 err_unreg_dev:
605	input_unregister_device(input);
606	input = NULL;
607 err_free_mem:
608	input_free_device(input);
609	kfree(kpad);
610
611	return error;
612}
613
614static int __devexit adp5588_remove(struct i2c_client *client)
615{
616	struct adp5588_kpad *kpad = i2c_get_clientdata(client);
617
618	adp5588_write(client, CFG, 0);
619	free_irq(client->irq, kpad);
620	cancel_delayed_work_sync(&kpad->work);
621	input_unregister_device(kpad->input);
622	adp5588_gpio_remove(kpad);
623	kfree(kpad);
624
625	return 0;
626}
627
628#ifdef CONFIG_PM
629static int adp5588_suspend(struct device *dev)
630{
631	struct adp5588_kpad *kpad = dev_get_drvdata(dev);
632	struct i2c_client *client = kpad->client;
633
634	disable_irq(client->irq);
635	cancel_delayed_work_sync(&kpad->work);
636
637	if (device_may_wakeup(&client->dev))
638		enable_irq_wake(client->irq);
639
640	return 0;
641}
642
643static int adp5588_resume(struct device *dev)
644{
645	struct adp5588_kpad *kpad = dev_get_drvdata(dev);
646	struct i2c_client *client = kpad->client;
647
648	if (device_may_wakeup(&client->dev))
649		disable_irq_wake(client->irq);
650
651	enable_irq(client->irq);
652
653	return 0;
654}
655
656static const struct dev_pm_ops adp5588_dev_pm_ops = {
657	.suspend = adp5588_suspend,
658	.resume  = adp5588_resume,
659};
660#endif
661
662static const struct i2c_device_id adp5588_id[] = {
663	{ KBUILD_MODNAME, 0 },
664	{ "adp5587-keys", 0 },
665	{ }
666};
667MODULE_DEVICE_TABLE(i2c, adp5588_id);
668
669static struct i2c_driver adp5588_driver = {
670	.driver = {
671		.name = KBUILD_MODNAME,
672#ifdef CONFIG_PM
673		.pm   = &adp5588_dev_pm_ops,
674#endif
675	},
676	.probe    = adp5588_probe,
677	.remove   = __devexit_p(adp5588_remove),
678	.id_table = adp5588_id,
679};
680
681static int __init adp5588_init(void)
682{
683	return i2c_add_driver(&adp5588_driver);
684}
685module_init(adp5588_init);
686
687static void __exit adp5588_exit(void)
688{
689	i2c_del_driver(&adp5588_driver);
690}
691module_exit(adp5588_exit);
692
693MODULE_LICENSE("GPL");
694MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
695MODULE_DESCRIPTION("ADP5588/87 Keypad driver");
696MODULE_ALIAS("platform:adp5588-keys");
697