Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
Kernel
提交
01c728a2
K
Kernel
项目概览
openeuler
/
Kernel
1 年多 前同步成功
通知
8
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
Kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
01c728a2
编写于
1月 11, 2011
作者:
D
Dmitry Torokhov
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'next' into for-linus
上级
554738da
50a88cb7
变更
18
隐藏空白更改
内联
并排
Showing
18 changed file
with
624 addition
and
265 deletion
+624
-265
Documentation/input/ff.txt
Documentation/input/ff.txt
+3
-1
Documentation/kernel-parameters.txt
Documentation/kernel-parameters.txt
+1
-0
drivers/input/joystick/Kconfig
drivers/input/joystick/Kconfig
+10
-0
drivers/input/joystick/Makefile
drivers/input/joystick/Makefile
+1
-0
drivers/input/joystick/as5011.c
drivers/input/joystick/as5011.c
+367
-0
drivers/input/keyboard/Kconfig
drivers/input/keyboard/Kconfig
+0
-12
drivers/input/keyboard/Makefile
drivers/input/keyboard/Makefile
+0
-1
drivers/input/keyboard/aaed2000_kbd.c
drivers/input/keyboard/aaed2000_kbd.c
+0
-186
drivers/input/serio/i8042-x86ia64io.h
drivers/input/serio/i8042-x86ia64io.h
+21
-0
drivers/input/serio/i8042.c
drivers/input/serio/i8042.c
+5
-1
drivers/input/touchscreen/ad7879-i2c.c
drivers/input/touchscreen/ad7879-i2c.c
+10
-7
drivers/input/touchscreen/cy8ctmg110_ts.c
drivers/input/touchscreen/cy8ctmg110_ts.c
+9
-6
drivers/input/touchscreen/eeti_ts.c
drivers/input/touchscreen/eeti_ts.c
+9
-7
drivers/input/touchscreen/mcs5000_ts.c
drivers/input/touchscreen/mcs5000_ts.c
+10
-7
drivers/input/touchscreen/migor_ts.c
drivers/input/touchscreen/migor_ts.c
+8
-4
drivers/input/touchscreen/wacom_w8001.c
drivers/input/touchscreen/wacom_w8001.c
+149
-33
include/linux/input.h
include/linux/input.h
+1
-0
include/linux/input/as5011.h
include/linux/input/as5011.h
+20
-0
未找到文件。
Documentation/input/ff.txt
浏览文件 @
01c728a2
...
...
@@ -49,7 +49,9 @@ This information is subject to change.
#include <linux/input.h>
#include <sys/ioctl.h>
unsigned long features[1 + FF_MAX/sizeof(unsigned long)];
#define BITS_TO_LONGS(x) \
(((x) + 8 * sizeof (unsigned long) - 1) / (8 * sizeof (unsigned long)))
unsigned long features[BITS_TO_LONGS(FF_CNT)];
int ioctl(int file_descriptor, int request, unsigned long *features);
"request" must be EVIOCGBIT(EV_FF, size of features array in bytes )
...
...
Documentation/kernel-parameters.txt
浏览文件 @
01c728a2
...
...
@@ -884,6 +884,7 @@ and is between 256 and 4096 characters. It is defined in the file
controller
i8042.nopnp [HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX
controllers
i8042.notimeout [HW] Ignore timeout condition signalled by conroller
i8042.reset [HW] Reset the controller during init and cleanup
i8042.unlock [HW] Unlock (ignore) the keylock
...
...
drivers/input/joystick/Kconfig
浏览文件 @
01c728a2
...
...
@@ -255,6 +255,16 @@ config JOYSTICK_AMIGA
To compile this driver as a module, choose M here: the
module will be called amijoy.
config JOYSTICK_AS5011
tristate "Austria Microsystem AS5011 joystick"
depends on I2C
help
Say Y here if you have an AS5011 digital joystick connected to your
system.
To compile this driver as a module, choose M here: the
module will be called as5011.
config JOYSTICK_JOYDUMP
tristate "Gameport data dumper"
select GAMEPORT
...
...
drivers/input/joystick/Makefile
浏览文件 @
01c728a2
...
...
@@ -7,6 +7,7 @@
obj-$(CONFIG_JOYSTICK_A3D)
+=
a3d.o
obj-$(CONFIG_JOYSTICK_ADI)
+=
adi.o
obj-$(CONFIG_JOYSTICK_AMIGA)
+=
amijoy.o
obj-$(CONFIG_JOYSTICK_AS5011)
+=
as5011.o
obj-$(CONFIG_JOYSTICK_ANALOG)
+=
analog.o
obj-$(CONFIG_JOYSTICK_COBRA)
+=
cobra.o
obj-$(CONFIG_JOYSTICK_DB9)
+=
db9.o
...
...
drivers/input/joystick/as5011.c
0 → 100644
浏览文件 @
01c728a2
/*
* Copyright (c) 2010, 2011 Fabien Marteau <fabien.marteau@armadeus.com>
* Sponsored by ARMadeus Systems
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Driver for Austria Microsystems joysticks AS5011
*
* TODO:
* - Power on the chip when open() and power down when close()
* - Manage power mode
*/
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/input/as5011.h>
#include <linux/slab.h>
#define DRIVER_DESC "Driver for Austria Microsystems AS5011 joystick"
#define MODULE_DEVICE_ALIAS "as5011"
MODULE_AUTHOR
(
"Fabien Marteau <fabien.marteau@armadeus.com>"
);
MODULE_DESCRIPTION
(
DRIVER_DESC
);
MODULE_LICENSE
(
"GPL"
);
/* registers */
#define AS5011_CTRL1 0x76
#define AS5011_CTRL2 0x75
#define AS5011_XP 0x43
#define AS5011_XN 0x44
#define AS5011_YP 0x53
#define AS5011_YN 0x54
#define AS5011_X_REG 0x41
#define AS5011_Y_REG 0x42
#define AS5011_X_RES_INT 0x51
#define AS5011_Y_RES_INT 0x52
/* CTRL1 bits */
#define AS5011_CTRL1_LP_PULSED 0x80
#define AS5011_CTRL1_LP_ACTIVE 0x40
#define AS5011_CTRL1_LP_CONTINUE 0x20
#define AS5011_CTRL1_INT_WUP_EN 0x10
#define AS5011_CTRL1_INT_ACT_EN 0x08
#define AS5011_CTRL1_EXT_CLK_EN 0x04
#define AS5011_CTRL1_SOFT_RST 0x02
#define AS5011_CTRL1_DATA_VALID 0x01
/* CTRL2 bits */
#define AS5011_CTRL2_EXT_SAMPLE_EN 0x08
#define AS5011_CTRL2_RC_BIAS_ON 0x04
#define AS5011_CTRL2_INV_SPINNING 0x02
#define AS5011_MAX_AXIS 80
#define AS5011_MIN_AXIS (-80)
#define AS5011_FUZZ 8
#define AS5011_FLAT 40
struct
as5011_device
{
struct
input_dev
*
input_dev
;
struct
i2c_client
*
i2c_client
;
unsigned
int
button_gpio
;
unsigned
int
button_irq
;
unsigned
int
axis_irq
;
};
static
int
as5011_i2c_write
(
struct
i2c_client
*
client
,
uint8_t
aregaddr
,
uint8_t
avalue
)
{
uint8_t
data
[
2
]
=
{
aregaddr
,
avalue
};
struct
i2c_msg
msg
=
{
client
->
addr
,
I2C_M_IGNORE_NAK
,
2
,
(
uint8_t
*
)
data
};
int
error
;
error
=
i2c_transfer
(
client
->
adapter
,
&
msg
,
1
);
return
error
<
0
?
error
:
0
;
}
static
int
as5011_i2c_read
(
struct
i2c_client
*
client
,
uint8_t
aregaddr
,
signed
char
*
value
)
{
uint8_t
data
[
2
]
=
{
aregaddr
};
struct
i2c_msg
msg_set
[
2
]
=
{
{
client
->
addr
,
I2C_M_REV_DIR_ADDR
,
1
,
(
uint8_t
*
)
data
},
{
client
->
addr
,
I2C_M_RD
|
I2C_M_NOSTART
,
1
,
(
uint8_t
*
)
data
}
};
int
error
;
error
=
i2c_transfer
(
client
->
adapter
,
msg_set
,
2
);
if
(
error
<
0
)
return
error
;
*
value
=
data
[
0
]
&
0x80
?
-
1
*
(
1
+
~
data
[
0
])
:
data
[
0
];
return
0
;
}
static
irqreturn_t
as5011_button_interrupt
(
int
irq
,
void
*
dev_id
)
{
struct
as5011_device
*
as5011
=
dev_id
;
int
val
=
gpio_get_value_cansleep
(
as5011
->
button_gpio
);
input_report_key
(
as5011
->
input_dev
,
BTN_JOYSTICK
,
!
val
);
input_sync
(
as5011
->
input_dev
);
return
IRQ_HANDLED
;
}
static
irqreturn_t
as5011_axis_interrupt
(
int
irq
,
void
*
dev_id
)
{
struct
as5011_device
*
as5011
=
dev_id
;
int
error
;
signed
char
x
,
y
;
error
=
as5011_i2c_read
(
as5011
->
i2c_client
,
AS5011_X_RES_INT
,
&
x
);
if
(
error
<
0
)
goto
out
;
error
=
as5011_i2c_read
(
as5011
->
i2c_client
,
AS5011_Y_RES_INT
,
&
y
);
if
(
error
<
0
)
goto
out
;
input_report_abs
(
as5011
->
input_dev
,
ABS_X
,
x
);
input_report_abs
(
as5011
->
input_dev
,
ABS_Y
,
y
);
input_sync
(
as5011
->
input_dev
);
out:
return
IRQ_HANDLED
;
}
static
int
__devinit
as5011_configure_chip
(
struct
as5011_device
*
as5011
,
const
struct
as5011_platform_data
*
plat_dat
)
{
struct
i2c_client
*
client
=
as5011
->
i2c_client
;
int
error
;
signed
char
value
;
/* chip soft reset */
error
=
as5011_i2c_write
(
client
,
AS5011_CTRL1
,
AS5011_CTRL1_SOFT_RST
);
if
(
error
<
0
)
{
dev_err
(
&
client
->
dev
,
"Soft reset failed
\n
"
);
return
error
;
}
mdelay
(
10
);
error
=
as5011_i2c_write
(
client
,
AS5011_CTRL1
,
AS5011_CTRL1_LP_PULSED
|
AS5011_CTRL1_LP_ACTIVE
|
AS5011_CTRL1_INT_ACT_EN
);
if
(
error
<
0
)
{
dev_err
(
&
client
->
dev
,
"Power config failed
\n
"
);
return
error
;
}
error
=
as5011_i2c_write
(
client
,
AS5011_CTRL2
,
AS5011_CTRL2_INV_SPINNING
);
if
(
error
<
0
)
{
dev_err
(
&
client
->
dev
,
"Can't invert spinning
\n
"
);
return
error
;
}
/* write threshold */
error
=
as5011_i2c_write
(
client
,
AS5011_XP
,
plat_dat
->
xp
);
if
(
error
<
0
)
{
dev_err
(
&
client
->
dev
,
"Can't write threshold
\n
"
);
return
error
;
}
error
=
as5011_i2c_write
(
client
,
AS5011_XN
,
plat_dat
->
xn
);
if
(
error
<
0
)
{
dev_err
(
&
client
->
dev
,
"Can't write threshold
\n
"
);
return
error
;
}
error
=
as5011_i2c_write
(
client
,
AS5011_YP
,
plat_dat
->
yp
);
if
(
error
<
0
)
{
dev_err
(
&
client
->
dev
,
"Can't write threshold
\n
"
);
return
error
;
}
error
=
as5011_i2c_write
(
client
,
AS5011_YN
,
plat_dat
->
yn
);
if
(
error
<
0
)
{
dev_err
(
&
client
->
dev
,
"Can't write threshold
\n
"
);
return
error
;
}
/* to free irq gpio in chip */
error
=
as5011_i2c_read
(
client
,
AS5011_X_RES_INT
,
&
value
);
if
(
error
<
0
)
{
dev_err
(
&
client
->
dev
,
"Can't read i2c X resolution value
\n
"
);
return
error
;
}
return
0
;
}
static
int
__devinit
as5011_probe
(
struct
i2c_client
*
client
,
const
struct
i2c_device_id
*
id
)
{
const
struct
as5011_platform_data
*
plat_data
;
struct
as5011_device
*
as5011
;
struct
input_dev
*
input_dev
;
int
irq
;
int
error
;
plat_data
=
client
->
dev
.
platform_data
;
if
(
!
plat_data
)
return
-
EINVAL
;
if
(
!
plat_data
->
axis_irq
)
{
dev_err
(
&
client
->
dev
,
"No axis IRQ?
\n
"
);
return
-
EINVAL
;
}
if
(
!
i2c_check_functionality
(
client
->
adapter
,
I2C_FUNC_PROTOCOL_MANGLING
))
{
dev_err
(
&
client
->
dev
,
"need i2c bus that supports protocol mangling
\n
"
);
return
-
ENODEV
;
}
as5011
=
kmalloc
(
sizeof
(
struct
as5011_device
),
GFP_KERNEL
);
input_dev
=
input_allocate_device
();
if
(
!
as5011
||
!
input_dev
)
{
dev_err
(
&
client
->
dev
,
"Can't allocate memory for device structure
\n
"
);
error
=
-
ENOMEM
;
goto
err_free_mem
;
}
as5011
->
i2c_client
=
client
;
as5011
->
input_dev
=
input_dev
;
as5011
->
button_gpio
=
plat_data
->
button_gpio
;
as5011
->
axis_irq
=
plat_data
->
axis_irq
;
input_dev
->
name
=
"Austria Microsystem as5011 joystick"
;
input_dev
->
id
.
bustype
=
BUS_I2C
;
input_dev
->
dev
.
parent
=
&
client
->
dev
;
__set_bit
(
EV_KEY
,
input_dev
->
evbit
);
__set_bit
(
EV_ABS
,
input_dev
->
evbit
);
__set_bit
(
BTN_JOYSTICK
,
input_dev
->
keybit
);
input_set_abs_params
(
input_dev
,
ABS_X
,
AS5011_MIN_AXIS
,
AS5011_MAX_AXIS
,
AS5011_FUZZ
,
AS5011_FLAT
);
input_set_abs_params
(
as5011
->
input_dev
,
ABS_Y
,
AS5011_MIN_AXIS
,
AS5011_MAX_AXIS
,
AS5011_FUZZ
,
AS5011_FLAT
);
error
=
gpio_request
(
as5011
->
button_gpio
,
"AS5011 button"
);
if
(
error
<
0
)
{
dev_err
(
&
client
->
dev
,
"Failed to request button gpio
\n
"
);
goto
err_free_mem
;
}
irq
=
gpio_to_irq
(
as5011
->
button_gpio
);
if
(
irq
<
0
)
{
dev_err
(
&
client
->
dev
,
"Failed to get irq number for button gpio
\n
"
);
goto
err_free_button_gpio
;
}
as5011
->
button_irq
=
irq
;
error
=
request_threaded_irq
(
as5011
->
button_irq
,
NULL
,
as5011_button_interrupt
,
IRQF_TRIGGER_RISING
|
IRQF_TRIGGER_FALLING
,
"as5011_button"
,
as5011
);
if
(
error
<
0
)
{
dev_err
(
&
client
->
dev
,
"Can't allocate button irq %d
\n
"
,
as5011
->
button_irq
);
goto
err_free_button_gpio
;
}
error
=
as5011_configure_chip
(
as5011
,
plat_data
);
if
(
error
)
goto
err_free_button_irq
;
error
=
request_threaded_irq
(
as5011
->
axis_irq
,
NULL
,
as5011_axis_interrupt
,
plat_data
->
axis_irqflags
,
"as5011_joystick"
,
as5011
);
if
(
error
)
{
dev_err
(
&
client
->
dev
,
"Can't allocate axis irq %d
\n
"
,
plat_data
->
axis_irq
);
goto
err_free_button_irq
;
}
error
=
input_register_device
(
as5011
->
input_dev
);
if
(
error
)
{
dev_err
(
&
client
->
dev
,
"Failed to register input device
\n
"
);
goto
err_free_axis_irq
;
}
i2c_set_clientdata
(
client
,
as5011
);
return
0
;
err_free_axis_irq:
free_irq
(
as5011
->
axis_irq
,
as5011
);
err_free_button_irq:
free_irq
(
as5011
->
button_irq
,
as5011
);
err_free_button_gpio:
gpio_free
(
as5011
->
button_gpio
);
err_free_mem:
input_free_device
(
input_dev
);
kfree
(
as5011
);
return
error
;
}
static
int
__devexit
as5011_remove
(
struct
i2c_client
*
client
)
{
struct
as5011_device
*
as5011
=
i2c_get_clientdata
(
client
);
free_irq
(
as5011
->
axis_irq
,
as5011
);
free_irq
(
as5011
->
button_irq
,
as5011
);
gpio_free
(
as5011
->
button_gpio
);
input_unregister_device
(
as5011
->
input_dev
);
kfree
(
as5011
);
return
0
;
}
static
const
struct
i2c_device_id
as5011_id
[]
=
{
{
MODULE_DEVICE_ALIAS
,
0
},
{
}
};
MODULE_DEVICE_TABLE
(
i2c
,
as5011_id
);
static
struct
i2c_driver
as5011_driver
=
{
.
driver
=
{
.
name
=
"as5011"
,
},
.
probe
=
as5011_probe
,
.
remove
=
__devexit_p
(
as5011_remove
),
.
id_table
=
as5011_id
,
};
static
int
__init
as5011_init
(
void
)
{
return
i2c_add_driver
(
&
as5011_driver
);
}
module_init
(
as5011_init
);
static
void
__exit
as5011_exit
(
void
)
{
i2c_del_driver
(
&
as5011_driver
);
}
module_exit
(
as5011_exit
);
drivers/input/keyboard/Kconfig
浏览文件 @
01c728a2
...
...
@@ -12,18 +12,6 @@ menuconfig INPUT_KEYBOARD
if INPUT_KEYBOARD
config KEYBOARD_AAED2000
tristate "AAED-2000 keyboard"
depends on MACH_AAED2000
select INPUT_POLLDEV
default y
help
Say Y here to enable the keyboard on the Agilent AAED-2000
development board.
To compile this driver as a module, choose M here: the
module will be called aaed2000_kbd.
config KEYBOARD_ADP5520
tristate "Keypad Support for ADP5520 PMIC"
depends on PMIC_ADP5520
...
...
drivers/input/keyboard/Makefile
浏览文件 @
01c728a2
...
...
@@ -4,7 +4,6 @@
# Each configuration option enables a list of files.
obj-$(CONFIG_KEYBOARD_AAED2000)
+=
aaed2000_kbd.o
obj-$(CONFIG_KEYBOARD_ADP5520)
+=
adp5520-keys.o
obj-$(CONFIG_KEYBOARD_ADP5588)
+=
adp5588-keys.o
obj-$(CONFIG_KEYBOARD_AMIGA)
+=
amikbd.o
...
...
drivers/input/keyboard/aaed2000_kbd.c
已删除
100644 → 0
浏览文件 @
554738da
/*
* Keyboard driver for the AAED-2000 dev board
*
* Copyright (c) 2006 Nicolas Bellido Y Ortega
*
* Based on corgikbd.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/init.h>
#include <linux/input-polldev.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <mach/hardware.h>
#include <mach/aaed2000.h>
#define KB_ROWS 12
#define KB_COLS 8
#define KB_ROWMASK(r) (1 << (r))
#define SCANCODE(r,c) (((c) * KB_ROWS) + (r))
#define NR_SCANCODES (KB_COLS * KB_ROWS)
#define SCAN_INTERVAL (50)
/* ms */
#define KB_ACTIVATE_DELAY (20)
/* us */
static
unsigned
char
aaedkbd_keycode
[
NR_SCANCODES
]
=
{
KEY_9
,
KEY_0
,
KEY_MINUS
,
KEY_EQUAL
,
KEY_BACKSPACE
,
0
,
KEY_SPACE
,
KEY_KP6
,
0
,
KEY_KPDOT
,
0
,
0
,
KEY_K
,
KEY_M
,
KEY_O
,
KEY_DOT
,
KEY_SLASH
,
0
,
KEY_F
,
0
,
0
,
0
,
KEY_LEFTSHIFT
,
0
,
KEY_I
,
KEY_P
,
KEY_LEFTBRACE
,
KEY_RIGHTBRACE
,
KEY_BACKSLASH
,
0
,
0
,
0
,
0
,
0
,
KEY_RIGHTSHIFT
,
0
,
KEY_8
,
KEY_L
,
KEY_SEMICOLON
,
KEY_APOSTROPHE
,
KEY_ENTER
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
KEY_J
,
KEY_H
,
KEY_B
,
KEY_KP8
,
KEY_KP4
,
0
,
KEY_C
,
KEY_D
,
KEY_S
,
KEY_A
,
0
,
KEY_CAPSLOCK
,
KEY_Y
,
KEY_U
,
KEY_N
,
KEY_T
,
0
,
0
,
KEY_R
,
KEY_E
,
KEY_W
,
KEY_Q
,
0
,
KEY_TAB
,
KEY_7
,
KEY_6
,
KEY_G
,
0
,
KEY_5
,
0
,
KEY_4
,
KEY_3
,
KEY_2
,
KEY_1
,
0
,
KEY_GRAVE
,
0
,
0
,
KEY_COMMA
,
0
,
KEY_KP2
,
0
,
KEY_V
,
KEY_LEFTALT
,
KEY_X
,
KEY_Z
,
0
,
KEY_LEFTCTRL
};
struct
aaedkbd
{
unsigned
char
keycode
[
ARRAY_SIZE
(
aaedkbd_keycode
)];
struct
input_polled_dev
*
poll_dev
;
int
kbdscan_state
[
KB_COLS
];
int
kbdscan_count
[
KB_COLS
];
};
#define KBDSCAN_STABLE_COUNT 2
static
void
aaedkbd_report_col
(
struct
aaedkbd
*
aaedkbd
,
unsigned
int
col
,
unsigned
int
rowd
)
{
unsigned
int
scancode
,
pressed
;
unsigned
int
row
;
for
(
row
=
0
;
row
<
KB_ROWS
;
row
++
)
{
scancode
=
SCANCODE
(
row
,
col
);
pressed
=
rowd
&
KB_ROWMASK
(
row
);
input_report_key
(
aaedkbd
->
poll_dev
->
input
,
aaedkbd
->
keycode
[
scancode
],
pressed
);
}
}
/* Scan the hardware keyboard and push any changes up through the input layer */
static
void
aaedkbd_poll
(
struct
input_polled_dev
*
dev
)
{
struct
aaedkbd
*
aaedkbd
=
dev
->
private
;
unsigned
int
col
,
rowd
;
col
=
0
;
do
{
AAEC_GPIO_KSCAN
=
col
+
8
;
udelay
(
KB_ACTIVATE_DELAY
);
rowd
=
AAED_EXT_GPIO
&
AAED_EGPIO_KBD_SCAN
;
if
(
rowd
!=
aaedkbd
->
kbdscan_state
[
col
])
{
aaedkbd
->
kbdscan_count
[
col
]
=
0
;
aaedkbd
->
kbdscan_state
[
col
]
=
rowd
;
}
else
if
(
++
aaedkbd
->
kbdscan_count
[
col
]
>=
KBDSCAN_STABLE_COUNT
)
{
aaedkbd_report_col
(
aaedkbd
,
col
,
rowd
);
col
++
;
}
}
while
(
col
<
KB_COLS
);
AAEC_GPIO_KSCAN
=
0x07
;
input_sync
(
dev
->
input
);
}
static
int
__devinit
aaedkbd_probe
(
struct
platform_device
*
pdev
)
{
struct
aaedkbd
*
aaedkbd
;
struct
input_polled_dev
*
poll_dev
;
struct
input_dev
*
input_dev
;
int
i
;
int
error
;
aaedkbd
=
kzalloc
(
sizeof
(
struct
aaedkbd
),
GFP_KERNEL
);
poll_dev
=
input_allocate_polled_device
();
if
(
!
aaedkbd
||
!
poll_dev
)
{
error
=
-
ENOMEM
;
goto
fail
;
}
platform_set_drvdata
(
pdev
,
aaedkbd
);
aaedkbd
->
poll_dev
=
poll_dev
;
memcpy
(
aaedkbd
->
keycode
,
aaedkbd_keycode
,
sizeof
(
aaedkbd
->
keycode
));
poll_dev
->
private
=
aaedkbd
;
poll_dev
->
poll
=
aaedkbd_poll
;
poll_dev
->
poll_interval
=
SCAN_INTERVAL
;
input_dev
=
poll_dev
->
input
;
input_dev
->
name
=
"AAED-2000 Keyboard"
;
input_dev
->
phys
=
"aaedkbd/input0"
;
input_dev
->
id
.
bustype
=
BUS_HOST
;
input_dev
->
id
.
vendor
=
0x0001
;
input_dev
->
id
.
product
=
0x0001
;
input_dev
->
id
.
version
=
0x0100
;
input_dev
->
dev
.
parent
=
&
pdev
->
dev
;
input_dev
->
evbit
[
0
]
=
BIT_MASK
(
EV_KEY
)
|
BIT_MASK
(
EV_REP
);
input_dev
->
keycode
=
aaedkbd
->
keycode
;
input_dev
->
keycodesize
=
sizeof
(
unsigned
char
);
input_dev
->
keycodemax
=
ARRAY_SIZE
(
aaedkbd_keycode
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
aaedkbd_keycode
);
i
++
)
set_bit
(
aaedkbd
->
keycode
[
i
],
input_dev
->
keybit
);
clear_bit
(
0
,
input_dev
->
keybit
);
error
=
input_register_polled_device
(
aaedkbd
->
poll_dev
);
if
(
error
)
goto
fail
;
return
0
;
fail:
kfree
(
aaedkbd
);
input_free_polled_device
(
poll_dev
);
return
error
;
}
static
int
__devexit
aaedkbd_remove
(
struct
platform_device
*
pdev
)
{
struct
aaedkbd
*
aaedkbd
=
platform_get_drvdata
(
pdev
);
input_unregister_polled_device
(
aaedkbd
->
poll_dev
);
input_free_polled_device
(
aaedkbd
->
poll_dev
);
kfree
(
aaedkbd
);
return
0
;
}
/* work with hotplug and coldplug */
MODULE_ALIAS
(
"platform:aaed2000-keyboard"
);
static
struct
platform_driver
aaedkbd_driver
=
{
.
probe
=
aaedkbd_probe
,
.
remove
=
__devexit_p
(
aaedkbd_remove
),
.
driver
=
{
.
name
=
"aaed2000-keyboard"
,
.
owner
=
THIS_MODULE
,
},
};
static
int
__init
aaedkbd_init
(
void
)
{
return
platform_driver_register
(
&
aaedkbd_driver
);
}
static
void
__exit
aaedkbd_exit
(
void
)
{
platform_driver_unregister
(
&
aaedkbd_driver
);
}
module_init
(
aaedkbd_init
);
module_exit
(
aaedkbd_exit
);
MODULE_AUTHOR
(
"Nicolas Bellido Y Ortega"
);
MODULE_DESCRIPTION
(
"AAED-2000 Keyboard Driver"
);
MODULE_LICENSE
(
"GPL v2"
);
drivers/input/serio/i8042-x86ia64io.h
浏览文件 @
01c728a2
...
...
@@ -424,6 +424,13 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
DMI_MATCH
(
DMI_PRODUCT_VERSION
,
"0100"
),
},
},
{
/* Dell Vostro V13 */
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"Dell Inc."
),
DMI_MATCH
(
DMI_PRODUCT_NAME
,
"Vostro V13"
),
},
},
{
}
};
...
...
@@ -545,6 +552,17 @@ static const struct dmi_system_id __initconst i8042_dmi_laptop_table[] = {
};
#endif
static
const
struct
dmi_system_id
__initconst
i8042_dmi_notimeout_table
[]
=
{
{
/* Dell Vostro V13 */
.
matches
=
{
DMI_MATCH
(
DMI_SYS_VENDOR
,
"Dell Inc."
),
DMI_MATCH
(
DMI_PRODUCT_NAME
,
"Vostro V13"
),
},
},
{
}
};
/*
* Some Wistron based laptops need us to explicitly enable the 'Dritek
* keyboard extension' to make their extra keys start generating scancodes.
...
...
@@ -896,6 +914,9 @@ static int __init i8042_platform_init(void)
if
(
dmi_check_system
(
i8042_dmi_nomux_table
))
i8042_nomux
=
true
;
if
(
dmi_check_system
(
i8042_dmi_notimeout_table
))
i8042_notimeout
=
true
;
if
(
dmi_check_system
(
i8042_dmi_dritek_table
))
i8042_dritek
=
true
;
#endif
/* CONFIG_X86 */
...
...
drivers/input/serio/i8042.c
浏览文件 @
01c728a2
...
...
@@ -63,6 +63,10 @@ static bool i8042_noloop;
module_param_named
(
noloop
,
i8042_noloop
,
bool
,
0
);
MODULE_PARM_DESC
(
noloop
,
"Disable the AUX Loopback command while probing for the AUX port"
);
static
bool
i8042_notimeout
;
module_param_named
(
notimeout
,
i8042_notimeout
,
bool
,
0
);
MODULE_PARM_DESC
(
notimeout
,
"Ignore timeouts signalled by i8042"
);
#ifdef CONFIG_X86
static
bool
i8042_dritek
;
module_param_named
(
dritek
,
i8042_dritek
,
bool
,
0
);
...
...
@@ -504,7 +508,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
}
else
{
dfl
=
((
str
&
I8042_STR_PARITY
)
?
SERIO_PARITY
:
0
)
|
((
str
&
I8042_STR_TIMEOUT
)
?
SERIO_TIMEOUT
:
0
);
((
str
&
I8042_STR_TIMEOUT
&&
!
i8042_notimeout
)
?
SERIO_TIMEOUT
:
0
);
port_no
=
(
str
&
I8042_STR_AUXDATA
)
?
I8042_AUX_PORT_NO
:
I8042_KBD_PORT_NO
;
...
...
drivers/input/touchscreen/ad7879-i2c.c
浏览文件 @
01c728a2
...
...
@@ -10,14 +10,16 @@
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/pm.h>
#include "ad7879.h"
#define AD7879_DEVID 0x79
/* AD7879-1/AD7889-1 */
#ifdef CONFIG_PM
static
int
ad7879_i2c_suspend
(
struct
i2c_client
*
client
,
pm_message_t
message
)
static
int
ad7879_i2c_suspend
(
struct
device
*
dev
)
{
struct
i2c_client
*
client
=
to_i2c_client
(
dev
);
struct
ad7879
*
ts
=
i2c_get_clientdata
(
client
);
ad7879_suspend
(
ts
);
...
...
@@ -25,17 +27,17 @@ static int ad7879_i2c_suspend(struct i2c_client *client, pm_message_t message)
return
0
;
}
static
int
ad7879_i2c_resume
(
struct
i2c_client
*
client
)
static
int
ad7879_i2c_resume
(
struct
device
*
dev
)
{
struct
i2c_client
*
client
=
to_i2c_client
(
dev
);
struct
ad7879
*
ts
=
i2c_get_clientdata
(
client
);
ad7879_resume
(
ts
);
return
0
;
}
#else
# define ad7879_i2c_suspend NULL
# define ad7879_i2c_resume NULL
static
SIMPLE_DEV_PM_OPS
(
ad7879_i2c_pm
,
ad7879_i2c_suspend
,
ad7879_i2c_resume
);
#endif
/* All registers are word-sized.
...
...
@@ -117,11 +119,12 @@ static struct i2c_driver ad7879_i2c_driver = {
.
driver
=
{
.
name
=
"ad7879"
,
.
owner
=
THIS_MODULE
,
#ifdef CONFIG_PM
.
pm
=
&
ad7879_i2c_pm
,
#endif
},
.
probe
=
ad7879_i2c_probe
,
.
remove
=
__devexit_p
(
ad7879_i2c_remove
),
.
suspend
=
ad7879_i2c_suspend
,
.
resume
=
ad7879_i2c_resume
,
.
id_table
=
ad7879_id
,
};
...
...
drivers/input/touchscreen/cy8ctmg110_ts.c
浏览文件 @
01c728a2
...
...
@@ -280,8 +280,9 @@ static int __devinit cy8ctmg110_probe(struct i2c_client *client,
}
#ifdef CONFIG_PM
static
int
cy8ctmg110_suspend
(
struct
i2c_client
*
client
,
pm_message_t
mesg
)
static
int
cy8ctmg110_suspend
(
struct
device
*
dev
)
{
struct
i2c_client
*
client
=
to_i2c_client
(
dev
);
struct
cy8ctmg110
*
ts
=
i2c_get_clientdata
(
client
);
if
(
device_may_wakeup
(
&
client
->
dev
))
...
...
@@ -293,8 +294,9 @@ static int cy8ctmg110_suspend(struct i2c_client *client, pm_message_t mesg)
return
0
;
}
static
int
cy8ctmg110_resume
(
struct
i2c_client
*
client
)
static
int
cy8ctmg110_resume
(
struct
device
*
dev
)
{
struct
i2c_client
*
client
=
to_i2c_client
(
dev
);
struct
cy8ctmg110
*
ts
=
i2c_get_clientdata
(
client
);
if
(
device_may_wakeup
(
&
client
->
dev
))
...
...
@@ -305,6 +307,8 @@ static int cy8ctmg110_resume(struct i2c_client *client)
}
return
0
;
}
static
SIMPLE_DEV_PM_OPS
(
cy8ctmg110_pm
,
cy8ctmg110_suspend
,
cy8ctmg110_resume
);
#endif
static
int
__devexit
cy8ctmg110_remove
(
struct
i2c_client
*
client
)
...
...
@@ -335,14 +339,13 @@ static struct i2c_driver cy8ctmg110_driver = {
.
driver
=
{
.
owner
=
THIS_MODULE
,
.
name
=
CY8CTMG110_DRIVER_NAME
,
#ifdef CONFIG_PM
.
pm
=
&
cy8ctmg110_pm
,
#endif
},
.
id_table
=
cy8ctmg110_idtable
,
.
probe
=
cy8ctmg110_probe
,
.
remove
=
__devexit_p
(
cy8ctmg110_remove
),
#ifdef CONFIG_PM
.
suspend
=
cy8ctmg110_suspend
,
.
resume
=
cy8ctmg110_resume
,
#endif
};
static
int
__init
cy8ctmg110_init
(
void
)
...
...
drivers/input/touchscreen/eeti_ts.c
浏览文件 @
01c728a2
...
...
@@ -261,8 +261,9 @@ static int __devexit eeti_ts_remove(struct i2c_client *client)
}
#ifdef CONFIG_PM
static
int
eeti_ts_suspend
(
struct
i2c_client
*
client
,
pm_message_t
mesg
)
static
int
eeti_ts_suspend
(
struct
device
*
dev
)
{
struct
i2c_client
*
client
=
to_i2c_client
(
dev
);
struct
eeti_ts_priv
*
priv
=
i2c_get_clientdata
(
client
);
struct
input_dev
*
input_dev
=
priv
->
input
;
...
...
@@ -279,8 +280,9 @@ static int eeti_ts_suspend(struct i2c_client *client, pm_message_t mesg)
return
0
;
}
static
int
eeti_ts_resume
(
struct
i2c_client
*
client
)
static
int
eeti_ts_resume
(
struct
device
*
dev
)
{
struct
i2c_client
*
client
=
to_i2c_client
(
dev
);
struct
eeti_ts_priv
*
priv
=
i2c_get_clientdata
(
client
);
struct
input_dev
*
input_dev
=
priv
->
input
;
...
...
@@ -296,9 +298,8 @@ static int eeti_ts_resume(struct i2c_client *client)
return
0
;
}
#else
#define eeti_ts_suspend NULL
#define eeti_ts_resume NULL
static
SIMPLE_DEV_PM_OPS
(
eeti_ts_pm
,
eeti_ts_suspend
,
eeti_ts_resume
);
#endif
static
const
struct
i2c_device_id
eeti_ts_id
[]
=
{
...
...
@@ -310,11 +311,12 @@ MODULE_DEVICE_TABLE(i2c, eeti_ts_id);
static
struct
i2c_driver
eeti_ts_driver
=
{
.
driver
=
{
.
name
=
"eeti_ts"
,
#ifdef CONFIG_PM
.
pm
=
&
eeti_ts_pm
,
#endif
},
.
probe
=
eeti_ts_probe
,
.
remove
=
__devexit_p
(
eeti_ts_remove
),
.
suspend
=
eeti_ts_suspend
,
.
resume
=
eeti_ts_resume
,
.
id_table
=
eeti_ts_id
,
};
...
...
drivers/input/touchscreen/mcs5000_ts.c
浏览文件 @
01c728a2
...
...
@@ -261,25 +261,27 @@ static int __devexit mcs5000_ts_remove(struct i2c_client *client)
}
#ifdef CONFIG_PM
static
int
mcs5000_ts_suspend
(
struct
i2c_client
*
client
,
pm_message_t
mesg
)
static
int
mcs5000_ts_suspend
(
struct
device
*
dev
)
{
struct
i2c_client
*
client
=
to_i2c_client
(
dev
);
/* Touch sleep mode */
i2c_smbus_write_byte_data
(
client
,
MCS5000_TS_OP_MODE
,
OP_MODE_SLEEP
);
return
0
;
}
static
int
mcs5000_ts_resume
(
struct
i2c_client
*
client
)
static
int
mcs5000_ts_resume
(
struct
device
*
dev
)
{
struct
i2c_client
*
client
=
to_i2c_client
(
dev
);
struct
mcs5000_ts_data
*
data
=
i2c_get_clientdata
(
client
);
mcs5000_ts_phys_init
(
data
);
return
0
;
}
#else
#define mcs5000_ts_suspend NULL
#define mcs5000_ts_resume NULL
static
SIMPLE_DEV_PM_OPS
(
mcs5000_ts_pm
,
mcs5000_ts_suspend
,
mcs5000_ts_resume
);
#endif
static
const
struct
i2c_device_id
mcs5000_ts_id
[]
=
{
...
...
@@ -291,10 +293,11 @@ MODULE_DEVICE_TABLE(i2c, mcs5000_ts_id);
static
struct
i2c_driver
mcs5000_ts_driver
=
{
.
probe
=
mcs5000_ts_probe
,
.
remove
=
__devexit_p
(
mcs5000_ts_remove
),
.
suspend
=
mcs5000_ts_suspend
,
.
resume
=
mcs5000_ts_resume
,
.
driver
=
{
.
name
=
"mcs5000_ts"
,
#ifdef CONFIG_PM
.
pm
=
&
mcs5000_ts_pm
,
#endif
},
.
id_table
=
mcs5000_ts_id
,
};
...
...
drivers/input/touchscreen/migor_ts.c
浏览文件 @
01c728a2
...
...
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/pm.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <linux/i2c.h>
...
...
@@ -226,8 +227,9 @@ static int migor_ts_remove(struct i2c_client *client)
return
0
;
}
static
int
migor_ts_suspend
(
struct
i2c_client
*
client
,
pm_message_t
mesg
)
static
int
migor_ts_suspend
(
struct
device
*
dev
)
{
struct
i2c_client
*
client
=
to_i2c_client
(
dev
);
struct
migor_ts_priv
*
priv
=
dev_get_drvdata
(
&
client
->
dev
);
if
(
device_may_wakeup
(
&
client
->
dev
))
...
...
@@ -236,8 +238,9 @@ static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg)
return
0
;
}
static
int
migor_ts_resume
(
struct
i2c_client
*
client
)
static
int
migor_ts_resume
(
struct
device
*
dev
)
{
struct
i2c_client
*
client
=
to_i2c_client
(
dev
);
struct
migor_ts_priv
*
priv
=
dev_get_drvdata
(
&
client
->
dev
);
if
(
device_may_wakeup
(
&
client
->
dev
))
...
...
@@ -246,6 +249,8 @@ static int migor_ts_resume(struct i2c_client *client)
return
0
;
}
static
SIMPLE_DEV_PM_OPS
(
migor_ts_pm
,
migor_ts_suspend
,
migor_ts_resume
);
static
const
struct
i2c_device_id
migor_ts_id
[]
=
{
{
"migor_ts"
,
0
},
{
}
...
...
@@ -255,11 +260,10 @@ MODULE_DEVICE_TABLE(i2c, migor_ts);
static
struct
i2c_driver
migor_ts_driver
=
{
.
driver
=
{
.
name
=
"migor_ts"
,
.
pm
=
&
migor_ts_pm
,
},
.
probe
=
migor_ts_probe
,
.
remove
=
migor_ts_remove
,
.
suspend
=
migor_ts_suspend
,
.
resume
=
migor_ts_resume
,
.
id_table
=
migor_ts_id
,
};
...
...
drivers/input/touchscreen/wacom_w8001.c
浏览文件 @
01c728a2
...
...
@@ -3,6 +3,7 @@
*
* Copyright (c) 2008 Jaya Kumar
* Copyright (c) 2010 Red Hat, Inc.
* Copyright (c) 2010 - 2011 Ping Cheng, Wacom. <pingc@wacom.com>
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
...
...
@@ -64,11 +65,11 @@ struct w8001_coord {
/* touch query reply packet */
struct
w8001_touch_query
{
u16
x
;
u16
y
;
u8
panel_res
;
u8
capacity_res
;
u8
sensor_id
;
u16
x
;
u16
y
;
};
/*
...
...
@@ -87,9 +88,14 @@ struct w8001 {
char
phys
[
32
];
int
type
;
unsigned
int
pktlen
;
u16
max_touch_x
;
u16
max_touch_y
;
u16
max_pen_x
;
u16
max_pen_y
;
char
name
[
64
];
};
static
void
parse_data
(
u8
*
data
,
struct
w8001_coord
*
coord
)
static
void
parse_
pen_
data
(
u8
*
data
,
struct
w8001_coord
*
coord
)
{
memset
(
coord
,
0
,
sizeof
(
*
coord
));
...
...
@@ -113,11 +119,30 @@ static void parse_data(u8 *data, struct w8001_coord *coord)
coord
->
tilt_y
=
data
[
8
]
&
0x7F
;
}
static
void
parse_touch
(
struct
w8001
*
w8001
)
static
void
parse_single_touch
(
u8
*
data
,
struct
w8001_coord
*
coord
)
{
coord
->
x
=
(
data
[
1
]
<<
7
)
|
data
[
2
];
coord
->
y
=
(
data
[
3
]
<<
7
)
|
data
[
4
];
coord
->
tsw
=
data
[
0
]
&
0x01
;
}
static
void
scale_touch_coordinates
(
struct
w8001
*
w8001
,
unsigned
int
*
x
,
unsigned
int
*
y
)
{
if
(
w8001
->
max_pen_x
&&
w8001
->
max_touch_x
)
*
x
=
*
x
*
w8001
->
max_pen_x
/
w8001
->
max_touch_x
;
if
(
w8001
->
max_pen_y
&&
w8001
->
max_touch_y
)
*
y
=
*
y
*
w8001
->
max_pen_y
/
w8001
->
max_touch_y
;
}
static
void
parse_multi_touch
(
struct
w8001
*
w8001
)
{
struct
input_dev
*
dev
=
w8001
->
dev
;
unsigned
char
*
data
=
w8001
->
data
;
unsigned
int
x
,
y
;
int
i
;
int
count
=
0
;
for
(
i
=
0
;
i
<
2
;
i
++
)
{
bool
touch
=
data
[
0
]
&
(
1
<<
i
);
...
...
@@ -125,15 +150,29 @@ static void parse_touch(struct w8001 *w8001)
input_mt_slot
(
dev
,
i
);
input_mt_report_slot_state
(
dev
,
MT_TOOL_FINGER
,
touch
);
if
(
touch
)
{
int
x
=
(
data
[
6
*
i
+
1
]
<<
7
)
|
(
data
[
6
*
i
+
2
])
;
int
y
=
(
data
[
6
*
i
+
3
]
<<
7
)
|
(
data
[
6
*
i
+
4
])
;
x
=
(
data
[
6
*
i
+
1
]
<<
7
)
|
data
[
6
*
i
+
2
]
;
y
=
(
data
[
6
*
i
+
3
]
<<
7
)
|
data
[
6
*
i
+
4
]
;
/* data[5,6] and [11,12] is finger capacity */
/* scale to pen maximum */
scale_touch_coordinates
(
w8001
,
&
x
,
&
y
);
input_report_abs
(
dev
,
ABS_MT_POSITION_X
,
x
);
input_report_abs
(
dev
,
ABS_MT_POSITION_Y
,
y
);
count
++
;
}
}
/* emulate single touch events when stylus is out of proximity.
* This is to make single touch backward support consistent
* across all Wacom single touch devices.
*/
if
(
w8001
->
type
!=
BTN_TOOL_PEN
&&
w8001
->
type
!=
BTN_TOOL_RUBBER
)
{
w8001
->
type
=
count
==
1
?
BTN_TOOL_FINGER
:
KEY_RESERVED
;
input_mt_report_pointer_emulation
(
dev
,
true
);
}
input_sync
(
dev
);
}
...
...
@@ -152,6 +191,15 @@ static void parse_touchquery(u8 *data, struct w8001_touch_query *query)
query
->
y
=
data
[
5
]
<<
9
;
query
->
y
|=
data
[
6
]
<<
2
;
query
->
y
|=
(
data
[
2
]
>>
3
)
&
0x3
;
/* Early days' single-finger touch models need the following defaults */
if
(
!
query
->
x
&&
!
query
->
y
)
{
query
->
x
=
1024
;
query
->
y
=
1024
;
if
(
query
->
panel_res
)
query
->
x
=
query
->
y
=
(
1
<<
query
->
panel_res
);
query
->
panel_res
=
10
;
}
}
static
void
report_pen_events
(
struct
w8001
*
w8001
,
struct
w8001_coord
*
coord
)
...
...
@@ -161,16 +209,15 @@ static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord)
/*
* We have 1 bit for proximity (rdy) and 3 bits for tip, side,
* side2/eraser. If rdy && f2 are set, this can be either pen + side2,
* or eraser.
assume
* or eraser.
Assume:
* - if dev is already in proximity and f2 is toggled → pen + side2
* - if dev comes into proximity with f2 set → eraser
* If f2 disappears after assuming eraser, fake proximity out for
* eraser and in for pen.
*/
if
(
!
w8001
->
type
)
{
w8001
->
type
=
coord
->
f2
?
BTN_TOOL_RUBBER
:
BTN_TOOL_PEN
;
}
else
if
(
w8001
->
type
==
BTN_TOOL_RUBBER
)
{
switch
(
w8001
->
type
)
{
case
BTN_TOOL_RUBBER
:
if
(
!
coord
->
f2
)
{
input_report_abs
(
dev
,
ABS_PRESSURE
,
0
);
input_report_key
(
dev
,
BTN_TOUCH
,
0
);
...
...
@@ -180,8 +227,21 @@ static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord)
input_sync
(
dev
);
w8001
->
type
=
BTN_TOOL_PEN
;
}
}
else
{
break
;
case
BTN_TOOL_FINGER
:
input_report_key
(
dev
,
BTN_TOUCH
,
0
);
input_report_key
(
dev
,
BTN_TOOL_FINGER
,
0
);
input_sync
(
dev
);
/* fall through */
case
KEY_RESERVED
:
w8001
->
type
=
coord
->
f2
?
BTN_TOOL_RUBBER
:
BTN_TOOL_PEN
;
break
;
default:
input_report_key
(
dev
,
BTN_STYLUS2
,
coord
->
f2
);
break
;
}
input_report_abs
(
dev
,
ABS_X
,
coord
->
x
);
...
...
@@ -193,7 +253,26 @@ static void report_pen_events(struct w8001 *w8001, struct w8001_coord *coord)
input_sync
(
dev
);
if
(
!
coord
->
rdy
)
w8001
->
type
=
0
;
w8001
->
type
=
KEY_RESERVED
;
}
static
void
report_single_touch
(
struct
w8001
*
w8001
,
struct
w8001_coord
*
coord
)
{
struct
input_dev
*
dev
=
w8001
->
dev
;
unsigned
int
x
=
coord
->
x
;
unsigned
int
y
=
coord
->
y
;
/* scale to pen maximum */
scale_touch_coordinates
(
w8001
,
&
x
,
&
y
);
input_report_abs
(
dev
,
ABS_X
,
x
);
input_report_abs
(
dev
,
ABS_Y
,
y
);
input_report_key
(
dev
,
BTN_TOUCH
,
coord
->
tsw
);
input_report_key
(
dev
,
BTN_TOOL_FINGER
,
coord
->
tsw
);
input_sync
(
dev
);
w8001
->
type
=
coord
->
tsw
?
BTN_TOOL_FINGER
:
KEY_RESERVED
;
}
static
irqreturn_t
w8001_interrupt
(
struct
serio
*
serio
,
...
...
@@ -214,9 +293,18 @@ static irqreturn_t w8001_interrupt(struct serio *serio,
case
W8001_PKTLEN_TOUCH93
-
1
:
case
W8001_PKTLEN_TOUCH9A
-
1
:
/* ignore one-finger touch packet. */
if
(
w8001
->
pktlen
==
w8001
->
idx
)
tmp
=
w8001
->
data
[
0
]
&
W8001_TOUCH_BYTE
;
if
(
tmp
!=
W8001_TOUCH_BYTE
)
break
;
if
(
w8001
->
pktlen
==
w8001
->
idx
)
{
w8001
->
idx
=
0
;
if
(
w8001
->
type
!=
BTN_TOOL_PEN
&&
w8001
->
type
!=
BTN_TOOL_RUBBER
)
{
parse_single_touch
(
w8001
->
data
,
&
coord
);
report_single_touch
(
w8001
,
&
coord
);
}
}
break
;
/* Pen coordinates packet */
...
...
@@ -225,18 +313,18 @@ static irqreturn_t w8001_interrupt(struct serio *serio,
if
(
unlikely
(
tmp
==
W8001_TAB_BYTE
))
break
;
tmp
=
(
w8001
->
data
[
0
]
&
W8001_TOUCH_BYTE
)
;
tmp
=
w8001
->
data
[
0
]
&
W8001_TOUCH_BYTE
;
if
(
tmp
==
W8001_TOUCH_BYTE
)
break
;
w8001
->
idx
=
0
;
parse_data
(
w8001
->
data
,
&
coord
);
parse_
pen_
data
(
w8001
->
data
,
&
coord
);
report_pen_events
(
w8001
,
&
coord
);
break
;
/* control packet */
case
W8001_PKTLEN_TPCCTL
-
1
:
tmp
=
(
w8001
->
data
[
0
]
&
W8001_TOUCH_MASK
)
;
tmp
=
w8001
->
data
[
0
]
&
W8001_TOUCH_MASK
;
if
(
tmp
==
W8001_TOUCH_BYTE
)
break
;
...
...
@@ -249,7 +337,7 @@ static irqreturn_t w8001_interrupt(struct serio *serio,
/* 2 finger touch packet */
case
W8001_PKTLEN_TOUCH2FG
-
1
:
w8001
->
idx
=
0
;
parse_touch
(
w8001
);
parse_
multi_
touch
(
w8001
);
break
;
}
...
...
@@ -279,6 +367,7 @@ static int w8001_setup(struct w8001 *w8001)
{
struct
input_dev
*
dev
=
w8001
->
dev
;
struct
w8001_coord
coord
;
struct
w8001_touch_query
touch
;
int
error
;
error
=
w8001_command
(
w8001
,
W8001_CMD_STOP
,
false
);
...
...
@@ -287,14 +376,21 @@ static int w8001_setup(struct w8001 *w8001)
msleep
(
250
);
/* wait 250ms before querying the device */
dev
->
evbit
[
0
]
=
BIT_MASK
(
EV_KEY
)
|
BIT_MASK
(
EV_ABS
);
strlcat
(
w8001
->
name
,
"Wacom Serial"
,
sizeof
(
w8001
->
name
));
/* penabled? */
error
=
w8001_command
(
w8001
,
W8001_CMD_QUERY
,
true
);
if
(
!
error
)
{
__set_bit
(
BTN_TOUCH
,
dev
->
keybit
);
__set_bit
(
BTN_TOOL_PEN
,
dev
->
keybit
);
__set_bit
(
BTN_TOOL_RUBBER
,
dev
->
keybit
);
__set_bit
(
BTN_STYLUS
,
dev
->
keybit
);
__set_bit
(
BTN_STYLUS2
,
dev
->
keybit
);
parse_data
(
w8001
->
response
,
&
coord
);
parse_pen_data
(
w8001
->
response
,
&
coord
);
w8001
->
max_pen_x
=
coord
.
x
;
w8001
->
max_pen_y
=
coord
.
y
;
input_set_abs_params
(
dev
,
ABS_X
,
0
,
coord
.
x
,
0
,
0
);
input_set_abs_params
(
dev
,
ABS_Y
,
0
,
coord
.
y
,
0
,
0
);
...
...
@@ -303,6 +399,8 @@ static int w8001_setup(struct w8001 *w8001)
input_set_abs_params
(
dev
,
ABS_TILT_X
,
0
,
coord
.
tilt_x
,
0
,
0
);
input_set_abs_params
(
dev
,
ABS_TILT_Y
,
0
,
coord
.
tilt_y
,
0
,
0
);
}
w8001
->
id
=
0x90
;
strlcat
(
w8001
->
name
,
" Penabled"
,
sizeof
(
w8001
->
name
));
}
/* Touch enabled? */
...
...
@@ -313,24 +411,38 @@ static int w8001_setup(struct w8001 *w8001)
* second byte is empty, which indicates touch is not supported.
*/
if
(
!
error
&&
w8001
->
response
[
1
])
{
struct
w8001_touch_query
touch
;
__set_bit
(
BTN_TOUCH
,
dev
->
keybit
);
__set_bit
(
BTN_TOOL_FINGER
,
dev
->
keybit
);
parse_touchquery
(
w8001
->
response
,
&
touch
);
w8001
->
max_touch_x
=
touch
.
x
;
w8001
->
max_touch_y
=
touch
.
y
;
/* scale to pen maximum */
if
(
w8001
->
max_pen_x
&&
w8001
->
max_pen_y
)
{
touch
.
x
=
w8001
->
max_pen_x
;
touch
.
y
=
w8001
->
max_pen_y
;
}
input_set_abs_params
(
dev
,
ABS_X
,
0
,
touch
.
x
,
0
,
0
);
input_set_abs_params
(
dev
,
ABS_Y
,
0
,
touch
.
y
,
0
,
0
);
__set_bit
(
BTN_TOOL_FINGER
,
dev
->
keybit
);
switch
(
touch
.
sensor_id
)
{
case
0
:
case
2
:
w8001
->
pktlen
=
W8001_PKTLEN_TOUCH93
;
w8001
->
id
=
0x93
;
strlcat
(
w8001
->
name
,
" 1FG"
,
sizeof
(
w8001
->
name
));
break
;
case
1
:
case
3
:
case
4
:
w8001
->
pktlen
=
W8001_PKTLEN_TOUCH9A
;
strlcat
(
w8001
->
name
,
" 1FG"
,
sizeof
(
w8001
->
name
));
w8001
->
id
=
0x9a
;
break
;
case
5
:
w8001
->
pktlen
=
W8001_PKTLEN_TOUCH2FG
;
...
...
@@ -341,10 +453,18 @@ static int w8001_setup(struct w8001 *w8001)
0
,
touch
.
y
,
0
,
0
);
input_set_abs_params
(
dev
,
ABS_MT_TOOL_TYPE
,
0
,
MT_TOOL_MAX
,
0
,
0
);
strlcat
(
w8001
->
name
,
" 2FG"
,
sizeof
(
w8001
->
name
));
if
(
w8001
->
max_pen_x
&&
w8001
->
max_pen_y
)
w8001
->
id
=
0xE3
;
else
w8001
->
id
=
0xE2
;
break
;
}
}
strlcat
(
w8001
->
name
,
" Touchscreen"
,
sizeof
(
w8001
->
name
));
return
w8001_command
(
w8001
,
W8001_CMD_START
,
false
);
}
...
...
@@ -384,22 +504,10 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
}
w8001
->
serio
=
serio
;
w8001
->
id
=
serio
->
id
.
id
;
w8001
->
dev
=
input_dev
;
init_completion
(
&
w8001
->
cmd_done
);
snprintf
(
w8001
->
phys
,
sizeof
(
w8001
->
phys
),
"%s/input0"
,
serio
->
phys
);
input_dev
->
name
=
"Wacom W8001 Penabled Serial TouchScreen"
;
input_dev
->
phys
=
w8001
->
phys
;
input_dev
->
id
.
bustype
=
BUS_RS232
;
input_dev
->
id
.
vendor
=
SERIO_W8001
;
input_dev
->
id
.
product
=
w8001
->
id
;
input_dev
->
id
.
version
=
0x0100
;
input_dev
->
dev
.
parent
=
&
serio
->
dev
;
input_dev
->
evbit
[
0
]
=
BIT_MASK
(
EV_KEY
)
|
BIT_MASK
(
EV_ABS
);
__set_bit
(
BTN_TOUCH
,
input_dev
->
keybit
);
serio_set_drvdata
(
serio
,
w8001
);
err
=
serio_open
(
serio
,
drv
);
if
(
err
)
...
...
@@ -409,6 +517,14 @@ static int w8001_connect(struct serio *serio, struct serio_driver *drv)
if
(
err
)
goto
fail3
;
input_dev
->
name
=
w8001
->
name
;
input_dev
->
phys
=
w8001
->
phys
;
input_dev
->
id
.
product
=
w8001
->
id
;
input_dev
->
id
.
bustype
=
BUS_RS232
;
input_dev
->
id
.
vendor
=
0x056a
;
input_dev
->
id
.
version
=
0x0100
;
input_dev
->
dev
.
parent
=
&
serio
->
dev
;
err
=
input_register_device
(
w8001
->
dev
);
if
(
err
)
goto
fail3
;
...
...
include/linux/input.h
浏览文件 @
01c728a2
...
...
@@ -800,6 +800,7 @@ struct input_keymap_entry {
#define SW_CAMERA_LENS_COVER 0x09
/* set = lens covered */
#define SW_KEYPAD_SLIDE 0x0a
/* set = keypad slide out */
#define SW_FRONT_PROXIMITY 0x0b
/* set = front proximity sensor active */
#define SW_ROTATE_LOCK 0x0c
/* set = rotate locked/disabled */
#define SW_MAX 0x0f
#define SW_CNT (SW_MAX+1)
...
...
include/linux/input/as5011.h
0 → 100644
浏览文件 @
01c728a2
#ifndef _AS5011_H
#define _AS5011_H
/*
* Copyright (c) 2010, 2011 Fabien Marteau <fabien.marteau@armadeus.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*/
struct
as5011_platform_data
{
unsigned
int
button_gpio
;
unsigned
int
axis_irq
;
/* irq number */
unsigned
long
axis_irqflags
;
char
xp
,
xn
;
/* threshold for x axis */
char
yp
,
yn
;
/* threshold for y axis */
};
#endif
/* _AS5011_H */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录