android下触摸屏驱动实现
- 格式:doc
- 大小:46.00 KB
- 文档页数:7
最近学习了电容触摸屏的驱动及其上层工作原理,拿出来和大家分享!转]Android触摸屏校准程序的实现一,校准的触摸算法如下:触摸屏校准通用方法。
(XL, YL是显示屏坐标,XT, YT是触摸屏坐标,)XL = XT*A+YT*B+CYL = XT*D+YT*E+F由于具体计算是希望是整数运算,所以实际中保存的ABCDEF为整数,而增加一个参数Div XL = (XT*A+YT*B+C) / DivYL = (YT*D+YT*E+F) / DivTSLIB把以上的7个参数ABCDEF Div 保存在pointercal 文件中。
不校准的数据:A=1, B=0, C=0, D=0, E=1, F=0, Div=1A B C D E F Div-411 37818 -3636780 -51325 39 47065584 65536二,Android 事件处理机制android 事件的传入是从EventHub开始的,EventHub是事件的抽象结构,维护着系统设备的运行情况(设备文件放在/dev/input里),设备类型包括Keyboard、TouchScreen、TraceBall。
它在系统启动的时候会通过open_device方法将系统提供的输入设备都增加到这个抽象结构中,并维护一个所有输入设备的文件描述符,如果输入设备是键盘的话还会读取/system/usr/keylayout/目录下对应键盘设备的映射文件(修改./development/emulator/keymaps /qwerty.kl来改变键值的映射关系),另外getEvent方法是对EventHub中的设备文件描述符使用poll操作等侍驱动层事件的发生,如果发生的事件是键盘事件,则调用Map函数按照映射文件转换成相应的键值并将扫描码和键码返回给KeyInputQueue.frameworks/base/services/jni/com_android_server_KeyInputQueue.cpp根据事件的类型以及事件值进行判断处理,从而确定这个事件对应的设备状态是否发生了改变并相应的改变对这个设备的描述结构InputDevice。
研发部受控文件图号:ZAN1604-2标题:安卓操作系统添加多点触摸设备支持特性内核配置步骤部门:研发部版本:V2.0日期:2016年3月2日修改安卓源码目录Android\x.x\kernel\drivers\hid中的hid-ids.h头文件,添加如下定义:如图1所示:Fig 1 hid-ids.h 文件截图#define USB_VENDOR_ID_ZAAG_VID_V3V50xAAEC #define USB_DEVICE_ID_ZAAG_PID_V3V50xB0D0#define USB_VENDOR_ID_ZAAG_VID_V60xAAEC #define USB_DEVICE_ID_ZAAG_PID_V60x0820 #define USB_VENDOR_ID_ZAAG_HID_VID_V6 0xAAEC #define USB_DEVICE_ID_ZAAG_HID_PID_V60x0922 #define USB_VENDOR_ID_ZAAG_HID_VID_V7 0x202E #define USB_DEVICE_ID_ZAAG_HID_PID_V70x0006修改上述目录下的hid-multitouch.c中的mt_devices[]数组,如图2所示:Fig 2 hid-multitouch.c文件截图检查上述目录下的hid-core.c中的hid_have_special_driver[]数组,如图3所示:Fig 3 hid-core.c文件截图确认该数组中包括如图4中红框内所示的两个成员变量,如果没有,请添加完整:Fig 4 数组成员变量截图修改make menuconfig中的选项,把多点触摸驱动编译进内核:make menuconifgDevice DriversHID DevicesSpecial HID driversHID Multitouch panels如图5所示: Fig 5 make menuconfig 修改截图罗益峰研发部受控文件版本控制表。
触摸屏驱动原理
触摸屏驱动原理基于电容变化的测量原理。
触摸屏是由一层导电膜覆盖在玻璃或塑料表面上形成的,平常不产生电流。
当手指或其他物体触摸到屏幕上时,触摸屏会感应到电流的变化。
触摸屏驱动器通过相应的算法来检测这些电流变化,并将其转化为对触摸点位置的坐标数据。
常见的触摸屏驱动技术有四种:电容式、电阻式、表面声波和红外线。
1. 电容式触摸屏驱动原理:
电容式触摸屏采用两层导电板构成电容,在不触摸屏幕时,电容平衡。
当手指触摸到屏幕上时,由于人体电容的存在,导致电容发生变化。
触摸屏驱动器会检测到变化的电容值,并通过测量和计算来确定触摸点位置。
2. 电阻式触摸屏驱动原理:
电阻式触摸屏由两层导电薄膜构成,中间夹有绝缘层。
当触摸屏被触摸时,导电薄膜会接触到一起,形成电阻的变化。
触摸屏驱动器通过测量电阻的变化来确定触摸点位置。
3. 表面声波触摸屏驱动原理:
表面声波触摸屏利用超声波传感器将声波传输到触摸屏表面。
当有物体触摸到触摸屏时,声波会被打断并反射回传感器。
触摸屏驱动器通过测量声波传输和反射时间的差异来确定触摸点位置。
4. 红外线触摸屏驱动原理:
红外线触摸屏在触摸屏表面周围设置红外线发射器和接收器,形成网状的红外线检测区域。
当有物体触碰到触摸屏时,会阻挡红外线的传输。
触摸屏驱动器会通过检测到的红外线被阻挡的位置来确定触摸点位置。
不同类型的触摸屏驱动原理各有优缺点,适用于不同场景和需求。
但无论采用哪种触摸屏驱动技术,其基本原理都是通过检测电容、电阻、声波或红外线的变化来确定触摸点位置。
基于DragonBoard 410c开发板的触摸屏驱动编写前言:让大家初步了解对高通MSM8916平台的输入子系统的实现,给大家提供Dragon Board 410c平台开发输入系统设备的思路。
(如:按键设备、触摸屏、轨迹球等)在高通MSM8916平台中,具有触摸屏、轨迹球和简单按键功能,这些功能是由Android 系统内中的驱动程序实现的,并且需要用户空间的内容来协助实现。
一、触摸屏驱动编写高通MSM8916平台的触摸屏驱动程序的实现文件是drivers/input/touchscreen/synapTIcs_i2c_rmi4.c,此文件的核心是函数synapTIcs_ts_probe(),在该函数中需要进行触摸屏工作模式的初始化,对作为输出设备的触摸屏驱动在Linux平台下的设备名注册,同事初始化触摸时间触发时引起的中断操作。
此函数的实现代码如下:staTIc int synapTIcs_rmi4_probe(struct i2c_client *client,const struct i2c_device_id *dev_id){int retval = 0;unsigned char ii;unsigned char attr_count;struct synaptics_rmi4_f1a_handle *f1a;struct synaptics_rmi4_fn *fhandler;struct synaptics_rmi4_fn *next_fhandler;struct synaptics_rmi4_data *rmi4_data;struct synaptics_rmi4_device_info *rmi;struct synaptics_rmi4_platform_data *platform_data =client-dev.platform_data;struct dentry *temp;if (!i2c_check_functionality(client-adapter,I2C_FUNC_SMBUS_BYTE_DATA)){dev_err(client-dev,%s: SMBus byte data not supported\n,__func__);return -EIO;}if (client-dev.of_node) {platform_data = devm_kzalloc(client-dev,sizeof(*platform_data),GFP_KERNEL);if (!platform_data) {dev_err(client-dev, Failed to allocate memory\n);return -ENOMEM;}retval = synaptics_rmi4_parse_dt(client-dev, platform_data);if (retval)return retval;} else {platform_data = client-dev.platform_data;}if (!platform_data) {dev_err(client-dev,%s: No platform data found\n,__func__);return -EINV AL;}rmi4_data = kzalloc(sizeof(*rmi4_data) * 2, GFP_KERNEL);if (!rmi4_data) {dev_err(client-dev,%s: Failed to alloc mem for rmi4_data\n,__func__);return -ENOMEM;}rmi = (rmi4_data-rmi4_mod_info);rmi4_data-input_dev = input_allocate_device();//创建设备if (rmi4_data-input_dev == NULL) {dev_err(client-dev,%s: Failed to allocate input。
MTK6515 android打版软件配置∙ 1 一、配置GPIO∙ 2 二、配置emmc3 三、配置LCMo 3.1 1、增加LCM驱动文件o 3.2 2、配置驱动文件o 3.3 3、配置背光4 四、配置touch panelo 4.1 1、通过dct配置gipo及其对应的别名o 4.2 2、配置mediatek/config/bbk15_td_ics/ProjectConfig.mko 4.3 3、增加tp 驱动目录及驱动文件o 4.4 4、配置刚刚添加的驱动文件o 4.5 5、配置pmic供电∙ 5 五、注意事项6 六、附录o 6.1 1、i2C配置的两种方法o 6.2 2、将触屏配置成点触模式一、配置GPIO通过工具:mediatek/source/dct/DrvGen.exe配置并替换dws文件:mediatek/custom/bbk75_emmc_gb2/kernel/dct/dct/codegen.dws∙配置GPIO的主要目的是使系统在uboot,甚至preloader阶段时保持BB管脚的状态;在kernel启动阶段加载驱动模块时,不少驱动是会重新设置其用的gpio功能的,所以这一阶段并不要求非常严格,然而同时也必须要保证gpio所配置的初始状态不会影响到系统的启动,如死机、复位等等。
二、配置emmc1、在下面文件的MTK6575标签栏添加对应的flash芯片型号信息:mediatek/build/tools/emigen/MT6575/MemoryDeviceList_MT6575.xls2、从以下文件获取flash芯片对应的序号(从第1列为0,开始数,如到第L列则为11):mediatek/build/tools/ptgen/emmc_region.xls3、mediatek/custom/bbk15_td_ics/preloader/inc/custom_MemoryDevice.h#define BOARD_ID LENOVO75#define CS_PART_NUMBER[0] KMSJS000KM_B308将上面的宏更改为MemoryDeviceList_MT6575.xls中对应的内容4、mediatek/config/bbk15_td_ics/ProjectConfig.mk将EMMC_CHIP更改为第2步获取的数值,如EMMC_CHIP = 11。
Android多点触摸的实现——1.6patch(一)第一章摘要在Linux内核支持的基础上,Android在其 2.0源码中加入多点触摸功能。
由此触摸屏在Android的frameworks被完全分为2种实现途径:单点触摸屏的单点方式,多点触摸屏的单点和多点方式。
第二章软件位在Linux的input.h中,多点触摸功能依赖于以下几个主要的软件位:………………………..#define SYN_REPORT 0#define SYN_CONFIG 1#define SYN_MT_REPORT 2………………………...#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */#define ABS_MT_TOUCH_MINOR 0x31 /* Minor axis (omit if circular) */#define ABS_MT_WIDTH_MAJOR 0x32 /* Major axis of approaching ellipse */#define ABS_MT_WIDTH_MINOR 0x33 /* Minor axis (omit if circular) */#define ABS_MT_ORIENTATION 0x34 /* Ellipse orientation */#define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */#define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */#define ABS_MT_TOOL_TYPE 0x37 /* Type of touching device */#define ABS_MT_BLOB_ID 0x38 /* Group a set of packets as a blob */ …………………………在Android中对应的软件位定义在RawInputEvent.java中:…………………..public class RawInputEvent {……………….public static final int CLASS_TOUCHSCREEN_MT = 0x00000010;………………..public static final int ABS_MT_TOUCH_MAJOR = 0x30;public static final int ABS_MT_TOUCH_MINOR = 0x31;public static final int ABS_MT_WIDTH_MAJOR = 0x32;public static final int ABS_MT_WIDTH_MINOR = 0x33;public static final int ABS_MT_ORIENTATION = 0x34;public static final int ABS_MT_POSITION_X = 0x35;public static final int ABS_MT_POSITION_Y = 0x36;public static final int ABS_MT_TOOL_TYPE = 0x37;public static final int ABS_MT_BLOB_ID = 0x38;………………….public static final int SYN_REPORT = 0;public static final int SYN_CONFIG = 1;public static final int SYN_MT_REPORT = 2;………………..在Android中,多点触摸的实现方法在具体的代码实现中和单点是完全区分开的。
触摸屏驱动触摸屏三种状态•active•monitor•hibernate 我们主要是需要通过serial interface建立与其的通讯接口,如write reg 、read reg等接口。
通过芯片使用手册提供给我们的寄存器信息,对芯片进行信息读取或配置。
i2c-core•总线驱动方法•i2c_smbus_write_block_data•i2c_smbus_read_i2c_block_data •i2c_smbus_read_byte•i2c_smbus_write_byte•设备注册、注销方法•i2c_register_driver•i2c_del_driver设备注册static struct i2c_board_info touchscreen_ft5x06_info[] = { {I2C_BOARD_INFO("ft5x0x_ts", 0x38),.platform_data = &touchscreen_ft5x06_pdata,.irq = MSM_GPIO_TO_INT(FT5X06_INT), }};static struct i2c_registry msm8x60_i2c_devices[] __initdata = { ..#ifdef CONFIG_TOUCHSCREEN_EDT_FT5X06{I2C_SURF | I2C_FFA | I2C_FLUID,MSM_GSBI3_QUP_I2C_BUS_ID,touchscreen_ft5x06_info,ARRAY_SIZE(touchscreen_ft5x06_info),},#endif}•msm8x60_init --》register_i2c_devices--》i2c_register_board_info•int __init i2c_register_board_info(int busnum,struct i2c_board_info const *info, unsigned len)•注册前面的数组中的设备驱动注册•module_init(ft5x0x_ts_init);编译过程中,宏定义module_init(ft5x0x_ts_init) 将把我们的模块驱动初始化函数指针添加到.initcall6.init 中。
s3c2440触摸屏驱动(针对android版)s3c2440 触摸屏驱动(针对android版)和原来的触摸屏驱动区别不是很⼤,增加了report函数来将事件发送到应⽤层。
驱动结构:很简单的字符设备+平台设备驱动,总的结构来说,主要四个部分构成:proberemoveresumesuspend⼯作机制则是注册设备,然后发⽣ts按下事件后产⽣ts中断以及adc中断,获得按下坐标。
没有读写函数,重点就是在两个中断处理函数上。
1,平台设备架构部分分析:probe函数:流程:ts基址的重映射->获得并启动时钟->ADCCON、ADCDLY、ADCTSC的初始化->初始化input设备完善ts结构体->建⽴ts_filter_chain->申请中断->注册input设备(2.6.27后为event0不再是ts0)。
static int __init s3c2410ts_probe(struct platform_device *pdev){int rc;struct s3c2410_ts_mach_info *info;struct input_dev *input_dev;int ret = 0;dev_info(&pdev->dev,"Starting\n");info =(struct s3c2410_ts_mach_info*)pdev->dev.platform_data;//获得平台设备数据if(!info){dev_err(&pdev->dev,"Hm... too bad: no platform data forts\n");return-EINVAL;}#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUGprintk(DEBUG_LVL "Entering s3c2410ts_init\n");#endifadc_clock = clk_get(NULL,"adc");if(!adc_clock){dev_err(&pdev->dev,"failed to get adc clock source\n");return-ENOENT;}clk_enable(adc_clock);#ifdef CONFIG_TOUCHSCREEN_S3C2410_DEBUGprintk(DEBUG_LVL "got and enabled clock\n");#endifbase_addr = ioremap(S3C2410_PA_ADC,0x20);//将PA_ADC寄存器重映射到内存上if(base_addr ==NULL){dev_err(&pdev->dev,"Failed to remap register block\n"); ret =-ENOMEM;goto bail0;}/* If we acutally are a S3C2410: Configure GPIOs */if(!strcmp(pdev->name,"s3c2410-ts"))s3c2410_ts_connect();//初始化相关gpio⼝if((info->presc & 0xff)> 0)writel(S3C2410_ADCCON_PRSCEN |S3C2410_ADCCON_PRSCVL(info->presc&0xFF),base_addr + S3C2410_ADCCON);elsewritel(0, base_addr+S3C2410_ADCCON);/* Initialise registers */if((info->delay & 0xffff)> 0)writel(info->delay & 0xffff, base_addr + S3C2410_ADCDLY);writel(WAIT4INT(0), base_addr + S3C2410_ADCTSC);/* Initialise input stuff */memset(&ts, 0,sizeof(struct s3c2410ts));input_dev = input_allocate_device();if(!input_dev){dev_err(&pdev->dev,"Unable to allocate the input device\n");ret =-ENOMEM;}//初始化input设备ts.dev = input_dev;ts.dev->evbit[0]= BIT_MASK(EV_SYN)| BIT_MASK(EV_KEY)|BIT_MASK(EV_ABS);ts.dev->keybit[BIT_WORD(BTN_TOUCH)]= BIT_MASK(BTN_TOUCH);input_set_abs_params(ts.dev, ABS_X, 0, 0x3FF, 0, 0);input_set_abs_params(ts.dev, ABS_Y, 0, 0x3FF, 0, 0);input_set_abs_params(ts.dev, ABS_PRESSURE, 0, 1, 0, 0);ts.dev->name = s3c2410ts_name;ts.dev->id.bustype = BUS_RS232;ts.dev->id.vendor = 0xDEAD;ts.dev->id.product = 0xBEEF;ts.dev->id.version = S3C2410TSVERSION;ts.state = TS_STATE_STANDBY;//设置ts状态为就绪ts.event_fifo = kfifo_alloc(TS_EVENT_FIFO_SIZE, GFP_KERNEL, NULL);//为event队列申请内存空间if(IS_ERR(ts.event_fifo)){ret =-EIO;goto bail2;}/* create the filter chain set up for the 2 coordinates we produce */ts.chain = ts_filter_chain_create(pdev, info->filter_config, 2);//针对android的,建⽴filter_chainif(IS_ERR(ts.chain))goto bail2;ts_filter_chain_clear(ts.chain);/* Get irqs */if(request_irq(IRQ_ADC, stylus_action, IRQF_SAMPLE_RANDOM,"s3c2410_action", ts.dev)){dev_err(&pdev->dev,"Could not allocate ts IRQ_ADC !\n"); iounmap(base_addr);goto bail3;}if(request_irq(IRQ_TC, stylus_updown, IRQF_SAMPLE_RANDOM, "s3c2410_action", ts.dev)){dev_err(&pdev->dev,"Could not allocate ts IRQ_TC !\n"); free_irq(IRQ_ADC, ts.dev);iounmap(base_addr);ret =-EIO;goto bail4;}dev_info(&pdev->dev,"Successfully loaded\n");/* All went ok, so register to the input system */rc = input_register_device(ts.dev);if(rc){ret =-EIO;goto bail5;}return 0;bail5:free_irq(IRQ_TC, ts.dev);free_irq(IRQ_ADC, ts.dev);clk_disable(adc_clock);iounmap(base_addr);disable_irq(IRQ_TC);bail4:disable_irq(IRQ_ADC);bail3:ts_filter_chain_destroy(ts.chain);kfifo_free(ts.event_fifo);bail2:input_unregister_device(ts.dev);bail1:iounmap(base_addr);bail0:return ret;}remove:就是probe的逆运算,static int s3c2410ts_remove(struct platform_device *pdev) {disable_irq(IRQ_ADC);disable_irq(IRQ_TC);free_irq(IRQ_TC,ts.dev);free_irq(IRQ_ADC,ts.dev);if(adc_clock){clk_disable(adc_clock);clk_put(adc_clock);adc_clock =NULL;}input_unregister_device(ts.dev);iounmap(base_addr);ts_filter_chain_destroy(ts.chain);kfifo_free(ts.event_fifo);return 0;}resume与suspend函数可有可⽆,完成触摸屏的激活和挂起,2,中断处理分析:三种模式转换过程:等待down中断模式->x,y连续坐标转换模式->等待up中断模式->等待down中断模式->..两个中断的发⽣:触摸屏按下,发⽣ts中断,开始ad转换,ad转换结束,发⽣adc中断。
最近学习了电容触摸屏的驱动及其上层工作原理,拿出来和大家分享!转]Android触摸屏校准程序的实现一,校准的触摸算法如下:触摸屏校准通用方法。
(XL, YL是显示屏坐标,XT, YT是触摸屏坐标,)XL = XT*A+YT*B+CYL = XT*D+YT*E+F由于具体计算是希望是整数运算,所以实际中保存的ABCDEF为整数,而增加一个参数Div XL = (XT*A+YT*B+C) / DivYL = (YT*D+YT*E+F) / DivTSLIB把以上的7个参数ABCDEF Div 保存在pointercal 文件中。
不校准的数据:A=1, B=0, C=0, D=0, E=1, F=0, Div=1A B C D E F Div-411 37818 -3636780 -51325 39 47065584 65536二,Android 事件处理机制android 事件的传入是从EventHub开始的,EventHub是事件的抽象结构,维护着系统设备的运行情况(设备文件放在/dev/input里),设备类型包括Keyboard、TouchScreen、TraceBall。
它在系统启动的时候会通过open_device方法将系统提供的输入设备都增加到这个抽象结构中,并维护一个所有输入设备的文件描述符,如果输入设备是键盘的话还会读取/system/usr/keylayout/目录下对应键盘设备的映射文件(修改./development/emulator/keymaps /qwerty.kl来改变键值的映射关系),另外getEvent方法是对EventHub中的设备文件描述符使用poll操作等侍驱动层事件的发生,如果发生的事件是键盘事件,则调用Map函数按照映射文件转换成相应的键值并将扫描码和键码返回给KeyInputQueue.frameworks/base/services/jni/com_android_server_KeyInputQueue.cpp根据事件的类型以及事件值进行判断处理,从而确定这个事件对应的设备状态是否发生了改变并相应的改变对这个设备的描述结构InputDevice。
Windowmanager会创建一个线程(InputDispatcherThread),在这个线程里从事件队列中读取发生的事件(QueuedEvent ev = mQueue.getEvent()),并根据读取到事件类型的不同分成三类(KEYBOARD、TOUCHSCREEN、TRACKBALL),分别进行处理,例如键盘事件会调用dispatchKey((KeyEvent)ev.event, 0, 0)以将事件通过Binder发送给具有焦点的窗口应用程序,然后调用mQueue.recycleEvent(ev)继续等侍键盘事件的发生;如果是触摸屏事件则调用dispatchPointer(ev, (MotionEvent)ev.event, 0, 0),这里会根据事件的种类(UP、DOWN、MOVE、OUT_SIDE等)进行判断并处理,比如Cancel或将事件发送到具有权限的指定的窗口中去;移植方案Android本身并不带触摸屏校准。
Android获取到的数据就是驱动上报的原始数据。
方案一: 移植TSLIB,通过TSLIB产生pointercal 校准参数文件。
方案二: 从Android框架层获取OnTouch事件产生pointercal 校准参数文件方案一: 数据的校准在驱动中完成。
即把pointercal 的参数数据通过某种方式(sysfs)传递给驱动程序进行校准。
方案二: 驱动上报原始点,原始点在框架层拦截后进行校验处理。
TSLIB移植过程修改源码以适应android的文件结构。
设定Android.mk 编译选项,生成库即应用。
etc/ts.conf module_raw inputsrc/ts_config.c #define TS_CONF "/system/etc/ts.conf"src/ts_load_module.cchar *plugin_directory="/system/lib/ts/plugins/";tests/fbutils.cchar *defaultfbdevice = "/dev/graphics/fb0";COPY ts.conf 到/system/etc/ts.confinit.rc. mkdir /data/etc/pointercal通过ts_calibrate 产生pointercal 数据文件。
框架内获取参数文件制作APK 应用,仿效ts_calibrate采点并计算出各参数,产生pointercal框架内实现触摸屏校准在InputDevive.java 中拦截触摸屏原始数据进行pointercal参数校验后再分发驱动内实现触摸屏校准在init.rc 中添加event,在触摸屏加载后把pointercal参数输送给驱动。
结果-效果实现细节:扩展init - proper_serivce 系统支持的属性权限,对自定义的特殊系统属性进行权限开放。
使用自定义系统属性在init.rc 中on property 事件中处理pointercal的读写权限。
使用自定义系统属性触摸屏校准程序.apk 和InputDevice.java 中的输入事件的同步。
(在触摸屏校准期间inputDevice 在输入事件中不能采用算法。
校准程序完成有inputDevice重新启用校准算法)模拟器中至今无法进入device.absX/Y != null 的代码,需要了解以下inputDevice 被调用的步骤。
三,触摸屏的时间流程:驱动层:/** Touchscreen absolute values** These parameters are used to help the input layer discard out of* range readings and reduce jitter etc.** o min, max:- indicate the min and max values your touch screen returns* o fuzz:- use a higher number to reduce jitter** The default values correspond to Mainstone II in QVGA mode** Please read* Documentation/input/input-programming.txt for more details.*/static int abs_x[3] = {350, 3900, 5};module_param_array(abs_x, int, NULL, 0);MODULE_PARM_DESC(abs_x, "Touchscreen absolute X min, max, fuzz");static int abs_y[3] = {320, 3750, 40};module_param_array(abs_y, int, NULL, 0);MODULE_PARM_DESC(abs_y, "Touchscreen absolute Y min, max, fuzz");static int abs_p[3] = {0, 150, 4};module_param_array(abs_p, int, NULL, 0);MODULE_PARM_DESC(abs_p, "Touchscreen absolute Pressure min, max, fuzz");/** 对设备进行初始化设置*/set_bit(EV_ABS, wm->input_dev->evbit);set_bit(ABS_X, wm->input_dev->absbit);set_bit(ABS_Y, wm->input_dev->absbit);set_bit(ABS_PRESSURE, wm->input_dev->absbit);input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1],abs_x[2], 0);input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1],abs_y[2], 0);input_set_abs_params(wm->input_dev, ABS_PRESSURE, abs_p[0], abs_p[1], abs_p[2], 0);/** 事件发生时,提供原始点*/input_report_abs(wm->input_dev, ABS_X, data.x & 0xfff);input_report_abs(wm->input_dev, ABS_Y, data.y & 0xfff);input_report_abs(wm->input_dev, ABS_PRESSURE, data.p & 0xfff);/** 提供给驱动外查询input_dev 的接口* struct input_absinfo info;* ioctl(fd, EVIOCGABS(axis), &info)* src file: evDev.c*/if ((_IOC_NR(cmd) & ~ABS_MAX) == _IOC_NR(EVIOCGABS(0))) {t = _IOC_NR(cmd) & ABS_MAX;abs.value = dev->abs[t];abs.minimum = dev->absmin[t];abs.maximum = dev->absmax[t];abs.fuzz = dev->absfuzz[t];abs.flat = dev->absflat[t];Android 底层驱动EventHub.cppstatic const char *device_path = "/dev/input";openPlatformInput(void)scan_dir(device_path);open_device(devname);fd = open(deviceName, O_RDWR);/** 对外接口,getEvent,* inotify 监控device_path目录,使用poll机制轮询inotify 和各个输入设备的可用状态。