Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Linux-御风守护者
linux
提交
106ad8d6
L
linux
项目概览
Linux-御风守护者
/
linux
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
106ad8d6
编写于
1月 09, 2009
作者:
L
Len Brown
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'fujitsu-laptop' into release
上级
33a8c927
f87a1a5f
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
293 addition
and
126 deletion
+293
-126
drivers/misc/fujitsu-laptop.c
drivers/misc/fujitsu-laptop.c
+293
-126
未找到文件。
drivers/misc/fujitsu-laptop.c
浏览文件 @
106ad8d6
...
...
@@ -3,6 +3,7 @@
/*
Copyright (C) 2007,2008 Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
Copyright (C) 2008 Peter Gruber <nokos@gmx.net>
Copyright (C) 2008 Tony Vroon <tony@linx.net>
Based on earlier work:
Copyright (C) 2003 Shane Spencer <shane@bogomip.com>
Adrian Yee <brewt-fujitsu@brewt.org>
...
...
@@ -65,8 +66,11 @@
#include <linux/kfifo.h>
#include <linux/video_output.h>
#include <linux/platform_device.h>
#ifdef CONFIG_LEDS_CLASS
#include <linux/leds.h>
#endif
#define FUJITSU_DRIVER_VERSION "0.
4.3
"
#define FUJITSU_DRIVER_VERSION "0.
5.0
"
#define FUJITSU_LCD_N_LEVELS 8
...
...
@@ -83,6 +87,24 @@
#define ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS 0x86
#define ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS 0x87
/* FUNC interface - command values */
#define FUNC_RFKILL 0x1000
#define FUNC_LEDS 0x1001
#define FUNC_BUTTONS 0x1002
#define FUNC_BACKLIGHT 0x1004
/* FUNC interface - responses */
#define UNSUPPORTED_CMD 0x80000000
#ifdef CONFIG_LEDS_CLASS
/* FUNC interface - LED control */
#define FUNC_LED_OFF 0x1
#define FUNC_LED_ON 0x30001
#define KEYBOARD_LAMPS 0x100
#define LOGOLAMP_POWERON 0x2000
#define LOGOLAMP_ALWAYS 0x4000
#endif
/* Hotkey details */
#define KEY1_CODE 0x410
/* codes for the keys in the GIRB register */
#define KEY2_CODE 0x411
...
...
@@ -133,7 +155,6 @@ struct fujitsu_t {
static
struct
fujitsu_t
*
fujitsu
;
static
int
use_alt_lcd_levels
=
-
1
;
static
int
disable_brightness_keys
=
-
1
;
static
int
disable_brightness_adjust
=
-
1
;
/* Device used to access other hotkeys on the laptop */
...
...
@@ -145,8 +166,9 @@ struct fujitsu_hotkey_t {
struct
platform_device
*
pf_device
;
struct
kfifo
*
fifo
;
spinlock_t
fifo_lock
;
unsigned
int
irb
;
/* info about the pressed buttons */
int
rfkill_state
;
int
logolamp_registered
;
int
kblamps_registered
;
};
static
struct
fujitsu_hotkey_t
*
fujitsu_hotkey
;
...
...
@@ -154,12 +176,139 @@ static struct fujitsu_hotkey_t *fujitsu_hotkey;
static
void
acpi_fujitsu_hotkey_notify
(
acpi_handle
handle
,
u32
event
,
void
*
data
);
#ifdef CONFIG_LEDS_CLASS
static
enum
led_brightness
logolamp_get
(
struct
led_classdev
*
cdev
);
static
void
logolamp_set
(
struct
led_classdev
*
cdev
,
enum
led_brightness
brightness
);
struct
led_classdev
logolamp_led
=
{
.
name
=
"fujitsu::logolamp"
,
.
brightness_get
=
logolamp_get
,
.
brightness_set
=
logolamp_set
};
static
enum
led_brightness
kblamps_get
(
struct
led_classdev
*
cdev
);
static
void
kblamps_set
(
struct
led_classdev
*
cdev
,
enum
led_brightness
brightness
);
struct
led_classdev
kblamps_led
=
{
.
name
=
"fujitsu::kblamps"
,
.
brightness_get
=
kblamps_get
,
.
brightness_set
=
kblamps_set
};
#endif
#ifdef CONFIG_FUJITSU_LAPTOP_DEBUG
static
u32
dbg_level
=
0x03
;
#endif
static
void
acpi_fujitsu_notify
(
acpi_handle
handle
,
u32
event
,
void
*
data
);
/* Fujitsu ACPI interface function */
static
int
call_fext_func
(
int
cmd
,
int
arg0
,
int
arg1
,
int
arg2
)
{
acpi_status
status
=
AE_OK
;
union
acpi_object
params
[
4
]
=
{
{
.
type
=
ACPI_TYPE_INTEGER
},
{
.
type
=
ACPI_TYPE_INTEGER
},
{
.
type
=
ACPI_TYPE_INTEGER
},
{
.
type
=
ACPI_TYPE_INTEGER
}
};
struct
acpi_object_list
arg_list
=
{
4
,
&
params
[
0
]
};
struct
acpi_buffer
output
;
union
acpi_object
out_obj
;
acpi_handle
handle
=
NULL
;
status
=
acpi_get_handle
(
fujitsu_hotkey
->
acpi_handle
,
"FUNC"
,
&
handle
);
if
(
ACPI_FAILURE
(
status
))
{
vdbg_printk
(
FUJLAPTOP_DBG_ERROR
,
"FUNC interface is not present
\n
"
);
return
-
ENODEV
;
}
params
[
0
].
integer
.
value
=
cmd
;
params
[
1
].
integer
.
value
=
arg0
;
params
[
2
].
integer
.
value
=
arg1
;
params
[
3
].
integer
.
value
=
arg2
;
output
.
length
=
sizeof
(
out_obj
);
output
.
pointer
=
&
out_obj
;
status
=
acpi_evaluate_object
(
handle
,
NULL
,
&
arg_list
,
&
output
);
if
(
ACPI_FAILURE
(
status
))
{
vdbg_printk
(
FUJLAPTOP_DBG_WARN
,
"FUNC 0x%x (args 0x%x, 0x%x, 0x%x) call failed
\n
"
,
cmd
,
arg0
,
arg1
,
arg2
);
return
-
ENODEV
;
}
if
(
out_obj
.
type
!=
ACPI_TYPE_INTEGER
)
{
vdbg_printk
(
FUJLAPTOP_DBG_WARN
,
"FUNC 0x%x (args 0x%x, 0x%x, 0x%x) did not "
"return an integer
\n
"
,
cmd
,
arg0
,
arg1
,
arg2
);
return
-
ENODEV
;
}
vdbg_printk
(
FUJLAPTOP_DBG_TRACE
,
"FUNC 0x%x (args 0x%x, 0x%x, 0x%x) returned 0x%x
\n
"
,
cmd
,
arg0
,
arg1
,
arg2
,
(
int
)
out_obj
.
integer
.
value
);
return
out_obj
.
integer
.
value
;
}
#ifdef CONFIG_LEDS_CLASS
/* LED class callbacks */
static
void
logolamp_set
(
struct
led_classdev
*
cdev
,
enum
led_brightness
brightness
)
{
if
(
brightness
>=
LED_FULL
)
{
call_fext_func
(
FUNC_LEDS
,
0x1
,
LOGOLAMP_POWERON
,
FUNC_LED_ON
);
call_fext_func
(
FUNC_LEDS
,
0x1
,
LOGOLAMP_ALWAYS
,
FUNC_LED_ON
);
}
else
if
(
brightness
>=
LED_HALF
)
{
call_fext_func
(
FUNC_LEDS
,
0x1
,
LOGOLAMP_POWERON
,
FUNC_LED_ON
);
call_fext_func
(
FUNC_LEDS
,
0x1
,
LOGOLAMP_ALWAYS
,
FUNC_LED_OFF
);
}
else
{
call_fext_func
(
FUNC_LEDS
,
0x1
,
LOGOLAMP_POWERON
,
FUNC_LED_OFF
);
}
}
static
void
kblamps_set
(
struct
led_classdev
*
cdev
,
enum
led_brightness
brightness
)
{
if
(
brightness
>=
LED_FULL
)
call_fext_func
(
FUNC_LEDS
,
0x1
,
KEYBOARD_LAMPS
,
FUNC_LED_ON
);
else
call_fext_func
(
FUNC_LEDS
,
0x1
,
KEYBOARD_LAMPS
,
FUNC_LED_OFF
);
}
static
enum
led_brightness
logolamp_get
(
struct
led_classdev
*
cdev
)
{
enum
led_brightness
brightness
=
LED_OFF
;
int
poweron
,
always
;
poweron
=
call_fext_func
(
FUNC_LEDS
,
0x2
,
LOGOLAMP_POWERON
,
0x0
);
if
(
poweron
==
FUNC_LED_ON
)
{
brightness
=
LED_HALF
;
always
=
call_fext_func
(
FUNC_LEDS
,
0x2
,
LOGOLAMP_ALWAYS
,
0x0
);
if
(
always
==
FUNC_LED_ON
)
brightness
=
LED_FULL
;
}
return
brightness
;
}
static
enum
led_brightness
kblamps_get
(
struct
led_classdev
*
cdev
)
{
enum
led_brightness
brightness
=
LED_OFF
;
if
(
call_fext_func
(
FUNC_LEDS
,
0x2
,
KEYBOARD_LAMPS
,
0x0
)
==
FUNC_LED_ON
)
brightness
=
LED_FULL
;
return
brightness
;
}
#endif
/* Hardware access for LCD brightness control */
static
int
set_lcd_level
(
int
level
)
...
...
@@ -263,44 +412,34 @@ static int get_max_brightness(void)
return
fujitsu
->
max_brightness
;
}
static
int
get_lcd_level_alt
(
void
)
{
unsigned
long
long
state
=
0
;
acpi_status
status
=
AE_OK
;
vdbg_printk
(
FUJLAPTOP_DBG_TRACE
,
"get lcd level via GBLS
\n
"
);
status
=
acpi_evaluate_integer
(
fujitsu
->
acpi_handle
,
"GBLS"
,
NULL
,
&
state
);
if
(
status
<
0
)
return
status
;
fujitsu
->
brightness_level
=
state
&
0x0fffffff
;
if
(
state
&
0x80000000
)
fujitsu
->
brightness_changed
=
1
;
else
fujitsu
->
brightness_changed
=
0
;
return
fujitsu
->
brightness_level
;
}
/* Backlight device stuff */
static
int
bl_get_brightness
(
struct
backlight_device
*
b
)
{
if
(
use_alt_lcd_levels
)
return
get_lcd_level_alt
();
else
return
get_lcd_level
();
return
get_lcd_level
();
}
static
int
bl_update_status
(
struct
backlight_device
*
b
)
{
int
ret
;
if
(
b
->
props
.
power
==
4
)
ret
=
call_fext_func
(
FUNC_BACKLIGHT
,
0x1
,
0x4
,
0x3
);
else
ret
=
call_fext_func
(
FUNC_BACKLIGHT
,
0x1
,
0x4
,
0x0
);
if
(
ret
!=
0
)
vdbg_printk
(
FUJLAPTOP_DBG_ERROR
,
"Unable to adjust backlight power, error code %i
\n
"
,
ret
);
if
(
use_alt_lcd_levels
)
ret
urn
set_lcd_level_alt
(
b
->
props
.
brightness
);
ret
=
set_lcd_level_alt
(
b
->
props
.
brightness
);
else
return
set_lcd_level
(
b
->
props
.
brightness
);
ret
=
set_lcd_level
(
b
->
props
.
brightness
);
if
(
ret
!=
0
)
vdbg_printk
(
FUJLAPTOP_DBG_ERROR
,
"Unable to adjust LCD brightness, error code %i
\n
"
,
ret
);
return
ret
;
}
static
struct
backlight_ops
fujitsubl_ops
=
{
...
...
@@ -344,10 +483,7 @@ static ssize_t show_lcd_level(struct device *dev,
int
ret
;
if
(
use_alt_lcd_levels
)
ret
=
get_lcd_level_alt
();
else
ret
=
get_lcd_level
();
ret
=
get_lcd_level
();
if
(
ret
<
0
)
return
ret
;
...
...
@@ -372,52 +508,71 @@ static ssize_t store_lcd_level(struct device *dev,
if
(
ret
<
0
)
return
ret
;
if
(
use_alt_lcd_levels
)
ret
=
get_lcd_level_alt
();
else
ret
=
get_lcd_level
();
ret
=
get_lcd_level
();
if
(
ret
<
0
)
return
ret
;
return
count
;
}
/* Hardware access for hotkey device */
static
int
get_irb
(
void
)
static
ssize_t
ignore_store
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
unsigned
long
long
state
=
0
;
acpi_status
status
=
AE_OK
;
vdbg_printk
(
FUJLAPTOP_DBG_TRACE
,
"Get irb
\n
"
);
status
=
acpi_evaluate_integer
(
fujitsu_hotkey
->
acpi_handle
,
"GIRB"
,
NULL
,
&
state
);
if
(
status
<
0
)
return
status
;
return
count
;
}
fujitsu_hotkey
->
irb
=
state
;
static
ssize_t
show_lid_state
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
if
(
fujitsu_hotkey
->
rfkill_state
==
UNSUPPORTED_CMD
)
return
sprintf
(
buf
,
"unknown
\n
"
);
if
(
fujitsu_hotkey
->
rfkill_state
&
0x100
)
return
sprintf
(
buf
,
"open
\n
"
);
else
return
sprintf
(
buf
,
"closed
\n
"
);
}
return
fujitsu_hotkey
->
irb
;
static
ssize_t
show_dock_state
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
if
(
fujitsu_hotkey
->
rfkill_state
==
UNSUPPORTED_CMD
)
return
sprintf
(
buf
,
"unknown
\n
"
);
if
(
fujitsu_hotkey
->
rfkill_state
&
0x200
)
return
sprintf
(
buf
,
"docked
\n
"
);
else
return
sprintf
(
buf
,
"undocked
\n
"
);
}
static
ssize_t
ignore_stor
e
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
show_radios_stat
e
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
return
count
;
if
(
fujitsu_hotkey
->
rfkill_state
==
UNSUPPORTED_CMD
)
return
sprintf
(
buf
,
"unknown
\n
"
);
if
(
fujitsu_hotkey
->
rfkill_state
&
0x20
)
return
sprintf
(
buf
,
"on
\n
"
);
else
return
sprintf
(
buf
,
"killed
\n
"
);
}
static
DEVICE_ATTR
(
max_brightness
,
0444
,
show_max_brightness
,
ignore_store
);
static
DEVICE_ATTR
(
brightness_changed
,
0444
,
show_brightness_changed
,
ignore_store
);
static
DEVICE_ATTR
(
lcd_level
,
0644
,
show_lcd_level
,
store_lcd_level
);
static
DEVICE_ATTR
(
lid
,
0444
,
show_lid_state
,
ignore_store
);
static
DEVICE_ATTR
(
dock
,
0444
,
show_dock_state
,
ignore_store
);
static
DEVICE_ATTR
(
radios
,
0444
,
show_radios_state
,
ignore_store
);
static
struct
attribute
*
fujitsupf_attributes
[]
=
{
&
dev_attr_brightness_changed
.
attr
,
&
dev_attr_max_brightness
.
attr
,
&
dev_attr_lcd_level
.
attr
,
&
dev_attr_lid
.
attr
,
&
dev_attr_dock
.
attr
,
&
dev_attr_radios
.
attr
,
NULL
};
...
...
@@ -435,24 +590,16 @@ static struct platform_driver fujitsupf_driver = {
static
void
dmi_check_cb_common
(
const
struct
dmi_system_id
*
id
)
{
acpi_handle
handle
;
int
have_blnf
;
printk
(
KERN_INFO
"fujitsu-laptop: Identified laptop model '%s'.
\n
"
,
id
->
ident
);
have_blnf
=
ACPI_SUCCESS
(
acpi_get_handle
(
NULL
,
"
\\
_SB.PCI0.GFX0.LCD.BLNF"
,
&
handle
));
if
(
use_alt_lcd_levels
==
-
1
)
{
vdbg_printk
(
FUJLAPTOP_DBG_TRACE
,
"auto-detecting usealt
\n
"
);
use_alt_lcd_levels
=
1
;
}
if
(
disable_brightness_keys
==
-
1
)
{
vdbg_printk
(
FUJLAPTOP_DBG_TRACE
,
"auto-detecting disable_keys
\n
"
);
disable_brightness_keys
=
have_blnf
?
1
:
0
;
}
if
(
disable_brightness_adjust
==
-
1
)
{
vdbg_printk
(
FUJLAPTOP_DBG_TRACE
,
"auto-detecting disable_adjust
\n
"
);
disable_brightness_adjust
=
have_blnf
?
0
:
1
;
if
(
ACPI_SUCCESS
(
acpi_get_handle
(
NULL
,
"
\\
_SB.PCI0.LPCB.FJEX.SBL2"
,
&
handle
)))
use_alt_lcd_levels
=
1
;
else
use_alt_lcd_levels
=
0
;
vdbg_printk
(
FUJLAPTOP_DBG_TRACE
,
"auto-detected usealt as "
"%i
\n
"
,
use_alt_lcd_levels
);
}
}
...
...
@@ -581,19 +728,14 @@ static int acpi_fujitsu_add(struct acpi_device *device)
/* do config (detect defaults) */
use_alt_lcd_levels
=
use_alt_lcd_levels
==
1
?
1
:
0
;
disable_brightness_keys
=
disable_brightness_keys
==
1
?
1
:
0
;
disable_brightness_adjust
=
disable_brightness_adjust
==
1
?
1
:
0
;
vdbg_printk
(
FUJLAPTOP_DBG_INFO
,
"config: [alt interface: %d], [key disable: %d], [adjust disable: %d]
\n
"
,
use_alt_lcd_levels
,
disable_brightness_keys
,
disable_brightness_adjust
);
"config: [alt interface: %d], [adjust disable: %d]
\n
"
,
use_alt_lcd_levels
,
disable_brightness_adjust
);
if
(
get_max_brightness
()
<=
0
)
fujitsu
->
max_brightness
=
FUJITSU_LCD_N_LEVELS
;
if
(
use_alt_lcd_levels
)
get_lcd_level_alt
();
else
get_lcd_level
();
get_lcd_level
();
return
result
;
...
...
@@ -644,43 +786,23 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data)
case
ACPI_FUJITSU_NOTIFY_CODE1
:
keycode
=
0
;
oldb
=
fujitsu
->
brightness_level
;
get_lcd_level
();
/* the alt version always yields changed */
get_lcd_level
();
newb
=
fujitsu
->
brightness_level
;
vdbg_printk
(
FUJLAPTOP_DBG_TRACE
,
"brightness button event [%i -> %i (%i)]
\n
"
,
oldb
,
newb
,
fujitsu
->
brightness_changed
);
if
(
oldb
==
newb
&&
fujitsu
->
brightness_changed
)
{
keycode
=
0
;
if
(
disable_brightness_keys
!=
1
)
{
if
(
oldb
==
0
)
{
acpi_bus_generate_proc_event
(
fujitsu
->
dev
,
ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS
,
0
);
keycode
=
KEY_BRIGHTNESSDOWN
;
}
else
if
(
oldb
==
(
fujitsu
->
max_brightness
)
-
1
)
{
acpi_bus_generate_proc_event
(
fujitsu
->
dev
,
ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS
,
0
);
keycode
=
KEY_BRIGHTNESSUP
;
}
}
}
else
if
(
oldb
<
newb
)
{
if
(
oldb
<
newb
)
{
if
(
disable_brightness_adjust
!=
1
)
{
if
(
use_alt_lcd_levels
)
set_lcd_level_alt
(
newb
);
else
set_lcd_level
(
newb
);
}
if
(
disable_brightness_keys
!=
1
)
{
acpi_bus_generate_proc_event
(
fujitsu
->
dev
,
ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS
,
0
);
keycode
=
KEY_BRIGHTNESSUP
;
}
acpi_bus_generate_proc_event
(
fujitsu
->
dev
,
ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS
,
0
);
keycode
=
KEY_BRIGHTNESSUP
;
}
else
if
(
oldb
>
newb
)
{
if
(
disable_brightness_adjust
!=
1
)
{
if
(
use_alt_lcd_levels
)
...
...
@@ -688,13 +810,9 @@ static void acpi_fujitsu_notify(acpi_handle handle, u32 event, void *data)
else
set_lcd_level
(
newb
);
}
if
(
disable_brightness_keys
!=
1
)
{
acpi_bus_generate_proc_event
(
fujitsu
->
dev
,
ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS
,
0
);
keycode
=
KEY_BRIGHTNESSDOWN
;
}
}
else
{
keycode
=
KEY_UNKNOWN
;
acpi_bus_generate_proc_event
(
fujitsu
->
dev
,
ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS
,
0
);
keycode
=
KEY_BRIGHTNESSDOWN
;
}
break
;
default:
...
...
@@ -771,7 +889,8 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
input
->
id
.
bustype
=
BUS_HOST
;
input
->
id
.
product
=
0x06
;
input
->
dev
.
parent
=
&
device
->
dev
;
input
->
evbit
[
0
]
=
BIT
(
EV_KEY
);
set_bit
(
EV_KEY
,
input
->
evbit
);
set_bit
(
fujitsu
->
keycode1
,
input
->
keybit
);
set_bit
(
fujitsu
->
keycode2
,
input
->
keybit
);
set_bit
(
fujitsu
->
keycode3
,
input
->
keybit
);
...
...
@@ -803,10 +922,44 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device)
printk
(
KERN_ERR
"_INI Method failed
\n
"
);
}
i
=
0
;
/* Discard hotkey ringbuffer */
while
(
get_irb
()
!=
0
&&
(
i
++
)
<
MAX_HOTKEY_RINGBUFFER_SIZE
)
;
i
=
0
;
while
(
call_fext_func
(
FUNC_BUTTONS
,
0x1
,
0x0
,
0x0
)
!=
0
&&
(
i
++
)
<
MAX_HOTKEY_RINGBUFFER_SIZE
)
;
/* No action, result is discarded */
vdbg_printk
(
FUJLAPTOP_DBG_INFO
,
"Discarded %i ringbuffer entries
\n
"
,
i
);
fujitsu_hotkey
->
rfkill_state
=
call_fext_func
(
FUNC_RFKILL
,
0x4
,
0x0
,
0x0
);
/* Suspect this is a keymap of the application panel, print it */
printk
(
KERN_INFO
"fujitsu-laptop: BTNI: [0x%x]
\n
"
,
call_fext_func
(
FUNC_BUTTONS
,
0x0
,
0x0
,
0x0
));
#ifdef CONFIG_LEDS_CLASS
if
(
call_fext_func
(
FUNC_LEDS
,
0x0
,
0x0
,
0x0
)
&
LOGOLAMP_POWERON
)
{
result
=
led_classdev_register
(
&
fujitsu
->
pf_device
->
dev
,
&
logolamp_led
);
if
(
result
==
0
)
{
fujitsu_hotkey
->
logolamp_registered
=
1
;
}
else
{
printk
(
KERN_ERR
"fujitsu-laptop: Could not register "
"LED handler for logo lamp, error %i
\n
"
,
result
);
}
}
if
((
call_fext_func
(
FUNC_LEDS
,
0x0
,
0x0
,
0x0
)
&
KEYBOARD_LAMPS
)
&&
(
call_fext_func
(
FUNC_BUTTONS
,
0x0
,
0x0
,
0x0
)
==
0x0
))
{
result
=
led_classdev_register
(
&
fujitsu
->
pf_device
->
dev
,
&
kblamps_led
);
if
(
result
==
0
)
{
fujitsu_hotkey
->
kblamps_registered
=
1
;
}
else
{
printk
(
KERN_ERR
"fujitsu-laptop: Could not register "
"LED handler for keyboard lamps, error %i
\n
"
,
result
);
}
}
#endif
return
result
;
end:
...
...
@@ -852,16 +1005,15 @@ static void acpi_fujitsu_hotkey_notify(acpi_handle handle, u32 event,
input
=
fujitsu_hotkey
->
input
;
vdbg_printk
(
FUJLAPTOP_DBG_TRACE
,
"Hotkey event
\n
"
);
fujitsu_hotkey
->
rfkill_state
=
call_fext_func
(
FUNC_RFKILL
,
0x4
,
0x0
,
0x0
);
switch
(
event
)
{
case
ACPI_FUJITSU_NOTIFY_CODE1
:
i
=
0
;
while
((
irb
=
get_irb
())
!=
0
&&
(
i
++
)
<
MAX_HOTKEY_RINGBUFFER_SIZE
)
{
vdbg_printk
(
FUJLAPTOP_DBG_TRACE
,
"GIRB result [%x]
\n
"
,
irb
);
while
((
irb
=
call_fext_func
(
FUNC_BUTTONS
,
0x1
,
0x0
,
0x0
))
!=
0
&&
(
i
++
)
<
MAX_HOTKEY_RINGBUFFER_SIZE
)
{
switch
(
irb
&
0x4ff
)
{
case
KEY1_CODE
:
keycode
=
fujitsu
->
keycode1
;
...
...
@@ -1035,6 +1187,15 @@ static int __init fujitsu_init(void)
goto
fail_hotkey1
;
}
/* Sync backlight power status (needs FUJ02E3 device, hence deferred) */
if
(
!
acpi_video_backlight_support
())
{
if
(
call_fext_func
(
FUNC_BACKLIGHT
,
0x2
,
0x4
,
0x0
)
==
3
)
fujitsu
->
bl_device
->
props
.
power
=
4
;
else
fujitsu
->
bl_device
->
props
.
power
=
0
;
}
printk
(
KERN_INFO
"fujitsu-laptop: driver "
FUJITSU_DRIVER_VERSION
" successfully loaded.
\n
"
);
...
...
@@ -1074,6 +1235,14 @@ static int __init fujitsu_init(void)
static
void
__exit
fujitsu_cleanup
(
void
)
{
#ifdef CONFIG_LEDS_CLASS
if
(
fujitsu_hotkey
->
logolamp_registered
!=
0
)
led_classdev_unregister
(
&
logolamp_led
);
if
(
fujitsu_hotkey
->
kblamps_registered
!=
0
)
led_classdev_unregister
(
&
kblamps_led
);
#endif
sysfs_remove_group
(
&
fujitsu
->
pf_device
->
dev
.
kobj
,
&
fujitsupf_attribute_group
);
platform_device_unregister
(
fujitsu
->
pf_device
);
...
...
@@ -1098,9 +1267,6 @@ module_exit(fujitsu_cleanup);
module_param
(
use_alt_lcd_levels
,
uint
,
0644
);
MODULE_PARM_DESC
(
use_alt_lcd_levels
,
"Use alternative interface for lcd_levels (needed for Lifebook s6410)."
);
module_param
(
disable_brightness_keys
,
uint
,
0644
);
MODULE_PARM_DESC
(
disable_brightness_keys
,
"Disable brightness keys (eg. if they are already handled by the generic ACPI_VIDEO device)."
);
module_param
(
disable_brightness_adjust
,
uint
,
0644
);
MODULE_PARM_DESC
(
disable_brightness_adjust
,
"Disable brightness adjustment ."
);
#ifdef CONFIG_FUJITSU_LAPTOP_DEBUG
...
...
@@ -1108,12 +1274,13 @@ module_param_named(debug, dbg_level, uint, 0644);
MODULE_PARM_DESC
(
debug
,
"Sets debug level bit-mask"
);
#endif
MODULE_AUTHOR
(
"Jonathan Woithe, Peter Gruber"
);
MODULE_AUTHOR
(
"Jonathan Woithe, Peter Gruber
, Tony Vroon
"
);
MODULE_DESCRIPTION
(
"Fujitsu laptop extras support"
);
MODULE_VERSION
(
FUJITSU_DRIVER_VERSION
);
MODULE_LICENSE
(
"GPL"
);
MODULE_ALIAS
(
"dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1D3:*:cvrS6410:*"
);
MODULE_ALIAS
(
"dmi:*:svnFUJITSUSIEMENS:*:pvr:rvnFUJITSU:rnFJNB1E6:*:cvrS6420:*"
);
MODULE_ALIAS
(
"dmi:*:svnFUJITSU:*:pvr:rvnFUJITSU:rnFJNB19C:*:cvrS7020:*"
);
static
struct
pnp_device_id
pnp_ids
[]
=
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录