firefly-rk3288j开发板 TP实验之GT9XX触摸驱动

linux TP实验之GT9XX触摸驱动

1 准备工作

开发板:aio-rk3288j
SDK版本:rk3288_linux_release_20210304
下载工具:Linux_Upgrade_Tool_v2.1
内核版本:4.4.194
文件系统:buildroot
Ubuntu版本:18.04
交叉编译工具:gcc version 6.3.1 20170404

2原理图

在这里插入图片描述

3 时序图

在这里插入图片描述
在这里插入图片描述

4 配置步骤

4.1 驱动添加到内核菜单

驱动源码路径:kernel/drivers/input/touchscreen/gt9xx
Kconfig文件添加如下内容
在这里插入图片描述
在Makefile里添加编译gt9xx驱动
在这里插入图片描述
在内核菜单中去配置gt9xx的驱动,把它编译进内核。打开make menuconfig
路径:
Devrive Drivers ->Input device support -> Touchscreens->Goodix gt9xx support for rockchip
在这里插入图片描述

4.2修改设备树

设备树路径:kernel/arch/arm/boot/dts/rk3288-firefly-aio.dts

&i2c4 {
	status = "okay";
	clock-frequency = <400000>;
	gt9xx: goodix-ts@14 {
		compatible = "goodix,gt9xx";
		reg = <0x14>;
		interrupt-parent = <&gpio5>;
		interrupts = <19 IRQ_TYPE_EDGE_FALLING>;
		touch-gpio = <&gpio5 19 GPIO_ACTIVE_HIGH>;
		reset-gpio = <&gpio7 9 GPIO_ACTIVE_LOW>;
 		pinctrl-names = "default";
		pinctrl-0 = <&goodix_touch &goodix_reset>;
		max-x = <1024>;
		max-y = <600>;
		tp-size = <910>;
	};

};

&pinctrl {
	gt9xx {
		goodix_touch: goodix-touch {
			rockchip,pins = <5 19 RK_FUNC_GPIO &pcfg_pull_up>;
		};
		goodix_reset: goodix-reset {
			rockchip,pins = <7 9 RK_FUNC_GPIO &pcfg_pull_up>;
		};
};

5 源码修改

gt9xx.h 文件配置修改
#define DEBUG_SWITCH  	        1 开启调试开关,打印信息(很重要)
#define GTP_CUSTOM_CFG	        1 用来用户自定义设置;
#define GTP_DRIVER_SEND_CFG     1 用来发送CFG文件配置;
group是厂家指定,6group(0 - 5),该方案配置group3
// TODO: define your config for Sensor_ID == 3 here, if needed
#define CTP_CFG_GROUP3 {\
	//厂家提供
     0x00,0x00,0x04,0x58,0x02,0x05,0x0C,0x20,0x02,0xC6,0x28,0x0F,0x64,0x50,0x03, \
	 0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x1A,0x1E,0x14,0x8A,0x29,0x0C, \
	 0x2A,0x28,0x0F,0x0A,0x00,0x00,0x00,0x81,0x03,0x11,0x00,0x01,0x00,0x00,0x00, \
	 0x03,0x00,0x00,0x00,0x00,0x00,0x14,0x52,0x94,0xC5,0x02,0x07,0x00,0x00,0x04, \
	 0xD4,0x17,0x00,0xA6,0x1E,0x00,0x80,0x28,0x00,0x62,0x36,0x00,0x4E,0x47,0x00, \
	 0x4E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x16,0x14,0x12,0x10,0x0E,0x0C,0x0A, \
	 0x08,0x06,0x04,0x02,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
	 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x22,0x21,0x20,0x1F,0x1E,0x1D,0x1C,0x18, \
	 0x16,0x12,0x10,0x0F,0x0C,0x0A,0x08,0x06,0x04,0x02,0x00,0xFF,0xFF,0xFF,0xFF, \
	 0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, \
	 0x00,0x00,0x00,0x00,0xFB,0x01 \
}

Gt9xxx.c源码分析
初始化TP,该函数打印信息判断Sensor id 判断,适配哪个屏幕,即哪个CFG

static s32 gtp_init_panel(struct goodix_ts_data *ts)
{
    s32 ret = -1;
#if GTP_DRIVER_SEND_CFG
    s32 i = 0;
    u8 check_sum = 0;
    u8 opr_buf[16] = {0};
    u8 sensor_id = 0;

    u8 cfg_info_group2[] = CTP_CFG_GROUP2;
    u8 cfg_info_group3[] = CTP_CFG_GROUP3;
    u8 cfg_info_group4[] = CTP_CFG_GROUP4;
    u8 cfg_info_group5[] = CTP_CFG_GROUP5;
    u8 cfg_info_group6[] = CTP_CFG_GROUP6;
    u8 *send_cfg_buf[] = {gtp_dat_10_1, cfg_info_group2, cfg_info_group3,
                            cfg_info_group4, cfg_info_group5, cfg_info_group6};
    u8 cfg_info_len[] = { CFG_GROUP_LEN(gtp_dat_10_1),
                              CFG_GROUP_LEN(cfg_info_group2),
                              CFG_GROUP_LEN(cfg_info_group3),
                              CFG_GROUP_LEN(cfg_info_group4),
                              CFG_GROUP_LEN(cfg_info_group5),
                              CFG_GROUP_LEN(cfg_info_group6)};;
    
    GTP_INFO("  <%s>_%d \n", __func__, __LINE__);
   
    if(m89or101){
        if (ts->cfg_file_num) {
            send_cfg_buf[0] = gtp_dat_8_9_1;
            cfg_info_len[0] =  CFG_GROUP_LEN(gtp_dat_8_9_1);
        } else {
            send_cfg_buf[0] = gtp_dat_8_9;
            cfg_info_len[0] =  CFG_GROUP_LEN(gtp_dat_8_9);
        }
    }
    
    if (bgt911) {
        send_cfg_buf[0] = gtp_dat_gt11;
        cfg_info_len[0] =  CFG_GROUP_LEN(gtp_dat_gt11);
    }

    if (bgt970) {
        send_cfg_buf[0] = gtp_dat_9_7;
        cfg_info_len[0] = CFG_GROUP_LEN(gtp_dat_9_7);
    }

    if (bgt910) {
        send_cfg_buf[0] = gtp_dat_7;
        cfg_info_len[0] = CFG_GROUP_LEN(gtp_dat_7);
    }

    GTP_DEBUG_FUNC();
    GTP_DEBUG("Config Groups\' Lengths: %d, %d, %d, %d, %d, %d", 
        cfg_info_len[0], cfg_info_len[1], cfg_info_len[2], cfg_info_len[3],
        cfg_info_len[4], cfg_info_len[5]);

    
#if GTP_COMPATIBLE_MODE
    if (CHIP_TYPE_GT9F == ts->chip_type)
    {
        ts->fw_error = 0;
    }
    else
#endif
    {
        ret = gtp_i2c_read_dbl_check(ts->client, 0x41E4, opr_buf, 1);
        if (SUCCESS == ret) 
        {
            if (opr_buf[0] != 0xBE)
            {
                ts->fw_error = 1;
                GTP_ERROR("Firmware error, no config sent!");
                return -1;
            }
        }
    }

    if ((!cfg_info_len[1]) && (!cfg_info_len[2]) && 
        (!cfg_info_len[3]) && (!cfg_info_len[4]) && 
        (!cfg_info_len[5]))
    {
        sensor_id = 0; 
    }
    else
    {
    #if GTP_COMPATIBLE_MODE
        msleep(50);
    #endif
        ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_SENSOR_ID, &sensor_id, 1);
        if (SUCCESS == ret)
        {
            if (sensor_id >= 0x06)
            {
                GTP_ERROR("Invalid sensor_id(0x%02X), No Config Sent!", sensor_id);
                ts->pnl_init_error = 1;
                return -1;
            }
        }
        else
        {
            GTP_ERROR("Failed to get sensor_id, No config sent!");
            ts->pnl_init_error = 1;
            return -1;
        }
        GTP_INFO("Sensor_ID: %d", sensor_id);
    }
    ts->gtp_cfg_len = cfg_info_len[sensor_id];
    GTP_INFO("CTP_CONFIG_GROUP%d used, config length: %d", sensor_id + 1, ts->gtp_cfg_len);
    
    if (ts->gtp_cfg_len < GTP_CONFIG_MIN_LENGTH)
    {
        GTP_ERROR("Config Group%d is INVALID CONFIG GROUP(Len: %d)! NO Config Sent! You need to check you header file CFG_GROUP section!", sensor_id+1, ts->gtp_cfg_len);
        ts->pnl_init_error = 1;
        return -1;
    }

#if GTP_COMPATIBLE_MODE
    if (CHIP_TYPE_GT9F == ts->chip_type)
    {
        ts->fixed_cfg = 0;
    }
    else
#endif
    {
        ret = gtp_i2c_read_dbl_check(ts->client, GTP_REG_CONFIG_DATA, &opr_buf[0], 1);
        
        if (ret == SUCCESS)
        {
            GTP_DEBUG("CFG_GROUP%d Config Version: %d, 0x%02X; IC Config Version: %d, 0x%02X", sensor_id+1, 
                        send_cfg_buf[sensor_id][0], send_cfg_buf[sensor_id][0], opr_buf[0], opr_buf[0]);
            
            if (opr_buf[0] < 90)    
            {
                GTP_INFO("  <%s>_%d \n", __func__, __LINE__);
                grp_cfg_version = send_cfg_buf[sensor_id][0];       // backup group config version
                send_cfg_buf[sensor_id][0] = 0x00;
                ts->fixed_cfg = 0;
            }
            else        // treated as fixed config, not send config
            {
                GTP_INFO("Ic fixed config with config version(%d, 0x%02X)", opr_buf[0], opr_buf[0]);
                ts->fixed_cfg = 1;
                gtp_get_info(ts);
                return 0;
            }
        }
        else
        {
            GTP_ERROR("Failed to get ic config version!No config sent!");
            return -1;
        }
    }
    
    memset(&config[GTP_ADDR_LENGTH], 0, GTP_CONFIG_MAX_LENGTH);
    memcpy(&config[GTP_ADDR_LENGTH], send_cfg_buf[sensor_id], ts->gtp_cfg_len);

#if GTP_CUSTOM_CFG
    config[RESOLUTION_LOC]     = (u8)GTP_MAX_WIDTH;
    config[RESOLUTION_LOC + 1] = (u8)(GTP_MAX_WIDTH>>8);
    config[RESOLUTION_LOC + 2] = (u8)GTP_MAX_HEIGHT;
    config[RESOLUTION_LOC + 3] = (u8)(GTP_MAX_HEIGHT>>8);
    
    if (GTP_INT_TRIGGER == 0)  //RISING
    {
        config[TRIGGER_LOC] &= 0xfe; 
    }
    else if (GTP_INT_TRIGGER == 1)  //FALLING
    {
        config[TRIGGER_LOC] |= 0x01;
    }
#endif  // GTP_CUSTOM_CFG
    
    check_sum = 0;
    for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++)
    {
        check_sum += config[i];
    }
    config[ts->gtp_cfg_len] = (~check_sum) + 1;

#else // driver not send config

    ts->gtp_cfg_len = GTP_CONFIG_MAX_LENGTH;
    ret = gtp_i2c_read(ts->client, config, ts->gtp_cfg_len + GTP_ADDR_LENGTH);
    if (ret < 0)
    {
        GTP_ERROR("Read Config Failed, Using Default Resolution & INT Trigger!");
        //ts->abs_x_max = GTP_MAX_WIDTH;
        //ts->abs_y_max = GTP_MAX_HEIGHT;
        ts->int_trigger_type = GTP_INT_TRIGGER;
    }
    
#endif // GTP_DRIVER_SEND_CFG

    if ((ts->abs_x_max == 0) && (ts->abs_y_max == 0))
    {
        ts->abs_x_max = (config[RESOLUTION_LOC + 1] << 8) + config[RESOLUTION_LOC];
        ts->abs_y_max = (config[RESOLUTION_LOC + 3] << 8) + config[RESOLUTION_LOC + 2];
        ts->int_trigger_type = (config[TRIGGER_LOC]) & 0x03; 
        GTP_INFO("  <%s>_%d    <%d, %d>\n", __func__, __LINE__, ts->abs_x_max, ts->abs_y_max);
    }
    GTP_INFO("  <%s>_%d \n", __func__, __LINE__);
#if GTP_COMPATIBLE_MODE
    if (CHIP_TYPE_GT9F == ts->chip_type)
    {
        u8 sensor_num = 0;
        u8 driver_num = 0;
        u8 have_key = 0;
        
        have_key = (config[GTP_REG_HAVE_KEY - GTP_REG_CONFIG_DATA + 2] & 0x01);
        
        if (1 == ts->is_950)
        {
            driver_num = config[GTP_REG_MATRIX_DRVNUM - GTP_REG_CONFIG_DATA + 2];
            sensor_num = config[GTP_REG_MATRIX_SENNUM - GTP_REG_CONFIG_DATA + 2];
            if (have_key)
            {
                driver_num--;
            }
            ts->bak_ref_len = (driver_num * (sensor_num - 1) + 2) * 2 * 6;
        }
        else
        {
            driver_num = (config[CFG_LOC_DRVA_NUM] & 0x1F) + (config[CFG_LOC_DRVB_NUM]&0x1F);
            if (have_key)
            {
                driver_num--;
            }
            sensor_num = (config[CFG_LOC_SENS_NUM] & 0x0F) + ((config[CFG_LOC_SENS_NUM] >> 4) & 0x0F);
            ts->bak_ref_len = (driver_num * (sensor_num - 2) + 2) * 2;
        }
    
        GTP_INFO("Drv * Sen: %d * %d(key: %d), X_MAX: %d, Y_MAX: %d, TRIGGER: 0x%02x",
           driver_num, sensor_num, have_key, ts->abs_x_max,ts->abs_y_max,ts->int_trigger_type);
        return 0;
    }
    else
#endif
    {
    #if GTP_DRIVER_SEND_CFG
        GTP_INFO("  <%s>_%d \n", __func__, __LINE__);
        ret = gtp_send_cfg(ts->client);
        if (ret < 0)
        {
            GTP_ERROR("Send config error.");
        }
        // set config version to CTP_CFG_GROUP, for resume to send config
        config[GTP_ADDR_LENGTH] = grp_cfg_version;
        check_sum = 0;
        for (i = GTP_ADDR_LENGTH; i < ts->gtp_cfg_len; i++)
        {
            check_sum += config[i];
        }
        config[ts->gtp_cfg_len] = (~check_sum) + 1;
    #endif
        GTP_INFO("X_MAX: %d, Y_MAX: %d, TRIGGER: 0x%02x", ts->abs_x_max,ts->abs_y_max,ts->int_trigger_type);
    }
    
    msleep(10);
    return 0;
}

6 测试触摸屏

查看触摸屏中断次数及驱动加载是否正常
cat /proc/interrupts
在这里插入图片描述
Hexdump来查看是否有上报坐标信息。可借助Tslib工具测试触摸屏是否打印正确的坐标信息。
hexdump /dev/input/event1
在这里插入图片描述

7 TP初始化打印数据

在这里插入图片描述

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林深见麋鹿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值