在一个屏幕中ic一般打在软体线上,通过TX与RX进行实时通信,IC(ft5x46)会对屏幕触点进行降噪和相应的算法等等,然后ic通过iic接口(有应答)与soc进行通讯,在ft5x46的datasheet里面有相应的框架图,如下图
当然这个并不是我们关注的点·
要对触屏进行了解,那么必须对input system进行了解,首先可以对整个的系统进行一个比较大致的了解,那么可以看到
input system有3大块组成:
input-event有3个元素分别是
那么如何看到这些定义呢?
可以在android源码目录下的/kernel/include/uapi/linux/input.h进行查阅,当然在后面解释这些宏一般的具体含义
在MMulti touch event中定义了相当多的宏,这些宏代表的是多点触屏的基本一些定义
可以到/kernel/Documentation/input/multi-touch-protocol.txt下面去查看相关的定义(该文详细地解释了多点触屏的协议)
至于他是如何实现的,可以去查看/kernel/drivers/input/input.c中的源码
多点触屏的协议实现在/kernel/drivers/input/touchscreen/ftxxx_ts.c(这个文件在不同的手机中的源码不同)
input_dev = input_allocate_device();
input_dev->name = Focal_input_dev_name;
__set_bit(KEY_BACK, input_dev->keybit);
__set_bit(KEY_HOME, input_dev->keybit);
__set_bit(KEY_APPSELECT, input_dev->keybit);
__set_bit(EV_ABS, input_dev->evbit);
__set_bit(EV_KEY, input_dev->evbit);
__set_bit(BTN_TOUCH, input_dev->keybit);
input_set_abs_params(input_dev, ABS_MT_TRACKING_ID, 0, CFG_MAX_TOUCH_POINTS, 0, 0);
input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, 31, 0, 0);
input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, ftxxxx_ts->x_max, 0, 0);
input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, ftxxxx_ts->y_max, 0, 0);
input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, PRESS_MAX, 0, 0);
input_register_device(input_dev);
对于触摸屏,必须支持的事件类型有以下这么三个
__set_bit(EV_SYN, input_dev->evbit); //设备同步,每次触摸完成以后都要发送一个同步事件,来表明这次触摸已经完成
__set_bit(EV_ABS, input_dev->evbit); //绝对坐标事件,触摸屏每次发送的坐标都是绝对坐标,不同于鼠标的相对坐标
__set_bit(EV_KEY, input_dev->evbit); //按键事件,每次触摸都有一个BTN_TOUCH的按键事件
触摸屏必须支持的按键类型
__set_bit(BTN_TOUCH, input_dev->keybit);//touch类型按键
触摸屏属性设置
input_mt_init_slots(input_dev, CFG_MAX_TOUCH_POINTS);//报告最大支持的点数
input_set_abs_params(input_dev,ABS_MT_TOUCH_MAJOR, 0, PRESS_MAX, 0, 0);//将触摸点看成一个椭圆,它的长轴长度。这个是可选项,并不影响正常使用。
input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, ft5x0x_ts->x_max, 0, 0);//x坐标取值范围
input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, ft5x0x_ts->y_max, 0, 0);//y坐标取值范围
A协议是不管什么tracking id直接发送出去给framwork由软件来实现对数据的处理,而B协议是要有SOLTS与tracking id在这里才能报告给上层
/*
*report the point information
*/
static void ftxxxx_report_value(struct ftxxxx_ts_data *data)
{
struct ts_event *event = &data->event;
int i;
u8 uppoint=0; //已经抬起的点数
#ifdef A
//protocol A
for(i=0;i < event->touch_point;i++)
{
if((event->au8_touch_event[i] == 0)||(event->au8_touch_event[i] ==2))
{
input_report_key(data->input_dev, BTN_TOUCH, 1);
input_report_abs(data->input_dev, ABS_MT_PRESSURE, event->pressure[i]);
input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->area[i]);
input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->au16_x[i]);
input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->au16_y[i]);
input_mt_sync(data->input_dev);
}
else
{
uppoint++;
input_mt_sync(data->input_dev);
}
}
if(uppoint==event->touch_point)
{
input_report_key(data->input_dev,BTN_TOUCH,0);
}
else
input_report_key(data->input_dev,BTN_TOUCH,event->touch_point>0);
input_sync(data->input_dev);
#endif
#ifdef B
//protocol B
for(i=0;i < event->touch_point;i++)//循环处理 缓存中的所有点
{
/*add by alex wang get slot*/
input_mt_slot(data->input_dev,event->au8_finger_id[i]); //发送点的ID
if((event->au8_touch_event[i] == 0)||(event->au8_touch_event[i] ==2)) //如果点按下
{
input_mt_report_slot_state(data->input_dev,MT_TOOL_FINGER , true); //手指按下
input_report_key(data->input_dev, BTN_TOUCH, 1); //告诉系统有键按下
input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->au8_finger_id[i]);
input_report_abs(data->input_dev, ABS_MT_PRESSURE, event->pressure[i]);
input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->area[i]);
input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->au16_x[i]);
input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->au16_y[i]);
}
else
{
uppoint++;
input_mt_report_slot_state(data->input_dev,MT_TOOL_FINGER,false);//报告手指抬起
}
}
if(uppoint==event->touch_point)
{
input_report_key(data->input_dev,BTN_TOUCH,0);/所有手指都抬起了 发送BTN_TOUCH 抬起事件
}
else
input_report_key(data->input_dev,BTN_TOUCH,event->touch_point>0);/还有手指没抬起,发送BTN_TOUCH 按下的事件
input_sync(data->input_dev);//sync 设备同步
}
#endif