RK3288 android7.1 适配 ilitek i2c接口TP

一,Ilitek 触摸屏简介

  1. Ilitek 提供多种型号的触控屏控制器,如 ILI6480、ILI9341 等,采用 I2C 接口。
    这些控制器能够支持多点触控,并具有优秀的灵敏度和响应速度。

  2. Ilitek 的触摸屏控制器监测屏幕上的触摸事件。
    当触摸发生时,控制器将触摸坐标(通常是 x 和 y 坐标)通过 I2C 总线发送给主机。


二,DTS配置

在这里插入图片描述

&i2c1 {status = "okay";ilitek@41 {compatible = "tchip,ilitek";reg = <0x41>;ilitek,irq-gpio = <&gpio7 6 GPIO_ACTIVE_HIGH>;ilitek,reset-gpio = <&gpio7 15 GPIO_ACTIVE_HIGH>; //修改相对应的gpio参数pinctrl-names = "default";pinctrl-0 = <&ilitek_gpio_e>;status = "okay";};
};&pinctrl {touchscreen {ilitek_gpio_e: ilitek-gpio-e {rockchip,pins =<7 6 RK_FUNC_GPIO &pcfg_pull_up>,<7 15 RK_FUNC_GPIO &pcfg_pull_up>;};};
};

注:一定要对应的I2C bus节点(硬件原理图上会有标注)。


三,驱动文件配置

在这里插入图片描述

1. ilitek_lim.c

static int ilitek_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id)
{int ret = 0;int revert_x=0;int revert_y=0;int revert_x_y=0;struct device_node *param_node;
#ifdef ILI_UPDATE_FW#ifdef UPDATE_THREADEstruct task_struct *thread_update = NULL;#endif
#endif#ifdef RECOGNITION_LONGTIME_BUTTON
struct task_struct *thread_longtime_button = NULL;
#endif#ifdef WRITE_2210_CFGstruct task_struct *thread_write_cfg = NULL;
#endif#if IC2120int i = 0;
#endif//int i = 0;//uint8_t buf[8] = {0};
#ifdef DEBUG_NETLINKstruct netlink_kernel_cfg cfg = {.groups = 0,.input	= udp_receive,};#endiftp_log_info("Enter ilitek_i2c_probe +++++++++ client->addr = 0x%x++++++\n", client->addr);if(!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)){tp_log_err("%s, I2C_FUNC_I2C not support\n", __func__);return -1;}// initialize global variable#ifdef TOOLmemset(&dev_ilitek, 0, sizeof(struct dev_data));#endifmemset(&i2c, 0, sizeof(struct i2c_data));// initialize mutex object
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37)init_MUTEX(&i2c.wr_sem);
#elsesema_init(&i2c.wr_sem,1);
#endifi2c.wr_sem.count = 1;mutex_init(&(i2c.irq_mutex));i2c.report_status = 1;i2c.client = client;#ifdef CONFIG_ENABLE_REGULATOR_POWER_ONret = ilitek_get_regulator();if (ret) {tp_log_err("%s, ilitek_get_regulator failed\n", __func__);return ret;}ret = ilitek_power_on(true);if (ret) {tp_log_err("%s, power on failed\n", __func__);return ret;}#endif//ret = ilitek_request_io_port(client);if (ret != 0){tp_log_err("%s, io error", __func__);return ret;}param_node = of_find_node_by_path("/smdt_param");if (!param_node){printk("gt9xx wxl error smdt_param not node!!!\n");}of_property_read_u32(param_node, "ctp_revert_x_flag", &revert_x);of_property_read_u32(param_node, "ctp_revert_y_flag", &revert_y);of_property_read_u32(param_node, "ctp_exchange_x_y_flag", &revert_x_y);if(revert_x == 1 )REVERT_X = 1;else    REVERT_X = 0;if(revert_y == 1 )REVERT_Y = 1;else    REVERT_Y = 0;if(revert_x_y == 1 )EXCHANG_XY = 1;else    EXCHANG_XY = 0;i2c.client->irq  = gpio_to_irq(i2c.irq_gpio);tp_log_info("ilitek i2c.irq_gpio = %d, i2c.client->irq = %d\n", i2c.irq_gpio, i2c.client->irq);i2c.valid_i2c_register = 1;#if 1ilitek_reset(i2c.reset_gpio);#endif#if !IC2120mdelay(200);#elsefor (i = 0; i < 30; i++ ) {ret = ilitek_poll_int();tp_log_info("ilitek int status = %d\n", ret);if (ret == 0) {break;}else {mdelay(5);}}if (i >= 30) {#ifdef ILI_UPDATE_FWtp_log_info("ilitek reset but int not pull low so driver_upgrade_flag = true\n");driver_upgrade_flag = true;#endif}else #endif{#if 0msleep(2000);for (i = 0; i < 127; i++) {//buf[0] = 0x10;client->addr = i;ret = ilitek_i2c_write_and_read(i2c.client, buf, 0, 10, buf, 4);tp_log_info("ilitek %s, write 0x10 read buf = %X, %X, %X\n", __func__, buf[0], buf[1], buf[2]);if (ret < 0) {mdelay(5);}else {tp_log_info("ilitek %s, client->addr = 0x%X, read buf = %X, %X, %X\n", __func__, client->addr, buf[0], buf[1], buf[2]);tp_log_info("ilitek %s, client->addr = 0x%X, read buf = %X, %X, %X\n", __func__, client->addr, buf[0], buf[1], buf[2]);tp_log_info("ilitek %s, client->addr = 0x%X, read buf = %X, %X, %X\n", __func__, client->addr, buf[0], buf[1], buf[2]);tp_log_info("ilitek %s, client->addr = 0x%X, read buf = %X, %X, %X\n", __func__, client->addr, buf[0], buf[1], buf[2]);tp_log_info("ilitek %s, client->addr = 0x%X, read buf = %X, %X, %X\n", __func__, client->addr, buf[0], buf[1], buf[2]);break;}}#endif// read touch parameterret = ilitek_i2c_read_tp_info();if(ret < 0){tp_log_err("ilitek read tp info fail free gpio\n");if (gpio_is_valid(i2c.irq_gpio)) {gpio_free(i2c.irq_gpio);}if (gpio_is_valid(i2c.reset_gpio)) {gpio_free(i2c.reset_gpio);}return ret;}}
#ifdef CLOCK_INTERRUPT
#ifdef REPORT_THREADi2c.thread = kthread_run(ilitek_i2c_touchevent_thread, NULL, "ilitek_i2c_thread");if(i2c.thread == (struct task_struct*)ERR_PTR){i2c.thread = NULL;tp_log_err("%s, kthread create, error\n", __func__);}
#endif
#endifilitek_handle_irqorpolling();i2c.input_dev = input_allocate_device();if(i2c.input_dev == NULL){tp_log_err("%s, allocate input device, error\n", __func__);return -1;}ilitek_set_input_param(i2c.input_dev, i2c.max_tp, i2c.max_x, i2c.max_y);ret = input_register_device(i2c.input_dev);if(ret){tp_log_err("%s, register input device, error\n", __func__);return ret;}i2c.valid_input_register = 1;tp_log_info("%s, register input device, success\n", __func__);
#ifdef ILI_UPDATE_FW#ifndef UPDATE_THREADE{update_wait_flag = 1;ret = ilitek_upgrade_firmware();if(ret == ILITEK_UPDATE_OK) {tp_log_info("update end\n");}else if(ret == ILITEK_I2C_TRANSFER_ERR) {tp_log_info("i2c communication error\n");}if(i2c.reset_request_success){ilitek_reset(i2c.reset_gpio);}// read touch parameterret=ilitek_i2c_read_tp_info();if(ret < 0){tp_log_err("ilitek_i2c_read_tp_info err\n");return ret;}update_wait_flag = 0;#if 1input_unregister_device(i2c.input_dev);#if 1i2c.input_dev = input_allocate_device();if(i2c.input_dev == NULL){tp_log_err("%s, allocate input device, error\n", __func__);return -1;}#endif// register input device//memset(i2c.input_dev, 0, sizeof(struct input_dev));// register input deviceilitek_set_input_param(i2c.input_dev, i2c.max_tp, i2c.max_x, i2c.max_y);ret = input_register_device(i2c.input_dev);if(ret){tp_log_err("%s, register input device, error\n", __func__);return ret;}tp_log_info("%s, register input device, success\n", __func__);#endif}#else{thread_update= kthread_run(ilitek_i2c_update_thread, NULL, "ilitek_i2c_updatethread");if(thread_update == (struct task_struct*)ERR_PTR){thread_update = NULL;tp_log_err("%s,thread_update kthread create, error\n", __func__);}}#endif
#endif#ifdef WRITE_2210_CFGthread_write_cfg = kthread_run(ilitek_i2c_write_cfg_thread, NULL, "ilitek_i2c_write_cfg_thread");if(thread_write_cfg == (struct task_struct*)ERR_PTR){thread_write_cfg = NULL;tp_log_err("%s,thread_write_cfg kthread create, error\n", __func__);}
#endif#ifdef RECOGNITION_LONGTIME_BUTTONthread_longtime_button = kthread_run(ilitek_i2c_check_longtime_button_thread, NULL, "ilitek_i2c_check_longtime_button_thread");if(thread_longtime_button == (struct task_struct*)ERR_PTR){thread_longtime_button = NULL;tp_log_err("%s,thread_longtime_button kthread create, error\n", __func__);}
#endif#ifdef GESTUREilitek_system_resume = 1;input_set_capability(i2c.input_dev, EV_KEY, KEY_POWER);input_set_capability(i2c.input_dev, EV_KEY, KEY_W);input_set_capability(i2c.input_dev, EV_KEY, KEY_LEFT);input_set_capability(i2c.input_dev, EV_KEY, KEY_RIGHT);input_set_capability(i2c.input_dev, EV_KEY, KEY_UP);input_set_capability(i2c.input_dev, EV_KEY, KEY_DOWN);input_set_capability(i2c.input_dev, EV_KEY, KEY_O);input_set_capability(i2c.input_dev, EV_KEY, KEY_C);input_set_capability(i2c.input_dev, EV_KEY, KEY_E);input_set_capability(i2c.input_dev, EV_KEY, KEY_M);
#endif#ifdef TOOLret = create_tool_node();
#endif#ifdef SENSOR_TEST
#ifdef SYS_ATTR_FILEilitek_sensor_test_init();
#endif
#endif#ifdef HALL_CHECK
#if HALL_CHECK == HALL_CHECK_OTHERilitek_hall_check_init();	
#elif HALL_CHECK == HALL_CHECK_HWilitek_hall_check_hw_init();	
#endif //end of HALL_CHECK
#endifReport_Flag=0;#ifdef PLAT_ROCKCHIPi2c.tp.tp_resume = ilitek_i2c_late_resume;i2c.tp.tp_suspend = ilitek_i2c_early_suspend;tp_register_fb(&i2c.tp);
#endif#ifdef ILITEK_ESD_CHECKINIT_DELAYED_WORK(&esd_work, ilitek_touch_esd_func);esd_wq = create_singlethread_workqueue("esd_wq");	 if (!esd_wq) {return -ENOMEM;}queue_delayed_work(esd_wq, &esd_work, delay);
#endif #ifdef WRITE_2210_CFGret = sysfs_create_group(&client->dev.kobj, &ilitek_test_attribute_group);if (ret) {dev_err(&client->dev, "failed to create sysfs attributes: %d\n",ret);return ret;}
#endif
#ifdef DEBUG_NETLINK//netlink_sock = netlink_kernel_create(&init_net, 21, 0,udp_receive, NULL, THIS_MODULE);netlink_sock = netlink_kernel_create(&init_net, 21, &cfg);#endifdevice_init_wakeup(&client->dev, 1);return 0;
}

ilitek_i2c_probe 函数是 I2C 设备的初始化函数,在设备被识别和加载驱动时调用。它的主要职责包括:

  • 初始化设备:根据 I2C 客户端信息和设备 ID 来配置和初始化设备。
  • 分配所需资源:如内存、GPIO 等。
  • 设置中断处理程序(如适用):为设备配置中断。
  • 注册输入设备:根据设备类型设置输入设备的相关参数。

2. ilitek_ts.h

ilitek_ts.h用于定义驱动相关的数据结构、常量、函数原型以及其他必要的包含。该头文件的内容用于抽象和管理与 Ilitek 触摸屏控制器之间的接口。

3. ILI25110CN080O0003_CRC.ili

ILI25110CN080O0003_CRC.ili 可能是与 Ilitek 触摸屏控制器 ILI2511 系列相关的文件。

4. 驱动移植

a.将原厂提供的的驱动(ilitek)拷贝到下面的文件夹:

./kernel/drivers/input/touchscreen

b. 然后修改 touchscreen 目录下的 Makefile以及Kconfig。这个Makefile中定义的就是要编译哪个平台的触摸屏驱动的。

kernel/drivers/input/touchscreen/Makefile中添加:
obj-$(CONFIG_TOUCHSCREEN_ILITEK)     += ilitek/--------------------------------------------------------
kernel/drivers/input/touchscreen/Kconfig中添加:
config TOUCHSCREEN_ILITEKtristate "ILITEK touchscreens matched with screen support for rockchip platform"depends on I2C && ARCH_ROCKCHIPhelpSay Y here if you have a touchscreen interface using the ILITEKtouchscreen chip on Rockchip platform, and your board-specificinitialization code includes that in its table of IIC devices.If unsure, say N.

c. 内核中加载驱动:

kernel/arch/arm/configs/rockchip_defconfig中添加:
CONFIG_TOUCHSCREEN_ILITEK=y

四,调试

  1. 确认 /sys/bus/i2c/devices 下有裝置节点 (-0041);
    在这里插入图片描述
  2. 报点问题:
    有触摸效果,只是坐标 mapping 问题。

X、Y 需要交換。
將 ILITEK_ROTATE_FLAG 设定值由 0 改为 1 或由 1 改为 0。

X、Y 值要做鏡像变化。
將 ILITEK_REVERT_X 或 ILITEK_REVERT_Y 的设定值由 0 改为 1 或由 1 改为 0。

若需要指定显示屏的解析度。
则开放 ILITEK_USE_LCM_RESOLUTION 宏,同时將TOUCH_SCREEN_X_MAX 和 TOUCH_SCREEN_Y_MAX 设为正确值。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/467721.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows系统中Oracle VM VirtualBox的安装

一.背景 公司安排了师带徒&#xff0c;环境搭建问题一直是初级程序员头疼的事情&#xff0c;我记录一下这些基础的内容&#xff0c;方便初学者。大部分开发者的机器还是windows系统&#xff0c;所以写了怎么安装。 二.版本信息及 操作系统&#xff1a;windows11 家庭版…

HTTP的了解

从输入 URL 到页面展示到底发生了什么&#xff1f;&#xff08;非常重要&#xff09; 类似的问题&#xff1a;打开一个网页&#xff0c;整个过程会使用哪些协议&#xff1f; 先来看一张图&#xff08;来源于《图解 HTTP》&#xff09;&#xff1a; 上图有一个错误需要注意&…

2-149 基于matlab的LDPC译码性能分析

基于matlab的LDPC译码性能分析&#xff0c;LDPC&#xff08;Low-Density Parity-Check&#xff09;码作为编码技术&#xff0c;具有优秀的纠错性能和较低的编解码复杂度。为保证可靠的数据传输&#xff0c;对传输过程中可能出现的信道噪声、干扰等进行模拟和分析。分析对比了误…

医学可视化之热力图

在医学领域&#xff0c;热力图是另一种非常有用的可视化工具&#xff0c;它能够以独特的方式展示数据的密度和趋势。 一、热力图的特点 热力图是一种通过颜色变化来表示数据密度或趋势的可视化图表。它通常将数据值映射到不同的颜色区间&#xff0c;颜色越深表示数据值越高&a…

YOLOv11融合[ECCV2024]自调制特征聚合SMFA模块及相关改进思路|YOLO改进最简教程

YOLOv11v10v8使用教程&#xff1a; YOLOv11入门到入土使用教程 YOLOv11改进汇总贴&#xff1a;YOLOv11及自研模型更新汇总 《SMFANet: A Lightweight Self-Modulation Feature Aggregation Network for Efficient Image Super-Resolution》 一、 模块介绍 论文链接&#xff1…

【C++】C++移动语义、左值右值、左值引用右值引用、移动构造函数、std::move、移动赋值操作符

二十五、C移动语义、左值和右值、左值引用右值引用、移动构造函数、std::move、移动赋值操作符 本部分讨论一些更高级的C特性&#xff1a;C移动语义。但是讲移动语义之前我们得先了解什么左值右值、左值引用和右值引用。 1、C的左值和右值、左值引用和右值引用左值是有地址的…

三菱QD77MS定位模块速度更改功能

速度更改功能” 是以任意时机将控制中的速度更改为新指定的速度的功能。更改后的速度直接设置到缓冲存储器中&#xff0c;并根据速度更改指令([cd.15速度更改请求)或者外部指令信号执行速度更改。 但是&#xff0c;机械原点复位的情况下&#xff0c;检测出近点狗 ON 并开始向蠕…

【Django】视图函数

【Django】视图函数 视图函数的本质是Python中的函数&#xff0c;视图函数负责处理用户的请求并返回响应&#xff0c;该响应可以是网页的HTML内容、重定向、404错误、XML文档、图像或者任何东西&#xff0c;一般在应用中的views.py编写&#xff0c;示例代码如下&#xff1a; …

Git 入门篇(二)

前言 Git 入门篇&#xff08;一&#xff09; Git 入门篇&#xff08;二&#xff09; Git 入门篇&#xff08;三&#xff09; 目录 创建远程代码仓库 创建本地代码仓库 同步本地-远程代码仓库 代码托管 创建远程代码仓库 登录&#xff1a;gitee.com ​ 新建仓库 ​ 创建本…

PLC_博图系列☞基本指令”TOF:启动关断延时定时器“

PLC_博图系列☞基本指令”TOF&#xff1a;启动关断延时定时器“ 文章目录 PLC_博图系列☞基本指令”TOF&#xff1a;启动关断延时定时器“背景介绍TOF&#xff1a; 启动关断延时定时器说明参数脉冲时序图示例 关键字&#xff1a; PLC、 西门子、 博图、 Siemens 、 TOF 背…

【RabbitMQ】之高可用集群搭建

一、RabbitMQ 集群简介 1、默认集群原理1-1、RabbitMQ 集群简介 单台 RabbitMQ 服务器处理消息的能力是有瓶颈的&#xff0c;而且可靠性还无法保证&#xff0c;所以需要通过集群来提高消息的吞吐量和提高数据可靠性。 由于 RabbitMQ 本身是基于 Erlang 编写&#xff0c;而 Er…

改进系列(3):基于ResNet网络与CBAM模块融合实现的生活垃圾分类

目录 1. ResNet介绍 2. CBAM 模块 3. resnet cbam 3.1 添加在每个layer层后 3.2 关于训练的建议 4. 垃圾分类实战 4.1 数据集 4.2 训练 4.3 最好的权重 4.4 推理 5. 其它 1. ResNet介绍 ResNet&#xff08;残差网络&#xff09;是一种深度卷积神经网络模型&#xf…

Linux 服务器上部署 .NET Core 应用程序,值得收藏!

在 Linux 服务器上部署 .NET Core 应用程序&#xff0c;标志着传统的以微软为中心的部署平台的重大转变。.NET Core 的跨平台特性允许开发人员享受 Linux 环境的性能、可靠性和安全性。本指南提供了在各种 Linux 发行版上部署 .NET Core 应用程序的全面概述&#xff0c;重点是使…

2024-11-01 - 统一身份认证 - OpenLdap - 中间件 - 流雨声

摘要 2024-11-01 周五 杭州 暴雨 调查问卷: https://www.wjx.cn/vm/exIBFDM.aspx# 2024年转瞬即逝&#xff0c;可是生活还在继续&#xff0c;这里有一项关于人工智能和项目管理对于效能关系的调研问卷&#xff0c;AI 对工作的作用和影响。问卷不采集个人信息&#xff0c;在此…

前端页面性能优化的常见问题与解决方案

在当今互联网高速发展的时代&#xff0c;前端页面的性能对于用户体验至关重要。一个加载缓慢、交互卡顿的页面很可能会导致用户流失。本文将深入探讨前端页面性能优化中常见的问题以及相应的解决方案。 一、常见问题 &#xff08;一&#xff09;资源加载问题 文件体积过大 …

视频播放相关的杂记

基于QT FFMPEG设计一款 RTMP协议推流、视频录制软件 实现的功能&#xff1a; &#xff08;1&#xff09;将摄像头视频流 麦克风音频流合并&#xff0c;并推到流媒体服务器 &#xff08;2&#xff09;将摄像头视频流 麦克风音频流保存到本地磁盘 基于QtFFMPEG设计一款RTM…

Pycharm,2024最新版Pycharm下载安装配置教程!

目录 1、Pycharm 简介2、Pycharm下载3、环境变量的配置4、Pycharm的使用 1、Pycharm 简介 Pycharm资料领取不收米 PyCharm是一种Python IDE&#xff08;Integrated Development Environment&#xff0c;集成开发环境&#xff09;&#xff0c;带有一整套可以帮助用户在使用Py…

Redis9:商户查询缓存3

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…

解锁函数的魔力:Python 中的多值传递、灵活参数与无名之美

文章目录 前言&#x1f4d6;一、多值返回&#x1f4da;1.1 多值返回的概念&#x1f4da;1.2 工作原理&#x1f4da;1.3 应用场景&#x1f4dc;总结 &#x1f4d6;二、 多种参数传递形式&#x1f4da;2.1 位置参数&#xff08;Positional Arguments&#xff09;&#x1f4da;2.2…

若依框架-添加测试类-最新

1、在【ruoyi-admin】的pom.xml下添加依赖 <!-- 单元测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-test</artifactId><scope>test</scope></dependency><dependency>…