diff options
Diffstat (limited to 'drivers/input/misc/wistron_btns.c')
| -rw-r--r-- | drivers/input/misc/wistron_btns.c | 685 | 
1 files changed, 610 insertions, 75 deletions
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c index e1183aeb8ed..961aad7a047 100644 --- a/drivers/input/misc/wistron_btns.c +++ b/drivers/input/misc/wistron_btns.c @@ -50,7 +50,7 @@  MODULE_AUTHOR("Miloslav Trmac <mitr@volny.cz>");  MODULE_DESCRIPTION("Wistron laptop button driver");  MODULE_LICENSE("GPL v2"); -MODULE_VERSION("0.1"); +MODULE_VERSION("0.2");  static int force; /* = 0; */  module_param(force, bool, 0); @@ -58,7 +58,7 @@ MODULE_PARM_DESC(force, "Load even if computer is not in database");  static char *keymap_name; /* = NULL; */  module_param_named(keymap, keymap_name, charp, 0); -MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected"); +MODULE_PARM_DESC(keymap, "Keymap name, if it can't be autodetected [generic, 1557/MS2141]");  static struct platform_device *wistron_device; @@ -233,10 +233,20 @@ static void bios_set_state(u8 subsys, int enable)  struct key_entry {  	char type;		/* See KE_* below */  	u8 code; -	unsigned keycode;	/* For KE_KEY */ +	union { +		u16 keycode;		/* For KE_KEY */ +		struct {		/* For KE_SW */ +			u8 code; +			u8 value; +		} sw; +	};  }; -enum { KE_END, KE_KEY, KE_WIFI, KE_BLUETOOTH }; +enum { KE_END, KE_KEY, KE_SW, KE_WIFI, KE_BLUETOOTH }; + +#define FE_MAIL_LED 0x01 +#define FE_WIFI_LED 0x02 +#define FE_UNTESTED 0x80  static const struct key_entry *keymap; /* = NULL; Current key map */  static int have_wifi; @@ -256,93 +266,341 @@ static int __init dmi_matched(struct dmi_system_id *dmi)  	return 1;  } -static struct key_entry keymap_empty[] = { +static struct key_entry keymap_empty[] __initdata = {  	{ KE_END, 0 }  }; -static struct key_entry keymap_fs_amilo_pro_v2000[] = { -	{ KE_KEY,  0x01, KEY_HELP }, -	{ KE_KEY,  0x11, KEY_PROG1 }, -	{ KE_KEY,  0x12, KEY_PROG2 }, -	{ KE_WIFI, 0x30, 0 }, -	{ KE_KEY,  0x31, KEY_MAIL }, -	{ KE_KEY,  0x36, KEY_WWW }, +static struct key_entry keymap_fs_amilo_pro_v2000[] __initdata = { +	{ KE_KEY,  0x01, {KEY_HELP} }, +	{ KE_KEY,  0x11, {KEY_PROG1} }, +	{ KE_KEY,  0x12, {KEY_PROG2} }, +	{ KE_WIFI, 0x30 }, +	{ KE_KEY,  0x31, {KEY_MAIL} }, +	{ KE_KEY,  0x36, {KEY_WWW} },  	{ KE_END,  0 }  }; -static struct key_entry keymap_fujitsu_n3510[] = { -	{ KE_KEY, 0x11, KEY_PROG1 }, -	{ KE_KEY, 0x12, KEY_PROG2 }, -	{ KE_KEY, 0x36, KEY_WWW }, -	{ KE_KEY, 0x31, KEY_MAIL }, -	{ KE_KEY, 0x71, KEY_STOPCD }, -	{ KE_KEY, 0x72, KEY_PLAYPAUSE }, -	{ KE_KEY, 0x74, KEY_REWIND }, -	{ KE_KEY, 0x78, KEY_FORWARD }, +static struct key_entry keymap_fujitsu_n3510[] __initdata = { +	{ KE_KEY, 0x11, {KEY_PROG1} }, +	{ KE_KEY, 0x12, {KEY_PROG2} }, +	{ KE_KEY, 0x36, {KEY_WWW} }, +	{ KE_KEY, 0x31, {KEY_MAIL} }, +	{ KE_KEY, 0x71, {KEY_STOPCD} }, +	{ KE_KEY, 0x72, {KEY_PLAYPAUSE} }, +	{ KE_KEY, 0x74, {KEY_REWIND} }, +	{ KE_KEY, 0x78, {KEY_FORWARD} },  	{ KE_END, 0 }  }; -static struct key_entry keymap_wistron_ms2111[] = { -	{ KE_KEY,  0x11, KEY_PROG1 }, -	{ KE_KEY,  0x12, KEY_PROG2 }, -	{ KE_KEY,  0x13, KEY_PROG3 }, -	{ KE_KEY,  0x31, KEY_MAIL }, -	{ KE_KEY,  0x36, KEY_WWW }, -	{ KE_END,  0 } +static struct key_entry keymap_wistron_ms2111[] __initdata = { +	{ KE_KEY,  0x11, {KEY_PROG1} }, +	{ KE_KEY,  0x12, {KEY_PROG2} }, +	{ KE_KEY,  0x13, {KEY_PROG3} }, +	{ KE_KEY,  0x31, {KEY_MAIL} }, +	{ KE_KEY,  0x36, {KEY_WWW} }, +	{ KE_END, FE_MAIL_LED } +}; + +static struct key_entry keymap_wistron_md40100[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x02, {KEY_CONFIG} }, +	{ KE_KEY, 0x31, {KEY_MAIL} }, +	{ KE_KEY, 0x36, {KEY_WWW} }, +	{ KE_KEY, 0x37, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ +	{ KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED }  }; -static struct key_entry keymap_wistron_ms2141[] = { -	{ KE_KEY,  0x11, KEY_PROG1 }, -	{ KE_KEY,  0x12, KEY_PROG2 }, -	{ KE_WIFI, 0x30, 0 }, -	{ KE_KEY,  0x22, KEY_REWIND }, -	{ KE_KEY,  0x23, KEY_FORWARD }, -	{ KE_KEY,  0x24, KEY_PLAYPAUSE }, -	{ KE_KEY,  0x25, KEY_STOPCD }, -	{ KE_KEY,  0x31, KEY_MAIL }, -	{ KE_KEY,  0x36, KEY_WWW }, +static struct key_entry keymap_wistron_ms2141[] __initdata = { +	{ KE_KEY,  0x11, {KEY_PROG1} }, +	{ KE_KEY,  0x12, {KEY_PROG2} }, +	{ KE_WIFI, 0x30 }, +	{ KE_KEY,  0x22, {KEY_REWIND} }, +	{ KE_KEY,  0x23, {KEY_FORWARD} }, +	{ KE_KEY,  0x24, {KEY_PLAYPAUSE} }, +	{ KE_KEY,  0x25, {KEY_STOPCD} }, +	{ KE_KEY,  0x31, {KEY_MAIL} }, +	{ KE_KEY,  0x36, {KEY_WWW} },  	{ 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 } +static struct key_entry keymap_acer_aspire_1500[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x03, {KEY_POWER} }, +	{ KE_KEY, 0x11, {KEY_PROG1} }, +	{ KE_KEY, 0x12, {KEY_PROG2} }, +	{ KE_WIFI, 0x30 }, +	{ KE_KEY, 0x31, {KEY_MAIL} }, +	{ KE_KEY, 0x36, {KEY_WWW} }, +	{ KE_KEY, 0x49, {KEY_CONFIG} }, +	{ KE_BLUETOOTH, 0x44 }, +	{ KE_END, FE_UNTESTED }  }; -static struct key_entry keymap_acer_travelmate_240[] = { -	{ KE_KEY, 0x31, KEY_MAIL }, -	{ KE_KEY, 0x36, KEY_WWW }, -	{ KE_KEY, 0x11, KEY_PROG1 }, -	{ KE_KEY, 0x12, KEY_PROG2 }, -	{ KE_BLUETOOTH, 0x44, 0 }, -	{ KE_WIFI, 0x30, 0 }, -	{ KE_END, 0 } +static struct key_entry keymap_acer_aspire_1600[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x03, {KEY_POWER} }, +	{ KE_KEY, 0x08, {KEY_MUTE} }, +	{ KE_KEY, 0x11, {KEY_PROG1} }, +	{ KE_KEY, 0x12, {KEY_PROG2} }, +	{ KE_KEY, 0x13, {KEY_PROG3} }, +	{ KE_KEY, 0x31, {KEY_MAIL} }, +	{ KE_KEY, 0x36, {KEY_WWW} }, +	{ KE_KEY, 0x49, {KEY_CONFIG} }, +	{ KE_WIFI, 0x30 }, +	{ KE_BLUETOOTH, 0x44 }, +	{ KE_END, FE_MAIL_LED | FE_UNTESTED } +}; + +/* 3020 has been tested */ +static struct key_entry keymap_acer_aspire_5020[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x03, {KEY_POWER} }, +	{ KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */ +	{ KE_KEY, 0x11, {KEY_PROG1} }, +	{ KE_KEY, 0x12, {KEY_PROG2} }, +	{ KE_KEY, 0x31, {KEY_MAIL} }, +	{ KE_KEY, 0x36, {KEY_WWW} }, +	{ KE_KEY, 0x6a, {KEY_CONFIG} }, +	{ KE_WIFI, 0x30 }, +	{ KE_BLUETOOTH, 0x44 }, +	{ KE_END, FE_MAIL_LED | FE_UNTESTED } +}; + +static struct key_entry keymap_acer_travelmate_2410[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x6d, {KEY_POWER} }, +	{ KE_KEY, 0x11, {KEY_PROG1} }, +	{ KE_KEY, 0x12, {KEY_PROG2} }, +	{ KE_KEY, 0x31, {KEY_MAIL} }, +	{ KE_KEY, 0x36, {KEY_WWW} }, +	{ KE_KEY, 0x6a, {KEY_CONFIG} }, +	{ KE_WIFI, 0x30 }, +	{ KE_BLUETOOTH, 0x44 }, +	{ KE_END, FE_MAIL_LED | FE_UNTESTED } +}; + +static struct key_entry keymap_acer_travelmate_110[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x02, {KEY_CONFIG} }, +	{ KE_KEY, 0x03, {KEY_POWER} }, +	{ KE_KEY, 0x08, {KEY_MUTE} }, +	{ KE_KEY, 0x11, {KEY_PROG1} }, +	{ KE_KEY, 0x12, {KEY_PROG2} }, +	{ KE_KEY, 0x20, {KEY_VOLUMEUP} }, +	{ KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, +	{ KE_KEY, 0x31, {KEY_MAIL} }, +	{ KE_KEY, 0x36, {KEY_WWW} }, +	{ KE_SW, 0x4a, {.sw = {SW_LID, 1}} }, /* lid close */ +	{ KE_SW, 0x4b, {.sw = {SW_LID, 0}} }, /* lid open */ +	{ KE_WIFI, 0x30 }, +	{ KE_END, FE_MAIL_LED | FE_UNTESTED } +}; + +static struct key_entry keymap_acer_travelmate_300[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x02, {KEY_CONFIG} }, +	{ KE_KEY, 0x03, {KEY_POWER} }, +	{ KE_KEY, 0x08, {KEY_MUTE} }, +	{ KE_KEY, 0x11, {KEY_PROG1} }, +	{ KE_KEY, 0x12, {KEY_PROG2} }, +	{ KE_KEY, 0x20, {KEY_VOLUMEUP} }, +	{ KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, +	{ KE_KEY, 0x31, {KEY_MAIL} }, +	{ KE_KEY, 0x36, {KEY_WWW} }, +	{ KE_WIFI, 0x30 }, +	{ KE_BLUETOOTH, 0x44 }, +	{ KE_END, FE_MAIL_LED | FE_UNTESTED }  }; -static struct key_entry keymap_aopen_1559as[] = { -	{ KE_KEY,  0x01, KEY_HELP }, -	{ KE_KEY,  0x06, KEY_PROG3 }, -	{ KE_KEY,  0x11, KEY_PROG1 }, -	{ KE_KEY,  0x12, KEY_PROG2 }, -	{ KE_WIFI, 0x30, 0 }, -	{ KE_KEY,  0x31, KEY_MAIL }, -	{ KE_KEY,  0x36, KEY_WWW }, +static struct key_entry keymap_acer_travelmate_380[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x02, {KEY_CONFIG} }, +	{ KE_KEY, 0x03, {KEY_POWER} }, /* not 370 */ +	{ KE_KEY, 0x11, {KEY_PROG1} }, +	{ KE_KEY, 0x12, {KEY_PROG2} }, +	{ KE_KEY, 0x13, {KEY_PROG3} }, +	{ KE_KEY, 0x31, {KEY_MAIL} }, +	{ KE_KEY, 0x36, {KEY_WWW} }, +	{ KE_WIFI, 0x30 }, +	{ KE_END, FE_MAIL_LED | FE_UNTESTED } +}; + +/* unusual map */ +static struct key_entry keymap_acer_travelmate_220[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x02, {KEY_CONFIG} }, +	{ KE_KEY, 0x11, {KEY_MAIL} }, +	{ KE_KEY, 0x12, {KEY_WWW} }, +	{ KE_KEY, 0x13, {KEY_PROG2} }, +	{ KE_KEY, 0x31, {KEY_PROG1} }, +	{ KE_END, FE_WIFI_LED | FE_UNTESTED } +}; + +static struct key_entry keymap_acer_travelmate_230[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x02, {KEY_CONFIG} }, +	{ KE_KEY, 0x11, {KEY_PROG1} }, +	{ KE_KEY, 0x12, {KEY_PROG2} }, +	{ KE_KEY, 0x31, {KEY_MAIL} }, +	{ KE_KEY, 0x36, {KEY_WWW} }, +	{ KE_END, FE_WIFI_LED | FE_UNTESTED } +}; + +static struct key_entry keymap_acer_travelmate_240[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x02, {KEY_CONFIG} }, +	{ KE_KEY, 0x03, {KEY_POWER} }, +	{ KE_KEY, 0x08, {KEY_MUTE} }, +	{ KE_KEY, 0x31, {KEY_MAIL} }, +	{ KE_KEY, 0x36, {KEY_WWW} }, +	{ KE_KEY, 0x11, {KEY_PROG1} }, +	{ KE_KEY, 0x12, {KEY_PROG2} }, +	{ KE_BLUETOOTH, 0x44 }, +	{ KE_WIFI, 0x30 }, +	{ KE_END, FE_UNTESTED } +}; + +static struct key_entry keymap_acer_travelmate_350[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x02, {KEY_CONFIG} }, +	{ KE_KEY, 0x11, {KEY_PROG1} }, +	{ KE_KEY, 0x12, {KEY_PROG2} }, +	{ KE_KEY, 0x13, {KEY_MAIL} }, +	{ KE_KEY, 0x14, {KEY_PROG3} }, +	{ KE_KEY, 0x15, {KEY_WWW} }, +	{ KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED } +}; + +static struct key_entry keymap_acer_travelmate_360[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x02, {KEY_CONFIG} }, +	{ KE_KEY, 0x11, {KEY_PROG1} }, +	{ KE_KEY, 0x12, {KEY_PROG2} }, +	{ KE_KEY, 0x13, {KEY_MAIL} }, +	{ KE_KEY, 0x14, {KEY_PROG3} }, +	{ KE_KEY, 0x15, {KEY_WWW} }, +	{ KE_KEY, 0x40, {KEY_WLAN} }, +	{ KE_END, FE_WIFI_LED | FE_UNTESTED } /* no mail led */ +}; + +/* Wifi subsystem only activates the led. Therefore we need to pass + * wifi event as a normal key, then userspace can really change the wifi state. + * TODO we need to export led state to userspace (wifi and mail) */ +static struct key_entry keymap_acer_travelmate_610[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x02, {KEY_CONFIG} }, +	{ KE_KEY, 0x11, {KEY_PROG1} }, +	{ KE_KEY, 0x12, {KEY_PROG2} }, +	{ KE_KEY, 0x13, {KEY_PROG3} }, +	{ KE_KEY, 0x14, {KEY_MAIL} }, +	{ KE_KEY, 0x15, {KEY_WWW} }, +	{ KE_KEY, 0x40, {KEY_WLAN} }, +	{ KE_END, FE_MAIL_LED | FE_WIFI_LED } +}; + +static struct key_entry keymap_acer_travelmate_630[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x02, {KEY_CONFIG} }, +	{ KE_KEY, 0x03, {KEY_POWER} }, +	{ KE_KEY, 0x08, {KEY_MUTE} }, /* not 620 */ +	{ KE_KEY, 0x11, {KEY_PROG1} }, +	{ KE_KEY, 0x12, {KEY_PROG2} }, +	{ KE_KEY, 0x13, {KEY_PROG3} }, +	{ KE_KEY, 0x20, {KEY_VOLUMEUP} }, +	{ KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, +	{ KE_KEY, 0x31, {KEY_MAIL} }, +	{ KE_KEY, 0x36, {KEY_WWW} }, +	{ KE_WIFI, 0x30 }, +	{ KE_END, FE_MAIL_LED | FE_UNTESTED } +}; + +static struct key_entry keymap_aopen_1559as[] __initdata = { +	{ KE_KEY,  0x01, {KEY_HELP} }, +	{ KE_KEY,  0x06, {KEY_PROG3} }, +	{ KE_KEY,  0x11, {KEY_PROG1} }, +	{ KE_KEY,  0x12, {KEY_PROG2} }, +	{ KE_WIFI, 0x30 }, +	{ KE_KEY,  0x31, {KEY_MAIL} }, +	{ KE_KEY,  0x36, {KEY_WWW} },  	{ KE_END,  0 },  }; -static struct key_entry keymap_fs_amilo_d88x0[] = { -	{ KE_KEY, 0x01, KEY_HELP }, -	{ KE_KEY, 0x08, KEY_MUTE }, -	{ KE_KEY, 0x31, KEY_MAIL }, -	{ KE_KEY, 0x36, KEY_WWW }, -	{ KE_KEY, 0x11, KEY_PROG1 }, -	{ KE_KEY, 0x12, KEY_PROG2 }, -	{ KE_KEY, 0x13, KEY_PROG3 }, +static struct key_entry keymap_fs_amilo_d88x0[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x08, {KEY_MUTE} }, +	{ KE_KEY, 0x31, {KEY_MAIL} }, +	{ KE_KEY, 0x36, {KEY_WWW} }, +	{ KE_KEY, 0x11, {KEY_PROG1} }, +	{ KE_KEY, 0x12, {KEY_PROG2} }, +	{ KE_KEY, 0x13, {KEY_PROG3} }, +	{ KE_END, FE_MAIL_LED | FE_WIFI_LED | FE_UNTESTED } +}; + +static struct key_entry keymap_wistron_md2900[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x02, {KEY_CONFIG} }, +	{ KE_KEY, 0x11, {KEY_PROG1} }, +	{ KE_KEY, 0x12, {KEY_PROG2} }, +	{ KE_KEY, 0x31, {KEY_MAIL} }, +	{ KE_KEY, 0x36, {KEY_WWW} }, +	{ KE_WIFI, 0x30 }, +	{ KE_END, FE_MAIL_LED | FE_UNTESTED } +}; + +static struct key_entry keymap_wistron_md96500[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x02, {KEY_CONFIG} }, +	{ KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */ +	{ KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ +	{ KE_KEY, 0x08, {KEY_MUTE} }, +	{ KE_KEY, 0x11, {KEY_PROG1} }, +	{ KE_KEY, 0x12, {KEY_PROG2} }, +	{ KE_KEY, 0x20, {KEY_VOLUMEUP} }, +	{ KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, +	{ KE_KEY, 0x22, {KEY_REWIND} }, +	{ KE_KEY, 0x23, {KEY_FORWARD} }, +	{ KE_KEY, 0x24, {KEY_PLAYPAUSE} }, +	{ KE_KEY, 0x25, {KEY_STOPCD} }, +	{ KE_KEY, 0x31, {KEY_MAIL} }, +	{ KE_KEY, 0x36, {KEY_WWW} }, +	{ KE_WIFI, 0x30 }, +	{ KE_BLUETOOTH, 0x44 }, +	{ KE_END, FE_UNTESTED } +}; + +static struct key_entry keymap_wistron_generic[] __initdata = { +	{ KE_KEY, 0x01, {KEY_HELP} }, +	{ KE_KEY, 0x02, {KEY_CONFIG} }, +	{ KE_KEY, 0x03, {KEY_POWER} }, +	{ KE_KEY, 0x05, {KEY_SWITCHVIDEOMODE} }, /* Display selection */ +	{ KE_KEY, 0x06, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ +	{ KE_KEY, 0x08, {KEY_MUTE} }, +	{ KE_KEY, 0x11, {KEY_PROG1} }, +	{ KE_KEY, 0x12, {KEY_PROG2} }, +	{ KE_KEY, 0x13, {KEY_PROG3} }, +	{ KE_KEY, 0x14, {KEY_MAIL} }, +	{ KE_KEY, 0x15, {KEY_WWW} }, +	{ KE_KEY, 0x20, {KEY_VOLUMEUP} }, +	{ KE_KEY, 0x21, {KEY_VOLUMEDOWN} }, +	{ KE_KEY, 0x22, {KEY_REWIND} }, +	{ KE_KEY, 0x23, {KEY_FORWARD} }, +	{ KE_KEY, 0x24, {KEY_PLAYPAUSE} }, +	{ KE_KEY, 0x25, {KEY_STOPCD} }, +	{ KE_KEY, 0x31, {KEY_MAIL} }, +	{ KE_KEY, 0x36, {KEY_WWW} }, +	{ KE_KEY, 0x37, {KEY_DISPLAYTOGGLE} }, /* Display on/off */ +	{ KE_KEY, 0x40, {KEY_WLAN} }, +	{ KE_KEY, 0x49, {KEY_CONFIG} }, +	{ KE_SW, 0x4a, {.sw = {SW_LID, 1}} }, /* lid close */ +	{ KE_SW, 0x4b, {.sw = {SW_LID, 0}} }, /* lid open */ +	{ KE_KEY, 0x6a, {KEY_CONFIG} }, +	{ KE_KEY, 0x6d, {KEY_POWER} }, +	{ KE_KEY, 0x71, {KEY_STOPCD} }, +	{ KE_KEY, 0x72, {KEY_PLAYPAUSE} }, +	{ KE_KEY, 0x74, {KEY_REWIND} }, +	{ KE_KEY, 0x78, {KEY_FORWARD} }, +	{ KE_WIFI, 0x30 }, +	{ KE_BLUETOOTH, 0x44 },  	{ KE_END, 0 }  }; @@ -390,6 +648,133 @@ static struct dmi_system_id dmi_ids[] __initdata = {  	},  	{  		.callback = dmi_matched, +		.ident = "Acer Aspire 1600", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 1600"), +		}, +		.driver_data = keymap_acer_aspire_1600 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Acer Aspire 3020", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3020"), +		}, +		.driver_data = keymap_acer_aspire_5020 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Acer Aspire 5020", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5020"), +		}, +		.driver_data = keymap_acer_aspire_5020 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Acer TravelMate 2100", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2100"), +		}, +		.driver_data = keymap_acer_aspire_5020 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Acer TravelMate 2410", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 2410"), +		}, +		.driver_data = keymap_acer_travelmate_2410 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Acer TravelMate C300", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C300"), +		}, +		.driver_data = keymap_acer_travelmate_300 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Acer TravelMate C100", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C100"), +		}, +		.driver_data = keymap_acer_travelmate_300 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Acer TravelMate C110", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate C110"), +		}, +		.driver_data = keymap_acer_travelmate_110 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Acer TravelMate 380", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 380"), +		}, +		.driver_data = keymap_acer_travelmate_380 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Acer TravelMate 370", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 370"), +		}, +		.driver_data = keymap_acer_travelmate_380 /* keyboard minus 1 key */ +	}, +	{ +		.callback = dmi_matched, +		.ident = "Acer TravelMate 220", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 220"), +		}, +		.driver_data = keymap_acer_travelmate_220 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Acer TravelMate 260", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 260"), +		}, +		.driver_data = keymap_acer_travelmate_220 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Acer TravelMate 230", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 230"), +			/* acerhk looks for "TravelMate F4..." ?! */ +		}, +		.driver_data = keymap_acer_travelmate_230 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Acer TravelMate 280", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 280"), +		}, +		.driver_data = keymap_acer_travelmate_230 +	}, +	{ +		.callback = dmi_matched,  		.ident = "Acer TravelMate 240",  		.matches = {  			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), @@ -399,6 +784,15 @@ static struct dmi_system_id dmi_ids[] __initdata = {  	},  	{  		.callback = dmi_matched, +		.ident = "Acer TravelMate 250", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 250"), +		}, +		.driver_data = keymap_acer_travelmate_240 +	}, +	{ +		.callback = dmi_matched,  		.ident = "Acer TravelMate 2424NWXCi",  		.matches = {  			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), @@ -408,6 +802,51 @@ static struct dmi_system_id dmi_ids[] __initdata = {  	},  	{  		.callback = dmi_matched, +		.ident = "Acer TravelMate 350", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 350"), +		}, +		.driver_data = keymap_acer_travelmate_350 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Acer TravelMate 360", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 360"), +		}, +		.driver_data = keymap_acer_travelmate_360 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Acer TravelMate 610", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "ACER"), +			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 610"), +		}, +		.driver_data = keymap_acer_travelmate_610 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Acer TravelMate 620", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 620"), +		}, +		.driver_data = keymap_acer_travelmate_630 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Acer TravelMate 630", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "Acer"), +			DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 630"), +		}, +		.driver_data = keymap_acer_travelmate_630 +	}, +	{ +		.callback = dmi_matched,  		.ident = "AOpen 1559AS",  		.matches = {  			DMI_MATCH(DMI_PRODUCT_NAME, "E2U"), @@ -426,6 +865,51 @@ static struct dmi_system_id dmi_ids[] __initdata = {  	},  	{  		.callback = dmi_matched, +		.ident = "Medion MD 40100", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), +			DMI_MATCH(DMI_PRODUCT_NAME, "WID2000"), +		}, +		.driver_data = keymap_wistron_md40100 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Medion MD 2900", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), +			DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2000"), +		}, +		.driver_data = keymap_wistron_md2900 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Medion MD 96500", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), +			DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2040"), +		}, +		.driver_data = keymap_wistron_md96500 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Medion MD 95400", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "MEDIONPC"), +			DMI_MATCH(DMI_PRODUCT_NAME, "WIM 2050"), +		}, +		.driver_data = keymap_wistron_md96500 +	}, +	{ +		.callback = dmi_matched, +		.ident = "Fujitsu Siemens Amilo D7820", +		.matches = { +			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), /* not sure */ +			DMI_MATCH(DMI_PRODUCT_NAME, "Amilo D"), +		}, +		.driver_data = keymap_fs_amilo_d88x0 +	}, +	{ +		.callback = dmi_matched,  		.ident = "Fujitsu Siemens Amilo D88x0",  		.matches = {  			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"), @@ -436,17 +920,39 @@ static struct dmi_system_id dmi_ids[] __initdata = {  	{ NULL, }  }; +/* Copy the good keymap, as the original ones are free'd */ +static int __init copy_keymap(void) +{ +	const struct key_entry *key; +	struct key_entry *new_keymap; +	unsigned int length = 1; + +	for (key = keymap; key->type != KE_END; key++) +		length++; + +	new_keymap = kmalloc(length * sizeof(struct key_entry), GFP_KERNEL); +	if (!new_keymap) +		return -ENOMEM; + +	memcpy(new_keymap, keymap, length * sizeof(struct key_entry)); +	keymap = new_keymap; + +	return 0; +} +  static int __init select_keymap(void)  { +	dmi_check_system(dmi_ids);  	if (keymap_name != NULL) {  		if (strcmp (keymap_name, "1557/MS2141") == 0)  			keymap = keymap_wistron_ms2141; +		else if (strcmp (keymap_name, "generic") == 0) +			keymap = keymap_wistron_generic;  		else {  			printk(KERN_ERR "wistron_btns: Keymap unknown\n");  			return -EINVAL;  		}  	} -	dmi_check_system(dmi_ids);  	if (keymap == NULL) {  		if (!force) {  			printk(KERN_ERR "wistron_btns: System unknown\n"); @@ -454,7 +960,8 @@ static int __init select_keymap(void)  		}  		keymap = keymap_empty;  	} -	return 0; + +	return copy_keymap();  }   /* Input layer interface */ @@ -476,12 +983,28 @@ static int __devinit setup_input_dev(void)  	input_dev->cdev.dev = &wistron_device->dev;  	for (key = keymap; key->type != KE_END; key++) { -		if (key->type == KE_KEY) { -			input_dev->evbit[LONG(EV_KEY)] = BIT(EV_KEY); -			set_bit(key->keycode, input_dev->keybit); +		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; + +			default: +				;  		}  	} +	/* 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_device(input_dev);  	if (error) {  		input_free_device(input_dev); @@ -499,6 +1022,12 @@ static void report_key(unsigned keycode)  	input_sync(input_dev);  } +static void report_switch(unsigned code, int value) +{ +	input_report_switch(input_dev, code, value); +	input_sync(input_dev); +} +   /* Driver core */  static int wifi_enabled; @@ -519,6 +1048,10 @@ static void handle_key(u8 code)  				report_key(key->keycode);  				break; +			case KE_SW: +				report_switch(key->sw.code, key->sw.value); +				break; +  			case KE_WIFI:  				if (have_wifi) {  					wifi_enabled = !wifi_enabled; @@ -534,6 +1067,7 @@ static void handle_key(u8 code)  				break;  			case KE_END: +				break;  			default:  				BUG();  			} @@ -690,6 +1224,7 @@ static void __exit wb_module_exit(void)  	platform_device_unregister(wistron_device);  	platform_driver_unregister(&wistron_driver);  	unmap_bios(); +	kfree(keymap);  }  module_init(wb_module_init);  |