Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
689a8ab3
Commit
689a8ab3
authored
Dec 16, 2009
by
Len Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'dell-wmi' into release
parents
1fc22fad
5ea25597
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
116 additions
and
13 deletions
+116
-13
drivers/platform/x86/dell-wmi.c
drivers/platform/x86/dell-wmi.c
+116
-13
No files found.
drivers/platform/x86/dell-wmi.c
View file @
689a8ab3
...
...
@@ -31,6 +31,7 @@
#include <acpi/acpi_drivers.h>
#include <linux/acpi.h>
#include <linux/string.h>
#include <linux/dmi.h>
MODULE_AUTHOR
(
"Matthew Garrett <mjg@redhat.com>"
);
MODULE_DESCRIPTION
(
"Dell laptop WMI hotkeys driver"
);
...
...
@@ -38,6 +39,8 @@ MODULE_LICENSE("GPL");
#define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492"
static
int
acpi_video
;
MODULE_ALIAS
(
"wmi:"
DELL_EVENT_GUID
);
struct
key_entry
{
...
...
@@ -54,7 +57,7 @@ enum { KE_KEY, KE_SW, KE_IGNORE, KE_END };
* via the keyboard controller so should not be sent again.
*/
static
struct
key_entry
dell_wmi_keymap
[]
=
{
static
struct
key_entry
dell_
legacy_
wmi_keymap
[]
=
{
{
KE_KEY
,
0xe045
,
KEY_PROG1
},
{
KE_KEY
,
0xe009
,
KEY_EJECTCD
},
...
...
@@ -72,7 +75,7 @@ static struct key_entry dell_wmi_keymap[] = {
/* The next device is at offset 6, the active devices are at
offset 8 and the attached devices at offset 10 */
{
KE_KEY
,
0xe00b
,
KEY_
DISPLAYTOGGL
E
},
{
KE_KEY
,
0xe00b
,
KEY_
SWITCHVIDEOMOD
E
},
{
KE_IGNORE
,
0xe00c
,
KEY_KBDILLUMTOGGLE
},
...
...
@@ -96,6 +99,47 @@ static struct key_entry dell_wmi_keymap[] = {
{
KE_END
,
0
}
};
static
bool
dell_new_hk_type
;
struct
dell_new_keymap_entry
{
u16
scancode
;
u16
keycode
;
};
struct
dell_hotkey_table
{
struct
dmi_header
header
;
struct
dell_new_keymap_entry
keymap
[];
};
static
struct
key_entry
*
dell_new_wmi_keymap
;
static
u16
bios_to_linux_keycode
[
256
]
=
{
KEY_MEDIA
,
KEY_NEXTSONG
,
KEY_PLAYPAUSE
,
KEY_PREVIOUSSONG
,
KEY_STOPCD
,
KEY_UNKNOWN
,
KEY_UNKNOWN
,
KEY_UNKNOWN
,
KEY_WWW
,
KEY_UNKNOWN
,
KEY_VOLUMEDOWN
,
KEY_MUTE
,
KEY_VOLUMEUP
,
KEY_UNKNOWN
,
KEY_BATTERY
,
KEY_EJECTCD
,
KEY_UNKNOWN
,
KEY_SLEEP
,
KEY_PROG1
,
KEY_BRIGHTNESSDOWN
,
KEY_BRIGHTNESSUP
,
KEY_UNKNOWN
,
KEY_KBDILLUMTOGGLE
,
KEY_UNKNOWN
,
KEY_SWITCHVIDEOMODE
,
KEY_UNKNOWN
,
KEY_UNKNOWN
,
KEY_SWITCHVIDEOMODE
,
KEY_UNKNOWN
,
KEY_UNKNOWN
,
KEY_PROG2
,
KEY_UNKNOWN
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
KEY_PROG3
};
static
struct
key_entry
*
dell_wmi_keymap
=
dell_legacy_wmi_keymap
;
static
struct
input_dev
*
dell_wmi_input_dev
;
static
struct
key_entry
*
dell_wmi_get_entry_by_scancode
(
int
code
)
...
...
@@ -164,24 +208,78 @@ static void dell_wmi_notify(u32 value, void *context)
obj
=
(
union
acpi_object
*
)
response
.
pointer
;
if
(
obj
&&
obj
->
type
==
ACPI_TYPE_BUFFER
)
{
int
*
buffer
=
(
int
*
)
obj
->
buffer
.
pointer
;
/*
* The upper bytes of the event may contain
* additional information, so mask them off for the
* scancode lookup
*/
key
=
dell_wmi_get_entry_by_scancode
(
buffer
[
1
]
&
0xFFFF
);
if
(
key
)
{
int
reported_key
;
u16
*
buffer_entry
=
(
u16
*
)
obj
->
buffer
.
pointer
;
if
(
dell_new_hk_type
&&
(
buffer_entry
[
1
]
!=
0x10
))
{
printk
(
KERN_INFO
"dell-wmi: Received unknown WMI event"
" (0x%x)
\n
"
,
buffer_entry
[
1
]);
return
;
}
if
(
dell_new_hk_type
)
reported_key
=
(
int
)
buffer_entry
[
2
];
else
reported_key
=
(
int
)
buffer_entry
[
1
]
&
0xffff
;
key
=
dell_wmi_get_entry_by_scancode
(
reported_key
);
if
(
!
key
)
{
printk
(
KERN_INFO
"dell-wmi: Unknown key %x pressed
\n
"
,
reported_key
);
}
else
if
((
key
->
keycode
==
KEY_BRIGHTNESSUP
||
key
->
keycode
==
KEY_BRIGHTNESSDOWN
)
&&
acpi_video
)
{
/* Don't report brightness notifications that will also
* come via ACPI */
return
;
}
else
{
input_report_key
(
dell_wmi_input_dev
,
key
->
keycode
,
1
);
input_sync
(
dell_wmi_input_dev
);
input_report_key
(
dell_wmi_input_dev
,
key
->
keycode
,
0
);
input_sync
(
dell_wmi_input_dev
);
}
else
if
(
buffer
[
1
]
&
0xFFFF
)
printk
(
KERN_INFO
"dell-wmi: Unknown key %x pressed
\n
"
,
buffer
[
1
]
&
0xFFFF
);
}
}
}
static
void
setup_new_hk_map
(
const
struct
dmi_header
*
dm
)
{
int
i
;
int
hotkey_num
=
(
dm
->
length
-
4
)
/
sizeof
(
struct
dell_new_keymap_entry
);
struct
dell_hotkey_table
*
table
=
container_of
(
dm
,
struct
dell_hotkey_table
,
header
);
dell_new_wmi_keymap
=
kzalloc
((
hotkey_num
+
1
)
*
sizeof
(
struct
key_entry
),
GFP_KERNEL
);
for
(
i
=
0
;
i
<
hotkey_num
;
i
++
)
{
dell_new_wmi_keymap
[
i
].
type
=
KE_KEY
;
dell_new_wmi_keymap
[
i
].
code
=
table
->
keymap
[
i
].
scancode
;
dell_new_wmi_keymap
[
i
].
keycode
=
(
table
->
keymap
[
i
].
keycode
>
255
)
?
0
:
bios_to_linux_keycode
[
table
->
keymap
[
i
].
keycode
];
}
dell_new_wmi_keymap
[
i
].
type
=
KE_END
;
dell_new_wmi_keymap
[
i
].
code
=
0
;
dell_new_wmi_keymap
[
i
].
keycode
=
0
;
dell_wmi_keymap
=
dell_new_wmi_keymap
;
}
static
void
find_hk_type
(
const
struct
dmi_header
*
dm
,
void
*
dummy
)
{
if
((
dm
->
type
==
0xb2
)
&&
(
dm
->
length
>
6
))
{
dell_new_hk_type
=
true
;
setup_new_hk_map
(
dm
);
}
}
static
int
__init
dell_wmi_input_setup
(
void
)
{
struct
key_entry
*
key
;
...
...
@@ -226,6 +324,9 @@ static int __init dell_wmi_init(void)
int
err
;
if
(
wmi_has_guid
(
DELL_EVENT_GUID
))
{
dmi_walk
(
find_hk_type
,
NULL
);
err
=
dell_wmi_input_setup
();
if
(
err
)
...
...
@@ -240,6 +341,8 @@ static int __init dell_wmi_init(void)
return
err
;
}
acpi_video
=
acpi_video_backlight_support
();
}
else
printk
(
KERN_WARNING
"dell-wmi: No known WMI GUID found
\n
"
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment