2 * Cobalt button interface driver.
4 * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #include <linux/init.h>
21 #include <linux/input-polldev.h>
22 #include <linux/ioport.h>
23 #include <linux/module.h>
24 #include <linux/platform_device.h>
26 #define BUTTONS_POLL_INTERVAL 30 /* msec */
27 #define BUTTONS_COUNT_THRESHOLD 3
28 #define BUTTONS_STATUS_MASK 0xfe000000
31 struct input_polled_dev
*poll_dev
;
41 static struct buttons_map buttons_map
[] = {
42 { 0x02000000, KEY_RESTART
, },
43 { 0x04000000, KEY_LEFT
, },
44 { 0x08000000, KEY_UP
, },
45 { 0x10000000, KEY_DOWN
, },
46 { 0x20000000, KEY_RIGHT
, },
47 { 0x40000000, KEY_ENTER
, },
48 { 0x80000000, KEY_SELECT
, },
51 static void handle_buttons(struct input_polled_dev
*dev
)
53 struct buttons_map
*button
= buttons_map
;
54 struct buttons_dev
*bdev
= dev
->private;
55 struct input_dev
*input
= dev
->input
;
59 status
= readl(bdev
->reg
);
60 status
= ~status
& BUTTONS_STATUS_MASK
;
62 for (i
= 0; i
< ARRAY_SIZE(buttons_map
); i
++) {
63 if (status
& button
->mask
) {
66 if (button
->count
>= BUTTONS_COUNT_THRESHOLD
) {
67 input_report_key(input
, button
->keycode
, 0);
73 if (button
->count
== BUTTONS_COUNT_THRESHOLD
) {
74 input_report_key(input
, button
->keycode
, 1);
82 static int __devinit
cobalt_buttons_probe(struct platform_device
*pdev
)
84 struct buttons_dev
*bdev
;
85 struct input_polled_dev
*poll_dev
;
86 struct input_dev
*input
;
90 bdev
= kzalloc(sizeof(struct buttons_dev
), GFP_KERNEL
);
91 poll_dev
= input_allocate_polled_device();
92 if (!bdev
|| !poll_dev
) {
97 poll_dev
->private = bdev
;
98 poll_dev
->poll
= handle_buttons
;
99 poll_dev
->poll_interval
= BUTTONS_POLL_INTERVAL
;
101 input
= poll_dev
->input
;
102 input
->name
= "Cobalt buttons";
103 input
->phys
= "cobalt/input0";
104 input
->id
.bustype
= BUS_HOST
;
105 input
->cdev
.dev
= &pdev
->dev
;
107 input
->evbit
[0] = BIT(EV_KEY
);
108 for (i
= 0; i
< ARRAY_SIZE(buttons_map
); i
++) {
109 set_bit(buttons_map
[i
].keycode
, input
->keybit
);
110 buttons_map
[i
].count
= 0;
113 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
119 bdev
->poll_dev
= poll_dev
;
120 bdev
->reg
= ioremap(res
->start
, res
->end
- res
->start
+ 1);
121 dev_set_drvdata(&pdev
->dev
, bdev
);
123 error
= input_register_polled_device(poll_dev
);
132 input_free_polled_device(poll_dev
);
134 dev_set_drvdata(&pdev
->dev
, NULL
);
138 static int __devexit
cobalt_buttons_remove(struct platform_device
*pdev
)
140 struct device
*dev
= &pdev
->dev
;
141 struct buttons_dev
*bdev
= dev_get_drvdata(dev
);
143 input_unregister_polled_device(bdev
->poll_dev
);
144 input_free_polled_device(bdev
->poll_dev
);
147 dev_set_drvdata(dev
, NULL
);
152 static struct platform_driver cobalt_buttons_driver
= {
153 .probe
= cobalt_buttons_probe
,
154 .remove
= __devexit_p(cobalt_buttons_remove
),
156 .name
= "Cobalt buttons",
157 .owner
= THIS_MODULE
,
161 static int __init
cobalt_buttons_init(void)
163 return platform_driver_register(&cobalt_buttons_driver
);
166 static void __exit
cobalt_buttons_exit(void)
168 platform_driver_unregister(&cobalt_buttons_driver
);
171 module_init(cobalt_buttons_init
);
172 module_exit(cobalt_buttons_exit
);