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 ...
随机推荐
- phpstudy配置SSL证书的步骤(Apache环境)以及一些注意事项
准备工具(我自己的): 腾讯云的域名和云主机,还有SSL证书,以及phpstudy 首先要下载自己的SSL证书,会得到一个压缩包,解压以后会得到四个文件夹和一个csr文件, Apache文件夹内三个文 ...
- python3 练习题100例 (十五)
这个比较难,主要难在考虑的问题太多,有好几个还没写出来.有空再来改进.请高手指教! #!/usr/bin/env python3 # -*- coding: utf-8 -*- __author__ ...
- Codeforces Round #460 (Div. 2)-B. Perfect Number
B. Perfect Number time limit per test2 seconds memory limit per test256 megabytes Problem Descriptio ...
- PAT basic 1086
1086 就不告诉你 (15 分) 做作业的时候,邻座的小盆友问你:“五乘以七等于多少?”你应该不失礼貌地围笑着告诉他:“五十三.”本题就要求你,对任何一对给定的正整数,倒着输出它们的乘积. 输入格式 ...
- UVa 1455 Kingdom 线段树 并查集
题意: 平面上有\(n\)个点,有一种操作和一种查询: \(road \, A \, B\):在\(a\),\(b\)两点之间加一条边 \(line C\):询问直线\(y=C\)经过的连通分量的个数 ...
- js中基础数据类型
变量声明 undefined //未定义只声明 var age; alert(name);function fc(a1,a2,a3) { //alert(a1); //alert(a2); //a ...
- AppDOMain(摘录)
AppDomain是CLR的运行单元,它可以加载Assembly.创建对象以及执行程序. AppDomain是CLR实现 代码隔离 的基本机制. 每一个AppDomain可以单独运行.停止:每个App ...
- Windows核心编程小结3
内存映射和堆栈 内存映射文件 内存映射文件可以用于3个不同的目的: 系统使用内存映射文件,以便加载和执行.exe和DLL文件.这可以大大节省页文件空间和应用程序启动运行所需的时间. 可以使用内存映射文 ...
- load_file()与into outfile函数详解
load_file()函数的使用: 1.使用条件 ①有读取文件的权限 r and (select count(*) from mysql.user)>0 如果返回正常则说明有权限,反之没有 ②文 ...
- Python+Selenium练习篇之3-利用tag name定位元素
前一篇文章介绍了如何通过元素的id值来定位web元素,本文介绍如何通过tag name来定位元素.个人认为,通过tag name来定位还是有很大缺陷,定位不够精确.主要是tag name有很多重复的, ...