GT2933触摸驱动分析 -中断处理

中断处理

向内核注册的中断处理函数为goodix_ts_threadirq_func,内容如下:

c 复制代码
static irqreturn_t goodix_ts_threadirq_func(int irq, void *data)
{
	struct goodix_ts_core *core_data = data;
	struct device *dev = core_data->bus->dev;
	struct goodix_ts_hw_ops *hw_ops = core_data->hw_ops;
	struct goodix_ts_event *ts_event = &core_data->ts_event;
	struct goodix_ts_esd *ts_esd = &core_data->ts_esd;
	int ret;

	disable_irq_nosync(core_data->irq);
	ts_esd->irq_status = true;
	core_data->irq_trig_cnt++;

	/* read touch data from touch device */
	ret = hw_ops->event_handler(core_data, ts_event);
	if (likely(!ret)) {
        if (!atomic_read(&core_data->suspended)) { // coor mode
            if (ts_event->event_type & EVENT_TOUCH) {
                /* report touch */
                goodix_ts_report_finger(core_data, &ts_event->touch_data);
            }
            if (core_data->board_data->pen_enable &&
                ts_event->event_type & EVENT_PEN) {
                goodix_ts_report_pen(core_data, &ts_event->pen_data);
            }
        } else if (core_data->gesture_type > 0) { // gesture mode
            if (ts_event->event_type & EVENT_GESTURE) {
                goodix_ts_report_gesture(core_data, ts_event);
            } else {
                /* resend gesture cmd */
                ts_info(dev, "can't recv gesture event, resend gesture cmd");
                hw_ops->gesture(core_data, core_data->gesture_type);
            }
        }

		if (ts_event->event_type & EVENT_REQUEST)
			goodix_ts_request_handle(core_data, ts_event);
	}
#if (GOODIX_ENABLE_DUMP_DEV)
	goodix_get_dump_frame(core_data);
#endif
	enable_irq(core_data->irq);
	return IRQ_HANDLED;
}

以touch触摸数据为例,在触摸之后,会拉低INT信号,接着就会触发中断,执行goodix_ts_threadirq_func函数,在该函数内首先调用event_handler(core_data, ts_event)去读取指定地址处的数据,在这里是0x10274 。读取数据之后,向该地址写0代表读取完成,读取后的数据存储在pre_buf[IRQ_EVENT_MAX_SIZE]中。接下来是根据数据Event类型执行不同的函数,这里的类型有Touch Event,Request Event,Gesture Event。

以Touch Event为例,会执行goodix_touch_handler(cd, ts_event, pre_buf)函数,传入读取到的数据pre_buf。在goodix_touch_handler函数中会根据点数据包中TYPE的类型去解析数据,把解析后的数据写入到pen_data或者touch_data中。这里的type类型有STYLUS_HOVER/STYLUS/FINGER/KEY。

以FINGER为例,对应的type数值为2,会执行goodix_parse_finger(touch_data, data, tid)函数,在该函数中将point中的x y w数据写入到touch_data中。

c 复制代码
static void goodix_parse_finger(struct goodix_touch_data *touch_data, u8 *buf,
				int id)
{
	touch_data->coords[id].status = TS_TOUCH;
	touch_data->coords[id].x = le16_to_cpup((__le16 *)(buf + 2));
	touch_data->coords[id].y = le16_to_cpup((__le16 *)(buf + 4));
	touch_data->coords[id].w = le16_to_cpup((__le16 *)(buf + 6));
	touch_data->touch_num += 1;
}

获得相应的数据之后,接下来会判断当前的工作模式,如果是Active模式,且ts_event->event_type 等于 EVENT_TOUCH,则会执行goodix_ts_report_finger(core_data, &ts_event->touch_data)函数,上报触摸数据。如果event_type等于EVENT_PEN,则执行goodix_ts_report_pen(core_data, &ts_event->pen_data)函数上报pen数据。上报数据则会调用input子系统中的接口,如input_report_abs上报触摸点的x/y数据等。

小结

中断处理的整个流程如下,首先是关闭中断,然后对中断计数加1,接下来是读取坐标的数据,读取之后根据信息的类型做不同的解析,如gesture或touch,解析完成之后,调用对应的上报函数,将数据上报至input子系统,最后开启中断。

驱动框图

触摸驱动整体框图如下所示,由上至下分别是用户空间、内核空间和硬件。

  • 用户空间
    用户空间是指使用触摸的应用程序,可以是编写操作input节点的程序文件,也可以是第三方库函数。
  • 内核空间
    驱动位于内核空间,涉及的系统GPIO用于中断和复位引脚,firmware子系统用于固件更新,sysfs系统用于在文件系统中创建调试节点,中断管理用于读取触摸的坐标等信息,platform系统用于创建驱动框架,I2C子系统用于读写触摸信息的数据,input子系统是关键,用于创建输入节点,将输入的节点信息上传至用户空间;
  • 硬件空间
    硬件空间涉及GPIO控制器和I2C控制器,由具体的芯片设计实现。
相关推荐
Lsir10110_13 分钟前
【Linux】进程信号(下半)
linux·运维·服务器
酉鬼女又兒31 分钟前
零基础入门Linux指南:每天一个Linux命令_pwd
linux·运维·服务器
云飞云共享云桌面33 分钟前
高性能图形工作站的资源如何共享给10个SolidWorks研发设计用
linux·运维·服务器·前端·网络·数据库·人工智能
zl_dfq35 分钟前
Linux 之 【多线程】(pthread_xxx、轻量级进程、原生线程库、线程ID、__thread、线程栈、线程与信号、线程与程序替换)
linux
choke23335 分钟前
Python 基础语法精讲:数据类型、运算符与输入输出
java·linux·服务器
菩提小狗44 分钟前
小迪安全2023-2024|第5天:基础入门-反弹SHELL&不回显带外&正反向连接&防火墙出入站&文件下载_笔记|web安全|渗透测试|
笔记·安全·web安全
AZ996ZA1 小时前
自学linux的第二十一天【DHCP 服务从入门到实战】
linux·运维·服务器·php
_OP_CHEN1 小时前
【Linux系统编程】(二十八)深入 ELF 文件原理:从目标文件到程序加载的完整揭秘
linux·操作系统·编译·c/c++·目标文件·elf文件
Wentao Sun1 小时前
致敬软件创业者2026
笔记·程序人生
Fleshy数模1 小时前
MySQL 表创建全攻略:Navicat 图形化与 Xshell 命令行双模式实践
linux·mysql