2 * SPEAr Keyboard Driver
3 * Based on omap-keypad driver
5 * Copyright (C) 2010 ST Microelectronics
6 * Rajeev Kumar<rajeev-dlh.kumar@st.com>
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
13 #include <linux/clk.h>
14 #include <linux/errno.h>
15 #include <linux/init.h>
16 #include <linux/interrupt.h>
17 #include <linux/input.h>
19 #include <linux/irq.h>
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/platform_device.h>
23 #include <linux/pm_wakeup.h>
24 #include <linux/slab.h>
25 #include <linux/types.h>
26 #include <plat/keyboard.h>
28 /* Keyboard Registers */
29 #define MODE_REG 0x00 /* 16 bit reg */
30 #define STATUS_REG 0x0C /* 2 bit reg */
31 #define DATA_REG 0x10 /* 8 bit reg */
32 #define INTR_MASK 0x54
36 * pclk freq mask = (APB FEQ -1)= 82 MHZ.Programme bit 15-9 in mode
37 * control register as 1010010(82MHZ)
39 #define PCLK_FREQ_MSK 0xA400 /* 82 MHz */
40 #define START_SCAN 0x0100
41 #define SCAN_RATE_10 0x0000
42 #define SCAN_RATE_20 0x0004
43 #define SCAN_RATE_40 0x0008
44 #define SCAN_RATE_80 0x000C
45 #define MODE_KEYBOARD 0x0002
46 #define DATA_AVAIL 0x2
48 #define KEY_MASK 0xFF000000
49 #define KEY_VALUE 0x00FFFFFF
51 #define COLUMN_MASK 0x0F
53 #define KEY_MATRIX_SHIFT 6
56 struct input_dev
*input
;
58 void __iomem
*io_base
;
62 unsigned short last_key
;
63 unsigned short keycodes
[256];
66 static irqreturn_t
spear_kbd_interrupt(int irq
, void *dev_id
)
68 struct spear_kbd
*kbd
= dev_id
;
69 struct input_dev
*input
= kbd
->input
;
73 sts
= readb(kbd
->io_base
+ STATUS_REG
);
74 if (!(sts
& DATA_AVAIL
))
77 if (kbd
->last_key
!= KEY_RESERVED
) {
78 input_report_key(input
, kbd
->last_key
, 0);
79 kbd
->last_key
= KEY_RESERVED
;
82 /* following reads active (row, col) pair */
83 val
= readb(kbd
->io_base
+ DATA_REG
);
84 key
= kbd
->keycodes
[val
];
86 input_event(input
, EV_MSC
, MSC_SCAN
, val
);
87 input_report_key(input
, key
, 1);
93 writeb(0, kbd
->io_base
+ STATUS_REG
);
98 static int spear_kbd_open(struct input_dev
*dev
)
100 struct spear_kbd
*kbd
= input_get_drvdata(dev
);
104 kbd
->last_key
= KEY_RESERVED
;
106 error
= clk_enable(kbd
->clk
);
110 /* program keyboard */
111 val
= SCAN_RATE_80
| MODE_KEYBOARD
| PCLK_FREQ_MSK
|
112 (kbd
->mode
<< KEY_MATRIX_SHIFT
);
113 writew(val
, kbd
->io_base
+ MODE_REG
);
114 writeb(1, kbd
->io_base
+ STATUS_REG
);
117 val
= readw(kbd
->io_base
+ MODE_REG
);
119 writew(val
, kbd
->io_base
+ MODE_REG
);
124 static void spear_kbd_close(struct input_dev
*dev
)
126 struct spear_kbd
*kbd
= input_get_drvdata(dev
);
130 val
= readw(kbd
->io_base
+ MODE_REG
);
132 writew(val
, kbd
->io_base
+ MODE_REG
);
134 clk_disable(kbd
->clk
);
136 kbd
->last_key
= KEY_RESERVED
;
139 static int __devinit
spear_kbd_probe(struct platform_device
*pdev
)
141 const struct kbd_platform_data
*pdata
= pdev
->dev
.platform_data
;
142 const struct matrix_keymap_data
*keymap
;
143 struct spear_kbd
*kbd
;
144 struct input_dev
*input_dev
;
145 struct resource
*res
;
150 dev_err(&pdev
->dev
, "Invalid platform data\n");
154 keymap
= pdata
->keymap
;
156 dev_err(&pdev
->dev
, "no keymap defined\n");
160 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
162 dev_err(&pdev
->dev
, "no keyboard resource defined\n");
166 irq
= platform_get_irq(pdev
, 0);
168 dev_err(&pdev
->dev
, "not able to get irq for the device\n");
172 kbd
= kzalloc(sizeof(*kbd
), GFP_KERNEL
);
173 input_dev
= input_allocate_device();
174 if (!kbd
|| !input_dev
) {
175 dev_err(&pdev
->dev
, "out of memory\n");
180 kbd
->input
= input_dev
;
182 kbd
->mode
= pdata
->mode
;
184 kbd
->res
= request_mem_region(res
->start
, resource_size(res
),
187 dev_err(&pdev
->dev
, "keyboard region already claimed\n");
192 kbd
->io_base
= ioremap(res
->start
, resource_size(res
));
194 dev_err(&pdev
->dev
, "ioremap failed for kbd_region\n");
196 goto err_release_mem_region
;
199 kbd
->clk
= clk_get(&pdev
->dev
, NULL
);
200 if (IS_ERR(kbd
->clk
)) {
201 error
= PTR_ERR(kbd
->clk
);
205 input_dev
->name
= "Spear Keyboard";
206 input_dev
->phys
= "keyboard/input0";
207 input_dev
->dev
.parent
= &pdev
->dev
;
208 input_dev
->id
.bustype
= BUS_HOST
;
209 input_dev
->id
.vendor
= 0x0001;
210 input_dev
->id
.product
= 0x0001;
211 input_dev
->id
.version
= 0x0100;
212 input_dev
->open
= spear_kbd_open
;
213 input_dev
->close
= spear_kbd_close
;
215 __set_bit(EV_KEY
, input_dev
->evbit
);
217 __set_bit(EV_REP
, input_dev
->evbit
);
218 input_set_capability(input_dev
, EV_MSC
, MSC_SCAN
);
220 input_dev
->keycode
= kbd
->keycodes
;
221 input_dev
->keycodesize
= sizeof(kbd
->keycodes
[0]);
222 input_dev
->keycodemax
= ARRAY_SIZE(kbd
->keycodes
);
224 matrix_keypad_build_keymap(keymap
, ROW_SHIFT
,
225 input_dev
->keycode
, input_dev
->keybit
);
227 input_set_drvdata(input_dev
, kbd
);
229 error
= request_irq(irq
, spear_kbd_interrupt
, 0, "keyboard", kbd
);
231 dev_err(&pdev
->dev
, "request_irq fail\n");
235 error
= input_register_device(input_dev
);
237 dev_err(&pdev
->dev
, "Unable to register keyboard device\n");
241 device_init_wakeup(&pdev
->dev
, 1);
242 platform_set_drvdata(pdev
, kbd
);
247 free_irq(kbd
->irq
, kbd
);
251 iounmap(kbd
->io_base
);
252 err_release_mem_region
:
253 release_mem_region(res
->start
, resource_size(res
));
255 input_free_device(input_dev
);
261 static int __devexit
spear_kbd_remove(struct platform_device
*pdev
)
263 struct spear_kbd
*kbd
= platform_get_drvdata(pdev
);
265 free_irq(kbd
->irq
, kbd
);
266 input_unregister_device(kbd
->input
);
268 iounmap(kbd
->io_base
);
269 release_mem_region(kbd
->res
->start
, resource_size(kbd
->res
));
272 device_init_wakeup(&pdev
->dev
, 1);
273 platform_set_drvdata(pdev
, NULL
);
279 static int spear_kbd_suspend(struct device
*dev
)
281 struct platform_device
*pdev
= to_platform_device(dev
);
282 struct spear_kbd
*kbd
= platform_get_drvdata(pdev
);
283 struct input_dev
*input_dev
= kbd
->input
;
285 mutex_lock(&input_dev
->mutex
);
287 if (input_dev
->users
)
288 clk_enable(kbd
->clk
);
290 if (device_may_wakeup(&pdev
->dev
))
291 enable_irq_wake(kbd
->irq
);
293 mutex_unlock(&input_dev
->mutex
);
298 static int spear_kbd_resume(struct device
*dev
)
300 struct platform_device
*pdev
= to_platform_device(dev
);
301 struct spear_kbd
*kbd
= platform_get_drvdata(pdev
);
302 struct input_dev
*input_dev
= kbd
->input
;
304 mutex_lock(&input_dev
->mutex
);
306 if (device_may_wakeup(&pdev
->dev
))
307 disable_irq_wake(kbd
->irq
);
309 if (input_dev
->users
)
310 clk_enable(kbd
->clk
);
312 mutex_unlock(&input_dev
->mutex
);
318 static SIMPLE_DEV_PM_OPS(spear_kbd_pm_ops
, spear_kbd_suspend
, spear_kbd_resume
);
320 static struct platform_driver spear_kbd_driver
= {
321 .probe
= spear_kbd_probe
,
322 .remove
= __devexit_p(spear_kbd_remove
),
325 .owner
= THIS_MODULE
,
326 .pm
= &spear_kbd_pm_ops
,
329 module_platform_driver(spear_kbd_driver
);
331 MODULE_AUTHOR("Rajeev Kumar");
332 MODULE_DESCRIPTION("SPEAr Keyboard Driver");
333 MODULE_LICENSE("GPL");