Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e97af4cb authored by Dmitry Torokhov's avatar Dmitry Torokhov
Browse files

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: default avatarDmitry Torokhov <dtor@mail.ru>
parent 36203c4f
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -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
+44 −134
Original line number Original line Diff line number Diff line
@@ -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 (key && key->type == KE_KEY) {
	/* if wifi or bluetooth are not available, create normal keys */
		*keycode = key->keycode;
	case KE_WIFI:
		return 0;
		if (!have_wifi) {
			entry->type = KE_KEY;
			entry->keycode = KEY_WLAN;
		}
		}
		break;


	return -EINVAL;
	case KE_BLUETOOTH:
		if (!have_bluetooth) {
			entry->type = KE_KEY;
			entry->keycode = KEY_BLUETOOTH;
		}
		}
		break;


static int wistron_setkeycode(struct input_dev *dev, int scancode, int keycode)
	case KE_END:
{
		if (entry->code & FE_UNTESTED)
	struct key_entry *key;
			printk(KERN_WARNING "Untested laptop multimedia keys, "
	int old_keycode;
				"please report success or failure to "

				"eric.piel@tremplin-utc.net\n");
	if (keycode < 0 || keycode > KEY_MAX)
		break;
		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;
	return 0;
}
}


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,58 +1217,23 @@ 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:
	error = input_register_polled_device(wistron_idev);
				break;
	if (error)
		}
		goto err_free_keymap;
	}


	/* reads information flags on KE_END */
	return 0;
	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);
 err_free_keymap:
	if (error) {
	sparse_keymap_free(input_dev);
 err_free_dev:
	input_free_polled_device(wistron_idev);
	input_free_polled_device(wistron_idev);
	return error;
	return error;
}
}


	return 0;
}

/* Driver core */
/* Driver core */


static int __devinit wistron_probe(struct platform_device *dev)
static int __devinit wistron_probe(struct platform_device *dev)
@@ -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();