当前位置:网站首页>gslx680触摸屏驱动源码码分析(gslX680.c)
gslx680触摸屏驱动源码码分析(gslX680.c)
2022-07-07 03:58:00 【正在起飞的蜗牛】
1、触摸屏代码整体分析
(1)gslx680触摸屏是I2C接口设备,所以驱动代码是利用I2C子系统提供的接口来编写,用I2C核心层提供的I2C驱动注册接口将构建好的I2C驱动结构体向I2C子系统注册;】
(2)注册的触摸屏I2C驱动会在I2C总线上和对应的I2C设备匹配上,从而调用I2C驱动的probe方法;
(3)I2C子系统在整个触摸屏驱动代码中,只是负责I2C设备和主控Soc的通信,整个触摸屏代码还涉及了input子系统用于向上层应用上报触摸时间,涉及中断子系统用于处理触摸屏的中断;
2、触摸屏驱动注册函数
static struct i2c_driver gsl_ts_driver = {
.driver = {
.name = GSLX680_I2C_NAME,
.owner = THIS_MODULE,
},
#ifndef CONFIG_HAS_EARLYSUSPEND
.suspend = gsl_ts_suspend,
.resume = gsl_ts_resume,
#endif
.probe = gsl_ts_probe,
.remove = __devexit_p(gsl_ts_remove),
.id_table = gsl_ts_id,
};
static int __init gsl_ts_init(void)
{
int ret;
print_info("==gsl_ts_init==\n");
ret = i2c_add_driver(&gsl_ts_driver);
print_info("ret=%d\n",ret);
return ret;
}
注册函数完成的功能就是向I2C子系统注册了名字是gsl_ts_driver的I2C驱动;
3、触摸屏驱动的probe函数
//在gslx680触摸屏驱动中用来描述I2C驱动的结构体
struct gsl_ts {
struct i2c_client *client;
struct input_dev *input;
struct work_struct work;
struct workqueue_struct *wq;
struct gsl_ts_data *dd;
u8 *touch_data;
u8 device_id;
int irq;
#if defined(CONFIG_HAS_EARLYSUSPEND)
struct early_suspend early_suspend;
#endif
};
static int __devinit gsl_ts_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct gsl_ts *ts;
int rc;
······
//检查适配器是否支持标准I2C通信协议
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
dev_err(&client->dev, "I2C functionality not supported\n");
return -ENODEV;
}
ts = kzalloc(sizeof(*ts), GFP_KERNEL);
if (!ts)
return -ENOMEM;
print_info("==kzalloc success=\n");
//将client保存到ts结构体中
ts->client = client;
//把ts保存到client->dev的私有数据
i2c_set_clientdata(client, ts);
ts->device_id = id->driver_data;
//注册input子系统,初始化工作队列,绑定触摸屏中断的下半部
rc = gslX680_ts_init(client, ts);
if (rc < 0) {
dev_err(&client->dev, "GSLX680 init failed\n");
goto error_mutex_destroy;
}
gsl_client = client;
//设置触摸屏相关GPIO引脚
gslX680_init();
//通过读写触摸屏芯片相关的寄存器完成初始化
init_chip(ts->client);
check_mem_data(ts->client);
//申请中断号并绑定中断处理程序
rc= request_irq(client->irq, gsl_ts_irq, IRQF_TRIGGER_RISING, client->name, ts);
if (rc < 0) {
print_info( "gsl_probe: request irq failed\n");
goto error_req_irq_fail;
}
······
}
(1)向I2C核心层注册的I2C触摸屏驱动最终会在I2C总线上匹配上I2C设备,也就是struct i2c_client结构体;
(2)I2C总线会调用I2C驱动的probe方法,把匹配上的struct i2c_client结构体传进去;
(3)probe函数中会完成初始化工作,其中包括input子系统的注册,中断程序的注册;
4、中断处理函数
static irqreturn_t gsl_ts_irq(int irq, void *dev_id)
{
struct gsl_ts *ts = dev_id;
print_info("========gslX680 Interrupt=========\n");
//禁止中断
disable_irq_nosync(ts->irq);
//检测中断下半部所属的工作队列是否挂起,如果挂起则将中断的下半部添加到队列中进行调度
//调用中断下半部函数,也就是gslX680_ts_worker()
if (!work_pending(&ts->work))
{
queue_work(ts->wq, &ts->work);
}
return IRQ_HANDLED;
}
(1)gsl_ts_irq()函数只是中断处理函数的上半部,实际功能就是禁止中断,然后调用中断下半部;
(2)gslX680_ts_worker()是中断的下半部,在gslX680_ts_init()函数中指定;
补充:参考博客:《中断的顶半部和底半部介绍以及实现方式(tasklet 和 工作队列)》;
5、整个触摸屏驱动代码工作的逻辑
gsl_ts_irq() //中断上半部
gslX680_ts_worker() //中断下半部
gsl_ts_write() //触摸屏驱动的写数据
i2c_master_send() //实际调用I2C核心层的发数据接口
gsl_ts_read() //触摸屏驱动的读数据
i2c_master_recv() //实际调用I2C核心层的收数据接口
report_data() //上报数据
input_report_abs() //实际调用input子系统的上报接口
(1)当触摸屏发生触摸事件时,触发绑定的中断处理程序gsl_ts_irq();
(2)gsl_ts_irq()是中断上半部,禁止中断然后调用中断下半部gslX680_ts_worker();
(3)gslX680_ts_worker()函数会通过I2C子系统提供的I2C总线的收发数据接口函数,读写触摸屏芯片的相关寄存器;
(4)gslX680_ts_worker()函数将从触摸屏芯片读取到的数据进行计算和转换,然后填充成输入事件结构体,根据之前注册的input子系统,按input子系统的输入事件往应用层上报;
边栏推荐
- Wechat applet full stack development practice Chapter 3 Introduction and use of APIs commonly used in wechat applet development -- 3.9 introduction to network interface (IX) extending the request3 met
- 【性能压测】如何做好性能压测?
- nacos
- 按键精灵脚本学习-关于天猫抢红包
- Wechat applet full stack development practice Chapter 3 Introduction and use of APIs commonly used in wechat applet development -- 3.10 tabbar component (I) how to open and use the default tabbar comp
- [2022 ACTF]web题目复现
- Advanced level of C language (high level) pointer
- Redis data migration
- After 95, the CV engineer posted the payroll and made up this. It's really fragrant
- I failed in the postgraduate entrance examination and couldn't get into the big factory. I feel like it's over
猜你喜欢
BGP experiment (1)
抽絲剝繭C語言(高階)數據的儲存+練習
[2022 ACTF]web题目复现
Leetcode-543. Diameter of Binary Tree
Detailed explanation of transform origin attribute
弹性布局(二)
1090: integer power (multi instance test)
URP - shaders and materials - light shader lit
4、 High performance go language release optimization and landing practice youth training camp notes
1142_ SiCp learning notes_ Functions and processes created by functions_ Linear recursion and iteration
随机推荐
Several important steps to light up the display
二、并发、测试笔记 青训营笔记
机器人技术创新与实践旧版本大纲
Modify the jupyter notebook file path
1141_ SiCp learning notes_ Functions abstracted as black boxes
Implementing data dictionary with JSP custom tag
Bi she - college student part-time platform system based on SSM
A concurrent rule verification implementation
Leetcode-206. Reverse Linked List
95后CV工程师晒出工资单,狠补了这个,真香...
JS small exercise
抽丝剥茧C语言(高阶)数据的储存+练习
mips uclibc 交叉编译ffmpeg,支持 G711A 编解码
Redis data migration
JS small exercise ---- time sharing reminder and greeting, form password display hidden effect, text box focus event, closing advertisement
2、 Concurrent and test notes youth training camp notes
直播平台源码,可折叠式菜单栏
BGP experiment (1)
詳解機器翻譯任務中的BLEU
Talk about seven ways to realize asynchronous programming