Input: wistron_btns - switch to using sparse keymap library
The keymap manipulation code was split into a library module, so let's make us of it. Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
This commit is contained in:
parent
36203c4f3d
commit
e97af4cbbe
|
@ -80,6 +80,7 @@ config INPUT_WISTRON_BTNS
|
||||||
tristate "x86 Wistron laptop button interface"
|
tristate "x86 Wistron laptop button interface"
|
||||||
depends on X86 && !X86_64
|
depends on X86 && !X86_64
|
||||||
select INPUT_POLLDEV
|
select INPUT_POLLDEV
|
||||||
|
select INPUT_SPARSEKMAP
|
||||||
select NEW_LEDS
|
select NEW_LEDS
|
||||||
select LEDS_CLASS
|
select LEDS_CLASS
|
||||||
select CHECK_SIGNATURE
|
select CHECK_SIGNATURE
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <linux/dmi.h>
|
#include <linux/dmi.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
#include <linux/input-polldev.h>
|
#include <linux/input-polldev.h>
|
||||||
|
#include <linux/input/sparse-keymap.h>
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/jiffies.h>
|
#include <linux/jiffies.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
@ -224,19 +225,8 @@ static void bios_set_state(u8 subsys, int enable)
|
||||||
|
|
||||||
/* Hardware database */
|
/* Hardware database */
|
||||||
|
|
||||||
struct key_entry {
|
#define KE_WIFI (KE_LAST + 1)
|
||||||
char type; /* See KE_* below */
|
#define KE_BLUETOOTH (KE_LAST + 2)
|
||||||
u8 code;
|
|
||||||
union {
|
|
||||||
u16 keycode; /* For KE_KEY */
|
|
||||||
struct { /* For KE_SW */
|
|
||||||
u8 code;
|
|
||||||
u8 value;
|
|
||||||
} sw;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH };
|
|
||||||
|
|
||||||
#define FE_MAIL_LED 0x01
|
#define FE_MAIL_LED 0x01
|
||||||
#define FE_WIFI_LED 0x02
|
#define FE_WIFI_LED 0x02
|
||||||
|
@ -1037,21 +1027,6 @@ static unsigned long jiffies_last_press;
|
||||||
static bool wifi_enabled;
|
static bool wifi_enabled;
|
||||||
static bool bluetooth_enabled;
|
static bool bluetooth_enabled;
|
||||||
|
|
||||||
static void report_key(struct input_dev *dev, unsigned int keycode)
|
|
||||||
{
|
|
||||||
input_report_key(dev, keycode, 1);
|
|
||||||
input_sync(dev);
|
|
||||||
input_report_key(dev, keycode, 0);
|
|
||||||
input_sync(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void report_switch(struct input_dev *dev, unsigned int code, int value)
|
|
||||||
{
|
|
||||||
input_report_switch(dev, code, value);
|
|
||||||
input_sync(dev);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* led management */
|
/* led management */
|
||||||
static void wistron_mail_led_set(struct led_classdev *led_cdev,
|
static void wistron_mail_led_set(struct led_classdev *led_cdev,
|
||||||
enum led_brightness value)
|
enum led_brightness value)
|
||||||
|
@ -1128,43 +1103,13 @@ static inline void wistron_led_resume(void)
|
||||||
led_classdev_resume(&wistron_wifi_led);
|
led_classdev_resume(&wistron_wifi_led);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct key_entry *wistron_get_entry_by_scancode(int code)
|
|
||||||
{
|
|
||||||
struct key_entry *key;
|
|
||||||
|
|
||||||
for (key = keymap; key->type != KE_END; key++)
|
|
||||||
if (code == key->code)
|
|
||||||
return key;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct key_entry *wistron_get_entry_by_keycode(int keycode)
|
|
||||||
{
|
|
||||||
struct key_entry *key;
|
|
||||||
|
|
||||||
for (key = keymap; key->type != KE_END; key++)
|
|
||||||
if (key->type == KE_KEY && keycode == key->keycode)
|
|
||||||
return key;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void handle_key(u8 code)
|
static void handle_key(u8 code)
|
||||||
{
|
{
|
||||||
const struct key_entry *key = wistron_get_entry_by_scancode(code);
|
const struct key_entry *key =
|
||||||
|
sparse_keymap_entry_from_scancode(wistron_idev->input, code);
|
||||||
|
|
||||||
if (key) {
|
if (key) {
|
||||||
switch (key->type) {
|
switch (key->type) {
|
||||||
case KE_KEY:
|
|
||||||
report_key(wistron_idev->input, key->keycode);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KE_SW:
|
|
||||||
report_switch(wistron_idev->input,
|
|
||||||
key->sw.code, key->sw.value);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KE_WIFI:
|
case KE_WIFI:
|
||||||
if (have_wifi) {
|
if (have_wifi) {
|
||||||
wifi_enabled = !wifi_enabled;
|
wifi_enabled = !wifi_enabled;
|
||||||
|
@ -1180,7 +1125,9 @@ static void handle_key(u8 code)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BUG();
|
sparse_keymap_report_entry(wistron_idev->input,
|
||||||
|
key, 1, true);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
jiffies_last_press = jiffies;
|
jiffies_last_press = jiffies;
|
||||||
} else
|
} else
|
||||||
|
@ -1220,42 +1167,39 @@ static void wistron_poll(struct input_polled_dev *dev)
|
||||||
dev->poll_interval = POLL_INTERVAL_DEFAULT;
|
dev->poll_interval = POLL_INTERVAL_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int wistron_getkeycode(struct input_dev *dev, int scancode, int *keycode)
|
static int __devinit wistron_setup_keymap(struct input_dev *dev,
|
||||||
|
struct key_entry *entry)
|
||||||
{
|
{
|
||||||
const struct key_entry *key = wistron_get_entry_by_scancode(scancode);
|
switch (entry->type) {
|
||||||
|
|
||||||
|
/* if wifi or bluetooth are not available, create normal keys */
|
||||||
|
case KE_WIFI:
|
||||||
|
if (!have_wifi) {
|
||||||
|
entry->type = KE_KEY;
|
||||||
|
entry->keycode = KEY_WLAN;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KE_BLUETOOTH:
|
||||||
|
if (!have_bluetooth) {
|
||||||
|
entry->type = KE_KEY;
|
||||||
|
entry->keycode = KEY_BLUETOOTH;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KE_END:
|
||||||
|
if (entry->code & FE_UNTESTED)
|
||||||
|
printk(KERN_WARNING "Untested laptop multimedia keys, "
|
||||||
|
"please report success or failure to "
|
||||||
|
"eric.piel@tremplin-utc.net\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (key && key->type == KE_KEY) {
|
|
||||||
*keycode = key->keycode;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode)
|
|
||||||
{
|
|
||||||
struct key_entry *key;
|
|
||||||
int old_keycode;
|
|
||||||
|
|
||||||
if (keycode < 0 || keycode > KEY_MAX)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
key = wistron_get_entry_by_scancode(scancode);
|
|
||||||
if (key && key->type == KE_KEY) {
|
|
||||||
old_keycode = key->keycode;
|
|
||||||
key->keycode = keycode;
|
|
||||||
set_bit(keycode, dev->keybit);
|
|
||||||
if (!wistron_get_entry_by_keycode(old_keycode))
|
|
||||||
clear_bit(old_keycode, dev->keybit);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __devinit setup_input_dev(void)
|
static int __devinit setup_input_dev(void)
|
||||||
{
|
{
|
||||||
struct key_entry *key;
|
|
||||||
struct input_dev *input_dev;
|
struct input_dev *input_dev;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
@ -1273,56 +1217,21 @@ static int __devinit setup_input_dev(void)
|
||||||
input_dev->id.bustype = BUS_HOST;
|
input_dev->id.bustype = BUS_HOST;
|
||||||
input_dev->dev.parent = &wistron_device->dev;
|
input_dev->dev.parent = &wistron_device->dev;
|
||||||
|
|
||||||
input_dev->getkeycode = wistron_getkeycode;
|
error = sparse_keymap_setup(input_dev, keymap, wistron_setup_keymap);
|
||||||
input_dev->setkeycode = wistron_setkeycode;
|
if (error)
|
||||||
|
goto err_free_dev;
|
||||||
for (key = keymap; key->type != KE_END; key++) {
|
|
||||||
switch (key->type) {
|
|
||||||
case KE_KEY:
|
|
||||||
set_bit(EV_KEY, input_dev->evbit);
|
|
||||||
set_bit(key->keycode, input_dev->keybit);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KE_SW:
|
|
||||||
set_bit(EV_SW, input_dev->evbit);
|
|
||||||
set_bit(key->sw.code, input_dev->swbit);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* if wifi or bluetooth are not available, create normal keys */
|
|
||||||
case KE_WIFI:
|
|
||||||
if (!have_wifi) {
|
|
||||||
key->type = KE_KEY;
|
|
||||||
key->keycode = KEY_WLAN;
|
|
||||||
key--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KE_BLUETOOTH:
|
|
||||||
if (!have_bluetooth) {
|
|
||||||
key->type = KE_KEY;
|
|
||||||
key->keycode = KEY_BLUETOOTH;
|
|
||||||
key--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reads information flags on KE_END */
|
|
||||||
if (key->code & FE_UNTESTED)
|
|
||||||
printk(KERN_WARNING "Untested laptop multimedia keys, "
|
|
||||||
"please report success or failure to eric.piel"
|
|
||||||
"@tremplin-utc.net\n");
|
|
||||||
|
|
||||||
error = input_register_polled_device(wistron_idev);
|
error = input_register_polled_device(wistron_idev);
|
||||||
if (error) {
|
if (error)
|
||||||
input_free_polled_device(wistron_idev);
|
goto err_free_keymap;
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_free_keymap:
|
||||||
|
sparse_keymap_free(input_dev);
|
||||||
|
err_free_dev:
|
||||||
|
input_free_polled_device(wistron_idev);
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Driver core */
|
/* Driver core */
|
||||||
|
@ -1371,6 +1280,7 @@ static int __devexit wistron_remove(struct platform_device *dev)
|
||||||
{
|
{
|
||||||
wistron_led_remove();
|
wistron_led_remove();
|
||||||
input_unregister_polled_device(wistron_idev);
|
input_unregister_polled_device(wistron_idev);
|
||||||
|
sparse_keymap_free(wistron_idev->input);
|
||||||
input_free_polled_device(wistron_idev);
|
input_free_polled_device(wistron_idev);
|
||||||
bios_detach();
|
bios_detach();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue