Android Qcom Display学习(六)

该系列文章总目录链接与各部分简介: Android Qcom Display学习(零)

Android Qcom TP代码流程分析

 在项目中我们经常会遇到需要兼容lcd和tp的情况,如果是不同i2c地址的touch,没有probe成功也就根本不过去用,所以one lcd mutil touch的情况暂时还没有遇到过去做区分的,那项目中主要遇到的就是以下这种情况one touch mutil lcd

one touch mutil lcd

   这种情况下,lcd本身通过dsi读取的id就能区分不同型号的panel,xbl会传入cmdline,lcd在模块注册就会去解析传参并注册到kernel中,tp在调用of_drm_find_panel(node)获得注册到kernel中的panel型号与devicetree中的panel型号进行比对绑定

dtsi:
atmel_maxtouch_ts@4a {
	panel  = <&dsi_hx8399_1080_video &dsi_ili9881c_720p_video>;

kernel:
	count = of_count_phandle_with_args(np, "panel", NULL);
	for (i = 0; i < count; i++) {
	    node = of_parse_phandle(np, "panel", i);
	    panel = of_drm_find_panel(node); //↓↓
	    of_node_put(node);
	    if (!IS_ERR(panel)) {
	        return panel;
	    }
	}
	drm_panel_notifier_register(data->active_panel, &data->fb_notif);

那项目中可能不仅仅是支持多个panel基础功能,需要不同的panel对应的tp支持不同的cfg(tunning的配置,触摸灵敏度或者旋转等)

devicetree:
atmel_maxtouch_ts@4a {
/* root node */
tp_a@0x0000 {     /* child node */
       board_version = "0x0000";
       /* root node */
       pnl_a@0x001 {    /* child node */
           pnl-name = "hx8399";
           pnl-cfg     = "mxt640u.raw";
           atmel,display-coords = <0  0 1080 1920>;
           atmel,panel-coords = <0  0 1080 1920>;
       };
       pnl_b@0x002 {    /* child node */
           pnl-name = "ili9881c";
           pnl-cfg = "mxt640u_version2.raw";
           atmel,display-coords = <0  0 720 1280>;
           atmel,panel-coords = <0  0 720 1280>;
       };
 };
tp_b@0x0001{     /*child node*/
         board_version = "0x0001";
         ...

kernel:
static int mxt_get_pnl_fw_cfg(struct device *dev, struct mxt_platform_data *pdata, int layer, struct device_node *root){
{
        int index = 0;
        int error = -EINVAL;
        struct device_node *child;
        u32 coords[MXT_COORDS_ARR_SIZE];

        dev_info(dev, "enter %s, layer = %d\n", __func__,layer);

        for_each_child_of_node(root, child) {
                if(!layer) { //Root
                //can add to compatible more;like project versin
                   continue;
                } else if (layer == 1) { //parse panel name
                        static const char *pnl_name = NULL;
                        error = of_property_read_string(child, "pnl-name", &pnl_name);
                        if (error && (error != -EINVAL)) {
                                dev_err(dev, "Unable to read pnl name\n");
                        }
                        dev_dbg(dev,"%s: pnl_name = %s lcm_panel_name = %s\n",__func__,pnl_name,lcm_panel_name);

                        /* select panel config according to panel name */
                        if ( NULL == strstr (lcm_panel_name, pnl_name) ) {
                                continue;
                        }
                }

                error = mxt_get_pnl_fw_cfg(dev, pdata, layer+1, child);
                if (!error) {
                        dev_dbg(dev,"%s: already get all information\n", __func__);
                        goto out;
                }

                error = of_property_read_string (child, "pnl-cfg", &pdata->cfg_name);
                dev_info(dev,"%s: cfg_name = %s\n", __func__, pdata->cfg_name);
                if (error && (error != -EINVAL)) {
                        dev_err(dev, "Unable to read cfg name\n");
                        goto out;
                }
                
                error = of_property_read_string(child, "pnl-fw", &pdata->fw_name);
                dev_info(dev,"%s: fw_name = %s\n", __func__, pdata->fw_name);
                if (error && (error != -EINVAL)) {
                        dev_err(dev, "Unable to read fw name\n");
                        goto out;
                }
                ...
               break;
        }
        
out:
        dev_info(dev, "leave %s, layer =%d\n", __func__, layer);
        return error;

   利用for_each_child_of_node对devicetree进行遍历,可扩展。上述案例利用两层循环,如果version不对的话,则会跳出循环到下一个childnode(tp_b@0x0001);如果version是对的话,那么会调用mxt_get_pnl_fw_cfg进入下一级循环,rootnode会变,layer+1,解析第一个childnode(pnl_a@0x0001)的panel name进行比较,如果对的话,进一步解析获取全部信息(主要时cfg文件和firmware用于更新);如果不对的跳出循环进入下一个childnode(pnl_b@0x0002);再对panel name进行比较;利用devicetree可以在其他项目中也能很容易的做到兼容,一套kernel驱动不用修改;所以后续跟项目有关的在devicetree中做标记,防止驱动冗余,可读性差。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值