X-Git-Url: http://git.rohieb.name/openwrt.git/blobdiff_plain/8315549c47c997f3b20f32747397234495d30341..2427a1a5f9baffc8a4faf578dbdb5b618e23ed53:/package/button-hotplug/src/button-hotplug.c diff --git a/package/button-hotplug/src/button-hotplug.c b/package/button-hotplug/src/button-hotplug.c index 4bdf36435..4a8c4a88e 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 , @@ -21,19 +21,14 @@ #include #include #include -#include +#include #define DRV_NAME "button-hotplug" -#define DRV_VERSION "0.3.1" +#define DRV_VERSION "0.4.1" #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,34 @@ struct bh_event { struct work_struct work; }; -extern struct sock *uevent_sock; +struct bh_map { + unsigned int code; + const char *name; +}; + 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 */ }; /* -------------------------------------------------------------------------*/ @@ -142,9 +159,6 @@ static void button_hotplug_work(struct work_struct *work) struct bh_event *event = container_of(work, struct bh_event, work); int ret = 0; - if (!uevent_sock) - goto out_free_event; - event->skb = alloc_skb(BH_SKB_SIZE, GFP_KERNEL); if (!event->skb) goto out_free_event; @@ -158,7 +172,7 @@ static void button_hotplug_work(struct work_struct *work) goto out_free_skb; NETLINK_CB(event->skb).dst_group = 1; - netlink_broadcast(uevent_sock, event->skb, 0, 1, GFP_KERNEL); + broadcast_uevent(event->skb, 0, 1, GFP_KERNEL); out_free_skb: if (ret) { @@ -169,7 +183,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 +208,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 +252,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;