1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Cobalt button interface driver.
5 * Copyright (C) 2007-2008 Yoichi Yuasa <yuasa@linux-mips.org>
7 #include <linux/input.h>
9 #include <linux/ioport.h>
10 #include <linux/module.h>
11 #include <linux/platform_device.h>
12 #include <linux/slab.h>
14 #define BUTTONS_POLL_INTERVAL 30 /* msec */
15 #define BUTTONS_COUNT_THRESHOLD 3
16 #define BUTTONS_STATUS_MASK 0xfe000000
18 static const unsigned short cobalt_map
[] = {
30 unsigned short keymap
[ARRAY_SIZE(cobalt_map
)];
31 int count
[ARRAY_SIZE(cobalt_map
)];
35 static void handle_buttons(struct input_dev
*input
)
37 struct buttons_dev
*bdev
= input_get_drvdata(input
);
41 status
= ~readl(bdev
->reg
) >> 24;
43 for (i
= 0; i
< ARRAY_SIZE(bdev
->keymap
); i
++) {
44 if (status
& (1U << i
)) {
45 if (++bdev
->count
[i
] == BUTTONS_COUNT_THRESHOLD
) {
46 input_event(input
, EV_MSC
, MSC_SCAN
, i
);
47 input_report_key(input
, bdev
->keymap
[i
], 1);
51 if (bdev
->count
[i
] >= BUTTONS_COUNT_THRESHOLD
) {
52 input_event(input
, EV_MSC
, MSC_SCAN
, i
);
53 input_report_key(input
, bdev
->keymap
[i
], 0);
61 static int cobalt_buttons_probe(struct platform_device
*pdev
)
63 struct buttons_dev
*bdev
;
64 struct input_dev
*input
;
68 bdev
= devm_kzalloc(&pdev
->dev
, sizeof(*bdev
), GFP_KERNEL
);
72 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
76 bdev
->reg
= devm_ioremap(&pdev
->dev
, res
->start
, resource_size(res
));
80 memcpy(bdev
->keymap
, cobalt_map
, sizeof(bdev
->keymap
));
82 input
= devm_input_allocate_device(&pdev
->dev
);
86 input_set_drvdata(input
, bdev
);
88 input
->name
= "Cobalt buttons";
89 input
->phys
= "cobalt/input0";
90 input
->id
.bustype
= BUS_HOST
;
92 input
->keycode
= bdev
->keymap
;
93 input
->keycodemax
= ARRAY_SIZE(bdev
->keymap
);
94 input
->keycodesize
= sizeof(unsigned short);
96 input_set_capability(input
, EV_MSC
, MSC_SCAN
);
97 __set_bit(EV_KEY
, input
->evbit
);
98 for (i
= 0; i
< ARRAY_SIZE(cobalt_map
); i
++)
99 __set_bit(bdev
->keymap
[i
], input
->keybit
);
100 __clear_bit(KEY_RESERVED
, input
->keybit
);
103 error
= input_setup_polling(input
, handle_buttons
);
107 input_set_poll_interval(input
, BUTTONS_POLL_INTERVAL
);
109 error
= input_register_device(input
);
116 MODULE_AUTHOR("Yoichi Yuasa <yuasa@linux-mips.org>");
117 MODULE_DESCRIPTION("Cobalt button interface driver");
118 MODULE_LICENSE("GPL");
119 /* work with hotplug and coldplug */
120 MODULE_ALIAS("platform:Cobalt buttons");
122 static struct platform_driver cobalt_buttons_driver
= {
123 .probe
= cobalt_buttons_probe
,
125 .name
= "Cobalt buttons",
128 module_platform_driver(cobalt_buttons_driver
);