From 7abcc664c6b63afff22410e16f9f73a244d8ee20 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Wed, 21 Apr 2010 19:07:14 +0000 Subject: package/button-hotplug: handle KEY_RESTART and KEY_WPS_BUTTON codes as well SVN-Revision: 21074 --- package/button-hotplug/src/button-hotplug.c | 73 ++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 21 deletions(-) (limited to 'package/button-hotplug/src') diff --git a/package/button-hotplug/src/button-hotplug.c b/package/button-hotplug/src/button-hotplug.c index 4bdf36435a..0259a3fbcd 100644 --- a/package/button-hotplug/src/button-hotplug.c +++ b/package/button-hotplug/src/button-hotplug.c @@ -1,7 +1,7 @@ /* * Button Hotplug driver * - * Copyright (C) 2008 Gabor Juhos + * Copyright (C) 2008-2010 Gabor Juhos * * Based on the diag.c - GPIO interface driver for Broadcom boards * Copyright (C) 2006 Mike Baker , @@ -24,16 +24,11 @@ #include #define DRV_NAME "button-hotplug" -#define DRV_VERSION "0.3.1" +#define DRV_VERSION "0.4.0" #define DRV_DESC "Button Hotplug driver" #define BH_SKB_SIZE 2048 -#define BH_BTN_MIN BTN_0 -#define BH_BTN_MAX BTN_9 - -#define BH_BTN_COUNT (BH_BTN_MAX - BH_BTN_MIN + 1) - #define PFX DRV_NAME ": " #undef BH_DEBUG @@ -51,12 +46,12 @@ #endif struct bh_priv { - unsigned long seen[BH_BTN_COUNT]; + unsigned long *seen; struct input_handle handle; }; struct bh_event { - char *name; + const char *name; char *action; unsigned long seen; @@ -64,12 +59,35 @@ struct bh_event { struct work_struct work; }; +struct bh_map { + unsigned int code; + const char *name; +}; + extern struct sock *uevent_sock; extern u64 uevent_next_seqnum(void); -static char *button_names[BH_BTN_COUNT] = { - "BTN_0", "BTN_1", "BTN_2", "BTN_3", "BTN_4", - "BTN_5", "BTN_6", "BTN_7", "BTN_8", "BTN_9" +#define BH_MAP(_code, _name) \ + { \ + .code = (_code), \ + .name = (_name), \ + } + +static struct bh_map button_map[] = { + BH_MAP(BTN_0, "BTN_0"), + BH_MAP(BTN_1, "BTN_1"), + BH_MAP(BTN_2, "BTN_2"), + BH_MAP(BTN_3, "BTN_3"), + BH_MAP(BTN_4, "BTN_4"), + BH_MAP(BTN_5, "BTN_5"), + BH_MAP(BTN_6, "BTN_6"), + BH_MAP(BTN_7, "BTN_7"), + BH_MAP(BTN_8, "BTN_8"), + BH_MAP(BTN_9, "BTN_9"), + BH_MAP(KEY_RESTART, "reset"), +#ifdef KEY_WPS_BUTTON + BH_MAP(KEY_WPS_BUTTON, "wps"), +#endif /* KEY_WPS_BUTTON */ }; /* -------------------------------------------------------------------------*/ @@ -169,7 +187,7 @@ static void button_hotplug_work(struct work_struct *work) kfree(event); } -static int button_hotplug_create_event(char *name, unsigned long seen, +static int button_hotplug_create_event(const char *name, unsigned long seen, int pressed) { struct bh_event *event; @@ -194,23 +212,33 @@ static int button_hotplug_create_event(char *name, unsigned long seen, /* -------------------------------------------------------------------------*/ #ifdef CONFIG_HOTPLUG +static int button_get_index(unsigned int code) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(button_map); i++) + if (button_map[i].code == code) + return i; + + return -1; +} static void button_hotplug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) { struct bh_priv *priv = handle->private; unsigned long seen = jiffies; - unsigned int btn; + int btn; BH_DBG("event type=%u, code=%u, value=%d\n", type, code, value); if (type != EV_KEY) return; - if (code < BH_BTN_MIN || code > BH_BTN_MAX) + btn = button_get_index(code); + if (btn < 0) return; - btn = code - BH_BTN_MIN; - button_hotplug_create_event(button_names[btn], + button_hotplug_create_event(button_map[btn].name, (seen - priv->seen[btn]) / HZ, value); priv->seen[btn] = seen; } @@ -228,17 +256,20 @@ static int button_hotplug_connect(struct input_handler *handler, int ret; int i; - for (i = BH_BTN_MIN; i <= BH_BTN_MAX; i++) - if (test_bit(i, dev->keybit)) + for (i = 0; i < ARRAY_SIZE(button_map); i++) + if (test_bit(button_map[i].code, dev->keybit)) break; - if (i > BH_BTN_MAX) + if (i == ARRAY_SIZE(button_map)) return -ENODEV; - priv = kzalloc(sizeof(*priv), GFP_KERNEL); + priv = kzalloc(sizeof(*priv) + + (sizeof(unsigned long) * ARRAY_SIZE(button_map)), + GFP_KERNEL); if (!priv) return -ENOMEM; + priv->seen = (unsigned long *) &priv[1]; priv->handle.private = priv; priv->handle.dev = dev; priv->handle.handler = handler; -- cgit v1.2.3