平台

开发板:tq2440
内核:Linux-4.9
u-boot:u-boot-2015.04

概述

之前移植了LCD驱动,下面继续移植触摸屏驱动,然后将tslib也移植上去。

正文

一、移植触摸屏驱动

为了简单起见我们对TQ2440自带的触摸屏驱动进行改写,改成设备树的形式。
1、设备树
触摸屏使用了两个中断,如下:
这两个中断是子中断,隶属于主中断INT_ADC:
关于寄存器,参考芯片手册的第16章,知道了上面的信息,我们就可以得到如下的设备树节点(可以参考博文基于设备树的TQ2440的中断(1)):
tq2440ts@5800000{
compatible= "tq2440,ts";
reg= <0x58000000 0x100>;
reg-names = "adc_ts_physical";
interrupts= <1 31 9 3>, <1 31 10 3>;
interrupt-names = "int_ts", "int_adc_s";
clocks= <&clocks PCLK_ADC>;
clock-names = "adc";
};

2、驱动
对应的触摸屏驱动是drivers/input/touchscreen/tq2440_ts.c
这部分我已经上传到github上面了,可以使用下面的命令下载:
git clone git@github.com:pengdonglin137/linux-4.9.git -b tq2440_dt

代码如下:

1 /*************************************2
3 NAME:tq2440_ts.c4 COPYRIGHT:www.embedsky.net5
6 *************************************/
7 #include <linux/errno.h>
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/slab.h>
11 #include <linux/input.h>
12 #include <linux/init.h>
13 #include <linux/serio.h>
14 #include <linux/delay.h>
15 #include <linux/platform_device.h>
16 #include <linux/clk.h>
17 #include <linux/of_device.h>
18 #include <linux/of.h>
19 #include <linux/of_gpio.h>
20 #include <asm/io.h>
21 #include <asm/irq.h>
22
23 #include <plat/regs-adc.h>
24 #include <mach/regs-gpio.h>
25
26 /*For ts.dev.id.version*/
27 #define S3C2410TSVERSION    0x0101
28
29 #define WAIT4INT(x)  (((x)<<8) | \
30     S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN |\31     S3C2410_ADCTSC_XY_PST(3))32
33 #define AUTOPST         (S3C2410_ADCTSC_YM_SEN | S3C2410_ADCTSC_YP_SEN | S3C2410_ADCTSC_XP_SEN | \
34     S3C2410_ADCTSC_AUTO_PST | S3C2410_ADCTSC_XY_PST(0))35
36 static char *tq2440ts_name = "TQ2440 TouchScreen";37
38 static    struct input_dev *idev;39 static    longxp;40 static    longyp;41 static    intcount;42
43 static void __iomem *base_addr;44
45 static void touch_timer_fire(unsigned longdata)46 {47 u32 data0;48 u32 data1;49     intupdown;50
51     data0 = readl(base_addr+S3C2410_ADCDAT0);52     data1 = readl(base_addr+S3C2410_ADCDAT1);53
54     updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 &S3C2410_ADCDAT0_UPDOWN));55
56     if(updown) {57         if (count != 0) {58             longtmp;59
60             tmp =xp;61             xp =yp;62             yp =tmp;63
64             xp >>= 2;65             yp >>= 2;66
67 input_report_abs(idev, ABS_X, xp);68 input_report_abs(idev, ABS_Y, yp);69
70             input_report_key(idev, BTN_TOUCH, 1);71             input_report_abs(idev, ABS_PRESSURE, 1);72 input_sync(idev);73 }74
75         xp = 0;76         yp = 0;77         count = 0;78
79         writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);80         writel(readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);81     } else{82         count = 0;83
84         input_report_key(idev, BTN_TOUCH, 0);85         input_report_abs(idev, ABS_PRESSURE, 0);86 input_sync(idev);87
88         writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);89 }90 }91
92 static struct timer_list touch_timer =
93 TIMER_INITIALIZER(touch_timer_fire, 0, 0);94
95 static irqreturn_t stylus_updown(int irq, void *dev_id)96 {97 u32 data0;98 u32 data1;99     intupdown;100
101     data0 = readl(base_addr+S3C2410_ADCDAT0);102     data1 = readl(base_addr+S3C2410_ADCDAT1);103
104     updown = (!(data0 & S3C2410_ADCDAT0_UPDOWN)) && (!(data1 &S3C2410_ADCDAT0_UPDOWN));105
106     if(updown)107         touch_timer_fire(0);108
109     returnIRQ_HANDLED;110 }111
112 static irqreturn_t stylus_action(int irq, void *dev_id)113 {114 u32 data0;115 u32 data1;116
117     data0 = readl(base_addr+S3C2410_ADCDAT0);118     data1 = readl(base_addr+S3C2410_ADCDAT1);119
120     xp += data0 &S3C2410_ADCDAT0_XPDATA_MASK;121     yp += data1 &S3C2410_ADCDAT1_YPDATA_MASK;122     count++;123
124     if (count < (1<<2)) {125         writel(S3C2410_ADCTSC_PULL_UP_DISABLE | AUTOPST, base_addr+S3C2410_ADCTSC);126         writel(readl(base_addr+S3C2410_ADCCON) | S3C2410_ADCCON_ENABLE_START, base_addr+S3C2410_ADCCON);127     } else{128         mod_timer(&touch_timer, jiffies+1);129         writel(WAIT4INT(1), base_addr+S3C2410_ADCTSC);130 }131
132     returnIRQ_HANDLED;133 }134
135 static int tq2440ts_probe(struct platform_device *pdev)136 {137     struct device *dev = &pdev->dev;138     struct device_node *node = dev->of_node;139     struct clk    *adc_clock;140     struct resource *tsmem, *irq;141     struct input_dev *input_dev;142     intret;143
144     if (!node) {145         dev_dbg(dev, "of_node is NULL\n");146         return -EINVAL;147 }148
149     adc_clock = devm_clk_get(dev, "adc");150     dev_dbg(dev, "adc_clock: %p\n", adc_clock);151     if(IS_ERR(adc_clock)) {152         dev_err(dev, "cannot get clock\n");153         return -ENOENT;154 }155 clk_prepare(adc_clock);156 clk_enable(adc_clock);157
158     dev_dbg(dev, "get mem\n");159     tsmem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "adc_ts_physical");160     if (!tsmem) {161         dev_dbg(dev, "get mem resource failed.\n");162         ret = -EINVAL;163         gotoerr;164 }165
166     base_addr =devm_ioremap_resource(dev, tsmem);167     if(IS_ERR(base_addr)) {168         dev_dbg(dev, "ioremap failed.\n");169         ret =PTR_ERR(base_addr);170         gotoerr;171 }172
173     writel(S3C2410_ADCCON_PRSCEN | S3C2410_ADCCON_PRSCVL(0xFF),base_addr+S3C2410_ADCCON);174     writel(0xffff,  base_addr+S3C2410_ADCDLY);175     writel(WAIT4INT(0), base_addr+S3C2410_ADCTSC);176
177     input_dev =devm_input_allocate_device(dev);178     if (!input_dev) {179         dev_dbg(dev, "ioremap failed.\n");180         ret = -ENOMEM;181         gotoerr;182 }183
184     idev =input_dev;185     idev->evbit[0] = BIT(EV_SYN) | BIT(EV_KEY) |BIT(EV_ABS);186
187
188     __set_bit(EV_SYN, idev->evbit);189     __set_bit(EV_KEY, idev->evbit);190     __set_bit(EV_ABS, idev->evbit);191     __set_bit(BTN_TOUCH, idev->keybit);192
193     input_set_abs_params(idev, ABS_X, 0, 0x3FF, 0, 0);194     input_set_abs_params(idev, ABS_Y, 0, 0x3FF, 0, 0);195     input_set_abs_params(idev, ABS_PRESSURE, 0, 1, 0, 0);196
197     idev->name =tq2440ts_name;198     idev->id.bustype =BUS_RS232;199     idev->id.vendor = 0xDEAD;200     idev->id.product = 0xBEEF;201     idev->id.version =S3C2410TSVERSION;202
203     irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "int_ts");204     if (!irq) {205         dev_err(dev, "get irq resource int_ts failed.\n");206         ret = -EINVAL;207         gotoerr;208 }209     ret = devm_request_irq(dev, irq->start, stylus_updown, IRQF_ONESHOT, "int_ts", NULL);210     if (ret < 0){211         dev_err(dev, "request irq tsirq %d failed.\n", irq->start);212         gotoerr;213 }214
215     irq = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "int_adc_s");216     if (!irq) {217         dev_err(dev, "get irq resource int_adc_s failed.\n");218         ret = -EINVAL;219         gotoerr;220 }221     ret = devm_request_irq(dev, irq->start, stylus_action, IRQF_ONESHOT, "int_adc_s", NULL);222     if (ret < 0) {223         dev_err(dev, "request irq adcirq %d failed.\n", irq->start);224         gotoerr;225 }226
227     dev_info(dev, "%s successfully loaded\n", tq2440ts_name);228 input_register_device(idev);229
230     return 0;231 err:232 clk_disable(adc_clock);233     returnret;234 }235
236 static const struct of_device_id tq2440ts_match[] ={237     { .compatible = "tq2440,ts", .data = (void *)0},238 {},239 };240
241 static struct platform_driver tq2440ts_driver ={242     .probe        =tq2440ts_probe,243     .driver        ={244         .name    = "tq2440ts",245         .of_match_table =of_match_ptr(tq2440ts_match),246 },247 };248
249 static int __init tq2440ts_init(void)250 {251     return platform_driver_register(&tq2440ts_driver);252 }253
254 static void __exit tq2440ts_exit(void)255 {256     platform_driver_unregister(&tq2440ts_driver);257 }258
259 module_init(tq2440ts_init);260 module_exit(tq2440ts_exit);261
262 MODULE_LICENSE("GPL");

View Code

3、测试
查看中断信息:
[root@tq2440 ]# cat /proc/interrupts CPU07:        973  s3c-eint   7Edge      eth08:          0       s3c   8 Edge      s3c2410-rtc tick13:     559459       s3c  13Edge      samsung_time_irq16:          0       s3c  16Edge      4d000000.fb26:          0       s3c  26Edge      ohci_hcd:usb127:          4       s3c  27 Edge      54000000.i2c30:          0       s3c  30 Edge      s3c2410-rtc alarm32:        218  s3c-level  32 Level     50000000.serial33:      11203  s3c-level  33 Level     50000000.serial41:        758  s3c-level  41Edge      int_ts42:      16712  s3c-level  42Edge      int_adc_s59:          0  s3c-level  59 Edge      53000000.watchdog
Err:0

使用hexdump /dev/input/event0:

[root@tq2440 ]# hexdump /dev/input/event00000000 cb74 386e bc0b 000b 0003 0000 0201 0000
0000010 cb74 386e bc0b 000b 0003 0001 01e4 0000
0000020 cb74 386e bc0b 000b 0001 014a 0001 0000
0000030 cb74 386e bc0b 000b 0003 0018 0001 0000
0000040 cb74 386e bc0b 000b 0000 0000 0000 0000
0000050 cb74 386e 0a4e 000c 0003 0000 01dc 0000
0000060 cb74 386e 0a4e 000c 0003 0001 01fa 0000
0000070 cb74 386e 0a4e 000c 0000 0000 0000 0000
0000080 cb74 386e 585a 000c 0001 014a 0000 0000
0000090 cb74 386e 585a 000c 0003 0018 0000 0000

二、移植tslib

参考:
http://www.latelee.org/embedded-linux/porting-linux-tslib.html
http://www.it165.net/embed/html/201409/2656.html
登陆http://www.tslib.org/下载最新的版本:
https://github.com/kergoth/tslib/releases/download/1.10/tslib-1.10.tar.xz
或者tslib-1.10.tar.gz
编译安装:
#!/bin/bash./autogen.shmkdir install./configure  \--prefix="`pwd`/install"\--host=arm-linux  \
ac_cv_func_malloc_0_nonnull=yesmake
make install

安装完成后,可以看到:

$ls installbin/  etc/  include/  lib/  share/

将这些文件拷贝到开发板上面,然后修改板子上面的/etc/profile文件,添加如下内容:
echo "Set Env for Tslib"export TSLIB_ROOT=/export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_CONFFILE=$TSLIB_ROOT/etc/ts.conf
export TSLIB_PLUGINDIR=$TSLIB_ROOT/lib/ts
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONSOLEDEVICE=none
export TSLIB_FBDEVICE=/dev/fb0
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$TSLIB_ROOT/lib

修改完成后,重新启动开发板。

三、测试

运行ts_calibrate生成校准数据
[root@tq2440 ]# ts_calibrate
xres= 480, yres = 272Took4samples...
Top left : X=  870 Y =  279Took8samples...
Top right : X=  162 Y =  277Took5samples...
Bot right : X=  156 Y =  757Took2samples...
Bot left : X=  688 Y =  660Took3samples...
Center : X=  517 Y =  522
582.617065 -0.602301 -0.108929
-72.806641 0.023253 0.396149Calibration constants:38182392 -39472 -7138 -4771456 1523 25962 65536 

运行ts_test测试:
[root@tq2440 ]# ts_test946785862.424089:    321    141      1
946785862.444036:    321    141      0
946785865.264038:     82    196      1
946785865.284058:     82    196      0
946785865.519036:     26    219      1
946785865.539107:     29    219      1
946785865.559054:     30    220      0
946785865.829038:    229    206      1

完。

基于设备树的TQ2440触摸屏驱动移植相关推荐

  1. 基于设备树的TQ2440的中断(2)

    下面以按键中断为例看看基于设备数的中断的用法: 设备树: tq2440_key {compatible = "tq2440,key";interrupt-parent = < ...

  2. 基于设备树的TQ2440 DMA学习(3)—— DMA控制器驱动

    作者 彭东林 pengdonglin137@163.com 平台 TQ2440 Linux-4.9 概述 上一篇直接操作DMA控制器实现了一个mem2mem的DMA传输,但是这样不符合linux dr ...

  3. 基于设备树的TQ2440 DMA学习(2)—— 简单的DMA传输

    作者 彭东林 pengdonglin137@163.com 平台 TQ2440 Linux-4.9 概述 上一篇博客分析了DMA控制器的寄存器,循序渐进,下面我们直接操作DMA控制器的寄存器实现一个m ...

  4. 基于设备树的中断实现 (24x0平台)

    文章目录 一.平台信息 1. 平台信息 二.中断的驱动实现方式 2. 不使用设备树的中断实现 2.1 mach-mini2440.c文件中注册中断 2.2 注册中断 3. 使用设备树的中断实现 设备树 ...

  5. 移植基于linux-2.6.26.5内核s3c2410触摸屏驱动移植

    移植基于linux-2.6.26.5内核s3c2410触摸屏驱动移植的过程记录下来: (1)首先打一个补丁:s3c2410_touchscreen.patch, 在内核解压的根目录下 patch -N ...

  6. Linux 设备树下的 platform 驱动实验基于正点原子IMX6ULL开发板

    1 设备树下的 platform 驱动简介 platform 驱动框架分为总线.设备和驱动,其中总线不需要我们这些驱动程序员去管理,这个是 Linux 内核提供的,我们在编写驱动的时候只要关注于设备和 ...

  7. NUC972触摸屏驱动移植过程分析(二)

    https://blog.csdn.net/b7376811/article/details/86607529 今天继续分析NUC972的触摸屏驱动移植过程,上一节主要分析了触摸屏需要数据,今天来分析 ...

  8. 设备树下的platform 驱动编写

    目录 设备树下的platform 驱动简介 硬件原理图分析 实验程序编写 修改设备树文件 platform 驱动程序编写 编写测试APP 运行测试 编译驱动程序和测试APP 运行测试 上一章我们详细的 ...

  9. 【正点原子Linux连载】第四十四章 设备树下的LED驱动实验 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0

    1)实验平台:正点原子阿尔法Linux开发板 2)平台购买地址:https://item.taobao.com/item.htm?id=603672744434 2)全套实验源码+手册+视频下载地址: ...

  10. Linux 设备树下的 platform 驱动示例

    1.简介 基于总线.设备和驱动这样的驱动框架,Linux 内核提出来 platform 这个虚拟总线,相应的也有 platform 设备和 platform 驱动. Linux 总线设备和驱动模式 2 ...

最新文章

  1. jdbc mysql查询显示图片_在实现JDBC时如何显示存储引擎-MySQL CONNECTION查询?
  2. winform控件大小改变是防止背景重绘导致的闪烁
  3. Windows 安装 MongoDB 5.0.2版本
  4. 3.爱跑步的蜗壳人动态(下同)
  5. windows命令行无法启动redis_windows系统安装redis
  6. 大数据没用?!张小龙:我们很少看统计数据!
  7. rabbitmq配置文件_RabbitMQ学习
  8. 堡垒之夜安装包删除_堡垒之夜安装不了怎么办_常见安装下载问题解决方法_3DM网游...
  9. [破解] DRM-内容数据版权加密保护技术学习(中):License预发放实现
  10. 30幅精美的Photoshop三维字体作品欣赏及教程
  11. mtk刷机显示连接服务器失败,MTk线刷刷机出现的错误和解决方法
  12. java多线程编程实例
  13. canvas应用——圆角矩形图片
  14. 毕业四年后的程序员继续租房子
  15. 《需求工程——软件建模与分析》阅读笔记3
  16. MySQL数据库密码破解
  17. 漂浮广告是什么?漂浮广告如何设置
  18. 2022我们都用这3个3D建模软件,常用简单又易上手
  19. 【Android】通用系列 —— 快速搭建设置界面
  20. [SDOI2009][BZOJ 1226]学校食堂

热门文章

  1. 《问佛》------------一篇精辟人生哲理短文(转)
  2. 为什么说程序员做外包没前途?
  3. 论治理与创新,2022 开放原子全球开源峰会 OpenAnolis 分论坛圆满落幕
  4. XSS盗取用户信息实验(详细)及xss之旅闯关
  5. matlab解方java_matlab解方程
  6. 脑科学和人工智能的思考
  7. Python制作经典坦克大战小游戏
  8. 《Python数据分析与应用》第7章 机器学习模型的应用 实训部分
  9. 怎么在计算机里有桌面快捷方式,桌面快捷方式不见了,小编教你桌面软件快捷方式图标不见了怎么办...
  10. 千锋前端-React全家桶_React项目实战全球新闻发布管理系统-db.json文件数据