MTK平台tp驱动详解
2016-05-10 11:52
1061 查看
MTK平台tp驱动详解
本博文将讲解基于Goodix触控芯片的tp驱动程序。这里有对应的驱动程序。初始化
static int __init tpd_driver_init(void) { GTP_INFO("MediaTek gt91xx touch panel driver init\n"); #if defined(TPD_I2C_NUMBER) i2c_register_board_info(TPD_I2C_NUMBER, &i2c_tpd, 1); #else i2c_register_board_info(0, &i2c_tpd, 1); #endif if (tpd_driver_add(&tpd_device_driver) < 0) GTP_INFO("add generic driver failed\n"); return 0; }
在
tpd_driver_init中主要做了两件事情:
1、注册一个i2c设备
i2c_register_board_info在 kernel\drivers\i2c\i2c-boardinfo.c 中定义。
对应的函数说明如下:
i2c_register_board_info - statically declare I2C devices
* @busnum: identifies the bus to which these devices belong
* @info: vector of i2c device descriptors
* @len: how many descriptors in the vector; may be zero to reserve
* the specified bus number.
因此我们可知道:
TPD_I2C_NUMBER表示的是当前注册的i2c设备是在哪个总线上面,需要查看硬件连接图;
i2c_tpd表示的是该i2c设备的描述,包括设备名”gt9xx”和i2c的设备地址“(0xBA >> 1)”
static struct i2c_board_info __initdata i2c_tpd = { I2C_BOARD_INFO("gt9xx", (0xBA >> 1))};
2、添加一个驱动到静态数组
tpd_driver_list数组中
if (tpd_driver_add(&tpd_device_driver) < 0) GTP_INFO("add generic driver failed\n");
其中
tpd_device_driver的定义为:
static struct tpd_driver_t tpd_device_driver = { .tpd_device_name = "gt9xx", .tpd_local_init = tpd_local_init, .suspend = tpd_suspend, .resume = tpd_resume, #ifdef TPD_HAVE_BUTTON .tpd_have_button = 1, #else .tpd_have_button = 0, #endif };
这几个选项都是必须的。
其中的
tpd_device_name不能为”generic”,那样的话就会识别为R-Touch(推测此处表示为电阻屏),被保存到
tpd_driver_list[0]中。否则为C-Touch(推测此处表示为电容屏),保存到
tpd_driver_list的非0位置处。在TP驱动中要自己实现这几个函数的所有内容。
tpd_local_init()
static int tpd_local_init(void) { #if GTP_ESD_PROTECT clk_tick_cnt = 2 * HZ; // HZ: clock ticks in 1 second generated by system GTP_DEBUG("Clock ticks for an esd cycle: %d", clk_tick_cnt); INIT_DELAYED_WORK(>p_esd_check_work, gtp_esd_check_func); gtp_esd_check_workqueue = create_workqueue("gtp_esd_check"); spin_lock_init(&esd_lock); // 2.6.39 & later // esd_lock = SPIN_LOCK_UNLOCKED; // 2.6.39 & before #endif #if GTP_SUPPORT_I2C_DMA tpd->dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); gpDMABuf_va = (u8 *)dma_alloc_coherent(&tpd->dev->dev, GTP_DMA_MAX_TRANSACTION_LENGTH, &gpDMABuf_pa, GFP_KERNEL); if(!gpDMABuf_va) { GTP_INFO("[Error] Allocate DMA I2C Buffer failed!\n"); } memset(gpDMABuf_va, 0, GTP_DMA_MAX_TRANSACTION_LENGTH); #endif if (i2c_add_driver(&tpd_i2c_driver) != 0) { GTP_INFO("unable to add i2c driver.\n"); return -1; } if (tpd_load_status == 0) //if(tpd_load_status == 0) // disable auto load touch driver for linux3.0 porting { GTP_INFO("add error touch panel driver.\n"); i2c_del_driver(&tpd_i2c_driver); return -1; } input_set_abs_params(tpd->dev, ABS_MT_TRACKING_ID, 0, (GTP_MAX_TOUCH-1), 0, 0); #ifdef TPD_HAVE_BUTTON if (FACTORY_BOOT == get_boot_mode()|| RECOVERY_BOOT == get_boot_mode()) // cty 2014-08-14 { tpd_button_setting(TPD_KEY_COUNT, tpd_keys_local_factory, tpd_keys_dim_local);// initialize tpd button data } else { tpd_button_setting(TPD_KEY_COUNT, tpd_keys_local, tpd_keys_dim_local);// initialize tpd button data } #endif #if (defined(TPD_WARP_START) && defined(TPD_WARP_END)) TPD_DO_WARP = 1; memcpy(tpd_wb_start, tpd_wb_start_local, TPD_WARP_CNT * 4); memcpy(tpd_wb_end, tpd_wb_start_local, TPD_WARP_CNT * 4); #endif #if (defined(TPD_HAVE_CALIBRATION) && !defined(TPD_CUSTOM_CALIBRATION)) memcpy(tpd_calmat, tpd_def_calmat_local, 8 * 4); memcpy(tpd_def_calmat, tpd_def_calmat_local, 8 * 4); #endif // set vendor string tpd->dev->id.vendor = 0x00; tpd->dev->id.product = tpd_info.pid; tpd->dev->id.version = tpd_info.vid; GTP_INFO("end %s, %d\n", __FUNCTION__, __LINE__); tpd_type_cap = 1; return 0; }
该函数主要做以下几项工作:
1、GTP_ESD_PROTECT的内容暂时不知道做啥的。
2、GTP_SUPPORT_I2C_DMA主要是申请I2C DMA的空间,由
gpDMABuf_va指向。
tpd->dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);表示这个设备能寻址的物理地址的范围为
DMA_BIT_MASK(32),这个值相当于
0xffffffffUL。关于这个成员的解释可以参见 linux下platform_device中的dma_mask与coherent_dma_mask。
接下来的
dma_alloc_coherent()申请DMA空间。返回值为
gpDMABuf_va表示虚拟地址,以及返回
gpDMABuf_pa表示DMA实际物理地址。至于这两个怎么用还不是很懂。详见:Dynamic DMA mapping using the generic device
3、注册i2c设备驱动
if (i2c_add_driver(&tpd_i2c_driver) != 0) { GTP_INFO("unable to add i2c driver.\n"); return -1; } if (tpd_load_status == 0) //if(tpd_load_status == 0) // disable auto load touch driver for linux3.0 porting { GTP_INFO("add error touch panel driver.\n"); i2c_del_driver(&tpd_i2c_driver); return -1; }
probe探测到总线上的设备并把设备和驱动建立连接以完成设备的初始化。这个中间会调用
tpd_i2c_driver中的
tpd_i2c_probe()来完成初始化工作。
static struct i2c_driver tpd_i2c_driver = { .probe = tpd_i2c_probe, .remove = tpd_i2c_remove, .detect = tpd_i2c_detect, .driver.name = "b_gt9xx_hotknot", .id_table = tpd_i2c_id, .address_list = (const unsigned short *) forces, };
这里面的内容都要自己去实现,特别是
tpd_i2c_probe()。如果
tpd_i2c_probe()中初始化设备全部完成,则要置位全局变量
tpd_load_status为1标记成功初始化,否则的话匹配失败需要调用
i2c_del_driver()删除已注册的驱动。
4、设置input设备
tpd->dev支持的最大手指触摸个数
input_set_abs_params(tpd->dev, ABS_MT_TRACKING_ID, 0, (GTP_MAX_TOUCH-1), 0, 0);
input设备
tpd->dev的申请以及定义和初始化的内容都在mtk_tpd.c这个文件中的
tpd_probe()函数实现了。推测之所以没有一起初始化的
ABS_MT_TRACKING_ID的内容是因为每个触控IC的原厂软件实现最大的触摸个数都不太一样,所以这里需要根据情况自己设定。
5、按键的初始化
#ifdef TPD_HAVE_BUTTON if (FACTORY_BOOT == get_boot_mode()|| RECOVERY_BOOT == get_boot_mode()) // cty 2014-08-14 { tpd_button_setting(TPD_KEY_COUNT, tpd_keys_local_factory, tpd_keys_dim_local);// initialize tpd button data } else { tpd_button_setting(TPD_KEY_COUNT, tpd_keys_local, tpd_keys_dim_local);// initialize tpd button data } #endif
tpd_button_setting()函数的内容非常简单,就是将数组
tpd_keys_local[TPD_KEY_COUNT]和
tpd_keys_dim_local[TPD_KEY_COUNT][4]拷贝给
tpd_keys和
tpd_keys_dim。这两个变量用于
tpd_button_init()的初始化创建virtual keys。数组内容要根据TP的分辨率来确定按键的位置。
6、设置input设备
tpd->dev的信息
// set vendor string tpd->dev->id.vendor = 0x00; tpd->dev->id.product = tpd_info.pid; tpd->dev->id.version = tpd_info.vid;
7、设置TP类型会电容屏
tpd_type_cap = 1;
从变量字面上的意思来看是设置标记TP为电容屏,至于还有何作用还不得而知。
tpd_i2c_probe()
相关文章推荐
- php 之 房屋租赁练习(0509)
- shonc项目中的设计资讯模块 php 字符串操作与正则表达式 strip_tags preg_match
- PHP 投票练习
- PHP,单项查询及多项查询
- 使用XHProf查找PHP性能瓶颈
- PHP 增删改查 import!!
- PHP 数据访问
- 深入理解浏览器会话机制(session && cookie)
- PHP 对象及其三大特性
- Only one AsyncAnnotationBeanPostProcessor may exist within the context.
- Yii2.0 实现RESTful风格的简单API
- php第十五节课
- php实现上传图片和等比例缩略图压缩图片
- thinkphp 分组、页面跳转与ajax
- thinkphp 分组、页面跳转与ajax
- thinkphp 分组、页面跳转与ajax
- PHP正则提取HTML中img的url值
- php+mysql实现的二级联动菜单效果详解
- parent:: self:: static $this->php
- static 关键字static2.php