2 * Keypad driver for Analog Devices ADP5520 MFD PMICs
4 * Copyright 2009 Analog Devices Inc.
6 * Licensed under the GPL-2 or later.
9 #include <linux/module.h>
10 #include <linux/kernel.h>
11 #include <linux/platform_device.h>
12 #include <linux/input.h>
13 #include <linux/mfd/adp5520.h>
14 #include <linux/slab.h>
17 struct input_dev
*input
;
18 struct notifier_block notifier
;
19 struct device
*master
;
20 unsigned short keycode
[ADP5520_KEYMAPSIZE
];
23 static void adp5520_keys_report_event(struct adp5520_keys
*dev
,
24 unsigned short keymask
, int value
)
28 for (i
= 0; i
< ADP5520_MAXKEYS
; i
++)
29 if (keymask
& (1 << i
))
30 input_report_key(dev
->input
, dev
->keycode
[i
], value
);
32 input_sync(dev
->input
);
35 static int adp5520_keys_notifier(struct notifier_block
*nb
,
36 unsigned long event
, void *data
)
38 struct adp5520_keys
*dev
;
39 uint8_t reg_val_lo
, reg_val_hi
;
40 unsigned short keymask
;
42 dev
= container_of(nb
, struct adp5520_keys
, notifier
);
44 if (event
& ADP5520_KP_INT
) {
45 adp5520_read(dev
->master
, ADP5520_KP_INT_STAT_1
, ®_val_lo
);
46 adp5520_read(dev
->master
, ADP5520_KP_INT_STAT_2
, ®_val_hi
);
48 keymask
= (reg_val_hi
<< 8) | reg_val_lo
;
49 /* Read twice to clear */
50 adp5520_read(dev
->master
, ADP5520_KP_INT_STAT_1
, ®_val_lo
);
51 adp5520_read(dev
->master
, ADP5520_KP_INT_STAT_2
, ®_val_hi
);
52 keymask
|= (reg_val_hi
<< 8) | reg_val_lo
;
53 adp5520_keys_report_event(dev
, keymask
, 1);
56 if (event
& ADP5520_KR_INT
) {
57 adp5520_read(dev
->master
, ADP5520_KR_INT_STAT_1
, ®_val_lo
);
58 adp5520_read(dev
->master
, ADP5520_KR_INT_STAT_2
, ®_val_hi
);
60 keymask
= (reg_val_hi
<< 8) | reg_val_lo
;
61 /* Read twice to clear */
62 adp5520_read(dev
->master
, ADP5520_KR_INT_STAT_1
, ®_val_lo
);
63 adp5520_read(dev
->master
, ADP5520_KR_INT_STAT_2
, ®_val_hi
);
64 keymask
|= (reg_val_hi
<< 8) | reg_val_lo
;
65 adp5520_keys_report_event(dev
, keymask
, 0);
71 static int adp5520_keys_probe(struct platform_device
*pdev
)
73 struct adp5520_keys_platform_data
*pdata
= dev_get_platdata(&pdev
->dev
);
74 struct input_dev
*input
;
75 struct adp5520_keys
*dev
;
77 unsigned char en_mask
, ctl_mask
= 0;
79 if (pdev
->id
!= ID_ADP5520
) {
80 dev_err(&pdev
->dev
, "only ADP5520 supports Keypad\n");
85 dev_err(&pdev
->dev
, "missing platform data\n");
89 if (!(pdata
->rows_en_mask
&& pdata
->cols_en_mask
))
92 dev
= kzalloc(sizeof(*dev
), GFP_KERNEL
);
94 dev_err(&pdev
->dev
, "failed to alloc memory\n");
98 input
= input_allocate_device();
104 dev
->master
= pdev
->dev
.parent
;
107 input
->name
= pdev
->name
;
108 input
->phys
= "adp5520-keys/input0";
109 input
->dev
.parent
= &pdev
->dev
;
111 input_set_drvdata(input
, dev
);
113 input
->id
.bustype
= BUS_I2C
;
114 input
->id
.vendor
= 0x0001;
115 input
->id
.product
= 0x5520;
116 input
->id
.version
= 0x0001;
118 input
->keycodesize
= sizeof(dev
->keycode
[0]);
119 input
->keycodemax
= pdata
->keymapsize
;
120 input
->keycode
= dev
->keycode
;
122 memcpy(dev
->keycode
, pdata
->keymap
,
123 pdata
->keymapsize
* input
->keycodesize
);
125 /* setup input device */
126 __set_bit(EV_KEY
, input
->evbit
);
129 __set_bit(EV_REP
, input
->evbit
);
131 for (i
= 0; i
< input
->keycodemax
; i
++)
132 __set_bit(dev
->keycode
[i
], input
->keybit
);
133 __clear_bit(KEY_RESERVED
, input
->keybit
);
135 ret
= input_register_device(input
);
137 dev_err(&pdev
->dev
, "unable to register input device\n");
141 en_mask
= pdata
->rows_en_mask
| pdata
->cols_en_mask
;
143 ret
= adp5520_set_bits(dev
->master
, ADP5520_GPIO_CFG_1
, en_mask
);
145 if (en_mask
& ADP5520_COL_C3
)
146 ctl_mask
|= ADP5520_C3_MODE
;
148 if (en_mask
& ADP5520_ROW_R3
)
149 ctl_mask
|= ADP5520_R3_MODE
;
152 ret
|= adp5520_set_bits(dev
->master
, ADP5520_LED_CONTROL
,
155 ret
|= adp5520_set_bits(dev
->master
, ADP5520_GPIO_PULLUP
,
156 pdata
->rows_en_mask
);
159 dev_err(&pdev
->dev
, "failed to write\n");
164 dev
->notifier
.notifier_call
= adp5520_keys_notifier
;
165 ret
= adp5520_register_notifier(dev
->master
, &dev
->notifier
,
166 ADP5520_KP_IEN
| ADP5520_KR_IEN
);
168 dev_err(&pdev
->dev
, "failed to register notifier\n");
172 platform_set_drvdata(pdev
, dev
);
176 input_unregister_device(input
);
179 input_free_device(input
);
184 static int adp5520_keys_remove(struct platform_device
*pdev
)
186 struct adp5520_keys
*dev
= platform_get_drvdata(pdev
);
188 adp5520_unregister_notifier(dev
->master
, &dev
->notifier
,
189 ADP5520_KP_IEN
| ADP5520_KR_IEN
);
191 input_unregister_device(dev
->input
);
196 static struct platform_driver adp5520_keys_driver
= {
198 .name
= "adp5520-keys",
199 .owner
= THIS_MODULE
,
201 .probe
= adp5520_keys_probe
,
202 .remove
= adp5520_keys_remove
,
204 module_platform_driver(adp5520_keys_driver
);
206 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
207 MODULE_DESCRIPTION("Keys ADP5520 Driver");
208 MODULE_LICENSE("GPL");
209 MODULE_ALIAS("platform:adp5520-keys");