aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2014-01-14 06:36:29 -0500
committerRalf Baechle <ralf@linux-mips.org>2014-01-24 16:39:51 -0500
commitef1e3e7a19bd498862eb36ef8730d1d4700891ea (patch)
treee17d17b6507000589d12f805e1793ff854d81fbe /arch/mips
parent515fa75d4845c424c853a727a4f02b0e02340370 (diff)
MIPS: BCM47XX: Prepare support for GPIO buttons
So far this adds support for one Netgear model only, but it's designed and ready to add many more device. We could hopefully import database from OpenWrt. Support for SSB is currently disabled, because SSB doesn't implement IRQ domain yet. Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Acked-by: Hauke Mehrtens <hauke@hauke-m.de> Signed-off-by: John Crispin <blogic@openwrt.org> Patchwork: http://patchwork.linux-mips.org/patch/6300/
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/bcm47xx/Makefile2
-rw-r--r--arch/mips/bcm47xx/bcm47xx_private.h3
-rw-r--r--arch/mips/bcm47xx/buttons.c95
-rw-r--r--arch/mips/bcm47xx/setup.c1
4 files changed, 100 insertions, 1 deletions
diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile
index 84e9aed25027..006a05e4cf6d 100644
--- a/arch/mips/bcm47xx/Makefile
+++ b/arch/mips/bcm47xx/Makefile
@@ -4,5 +4,5 @@
4# 4#
5 5
6obj-y += irq.o nvram.o prom.o serial.o setup.o time.o sprom.o 6obj-y += irq.o nvram.o prom.o serial.o setup.o time.o sprom.o
7obj-y += board.o leds.o 7obj-y += board.o buttons.o leds.o
8obj-$(CONFIG_BCM47XX_SSB) += wgt634u.o 8obj-$(CONFIG_BCM47XX_SSB) += wgt634u.o
diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h
index 1a1e600b74e6..5c94acebf76a 100644
--- a/arch/mips/bcm47xx/bcm47xx_private.h
+++ b/arch/mips/bcm47xx/bcm47xx_private.h
@@ -3,6 +3,9 @@
3 3
4#include <linux/kernel.h> 4#include <linux/kernel.h>
5 5
6/* buttons.c */
7int __init bcm47xx_buttons_register(void);
8
6/* leds.c */ 9/* leds.c */
7void __init bcm47xx_leds_register(void); 10void __init bcm47xx_leds_register(void);
8 11
diff --git a/arch/mips/bcm47xx/buttons.c b/arch/mips/bcm47xx/buttons.c
new file mode 100644
index 000000000000..d93711bf41b0
--- /dev/null
+++ b/arch/mips/bcm47xx/buttons.c
@@ -0,0 +1,95 @@
1#include "bcm47xx_private.h"
2
3#include <linux/input.h>
4#include <linux/gpio_keys.h>
5#include <linux/interrupt.h>
6#include <linux/ssb/ssb_embedded.h>
7#include <bcm47xx_board.h>
8#include <bcm47xx.h>
9
10/**************************************************
11 * Database
12 **************************************************/
13
14static const struct gpio_keys_button
15bcm47xx_buttons_netgear_wndr4500_v1[] __initconst = {
16 {
17 .code = KEY_WPS_BUTTON,
18 .gpio = 4,
19 .active_low = 1,
20 },
21 {
22 .code = KEY_RFKILL,
23 .gpio = 5,
24 .active_low = 1,
25 },
26 {
27 .code = KEY_RESTART,
28 .gpio = 6,
29 .active_low = 1,
30 },
31};
32
33/**************************************************
34 * Init
35 **************************************************/
36
37static struct gpio_keys_platform_data bcm47xx_button_pdata;
38
39static struct platform_device bcm47xx_buttons_gpio_keys = {
40 .name = "gpio-keys",
41 .dev = {
42 .platform_data = &bcm47xx_button_pdata,
43 }
44};
45
46/* Copy data from __initconst */
47static int __init bcm47xx_buttons_copy(const struct gpio_keys_button *buttons,
48 size_t nbuttons)
49{
50 size_t size = nbuttons * sizeof(*buttons);
51
52 bcm47xx_button_pdata.buttons = kmalloc(size, GFP_KERNEL);
53 if (!bcm47xx_button_pdata.buttons)
54 return -ENOMEM;
55 memcpy(bcm47xx_button_pdata.buttons, buttons, size);
56 bcm47xx_button_pdata.nbuttons = nbuttons;
57
58 return 0;
59}
60
61#define bcm47xx_copy_bdata(dev_buttons) \
62 bcm47xx_buttons_copy(dev_buttons, ARRAY_SIZE(dev_buttons));
63
64int __init bcm47xx_buttons_register(void)
65{
66 enum bcm47xx_board board = bcm47xx_board_get();
67 int err;
68
69#ifdef CONFIG_BCM47XX_SSB
70 if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_SSB) {
71 pr_debug("Buttons on SSB are not supported yet.\n");
72 return -ENOTSUPP;
73 }
74#endif
75
76 switch (board) {
77 case BCM47XX_BOARD_NETGEAR_WNDR4500V1:
78 err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr4500_v1);
79 break;
80 default:
81 pr_debug("No buttons configuration found for this device\n");
82 return -ENOTSUPP;
83 }
84
85 if (err)
86 return -ENOMEM;
87
88 err = platform_device_register(&bcm47xx_buttons_gpio_keys);
89 if (err) {
90 pr_err("Failed to register platform device: %d\n", err);
91 return err;
92 }
93
94 return 0;
95}
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index 91166967f8f7..2d6e7cccae6b 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -255,6 +255,7 @@ static int __init bcm47xx_register_bus_complete(void)
255 break; 255 break;
256#endif 256#endif
257 } 257 }
258 bcm47xx_buttons_register();
258 bcm47xx_leds_register(); 259 bcm47xx_leds_register();
259 260
260 return 0; 261 return 0;