X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/096bb4f920ce8e2c366029ed9ac75161256d015f..2e3a7d5dc74459c68f87838939a5b74bc17189c6:/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 3b5527fcf..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,38 +21,37 @@ #include #include #include -#include +#include #define DRV_NAME "button-hotplug" -#define DRV_VERSION "0.3.0" +#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 ": " -/*#define BH_DEBUG*/ +#undef BH_DEBUG #ifdef BH_DEBUG -#define BH_DBG(fmt, args...) printk(KERN_DEBUG "%s" fmt, ##args ) +#define BH_DBG(fmt, args...) printk(KERN_DEBUG "%s: " fmt, DRV_NAME, ##args ) #else #define BH_DBG(fmt, args...) do {} while (0) #endif -#define BH_ERR(fmt, args...) printk(KERN_ERR "%s" fmt, ##args ) +#define BH_ERR(fmt, args...) printk(KERN_ERR "%s: " fmt, DRV_NAME, ##args ) + +#ifndef BIT_MASK +#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG)) +#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; @@ -60,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 */ }; /* -------------------------------------------------------------------------*/ @@ -138,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; @@ -154,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) { @@ -165,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; @@ -190,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; } @@ -224,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;