input上报流程分析【转】

 2023-09-05 阅读 279 评论 0

摘要:转自:http://blog.chinaunix.net/uid-28320320-id-3389196.html 1、参考文章【Andorid】input系统的事件处理2、源码分析 linux 3.6.31)查看linux-3.6.3/drivers/input下Makefile点击(此处)折叠或打开obj-$(CONFIG_INPUT) += input-core.oinput-core-y :=

转自:http://blog.chinaunix.net/uid-28320320-id-3389196.html

1、参考文章【Andorid】input系统的事件处理2、源码分析 linux 3.6.31)查看linux-3.6.3/drivers/input下Makefile点击(此处)折叠或打开obj-$(CONFIG_INPUT) += input-core.oinput-core-y := input.o input-compat.o input-mt.o ff-core.o2)查看文件input.c点击(此处)折叠或打开/* input subsystem entry */subsys_initcall(input_init);module_exit(input_exit);3)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 1: /dev/input/event0name: "fluid-keypad"add device 2: /dev/input/event3name: "7k_handset"add device 3: /dev/input/event2name: "sensors"add device 4: /dev/input/event1name: "Synaptics RMI4"# pwd/sys/class/input# lsevent0 event1 event2 event3 input0 input1 input2 input3# cat /proc/bus/input/devicesI: Bus=0019 Vendor=0001 Product=0001 Version=0001N: Name="fluid-keypad"P: Phys=fluid-keypad/input0S: Sysfs=/devices/i2c-6/6-0000/pm8058-keypad/input/input0U: Uniq=H: Handlers=kbd event0B: EV=13B: KEY=1200000 0 0 c0000 0 0 0B: MSC=10I: Bus=0000 Vendor=0000 Product=0000 Version=0000N: Name="Synaptics RMI4"P: Phys=Synaptics_rmiS: Sysfs=/devices/virtual/input/input1U: Uniq=H: Handlers=event1B: EV=bB: KEY=400 0 0 0 2000000 0 40000800 40 0 0 0B: ABS=770000 11030003I: Bus=0018 Vendor=0003 Product=0000 Version=0000N: Name="sensors"P: Phys=S: Sysfs=/devices/virtual/input/input2U: Uniq=H: Handlers=event2B: EV=9B: ABS=8000 20304bfI: Bus=0000 Vendor=0001 Product=0001 Version=0001N: Name="7k_handset"P: Phys=S: Sysfs=/devices/virtual/input/input3U: Uniq=H: Handlers=kbd event3B: EV=23B: KEY=4 0 28 0 1c0800 0 0 0B: SW=44)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 0;}static int gsl_sw_init(void){return 0;}/*** Description : touch panel driver*/static void gsl_report_work(struct work_struct *work){}static int gsl_request_input(void){int ret = 0;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, 0, 0);input_set_abs_params(ddata->idev, ABS_MT_POSITION_Y,DIS_MIN_Y, DIS_MAX_Y, 0, 0);input_set_abs_params(ddata->idev, ABS_MT_TOUCH_MAJOR,MIN_TOUCH, MAX_TOUCH, 0, 0);input_set_abs_params(ddata->idev, ABS_MT_WIDTH_MAJOR,MIN_WIDTH, MAX_WIDTH, 0, 0);input_set_abs_params(ddata->idev, ABS_MT_TRACKING_ID,MIN_TRCKID, MAX_TRCKID, 0, 0);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 0ddata->pm.suspend = gsl_suspend;ddata->pm.resume = gsl_resume;register_early_suspend(&ddata->pm);#endifret = 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 0;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 = 0;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 0;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 0;}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 = 0;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 0;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 : 12;u16 id : 4;};u8 all[4];};/* the 24-byte data of read once */union gsl_touch_info {struct {u32 finger_num : 8;u32 : 0;union gsl_point_data point[5];};u8 all[24];};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 : 8;u32 : 0;u32 val;};static const struct fw_data GSL1680_D0_FW[] = {/* void */{ },};5)input_report_abs上报流程点击(此处)折叠或打开/* 观察linux-3.6.3/drivers/input/Kconfig, 对应/dev/input/eventX */config INPUT_EVDEVtristate "Event interface"helpSay Y here if you want your input device events be accessibleunder char device 13:64+ - /dev/input/eventX in a generic way.To compile this driver as a module, choose M here: themodule 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, 1);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, 1);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 != 2) {__change_bit(code, dev->key);if (value)input_start_autorepeat(dev, code);elseinput_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 4.0上报方式(linux必须2.6.38以上)点击(此处)折叠或打开#include <linux/input/mt.h>点击(此处)折叠或打开//downinput_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);点击(此处)折叠或打开//upinput_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, 255);

 

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/723.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息