Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xiphi1978
linux
提交
99380825
L
linux
项目概览
xiphi1978
/
linux
通知
2
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,发现更多精彩内容 >>
提交
99380825
编写于
3月 27, 2012
作者:
D
Dmitry Torokhov
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'next' into for-linus
Conflicts: drivers/input/tablet/wacom_sys.c
上级
10ce3cc9
131c713f
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
694 addition
and
202 deletion
+694
-202
arch/arm/plat-spear/include/plat/keyboard.h
arch/arm/plat-spear/include/plat/keyboard.h
+0
-7
drivers/input/joystick/amijoy.c
drivers/input/joystick/amijoy.c
+3
-0
drivers/input/keyboard/gpio_keys.c
drivers/input/keyboard/gpio_keys.c
+169
-90
drivers/input/keyboard/tegra-kbc.c
drivers/input/keyboard/tegra-kbc.c
+1
-0
drivers/input/mouse/sentelic.c
drivers/input/mouse/sentelic.c
+224
-70
drivers/input/mouse/sentelic.h
drivers/input/mouse/sentelic.h
+33
-2
drivers/input/tablet/Kconfig
drivers/input/tablet/Kconfig
+1
-0
drivers/input/tablet/wacom.h
drivers/input/tablet/wacom.h
+9
-0
drivers/input/tablet/wacom_sys.c
drivers/input/tablet/wacom_sys.c
+198
-31
drivers/input/tablet/wacom_wac.c
drivers/input/tablet/wacom_wac.c
+48
-1
drivers/input/tablet/wacom_wac.h
drivers/input/tablet/wacom_wac.h
+6
-0
include/linux/gpio_keys.h
include/linux/gpio_keys.h
+2
-1
未找到文件。
arch/arm/plat-spear/include/plat/keyboard.h
浏览文件 @
99380825
...
@@ -159,11 +159,4 @@ struct kbd_platform_data {
...
@@ -159,11 +159,4 @@ struct kbd_platform_data {
unsigned
int
mode
;
unsigned
int
mode
;
};
};
/* This function is used to set platform data field of pdev->dev */
static
inline
void
kbd_set_plat_data
(
struct
platform_device
*
pdev
,
struct
kbd_platform_data
*
data
)
{
pdev
->
dev
.
platform_data
=
data
;
}
#endif
/* __PLAT_KEYBOARD_H */
#endif
/* __PLAT_KEYBOARD_H */
drivers/input/joystick/amijoy.c
浏览文件 @
99380825
...
@@ -108,6 +108,9 @@ static int __init amijoy_init(void)
...
@@ -108,6 +108,9 @@ static int __init amijoy_init(void)
int
i
,
j
;
int
i
,
j
;
int
err
;
int
err
;
if
(
!
MACH_IS_AMIGA
)
return
-
ENODEV
;
for
(
i
=
0
;
i
<
2
;
i
++
)
{
for
(
i
=
0
;
i
<
2
;
i
++
)
{
if
(
!
amijoy
[
i
])
if
(
!
amijoy
[
i
])
continue
;
continue
;
...
...
drivers/input/keyboard/gpio_keys.c
浏览文件 @
99380825
...
@@ -28,14 +28,18 @@
...
@@ -28,14 +28,18 @@
#include <linux/gpio.h>
#include <linux/gpio.h>
#include <linux/of_platform.h>
#include <linux/of_platform.h>
#include <linux/of_gpio.h>
#include <linux/of_gpio.h>
#include <linux/spinlock.h>
struct
gpio_button_data
{
struct
gpio_button_data
{
struct
gpio_keys_button
*
button
;
const
struct
gpio_keys_button
*
button
;
struct
input_dev
*
input
;
struct
input_dev
*
input
;
struct
timer_list
timer
;
struct
timer_list
timer
;
struct
work_struct
work
;
struct
work_struct
work
;
int
timer_debounce
;
/* in msecs */
unsigned
int
timer_debounce
;
/* in msecs */
unsigned
int
irq
;
spinlock_t
lock
;
bool
disabled
;
bool
disabled
;
bool
key_pressed
;
};
};
struct
gpio_keys_drvdata
{
struct
gpio_keys_drvdata
{
...
@@ -114,7 +118,7 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata)
...
@@ -114,7 +118,7 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata)
/*
/*
* Disable IRQ and possible debouncing timer.
* Disable IRQ and possible debouncing timer.
*/
*/
disable_irq
(
gpio_to_irq
(
bdata
->
button
->
gpio
)
);
disable_irq
(
bdata
->
irq
);
if
(
bdata
->
timer_debounce
)
if
(
bdata
->
timer_debounce
)
del_timer_sync
(
&
bdata
->
timer
);
del_timer_sync
(
&
bdata
->
timer
);
...
@@ -135,7 +139,7 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata)
...
@@ -135,7 +139,7 @@ static void gpio_keys_disable_button(struct gpio_button_data *bdata)
static
void
gpio_keys_enable_button
(
struct
gpio_button_data
*
bdata
)
static
void
gpio_keys_enable_button
(
struct
gpio_button_data
*
bdata
)
{
{
if
(
bdata
->
disabled
)
{
if
(
bdata
->
disabled
)
{
enable_irq
(
gpio_to_irq
(
bdata
->
button
->
gpio
)
);
enable_irq
(
bdata
->
irq
);
bdata
->
disabled
=
false
;
bdata
->
disabled
=
false
;
}
}
}
}
...
@@ -195,7 +199,7 @@ static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata,
...
@@ -195,7 +199,7 @@ static ssize_t gpio_keys_attr_show_helper(struct gpio_keys_drvdata *ddata,
* @type: button type (%EV_KEY, %EV_SW)
* @type: button type (%EV_KEY, %EV_SW)
*
*
* This function parses stringified bitmap from @buf and disables/enables
* This function parses stringified bitmap from @buf and disables/enables
* GPIO buttons accordinly. Returns 0 on success and negative error
* GPIO buttons accordin
g
ly. Returns 0 on success and negative error
* on failure.
* on failure.
*/
*/
static
ssize_t
gpio_keys_attr_store_helper
(
struct
gpio_keys_drvdata
*
ddata
,
static
ssize_t
gpio_keys_attr_store_helper
(
struct
gpio_keys_drvdata
*
ddata
,
...
@@ -320,9 +324,9 @@ static struct attribute_group gpio_keys_attr_group = {
...
@@ -320,9 +324,9 @@ static struct attribute_group gpio_keys_attr_group = {
.
attrs
=
gpio_keys_attrs
,
.
attrs
=
gpio_keys_attrs
,
};
};
static
void
gpio_keys_report_event
(
struct
gpio_button_data
*
bdata
)
static
void
gpio_keys_
gpio_
report_event
(
struct
gpio_button_data
*
bdata
)
{
{
struct
gpio_keys_button
*
button
=
bdata
->
button
;
const
struct
gpio_keys_button
*
button
=
bdata
->
button
;
struct
input_dev
*
input
=
bdata
->
input
;
struct
input_dev
*
input
=
bdata
->
input
;
unsigned
int
type
=
button
->
type
?:
EV_KEY
;
unsigned
int
type
=
button
->
type
?:
EV_KEY
;
int
state
=
(
gpio_get_value_cansleep
(
button
->
gpio
)
?
1
:
0
)
^
button
->
active_low
;
int
state
=
(
gpio_get_value_cansleep
(
button
->
gpio
)
?
1
:
0
)
^
button
->
active_low
;
...
@@ -336,27 +340,26 @@ static void gpio_keys_report_event(struct gpio_button_data *bdata)
...
@@ -336,27 +340,26 @@ static void gpio_keys_report_event(struct gpio_button_data *bdata)
input_sync
(
input
);
input_sync
(
input
);
}
}
static
void
gpio_keys_work_func
(
struct
work_struct
*
work
)
static
void
gpio_keys_
gpio_
work_func
(
struct
work_struct
*
work
)
{
{
struct
gpio_button_data
*
bdata
=
struct
gpio_button_data
*
bdata
=
container_of
(
work
,
struct
gpio_button_data
,
work
);
container_of
(
work
,
struct
gpio_button_data
,
work
);
gpio_keys_report_event
(
bdata
);
gpio_keys_
gpio_
report_event
(
bdata
);
}
}
static
void
gpio_keys_timer
(
unsigned
long
_data
)
static
void
gpio_keys_
gpio_
timer
(
unsigned
long
_data
)
{
{
struct
gpio_button_data
*
data
=
(
struct
gpio_button_data
*
)
_data
;
struct
gpio_button_data
*
b
data
=
(
struct
gpio_button_data
*
)
_data
;
schedule_work
(
&
data
->
work
);
schedule_work
(
&
b
data
->
work
);
}
}
static
irqreturn_t
gpio_keys_isr
(
int
irq
,
void
*
dev_id
)
static
irqreturn_t
gpio_keys_
gpio_
isr
(
int
irq
,
void
*
dev_id
)
{
{
struct
gpio_button_data
*
bdata
=
dev_id
;
struct
gpio_button_data
*
bdata
=
dev_id
;
struct
gpio_keys_button
*
button
=
bdata
->
button
;
BUG_ON
(
irq
!=
gpio_to_irq
(
button
->
gpio
)
);
BUG_ON
(
irq
!=
bdata
->
irq
);
if
(
bdata
->
timer_debounce
)
if
(
bdata
->
timer_debounce
)
mod_timer
(
&
bdata
->
timer
,
mod_timer
(
&
bdata
->
timer
,
...
@@ -367,50 +370,133 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
...
@@ -367,50 +370,133 @@ static irqreturn_t gpio_keys_isr(int irq, void *dev_id)
return
IRQ_HANDLED
;
return
IRQ_HANDLED
;
}
}
static
void
gpio_keys_irq_timer
(
unsigned
long
_data
)
{
struct
gpio_button_data
*
bdata
=
(
struct
gpio_button_data
*
)
_data
;
struct
input_dev
*
input
=
bdata
->
input
;
unsigned
long
flags
;
spin_lock_irqsave
(
&
bdata
->
lock
,
flags
);
if
(
bdata
->
key_pressed
)
{
input_event
(
input
,
EV_KEY
,
bdata
->
button
->
code
,
0
);
input_sync
(
input
);
bdata
->
key_pressed
=
false
;
}
spin_unlock_irqrestore
(
&
bdata
->
lock
,
flags
);
}
static
irqreturn_t
gpio_keys_irq_isr
(
int
irq
,
void
*
dev_id
)
{
struct
gpio_button_data
*
bdata
=
dev_id
;
const
struct
gpio_keys_button
*
button
=
bdata
->
button
;
struct
input_dev
*
input
=
bdata
->
input
;
unsigned
long
flags
;
BUG_ON
(
irq
!=
bdata
->
irq
);
spin_lock_irqsave
(
&
bdata
->
lock
,
flags
);
if
(
!
bdata
->
key_pressed
)
{
input_event
(
input
,
EV_KEY
,
button
->
code
,
1
);
input_sync
(
input
);
if
(
!
bdata
->
timer_debounce
)
{
input_event
(
input
,
EV_KEY
,
button
->
code
,
0
);
input_sync
(
input
);
goto
out
;
}
bdata
->
key_pressed
=
true
;
}
if
(
bdata
->
timer_debounce
)
mod_timer
(
&
bdata
->
timer
,
jiffies
+
msecs_to_jiffies
(
bdata
->
timer_debounce
));
out:
spin_unlock_irqrestore
(
&
bdata
->
lock
,
flags
);
return
IRQ_HANDLED
;
}
static
int
__devinit
gpio_keys_setup_key
(
struct
platform_device
*
pdev
,
static
int
__devinit
gpio_keys_setup_key
(
struct
platform_device
*
pdev
,
struct
input_dev
*
input
,
struct
gpio_button_data
*
bdata
,
struct
gpio_button_data
*
bdata
,
struct
gpio_keys_button
*
button
)
const
struct
gpio_keys_button
*
button
)
{
{
const
char
*
desc
=
button
->
desc
?
button
->
desc
:
"gpio_keys"
;
const
char
*
desc
=
button
->
desc
?
button
->
desc
:
"gpio_keys"
;
struct
device
*
dev
=
&
pdev
->
dev
;
struct
device
*
dev
=
&
pdev
->
dev
;
irq_handler_t
isr
;
unsigned
long
irqflags
;
unsigned
long
irqflags
;
int
irq
,
error
;
int
irq
,
error
;
setup_timer
(
&
bdata
->
timer
,
gpio_keys_timer
,
(
unsigned
long
)
bdata
);
bdata
->
input
=
input
;
INIT_WORK
(
&
bdata
->
work
,
gpio_keys_work_func
);
bdata
->
button
=
button
;
spin_lock_init
(
&
bdata
->
lock
);
error
=
gpio_request
(
button
->
gpio
,
desc
);
if
(
gpio_is_valid
(
button
->
gpio
))
{
if
(
error
<
0
)
{
dev_err
(
dev
,
"failed to request GPIO %d, error %d
\n
"
,
button
->
gpio
,
error
);
goto
fail2
;
}
error
=
gpio_direction_input
(
button
->
gpio
);
error
=
gpio_request
(
button
->
gpio
,
desc
);
if
(
error
<
0
)
{
if
(
error
<
0
)
{
dev_err
(
dev
,
"failed to configure"
dev_err
(
dev
,
"Failed to request GPIO %d, error %d
\n
"
,
" direction for GPIO %d, error %d
\n
"
,
button
->
gpio
,
error
);
button
->
gpio
,
error
);
return
error
;
goto
fail3
;
}
}
if
(
button
->
debounce_interval
)
{
error
=
gpio_direction_input
(
button
->
gpio
);
error
=
gpio_set_debounce
(
button
->
gpio
,
if
(
error
<
0
)
{
button
->
debounce_interval
*
1000
);
dev_err
(
dev
,
/* use timer if gpiolib doesn't provide debounce */
"Failed to configure direction for GPIO %d, error %d
\n
"
,
if
(
error
<
0
)
button
->
gpio
,
error
);
bdata
->
timer_debounce
=
button
->
debounce_interva
l
;
goto
fai
l
;
}
}
irq
=
gpio_to_irq
(
button
->
gpio
);
if
(
button
->
debounce_interval
)
{
if
(
irq
<
0
)
{
error
=
gpio_set_debounce
(
button
->
gpio
,
error
=
irq
;
button
->
debounce_interval
*
1000
);
dev_err
(
dev
,
"Unable to get irq number for GPIO %d, error %d
\n
"
,
/* use timer if gpiolib doesn't provide debounce */
button
->
gpio
,
error
);
if
(
error
<
0
)
goto
fail3
;
bdata
->
timer_debounce
=
button
->
debounce_interval
;
}
irq
=
gpio_to_irq
(
button
->
gpio
);
if
(
irq
<
0
)
{
error
=
irq
;
dev_err
(
dev
,
"Unable to get irq number for GPIO %d, error %d
\n
"
,
button
->
gpio
,
error
);
goto
fail
;
}
bdata
->
irq
=
irq
;
INIT_WORK
(
&
bdata
->
work
,
gpio_keys_gpio_work_func
);
setup_timer
(
&
bdata
->
timer
,
gpio_keys_gpio_timer
,
(
unsigned
long
)
bdata
);
isr
=
gpio_keys_gpio_isr
;
irqflags
=
IRQF_TRIGGER_RISING
|
IRQF_TRIGGER_FALLING
;
}
else
{
if
(
!
button
->
irq
)
{
dev_err
(
dev
,
"No IRQ specified
\n
"
);
return
-
EINVAL
;
}
bdata
->
irq
=
button
->
irq
;
if
(
button
->
type
&&
button
->
type
!=
EV_KEY
)
{
dev_err
(
dev
,
"Only EV_KEY allowed for IRQ buttons.
\n
"
);
return
-
EINVAL
;
}
bdata
->
timer_debounce
=
button
->
debounce_interval
;
setup_timer
(
&
bdata
->
timer
,
gpio_keys_irq_timer
,
(
unsigned
long
)
bdata
);
isr
=
gpio_keys_irq_isr
;
irqflags
=
0
;
}
}
irqflags
=
IRQF_TRIGGER_RISING
|
IRQF_TRIGGER_FALLING
;
input_set_capability
(
input
,
button
->
type
?:
EV_KEY
,
button
->
code
);
/*
/*
* If platform has specified that the button can be disabled,
* If platform has specified that the button can be disabled,
* we don't want it to share the interrupt line.
* we don't want it to share the interrupt line.
...
@@ -418,18 +504,19 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev,
...
@@ -418,18 +504,19 @@ static int __devinit gpio_keys_setup_key(struct platform_device *pdev,
if
(
!
button
->
can_disable
)
if
(
!
button
->
can_disable
)
irqflags
|=
IRQF_SHARED
;
irqflags
|=
IRQF_SHARED
;
error
=
request_
threaded_irq
(
irq
,
NULL
,
gpio_keys_
isr
,
irqflags
,
desc
,
bdata
);
error
=
request_
any_context_irq
(
bdata
->
irq
,
isr
,
irqflags
,
desc
,
bdata
);
if
(
error
<
0
)
{
if
(
error
<
0
)
{
dev_err
(
dev
,
"Unable to claim irq %d; error %d
\n
"
,
dev_err
(
dev
,
"Unable to claim irq %d; error %d
\n
"
,
irq
,
error
);
bdata
->
irq
,
error
);
goto
fail
3
;
goto
fail
;
}
}
return
0
;
return
0
;
fail3:
fail:
gpio_free
(
button
->
gpio
);
if
(
gpio_is_valid
(
button
->
gpio
))
fail2:
gpio_free
(
button
->
gpio
);
return
error
;
return
error
;
}
}
...
@@ -547,9 +634,19 @@ static int gpio_keys_get_devtree_pdata(struct device *dev,
...
@@ -547,9 +634,19 @@ static int gpio_keys_get_devtree_pdata(struct device *dev,
#endif
#endif
static
void
gpio_remove_key
(
struct
gpio_button_data
*
bdata
)
{
free_irq
(
bdata
->
irq
,
bdata
);
if
(
bdata
->
timer_debounce
)
del_timer_sync
(
&
bdata
->
timer
);
cancel_work_sync
(
&
bdata
->
work
);
if
(
gpio_is_valid
(
bdata
->
button
->
gpio
))
gpio_free
(
bdata
->
button
->
gpio
);
}
static
int
__devinit
gpio_keys_probe
(
struct
platform_device
*
pdev
)
static
int
__devinit
gpio_keys_probe
(
struct
platform_device
*
pdev
)
{
{
struct
gpio_keys_platform_data
*
pdata
=
pdev
->
dev
.
platform_data
;
const
struct
gpio_keys_platform_data
*
pdata
=
pdev
->
dev
.
platform_data
;
struct
gpio_keys_drvdata
*
ddata
;
struct
gpio_keys_drvdata
*
ddata
;
struct
device
*
dev
=
&
pdev
->
dev
;
struct
device
*
dev
=
&
pdev
->
dev
;
struct
gpio_keys_platform_data
alt_pdata
;
struct
gpio_keys_platform_data
alt_pdata
;
...
@@ -599,21 +696,15 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
...
@@ -599,21 +696,15 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
__set_bit
(
EV_REP
,
input
->
evbit
);
__set_bit
(
EV_REP
,
input
->
evbit
);
for
(
i
=
0
;
i
<
pdata
->
nbuttons
;
i
++
)
{
for
(
i
=
0
;
i
<
pdata
->
nbuttons
;
i
++
)
{
struct
gpio_keys_button
*
button
=
&
pdata
->
buttons
[
i
];
const
struct
gpio_keys_button
*
button
=
&
pdata
->
buttons
[
i
];
struct
gpio_button_data
*
bdata
=
&
ddata
->
data
[
i
];
struct
gpio_button_data
*
bdata
=
&
ddata
->
data
[
i
];
unsigned
int
type
=
button
->
type
?:
EV_KEY
;
bdata
->
input
=
input
;
bdata
->
button
=
button
;
error
=
gpio_keys_setup_key
(
pdev
,
bdata
,
button
);
error
=
gpio_keys_setup_key
(
pdev
,
input
,
bdata
,
button
);
if
(
error
)
if
(
error
)
goto
fail2
;
goto
fail2
;
if
(
button
->
wakeup
)
if
(
button
->
wakeup
)
wakeup
=
1
;
wakeup
=
1
;
input_set_capability
(
input
,
type
,
button
->
code
);
}
}
error
=
sysfs_create_group
(
&
pdev
->
dev
.
kobj
,
&
gpio_keys_attr_group
);
error
=
sysfs_create_group
(
&
pdev
->
dev
.
kobj
,
&
gpio_keys_attr_group
);
...
@@ -630,9 +721,12 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
...
@@ -630,9 +721,12 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
goto
fail3
;
goto
fail3
;
}
}
/* get current state of buttons */
/* get current state of buttons that are connected to GPIOs */
for
(
i
=
0
;
i
<
pdata
->
nbuttons
;
i
++
)
for
(
i
=
0
;
i
<
pdata
->
nbuttons
;
i
++
)
{
gpio_keys_report_event
(
&
ddata
->
data
[
i
]);
struct
gpio_button_data
*
bdata
=
&
ddata
->
data
[
i
];
if
(
gpio_is_valid
(
bdata
->
button
->
gpio
))
gpio_keys_gpio_report_event
(
bdata
);
}
input_sync
(
input
);
input_sync
(
input
);
device_init_wakeup
(
&
pdev
->
dev
,
wakeup
);
device_init_wakeup
(
&
pdev
->
dev
,
wakeup
);
...
@@ -642,13 +736,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
...
@@ -642,13 +736,8 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
fail3:
fail3:
sysfs_remove_group
(
&
pdev
->
dev
.
kobj
,
&
gpio_keys_attr_group
);
sysfs_remove_group
(
&
pdev
->
dev
.
kobj
,
&
gpio_keys_attr_group
);
fail2:
fail2:
while
(
--
i
>=
0
)
{
while
(
--
i
>=
0
)
free_irq
(
gpio_to_irq
(
pdata
->
buttons
[
i
].
gpio
),
&
ddata
->
data
[
i
]);
gpio_remove_key
(
&
ddata
->
data
[
i
]);
if
(
ddata
->
data
[
i
].
timer_debounce
)
del_timer_sync
(
&
ddata
->
data
[
i
].
timer
);
cancel_work_sync
(
&
ddata
->
data
[
i
].
work
);
gpio_free
(
pdata
->
buttons
[
i
].
gpio
);
}
platform_set_drvdata
(
pdev
,
NULL
);
platform_set_drvdata
(
pdev
,
NULL
);
fail1:
fail1:
...
@@ -671,14 +760,8 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
...
@@ -671,14 +760,8 @@ static int __devexit gpio_keys_remove(struct platform_device *pdev)
device_init_wakeup
(
&
pdev
->
dev
,
0
);
device_init_wakeup
(
&
pdev
->
dev
,
0
);
for
(
i
=
0
;
i
<
ddata
->
n_buttons
;
i
++
)
{
for
(
i
=
0
;
i
<
ddata
->
n_buttons
;
i
++
)
int
irq
=
gpio_to_irq
(
ddata
->
data
[
i
].
button
->
gpio
);
gpio_remove_key
(
&
ddata
->
data
[
i
]);
free_irq
(
irq
,
&
ddata
->
data
[
i
]);
if
(
ddata
->
data
[
i
].
timer_debounce
)
del_timer_sync
(
&
ddata
->
data
[
i
].
timer
);
cancel_work_sync
(
&
ddata
->
data
[
i
].
work
);
gpio_free
(
ddata
->
data
[
i
].
button
->
gpio
);
}
input_unregister_device
(
input
);
input_unregister_device
(
input
);
...
@@ -703,11 +786,9 @@ static int gpio_keys_suspend(struct device *dev)
...
@@ -703,11 +786,9 @@ static int gpio_keys_suspend(struct device *dev)
if
(
device_may_wakeup
(
dev
))
{
if
(
device_may_wakeup
(
dev
))
{
for
(
i
=
0
;
i
<
ddata
->
n_buttons
;
i
++
)
{
for
(
i
=
0
;
i
<
ddata
->
n_buttons
;
i
++
)
{
struct
gpio_keys_button
*
button
=
ddata
->
data
[
i
].
button
;
struct
gpio_button_data
*
bdata
=
&
ddata
->
data
[
i
];
if
(
button
->
wakeup
)
{
if
(
bdata
->
button
->
wakeup
)
int
irq
=
gpio_to_irq
(
button
->
gpio
);
enable_irq_wake
(
bdata
->
irq
);
enable_irq_wake
(
irq
);
}
}
}
}
}
...
@@ -720,14 +801,12 @@ static int gpio_keys_resume(struct device *dev)
...
@@ -720,14 +801,12 @@ static int gpio_keys_resume(struct device *dev)
int
i
;
int
i
;
for
(
i
=
0
;
i
<
ddata
->
n_buttons
;
i
++
)
{
for
(
i
=
0
;
i
<
ddata
->
n_buttons
;
i
++
)
{
struct
gpio_button_data
*
bdata
=
&
ddata
->
data
[
i
];
if
(
bdata
->
button
->
wakeup
&&
device_may_wakeup
(
dev
))
disable_irq_wake
(
bdata
->
irq
);
struct
gpio_keys_button
*
button
=
ddata
->
data
[
i
].
button
;
if
(
gpio_is_valid
(
bdata
->
button
->
gpio
))
if
(
button
->
wakeup
&&
device_may_wakeup
(
dev
))
{
gpio_keys_gpio_report_event
(
bdata
);
int
irq
=
gpio_to_irq
(
button
->
gpio
);
disable_irq_wake
(
irq
);
}
gpio_keys_report_event
(
&
ddata
->
data
[
i
]);
}
}
input_sync
(
ddata
->
input
);
input_sync
(
ddata
->
input
);
...
...
drivers/input/keyboard/tegra-kbc.c
浏览文件 @
99380825
...
@@ -630,6 +630,7 @@ tegra_kbc_dt_parse_pdata(struct platform_device *pdev)
...
@@ -630,6 +630,7 @@ tegra_kbc_dt_parse_pdata(struct platform_device *pdev)
if
(
!
np
)
if
(
!
np
)
return
NULL
;
return
NULL
;
pdata
=
kzalloc
(
sizeof
(
*
pdata
),
GFP_KERNEL
);
if
(
!
pdata
)
if
(
!
pdata
)
return
NULL
;
return
NULL
;
...
...
drivers/input/mouse/sentelic.c
浏览文件 @
99380825
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* Finger Sensing Pad PS/2 mouse driver.
* Finger Sensing Pad PS/2 mouse driver.
*
*
* Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
* Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
* Copyright (C) 2005-201
1
Tai-hwa Liang, Sentelic Corporation.
* Copyright (C) 2005-201
2
Tai-hwa Liang, Sentelic Corporation.
*
*
* This program is free software; you can redistribute it and/or
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* modify it under the terms of the GNU General Public License
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
#include <linux/module.h>
#include <linux/module.h>
#include <linux/input.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/ctype.h>
#include <linux/ctype.h>
#include <linux/libps2.h>
#include <linux/libps2.h>
#include <linux/serio.h>
#include <linux/serio.h>
...
@@ -36,6 +37,9 @@
...
@@ -36,6 +37,9 @@
#define FSP_CMD_TIMEOUT 200
#define FSP_CMD_TIMEOUT 200
#define FSP_CMD_TIMEOUT2 30
#define FSP_CMD_TIMEOUT2 30
#define GET_ABS_X(packet) ((packet[1] << 2) | ((packet[3] >> 2) & 0x03))
#define GET_ABS_Y(packet) ((packet[2] << 2) | (packet[3] & 0x03))
/** Driver version. */
/** Driver version. */
static
const
char
fsp_drv_ver
[]
=
"1.0.0-K"
;
static
const
char
fsp_drv_ver
[]
=
"1.0.0-K"
;
...
@@ -128,8 +132,9 @@ static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val)
...
@@ -128,8 +132,9 @@ static int fsp_reg_read(struct psmouse *psmouse, int reg_addr, int *reg_val)
out:
out:
ps2_end_command
(
ps2dev
);
ps2_end_command
(
ps2dev
);
psmouse_activate
(
psmouse
);
psmouse_activate
(
psmouse
);
dev_dbg
(
&
ps2dev
->
serio
->
dev
,
"READ REG: 0x%02x is 0x%02x (rc = %d)
\n
"
,
psmouse_dbg
(
psmouse
,
reg_addr
,
*
reg_val
,
rc
);
"READ REG: 0x%02x is 0x%02x (rc = %d)
\n
"
,
reg_addr
,
*
reg_val
,
rc
);
return
rc
;
return
rc
;
}
}
...
@@ -179,8 +184,9 @@ static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val)
...
@@ -179,8 +184,9 @@ static int fsp_reg_write(struct psmouse *psmouse, int reg_addr, int reg_val)
out:
out:
ps2_end_command
(
ps2dev
);
ps2_end_command
(
ps2dev
);
dev_dbg
(
&
ps2dev
->
serio
->
dev
,
"WRITE REG: 0x%02x to 0x%02x (rc = %d)
\n
"
,
psmouse_dbg
(
psmouse
,
reg_addr
,
reg_val
,
rc
);
"WRITE REG: 0x%02x to 0x%02x (rc = %d)
\n
"
,
reg_addr
,
reg_val
,
rc
);
return
rc
;
return
rc
;
}
}
...
@@ -237,8 +243,9 @@ static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val)
...
@@ -237,8 +243,9 @@ static int fsp_page_reg_read(struct psmouse *psmouse, int *reg_val)
out:
out:
ps2_end_command
(
ps2dev
);
ps2_end_command
(
ps2dev
);
psmouse_activate
(
psmouse
);
psmouse_activate
(
psmouse
);
dev_dbg
(
&
ps2dev
->
serio
->
dev
,
"READ PAGE REG: 0x%02x (rc = %d)
\n
"
,
psmouse_dbg
(
psmouse
,
*
reg_val
,
rc
);
"READ PAGE REG: 0x%02x (rc = %d)
\n
"
,
*
reg_val
,
rc
);
return
rc
;
return
rc
;
}
}
...
@@ -274,8 +281,9 @@ static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val)
...
@@ -274,8 +281,9 @@ static int fsp_page_reg_write(struct psmouse *psmouse, int reg_val)
out:
out:
ps2_end_command
(
ps2dev
);
ps2_end_command
(
ps2dev
);
dev_dbg
(
&
ps2dev
->
serio
->
dev
,
"WRITE PAGE REG: to 0x%02x (rc = %d)
\n
"
,
psmouse_dbg
(
psmouse
,
reg_val
,
rc
);
"WRITE PAGE REG: to 0x%02x (rc = %d)
\n
"
,
reg_val
,
rc
);
return
rc
;
return
rc
;
}
}
...
@@ -319,7 +327,7 @@ static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable)
...
@@ -319,7 +327,7 @@ static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable)
int
res
=
0
;
int
res
=
0
;
if
(
fsp_reg_read
(
psmouse
,
FSP_REG_OPC_QDOWN
,
&
v
)
==
-
1
)
{
if
(
fsp_reg_read
(
psmouse
,
FSP_REG_OPC_QDOWN
,
&
v
)
==
-
1
)
{
dev_err
(
&
psmouse
->
ps2dev
.
serio
->
dev
,
"Unable get OPC state.
\n
"
);
psmouse_err
(
psmouse
,
"Unable get OPC state.
\n
"
);
return
-
EIO
;
return
-
EIO
;
}
}
...
@@ -336,8 +344,7 @@ static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable)
...
@@ -336,8 +344,7 @@ static int fsp_opc_tag_enable(struct psmouse *psmouse, bool enable)
}
}
if
(
res
!=
0
)
{
if
(
res
!=
0
)
{
dev_err
(
&
psmouse
->
ps2dev
.
serio
->
dev
,
psmouse_err
(
psmouse
,
"Unable to enable OPC tag.
\n
"
);
"Unable to enable OPC tag.
\n
"
);
res
=
-
EIO
;
res
=
-
EIO
;
}
}
...
@@ -615,18 +622,40 @@ static struct attribute_group fsp_attribute_group = {
...
@@ -615,18 +622,40 @@ static struct attribute_group fsp_attribute_group = {
.
attrs
=
fsp_attributes
,
.
attrs
=
fsp_attributes
,
};
};
#ifdef
FSP_DEBUG
#ifdef
FSP_DEBUG
static
void
fsp_packet_debug
(
unsigned
char
packet
[])
static
void
fsp_packet_debug
(
struct
psmouse
*
psmouse
,
unsigned
char
packet
[])
{
{
static
unsigned
int
ps2_packet_cnt
;
static
unsigned
int
ps2_packet_cnt
;
static
unsigned
int
ps2_last_second
;
static
unsigned
int
ps2_last_second
;
unsigned
int
jiffies_msec
;
unsigned
int
jiffies_msec
;
const
char
*
packet_type
=
"UNKNOWN"
;
unsigned
short
abs_x
=
0
,
abs_y
=
0
;
/* Interpret & dump the packet data. */
switch
(
packet
[
0
]
>>
FSP_PKT_TYPE_SHIFT
)
{
case
FSP_PKT_TYPE_ABS
:
packet_type
=
"Absolute"
;
abs_x
=
GET_ABS_X
(
packet
);
abs_y
=
GET_ABS_Y
(
packet
);
break
;
case
FSP_PKT_TYPE_NORMAL
:
packet_type
=
"Normal"
;
break
;
case
FSP_PKT_TYPE_NOTIFY
:
packet_type
=
"Notify"
;
break
;
case
FSP_PKT_TYPE_NORMAL_OPC
:
packet_type
=
"Normal-OPC"
;
break
;
}
ps2_packet_cnt
++
;
ps2_packet_cnt
++
;
jiffies_msec
=
jiffies_to_msecs
(
jiffies
);
jiffies_msec
=
jiffies_to_msecs
(
jiffies
);
psmouse_dbg
(
psmouse
,
psmouse_dbg
(
psmouse
,
"%08dms PS/2 packets: %02x, %02x, %02x, %02x
\n
"
,
"%08dms %s packets: %02x, %02x, %02x, %02x; "
jiffies_msec
,
packet
[
0
],
packet
[
1
],
packet
[
2
],
packet
[
3
]);
"abs_x: %d, abs_y: %d
\n
"
,
jiffies_msec
,
packet_type
,
packet
[
0
],
packet
[
1
],
packet
[
2
],
packet
[
3
],
abs_x
,
abs_y
);
if
(
jiffies_msec
-
ps2_last_second
>
1000
)
{
if
(
jiffies_msec
-
ps2_last_second
>
1000
)
{
psmouse_dbg
(
psmouse
,
"PS/2 packets/sec = %d
\n
"
,
ps2_packet_cnt
);
psmouse_dbg
(
psmouse
,
"PS/2 packets/sec = %d
\n
"
,
ps2_packet_cnt
);
...
@@ -635,17 +664,29 @@ static void fsp_packet_debug(unsigned char packet[])
...
@@ -635,17 +664,29 @@ static void fsp_packet_debug(unsigned char packet[])
}
}
}
}
#else
#else
static
void
fsp_packet_debug
(
unsigned
char
packet
[])
static
void
fsp_packet_debug
(
struct
psmouse
*
psmouse
,
unsigned
char
packet
[])
{
{
}
}
#endif
#endif
static
void
fsp_set_slot
(
struct
input_dev
*
dev
,
int
slot
,
bool
active
,
unsigned
int
x
,
unsigned
int
y
)
{
input_mt_slot
(
dev
,
slot
);
input_mt_report_slot_state
(
dev
,
MT_TOOL_FINGER
,
active
);
if
(
active
)
{
input_report_abs
(
dev
,
ABS_MT_POSITION_X
,
x
);
input_report_abs
(
dev
,
ABS_MT_POSITION_Y
,
y
);
}
}
static
psmouse_ret_t
fsp_process_byte
(
struct
psmouse
*
psmouse
)
static
psmouse_ret_t
fsp_process_byte
(
struct
psmouse
*
psmouse
)
{
{
struct
input_dev
*
dev
=
psmouse
->
dev
;
struct
input_dev
*
dev
=
psmouse
->
dev
;
struct
fsp_data
*
ad
=
psmouse
->
private
;
struct
fsp_data
*
ad
=
psmouse
->
private
;
unsigned
char
*
packet
=
psmouse
->
packet
;
unsigned
char
*
packet
=
psmouse
->
packet
;
unsigned
char
button_status
=
0
,
lscroll
=
0
,
rscroll
=
0
;
unsigned
char
button_status
=
0
,
lscroll
=
0
,
rscroll
=
0
;
unsigned
short
abs_x
,
abs_y
,
fgrs
=
0
;
int
rel_x
,
rel_y
;
int
rel_x
,
rel_y
;
if
(
psmouse
->
pktcnt
<
4
)
if
(
psmouse
->
pktcnt
<
4
)
...
@@ -655,16 +696,76 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
...
@@ -655,16 +696,76 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
* Full packet accumulated, process it
* Full packet accumulated, process it
*/
*/
fsp_packet_debug
(
psmouse
,
packet
);
switch
(
psmouse
->
packet
[
0
]
>>
FSP_PKT_TYPE_SHIFT
)
{
switch
(
psmouse
->
packet
[
0
]
>>
FSP_PKT_TYPE_SHIFT
)
{
case
FSP_PKT_TYPE_ABS
:
case
FSP_PKT_TYPE_ABS
:
dev_warn
(
&
psmouse
->
ps2dev
.
serio
->
dev
,
abs_x
=
GET_ABS_X
(
packet
);
"Unexpected absolute mode packet, ignored.
\n
"
);
abs_y
=
GET_ABS_Y
(
packet
);
if
(
packet
[
0
]
&
FSP_PB0_MFMC
)
{
/*
* MFMC packet: assume that there are two fingers on
* pad
*/
fgrs
=
2
;
/* MFMC packet */
if
(
packet
[
0
]
&
FSP_PB0_MFMC_FGR2
)
{
/* 2nd finger */
if
(
ad
->
last_mt_fgr
==
2
)
{
/*
* workaround for buggy firmware
* which doesn't clear MFMC bit if
* the 1st finger is up
*/
fgrs
=
1
;
fsp_set_slot
(
dev
,
0
,
false
,
0
,
0
);
}
ad
->
last_mt_fgr
=
2
;
fsp_set_slot
(
dev
,
1
,
fgrs
==
2
,
abs_x
,
abs_y
);
}
else
{
/* 1st finger */
if
(
ad
->
last_mt_fgr
==
1
)
{
/*
* workaround for buggy firmware
* which doesn't clear MFMC bit if
* the 2nd finger is up
*/
fgrs
=
1
;
fsp_set_slot
(
dev
,
1
,
false
,
0
,
0
);
}
ad
->
last_mt_fgr
=
1
;
fsp_set_slot
(
dev
,
0
,
fgrs
!=
0
,
abs_x
,
abs_y
);
}
}
else
{
/* SFAC packet */
/* no multi-finger information */
ad
->
last_mt_fgr
=
0
;
if
(
abs_x
!=
0
&&
abs_y
!=
0
)
fgrs
=
1
;
fsp_set_slot
(
dev
,
0
,
fgrs
>
0
,
abs_x
,
abs_y
);
fsp_set_slot
(
dev
,
1
,
false
,
0
,
0
);
}
if
(
fgrs
>
0
)
{
input_report_abs
(
dev
,
ABS_X
,
abs_x
);
input_report_abs
(
dev
,
ABS_Y
,
abs_y
);
}
input_report_key
(
dev
,
BTN_LEFT
,
packet
[
0
]
&
0x01
);
input_report_key
(
dev
,
BTN_RIGHT
,
packet
[
0
]
&
0x02
);
input_report_key
(
dev
,
BTN_TOUCH
,
fgrs
);
input_report_key
(
dev
,
BTN_TOOL_FINGER
,
fgrs
==
1
);
input_report_key
(
dev
,
BTN_TOOL_DOUBLETAP
,
fgrs
==
2
);
break
;
break
;
case
FSP_PKT_TYPE_NORMAL_OPC
:
case
FSP_PKT_TYPE_NORMAL_OPC
:
/* on-pad click, filter it if necessary */
/* on-pad click, filter it if necessary */
if
((
ad
->
flags
&
FSPDRV_FLAG_EN_OPC
)
!=
FSPDRV_FLAG_EN_OPC
)
if
((
ad
->
flags
&
FSPDRV_FLAG_EN_OPC
)
!=
FSPDRV_FLAG_EN_OPC
)
packet
[
0
]
&=
~
BIT
(
0
)
;
packet
[
0
]
&=
~
FSP_PB0_LBTN
;
/* fall through */
/* fall through */
case
FSP_PKT_TYPE_NORMAL
:
case
FSP_PKT_TYPE_NORMAL
:
...
@@ -711,8 +812,6 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
...
@@ -711,8 +812,6 @@ static psmouse_ret_t fsp_process_byte(struct psmouse *psmouse)
input_sync
(
dev
);
input_sync
(
dev
);
fsp_packet_debug
(
packet
);
return
PSMOUSE_FULL_PACKET
;
return
PSMOUSE_FULL_PACKET
;
}
}
...
@@ -736,42 +835,106 @@ static int fsp_activate_protocol(struct psmouse *psmouse)
...
@@ -736,42 +835,106 @@ static int fsp_activate_protocol(struct psmouse *psmouse)
ps2_command
(
ps2dev
,
param
,
PSMOUSE_CMD_GETID
);
ps2_command
(
ps2dev
,
param
,
PSMOUSE_CMD_GETID
);
if
(
param
[
0
]
!=
0x04
)
{
if
(
param
[
0
]
!=
0x04
)
{
dev_err
(
&
psmouse
->
ps2dev
.
serio
->
dev
,
psmouse_err
(
psmouse
,
"Unable to enable 4 bytes packet format.
\n
"
);
"Unable to enable 4 bytes packet format.
\n
"
);
return
-
EIO
;
return
-
EIO
;
}
}
if
(
fsp_reg_read
(
psmouse
,
FSP_REG_SYSCTL5
,
&
val
))
{
if
(
pad
->
ver
<
FSP_VER_STL3888_C0
)
{
dev_err
(
&
psmouse
->
ps2dev
.
serio
->
dev
,
/* Preparing relative coordinates output for older hardware */
"Unable to read SYSCTL5 register.
\n
"
);
if
(
fsp_reg_read
(
psmouse
,
FSP_REG_SYSCTL5
,
&
val
))
{
return
-
EIO
;
psmouse_err
(
psmouse
,
}
"Unable to read SYSCTL5 register.
\n
"
);
return
-
EIO
;
}
val
&=
~
(
FSP_BIT_EN_MSID7
|
FSP_BIT_EN_MSID8
|
FSP_BIT_EN_AUTO_MSID8
);
if
(
fsp_get_buttons
(
psmouse
,
&
pad
->
buttons
))
{
/* Ensure we are not in absolute mode */
psmouse_err
(
psmouse
,
val
&=
~
FSP_BIT_EN_PKT_G0
;
"Unable to retrieve number of buttons.
\n
"
);
if
(
pad
->
buttons
==
0x06
)
{
return
-
EIO
;
/* Left/Middle/Right & Scroll Up/Down/Right/Left */
}
val
|=
FSP_BIT_EN_MSID6
;
}
if
(
fsp_reg_write
(
psmouse
,
FSP_REG_SYSCTL5
,
val
))
{
val
&=
~
(
FSP_BIT_EN_MSID7
|
FSP_BIT_EN_MSID8
|
FSP_BIT_EN_AUTO_MSID8
);
dev_err
(
&
psmouse
->
ps2dev
.
serio
->
dev
,
/* Ensure we are not in absolute mode */
"Unable to set up required mode bits.
\n
"
);
val
&=
~
FSP_BIT_EN_PKT_G0
;
return
-
EIO
;
if
(
pad
->
buttons
==
0x06
)
{
/* Left/Middle/Right & Scroll Up/Down/Right/Left */
val
|=
FSP_BIT_EN_MSID6
;
}
if
(
fsp_reg_write
(
psmouse
,
FSP_REG_SYSCTL5
,
val
))
{
psmouse_err
(
psmouse
,
"Unable to set up required mode bits.
\n
"
);
return
-
EIO
;
}
/*
* Enable OPC tags such that driver can tell the difference
* between on-pad and real button click
*/
if
(
fsp_opc_tag_enable
(
psmouse
,
true
))
psmouse_warn
(
psmouse
,
"Failed to enable OPC tag mode.
\n
"
);
/* enable on-pad click by default */
pad
->
flags
|=
FSPDRV_FLAG_EN_OPC
;
/* Enable on-pad vertical and horizontal scrolling */
fsp_onpad_vscr
(
psmouse
,
true
);
fsp_onpad_hscr
(
psmouse
,
true
);
}
else
{
/* Enable absolute coordinates output for Cx/Dx hardware */
if
(
fsp_reg_write
(
psmouse
,
FSP_REG_SWC1
,
FSP_BIT_SWC1_EN_ABS_1F
|
FSP_BIT_SWC1_EN_ABS_2F
|
FSP_BIT_SWC1_EN_FUP_OUT
|
FSP_BIT_SWC1_EN_ABS_CON
))
{
psmouse_err
(
psmouse
,
"Unable to enable absolute coordinates output.
\n
"
);
return
-
EIO
;
}
}
}
/*
return
0
;
* Enable OPC tags such that driver can tell the difference between
}
* on-pad and real button click
*/
if
(
fsp_opc_tag_enable
(
psmouse
,
true
))
dev_warn
(
&
psmouse
->
ps2dev
.
serio
->
dev
,
"Failed to enable OPC tag mode.
\n
"
);
/* Enable on-pad vertical and horizontal scrolling */
static
int
fsp_set_input_params
(
struct
psmouse
*
psmouse
)
fsp_onpad_vscr
(
psmouse
,
true
);
{
fsp_onpad_hscr
(
psmouse
,
true
);
struct
input_dev
*
dev
=
psmouse
->
dev
;
struct
fsp_data
*
pad
=
psmouse
->
private
;
if
(
pad
->
ver
<
FSP_VER_STL3888_C0
)
{
__set_bit
(
BTN_MIDDLE
,
dev
->
keybit
);
__set_bit
(
BTN_BACK
,
dev
->
keybit
);
__set_bit
(
BTN_FORWARD
,
dev
->
keybit
);
__set_bit
(
REL_WHEEL
,
dev
->
relbit
);
__set_bit
(
REL_HWHEEL
,
dev
->
relbit
);
}
else
{
/*
* Hardware prior to Cx performs much better in relative mode;
* hence, only enable absolute coordinates output as well as
* multi-touch output for the newer hardware.
*
* Maximum coordinates can be computed as:
*
* number of scanlines * 64 - 57
*
* where number of X/Y scanline lines are 16/12.
*/
int
abs_x
=
967
,
abs_y
=
711
;
__set_bit
(
EV_ABS
,
dev
->
evbit
);
__clear_bit
(
EV_REL
,
dev
->
evbit
);
__set_bit
(
BTN_TOUCH
,
dev
->
keybit
);
__set_bit
(
BTN_TOOL_FINGER
,
dev
->
keybit
);
__set_bit
(
BTN_TOOL_DOUBLETAP
,
dev
->
keybit
);
__set_bit
(
INPUT_PROP_SEMI_MT
,
dev
->
propbit
);
input_set_abs_params
(
dev
,
ABS_X
,
0
,
abs_x
,
0
,
0
);
input_set_abs_params
(
dev
,
ABS_Y
,
0
,
abs_y
,
0
,
0
);
input_mt_init_slots
(
dev
,
2
);
input_set_abs_params
(
dev
,
ABS_MT_POSITION_X
,
0
,
abs_x
,
0
,
0
);
input_set_abs_params
(
dev
,
ABS_MT_POSITION_Y
,
0
,
abs_y
,
0
,
0
);
}
return
0
;
return
0
;
}
}
...
@@ -829,18 +992,16 @@ static int fsp_reconnect(struct psmouse *psmouse)
...
@@ -829,18 +992,16 @@ static int fsp_reconnect(struct psmouse *psmouse)
int
fsp_init
(
struct
psmouse
*
psmouse
)
int
fsp_init
(
struct
psmouse
*
psmouse
)
{
{
struct
fsp_data
*
priv
;
struct
fsp_data
*
priv
;
int
ver
,
rev
,
buttons
;
int
ver
,
rev
;
int
error
;
int
error
;
if
(
fsp_get_version
(
psmouse
,
&
ver
)
||
if
(
fsp_get_version
(
psmouse
,
&
ver
)
||
fsp_get_revision
(
psmouse
,
&
rev
)
||
fsp_get_revision
(
psmouse
,
&
rev
))
{
fsp_get_buttons
(
psmouse
,
&
buttons
))
{
return
-
ENODEV
;
return
-
ENODEV
;
}
}
psmouse_info
(
psmouse
,
psmouse_info
(
psmouse
,
"Finger Sensing Pad, hw: %d.%d.%d, sw: %s
\n
"
,
"Finger Sensing Pad, hw: %d.%d.%d, sw: %s, buttons: %d
\n
"
,
ver
>>
4
,
ver
&
0x0F
,
rev
,
fsp_drv_ver
);
ver
>>
4
,
ver
&
0x0F
,
rev
,
fsp_drv_ver
,
buttons
&
7
);
psmouse
->
private
=
priv
=
kzalloc
(
sizeof
(
struct
fsp_data
),
GFP_KERNEL
);
psmouse
->
private
=
priv
=
kzalloc
(
sizeof
(
struct
fsp_data
),
GFP_KERNEL
);
if
(
!
priv
)
if
(
!
priv
)
...
@@ -848,17 +1009,6 @@ int fsp_init(struct psmouse *psmouse)
...
@@ -848,17 +1009,6 @@ int fsp_init(struct psmouse *psmouse)
priv
->
ver
=
ver
;
priv
->
ver
=
ver
;
priv
->
rev
=
rev
;
priv
->
rev
=
rev
;
priv
->
buttons
=
buttons
;
/* enable on-pad click by default */
priv
->
flags
|=
FSPDRV_FLAG_EN_OPC
;
/* Set up various supported input event bits */
__set_bit
(
BTN_MIDDLE
,
psmouse
->
dev
->
keybit
);
__set_bit
(
BTN_BACK
,
psmouse
->
dev
->
keybit
);
__set_bit
(
BTN_FORWARD
,
psmouse
->
dev
->
keybit
);
__set_bit
(
REL_WHEEL
,
psmouse
->
dev
->
relbit
);
__set_bit
(
REL_HWHEEL
,
psmouse
->
dev
->
relbit
);
psmouse
->
protocol_handler
=
fsp_process_byte
;
psmouse
->
protocol_handler
=
fsp_process_byte
;
psmouse
->
disconnect
=
fsp_disconnect
;
psmouse
->
disconnect
=
fsp_disconnect
;
...
@@ -866,16 +1016,20 @@ int fsp_init(struct psmouse *psmouse)
...
@@ -866,16 +1016,20 @@ int fsp_init(struct psmouse *psmouse)
psmouse
->
cleanup
=
fsp_reset
;
psmouse
->
cleanup
=
fsp_reset
;
psmouse
->
pktsize
=
4
;
psmouse
->
pktsize
=
4
;
/* set default packet output based on number of buttons we found */
error
=
fsp_activate_protocol
(
psmouse
);
error
=
fsp_activate_protocol
(
psmouse
);
if
(
error
)
if
(
error
)
goto
err_out
;
goto
err_out
;
/* Set up various supported input event bits */
error
=
fsp_set_input_params
(
psmouse
);
if
(
error
)
goto
err_out
;
error
=
sysfs_create_group
(
&
psmouse
->
ps2dev
.
serio
->
dev
.
kobj
,
error
=
sysfs_create_group
(
&
psmouse
->
ps2dev
.
serio
->
dev
.
kobj
,
&
fsp_attribute_group
);
&
fsp_attribute_group
);
if
(
error
)
{
if
(
error
)
{
dev_err
(
&
psmouse
->
ps2dev
.
serio
->
dev
,
psmouse_err
(
psmouse
,
"Failed to create sysfs attributes (%d)"
,
error
);
"Failed to create sysfs attributes (%d)"
,
error
);
goto
err_out
;
goto
err_out
;
}
}
...
...
drivers/input/mouse/sentelic.h
浏览文件 @
99380825
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* Finger Sensing Pad PS/2 mouse driver.
* Finger Sensing Pad PS/2 mouse driver.
*
*
* Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
* Copyright (C) 2005-2007 Asia Vital Components Co., Ltd.
* Copyright (C) 2005-201
1
Tai-hwa Liang, Sentelic Corporation.
* Copyright (C) 2005-201
2
Tai-hwa Liang, Sentelic Corporation.
*
*
* This program is free software; you can redistribute it and/or
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* modify it under the terms of the GNU General Public License
...
@@ -55,6 +55,16 @@
...
@@ -55,6 +55,16 @@
#define FSP_BIT_FIX_HSCR BIT(5)
#define FSP_BIT_FIX_HSCR BIT(5)
#define FSP_BIT_DRAG_LOCK BIT(6)
#define FSP_BIT_DRAG_LOCK BIT(6)
#define FSP_REG_SWC1 (0x90)
#define FSP_BIT_SWC1_EN_ABS_1F BIT(0)
#define FSP_BIT_SWC1_EN_GID BIT(1)
#define FSP_BIT_SWC1_EN_ABS_2F BIT(2)
#define FSP_BIT_SWC1_EN_FUP_OUT BIT(3)
#define FSP_BIT_SWC1_EN_ABS_CON BIT(4)
#define FSP_BIT_SWC1_GST_GRP0 BIT(5)
#define FSP_BIT_SWC1_GST_GRP1 BIT(6)
#define FSP_BIT_SWC1_BX_COMPAT BIT(7)
/* Finger-sensing Pad packet formating related definitions */
/* Finger-sensing Pad packet formating related definitions */
/* absolute packet type */
/* absolute packet type */
...
@@ -64,12 +74,32 @@
...
@@ -64,12 +74,32 @@
#define FSP_PKT_TYPE_NORMAL_OPC (0x03)
#define FSP_PKT_TYPE_NORMAL_OPC (0x03)
#define FSP_PKT_TYPE_SHIFT (6)
#define FSP_PKT_TYPE_SHIFT (6)
/* bit definitions for the first byte of report packet */
#define FSP_PB0_LBTN BIT(0)
#define FSP_PB0_RBTN BIT(1)
#define FSP_PB0_MBTN BIT(2)
#define FSP_PB0_MFMC_FGR2 FSP_PB0_MBTN
#define FSP_PB0_MUST_SET BIT(3)
#define FSP_PB0_PHY_BTN BIT(4)
#define FSP_PB0_MFMC BIT(5)
/* hardware revisions */
#define FSP_VER_STL3888_A4 (0xC1)
#define FSP_VER_STL3888_B0 (0xD0)
#define FSP_VER_STL3888_B1 (0xD1)
#define FSP_VER_STL3888_B2 (0xD2)
#define FSP_VER_STL3888_C0 (0xE0)
#define FSP_VER_STL3888_C1 (0xE1)
#define FSP_VER_STL3888_D0 (0xE2)
#define FSP_VER_STL3888_D1 (0xE3)
#define FSP_VER_STL3888_E0 (0xE4)
#ifdef __KERNEL__
#ifdef __KERNEL__
struct
fsp_data
{
struct
fsp_data
{
unsigned
char
ver
;
/* hardware version */
unsigned
char
ver
;
/* hardware version */
unsigned
char
rev
;
/* hardware revison */
unsigned
char
rev
;
/* hardware revison */
unsigned
char
buttons
;
/* Number of buttons */
unsigned
int
buttons
;
/* Number of buttons */
unsigned
int
flags
;
unsigned
int
flags
;
#define FSPDRV_FLAG_EN_OPC (0x001)
/* enable on-pad clicking */
#define FSPDRV_FLAG_EN_OPC (0x001)
/* enable on-pad clicking */
...
@@ -78,6 +108,7 @@ struct fsp_data {
...
@@ -78,6 +108,7 @@ struct fsp_data {
unsigned
char
last_reg
;
/* Last register we requested read from */
unsigned
char
last_reg
;
/* Last register we requested read from */
unsigned
char
last_val
;
unsigned
char
last_val
;
unsigned
int
last_mt_fgr
;
/* Last seen finger(multitouch) */
};
};
#ifdef CONFIG_MOUSE_PS2_SENTELIC
#ifdef CONFIG_MOUSE_PS2_SENTELIC
...
...
drivers/input/tablet/Kconfig
浏览文件 @
99380825
...
@@ -76,6 +76,7 @@ config TABLET_USB_KBTAB
...
@@ -76,6 +76,7 @@ config TABLET_USB_KBTAB
config TABLET_USB_WACOM
config TABLET_USB_WACOM
tristate "Wacom Intuos/Graphire tablet support (USB)"
tristate "Wacom Intuos/Graphire tablet support (USB)"
depends on USB_ARCH_HAS_HCD
depends on USB_ARCH_HAS_HCD
select POWER_SUPPLY
select USB
select USB
select NEW_LEDS
select NEW_LEDS
select LEDS_CLASS
select LEDS_CLASS
...
...
drivers/input/tablet/wacom.h
浏览文件 @
99380825
...
@@ -88,6 +88,7 @@
...
@@ -88,6 +88,7 @@
#include <linux/mod_devicetable.h>
#include <linux/mod_devicetable.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/usb/input.h>
#include <linux/usb/input.h>
#include <linux/power_supply.h>
#include <asm/unaligned.h>
#include <asm/unaligned.h>
/*
/*
...
@@ -112,6 +113,7 @@ struct wacom {
...
@@ -112,6 +113,7 @@ struct wacom {
struct
urb
*
irq
;
struct
urb
*
irq
;
struct
wacom_wac
wacom_wac
;
struct
wacom_wac
wacom_wac
;
struct
mutex
lock
;
struct
mutex
lock
;
struct
work_struct
work
;
bool
open
;
bool
open
;
char
phys
[
32
];
char
phys
[
32
];
struct
wacom_led
{
struct
wacom_led
{
...
@@ -120,8 +122,15 @@ struct wacom {
...
@@ -120,8 +122,15 @@ struct wacom {
u8
hlv
;
/* status led brightness button pressed (1..127) */
u8
hlv
;
/* status led brightness button pressed (1..127) */
u8
img_lum
;
/* OLED matrix display brightness */
u8
img_lum
;
/* OLED matrix display brightness */
}
led
;
}
led
;
struct
power_supply
battery
;
};
};
static
inline
void
wacom_schedule_work
(
struct
wacom_wac
*
wacom_wac
)
{
struct
wacom
*
wacom
=
container_of
(
wacom_wac
,
struct
wacom
,
wacom_wac
);
schedule_work
(
&
wacom
->
work
);
}
extern
const
struct
usb_device_id
wacom_ids
[];
extern
const
struct
usb_device_id
wacom_ids
[];
void
wacom_wac_irq
(
struct
wacom_wac
*
wacom_wac
,
size_t
len
);
void
wacom_wac_irq
(
struct
wacom_wac
*
wacom_wac
,
size_t
len
);
...
...
drivers/input/tablet/wacom_sys.c
浏览文件 @
99380825
...
@@ -167,6 +167,19 @@ static void wacom_close(struct input_dev *dev)
...
@@ -167,6 +167,19 @@ static void wacom_close(struct input_dev *dev)
usb_autopm_put_interface
(
wacom
->
intf
);
usb_autopm_put_interface
(
wacom
->
intf
);
}
}
/*
* Static values for max X/Y and resolution of Pen interface is stored in
* features. This mean physical size of active area can be computed.
* This is useful to do when Pen and Touch have same active area of tablet.
* This means for Touch device, we only need to find max X/Y value and we
* have enough information to compute resolution of touch.
*/
static
void
wacom_set_phy_from_res
(
struct
wacom_features
*
features
)
{
features
->
x_phy
=
(
features
->
x_max
*
100
)
/
features
->
x_resolution
;
features
->
y_phy
=
(
features
->
y_max
*
100
)
/
features
->
y_resolution
;
}
static
int
wacom_parse_logical_collection
(
unsigned
char
*
report
,
static
int
wacom_parse_logical_collection
(
unsigned
char
*
report
,
struct
wacom_features
*
features
)
struct
wacom_features
*
features
)
{
{
...
@@ -178,15 +191,7 @@ static int wacom_parse_logical_collection(unsigned char *report,
...
@@ -178,15 +191,7 @@ static int wacom_parse_logical_collection(unsigned char *report,
features
->
pktlen
=
WACOM_PKGLEN_BBTOUCH3
;
features
->
pktlen
=
WACOM_PKGLEN_BBTOUCH3
;
features
->
device_type
=
BTN_TOOL_FINGER
;
features
->
device_type
=
BTN_TOOL_FINGER
;
/*
wacom_set_phy_from_res
(
features
);
* Stylus and Touch have same active area
* so compute physical size based on stylus
* data before its overwritten.
*/
features
->
x_phy
=
(
features
->
x_max
*
100
)
/
features
->
x_resolution
;
features
->
y_phy
=
(
features
->
y_max
*
100
)
/
features
->
y_resolution
;
features
->
x_max
=
features
->
y_max
=
features
->
x_max
=
features
->
y_max
=
get_unaligned_le16
(
&
report
[
10
]);
get_unaligned_le16
(
&
report
[
10
]);
...
@@ -422,6 +427,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
...
@@ -422,6 +427,7 @@ static int wacom_query_tablet_data(struct usb_interface *intf, struct wacom_feat
report_id
,
rep_data
,
4
,
1
);
report_id
,
rep_data
,
4
,
1
);
}
while
((
error
<
0
||
rep_data
[
1
]
!=
4
)
&&
limit
++
<
WAC_MSG_RETRIES
);
}
while
((
error
<
0
||
rep_data
[
1
]
!=
4
)
&&
limit
++
<
WAC_MSG_RETRIES
);
}
else
if
(
features
->
type
!=
TABLETPC
&&
}
else
if
(
features
->
type
!=
TABLETPC
&&
features
->
type
!=
WIRELESS
&&
features
->
device_type
==
BTN_TOOL_PEN
)
{
features
->
device_type
==
BTN_TOOL_PEN
)
{
do
{
do
{
rep_data
[
0
]
=
2
;
rep_data
[
0
]
=
2
;
...
@@ -454,6 +460,21 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
...
@@ -454,6 +460,21 @@ static int wacom_retrieve_hid_descriptor(struct usb_interface *intf,
features
->
pressure_fuzz
=
0
;
features
->
pressure_fuzz
=
0
;
features
->
distance_fuzz
=
0
;
features
->
distance_fuzz
=
0
;
/*
* The wireless device HID is basic and layout conflicts with
* other tablets (monitor and touch interface can look like pen).
* Skip the query for this type and modify defaults based on
* interface number.
*/
if
(
features
->
type
==
WIRELESS
)
{
if
(
intf
->
cur_altsetting
->
desc
.
bInterfaceNumber
==
0
)
{
features
->
device_type
=
0
;
}
else
if
(
intf
->
cur_altsetting
->
desc
.
bInterfaceNumber
==
2
)
{
features
->
device_type
=
BTN_TOOL_DOUBLETAP
;
features
->
pktlen
=
WACOM_PKGLEN_BBTOUCH3
;
}
}
/* only Tablet PCs and Bamboo P&T need to retrieve the info */
/* only Tablet PCs and Bamboo P&T need to retrieve the info */
if
((
features
->
type
!=
TABLETPC
)
&&
(
features
->
type
!=
TABLETPC2FG
)
&&
if
((
features
->
type
!=
TABLETPC
)
&&
(
features
->
type
!=
TABLETPC2FG
)
&&
(
features
->
type
!=
BAMBOO_PT
))
(
features
->
type
!=
BAMBOO_PT
))
...
@@ -822,6 +843,152 @@ static void wacom_destroy_leds(struct wacom *wacom)
...
@@ -822,6 +843,152 @@ static void wacom_destroy_leds(struct wacom *wacom)
}
}
}
}
static
enum
power_supply_property
wacom_battery_props
[]
=
{
POWER_SUPPLY_PROP_CAPACITY
};
static
int
wacom_battery_get_property
(
struct
power_supply
*
psy
,
enum
power_supply_property
psp
,
union
power_supply_propval
*
val
)
{
struct
wacom
*
wacom
=
container_of
(
psy
,
struct
wacom
,
battery
);
int
ret
=
0
;
switch
(
psp
)
{
case
POWER_SUPPLY_PROP_CAPACITY
:
val
->
intval
=
wacom
->
wacom_wac
.
battery_capacity
*
100
/
31
;
break
;
default:
ret
=
-
EINVAL
;
break
;
}
return
ret
;
}
static
int
wacom_initialize_battery
(
struct
wacom
*
wacom
)
{
int
error
=
0
;
if
(
wacom
->
wacom_wac
.
features
.
quirks
&
WACOM_QUIRK_MONITOR
)
{
wacom
->
battery
.
properties
=
wacom_battery_props
;
wacom
->
battery
.
num_properties
=
ARRAY_SIZE
(
wacom_battery_props
);
wacom
->
battery
.
get_property
=
wacom_battery_get_property
;
wacom
->
battery
.
name
=
"wacom_battery"
;
wacom
->
battery
.
type
=
POWER_SUPPLY_TYPE_BATTERY
;
wacom
->
battery
.
use_for_apm
=
0
;
error
=
power_supply_register
(
&
wacom
->
usbdev
->
dev
,
&
wacom
->
battery
);
}
return
error
;
}
static
void
wacom_destroy_battery
(
struct
wacom
*
wacom
)
{
if
(
wacom
->
wacom_wac
.
features
.
quirks
&
WACOM_QUIRK_MONITOR
)
power_supply_unregister
(
&
wacom
->
battery
);
}
static
int
wacom_register_input
(
struct
wacom
*
wacom
)
{
struct
input_dev
*
input_dev
;
struct
usb_interface
*
intf
=
wacom
->
intf
;
struct
usb_device
*
dev
=
interface_to_usbdev
(
intf
);
struct
wacom_wac
*
wacom_wac
=
&
(
wacom
->
wacom_wac
);
int
error
;
input_dev
=
input_allocate_device
();
if
(
!
input_dev
)
return
-
ENOMEM
;
input_dev
->
name
=
wacom_wac
->
name
;
input_dev
->
dev
.
parent
=
&
intf
->
dev
;
input_dev
->
open
=
wacom_open
;
input_dev
->
close
=
wacom_close
;
usb_to_input_id
(
dev
,
&
input_dev
->
id
);
input_set_drvdata
(
input_dev
,
wacom
);
wacom_wac
->
input
=
input_dev
;
wacom_setup_input_capabilities
(
input_dev
,
wacom_wac
);
error
=
input_register_device
(
input_dev
);
if
(
error
)
{
input_free_device
(
input_dev
);
wacom_wac
->
input
=
NULL
;
}
return
error
;
}
static
void
wacom_wireless_work
(
struct
work_struct
*
work
)
{
struct
wacom
*
wacom
=
container_of
(
work
,
struct
wacom
,
work
);
struct
usb_device
*
usbdev
=
wacom
->
usbdev
;
struct
wacom_wac
*
wacom_wac
=
&
wacom
->
wacom_wac
;
/*
* Regardless if this is a disconnect or a new tablet,
* remove any existing input devices.
*/
/* Stylus interface */
wacom
=
usb_get_intfdata
(
usbdev
->
config
->
interface
[
1
]);
if
(
wacom
->
wacom_wac
.
input
)
input_unregister_device
(
wacom
->
wacom_wac
.
input
);
wacom
->
wacom_wac
.
input
=
0
;
/* Touch interface */
wacom
=
usb_get_intfdata
(
usbdev
->
config
->
interface
[
2
]);
if
(
wacom
->
wacom_wac
.
input
)
input_unregister_device
(
wacom
->
wacom_wac
.
input
);
wacom
->
wacom_wac
.
input
=
0
;
if
(
wacom_wac
->
pid
==
0
)
{
printk
(
KERN_INFO
"wacom: wireless tablet disconnected
\n
"
);
}
else
{
const
struct
usb_device_id
*
id
=
wacom_ids
;
printk
(
KERN_INFO
"wacom: wireless tablet connected with PID %x
\n
"
,
wacom_wac
->
pid
);
while
(
id
->
match_flags
)
{
if
(
id
->
idVendor
==
USB_VENDOR_ID_WACOM
&&
id
->
idProduct
==
wacom_wac
->
pid
)
break
;
id
++
;
}
if
(
!
id
->
match_flags
)
{
printk
(
KERN_INFO
"wacom: ignorning unknown PID.
\n
"
);
return
;
}
/* Stylus interface */
wacom
=
usb_get_intfdata
(
usbdev
->
config
->
interface
[
1
]);
wacom_wac
=
&
wacom
->
wacom_wac
;
wacom_wac
->
features
=
*
((
struct
wacom_features
*
)
id
->
driver_info
);
wacom_wac
->
features
.
device_type
=
BTN_TOOL_PEN
;
wacom_register_input
(
wacom
);
/* Touch interface */
wacom
=
usb_get_intfdata
(
usbdev
->
config
->
interface
[
2
]);
wacom_wac
=
&
wacom
->
wacom_wac
;
wacom_wac
->
features
=
*
((
struct
wacom_features
*
)
id
->
driver_info
);
wacom_wac
->
features
.
pktlen
=
WACOM_PKGLEN_BBTOUCH3
;
wacom_wac
->
features
.
device_type
=
BTN_TOOL_FINGER
;
wacom_set_phy_from_res
(
&
wacom_wac
->
features
);
wacom_wac
->
features
.
x_max
=
wacom_wac
->
features
.
y_max
=
4096
;
wacom_register_input
(
wacom
);
}
}
static
int
wacom_probe
(
struct
usb_interface
*
intf
,
const
struct
usb_device_id
*
id
)
static
int
wacom_probe
(
struct
usb_interface
*
intf
,
const
struct
usb_device_id
*
id
)
{
{
struct
usb_device
*
dev
=
interface_to_usbdev
(
intf
);
struct
usb_device
*
dev
=
interface_to_usbdev
(
intf
);
...
@@ -829,18 +996,12 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
...
@@ -829,18 +996,12 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
struct
wacom
*
wacom
;
struct
wacom
*
wacom
;
struct
wacom_wac
*
wacom_wac
;
struct
wacom_wac
*
wacom_wac
;
struct
wacom_features
*
features
;
struct
wacom_features
*
features
;
struct
input_dev
*
input_dev
;
int
error
;
int
error
;
if
(
!
id
->
driver_info
)
if
(
!
id
->
driver_info
)
return
-
EINVAL
;
return
-
EINVAL
;
wacom
=
kzalloc
(
sizeof
(
struct
wacom
),
GFP_KERNEL
);
wacom
=
kzalloc
(
sizeof
(
struct
wacom
),
GFP_KERNEL
);
input_dev
=
input_allocate_device
();
if
(
!
wacom
||
!
input_dev
)
{
error
=
-
ENOMEM
;
goto
fail1
;
}
wacom_wac
=
&
wacom
->
wacom_wac
;
wacom_wac
=
&
wacom
->
wacom_wac
;
wacom_wac
->
features
=
*
((
struct
wacom_features
*
)
id
->
driver_info
);
wacom_wac
->
features
=
*
((
struct
wacom_features
*
)
id
->
driver_info
);
...
@@ -866,11 +1027,10 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
...
@@ -866,11 +1027,10 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
wacom
->
usbdev
=
dev
;
wacom
->
usbdev
=
dev
;
wacom
->
intf
=
intf
;
wacom
->
intf
=
intf
;
mutex_init
(
&
wacom
->
lock
);
mutex_init
(
&
wacom
->
lock
);
INIT_WORK
(
&
wacom
->
work
,
wacom_wireless_work
);
usb_make_path
(
dev
,
wacom
->
phys
,
sizeof
(
wacom
->
phys
));
usb_make_path
(
dev
,
wacom
->
phys
,
sizeof
(
wacom
->
phys
));
strlcat
(
wacom
->
phys
,
"/input0"
,
sizeof
(
wacom
->
phys
));
strlcat
(
wacom
->
phys
,
"/input0"
,
sizeof
(
wacom
->
phys
));
wacom_wac
->
input
=
input_dev
;
endpoint
=
&
intf
->
cur_altsetting
->
endpoint
[
0
].
desc
;
endpoint
=
&
intf
->
cur_altsetting
->
endpoint
[
0
].
desc
;
/* Retrieve the physical and logical size for OEM devices */
/* Retrieve the physical and logical size for OEM devices */
...
@@ -894,15 +1054,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
...
@@ -894,15 +1054,6 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
goto
fail3
;
goto
fail3
;
}
}
input_dev
->
name
=
wacom_wac
->
name
;
input_dev
->
dev
.
parent
=
&
intf
->
dev
;
input_dev
->
open
=
wacom_open
;
input_dev
->
close
=
wacom_close
;
usb_to_input_id
(
dev
,
&
input_dev
->
id
);
input_set_drvdata
(
input_dev
,
wacom
);
wacom_setup_input_capabilities
(
input_dev
,
wacom_wac
);
usb_fill_int_urb
(
wacom
->
irq
,
dev
,
usb_fill_int_urb
(
wacom
->
irq
,
dev
,
usb_rcvintpipe
(
dev
,
endpoint
->
bEndpointAddress
),
usb_rcvintpipe
(
dev
,
endpoint
->
bEndpointAddress
),
wacom_wac
->
data
,
features
->
pktlen
,
wacom_wac
->
data
,
features
->
pktlen
,
...
@@ -914,22 +1065,34 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
...
@@ -914,22 +1065,34 @@ static int wacom_probe(struct usb_interface *intf, const struct usb_device_id *i
if
(
error
)
if
(
error
)
goto
fail4
;
goto
fail4
;
error
=
input_register_device
(
input_dev
);
error
=
wacom_initialize_battery
(
wacom
);
if
(
error
)
if
(
error
)
goto
fail5
;
goto
fail5
;
if
(
!
(
features
->
quirks
&
WACOM_QUIRK_NO_INPUT
))
{
error
=
wacom_register_input
(
wacom
);
if
(
error
)
goto
fail6
;
}
/* Note that if query fails it is not a hard failure */
/* Note that if query fails it is not a hard failure */
wacom_query_tablet_data
(
intf
,
features
);
wacom_query_tablet_data
(
intf
,
features
);
usb_set_intfdata
(
intf
,
wacom
);
usb_set_intfdata
(
intf
,
wacom
);
if
(
features
->
quirks
&
WACOM_QUIRK_MONITOR
)
{
if
(
usb_submit_urb
(
wacom
->
irq
,
GFP_KERNEL
))
goto
fail5
;
}
return
0
;
return
0
;
fail6:
wacom_destroy_battery
(
wacom
);
fail5:
wacom_destroy_leds
(
wacom
);
fail5:
wacom_destroy_leds
(
wacom
);
fail4:
wacom_remove_shared_data
(
wacom_wac
);
fail4:
wacom_remove_shared_data
(
wacom_wac
);
fail3:
usb_free_urb
(
wacom
->
irq
);
fail3:
usb_free_urb
(
wacom
->
irq
);
fail2:
usb_free_coherent
(
dev
,
WACOM_PKGLEN_MAX
,
wacom_wac
->
data
,
wacom
->
data_dma
);
fail2:
usb_free_coherent
(
dev
,
WACOM_PKGLEN_MAX
,
wacom_wac
->
data
,
wacom
->
data_dma
);
fail1:
input_free_device
(
input_dev
);
fail1:
kfree
(
wacom
);
kfree
(
wacom
);
return
error
;
return
error
;
}
}
...
@@ -940,7 +1103,10 @@ static void wacom_disconnect(struct usb_interface *intf)
...
@@ -940,7 +1103,10 @@ static void wacom_disconnect(struct usb_interface *intf)
usb_set_intfdata
(
intf
,
NULL
);
usb_set_intfdata
(
intf
,
NULL
);
usb_kill_urb
(
wacom
->
irq
);
usb_kill_urb
(
wacom
->
irq
);
input_unregister_device
(
wacom
->
wacom_wac
.
input
);
cancel_work_sync
(
&
wacom
->
work
);
if
(
wacom
->
wacom_wac
.
input
)
input_unregister_device
(
wacom
->
wacom_wac
.
input
);
wacom_destroy_battery
(
wacom
);
wacom_destroy_leds
(
wacom
);
wacom_destroy_leds
(
wacom
);
usb_free_urb
(
wacom
->
irq
);
usb_free_urb
(
wacom
->
irq
);
usb_free_coherent
(
interface_to_usbdev
(
intf
),
WACOM_PKGLEN_MAX
,
usb_free_coherent
(
interface_to_usbdev
(
intf
),
WACOM_PKGLEN_MAX
,
...
@@ -972,7 +1138,8 @@ static int wacom_resume(struct usb_interface *intf)
...
@@ -972,7 +1138,8 @@ static int wacom_resume(struct usb_interface *intf)
wacom_query_tablet_data
(
intf
,
features
);
wacom_query_tablet_data
(
intf
,
features
);
wacom_led_control
(
wacom
);
wacom_led_control
(
wacom
);
if
(
wacom
->
open
&&
usb_submit_urb
(
wacom
->
irq
,
GFP_NOIO
)
<
0
)
if
((
wacom
->
open
||
features
->
quirks
&
WACOM_QUIRK_MONITOR
)
&&
usb_submit_urb
(
wacom
->
irq
,
GFP_NOIO
)
<
0
)
rv
=
-
EIO
;
rv
=
-
EIO
;
mutex_unlock
(
&
wacom
->
lock
);
mutex_unlock
(
&
wacom
->
lock
);
...
...
drivers/input/tablet/wacom_wac.c
浏览文件 @
99380825
...
@@ -1044,6 +1044,35 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
...
@@ -1044,6 +1044,35 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len)
return
0
;
return
0
;
}
}
static
int
wacom_wireless_irq
(
struct
wacom_wac
*
wacom
,
size_t
len
)
{
unsigned
char
*
data
=
wacom
->
data
;
int
connected
;
if
(
len
!=
WACOM_PKGLEN_WIRELESS
||
data
[
0
]
!=
0x80
)
return
0
;
connected
=
data
[
1
]
&
0x01
;
if
(
connected
)
{
int
pid
,
battery
;
pid
=
get_unaligned_be16
(
&
data
[
6
]);
battery
=
data
[
5
]
&
0x3f
;
if
(
wacom
->
pid
!=
pid
)
{
wacom
->
pid
=
pid
;
wacom_schedule_work
(
wacom
);
}
wacom
->
battery_capacity
=
battery
;
}
else
if
(
wacom
->
pid
!=
0
)
{
/* disconnected while previously connected */
wacom
->
pid
=
0
;
wacom_schedule_work
(
wacom
);
wacom
->
battery_capacity
=
0
;
}
return
0
;
}
void
wacom_wac_irq
(
struct
wacom_wac
*
wacom_wac
,
size_t
len
)
void
wacom_wac_irq
(
struct
wacom_wac
*
wacom_wac
,
size_t
len
)
{
{
bool
sync
;
bool
sync
;
...
@@ -1094,6 +1123,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
...
@@ -1094,6 +1123,10 @@ void wacom_wac_irq(struct wacom_wac *wacom_wac, size_t len)
sync
=
wacom_bpt_irq
(
wacom_wac
,
len
);
sync
=
wacom_bpt_irq
(
wacom_wac
,
len
);
break
;
break
;
case
WIRELESS
:
sync
=
wacom_wireless_irq
(
wacom_wac
,
len
);
break
;
default:
default:
sync
=
false
;
sync
=
false
;
break
;
break
;
...
@@ -1155,7 +1188,7 @@ void wacom_setup_device_quirks(struct wacom_features *features)
...
@@ -1155,7 +1188,7 @@ void wacom_setup_device_quirks(struct wacom_features *features)
/* these device have multiple inputs */
/* these device have multiple inputs */
if
(
features
->
type
==
TABLETPC
||
features
->
type
==
TABLETPC2FG
||
if
(
features
->
type
==
TABLETPC
||
features
->
type
==
TABLETPC2FG
||
features
->
type
==
BAMBOO_PT
)
features
->
type
==
BAMBOO_PT
||
features
->
type
==
WIRELESS
)
features
->
quirks
|=
WACOM_QUIRK_MULTI_INPUT
;
features
->
quirks
|=
WACOM_QUIRK_MULTI_INPUT
;
/* quirk for bamboo touch with 2 low res touches */
/* quirk for bamboo touch with 2 low res touches */
...
@@ -1167,6 +1200,16 @@ void wacom_setup_device_quirks(struct wacom_features *features)
...
@@ -1167,6 +1200,16 @@ void wacom_setup_device_quirks(struct wacom_features *features)
features
->
y_fuzz
<<=
5
;
features
->
y_fuzz
<<=
5
;
features
->
quirks
|=
WACOM_QUIRK_BBTOUCH_LOWRES
;
features
->
quirks
|=
WACOM_QUIRK_BBTOUCH_LOWRES
;
}
}
if
(
features
->
type
==
WIRELESS
)
{
/* monitor never has input and pen/touch have delayed create */
features
->
quirks
|=
WACOM_QUIRK_NO_INPUT
;
/* must be monitor interface if no device_type set */
if
(
!
features
->
device_type
)
features
->
quirks
|=
WACOM_QUIRK_MONITOR
;
}
}
}
static
unsigned
int
wacom_calculate_touch_res
(
unsigned
int
logical_max
,
static
unsigned
int
wacom_calculate_touch_res
(
unsigned
int
logical_max
,
...
@@ -1640,6 +1683,9 @@ static const struct wacom_features wacom_features_0xEC =
...
@@ -1640,6 +1683,9 @@ static const struct wacom_features wacom_features_0xEC =
static
const
struct
wacom_features
wacom_features_0x47
=
static
const
struct
wacom_features
wacom_features_0x47
=
{
"Wacom Intuos2 6x8"
,
WACOM_PKGLEN_INTUOS
,
20320
,
16240
,
1023
,
{
"Wacom Intuos2 6x8"
,
WACOM_PKGLEN_INTUOS
,
20320
,
16240
,
1023
,
31
,
INTUOS
,
WACOM_INTUOS_RES
,
WACOM_INTUOS_RES
};
31
,
INTUOS
,
WACOM_INTUOS_RES
,
WACOM_INTUOS_RES
};
static
const
struct
wacom_features
wacom_features_0x84
=
{
"Wacom Wireless Receiver"
,
WACOM_PKGLEN_WIRELESS
,
0
,
0
,
0
,
0
,
WIRELESS
,
0
,
0
};
static
const
struct
wacom_features
wacom_features_0xD0
=
static
const
struct
wacom_features
wacom_features_0xD0
=
{
"Wacom Bamboo 2FG"
,
WACOM_PKGLEN_BBFUN
,
14720
,
9200
,
1023
,
{
"Wacom Bamboo 2FG"
,
WACOM_PKGLEN_BBFUN
,
14720
,
9200
,
1023
,
31
,
BAMBOO_PT
,
WACOM_INTUOS_RES
,
WACOM_INTUOS_RES
};
31
,
BAMBOO_PT
,
WACOM_INTUOS_RES
,
WACOM_INTUOS_RES
};
...
@@ -1766,6 +1812,7 @@ const struct usb_device_id wacom_ids[] = {
...
@@ -1766,6 +1812,7 @@ const struct usb_device_id wacom_ids[] = {
{
USB_DEVICE_DETAILED
(
0xCE
,
USB_CLASS_HID
,
{
USB_DEVICE_DETAILED
(
0xCE
,
USB_CLASS_HID
,
USB_INTERFACE_SUBCLASS_BOOT
,
USB_INTERFACE_SUBCLASS_BOOT
,
USB_INTERFACE_PROTOCOL_MOUSE
)
},
USB_INTERFACE_PROTOCOL_MOUSE
)
},
{
USB_DEVICE_WACOM
(
0x84
)
},
{
USB_DEVICE_WACOM
(
0xD0
)
},
{
USB_DEVICE_WACOM
(
0xD0
)
},
{
USB_DEVICE_WACOM
(
0xD1
)
},
{
USB_DEVICE_WACOM
(
0xD1
)
},
{
USB_DEVICE_WACOM
(
0xD2
)
},
{
USB_DEVICE_WACOM
(
0xD2
)
},
...
...
drivers/input/tablet/wacom_wac.h
浏览文件 @
99380825
...
@@ -24,6 +24,7 @@
...
@@ -24,6 +24,7 @@
#define WACOM_PKGLEN_BBTOUCH 20
#define WACOM_PKGLEN_BBTOUCH 20
#define WACOM_PKGLEN_BBTOUCH3 64
#define WACOM_PKGLEN_BBTOUCH3 64
#define WACOM_PKGLEN_BBPEN 10
#define WACOM_PKGLEN_BBPEN 10
#define WACOM_PKGLEN_WIRELESS 32
/* device IDs */
/* device IDs */
#define STYLUS_DEVICE_ID 0x02
#define STYLUS_DEVICE_ID 0x02
...
@@ -45,6 +46,8 @@
...
@@ -45,6 +46,8 @@
/* device quirks */
/* device quirks */
#define WACOM_QUIRK_MULTI_INPUT 0x0001
#define WACOM_QUIRK_MULTI_INPUT 0x0001
#define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002
#define WACOM_QUIRK_BBTOUCH_LOWRES 0x0002
#define WACOM_QUIRK_NO_INPUT 0x0004
#define WACOM_QUIRK_MONITOR 0x0008
enum
{
enum
{
PENPARTNER
=
0
,
PENPARTNER
=
0
,
...
@@ -54,6 +57,7 @@ enum {
...
@@ -54,6 +57,7 @@ enum {
PL
,
PL
,
DTU
,
DTU
,
BAMBOO_PT
,
BAMBOO_PT
,
WIRELESS
,
INTUOS
,
INTUOS
,
INTUOS3S
,
INTUOS3S
,
INTUOS3
,
INTUOS3
,
...
@@ -107,6 +111,8 @@ struct wacom_wac {
...
@@ -107,6 +111,8 @@ struct wacom_wac {
struct
wacom_features
features
;
struct
wacom_features
features
;
struct
wacom_shared
*
shared
;
struct
wacom_shared
*
shared
;
struct
input_dev
*
input
;
struct
input_dev
*
input
;
int
pid
;
int
battery_capacity
;
};
};
#endif
#endif
include/linux/gpio_keys.h
浏览文件 @
99380825
...
@@ -6,7 +6,7 @@ struct device;
...
@@ -6,7 +6,7 @@ struct device;
struct
gpio_keys_button
{
struct
gpio_keys_button
{
/* Configuration parameters */
/* Configuration parameters */
unsigned
int
code
;
/* input event code (KEY_*, SW_*) */
unsigned
int
code
;
/* input event code (KEY_*, SW_*) */
int
gpio
;
int
gpio
;
/* -1 if this key does not support gpio */
int
active_low
;
int
active_low
;
const
char
*
desc
;
const
char
*
desc
;
unsigned
int
type
;
/* input event type (EV_KEY, EV_SW, EV_ABS) */
unsigned
int
type
;
/* input event type (EV_KEY, EV_SW, EV_ABS) */
...
@@ -14,6 +14,7 @@ struct gpio_keys_button {
...
@@ -14,6 +14,7 @@ struct gpio_keys_button {
int
debounce_interval
;
/* debounce ticks interval in msecs */
int
debounce_interval
;
/* debounce ticks interval in msecs */
bool
can_disable
;
bool
can_disable
;
int
value
;
/* axis value for EV_ABS */
int
value
;
/* axis value for EV_ABS */
unsigned
int
irq
;
/* Irq number in case of interrupt keys */
};
};
struct
gpio_keys_platform_data
{
struct
gpio_keys_platform_data
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录