input上报流程分析【转】
转自:http://blog.chinaunix.net/uid-28320320-id-3389196.html
、参考文章
【Andorid】input系统的事件处理 、源码分析 linux 3.6.
)查看linux-3.6./drivers/input下Makefile 点击(此处)折叠或打开 obj-$(CONFIG_INPUT) += input-core.o
input-core-y := input.o input-compat.o input-mt.o ff-core.o )查看文件input.c 点击(此处)折叠或打开 /* input subsystem entry */
subsys_initcall(input_init);
module_exit(input_exit); )input.c搞啥子 点击(此处)折叠或打开 /* sysfs/procfs/devfs show */
|-----------|
| \/
| err = class_register(&input_class);
|
|-----------|
| \/
| err = input_proc_init();
|
|-----------|
| \/
| err = register_chrdev(INPUT_MAJOR, "input", &input_fops); 根据下面的方法,发现手机的tp 对应event1 点击(此处)折叠或打开 # getevent
add device : /dev/input/event0
name: "fluid-keypad"
add device : /dev/input/event3
name: "7k_handset"
add device : /dev/input/event2
name: "sensors"
add device : /dev/input/event1
name: "Synaptics RMI4" # pwd
/sys/class/input
# ls
event0 event1 event2 event3 input0 input1 input2 input3 # cat /proc/bus/input/devices
I: Bus= Vendor= Product= Version=
N: Name="fluid-keypad"
P: Phys=fluid-keypad/input0
S: Sysfs=/devices/i2c-/-/pm8058-keypad/input/input0
U: Uniq=
H: Handlers=kbd event0
B: EV=
B: KEY= c0000
B: MSC= I: Bus= Vendor= Product= Version=
N: Name="Synaptics RMI4"
P: Phys=Synaptics_rmi
S: Sysfs=/devices/virtual/input/input1
U: Uniq=
H: Handlers=event1
B: EV=b
B: KEY=
B: ABS= I: Bus= Vendor= Product= Version=
N: Name="sensors"
P: Phys=
S: Sysfs=/devices/virtual/input/input2
U: Uniq=
H: Handlers=event2
B: EV=
B: ABS= 20304bf I: Bus= Vendor= Product= Version=
N: Name="7k_handset"
P: Phys=
S: Sysfs=/devices/virtual/input/input3
U: Uniq=
H: Handlers=kbd event3
B: EV=
B: KEY= 1c0800
B: SW= )touch panel驱动源码 点击(此处)折叠或打开 #include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/input.h> #include "gsl1680.h" #define gsl_pr(fmt, arg...) \
printk(KERN_ERR "[GSL]%s: \033[32m" fmt "\033[0m\n", __FUNCTION__, ##arg) #define GSL_ADAPTER_INDEX 0
#define GSL1680D0_ID 0
#define GSL_DEV_NAME "gsl" /**
* Description : global var
*/
static struct gsl_ts_data *ddata = NULL;
static const struct i2c_device_id gsl_id[] = {
{GSL_DEV_NAME, GSL1680D0_ID},
{},
};
MODULE_DEVICE_TABLE(silead, gsl_id); static struct i2c_board_info gsl_i2c_info = {
.type = GSL_DEV_NAME,
.addr = 0x40,
}; /**
* Description : gsl soc operation
*/
static int gsl_hw_init(void)
{
return ;
} static int gsl_sw_init(void)
{
return ;
} /**
* Description : touch panel driver
*/
static void gsl_report_work(struct work_struct *work)
{
} static int gsl_request_input(void)
{
int ret = ; ddata->idev = input_allocate_device();
if (!ddata->idev) {
dev_err(&ddata->idev->dev, "could not allocate device\n");
return -ENODEV;
} ddata->idev->name = GSL_DEV_NAME;
ddata->idev->id.bustype = BUS_I2C;
ddata->idev->dev.parent = &ddata->client->dev;
input_set_drvdata(ddata->idev, ddata); __set_bit(EV_ABS, ddata->idev->evbit); input_set_abs_params(ddata->idev, ABS_MT_POSITION_X,
DIS_MIN_X, DIS_MAX_X, , );
input_set_abs_params(ddata->idev, ABS_MT_POSITION_Y,
DIS_MIN_Y, DIS_MAX_Y, , );
input_set_abs_params(ddata->idev, ABS_MT_TOUCH_MAJOR,
MIN_TOUCH, MAX_TOUCH, , );
input_set_abs_params(ddata->idev, ABS_MT_WIDTH_MAJOR,
MIN_WIDTH, MAX_WIDTH, , );
input_set_abs_params(ddata->idev, ABS_MT_TRACKING_ID,
MIN_TRCKID, MAX_TRCKID, , ); INIT_WORK(&ddata->work, gsl_report_work); ddata->wq = create_singlethread_workqueue(GSL_DEV_NAME);
if (!ddata->wq) {
dev_err(&ddata->idev->dev, "could not create workqueue\n");
ret = -ENOMEM;
goto error_wq_create;
}
#if 0
ddata->pm.suspend = gsl_suspend;
ddata->pm.resume = gsl_resume;
register_early_suspend(&ddata->pm);
#endif
ret = input_register_device(ddata->idev);
if (ret) {
dev_err(&ddata->idev->dev, "ret = %d : could not register input device\n", ret);
goto error_unreg_device;
}
return ; error_unreg_device:
destroy_workqueue(ddata->wq);
error_wq_create:
input_free_device(ddata->idev);
return ret;
} static __devinit int gsl_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int ret = ; gsl_pr(); ddata->ti = kzalloc(sizeof(union gsl_touch_info), GFP_KERNEL);
if (!ddata->ti) {
dev_err(&client->dev, "failed to alloc ddata->ti memory!\n");
ret = -ENOMEM;
goto error_alloc_mem;
} /* regist a input dev */
ret = gsl_request_input();
if (ret) {
dev_err(&client->dev, "failed to regist input dev!\n");
goto error_regist_input;
} /* setup the gpio -- irq & rst */
ret = gsl_hw_init();
if (ret) {
dev_err(&client->dev, "failed to init hw!\n");
goto error_init_hw;
} /* setup client data & download fw */
ret = gsl_sw_init();
if (ret) {
dev_err(&client->dev, "failed to init sw!\n");
goto error_init_sw;
} return ; error_init_sw:
error_init_hw:
destroy_workqueue(ddata->wq);
input_free_device(ddata->idev);
error_regist_input:
kfree(ddata->ti);
input_unregister_device(ddata->idev);
destroy_workqueue(ddata->wq);
input_free_device(ddata->idev);
error_alloc_mem:
kfree(ddata);
return ret;
} static __devexit int gsl_remove(struct i2c_client *client)
{
return ;
} static struct i2c_driver gsl_driver = {
.driver = {
.name = GSL_DEV_NAME,
.owner = THIS_MODULE,
},
.probe = gsl_probe,
.remove = gsl_remove,
.id_table = gsl_id,
}; /**
* Description : module operation
*/
static __init int gsl_init(void)
{
int ret = ;
struct i2c_adapter *adapter; gsl_pr(); ddata = kzalloc(sizeof(struct gsl_ts_data), GFP_KERNEL);
if (!ddata) {
gsl_pr("alloc mem error");
goto err_mem;
} /* tips : try_module_get */
adapter = i2c_get_adapter(GSL_ADAPTER_INDEX);
if (!(adapter)) {
gsl_pr("get %d adapter failed", GSL_ADAPTER_INDEX);
ret = -ENODEV;
goto err_adap;
} ddata->client = i2c_new_device(adapter, &gsl_i2c_info);
if (!(ddata->client)) {
gsl_pr("get i2c device error");
ret = -ENODEV;
goto err_dev;
} /* release the module */
i2c_put_adapter(adapter); ret = i2c_add_driver(&gsl_driver);
if (ret) {
gsl_pr("i2c add driver failed");
goto err_driver;
} return ; err_driver:
i2c_unregister_device(ddata->client);
i2c_put_adapter(adapter);
err_dev:
err_adap:
kfree(ddata);
err_mem:
return ret;
} static __exit void gsl_exit(void)
{
gsl_pr(); /* reverse effect of i2c_new_device() */
i2c_del_driver(&gsl_driver);
i2c_unregister_device(ddata->client);
kfree(ddata); return;
} module_init(gsl_init);
module_exit(gsl_exit); MODULE_LICENSE("GPL");
MODULE_AUTHOR("mark"); 点击(此处)折叠或打开 //touch coordinate range
#define TP_WIDTH 480
#define TP_LENTH 800 //coordinate direction
#define TP_DIREC 1 // if 1 is (1,1), then 2(1,-1), 3(-1,-1), 4(-1,1) //touch threshold
#define MAI_TRSD 200
#define SUB_TRSD 40
#define SUM_TRSD (MAI_TRSD + SUB_TRSD + 20) //touch tigger condition
#define TRIG_MOD 1 // 1 is edge, 0 is level
#define VOLT_LEV 0 // if trig mode is edge,
// 0 is IRQF_TRIGGER_RISING, 1 is IRQF_TRIGGER_FALLING
// if trig mode is level,
// 0 is IRQF_TRIGGER_HIGH, 1 is IRQF_TRIGGER_LOW //touch sensitivity
#define TP_DACG 0x00100010 //9f/30
#define DAC_STEP 0x8e //if TP_DACG=0x00180018,TP_DAC_STEP=0x61
//if TP_DACG=0x00100010,TP_DAC_STEP=0x8e
//if TP_DACG=0x000c000c,TP_DAC_STEP=0xbb
//if TP_DACG=0x000a000a,TP_DAC_STEP=0xdf
//if TP_DACG=0x00080008,TP_DAC_STEP=0x114
//if TP_DACG=0x00060006,TP_DAC_STEP=0x16e
#define CHANGE_CONDITION 0x0 //0--use average,1--use max #define GSL_PAGE_REG 0xf0
#define GSL_CLOCK_REG 0xe4
#define GSL_START_REG 0xe0
#define GSL_CLOCK_REG 0xe4
#define POWE_FAIL_REG 0xbc
#define TOUCH_INFO_REG 0x80 #define DIS_MIN_X 0
#define DIS_MAX_X TP_WIDTH
#define DIS_MIN_Y 0
#define DIS_MAX_Y TP_LENTH #define MIN_TOUCH 0
#define MAX_TOUCH 1
#define MIN_WIDTH 0
#define MAX_WIDTH 1
#define MIN_TRCKID 1
#define MAX_TRCKID 5 /* the data format of one point */
union gsl_point_data {
struct {
u16 y;
u16 x : ;
u16 id : ;
};
u8 all[];
}; /* the 24-byte data of read once */
union gsl_touch_info {
struct {
u32 finger_num : ;
u32 : ;
union gsl_point_data point[];
};
u8 all[];
}; struct gsl_ts_data {
union gsl_touch_info *ti;
struct i2c_client *client;
struct input_dev *idev;
struct workqueue_struct *wq;
struct work_struct work;
unsigned int irq;
}; /* Fixme mem Alig */
struct fw_data {
u32 offset : ;
u32 : ;
u32 val;
}; static const struct fw_data GSL1680_D0_FW[] = {
/* void */
{ },
}; )input_report_abs上报流程 点击(此处)折叠或打开 /* 观察linux-3.6.3/drivers/input/Kconfig, 对应/dev/input/eventX */
config INPUT_EVDEV
tristate "Event interface"
help
Say Y here if you want your input device events be accessible
under char device :+ - /dev/input/eventX in a generic way. To compile this driver as a module, choose M here: the
module will be called evdev. android 4.0 一般报点序列: 点击(此处)折叠或打开 input_mt_slot(ts->input, id);
input_report_abs(ts->input, ABS_MT_TRACKING_ID, id);
input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, );
input_report_abs(ts->input, ABS_MT_POSITION_X, x);
input_report_abs(ts->input, ABS_MT_POSITION_Y, y);
input_report_abs(ts->input, ABS_MT_WIDTH_MAJOR, );
input_mt_sync(ts->input); 点击(此处)折叠或打开 input_sync(ts->input); input_handle_event(dev, type, code, value)上报流程: 点击(此处)折叠或打开 ...
switch (type) { case EV_SYN:
switch (code) {
...
case SYN_REPORT:
if (!dev->sync) {
dev->sync = true;
disposition = INPUT_PASS_TO_HANDLERS;
}
break;
case SYN_MT_REPORT:
dev->sync = false;
disposition = INPUT_PASS_TO_HANDLERS;
break;
}
break; case EV_KEY:
if (is_event_supported(code, dev->keybit, KEY_MAX) &&
!!test_bit(code, dev->key) != value) { if (value != ) {
__change_bit(code, dev->key);
if (value)
input_start_autorepeat(dev, code);
else
input_stop_autorepeat(dev);
} disposition = INPUT_PASS_TO_HANDLERS;
}
break;
...
case EV_ABS:
if (is_event_supported(code, dev->absbit, ABS_MAX))
disposition = input_handle_abs_event(dev, code, &value); break;
...
} ...
if (disposition & INPUT_PASS_TO_HANDLERS)
input_pass_event(dev, type, code, value); 点击(此处)折叠或打开 static void input_pass_event(struct input_dev *dev,
unsigned int type, unsigned int code, int value)
{
struct input_handler *handler;
struct input_handle *handle; rcu_read_lock(); /* 获得一个被RCU保护的指针 */
handle = rcu_dereference(dev->grab);
/* (1) 如果是设备专有handle, 仅将事件传给该handler. */
if (handle)
handle->handler->event(handle, type, code, value);
else {
bool filtered = false; /* (2)遍历与此设备连接的每一个handle. */
list_for_each_entry_rcu(handle, &dev->h_list, d_node) {
/* (3)如果hnadle已经被打开. */
if (!handle->open)
continue; handler = handle->handler;
if (!handler->filter) {
if (filtered)
break;
/* (4)将事件分发给handler的事件处理函数. */
handler->event(handle, type, code, value); } else if (handler->filter(handle, type, code, value))
filtered = true;
}
} rcu_read_unlock();
} 附上android .0上报方式(linux必须2..38以上) 点击(此处)折叠或打开 #include <linux/input/mt.h> 点击(此处)折叠或打开 //down
input_mt_slot(ts->input_dev, id);
//input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, id);
input_mt_report_slot_state(data->input_dev, MT_TOOL_FINGER, true);
input_report_abs(ts->input_dev, ABS_MT_TOUCH_MAJOR, w);
input_report_abs(ts->input_dev, ABS_MT_POSITION_X, x);
input_report_abs(ts->input_dev, ABS_MT_POSITION_Y, y); 点击(此处)折叠或打开 //up
input_mt_slot(ts->input_dev, id);
//input_report_abs(ts->input_dev, ABS_MT_TRACKING_ID, -1);
input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, false); 点击(此处)折叠或打开 //init
//__set_bit(INPUT_PROP_DIRECT, ts->input_dev->propbit);
input_mt_init_slots(ts->input_dev, );
input上报流程分析【转】的更多相关文章
- Linux input系统数据上报流程【转】
转自:https://segmentfault.com/a/1190000017255939 作为鸡生蛋系列文章,这里主要关注Linux input系统,主要为触摸事件上报流程. 读该文章最好有对li ...
- Hogp连接流程分析
当BLE设备已经完成配对,并且完成GATT服务的搜索,下一步就开始profile 的连接流程了,一般LE设备都是走的HOGP的流程,我们这篇文章就分析一下hogp的连接流程. 连接是从framewor ...
- thttpd和cgilua安装与运行流程分析
安装 参考如下博文安装thttpd软件 http://blog.csdn.net/21aspnet/article/details/7045845 http://blog.csdn.net/drago ...
- Android7.0 Phone应用源码分析(一) phone拨号流程分析
1.1 dialer拨号 拨号盘点击拨号DialpadFragment的onClick方法会被调用 public void onClick(View view) { int resId = view. ...
- Android 4.4KitKat AudioRecord 流程分析
Android是架构分为三层: 底层 Linux Kernel 中间层 主要由C++实现 (Android 60%源码都是C++实现) 应用层 主要由JAVA开发的应用程序 应用程序执行 ...
- HDFS2.x之RPC流程分析
HDFS2.x之RPC流程分析 1 概述 Hadoop提供了一个统一的RPC机制来处理client-namenode, namenode-dataname,client-dataname之间的通信.R ...
- hadoop运行流程分析源代码级
前言: 最近一直在分析hadoop的运行流程,我们查阅了大量的资料,虽然从感性上对这个流程有了一个认识但是我总是感觉对mapreduce的运行还是没有一个全面的认识,所以决定从源代码级别对mapred ...
- openstack之nova-api服务流程分析
nova-api公布api服务没实用到一个些框架,基本都是从头写的.在不了解它时,以为它很复杂,难以掌握.花了两三天的时间把它分析一遍后,发现它本身的结构比較简单,主要难点在于对它所使用的一些类库不了 ...
- Android7.0 Phone应用源码分析(四) phone挂断流程分析
电话挂断分为本地挂断和远程挂断,下面我们就针对这两种情况各做分析 先来看下本地挂断电话的时序图: 步骤1:点击通话界面的挂断按钮,会调用到CallCardPresenter的endCallClicke ...
随机推荐
- 【jenkins】jenkins服务器与svn服务器时间不一致出现的问题
问题描述: svn提交了一次更新包,到了jenkins提交更新的时候,第一次代码没有生效,然后重新提交了一次,第二次才生效. 问题排查: 1.首先第一反应比对了下两次更新的包文件是否一致,然后发现大小 ...
- thinkphp 3.2.3 - Think.class.php 解析
class Think { public static function start() { // 注册AUTOLOAD方法 spl_autoload_register('Think\Think::a ...
- GoF23种设计模式之创建型模式之抽象工厂模式
一.概述 提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 二.适用性 1.一个系统要独立于它的产品的创建.组合和表示的时候. 2.一个系统要由多个产品系列中的一个来配置的时候. ...
- 离线安装 Visual Studio Express 而不下载整个镜像文件的方法(转载)
转 visual studio 2010 express 全序列号 phone开发工具YDK44-2WW9W-QV7PM-8P8G8-FTYDF VC# 2010 Express: PQT8W-68Y ...
- HDU 6053 ( TrickGCD ) 分块+容斥
TrickGCD Time Limit: 5000/2500 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
- Codeforces Round #460 (Div. 2)-B. Perfect Number
B. Perfect Number time limit per test2 seconds memory limit per test256 megabytes Problem Descriptio ...
- 动态规划(入门,滚动数组,记录的都是状态):SWUSTACM-1010 魔兽争霸之最后的反击
题目: 1010: 魔兽争霸之最后的反击 Time Li ...
- 在MAC下使用Robotframework+Selenium2【第一枪】robotframework安装步骤
最近使用苹果的MAC Pro本本,感受着苹果系统的新鲜,确实让我手忙脚乱一阵,毕竟使用windows系统太长时间了,刚开始用MAC Pro确实感觉别扭,用了一段,发现MAC系统还不错,好了,转入正题. ...
- 读书笔记jvm探秘之一:内存概况
jvm内存大致可以分为六大块: 堆,虚拟机主要内存,可以形象的说,堆是对象的存储库,几乎所有的对象实例和数组都在此分配内存,当然也死于此,jvm垃圾回收机制(简称GC)主要处理的就是这个地方.它被所有 ...
- OpenCV学习笔记(五) 文件存取
转自输入输出XML和YAML文件 To be filled