MTK 平台TP 驱动

本文以汇顶gt9xx_driver.c驱动为例,详细讲解MTK平台TP驱动的初始化流程和关键点。主要内容包括获取DTS信息、驱动加入内核、TP的真正初始化、I2C驱动注册、中断处理函数、线程创建以及TP的功能函数等。涉及到的函数有tpd_driver_init、tpd_device_add、tpd_local_init、i2c_add_driver、tpd_i2c_probe等。
摘要由CSDN通过智能技术生成

下面以汇顶gt9xx_driver.c 驱动为例讲解TP 驱动的整个关键点,本篇只讲TP 驱动本身的代码,

在驱动代码涉及的方法技术,因为每一个都牵涉linux内核的设计和知识,后面会逐个展开深入讲解。

首先,我们来总体看下TP 驱动代码初始化流程:


MTK kernel-4.14 TP 驱动初始化和部分工作流程main.cmain.cgt9xx_driver.cgt9xx_driver.cmtk_tpd.cmtk_tpd.ci2c.hi2c.hkthread.hkthread.hwait.hwait.hgt9xx_update.cgt9xx_update.cdo_initcallsmodule_inittpd_driver_inittpd_get_dts_infotpd_driver_addtpd_local_initi2c_add_drivertpd_i2c_probetpd_power_ongtp_init_panelkthread_runtouch_event_handlerwait_event_interruptibletpd_irq_registrationtpd_interrupt_handlerwake_up_interruptiblegup_init_update_proc

首先看TP 驱动模块初始化:

 

1

2

3

4

5

6

7

8

9

static int __init tpd_driver_init(void)

{

        GTP_INFO("GT9 series touch panel driver init");

        tpd_get_dts_info();

        if (tpd_driver_add(&tpd_device_driver) < 0)

                GTP_INFO("add generic driver failed");

 

                return 0;

}

 

 


请注意这个tpd_driver_init 是一个__init 修饰的函数,说明这个函数在编译时会被放到跟其他__init 修饰的函数放到一起,
在系统初始化,一旦内核启动后,就释放这些东西。一般用__init修饰的变量或者函数会编译到专门的一个段里面去,
这个段的数据和函数只有在kernel初始化的时候会被调用,以后一定不会被使用,kernel可能会在以后的某个时候释放掉这个段所占用的内存,
给别的地方使用,是不是设计很巧妙? 感兴趣的同学可以继续深入分析看看。

那么,我们看到这个函数主要就做了两件事情:
(1)是获取这个TP 所有的DTS 信息,我们看看这个代码的实现:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

void tpd_get_dts_info(void)

{

        struct device_node *node1 = NULL;

        int key_dim_local[16], i, ret;

 

        node1 = of_find_matching_node(node1, touch_of_match);

        if (node1) {

                ret = of_property_read_u32(node1, "tpd-max-touch-num", &tpd_dts_data.touch_max_num);

                if (ret != 0)

                        TPD_DEBUG("tpd-max-touch-num not found\n");

                ret = of_property_read_u32(node1, "use-tpd-button", &tpd_dts_data.use_tpd_button);

                if (ret != 0)

                        TPD_DEBUG("use-tpd-button not found\n");

                else

                        TPD_DEBUG("[tpd]use-tpd-button = %d\n", tpd_dts_data.use_tpd_button);

                ret = of_property_read_u32_array(node1, "tpd-resolution",

                        tpd_dts_data.tpd_resolution, ARRAY_SIZE(tpd_dts_data.tpd_resolution));

                if (ret != 0)

                        TPD_DEBUG("tpd-resolution not found\n");

                if (tpd_dts_data.use_tpd_button) {

                        ret = of_property_read_u32(node1, "tpd-key-num", &tpd_dts_data.tpd_key_num);

                        if (ret != 0)

                                TPD_DEBUG("tpd-key-num not found\n");

                        ret = of_property_read_u32_array(node1, "tpd-key-local",

                                tpd_dts_data.tpd_key_local, ARRAY_SIZE(tpd_dts_data.tpd_key_local));

                        if (ret != 0)

                                TPD_DEBUG("tpd-key-local not found\n");

                        ret = of_property_read_u32_array(node1, "tpd-key-dim-local",

                                key_dim_local, ARRAY_SIZE(key_dim_local));

                        if (ret != 0)

                                TPD_DEBUG("tpd-key-dim-local not found\n");

 

                        memcpy(tpd_dts_data.tpd_key_dim_local, key_dim_local, sizeof(key_dim_local));

                        for (i = 0; i < 4; i++) {

                                pr_debug("[tpd]key[%d].key_x = %d\n", i, tpd_dts_data.tpd_key_dim_local[i].key_x);

                                pr_debug("[tpd]key[%d].key_y = %d\n", i, tpd_dts_data.tpd_key_dim_local[i].key_y);

                                pr_debug("[tpd]key[%d].key_W = %d\n", i, tpd_dts_data.tpd_key_dim_local[i].key_width);

                                pr_debug("[tpd]key[%d].key_H = %d\n", i, tpd_dts_data.tpd_key_dim_local[i].key_height);

                        }

                }

                ret = of_property_read_u32(node1, "tpd-filter-enable", &tpd_dts_data.touch_filter.enable);

                if (ret != 0)

                        TPD_DEBUG("tpd-filter-enable not found\n");

                if (tpd_dts_data.touch_filter.enable) {

                        ret = of_property_read_u32(node1, "tpd-filter-pixel-density",

                                                 &tpd_dts_data.touch_filter.pixel_density);

                        if (ret != 0)

                                TPD_DEBUG("tpd-filter-pixel-density not found\n");

                        ret = of_property_read_u32_array(node1, "tpd-filter-custom-prameters",

                                (u32 *)tpd_dts_data.touch_filter.W_W, ARRAY_SIZE(tpd_dts_data.touch_filter.W_W));

                        if (ret != 0)

                                TPD_DEBUG("tpd-filter-custom-prameters not found\n");

                        ret = of_property_read_u32_array(node1, "tpd-filter-custom-speed",

                                tpd_dts_data.touch_filter.VECLOCITY_THRESHOLD,

                                ARRAY_SIZE(tpd_dts_data.touch_filter.VECLOCITY_THRESHOLD));

                        if (ret != 0)

                                TPD_DEBUG("tpd-filter-custom-speed not found\n");

                }

                memcpy(&tpd_filter, &tpd_dts_data.touch_filter, sizeof(tpd_filter));

                TPD_DEBUG("[tpd]tpd-filter-enable = %d, pixel_density = %d\n",

                                        tpd_filter.enable, tpd_filter.pixel_density);

                tpd_dts_data.tpd_use_ext_gpio = of_property_read_bool(node1, "tpd-use-ext-gpio");

                ret = of_property_read_u32(node1, "tpd-rst-ext-gpio-num", &tpd_dts_data.rst_ext_gpio_num);

                if (ret != 0)

                        TPD_DEBUG("tpd-rst-ext-gpio-num not found\n");

        else {

                pr_err("[tpd]%s can't find touch compatible custom node\n", __func__);

        }

}

 

这个函数看似很长,其实就是在读取我们定义在dts文件里面跟这个TP相关的数据,包括最大手指数:tpd-max-touch-num,对应的数据上报分辨率:tpd_re

  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: TP5100和TP5400都是锂电池充电管理芯片。 TP5100是一种单节或双节锂电池充电管理芯片。它可以通过简单的五引脚接口,实现锂电池的充电过程。TP5100内部集成了充电管理和保护功能,包括过压保护、欠压保护、过流保护和短路保护。它还具有充电状态与充电完成状态指示灯,方便用户了解充电状态。 TP5400也是一种锂电池充电管理芯片,但相比于TP5100,它具有更多的功能和更高的充电效率。TP5400的特点之一是支持快速充电技术,可以比常规充电芯片更快地充电。此外,它还具有过热保护、电池极性保护、温度监测等功能,提高了充电的安全性和稳定性。 无论是TP5100还是TP5400,它们都广泛应用于便携式电子产品中,如智能手机、平板电脑、蓝牙耳机等。这些芯片的使用可以提供高效、安全和稳定的充电方案,保护锂电池的寿命并保障用户的使用体验。 综上所述,TP5100和TP5400是两种常见的锂电池充电管理芯片,它们在功能和性能上有所差异,但都提供了高效、安全和稳定的充电解决方案。 ### 回答2: TP5100和TP5400是什么? TP5100和TP5400是锂电池管理芯片,被广泛应用于电池充电和保护电路中。 TP5100是一款单节锂电池管理芯片,能够对锂电池进行充电和保护。它具有过流保护、过放保护、过充保护和过温保护等功能。其充电电流和终止电压可以进行调节,可以满足不同应用的需求。TP5100采用SOP-16封装,体积小巧,便于集成到各种电子设备中。 TP5400是一款多节锂电池管理芯片,适用于2节或3节锂电池组的充电和保护。TP5400与TP5100相比,拥有更高的输入电压范围和更大的电流处理能力,适用于更大容量的电池组。同样,它也具备过流、过放、过充和过温保护等功能,以确保电池的安全和稳定性。TP5400同样采用SOP-16封装,便于与其他电路集成在一起。 无论是TP5100还是TP5400,它们都是为了满足锂电池充电和保护的需求而设计的专用管理芯片。它们的出现为锂电池的应用提供了更高效、更安全的解决方案,广泛应用于移动电源、充电宝、智能设备等领域。 ### 回答3: TP5100和TP5400是一种电池充放电管理芯片,主要用于锂离子电池的管理和保护。这两款芯片具有相似的功能,但也存在一些差异。 首先,TP5100和TP5400都提供了锂离子电池的充电管理功能。它们都支持恒流恒压充电模式,并能够自动识别电池类型和充电状态。此外,它们还能够监测充电过程中的电压和电流,以确保充电过程的稳定性和安全性。 其次,TP5100和TP5400也都具备了电池保护功能。它们能够监测电池的电压、电流和温度,并在电池过压、过流、过温等异常情况下进行保护。此外,它们还支持充电过程中的反向极性保护,避免了错误的连接带来的潜在危险。 然而,TP5100和TP5400也存在一些区别。首先,TP5400相对于TP5100来说具有更高的电流输出能力,能够处理更大容量的电池充放电。其次,TP5400具备了更多的保护功能,比如电池的欠压保护和短路保护等。此外,TP5400还设计了休眠模式,以降低功耗并延长电池使用寿命。 总的来说,TP5100和TP5400都是为锂离子电池提供充放电管理和保护的芯片,具备类似的功能,但在电流输出能力和保护功能上存在差别。选择合适的芯片应根据具体应用的需求来决定。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值