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

Commit 84b256a6 authored by Bernhard Rosenkraenzer's avatar Bernhard Rosenkraenzer Committed by Dmitry Torokhov
Browse files

Input: wistron - add support for Acer Aspire 1500 notebooks



Also fix a potential issue with some notebooks:

The current code assumes the response to bios_wifi_get_default_setting is
either 1 (disabled) or 3 (enabled), or wifi isn't supported.  The BIOS
response appears to be a bit field w/ 0x1 indicating hardware presence, 0x2
indicating actiation status, and the other 6 bits being unknown/reserved --
with the patch, these 6 bits are ignored.

Signed-off-by: default avatarBernhard Rosenkraenzer <bero@arklinux.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent e9fb028e
Loading
Loading
Loading
Loading
+59 −20
Original line number Original line Diff line number Diff line
/*
/*
 * Wistron laptop button driver
 * Wistron laptop button driver
 * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
 * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
 * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
 *
 *
 * You can redistribute and/or modify this program under the terms of the
 * You can redistribute and/or modify this program under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * GNU General Public License version 2 as published by the Free Software
@@ -40,6 +41,10 @@
#error "POLL_FREQUENCY too high"
#error "POLL_FREQUENCY too high"
#endif
#endif


/* BIOS subsystem IDs */
#define WIFI		0x35
#define BLUETOOTH	0x34

MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>");
MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>");
MODULE_DESCRIPTION("Wistron laptop button driver");
MODULE_DESCRIPTION("Wistron laptop button driver");
MODULE_LICENSE("GPL v2");
MODULE_LICENSE("GPL v2");
@@ -197,25 +202,25 @@ static u8 __init bios_get_cmos_address(void)
	return regs.ecx;
	return regs.ecx;
}
}


static u16 __init bios_wifi_get_default_setting(void)
static u16 __init bios_get_default_setting(u8 subsys)
{
{
	struct regs regs;
	struct regs regs;


	memset(&regs, 0, sizeof (regs));
	memset(&regs, 0, sizeof (regs));
	regs.eax = 0x9610;
	regs.eax = 0x9610;
	regs.ebx = 0x0235;
	regs.ebx = 0x0200 | subsys;
	call_bios(&regs);
	call_bios(&regs);


	return regs.eax;
	return regs.eax;
}
}


static void bios_wifi_set_state(int enable)
static void bios_set_state(u8 subsys, int enable)
{
{
	struct regs regs;
	struct regs regs;


	memset(&regs, 0, sizeof (regs));
	memset(&regs, 0, sizeof (regs));
	regs.eax = 0x9610;
	regs.eax = 0x9610;
	regs.ebx = enable ? 0x0135 : 0x0035;
	regs.ebx = (enable ? 0x0100 : 0x0000) | subsys;
	call_bios(&regs);
	call_bios(&regs);
}
}


@@ -227,10 +232,11 @@ struct key_entry {
	unsigned keycode;	/* For KE_KEY */
	unsigned keycode;	/* For KE_KEY */
};
};


enum { KE_END, KE_KEY, KE_WIFI };
enum { KE_END, KE_KEY, KE_WIFI, KE_BLUETOOTH };


static const struct key_entry *keymap; /* = NULL; Current key map */
static const struct key_entry *keymap; /* = NULL; Current key map */
static int have_wifi;
static int have_wifi;
static int have_bluetooth;


static int __init dmi_matched(struct dmi_system_id *dmi)
static int __init dmi_matched(struct dmi_system_id *dmi)
{
{
@@ -241,6 +247,9 @@ static int __init dmi_matched(struct dmi_system_id *dmi)
		if (key->type == KE_WIFI) {
		if (key->type == KE_WIFI) {
			have_wifi = 1;
			have_wifi = 1;
			break;
			break;
		} else if (key->type == KE_BLUETOOTH) {
			have_bluetooth = 1;
			break;
		}
		}
	}
	}
	return 1;
	return 1;
@@ -273,6 +282,16 @@ static struct key_entry keymap_wistron_ms2141[] = {
	{ KE_END,  0 }
	{ KE_END,  0 }
};
};


static struct key_entry keymap_acer_aspire_1500[] = {
	{ KE_KEY, 0x11, KEY_PROG1 },
	{ KE_KEY, 0x12, KEY_PROG2 },
	{ KE_WIFI, 0x30, 0 },
	{ KE_KEY, 0x31, KEY_MAIL },
	{ KE_KEY, 0x36, KEY_WWW },
	{ KE_BLUETOOTH, 0x44, 0 },
	{ KE_END, 0 }
};

/*
/*
 * If your machine is not here (which is currently rather likely), please send
 * If your machine is not here (which is currently rather likely), please send
 * a list of buttons and their key codes (reported when loading this module
 * a list of buttons and their key codes (reported when loading this module
@@ -288,6 +307,15 @@ static struct dmi_system_id dmi_ids[] = {
		},
		},
		.driver_data = keymap_fs_amilo_pro_v2000
		.driver_data = keymap_fs_amilo_pro_v2000
	},
	},
	{
		.callback = dmi_matched,
		.ident = "Acer Aspire 1500",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1500"),
		},
		.driver_data = keymap_acer_aspire_1500
	},
	{ 0, }
	{ 0, }
};
};


@@ -344,6 +372,7 @@ static void report_key(unsigned keycode)
 /* Driver core */
 /* Driver core */


static int wifi_enabled;
static int wifi_enabled;
static int bluetooth_enabled;


static void poll_bios(unsigned long);
static void poll_bios(unsigned long);


@@ -363,7 +392,14 @@ static void handle_key(u8 code)
			case KE_WIFI:
			case KE_WIFI:
				if (have_wifi) {
				if (have_wifi) {
					wifi_enabled = !wifi_enabled;
					wifi_enabled = !wifi_enabled;
					bios_wifi_set_state(wifi_enabled);
					bios_set_state(WIFI, wifi_enabled);
				}
				break;

			case KE_BLUETOOTH:
				if (have_bluetooth) {
					bluetooth_enabled = !bluetooth_enabled;
					bios_set_state(BLUETOOTH, bluetooth_enabled);
				}
				}
				break;
				break;


@@ -407,21 +443,24 @@ static int __init wb_module_init(void)
	bios_attach();
	bios_attach();
	cmos_address = bios_get_cmos_address();
	cmos_address = bios_get_cmos_address();
	if (have_wifi) {
	if (have_wifi) {
		switch (bios_wifi_get_default_setting()) {
		u16 wifi = bios_get_default_setting(WIFI);
		case 0x01:
		if (wifi & 1)
			wifi_enabled = 0;
			wifi_enabled = (wifi & 2) ? 1 : 0;
			break;
		else

		case 0x03:
			wifi_enabled = 1;
			break;

		default:
			have_wifi = 0;
			have_wifi = 0;
			break;

		}
		if (have_wifi)
		if (have_wifi)
			bios_wifi_set_state(wifi_enabled);
			bios_set_state(WIFI, wifi_enabled);
	}
	if (have_bluetooth) {
		u16 bt = bios_get_default_setting(BLUETOOTH);
		if (bt & 1)
			bluetooth_enabled = (bt & 2) ? 1 : 0;
		else
			have_bluetooth = 0;

		if (have_bluetooth)
			bios_set_state(BLUETOOTH, bluetooth_enabled);
	}
	}


	setup_input_dev();
	setup_input_dev();