OpenHarmony南向之TP触摸屏

概述

Touchscreen驱动用于驱动触摸屏使其正常工作,该驱动主要完成如下工作:对触摸屏驱动IC进行上电、配置硬件管脚并初始化其状态、注册中断、配置通信接口(I2C或SPI)、设定Input相关配置、下载及更新固件等操作。

Touchscreen驱动基于HDF的Input驱动模型

Input驱动模型

Input驱动模型基于HDF驱动框架、Platform接口、OSAL接口进行开发,向上对接规范化的驱动接口HDI(Hardware Device Interface)层,通过Input-HDI层对外提供硬件能力,即上层Input Service可以通过HDI接口层获取相应的驱动能力,进而操控Touchscreen等输入设备。

Input驱动模型核心部分由设备管理层、公共驱动层、器件驱动层组成。

  • Input设备管理:为各类输入设备驱动提供Input设备的注册、注销接口,同时对Input设备列表进行统一管理。

  • Input平台驱动:指各类Input设备的公共抽象驱动(例如触摸屏的公共驱动),该部分主要负责对板级硬件进行初始化、硬件中断处理、向manager注册Input设备等。

  • Input器件驱动:指各器件厂家的差异化驱动,开发者可以通过适配平台驱动预留的差异化接口进行器件驱动开发,实现器件驱动开发量最小化。

  • Input数据通道(event hub):提供一套通用的数据上报通道,各类别的Input设备驱动均可用此通道上报Input事件。

  • Input配置解析(hcs):负责对Input设备的板级配置及器件私有配置进行解析及管理。

Touchscreen驱动架构

现在以RK3568为例,来看看Touchscreen整个驱动架构

主要相关代码路径:

  • drivers/hdf_core/framework/model/input/driver/touchscreen/

  • vendor/hihope/rk3568/hdf_config/khdf/device_info/device_info.hcs

  • vendor/hihope/rk3568/hdf_config/khdf/input/input_config.hcs

主要代码框架:

下面详细展开

hcs

先看看hcs文件

device_info.hcs

input :: host {
    hostName = "input_host";
    priority = 100;
    device_input_manager :: device {
        device0 :: deviceNode {
            policy = 2;
            priority = 100;
            preload = 0;
            permission = 0660;
            moduleName = "HDF_INPUT_MANAGER";
            serviceName = "hdf_input_host";
            deviceMatchAttr = "";
        }
    }
    device_hdf_touch :: device {
        device0 :: deviceNode {
            policy = 2;
            priority = 120;
            preload = 0;
            permission = 0660;
            moduleName = "HDF_TOUCH";
            serviceName = "hdf_input_event1";
            deviceMatchAttr = "touch_device1";
        }
    }

    device_touch_chip :: device {
        device0 :: deviceNode {
            policy = 0;
            priority = 130;
            preload = 0;
            permission = 0660;
            moduleName = "HDF_TOUCH_GT911";
            serviceName = "hdf_touch_gt911_service";
            deviceMatchAttr = "zsj_gt911_5p5";
        }
    }

    ...
}

从上面可以看出,与触摸相关的主要是3个节点,刚好与实现TS驱动模型对应:

  • HDF_INPUT_MANAGER:Input设备管理

  • HDF_TOUCH:触摸屏的公共抽象驱动

  • HDF_TOUCH_GT911:具体的Input器件驱动

后面章节会基于源码详细展开这3块

input_config.hcs

root {
    input_config {
        touchConfig {
            touch0 {
                boardConfig {
                    match_attr = "touch_device1";
                    inputAttr {
                        /* 0:touch 1:key 2:keyboard 3:mouse 4:button 5:crown 6:encoder */
                        inputType = 0;
                        solutionX = 720;
                        solutionY = 1280;
                        devName = "main_touch";
                    }
                    busConfig {
                        // 0:i2c 1:spi
                        busType = 0;
                        busNum = 1;
                        clkGpio = 86;
                        dataGpio = 87;
                        i2cClkIomux = [0x114f0048, 0x403];
                        i2cDataIomux = [0x114f004c, 0x403];
                    }
                    pinConfig {
                        rstGpio = 14;
                        intGpio = 13;
                        rstRegCfg = [0x112f0094, 0x400];
                        intRegCfg = [0x112f0098, 0x400];
                    }
                    powerConfig {
                        /* 0:unused 1:ldo 2:gpio 3:pmic */
                        vccType = 2;
                        vccNum = 20;    // gpio20
                        vccValue = 1800;
                        vciType = 1;
                        vciNum = 12;    // ldo12
                        vciValue = 3300;
                    }

                    featureConfig {
                        capacitanceTest = 0;
                        gestureMode = 0;
                        gloverMOde = 0;
                        coverMode = 0;
                        chargerMode = 0;
                        knuckleMode = 0;
                    }
                }
                chipConfig {
                    template touchChip {
                        match_attr = "";
                        chipName = "gt911";
                        vendorName = "zsj";
                        chipInfo = "AAAA11222";  // 4-ProjectName, 2-TP IC, 3-TP Module
                        /* 0:i2c 1:spi*/
                        busType = 0;
                        deviceAddr = 0x5D;
                        /* 0:None 1:Rising 2:Failing 4:High-level 8:Low-level */
                        irqFlag = 2;
                        maxSpeed = 400;
                        chipVersion = 0; //parse Coord TypeA
                        powerSequence {
                            /* [type, status, dir , delay]
                                <type> 0:none 1:vcc-1.8v 2:vci-3.3v 3:reset 4:int
                                <status> 0:off or low  1:on or high  2:no ops
                                <dir> 0:input  1:output  2:no ops
                                <delay> meanings delay xms, 20: delay 20ms
                                */
                            powerOnSeq = [4, 0, 1, 5,
                                            3, 0, 1, 10,
                                            3, 1, 1, 60,
                                            4, 2, 0, 50];
                            suspendSeq = [3, 0, 2, 10];
                            resumeSeq = [3, 1, 2, 10];
                            powerOffSeq = [3, 0, 2, 10,
                                            1, 0, 2, 20];
                        }
                    }

                    chip0 :: touchChip {
                        match_attr = "zsj_gt911_5p5";
                        chipInfo = "ZIDN45100";  // 4-ProjectName, 2-TP IC, 3-TP Module
                        chipVersion = 0; //parse point by TypeA
                    }
                    ...
                }         
                ...
            }
        }
    }
}

device_info中的节点通过 deviceMatchAttrmatch_attr字段匹配配置,
chipConfig配置中主要定义了一些与实际硬件相关的信息:

  • 硬件接口的总线类型,主要有2类:SPI和I2C

  • 设备地址,这里使用的是I2C接口,所以就是I2C从设备的地址

  • 总线最高速率

  • 中断触发方式:边缘触发(上升沿、下降沿),还是电平触发(高低电平)

  • 电源相关的时序:上下电时序,休眠和唤醒时序

  • 自定义的一些info,版本等

驱动源码分析

HDF_TOUCH_GT911驱动

HDF_TOUCH_GT911驱动(touch_gt911.c)初始化(HdfGoodixChipInit)的主要过程:

//获取上面hcs中的chipConfig
chipCfg = ChipConfigInstance()  

//前面获取的配置
chipDev->chipCfg = chipCfg;  
//函数操作集,主要包括初始化,休眠唤醒,数据处理,固件更新,能力设置等接口,见后面定义  
chipDev->ops = &g_gt911ChipOps;  
chipDev->chipName = chipCfg->chipName;
chipDev->vendorName = chipCfg->vendorName;
device->priv = (void *)chipDev;
//注册 TouchChipDevice, 具体实现在后面的`HDF_TOUCH`驱动中
RegisterTouchChipDevice(chipDev) 

static struct TouchChipOps g_gt911ChipOps = {
    .Init = ChipInit,
    .Detect = ChipDetect,
    .Resume = ChipResume,
    .Suspend = ChipSuspend,
    .DataHandle = ChipDataHandle,
    .UpdateFirmware = UpdateFirmware,
    .SetAbility = SetAbility,
};

RegisterTouchChipDevice()函数的具体实现在后面的 HDF_TOUCH驱动

HDF_TOUCH驱动

HDF_TOUCH驱动(hdf_touch.c)主要有3大块

  • 驱动初始化
    部分伪代码:
//获取上面hcs中的 boardConfig
boardCfg = BoardConfigInstance(device); 

// 初始化驱动数据,Setup bus接口(这里主要是i2c)
ret = TouchDriverInit(touchDriver, boardCfg); 

//增加到驱动列表
AddTouchDriver(touchDriver); 

//对于RK平台,这里会注册一个PM的监听器,用来处理休眠和唤醒
#if defined(CONFIG_ARCH_ROCKCHIP)
    HdfTouchDriverRegisterPowerListener(device); 
#endif
  • Bind接口
    通过Bind对外提供IoService接口(Dispatch),主要有以下接口:
switch (cmd) {
    case GET_DEV_TYPE:
        ret = TouchGetDevType(touchDriver, reply);
        break;
    case SET_PWR_STATUS:
        ret = TouchSetPowerStatus(touchDriver, data);
        break;
    case GET_PWR_STATUS:
        ret = TouchGetPowerStatus(touchDriver, reply);
        break;
    case GET_CHIP_NAME:
    case GET_VENDOR_NAME:
    case GET_CHIP_INFO:
        ret = TouchGetDeviceStrInfo(touchDriver, cmd, reply);
        break;
    case GET_DEV_ATTR:
        ret = TouchGetDeviceAttr(touchDriver, reply);
        break;
    case GET_DEV_ABILITY:
        ret = TouchGetDeviceAbility(touchDriver, reply);
        break;
    case SET_GESTURE_MODE:
        ret = TouchSetGestureMode(touchDriver, data);
        break;
    case RUN_CAPAC_TEST:
        ret = TouchSelfCapacitance(touchDriver, data, reply);
        break;
    case RUN_EXTRA_CMD:
        ret = TouchRunExtraCmd(touchDriver, data);
        break;
    default:
        ret = HDF_SUCCESS;
        HDF_LOGE("%s: cmd unknown, cmd = 0x%x", __func__, cmd);
        break;
}
  • RegisterTouchChipDevice()函数实现

部分伪代码:

//绑定驱动和设备
ret = DeviceBindDriver(chipDev); 

//主要是上电操作,Detect设备,UpdateFirmware,
//配置使能中断,设置中断处理函数(坐标上报等就在里面)等操作,这里就不展开了
ret = ChipDriverInit(chipDev); 

//注册Input 设备, 具体实现在后面的 HDF_INPUT_MANAGER 驱动中
ret = RegisterInputDevice(inputDev); 

//调用chipdev的SetAbility接口
chipDev->ops->SetAbility(chipDev);   

HDF_INPUT_MANAGER驱动

HDF_INPUT_MANAGER驱动(hdf_input_device_manager.c),这里我们主要看下
RegisterInputDevice()函数的实现

部分伪代码:

    //分配设备ID
    ret = AllocDeviceID(inputDev);

    //创建设备节点
    ret = CreateDeviceNode(inputDev);

    //分配相关的buf,主要是pkgBuf和eventBuf
    ret = AllocPackageBuffer(inputDev); 

#ifndef __LITEOS_M__
    //初始化Event的工作队列,
    ret = InitEventWorkQueue(inputDev);

#endif // __LITEOS_M__
    //加入Input设备列表
    AddInputDevice(inputDev); 
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容